From ebe18e0ddf283425d3539a08cbca8834c7dbdb4a Mon Sep 17 00:00:00 2001 From: peefy Date: Mon, 18 Mar 2024 15:56:24 +0800 Subject: [PATCH] chore: narrow versioned documents Signed-off-by: peefy --- .github/workflows/check.yml | 63 - .github/workflows/cla.yml | 2 +- .github/workflows/install-kusion.yml | 79 - CHANGELOG.md | 16 - VERSION | 2 +- .../version-0.5.0.json | 246 -- .../version-0.5.3.json | 254 -- .../version-0.5.4.json | 254 -- .../version-0.5.5.json | 254 -- .../version-0.5.6.json | 254 -- .../{version-0.5.2.json => version-0.5.json} | 4 +- .../{version-0.6.0.json => version-0.6.json} | 4 +- .../{version-0.7.0.json => version-0.7.json} | 4 +- .../{version-0.5.1.json => version-0.8.json} | 34 +- .../reference/lang/error/exception.md | 1584 -------- .../version-0.5.0/reference/lang/tour.md | 3201 ---------------- .../version-0.5.0/reference/model/datetime.md | 31 - .../version-0.5.0/reference/model/json.md | 40 - .../version-0.5.0/reference/model/yaml.md | 39 - .../version-0.5.0/tools/Ide/intellij.md | 3 - .../version-0.5.0/tools/Ide/vs-code.md | 54 - .../version-0.5.0/tools/cli/kcl/overview.md | 18 - .../user_docs/getting-started/install.md | 140 - .../user_docs/guides/abstraction.md | 145 - .../user_docs/guides/automation.md | 201 - .../guides/ci-integration/1-github-actions.md | 162 - .../user_docs/guides/configuration.md | 125 - .../user_docs/guides/data-integration.md | 102 - .../user_docs/guides/gitops/1-quick-start.md | 141 - .../user_docs/guides/schema-definition.md | 113 - .../user_docs/guides/validation.md | 95 - .../working-with-kusion/_category_.json | 4 - .../version-0.5.1.json | 130 - .../reference/lang/error/exception.md | 1584 -------- .../version-0.5.1/reference/lang/tour.md | 3208 ---------------- .../version-0.5.1/reference/model/datetime.md | 31 - .../version-0.5.1/reference/model/json.md | 40 - .../version-0.5.1/reference/model/yaml.md | 39 - .../package-management/_category_.json | 4 - .../version-0.5.1/tools/Ide/index.md | 6 - .../version-0.5.1/tools/Ide/intellij.md | 3 - .../version-0.5.1/tools/Ide/vs-code.md | 54 - .../user_docs/getting-started/install.md | 140 - .../user_docs/getting-started/intro.md | 199 - .../user_docs/guides/abstraction.md | 145 - .../user_docs/guides/automation.md | 201 - .../guides/ci-integration/1-github-actions.md | 162 - .../user_docs/guides/configuration.md | 125 - .../user_docs/guides/data-integration.md | 102 - .../user_docs/guides/gitops/1-quick-start.md | 141 - .../guides/package-management/_category_.json | 4 - .../user_docs/guides/schema-definition.md | 113 - .../user_docs/guides/validation.md | 95 - .../1-adopt-from-kubernetes.md | 60 - .../guides/working-with-konfig/1-overview.md | 30 - .../guides/working-with-konfig/2-structure.md | 97 - .../working-with-konfig/3-quick-start.md | 198 - .../user_docs/support/faq-install.md | 29 - .../user_docs/support/faq-kcl.md | 2355 ------------ .../version-0.5.2.json | 130 - .../community/release-policy/roadmap.md | 3 - .../reference/lang/error/exception.md | 1584 -------- .../version-0.5.2/reference/lang/tour.md | 3208 ---------------- .../version-0.5.2/reference/model/datetime.md | 31 - .../version-0.5.2/reference/model/index.md | 3 - .../version-0.5.2/reference/model/json.md | 40 - .../version-0.5.2/reference/model/overview.md | 11 - .../version-0.5.2/reference/model/yaml.md | 39 - .../package-management/_category_.json | 4 - .../command-reference/1.init.md | 45 - .../command-reference/10.help.md | 21 - .../command-reference/2.add.md | 53 - .../command-reference/3.pkg.md | 33 - .../command-reference/4.metadata.md | 41 - .../command-reference/5.run.md | 69 - .../command-reference/6.login.md | 68 - .../command-reference/7.logout.md | 27 - .../command-reference/8.push.md | 46 - .../command-reference/9.pull.md | 41 - .../command-reference/index.md | 36 - .../reference/plugin/overview.md | 183 - .../reference/xlang-api/rest-api.md | 455 --- .../version-0.5.2/tools/Ide/index.md | 6 - .../version-0.5.2/tools/Ide/intellij.md | 3 - .../version-0.5.2/tools/Ide/vs-code.md | 54 - .../version-0.5.2/tools/cli/kcl/docgen.md | 313 -- .../version-0.5.2/tools/cli/kcl/fmt.md | 70 - .../version-0.5.2/tools/cli/kcl/index.md | 3 - .../version-0.5.2/tools/cli/kcl/lint.md | 54 - .../version-0.5.2/tools/cli/kcl/test.md | 7 - .../version-0.5.2/tools/cli/kcl/vet.md | 87 - .../tools/cli/openapi/crd-to-kcl.md | 118 - .../tools/cli/openapi/openapi-to-kcl.md | 64 - .../tools/cli/openapi/quick-start.md | 47 - .../user_docs/concepts/concepts.md | 3 - .../user_docs/getting-started/index.md | 1 - .../user_docs/getting-started/install.md | 140 - .../user_docs/getting-started/intro.md | 199 - .../version-0.5.2/user_docs/guides/index.md | 1 - .../guides/package-management/1-overview.md | 3 - .../package-management/2-installation.md | 53 - .../package-management/3-quick-start.md | 108 - .../guides/package-management/_category_.json | 4 - .../1-adopt-from-kubernetes.md | 60 - .../2-generate-k8s-manifests.md | 249 -- .../1-kubectl-kcl-plugin.md | 100 - .../3-mutate-manifests/2-helm-kcl-plugin.md | 100 - .../3-kustomize-kcl-plugin.md | 104 - .../guides/working-with-konfig/1-overview.md | 30 - .../guides/working-with-konfig/2-structure.md | 97 - .../working-with-konfig/3-quick-start.md | 198 - .../user_docs/support/faq-install.md | 29 - .../user_docs/support/faq-kcl.md | 2355 ------------ .../user_docs/support/support.md | 3 - .../version-0.5.3.json | 130 - .../community/release-policy/roadmap.md | 3 - .../reference/lang/error/_error.md | 52 - .../reference/lang/error/exception.md | 1584 -------- .../version-0.5.3/reference/lang/tour.md | 3208 ---------------- .../version-0.5.3/reference/model/crypto.md | 43 - .../version-0.5.3/reference/model/datetime.md | 31 - .../version-0.5.3/reference/model/index.md | 3 - .../version-0.5.3/reference/model/json.md | 40 - .../version-0.5.3/reference/model/overview.md | 11 - .../version-0.5.3/reference/model/yaml.md | 39 - .../package-management/_category_.json | 4 - .../command-reference/1.init.md | 45 - .../command-reference/10.help.md | 21 - .../command-reference/2.add.md | 53 - .../command-reference/3.pkg.md | 33 - .../command-reference/4.metadata.md | 41 - .../command-reference/5.run.md | 69 - .../command-reference/6.login.md | 68 - .../command-reference/7.logout.md | 27 - .../command-reference/8.push.md | 46 - .../command-reference/9.pull.md | 41 - .../command-reference/index.md | 36 - .../version-0.5.3/reference/plugin/index.md | 1 - .../reference/plugin/overview.md | 183 - .../reference/xlang-api/index.md | 1 - .../reference/xlang-api/overview.md | 295 -- .../reference/xlang-api/rest-api.md | 455 --- .../version-0.5.3/tools/Ide/index.md | 6 - .../version-0.5.3/tools/Ide/intellij.md | 3 - .../version-0.5.3/tools/Ide/vs-code.md | 54 - .../version-0.5.3/tools/cli/kcl/docgen.md | 313 -- .../version-0.5.3/tools/cli/kcl/fmt.md | 70 - .../version-0.5.3/tools/cli/kcl/index.md | 3 - .../version-0.5.3/tools/cli/kcl/lint.md | 54 - .../version-0.5.3/tools/cli/kcl/overview.md | 58 - .../version-0.5.3/tools/cli/kcl/test.md | 7 - .../version-0.5.3/tools/cli/kcl/vet.md | 87 - .../tools/cli/openapi/crd-to-kcl.md | 118 - .../version-0.5.3/tools/cli/openapi/index.md | 3 - .../tools/cli/openapi/openapi-to-kcl.md | 64 - .../tools/cli/openapi/quick-start.md | 47 - .../user_docs/concepts/concepts.md | 3 - .../user_docs/getting-started/index.md | 1 - .../user_docs/getting-started/install.md | 140 - .../user_docs/getting-started/intro.md | 199 - .../user_docs/guides/automation.md | 205 - .../version-0.5.3/user_docs/guides/index.md | 1 - .../guides/package-management/1-overview.md | 3 - .../package-management/2-installation.md | 53 - .../package-management/3-quick-start.md | 108 - .../guides/package-management/_category_.json | 4 - .../1-adopt-from-kubernetes.md | 60 - .../2-generate-k8s-manifests.md | 249 -- .../1-kubectl-kcl-plugin.md | 100 - .../3-mutate-manifests/2-helm-kcl-plugin.md | 100 - .../3-kustomize-kcl-plugin.md | 104 - .../guides/working-with-konfig/1-overview.md | 30 - .../guides/working-with-konfig/2-structure.md | 97 - .../working-with-konfig/3-quick-start.md | 198 - .../user_docs/support/faq-install.md | 29 - .../user_docs/support/faq-kcl.md | 2355 ------------ .../user_docs/support/support.md | 3 - .../version-0.5.4.json | 130 - .../version-0.5.4/community/_category_.json | 4 - .../community/contribute/_category_.json | 4 - .../community/contribute/contribute-code.md | 25 - .../community/contribute/contribute-docs.md | 61 - .../community/contribute/contribute.md | 1 - .../community/contribute/git-guideline.md | 132 - .../community/intro/_category_.json | 4 - .../version-0.5.4/community/intro/intro.md | 9 - .../version-0.5.4/community/intro/license.md | 211 -- .../version-0.5.4/community/intro/support.md | 19 - .../community/release-policy/_category_.json | 4 - .../community/release-policy/index.md | 1 - .../community/release-policy/kcl.md | 39 - .../community/release-policy/roadmap.md | 3 - .../version-0.5.4/reference/_category_.json | 4 - .../reference/cheatsheets/_category_.json | 4 - .../reference/cheatsheets/index.md | 5 - .../version-0.5.4/reference/index.md | 1 - .../reference/lang/_category_.json | 4 - .../reference/lang/codelab/_category_.json | 4 - .../reference/lang/codelab/collaborative.md | 345 -- .../reference/lang/codelab/index.md | 1 - .../reference/lang/codelab/schema.md | 814 ---- .../reference/lang/codelab/simple.md | 495 --- .../reference/lang/error/_category_.json | 4 - .../reference/lang/error/_error.md | 52 - .../reference/lang/error/exception.md | 1584 -------- .../reference/lang/error/index.md | 1 - .../version-0.5.4/reference/lang/index.md | 1 - .../reference/lang/spec/_category_.json | 4 - .../reference/lang/spec/error.md | 53 - .../reference/lang/spec/expressions.md | 915 ----- .../reference/lang/spec/index.md | 1 - .../reference/lang/spec/kcl-spec.md | 343 -- .../reference/lang/spec/lexical.md | 213 -- .../reference/lang/spec/modules.md | 621 --- .../reference/lang/spec/schema.md | 916 ----- .../reference/lang/spec/statements.md | 185 - .../version-0.5.4/reference/lang/tour.md | 3208 ---------------- .../reference/lang/types/_category_.json | 4 - .../reference/lang/types/types.md | 1401 ------- .../reference/model/_category_.json | 4 - .../version-0.5.4/reference/model/base64.md | 19 - .../version-0.5.4/reference/model/builtin.md | 401 -- .../version-0.5.4/reference/model/crypto.md | 43 - .../version-0.5.4/reference/model/datetime.md | 31 - .../version-0.5.4/reference/model/index.md | 3 - .../version-0.5.4/reference/model/json.md | 40 - .../reference/model/manifests.md | 89 - .../version-0.5.4/reference/model/math.md | 103 - .../version-0.5.4/reference/model/net.md | 103 - .../version-0.5.4/reference/model/overview.md | 11 - .../version-0.5.4/reference/model/regex.md | 43 - .../version-0.5.4/reference/model/units.md | 41 - .../version-0.5.4/reference/model/yaml.md | 39 - .../package-management/_category_.json | 4 - .../command-reference/1.init.md | 45 - .../command-reference/10.help.md | 21 - .../command-reference/2.add.md | 53 - .../command-reference/3.pkg.md | 33 - .../command-reference/4.metadata.md | 41 - .../command-reference/5.run.md | 69 - .../command-reference/6.login.md | 68 - .../command-reference/7.logout.md | 27 - .../command-reference/8.push.md | 46 - .../command-reference/9.pull.md | 41 - .../command-reference/_category_.json | 4 - .../command-reference/index.md | 36 - .../reference/plugin/_category_.json | 4 - .../version-0.5.4/reference/plugin/index.md | 1 - .../reference/plugin/overview.md | 183 - .../reference/xlang-api/_category_.json | 4 - .../reference/xlang-api/go-api.md | 665 ---- .../reference/xlang-api/index.md | 1 - .../reference/xlang-api/java-api.md | 7 - .../reference/xlang-api/overview.md | 295 -- .../reference/xlang-api/python-api.md | 7 - .../reference/xlang-api/rest-api.md | 455 --- .../version-0.5.4/tools/Ide/_category_.json | 4 - .../version-0.5.4/tools/Ide/index.md | 6 - .../version-0.5.4/tools/Ide/intellij.md | 3 - .../version-0.5.4/tools/Ide/vs-code.md | 54 - .../version-0.5.4/tools/_category_.json | 4 - .../version-0.5.4/tools/cli/_category_.json | 4 - .../version-0.5.4/tools/cli/index.md | 3 - .../tools/cli/kcl/_category_.json | 4 - .../version-0.5.4/tools/cli/kcl/docgen.md | 313 -- .../version-0.5.4/tools/cli/kcl/fmt.md | 70 - .../version-0.5.4/tools/cli/kcl/index.md | 3 - .../version-0.5.4/tools/cli/kcl/lint.md | 54 - .../version-0.5.4/tools/cli/kcl/overview.md | 58 - .../version-0.5.4/tools/cli/kcl/test.md | 7 - .../version-0.5.4/tools/cli/kcl/vet.md | 87 - .../tools/cli/openapi/_category_.json | 4 - .../tools/cli/openapi/crd-to-kcl.md | 118 - .../version-0.5.4/tools/cli/openapi/index.md | 3 - .../tools/cli/openapi/openapi-to-kcl.md | 64 - .../tools/cli/openapi/quick-start.md | 47 - .../version-0.5.4/tools/cli/openapi/spec.md | 424 --- .../user_docs/concepts/_category_.json | 4 - .../user_docs/concepts/concepts.md | 3 - .../user_docs/concepts/package-and-module.md | 156 - .../user_docs/getting-started/_category_.json | 4 - .../user_docs/getting-started/index.md | 1 - .../user_docs/getting-started/install.md | 140 - .../user_docs/getting-started/intro.md | 199 - .../getting-started/kcl-quick-start.md | 166 - .../user_docs/guides/_category_.json | 4 - .../user_docs/guides/automation.md | 205 - .../guides/ci-integration/_2-gitlab-ci.md | 12 - .../version-0.5.4/user_docs/guides/index.md | 1 - .../guides/package-management/1-overview.md | 3 - .../package-management/2-installation.md | 53 - .../package-management/3-quick-start.md | 108 - .../4-how-to/4-share_your_pkg.md | 73 - .../4-how-to/5-share_your_pkg_docker.md | 65 - .../4-how-to/6-push_github_action.md | 83 - .../4-how-to/_category_.json | 4 - .../guides/package-management/_category_.json | 4 - .../user_docs/guides/validation.md | 99 - .../1-adopt-from-kubernetes.md | 60 - .../2-generate-k8s-manifests.md | 249 -- .../1-kubectl-kcl-plugin.md | 100 - .../3-mutate-manifests/2-helm-kcl-plugin.md | 100 - .../3-kustomize-kcl-plugin.md | 104 - .../3-mutate-manifests/4-kpt-kcl-sdk.md | 87 - .../guides/working-with-konfig/1-overview.md | 30 - .../guides/working-with-konfig/2-structure.md | 97 - .../working-with-konfig/3-quick-start.md | 198 - .../working-with-konfig/4-best-practice.md | 271 -- .../guides/working-with-kusion/index.md | 15 - .../user_docs/support/_category_.json | 4 - .../user_docs/support/faq-cli.md | 107 - .../user_docs/support/faq-install.md | 29 - .../user_docs/support/faq-kcl.md | 2355 ------------ .../user_docs/support/faq-yaml.md | 104 - .../user_docs/support/support.md | 3 - .../version-0.5.5.json | 130 - .../version-0.5.5/community/_category_.json | 4 - .../community/contribute/_category_.json | 4 - .../community/contribute/contribute-code.md | 25 - .../community/contribute/contribute-docs.md | 61 - .../community/contribute/contribute.md | 1 - .../community/contribute/git-guideline.md | 132 - .../community/intro/_category_.json | 4 - .../version-0.5.5/community/intro/intro.md | 9 - .../version-0.5.5/community/intro/license.md | 211 -- .../version-0.5.5/community/intro/support.md | 19 - .../community/release-policy/_category_.json | 4 - .../community/release-policy/index.md | 1 - .../community/release-policy/kcl.md | 39 - .../community/release-policy/roadmap.md | 3 - .../version-0.5.5/reference/_category_.json | 4 - .../reference/cheatsheets/_category_.json | 4 - .../reference/cheatsheets/index.md | 5 - .../version-0.5.5/reference/index.md | 1 - .../reference/lang/_category_.json | 4 - .../reference/lang/codelab/_category_.json | 4 - .../reference/lang/codelab/collaborative.md | 345 -- .../reference/lang/codelab/index.md | 1 - .../reference/lang/codelab/schema.md | 814 ---- .../reference/lang/codelab/simple.md | 495 --- .../reference/lang/error/_category_.json | 4 - .../reference/lang/error/_error.md | 52 - .../reference/lang/error/exception.md | 1584 -------- .../reference/lang/error/index.md | 1 - .../version-0.5.5/reference/lang/index.md | 1 - .../reference/lang/spec/_category_.json | 4 - .../reference/lang/spec/error.md | 53 - .../reference/lang/spec/expressions.md | 915 ----- .../reference/lang/spec/index.md | 1 - .../reference/lang/spec/kcl-spec.md | 343 -- .../reference/lang/spec/lexical.md | 213 -- .../reference/lang/spec/modules.md | 621 --- .../reference/lang/spec/schema.md | 916 ----- .../reference/lang/spec/statements.md | 185 - .../version-0.5.5/reference/lang/tour.md | 3208 ---------------- .../reference/lang/types/_category_.json | 4 - .../reference/lang/types/types.md | 1401 ------- .../reference/model/_category_.json | 4 - .../version-0.5.5/reference/model/base64.md | 19 - .../version-0.5.5/reference/model/builtin.md | 401 -- .../version-0.5.5/reference/model/crypto.md | 43 - .../version-0.5.5/reference/model/datetime.md | 31 - .../version-0.5.5/reference/model/index.md | 3 - .../version-0.5.5/reference/model/json.md | 40 - .../reference/model/manifests.md | 89 - .../version-0.5.5/reference/model/math.md | 103 - .../version-0.5.5/reference/model/net.md | 103 - .../version-0.5.5/reference/model/overview.md | 11 - .../version-0.5.5/reference/model/regex.md | 43 - .../version-0.5.5/reference/model/units.md | 41 - .../version-0.5.5/reference/model/yaml.md | 39 - .../package-management/_category_.json | 4 - .../command-reference/1.init.md | 45 - .../command-reference/10.help.md | 21 - .../command-reference/2.add.md | 53 - .../command-reference/3.pkg.md | 33 - .../command-reference/4.metadata.md | 41 - .../command-reference/5.run.md | 69 - .../command-reference/6.login.md | 68 - .../command-reference/7.logout.md | 27 - .../command-reference/8.push.md | 46 - .../command-reference/9.pull.md | 41 - .../command-reference/_category_.json | 4 - .../command-reference/index.md | 36 - .../reference/plugin/_category_.json | 4 - .../version-0.5.5/reference/plugin/index.md | 1 - .../reference/plugin/overview.md | 183 - .../reference/xlang-api/_category_.json | 4 - .../reference/xlang-api/go-api.md | 665 ---- .../reference/xlang-api/index.md | 1 - .../reference/xlang-api/java-api.md | 7 - .../reference/xlang-api/overview.md | 295 -- .../reference/xlang-api/python-api.md | 7 - .../reference/xlang-api/rest-api.md | 455 --- .../version-0.5.5/tools/Ide/_category_.json | 4 - .../version-0.5.5/tools/Ide/index.md | 6 - .../version-0.5.5/tools/_category_.json | 4 - .../version-0.5.5/tools/cli/_category_.json | 4 - .../version-0.5.5/tools/cli/index.md | 3 - .../tools/cli/kcl/_category_.json | 4 - .../version-0.5.5/tools/cli/kcl/docgen.md | 313 -- .../version-0.5.5/tools/cli/kcl/fmt.md | 70 - .../version-0.5.5/tools/cli/kcl/index.md | 3 - .../version-0.5.5/tools/cli/kcl/lint.md | 54 - .../version-0.5.5/tools/cli/kcl/overview.md | 58 - .../version-0.5.5/tools/cli/kcl/test.md | 7 - .../version-0.5.5/tools/cli/kcl/vet.md | 87 - .../tools/cli/openapi/_category_.json | 4 - .../tools/cli/openapi/crd-to-kcl.md | 118 - .../version-0.5.5/tools/cli/openapi/index.md | 3 - .../tools/cli/openapi/openapi-to-kcl.md | 64 - .../tools/cli/openapi/quick-start.md | 47 - .../version-0.5.5/tools/cli/openapi/spec.md | 424 --- .../user_docs/concepts/_category_.json | 4 - .../user_docs/concepts/concepts.md | 3 - .../user_docs/concepts/package-and-module.md | 156 - .../user_docs/getting-started/_category_.json | 4 - .../user_docs/getting-started/index.md | 1 - .../user_docs/getting-started/intro.md | 199 - .../getting-started/kcl-quick-start.md | 166 - .../user_docs/guides/_category_.json | 4 - .../user_docs/guides/automation.md | 205 - .../guides/ci-integration/_2-gitlab-ci.md | 12 - .../user_docs/guides/gitops/1-quick-start.md | 145 - .../version-0.5.5/user_docs/guides/index.md | 1 - .../guides/package-management/1-overview.md | 3 - .../package-management/2-installation.md | 53 - .../package-management/3-quick-start.md | 108 - .../4-how-to/4-share_your_pkg.md | 73 - .../4-how-to/5-share_your_pkg_docker.md | 65 - .../4-how-to/6-push_github_action.md | 83 - .../4-how-to/_category_.json | 4 - .../guides/package-management/_category_.json | 4 - .../guides/secret-management/1-vault.md | 142 - .../user_docs/guides/validation.md | 99 - .../1-adopt-from-kubernetes.md | 60 - .../2-generate-k8s-manifests.md | 249 -- .../1-kubectl-kcl-plugin.md | 100 - .../3-mutate-manifests/2-helm-kcl-plugin.md | 100 - .../3-kustomize-kcl-plugin.md | 104 - .../3-mutate-manifests/4-kpt-kcl-sdk.md | 87 - .../guides/working-with-konfig/1-overview.md | 30 - .../guides/working-with-konfig/2-structure.md | 97 - .../working-with-konfig/3-quick-start.md | 198 - .../working-with-konfig/4-best-practice.md | 271 -- .../guides/working-with-kusion/index.md | 15 - .../user_docs/support/_category_.json | 4 - .../user_docs/support/faq-cli.md | 107 - .../user_docs/support/faq-install.md | 29 - .../user_docs/support/faq-kcl.md | 2355 ------------ .../user_docs/support/faq-yaml.md | 104 - .../user_docs/support/support.md | 3 - .../version-0.5.6.json | 130 - .../version-0.5.6/community/_category_.json | 4 - .../community/contribute/_category_.json | 4 - .../community/contribute/contribute-code.md | 25 - .../community/contribute/contribute-docs.md | 61 - .../community/contribute/contribute.md | 1 - .../community/contribute/git-guideline.md | 132 - .../community/intro/_category_.json | 4 - .../version-0.5.6/community/intro/intro.md | 9 - .../version-0.5.6/community/intro/license.md | 211 -- .../version-0.5.6/community/intro/support.md | 19 - .../community/release-policy/_category_.json | 4 - .../community/release-policy/index.md | 1 - .../community/release-policy/kcl.md | 39 - .../community/release-policy/roadmap.md | 3 - .../version-0.5.6/reference/_category_.json | 4 - .../reference/cheatsheets/_category_.json | 4 - .../reference/cheatsheets/index.md | 5 - .../version-0.5.6/reference/index.md | 1 - .../reference/lang/_category_.json | 4 - .../reference/lang/codelab/_category_.json | 4 - .../reference/lang/codelab/collaborative.md | 345 -- .../reference/lang/codelab/index.md | 1 - .../reference/lang/codelab/schema.md | 814 ---- .../reference/lang/codelab/simple.md | 495 --- .../reference/lang/error/_category_.json | 4 - .../reference/lang/error/_error.md | 52 - .../reference/lang/error/index.md | 1 - .../version-0.5.6/reference/lang/index.md | 1 - .../reference/lang/spec/_category_.json | 4 - .../reference/lang/spec/codestyle.md | 608 --- .../reference/lang/spec/error.md | 53 - .../reference/lang/spec/expressions.md | 915 ----- .../reference/lang/spec/index.md | 1 - .../reference/lang/spec/kcl-spec.md | 343 -- .../reference/lang/spec/lexical.md | 213 -- .../reference/lang/spec/modules.md | 621 --- .../reference/lang/spec/schema.md | 916 ----- .../reference/lang/spec/statements.md | 185 - .../reference/lang/types/_category_.json | 4 - .../reference/lang/types/types.md | 1401 ------- .../reference/model/_category_.json | 4 - .../version-0.5.6/reference/model/base64.md | 19 - .../version-0.5.6/reference/model/builtin.md | 401 -- .../version-0.5.6/reference/model/crypto.md | 43 - .../version-0.5.6/reference/model/index.md | 3 - .../reference/model/manifests.md | 89 - .../version-0.5.6/reference/model/math.md | 103 - .../version-0.5.6/reference/model/net.md | 103 - .../version-0.5.6/reference/model/overview.md | 11 - .../version-0.5.6/reference/model/regex.md | 43 - .../version-0.5.6/reference/model/units.md | 41 - .../package-management/_category_.json | 4 - .../command-reference/1.init.md | 45 - .../command-reference/10.help.md | 21 - .../command-reference/2.add.md | 53 - .../command-reference/3.pkg.md | 33 - .../command-reference/4.metadata.md | 41 - .../command-reference/5.run.md | 69 - .../command-reference/6.login.md | 68 - .../command-reference/7.logout.md | 27 - .../command-reference/8.push.md | 46 - .../command-reference/9.pull.md | 41 - .../command-reference/_category_.json | 4 - .../command-reference/index.md | 36 - .../reference/plugin/_category_.json | 4 - .../version-0.5.6/reference/plugin/index.md | 1 - .../reference/plugin/overview.md | 183 - .../reference/plugin/project_context.md | 59 - .../reference/xlang-api/_category_.json | 4 - .../reference/xlang-api/go-api.md | 665 ---- .../reference/xlang-api/index.md | 1 - .../reference/xlang-api/java-api.md | 7 - .../reference/xlang-api/overview.md | 295 -- .../reference/xlang-api/python-api.md | 7 - .../reference/xlang-api/rest-api.md | 455 --- .../version-0.5.6/tools/Ide/_category_.json | 4 - .../version-0.5.6/tools/Ide/index.md | 6 - .../version-0.5.6/tools/Ide/vs-code.md | 58 - .../version-0.5.6/tools/_category_.json | 4 - .../version-0.5.6/tools/cli/_category_.json | 4 - .../version-0.5.6/tools/cli/index.md | 3 - .../tools/cli/kcl/_category_.json | 4 - .../version-0.5.6/tools/cli/kcl/docgen.md | 313 -- .../version-0.5.6/tools/cli/kcl/fmt.md | 70 - .../version-0.5.6/tools/cli/kcl/index.md | 3 - .../version-0.5.6/tools/cli/kcl/lint.md | 54 - .../version-0.5.6/tools/cli/kcl/overview.md | 58 - .../version-0.5.6/tools/cli/kcl/test.md | 7 - .../version-0.5.6/tools/cli/kcl/vet.md | 87 - .../tools/cli/openapi/_category_.json | 4 - .../tools/cli/openapi/crd-to-kcl.md | 118 - .../version-0.5.6/tools/cli/openapi/index.md | 3 - .../tools/cli/openapi/openapi-to-kcl.md | 64 - .../tools/cli/openapi/quick-start.md | 47 - .../version-0.5.6/tools/cli/openapi/spec.md | 424 --- .../user_docs/concepts/_category_.json | 4 - .../user_docs/concepts/concepts.md | 3 - .../user_docs/concepts/package-and-module.md | 156 - .../user_docs/getting-started/_category_.json | 4 - .../user_docs/getting-started/index.md | 1 - .../user_docs/getting-started/install.md | 148 - .../user_docs/getting-started/intro.md | 199 - .../getting-started/kcl-quick-start.md | 166 - .../user_docs/guides/_category_.json | 4 - .../user_docs/guides/abstraction.md | 149 - .../user_docs/guides/automation.md | 205 - .../guides/ci-integration/1-github-actions.md | 166 - .../guides/ci-integration/_2-gitlab-ci.md | 12 - .../user_docs/guides/configuration.md | 129 - .../user_docs/guides/data-integration.md | 106 - .../user_docs/guides/gitops/1-quick-start.md | 145 - .../version-0.5.6/user_docs/guides/index.md | 1 - .../guides/package-management/1-overview.md | 3 - .../package-management/2-installation.md | 53 - .../package-management/3-quick-start.md | 108 - .../4-how-to/4-share_your_pkg.md | 73 - .../4-how-to/5-share_your_pkg_docker.md | 65 - .../4-how-to/6-push_github_action.md | 83 - .../4-how-to/_category_.json | 4 - .../guides/package-management/_category_.json | 4 - .../user_docs/guides/schema-definition.md | 117 - .../guides/secret-management/1-vault.md | 142 - .../user_docs/guides/validation.md | 99 - .../1-adopt-from-kubernetes.md | 60 - .../2-generate-k8s-manifests.md | 249 -- .../1-kubectl-kcl-plugin.md | 100 - .../3-mutate-manifests/2-helm-kcl-plugin.md | 100 - .../3-kustomize-kcl-plugin.md | 104 - .../3-mutate-manifests/4-kpt-kcl-sdk.md | 87 - .../guides/working-with-konfig/1-overview.md | 30 - .../guides/working-with-konfig/2-structure.md | 97 - .../working-with-konfig/3-quick-start.md | 198 - .../working-with-konfig/4-best-practice.md | 271 -- .../guides/working-with-kusion/index.md | 15 - .../user_docs/support/_category_.json | 4 - .../user_docs/support/faq-cli.md | 107 - .../user_docs/support/faq-install.md | 29 - .../user_docs/support/faq-kcl.md | 2355 ------------ .../user_docs/support/faq-yaml.md | 104 - .../user_docs/support/support.md | 3 - .../{version-0.5.0.json => version-0.5.json} | 0 .../community/_category_.json | 0 .../community/contribute/_category_.json | 0 .../community/contribute/contribute-code.md | 0 .../community/contribute/contribute-docs.md | 0 .../community/contribute/contribute.md | 0 .../community/contribute/git-guideline.md | 0 .../community/intro/_category_.json | 0 .../community/intro/intro.md | 0 .../community/intro/license.md | 0 .../community/intro/support.md | 0 .../community/release-policy/_category_.json | 0 .../community/release-policy/index.md | 0 .../community/release-policy/kcl.md | 0 .../community/release-policy/roadmap.md | 0 .../reference/_category_.json | 0 .../reference/cheatsheets/_category_.json | 0 .../reference/cheatsheets/index.md | 0 .../reference/index.md | 0 .../reference/lang/_category_.json | 0 .../reference/lang/codelab/_category_.json | 0 .../reference/lang/codelab/collaborative.md | 0 .../reference/lang/codelab/index.md | 0 .../reference/lang/codelab/schema.md | 0 .../reference/lang/codelab/simple.md | 0 .../reference/lang/error/_category_.json | 0 .../reference/lang/error/_error.md | 0 .../reference/lang/error/exception.md | 0 .../reference/lang/error/index.md | 0 .../reference/lang/index.md | 0 .../reference/lang/spec/_category_.json | 0 .../reference/lang/spec/codestyle.md | 0 .../reference/lang/spec/datatypes.md | 0 .../reference/lang/spec/error.md | 0 .../reference/lang/spec/expressions.md | 0 .../reference/lang/spec/index.md | 0 .../reference/lang/spec/kcl-spec.md | 0 .../reference/lang/spec/lexical.md | 0 .../reference/lang/spec/modules.md | 0 .../reference/lang/spec/schema.md | 0 .../reference/lang/spec/statements.md | 0 .../reference/lang/spec/variables.md | 0 .../reference/lang/tour.md | 0 .../reference/lang/types/_category_.json | 0 .../reference/lang/types/types.md | 0 .../reference/model/_category_.json | 0 .../reference/model/base64.md | 0 .../reference/model/builtin.md | 0 .../reference/model/crypto.md | 0 .../reference/model/datetime.md | 0 .../reference/model/index.md | 0 .../reference/model/json.md | 0 .../reference/model/manifests.md | 0 .../reference/model/math.md | 0 .../reference/model/net.md | 0 .../reference/model/overview.md | 0 .../reference/model/regex.md | 0 .../reference/model/units.md | 0 .../reference/model/yaml.md | 0 .../package-management/_category_.json | 0 .../command-reference/1.init.md | 0 .../command-reference/10.help.md | 0 .../command-reference/2.add.md | 0 .../command-reference/3.pkg.md | 0 .../command-reference/4.metadata.md | 0 .../command-reference/5.run.md | 0 .../command-reference/6.login.md | 0 .../command-reference/7.logout.md | 0 .../command-reference/8.push.md | 0 .../command-reference/9.pull.md | 0 .../command-reference/_category_.json | 0 .../command-reference/index.md | 0 .../reference/plugin/_category_.json | 0 .../reference/plugin/index.md | 0 .../reference/plugin/overview.md | 0 .../reference/plugin/project_context.md | 0 .../reference/xlang-api/_category_.json | 0 .../reference/xlang-api/go-api.md | 0 .../reference/xlang-api/index.md | 0 .../reference/xlang-api/java-api.md | 0 .../reference/xlang-api/overview.md | 0 .../reference/xlang-api/python-api.md | 0 .../reference/xlang-api/rest-api.md | 0 .../tools/Ide/_category_.json | 0 .../tools/Ide/index.md | 0 .../tools/Ide/intellij.md | 0 .../tools/Ide/neovim.md | 0 .../tools/Ide/vs-code.md | 0 .../tools/_category_.json | 0 .../tools/cli/_category_.json | 0 .../tools/cli/index.md | 0 .../tools/cli/kcl/_category_.json | 0 .../tools/cli/kcl/docgen.md | 0 .../tools/cli/kcl/fmt.md | 0 .../tools/cli/kcl/index.md | 0 .../tools/cli/kcl/lint.md | 0 .../tools/cli/kcl/overview.md | 0 .../tools/cli/kcl/test.md | 0 .../tools/cli/kcl/vet.md | 0 .../tools/cli/openapi/_category_.json | 0 .../tools/cli/openapi/crd-to-kcl.md | 0 .../tools/cli/openapi/index.md | 0 .../tools/cli/openapi/openapi-to-kcl.md | 0 .../tools/cli/openapi/quick-start.md | 0 .../tools/cli/openapi/spec.md | 0 .../user_docs/concepts/_category_.json | 0 .../user_docs/concepts/concepts.md | 0 .../user_docs/concepts/package-and-module.md | 0 .../user_docs/concepts/type-and-definition.md | 0 .../user_docs/getting-started/_category_.json | 0 .../user_docs/getting-started/index.md | 0 .../user_docs/getting-started/install.md | 0 .../user_docs/getting-started/intro.md | 0 .../getting-started/kcl-quick-start.md | 0 .../user_docs/guides/_category_.json | 0 .../user_docs/guides/abstraction.md | 0 .../user_docs/guides/automation.md | 0 .../guides/ci-integration/1-github-actions.md | 0 .../guides/ci-integration/_2-gitlab-ci.md | 0 .../guides/ci-integration/_3-jenkins-ci.md | 0 .../guides/ci-integration/_category_.json | 0 .../user_docs/guides/configuration.md | 0 .../user_docs/guides/data-integration.md | 0 .../user_docs/guides/gitops/1-quick-start.md | 0 .../user_docs/guides/gitops/_category_.json | 0 .../user_docs/guides/index.md | 0 .../guides/package-management/1-overview.md | 0 .../package-management/2-installation.md | 0 .../package-management/3-quick-start.md | 0 .../4-how-to/4-share_your_pkg.md | 0 .../4-how-to/5-share_your_pkg_docker.md | 0 .../4-how-to/6-push_github_action.md | 0 .../4-how-to/_category_.json | 0 .../guides/package-management/_category_.json | 0 .../user_docs/guides/schema-definition.md | 0 .../guides/secret-management/1-vault.md | 0 .../guides/secret-management/_category_.json | 0 .../user_docs/guides/validation.md | 0 .../1-adopt-from-kubernetes.md | 0 .../2-generate-k8s-manifests.md | 0 .../1-kubectl-kcl-plugin.md | 0 .../3-mutate-manifests/2-helm-kcl-plugin.md | 0 .../3-kustomize-kcl-plugin.md | 0 .../3-mutate-manifests/4-kpt-kcl-sdk.md | 0 .../3-mutate-manifests/_category_.json | 0 .../guides/working-with-k8s/_category_.json | 0 .../guides/working-with-k8s/index.md | 0 .../guides/working-with-konfig/1-overview.md | 0 .../guides/working-with-konfig/2-structure.md | 0 .../working-with-konfig/3-quick-start.md | 0 .../working-with-konfig/4-best-practice.md | 0 .../working-with-konfig/_category_.json | 0 .../working-with-kusion/_category_.json | 0 .../guides/working-with-kusion/index.md | 0 .../user_docs/support/_category_.json | 0 .../user_docs/support/faq-cli.md | 0 .../user_docs/support/faq-install.md | 0 .../user_docs/support/faq-kcl.md | 0 .../user_docs/support/faq-yaml.md | 0 .../user_docs/support/support.md | 0 .../version-0.6.0/community/_category_.json | 4 - .../community/contribute/_category_.json | 4 - .../community/contribute/contribute-code.md | 25 - .../community/contribute/contribute-docs.md | 61 - .../community/contribute/contribute.md | 1 - .../community/contribute/git-guideline.md | 132 - .../community/intro/_category_.json | 4 - .../version-0.6.0/community/intro/intro.md | 9 - .../version-0.6.0/community/intro/license.md | 211 -- .../version-0.6.0/community/intro/support.md | 19 - .../community/release-policy/_category_.json | 4 - .../community/release-policy/index.md | 1 - .../community/release-policy/kcl.md | 39 - .../community/release-policy/roadmap.md | 3 - .../version-0.6.0/reference/_category_.json | 4 - .../reference/cheatsheets/_category_.json | 4 - .../reference/cheatsheets/index.md | 5 - .../version-0.6.0/reference/index.md | 1 - .../reference/lang/_category_.json | 4 - .../reference/lang/codelab/_category_.json | 4 - .../reference/lang/codelab/collaborative.md | 345 -- .../reference/lang/codelab/index.md | 1 - .../reference/lang/codelab/schema.md | 814 ---- .../reference/lang/codelab/simple.md | 495 --- .../reference/lang/error/_category_.json | 4 - .../reference/lang/error/_error.md | 52 - .../reference/lang/error/index.md | 1 - .../version-0.6.0/reference/lang/index.md | 1 - .../reference/lang/spec/_category_.json | 4 - .../reference/lang/spec/codestyle.md | 608 --- .../reference/lang/spec/error.md | 53 - .../reference/lang/spec/expressions.md | 915 ----- .../reference/lang/spec/index.md | 1 - .../reference/lang/spec/kcl-spec.md | 343 -- .../reference/lang/spec/lexical.md | 213 -- .../reference/lang/spec/modules.md | 621 --- .../reference/lang/spec/schema.md | 916 ----- .../reference/lang/spec/statements.md | 185 - .../reference/lang/types/_category_.json | 4 - .../reference/lang/types/types.md | 1401 ------- .../reference/model/_category_.json | 4 - .../version-0.6.0/reference/model/base64.md | 19 - .../version-0.6.0/reference/model/builtin.md | 401 -- .../version-0.6.0/reference/model/crypto.md | 43 - .../version-0.6.0/reference/model/index.md | 3 - .../reference/model/manifests.md | 89 - .../version-0.6.0/reference/model/math.md | 103 - .../version-0.6.0/reference/model/net.md | 103 - .../version-0.6.0/reference/model/overview.md | 11 - .../version-0.6.0/reference/model/regex.md | 43 - .../version-0.6.0/reference/model/units.md | 41 - .../reference/plugin/_category_.json | 4 - .../version-0.6.0/reference/plugin/index.md | 1 - .../reference/plugin/overview.md | 183 - .../reference/plugin/project_context.md | 59 - .../reference/xlang-api/_category_.json | 4 - .../reference/xlang-api/go-api.md | 665 ---- .../reference/xlang-api/index.md | 1 - .../reference/xlang-api/java-api.md | 7 - .../reference/xlang-api/overview.md | 295 -- .../reference/xlang-api/python-api.md | 7 - .../reference/xlang-api/rest-api.md | 455 --- .../version-0.6.0/tools/Ide/_category_.json | 4 - .../version-0.6.0/tools/_category_.json | 4 - .../version-0.6.0/tools/cli/_category_.json | 4 - .../version-0.6.0/tools/cli/index.md | 3 - .../tools/cli/kcl/_category_.json | 4 - .../version-0.6.0/tools/cli/kcl/docgen.md | 313 -- .../version-0.6.0/tools/cli/kcl/fmt.md | 70 - .../version-0.6.0/tools/cli/kcl/index.md | 3 - .../version-0.6.0/tools/cli/kcl/lint.md | 54 - .../version-0.6.0/tools/cli/kcl/overview.md | 58 - .../version-0.6.0/tools/cli/kcl/test.md | 7 - .../version-0.6.0/tools/cli/kcl/vet.md | 87 - .../tools/cli/openapi/_category_.json | 4 - .../tools/cli/openapi/crd-to-kcl.md | 118 - .../version-0.6.0/tools/cli/openapi/index.md | 3 - .../tools/cli/openapi/openapi-to-kcl.md | 64 - .../tools/cli/openapi/quick-start.md | 47 - .../version-0.6.0/tools/cli/openapi/spec.md | 424 --- .../command-reference/1.init.md | 45 - .../command-reference/10.help.md | 21 - .../command-reference/2.add.md | 53 - .../command-reference/3.pkg.md | 33 - .../command-reference/4.metadata.md | 41 - .../command-reference/5.run.md | 69 - .../command-reference/6.login.md | 68 - .../command-reference/7.logout.md | 27 - .../command-reference/8.push.md | 46 - .../command-reference/9.pull.md | 41 - .../command-reference/_category_.json | 4 - .../command-reference/index.md | 36 - .../user_docs/concepts/_category_.json | 4 - .../user_docs/concepts/concepts.md | 3 - .../user_docs/concepts/package-and-module.md | 156 - .../user_docs/getting-started/_category_.json | 4 - .../user_docs/getting-started/index.md | 1 - .../getting-started/kcl-quick-start.md | 166 - .../user_docs/guides/_category_.json | 4 - .../user_docs/guides/abstraction.md | 149 - .../guides/ci-integration/1-github-actions.md | 166 - .../guides/ci-integration/_2-gitlab-ci.md | 12 - .../user_docs/guides/configuration.md | 129 - .../user_docs/guides/data-integration.md | 106 - .../user_docs/guides/gitops/1-quick-start.md | 145 - .../version-0.6.0/user_docs/guides/index.md | 1 - .../guides/package-management/1-overview.md | 3 - .../package-management/2-installation.md | 53 - .../package-management/3-quick-start.md | 108 - .../4-how-to/4-share_your_pkg.md | 73 - .../4-how-to/5-share_your_pkg_docker.md | 65 - .../4-how-to/6-push_github_action.md | 83 - .../4-how-to/_category_.json | 4 - .../user_docs/guides/schema-definition.md | 117 - .../guides/secret-management/1-vault.md | 142 - .../user_docs/guides/validation.md | 99 - .../2-generate-k8s-manifests.md | 249 -- .../1-kubectl-kcl-plugin.md | 100 - .../3-mutate-manifests/2-helm-kcl-plugin.md | 100 - .../3-kustomize-kcl-plugin.md | 104 - .../3-mutate-manifests/4-kpt-kcl-sdk.md | 87 - .../guides/working-with-k8s/index.md | 1 - .../working-with-konfig/4-best-practice.md | 271 -- .../guides/working-with-kusion/index.md | 15 - .../user_docs/support/_category_.json | 4 - .../user_docs/support/faq-cli.md | 107 - .../user_docs/support/faq-yaml.md | 104 - .../user_docs/support/support.md | 3 - .../{version-0.6.0.json => version-0.6.json} | 0 .../community/_category_.json | 0 .../community/contribute/_category_.json | 0 .../community/contribute/contribute-code.md | 0 .../community/contribute/contribute-docs.md | 0 .../community/contribute/contribute.md | 0 .../community/contribute/git-guideline.md | 0 .../community/intro/_category_.json | 0 .../community/intro/intro.md | 0 .../community/intro/license.md | 0 .../community/intro/support.md | 0 .../community/release-policy/_category_.json | 0 .../community/release-policy/index.md | 0 .../community/release-policy/kcl.md | 0 .../community/release-policy/roadmap.md | 0 .../reference/_category_.json | 0 .../reference/cheatsheets/_category_.json | 0 .../reference/cheatsheets/index.md | 0 .../reference/index.md | 0 .../reference/lang/_category_.json | 0 .../reference/lang/codelab/_category_.json | 0 .../reference/lang/codelab/collaborative.md | 0 .../reference/lang/codelab/index.md | 0 .../reference/lang/codelab/schema.md | 0 .../reference/lang/codelab/simple.md | 0 .../reference/lang/error/_category_.json | 0 .../reference/lang/error/_error.md | 0 .../reference/lang/error/exception.md | 0 .../reference/lang/error/index.md | 0 .../reference/lang/index.md | 0 .../reference/lang/spec/_category_.json | 0 .../reference/lang/spec/codestyle.md | 0 .../reference/lang/spec/datatypes.md | 0 .../reference/lang/spec/error.md | 0 .../reference/lang/spec/expressions.md | 0 .../reference/lang/spec/index.md | 0 .../reference/lang/spec/kcl-spec.md | 0 .../reference/lang/spec/lexical.md | 0 .../reference/lang/spec/modules.md | 0 .../reference/lang/spec/schema.md | 0 .../reference/lang/spec/statements.md | 0 .../reference/lang/spec/variables.md | 0 .../reference/lang/tour.md | 0 .../reference/lang/types/_category_.json | 0 .../reference/lang/types/types.md | 0 .../reference/model/_category_.json | 0 .../reference/model/base64.md | 0 .../reference/model/builtin.md | 0 .../reference/model/crypto.md | 0 .../reference/model/datetime.md | 0 .../reference/model/index.md | 0 .../reference/model/json.md | 0 .../reference/model/manifests.md | 0 .../reference/model/math.md | 0 .../reference/model/net.md | 0 .../reference/model/overview.md | 0 .../reference/model/regex.md | 0 .../reference/model/units.md | 0 .../reference/model/yaml.md | 0 .../reference/plugin/_category_.json | 0 .../reference/plugin/index.md | 0 .../reference/plugin/overview.md | 0 .../reference/plugin/project_context.md | 0 .../reference/xlang-api/_category_.json | 0 .../reference/xlang-api/go-api.md | 0 .../reference/xlang-api/index.md | 0 .../reference/xlang-api/java-api.md | 0 .../reference/xlang-api/overview.md | 0 .../reference/xlang-api/python-api.md | 0 .../reference/xlang-api/rest-api.md | 0 .../tools/Ide/_category_.json | 0 .../tools/Ide/index.md | 0 .../tools/Ide/intellij.md | 0 .../tools/Ide/neovim.md | 0 .../tools/Ide/vs-code.md | 0 .../tools/_category_.json | 0 .../tools/cli/_category_.json | 0 .../tools/cli/index.md | 0 .../tools/cli/kcl/_category_.json | 0 .../tools/cli/kcl/docgen.md | 0 .../tools/cli/kcl/fmt.md | 0 .../tools/cli/kcl/index.md | 0 .../tools/cli/kcl/lint.md | 0 .../tools/cli/kcl/overview.md | 0 .../tools/cli/kcl/test.md | 0 .../tools/cli/kcl/vet.md | 0 .../tools/cli/openapi/_category_.json | 0 .../tools/cli/openapi/crd-to-kcl.md | 0 .../tools/cli/openapi/index.md | 0 .../tools/cli/openapi/openapi-to-kcl.md | 0 .../tools/cli/openapi/quick-start.md | 0 .../tools/cli/openapi/spec.md | 0 .../cli/package-management/_category_.json | 0 .../command-reference/1.init.md | 0 .../command-reference/10.help.md | 0 .../command-reference/2.add.md | 0 .../command-reference/3.pkg.md | 0 .../command-reference/4.metadata.md | 0 .../command-reference/5.run.md | 0 .../command-reference/6.login.md | 0 .../command-reference/7.logout.md | 0 .../command-reference/8.push.md | 0 .../command-reference/9.pull.md | 0 .../command-reference/_category_.json | 0 .../command-reference/index.md | 0 .../user_docs/concepts/_category_.json | 0 .../user_docs/concepts/concepts.md | 0 .../user_docs/concepts/package-and-module.md | 0 .../user_docs/concepts/type-and-definition.md | 0 .../user_docs/getting-started/_category_.json | 0 .../user_docs/getting-started/index.md | 0 .../user_docs/getting-started/install.md | 0 .../user_docs/getting-started/intro.md | 0 .../getting-started/kcl-quick-start.md | 0 .../user_docs/guides/_category_.json | 0 .../user_docs/guides/abstraction.md | 0 .../user_docs/guides/automation.md | 0 .../guides/ci-integration/1-github-actions.md | 0 .../guides/ci-integration/_2-gitlab-ci.md | 0 .../guides/ci-integration/_3-jenkins-ci.md | 0 .../guides/ci-integration/_category_.json | 0 .../user_docs/guides/configuration.md | 0 .../user_docs/guides/data-integration.md | 0 .../user_docs/guides/gitops/1-quick-start.md | 0 .../user_docs/guides/gitops/_category_.json | 0 .../user_docs/guides/index.md | 0 .../guides/package-management/1-overview.md | 0 .../package-management/2-installation.md | 0 .../package-management/3-quick-start.md | 0 .../4-how-to/4-share_your_pkg.md | 0 .../4-how-to/5-share_your_pkg_docker.md | 0 .../4-how-to/6-push_github_action.md | 0 .../4-how-to/_category_.json | 0 .../guides/package-management/_category_.json | 0 .../user_docs/guides/schema-definition.md | 0 .../guides/secret-management/1-vault.md | 0 .../guides/secret-management/_category_.json | 0 .../user_docs/guides/validation.md | 0 .../1-adopt-from-kubernetes.md | 0 .../2-generate-k8s-manifests.md | 0 .../1-kubectl-kcl-plugin.md | 0 .../3-mutate-manifests/2-helm-kcl-plugin.md | 0 .../3-kustomize-kcl-plugin.md | 0 .../3-mutate-manifests/4-kpt-kcl-sdk.md | 0 .../3-mutate-manifests/_category_.json | 0 .../guides/working-with-k8s/_category_.json | 0 .../guides/working-with-k8s/index.md | 0 .../guides/working-with-konfig/1-overview.md | 0 .../guides/working-with-konfig/2-structure.md | 0 .../working-with-konfig/3-quick-start.md | 0 .../working-with-konfig/4-best-practice.md | 0 .../working-with-konfig/_category_.json | 0 .../working-with-kusion/_category_.json | 0 .../guides/working-with-kusion/index.md | 0 .../user_docs/support/_category_.json | 0 .../user_docs/support/faq-cli.md | 0 .../user_docs/support/faq-install.md | 0 .../user_docs/support/faq-kcl.md | 0 .../user_docs/support/faq-yaml.md | 0 .../user_docs/support/support.md | 0 .../version-0.7.0/community/_category_.json | 4 - .../community/contribute/_category_.json | 4 - .../community/contribute/contribute-code.md | 25 - .../community/contribute/contribute-docs.md | 61 - .../community/contribute/contribute.md | 1 - .../community/contribute/git-guideline.md | 132 - .../community/intro/_category_.json | 4 - .../version-0.7.0/community/intro/intro.md | 9 - .../version-0.7.0/community/intro/license.md | 211 -- .../version-0.7.0/community/intro/support.md | 19 - .../community/release-policy/_category_.json | 4 - .../community/release-policy/index.md | 1 - .../community/release-policy/kcl.md | 39 - .../version-0.7.0/reference/_category_.json | 4 - .../reference/cheatsheets/_category_.json | 4 - .../reference/cheatsheets/index.md | 5 - .../version-0.7.0/reference/index.md | 1 - .../reference/lang/_category_.json | 4 - .../reference/lang/codelab/_category_.json | 4 - .../reference/lang/codelab/collaborative.md | 345 -- .../reference/lang/codelab/index.md | 1 - .../reference/lang/codelab/schema.md | 814 ---- .../reference/lang/codelab/simple.md | 495 --- .../reference/lang/error/_category_.json | 4 - .../reference/lang/error/_error.md | 52 - .../reference/lang/error/index.md | 1 - .../version-0.7.0/reference/lang/index.md | 1 - .../reference/lang/spec/_category_.json | 4 - .../reference/lang/spec/codestyle.md | 608 --- .../reference/lang/spec/datatypes.md | 452 --- .../reference/lang/spec/expressions.md | 915 ----- .../reference/lang/spec/index.md | 1 - .../reference/lang/spec/lexical.md | 213 -- .../reference/lang/spec/variables.md | 68 - .../reference/lang/types/_category_.json | 4 - .../reference/lang/types/types.md | 1401 ------- .../reference/model/_category_.json | 4 - .../version-0.7.0/reference/model/base64.md | 19 - .../version-0.7.0/reference/model/builtin.md | 401 -- .../version-0.7.0/reference/model/crypto.md | 43 - .../reference/model/manifests.md | 89 - .../version-0.7.0/reference/model/math.md | 103 - .../version-0.7.0/reference/model/net.md | 103 - .../version-0.7.0/reference/model/regex.md | 43 - .../version-0.7.0/reference/model/units.md | 41 - .../reference/plugin/_category_.json | 4 - .../version-0.7.0/reference/plugin/index.md | 1 - .../reference/plugin/project_context.md | 59 - .../reference/xlang-api/_category_.json | 4 - .../reference/xlang-api/index.md | 1 - .../reference/xlang-api/java-api.md | 7 - .../reference/xlang-api/overview.md | 295 -- .../reference/xlang-api/python-api.md | 7 - .../version-0.7.0/tools/Ide/_category_.json | 4 - .../version-0.7.0/tools/_category_.json | 4 - .../version-0.7.0/tools/cli/_category_.json | 4 - .../version-0.7.0/tools/cli/index.md | 3 - .../tools/cli/kcl/_category_.json | 4 - .../tools/cli/openapi/_category_.json | 4 - .../version-0.7.0/tools/cli/openapi/index.md | 3 - .../version-0.7.0/tools/cli/openapi/spec.md | 424 --- .../command-reference/_category_.json | 4 - .../user_docs/concepts/_category_.json | 4 - .../user_docs/concepts/package-and-module.md | 156 - .../user_docs/concepts/type-and-definition.md | 94 - .../user_docs/getting-started/_category_.json | 4 - .../getting-started/kcl-quick-start.md | 166 - .../user_docs/guides/_category_.json | 4 - .../user_docs/guides/abstraction.md | 149 - .../guides/ci-integration/1-github-actions.md | 166 - .../guides/ci-integration/_2-gitlab-ci.md | 12 - .../guides/ci-integration/_3-jenkins-ci.md | 12 - .../guides/ci-integration/_category_.json | 4 - .../user_docs/guides/configuration.md | 129 - .../user_docs/guides/data-integration.md | 106 - .../user_docs/guides/gitops/1-quick-start.md | 145 - .../user_docs/guides/gitops/_category_.json | 4 - .../4-how-to/4-share_your_pkg.md | 73 - .../4-how-to/5-share_your_pkg_docker.md | 65 - .../4-how-to/6-push_github_action.md | 83 - .../4-how-to/_category_.json | 4 - .../user_docs/guides/schema-definition.md | 117 - .../guides/secret-management/1-vault.md | 142 - .../3-mutate-manifests/4-kpt-kcl-sdk.md | 87 - .../3-mutate-manifests/_category_.json | 4 - .../guides/working-with-k8s/_category_.json | 4 - .../guides/working-with-k8s/index.md | 1 - .../working-with-konfig/4-best-practice.md | 271 -- .../working-with-konfig/_category_.json | 4 - .../guides/working-with-kusion/index.md | 15 - .../user_docs/support/_category_.json | 4 - .../user_docs/support/faq-cli.md | 107 - .../user_docs/support/faq-yaml.md | 104 - .../{version-0.7.0.json => version-0.7.json} | 0 .../community/_category_.json | 0 .../community/contribute/_category_.json | 0 .../community/contribute/contribute-code.md | 0 .../community/contribute/contribute-docs.md | 0 .../community/contribute/contribute.md | 0 .../community/contribute/git-guideline.md | 0 .../community/intro/_category_.json | 0 .../community/intro/intro.md | 0 .../community/intro/license.md | 0 .../community/intro/support.md | 0 .../community/release-policy/_category_.json | 0 .../community/release-policy/index.md | 0 .../community/release-policy/kcl.md | 0 .../community/release-policy/roadmap.md | 0 .../reference/_category_.json | 0 .../reference/cheatsheets/_category_.json | 0 .../reference/cheatsheets/index.md | 0 .../reference/index.md | 0 .../reference/lang/_category_.json | 0 .../reference/lang/codelab/_category_.json | 0 .../reference/lang/codelab/collaborative.md | 0 .../reference/lang/codelab/index.md | 0 .../reference/lang/codelab/schema.md | 0 .../reference/lang/codelab/simple.md | 0 .../reference/lang/error/_category_.json | 0 .../reference/lang/error/_error.md | 0 .../reference/lang/error/exception.md | 0 .../reference/lang/error/index.md | 0 .../reference/lang/index.md | 0 .../reference/lang/spec/_category_.json | 0 .../reference/lang/spec/codestyle.md | 0 .../reference/lang/spec/datatypes.md | 0 .../reference/lang/spec/error.md | 0 .../reference/lang/spec/expressions.md | 0 .../reference/lang/spec/index.md | 0 .../reference/lang/spec/kcl-spec.md | 0 .../reference/lang/spec/lexical.md | 0 .../reference/lang/spec/modules.md | 0 .../reference/lang/spec/schema.md | 0 .../reference/lang/spec/statements.md | 0 .../reference/lang/spec/variables.md | 0 .../reference/lang/tour.md | 0 .../reference/lang/types/_category_.json | 0 .../reference/lang/types/types.md | 0 .../reference/model/_category_.json | 0 .../reference/model/base64.md | 0 .../reference/model/builtin.md | 0 .../reference/model/crypto.md | 0 .../reference/model/datetime.md | 0 .../reference/model/json.md | 0 .../reference/model/manifests.md | 0 .../reference/model/math.md | 0 .../reference/model/net.md | 0 .../reference/model/overview.md | 0 .../reference/model/regex.md | 0 .../reference/model/units.md | 0 .../reference/model/yaml.md | 0 .../reference/plugin/_category_.json | 0 .../reference/plugin/index.md | 0 .../reference/plugin/overview.md | 0 .../reference/plugin/project_context.md | 0 .../reference/xlang-api/_category_.json | 0 .../reference/xlang-api/go-api.md | 0 .../reference/xlang-api/index.md | 0 .../reference/xlang-api/java-api.md | 0 .../reference/xlang-api/overview.md | 0 .../reference/xlang-api/python-api.md | 0 .../reference/xlang-api/rest-api.md | 0 .../tools/Ide/_category_.json | 0 .../tools/Ide/index.md | 0 .../tools/Ide/intellij.md | 0 .../tools/Ide/neovim.md | 0 .../tools/Ide/vs-code.md | 0 .../tools/_category_.json | 0 .../tools/cli/_category_.json | 0 .../tools/cli/index.md | 0 .../tools/cli/kcl/_category_.json | 0 .../tools/cli/kcl/docgen.md | 0 .../tools/cli/kcl/fmt.md | 0 .../tools/cli/kcl/import.md | 0 .../tools/cli/kcl/index.md | 0 .../tools/cli/kcl/lint.md | 0 .../tools/cli/kcl/overview.md | 0 .../tools/cli/kcl/run.md | 0 .../tools/cli/kcl/test.md | 0 .../tools/cli/kcl/vet.md | 0 .../tools/cli/openapi/_category_.json | 0 .../tools/cli/openapi/crd-to-kcl.md | 0 .../tools/cli/openapi/index.md | 0 .../tools/cli/openapi/openapi-to-kcl.md | 0 .../tools/cli/openapi/spec.md | 0 .../cli/package-management/_category_.json | 0 .../command-reference/1.init.md | 0 .../command-reference/10.help.md | 0 .../command-reference/2.add.md | 0 .../command-reference/3.pkg.md | 0 .../command-reference/4.metadata.md | 0 .../command-reference/6.login.md | 0 .../command-reference/7.logout.md | 0 .../command-reference/8.push.md | 0 .../command-reference/9.pull.md | 0 .../command-reference/_category_.json | 0 .../user_docs/concepts/_category_.json | 0 .../user_docs/concepts/concepts.md | 0 .../user_docs/concepts/package-and-module.md | 0 .../user_docs/concepts/type-and-definition.md | 0 .../user_docs/getting-started/_category_.json | 0 .../user_docs/getting-started/index.md | 0 .../user_docs/getting-started/install.md | 0 .../user_docs/getting-started/intro.md | 0 .../getting-started/kcl-quick-start.md | 0 .../user_docs/guides/_category_.json | 0 .../user_docs/guides/abstraction.md | 0 .../user_docs/guides/automation.md | 0 .../guides/ci-integration/1-github-actions.md | 0 .../guides/ci-integration/_2-gitlab-ci.md | 0 .../guides/ci-integration/_3-jenkins-ci.md | 0 .../guides/ci-integration/_category_.json | 0 .../user_docs/guides/configuration.md | 0 .../user_docs/guides/data-integration.md | 0 .../user_docs/guides/gitops/1-quick-start.md | 0 .../user_docs/guides/gitops/_category_.json | 0 .../user_docs/guides/index.md | 0 .../package-management/3-quick-start.md | 0 .../4-how-to/4-share_your_pkg.md | 0 .../4-how-to/5-share_your_pkg_docker.md | 0 .../4-how-to/6-push_github_action.md | 0 .../4-how-to/7-publish_pkg_to_ah.md | 0 .../package-management/4-how-to/8-kcl_mod.md | 0 .../package-management/4-how-to/9-kpm_oci.md | 0 .../4-how-to/_category_.json | 0 .../guides/package-management/_category_.json | 0 .../user_docs/guides/schema-definition.md | 0 .../guides/secret-management/1-vault.md | 0 .../guides/secret-management/_category_.json | 0 .../user_docs/guides/validation.md | 0 .../guides/working-with-k8s/0-overview.md | 0 .../1-adopt-from-kubernetes.md | 0 .../2-generate-k8s-manifests.md | 0 .../1-kubectl-kcl-plugin.md | 0 .../3-mutate-manifests/2-helm-kcl-plugin.md | 0 .../3-kustomize-kcl-plugin.md | 0 .../3-mutate-manifests/4-kpt-kcl-sdk.md | 0 .../3-mutate-manifests/_category_.json | 0 .../working-with-k8s/4-publish-modules.md | 0 .../working-with-k8s/_4-publish-modules.md | 0 .../guides/working-with-k8s/_category_.json | 0 .../guides/working-with-k8s/index.md | 0 .../guides/working-with-konfig/1-overview.md | 0 .../guides/working-with-konfig/2-structure.md | 0 .../working-with-konfig/3-quick-start.md | 0 .../working-with-konfig/4-best-practice.md | 0 .../working-with-konfig/_category_.json | 0 .../working-with-kubevela/_category_.json | 0 .../guides/working-with-kubevela/index.md | 0 .../working-with-kusion/_category_.json | 0 .../guides/working-with-kusion/index.md | 0 .../user_docs/support/_category_.json | 0 .../user_docs/support/faq-cli.md | 0 .../user_docs/support/faq-install.md | 0 .../user_docs/support/faq-kcl.md | 0 .../user_docs/support/faq-yaml.md | 0 .../user_docs/support/support.md | 0 .../version-0.8.0/community/_category_.json | 4 - .../community/contribute/_category_.json | 4 - .../community/contribute/contribute-code.md | 25 - .../community/contribute/contribute-docs.md | 61 - .../community/contribute/contribute.md | 1 - .../community/contribute/git-guideline.md | 132 - .../community/intro/_category_.json | 4 - .../version-0.8.0/community/intro/intro.md | 9 - .../version-0.8.0/community/intro/license.md | 211 -- .../version-0.8.0/community/intro/support.md | 19 - .../community/release-policy/_category_.json | 4 - .../community/release-policy/index.md | 1 - .../community/release-policy/kcl.md | 39 - .../version-0.8.0/reference/_category_.json | 4 - .../reference/cheatsheets/_category_.json | 4 - .../reference/cheatsheets/index.md | 5 - .../version-0.8.0/reference/index.md | 1 - .../reference/lang/_category_.json | 4 - .../reference/lang/codelab/_category_.json | 4 - .../reference/lang/codelab/collaborative.md | 345 -- .../reference/lang/codelab/index.md | 1 - .../reference/lang/codelab/schema.md | 814 ---- .../reference/lang/codelab/simple.md | 495 --- .../reference/lang/error/_category_.json | 4 - .../reference/lang/error/index.md | 1 - .../version-0.8.0/reference/lang/index.md | 1 - .../reference/lang/spec/_category_.json | 4 - .../reference/lang/spec/datatypes.md | 452 --- .../reference/lang/spec/expressions.md | 915 ----- .../reference/lang/spec/index.md | 1 - .../reference/lang/spec/lexical.md | 213 -- .../reference/lang/spec/variables.md | 68 - .../reference/lang/types/_category_.json | 4 - .../reference/lang/types/types.md | 1401 ------- .../reference/model/_category_.json | 4 - .../version-0.8.0/reference/model/base64.md | 19 - .../version-0.8.0/reference/model/builtin.md | 401 -- .../reference/model/manifests.md | 89 - .../version-0.8.0/reference/model/math.md | 103 - .../version-0.8.0/reference/model/net.md | 103 - .../version-0.8.0/reference/model/regex.md | 43 - .../version-0.8.0/reference/model/units.md | 41 - .../reference/plugin/_category_.json | 4 - .../reference/xlang-api/_category_.json | 4 - .../reference/xlang-api/java-api.md | 7 - .../reference/xlang-api/python-api.md | 7 - .../version-0.8.0/tools/Ide/_category_.json | 4 - .../version-0.8.0/tools/Ide/intellij.md | 9 - .../version-0.8.0/tools/Ide/neovim.md | 9 - .../version-0.8.0/tools/_category_.json | 4 - .../version-0.8.0/tools/cli/_category_.json | 4 - .../version-0.8.0/tools/cli/index.md | 3 - .../tools/cli/kcl/_category_.json | 4 - .../tools/cli/openapi/_category_.json | 4 - .../version-0.8.0/tools/cli/openapi/spec.md | 424 --- .../command-reference/_category_.json | 4 - .../user_docs/concepts/_category_.json | 4 - .../user_docs/concepts/package-and-module.md | 156 - .../user_docs/concepts/type-and-definition.md | 94 - .../user_docs/getting-started/_category_.json | 4 - .../getting-started/kcl-quick-start.md | 166 - .../user_docs/guides/_category_.json | 4 - .../user_docs/guides/abstraction.md | 149 - .../guides/ci-integration/1-github-actions.md | 166 - .../guides/ci-integration/_2-gitlab-ci.md | 12 - .../guides/ci-integration/_3-jenkins-ci.md | 12 - .../guides/ci-integration/_category_.json | 4 - .../user_docs/guides/configuration.md | 129 - .../user_docs/guides/data-integration.md | 106 - .../user_docs/guides/gitops/_category_.json | 4 - .../4-how-to/4-share_your_pkg.md | 73 - .../4-how-to/5-share_your_pkg_docker.md | 65 - .../4-how-to/6-push_github_action.md | 83 - .../4-how-to/_category_.json | 4 - .../user_docs/guides/schema-definition.md | 117 - .../guides/secret-management/1-vault.md | 142 - .../guides/secret-management/_category_.json | 4 - .../3-mutate-manifests/4-kpt-kcl-sdk.md | 87 - .../3-mutate-manifests/_category_.json | 4 - .../guides/working-with-k8s/_category_.json | 4 - .../guides/working-with-k8s/index.md | 1 - .../working-with-konfig/4-best-practice.md | 271 -- .../working-with-konfig/_category_.json | 4 - .../working-with-kusion/_category_.json | 4 - .../guides/working-with-kusion/index.md | 15 - .../user_docs/support/_category_.json | 4 - .../user_docs/support/faq-cli.md | 107 - .../user_docs/support/faq-yaml.md | 104 - .../{version-0.8.0.json => version-0.8.json} | 0 .../community/_category_.json | 0 .../community/contribute/_category_.json | 0 .../community/contribute/contribute-code.md | 0 .../community/contribute/contribute-docs.md | 0 .../community/contribute/contribute.md | 0 .../community/contribute/git-guideline.md | 0 .../community/intro/_category_.json | 0 .../community/intro/intro.md | 0 .../community/intro/license.md | 0 .../community/intro/support.md | 0 .../community/release-policy/_category_.json | 0 .../community/release-policy/index.md | 0 .../community/release-policy/kcl.md | 0 .../community/release-policy/roadmap.md | 0 .../reference/_category_.json | 0 .../reference/cheatsheets/_category_.json | 0 .../reference/cheatsheets/index.md | 0 .../reference/index.md | 0 .../reference/lang/_category_.json | 0 .../reference/lang/codelab/_category_.json | 0 .../reference/lang/codelab/collaborative.md | 0 .../reference/lang/codelab/index.md | 0 .../reference/lang/codelab/schema.md | 0 .../reference/lang/codelab/simple.md | 0 .../reference/lang/error/_category_.json | 0 .../reference/lang/error/exception.md | 0 .../reference/lang/error/index.md | 0 .../reference/lang/index.md | 0 .../reference/lang/spec/_category_.json | 0 .../reference/lang/spec/codestyle.md | 0 .../reference/lang/spec/datatypes.md | 0 .../reference/lang/spec/error.md | 0 .../reference/lang/spec/expressions.md | 0 .../reference/lang/spec/index.md | 0 .../reference/lang/spec/kcl-spec.md | 0 .../reference/lang/spec/lexical.md | 0 .../reference/lang/spec/modules.md | 0 .../reference/lang/spec/schema.md | 0 .../reference/lang/spec/statements.md | 0 .../reference/lang/spec/variables.md | 0 .../reference/lang/tour.md | 0 .../reference/lang/types/_category_.json | 0 .../reference/lang/types/types.md | 0 .../reference/model/_category_.json | 0 .../reference/model/base64.md | 0 .../reference/model/builtin.md | 0 .../reference/model/crypto.md | 0 .../reference/model/datetime.md | 0 .../reference/model/file.md | 0 .../reference/model/json.md | 0 .../reference/model/manifests.md | 0 .../reference/model/math.md | 0 .../reference/model/net.md | 0 .../reference/model/overview.md | 0 .../reference/model/regex.md | 0 .../reference/model/units.md | 0 .../reference/model/yaml.md | 0 .../reference/plugin/_category_.json | 0 .../reference/plugin/overview.md | 0 .../reference/xlang-api/_category_.json | 0 .../reference/xlang-api/go-api.md | 0 .../reference/xlang-api/java-api.md | 0 .../reference/xlang-api/overview.md | 0 .../reference/xlang-api/python-api.md | 0 .../reference/xlang-api/rest-api.md | 0 .../tools/Ide/_category_.json | 0 .../tools/Ide/index.md | 0 .../tools/Ide/intellij.md | 0 .../tools/Ide/neovim.md | 0 .../tools/Ide/vs-code.md | 0 .../tools/_category_.json | 0 .../tools/cli/_category_.json | 0 .../tools/cli/index.md | 0 .../tools/cli/kcl/_category_.json | 0 .../tools/cli/kcl/docgen.md | 0 .../tools/cli/kcl/fmt.md | 0 .../tools/cli/kcl/import.md | 0 .../tools/cli/kcl/index.md | 0 .../tools/cli/kcl/lint.md | 0 .../tools/cli/kcl/overview.md | 0 .../tools/cli/kcl/run.md | 0 .../tools/cli/kcl/test.md | 0 .../tools/cli/kcl/vet.md | 0 .../tools/cli/openapi/_category_.json | 0 .../tools/cli/openapi/crd-to-kcl.md | 0 .../tools/cli/openapi/openapi-to-kcl.md | 0 .../tools/cli/openapi/spec.md | 0 .../cli/package-management/_category_.json | 0 .../command-reference/1.init.md | 0 .../command-reference/10.help.md | 0 .../command-reference/2.add.md | 0 .../command-reference/3.pkg.md | 0 .../command-reference/4.metadata.md | 0 .../command-reference/6.login.md | 0 .../command-reference/7.logout.md | 0 .../command-reference/8.push.md | 0 .../command-reference/9.pull.md | 0 .../command-reference/_category_.json | 0 .../user_docs/concepts/_category_.json | 0 .../user_docs/concepts/concepts.md | 0 .../user_docs/concepts/package-and-module.md | 0 .../user_docs/concepts/type-and-definition.md | 0 .../user_docs/getting-started/_category_.json | 0 .../user_docs/getting-started/index.md | 0 .../user_docs/getting-started/install.md | 0 .../user_docs/getting-started/intro.md | 0 .../getting-started/kcl-quick-start.md | 0 .../user_docs/guides/_category_.json | 0 .../user_docs/guides/abstraction.md | 0 .../user_docs/guides/automation.md | 0 .../guides/ci-integration/1-github-actions.md | 0 .../guides/ci-integration/_2-gitlab-ci.md | 0 .../guides/ci-integration/_3-jenkins-ci.md | 0 .../guides/ci-integration/_category_.json | 0 .../user_docs/guides/configuration.md | 0 .../user_docs/guides/data-integration.md | 0 .../user_docs/guides/gitops/1-argocd.md | 0 .../user_docs/guides/gitops/2-fluxcd.md | 0 .../user_docs/guides/gitops/_category_.json | 0 .../user_docs/guides/index.md | 0 .../package-management/3-quick-start.md | 0 .../4-how-to/4-share_your_pkg.md | 0 .../4-how-to/5-share_your_pkg_docker.md | 0 .../4-how-to/6-push_github_action.md | 0 .../4-how-to/7-publish_pkg_to_ah.md | 0 .../package-management/4-how-to/8-kcl_mod.md | 0 .../package-management/4-how-to/9-kpm_oci.md | 0 .../4-how-to/_category_.json | 0 .../guides/package-management/_category_.json | 0 .../user_docs/guides/schema-definition.md | 0 .../guides/secret-management/1-vault.md | 0 .../guides/secret-management/_category_.json | 0 .../user_docs/guides/validation.md | 0 .../guides/working-with-k8s/0-overview.md | 0 .../1-adopt-from-kubernetes.md | 0 .../2-generate-k8s-manifests.md | 0 .../1-kubectl-kcl-plugin.md | 0 .../3-mutate-manifests/2-helm-kcl-plugin.md | 0 .../3-kustomize-kcl-plugin.md | 0 .../3-mutate-manifests/4-kpt-kcl-sdk.md | 0 .../3-mutate-manifests/_category_.json | 0 .../working-with-k8s/4-publish-modules.md | 0 .../guides/working-with-k8s/_category_.json | 0 .../guides/working-with-k8s/index.md | 0 .../guides/working-with-konfig/1-overview.md | 0 .../guides/working-with-konfig/2-structure.md | 0 .../working-with-konfig/3-quick-start.md | 0 .../working-with-konfig/4-best-practice.md | 0 .../working-with-konfig/_category_.json | 0 .../working-with-kubevela/_category_.json | 0 .../guides/working-with-kubevela/index.md | 0 .../working-with-kusion/_category_.json | 0 .../guides/working-with-kusion/index.md | 0 .../user_docs/support/_category_.json | 0 .../user_docs/support/faq-cli.md | 0 .../user_docs/support/faq-install.md | 0 .../user_docs/support/faq-kcl.md | 0 .../user_docs/support/faq-yaml.md | 0 .../user_docs/support/support.md | 0 package.json | 2 +- static/stack/ci-test/settings.yaml | 0 static/stack/ci-test/stdout.golden.yaml | 24 - static/stack/kcl.yaml | 3 - static/stack/main.k | 22 - static/stack/project.yaml | 3 - static/stack/stack.yaml | 1 - .../reference/lang/error/exception.md | 1427 ------- .../reference/lang/spec/codestyle.md | 608 --- .../reference/lang/spec/datatypes.md | 452 --- .../reference/lang/spec/error.md | 53 - .../reference/lang/spec/expressions.md | 915 ----- .../reference/lang/spec/kcl-spec.md | 343 -- .../reference/lang/spec/modules.md | 621 --- .../reference/lang/spec/schema.md | 916 ----- .../reference/lang/spec/statements.md | 185 - .../reference/lang/spec/variables.md | 68 - .../version-0.5.0/reference/lang/tour.md | 3317 ---------------- .../version-0.5.0/reference/model/datetime.md | 31 - .../version-0.5.0/reference/model/json.md | 40 - .../version-0.5.0/reference/model/math.md | 102 - .../reference/plugin/project_context.md | 59 - .../reference/xlang-api/go-api.md | 665 ---- .../reference/xlang-api/rest-api.md | 443 --- .../version-0.5.0/tools/Ide/intellij.md | 3 - .../version-0.5.0/tools/Ide/vs-code.md | 55 - .../version-0.5.0/tools/cli/kcl/fmt.md | 70 - .../version-0.5.0/tools/cli/kcl/lint.md | 56 - .../version-0.5.0/tools/cli/kcl/overview.md | 18 - .../tools/cli/openapi/quick-start.md | 49 - .../version-0.5.0/tools/cli/openapi/spec.md | 438 --- .../user_docs/getting-started/install.md | 140 - .../user_docs/guides/abstraction.md | 147 - .../user_docs/guides/automation.md | 185 - .../guides/ci-integration/1-github-actions.md | 162 - .../guides/ci-integration/2-gitlab-ci.md | 135 - .../guides/ci-integration/_2-gitlab-ci.md | 12 - .../guides/ci-integration/_3-jenkins-ci.md | 12 - .../guides/ci-integration/_category_.json | 4 - .../user_docs/guides/configuration.md | 125 - .../user_docs/guides/data-integration.md | 102 - .../user_docs/guides/gitops/1-quick-start.md | 159 - .../user_docs/guides/gitops/_category_.json | 4 - .../package-management/2-installation.md | 55 - .../package-management/3-quick-start.md | 108 - .../4-how-to/4-share_your_pkg.md | 73 - .../4-how-to/5-share_your_pkg_docker.md | 66 - .../4-how-to/6-push_github_action.md | 81 - .../user_docs/guides/schema-definition.md | 135 - .../user_docs/guides/validation.md | 95 - .../1-adopt-from-kubernetes.md | 62 - .../3-kustomize-kcl-plugin.md | 104 - .../5-helmfile-kcl-plugin.md | 94 - .../3-mutate-manifests/_category_.json | 4 - .../guides/working-with-k8s/_category_.json | 4 - .../guides/working-with-k8s/index.md | 1 - .../working-with-konfig/_category_.json | 4 - .../working-with-kusion/_category_.json | 4 - .../reference/lang/error/exception.md | 1427 ------- .../reference/lang/spec/codestyle.md | 608 --- .../reference/lang/spec/datatypes.md | 452 --- .../reference/lang/spec/error.md | 53 - .../reference/lang/spec/expressions.md | 915 ----- .../reference/lang/spec/kcl-spec.md | 343 -- .../reference/lang/spec/modules.md | 621 --- .../reference/lang/spec/schema.md | 916 ----- .../reference/lang/spec/statements.md | 185 - .../reference/lang/spec/variables.md | 68 - .../version-0.5.1/reference/lang/tour.md | 3324 ----------------- .../version-0.5.1/reference/model/datetime.md | 31 - .../version-0.5.1/reference/model/json.md | 40 - .../version-0.5.1/reference/model/math.md | 102 - .../reference/plugin/project_context.md | 59 - .../reference/xlang-api/go-api.md | 665 ---- .../reference/xlang-api/rest-api.md | 443 --- .../version-0.5.1/tools/Ide/index.md | 6 - .../version-0.5.1/tools/Ide/intellij.md | 3 - .../version-0.5.1/tools/Ide/vs-code.md | 55 - .../version-0.5.1/tools/cli/kcl/fmt.md | 70 - .../version-0.5.1/tools/cli/kcl/lint.md | 56 - .../tools/cli/openapi/quick-start.md | 49 - .../version-0.5.1/tools/cli/openapi/spec.md | 438 --- .../user_docs/getting-started/install.md | 140 - .../user_docs/getting-started/intro.md | 199 - .../user_docs/guides/abstraction.md | 147 - .../user_docs/guides/automation.md | 185 - .../guides/ci-integration/1-github-actions.md | 162 - .../guides/ci-integration/2-gitlab-ci.md | 135 - .../guides/ci-integration/_3-jenkins-ci.md | 12 - .../guides/ci-integration/_category_.json | 4 - .../user_docs/guides/configuration.md | 125 - .../user_docs/guides/data-integration.md | 102 - .../user_docs/guides/gitops/1-quick-start.md | 159 - .../user_docs/guides/gitops/_category_.json | 4 - .../package-management/2-installation.md | 55 - .../package-management/3-quick-start.md | 108 - .../4-how-to/4-share_your_pkg.md | 73 - .../4-how-to/5-share_your_pkg_docker.md | 66 - .../4-how-to/6-push_github_action.md | 81 - .../user_docs/guides/schema-definition.md | 135 - .../guides/secret-management/_category_.json | 4 - .../user_docs/guides/validation.md | 95 - .../1-adopt-from-kubernetes.md | 62 - .../3-kustomize-kcl-plugin.md | 104 - .../5-helmfile-kcl-plugin.md | 94 - .../3-mutate-manifests/_category_.json | 4 - .../guides/working-with-k8s/_category_.json | 4 - .../guides/working-with-k8s/index.md | 1 - .../guides/working-with-konfig/1-overview.md | 30 - .../guides/working-with-konfig/2-structure.md | 98 - .../working-with-konfig/3-quick-start.md | 198 - .../working-with-konfig/_category_.json | 4 - .../working-with-kusion/_category_.json | 4 - .../user_docs/support/faq-install.md | 29 - .../user_docs/support/faq-kcl.md | 2341 ------------ .../community/contribute/git-guideline.md | 130 - .../community/release-policy/kcl.md | 39 - .../community/release-policy/roadmap.md | 3 - .../reference/lang/error/exception.md | 1427 ------- .../reference/lang/spec/codestyle.md | 608 --- .../reference/lang/spec/datatypes.md | 452 --- .../reference/lang/spec/error.md | 53 - .../reference/lang/spec/expressions.md | 915 ----- .../reference/lang/spec/kcl-spec.md | 343 -- .../reference/lang/spec/modules.md | 621 --- .../reference/lang/spec/schema.md | 916 ----- .../reference/lang/spec/statements.md | 185 - .../reference/lang/spec/variables.md | 68 - .../version-0.5.2/reference/lang/tour.md | 3324 ----------------- .../version-0.5.2/reference/model/datetime.md | 31 - .../version-0.5.2/reference/model/index.md | 3 - .../version-0.5.2/reference/model/json.md | 40 - .../version-0.5.2/reference/model/math.md | 102 - .../version-0.5.2/reference/model/overview.md | 15 - .../version-0.5.2/reference/model/yaml.md | 39 - .../package-management/_category_.json | 4 - .../command-reference/1.init.md | 45 - .../command-reference/10.help.md | 21 - .../command-reference/2.add.md | 53 - .../command-reference/3.pkg.md | 33 - .../command-reference/4.metadata.md | 41 - .../command-reference/5.run.md | 69 - .../command-reference/6.login.md | 68 - .../command-reference/7.logout.md | 27 - .../command-reference/8.push.md | 46 - .../command-reference/9.pull.md | 42 - .../command-reference/index.md | 36 - .../reference/plugin/overview.md | 187 - .../reference/plugin/project_context.md | 59 - .../reference/xlang-api/go-api.md | 665 ---- .../reference/xlang-api/rest-api.md | 443 --- .../version-0.5.2/tools/Ide/index.md | 6 - .../version-0.5.2/tools/Ide/intellij.md | 3 - .../version-0.5.2/tools/Ide/vs-code.md | 55 - .../version-0.5.2/tools/cli/kcl/docgen.md | 317 -- .../version-0.5.2/tools/cli/kcl/fmt.md | 70 - .../version-0.5.2/tools/cli/kcl/index.md | 3 - .../version-0.5.2/tools/cli/kcl/lint.md | 56 - .../version-0.5.2/tools/cli/kcl/test.md | 7 - .../version-0.5.2/tools/cli/kcl/vet.md | 87 - .../tools/cli/openapi/crd-to-kcl.md | 118 - .../tools/cli/openapi/openapi-to-kcl.md | 64 - .../tools/cli/openapi/quick-start.md | 49 - .../version-0.5.2/tools/cli/openapi/spec.md | 438 --- .../user_docs/concepts/concepts.md | 3 - .../user_docs/getting-started/index.md | 3 - .../user_docs/getting-started/install.md | 140 - .../user_docs/getting-started/intro.md | 199 - .../_working-with-terraform/1-overview.md | 8 - .../_working-with-terraform/2-abstraction.md | 8 - .../_working-with-terraform/3-coverter.md | 8 - .../_working-with-terraform/_category_.json | 4 - .../guides/ci-integration/_3-jenkins-ci.md | 12 - .../guides/ci-integration/_category_.json | 4 - .../user_docs/guides/gitops/_category_.json | 4 - .../version-0.5.2/user_docs/guides/index.md | 1 - .../guides/package-management/1-overview.md | 3 - .../4-how-to/4-share_your_pkg.md | 73 - .../4-how-to/5-share_your_pkg_docker.md | 66 - .../4-how-to/6-push_github_action.md | 81 - .../guides/secret-management/_category_.json | 4 - .../2-generate-k8s-manifests.md | 249 -- .../1-kubectl-kcl-plugin.md | 100 - .../3-mutate-manifests/2-helm-kcl-plugin.md | 100 - .../3-mutate-manifests/4-kpt-kcl-sdk.md | 96 - .../3-mutate-manifests/_category_.json | 4 - .../guides/working-with-k8s/_category_.json | 4 - .../guides/working-with-k8s/index.md | 1 - .../guides/working-with-konfig/1-overview.md | 30 - .../guides/working-with-konfig/2-structure.md | 98 - .../working-with-konfig/3-quick-start.md | 198 - .../working-with-konfig/_category_.json | 4 - .../working-with-kusion/_category_.json | 4 - .../user_docs/support/faq-install.md | 29 - .../user_docs/support/faq-kcl.md | 2341 ------------ .../user_docs/support/support.md | 3 - .../community/contribute/git-guideline.md | 130 - .../community/release-policy/kcl.md | 39 - .../community/release-policy/roadmap.md | 3 - .../reference/lang/error/exception.md | 1427 ------- .../reference/lang/spec/codestyle.md | 608 --- .../reference/lang/spec/datatypes.md | 452 --- .../reference/lang/spec/error.md | 53 - .../reference/lang/spec/expressions.md | 915 ----- .../reference/lang/spec/kcl-spec.md | 343 -- .../reference/lang/spec/modules.md | 621 --- .../reference/lang/spec/schema.md | 916 ----- .../reference/lang/spec/statements.md | 185 - .../reference/lang/spec/variables.md | 68 - .../version-0.5.3/reference/lang/tour.md | 3324 ----------------- .../version-0.5.3/reference/model/crypto.md | 43 - .../version-0.5.3/reference/model/datetime.md | 31 - .../version-0.5.3/reference/model/index.md | 3 - .../version-0.5.3/reference/model/json.md | 40 - .../version-0.5.3/reference/model/math.md | 102 - .../version-0.5.3/reference/model/overview.md | 15 - .../version-0.5.3/reference/model/yaml.md | 39 - .../package-management/_category_.json | 4 - .../command-reference/1.init.md | 45 - .../command-reference/10.help.md | 21 - .../command-reference/2.add.md | 53 - .../command-reference/3.pkg.md | 33 - .../command-reference/4.metadata.md | 41 - .../command-reference/5.run.md | 69 - .../command-reference/6.login.md | 68 - .../command-reference/7.logout.md | 27 - .../command-reference/8.push.md | 46 - .../command-reference/9.pull.md | 42 - .../command-reference/index.md | 36 - .../version-0.5.3/reference/plugin/index.md | 1 - .../reference/plugin/overview.md | 187 - .../reference/plugin/project_context.md | 59 - .../reference/xlang-api/go-api.md | 665 ---- .../reference/xlang-api/index.md | 1 - .../reference/xlang-api/overview.md | 293 -- .../reference/xlang-api/rest-api.md | 443 --- .../version-0.5.3/tools/Ide/index.md | 6 - .../version-0.5.3/tools/Ide/intellij.md | 3 - .../version-0.5.3/tools/Ide/vs-code.md | 55 - .../version-0.5.3/tools/cli/kcl/docgen.md | 317 -- .../version-0.5.3/tools/cli/kcl/fmt.md | 70 - .../version-0.5.3/tools/cli/kcl/index.md | 3 - .../version-0.5.3/tools/cli/kcl/lint.md | 56 - .../version-0.5.3/tools/cli/kcl/overview.md | 58 - .../version-0.5.3/tools/cli/kcl/test.md | 7 - .../version-0.5.3/tools/cli/kcl/vet.md | 87 - .../tools/cli/openapi/crd-to-kcl.md | 118 - .../version-0.5.3/tools/cli/openapi/index.md | 3 - .../tools/cli/openapi/openapi-to-kcl.md | 64 - .../tools/cli/openapi/quick-start.md | 49 - .../version-0.5.3/tools/cli/openapi/spec.md | 438 --- .../user_docs/concepts/concepts.md | 3 - .../user_docs/getting-started/index.md | 3 - .../user_docs/getting-started/install.md | 140 - .../user_docs/getting-started/intro.md | 199 - .../_working-with-terraform/1-overview.md | 8 - .../_working-with-terraform/2-abstraction.md | 8 - .../_working-with-terraform/3-coverter.md | 8 - .../_working-with-terraform/_category_.json | 4 - .../guides/ci-integration/_3-jenkins-ci.md | 12 - .../guides/ci-integration/_category_.json | 4 - .../user_docs/guides/gitops/_category_.json | 4 - .../version-0.5.3/user_docs/guides/index.md | 1 - .../guides/package-management/1-overview.md | 3 - .../4-how-to/4-share_your_pkg.md | 73 - .../4-how-to/5-share_your_pkg_docker.md | 66 - .../4-how-to/6-push_github_action.md | 81 - .../4-how-to/_category_.json | 4 - .../guides/secret-management/_category_.json | 4 - .../1-adopt-from-kubernetes.md | 66 - .../2-generate-k8s-manifests.md | 249 -- .../1-kubectl-kcl-plugin.md | 100 - .../3-mutate-manifests/2-helm-kcl-plugin.md | 100 - .../3-mutate-manifests/4-kpt-kcl-sdk.md | 96 - .../5-helmfile-kcl-plugin.md | 113 - .../3-mutate-manifests/_category_.json | 4 - .../guides/working-with-k8s/_category_.json | 4 - .../guides/working-with-k8s/index.md | 1 - .../guides/working-with-konfig/1-overview.md | 30 - .../guides/working-with-konfig/2-structure.md | 98 - .../working-with-konfig/3-quick-start.md | 198 - .../working-with-konfig/_category_.json | 4 - .../working-with-kusion/_category_.json | 4 - .../user_docs/support/faq-install.md | 29 - .../user_docs/support/faq-kcl.md | 2341 ------------ .../user_docs/support/support.md | 3 - .../community/contribute/_category_.json | 4 - .../community/contribute/contribute-code.md | 19 - .../community/contribute/contribute-docs.md | 52 - .../community/contribute/contribute.md | 3 - .../community/contribute/git-guideline.md | 130 - .../community/intro/_category_.json | 4 - .../version-0.5.4/community/intro/intro.md | 9 - .../version-0.5.4/community/intro/license.md | 211 -- .../version-0.5.4/community/intro/support.md | 21 - .../community/release-policy/_category_.json | 4 - .../community/release-policy/index.md | 3 - .../community/release-policy/kcl.md | 39 - .../community/release-policy/roadmap.md | 3 - .../_advanced-concepts/_category_.json | 4 - .../_advanced-concepts/build_cache.md | 1 - .../version-0.5.4/reference/_category_.json | 4 - .../reference/cheatsheets/_category_.json | 4 - .../reference/cheatsheets/index.md | 5 - .../reference/lang/_category_.json | 4 - .../reference/lang/codelab/_category_.json | 4 - .../reference/lang/codelab/collaborative.md | 345 -- .../reference/lang/codelab/index.md | 1 - .../reference/lang/codelab/schema.md | 817 ---- .../reference/lang/codelab/simple.md | 495 --- .../reference/lang/error/_category_.json | 4 - .../reference/lang/error/exception.md | 1427 ------- .../reference/lang/error/index.md | 1 - .../reference/lang/spec/_category_.json | 4 - .../reference/lang/spec/codestyle.md | 608 --- .../reference/lang/spec/datatypes.md | 452 --- .../reference/lang/spec/error.md | 53 - .../reference/lang/spec/expressions.md | 915 ----- .../reference/lang/spec/index.md | 1 - .../reference/lang/spec/kcl-spec.md | 343 -- .../reference/lang/spec/lexical.md | 213 -- .../reference/lang/spec/modules.md | 621 --- .../reference/lang/spec/schema.md | 916 ----- .../reference/lang/spec/statements.md | 185 - .../reference/lang/spec/variables.md | 68 - .../version-0.5.4/reference/lang/tour.md | 3324 ----------------- .../reference/lang/types/_category_.json | 4 - .../reference/lang/types/types.md | 1381 ------- .../reference/model/_category_.json | 4 - .../version-0.5.4/reference/model/base64.md | 19 - .../version-0.5.4/reference/model/builtin.md | 386 -- .../version-0.5.4/reference/model/crypto.md | 43 - .../version-0.5.4/reference/model/datetime.md | 31 - .../version-0.5.4/reference/model/index.md | 3 - .../version-0.5.4/reference/model/json.md | 40 - .../reference/model/manifests.md | 89 - .../version-0.5.4/reference/model/math.md | 102 - .../version-0.5.4/reference/model/net.md | 103 - .../version-0.5.4/reference/model/overview.md | 15 - .../version-0.5.4/reference/model/regex.md | 43 - .../version-0.5.4/reference/model/units.md | 41 - .../version-0.5.4/reference/model/yaml.md | 39 - .../package-management/_category_.json | 4 - .../command-reference/1.init.md | 45 - .../command-reference/10.help.md | 21 - .../command-reference/2.add.md | 53 - .../command-reference/3.pkg.md | 33 - .../command-reference/4.metadata.md | 41 - .../command-reference/5.run.md | 69 - .../command-reference/6.login.md | 68 - .../command-reference/7.logout.md | 27 - .../command-reference/8.push.md | 46 - .../command-reference/9.pull.md | 42 - .../command-reference/_category_.json | 4 - .../command-reference/index.md | 36 - .../reference/plugin/_category_.json | 4 - .../version-0.5.4/reference/plugin/index.md | 1 - .../reference/plugin/overview.md | 187 - .../reference/plugin/project_context.md | 59 - .../reference/xlang-api/_category_.json | 4 - .../reference/xlang-api/go-api.md | 665 ---- .../reference/xlang-api/index.md | 1 - .../reference/xlang-api/java-api.md | 7 - .../reference/xlang-api/overview.md | 293 -- .../reference/xlang-api/python-api.md | 7 - .../reference/xlang-api/rest-api.md | 443 --- .../version-0.5.4/tools/Ide/_category_.json | 4 - .../version-0.5.4/tools/Ide/index.md | 6 - .../version-0.5.4/tools/Ide/intellij.md | 3 - .../version-0.5.4/tools/Ide/vs-code.md | 55 - .../version-0.5.4/tools/_category_.json | 4 - .../version-0.5.4/tools/cli/_category_.json | 4 - .../version-0.5.4/tools/cli/index.md | 3 - .../tools/cli/kcl/_category_.json | 4 - .../version-0.5.4/tools/cli/kcl/docgen.md | 317 -- .../version-0.5.4/tools/cli/kcl/fmt.md | 70 - .../version-0.5.4/tools/cli/kcl/index.md | 3 - .../version-0.5.4/tools/cli/kcl/lint.md | 56 - .../version-0.5.4/tools/cli/kcl/overview.md | 58 - .../version-0.5.4/tools/cli/kcl/test.md | 7 - .../version-0.5.4/tools/cli/kcl/vet.md | 87 - .../tools/cli/openapi/_category_.json | 4 - .../tools/cli/openapi/crd-to-kcl.md | 118 - .../version-0.5.4/tools/cli/openapi/index.md | 3 - .../tools/cli/openapi/openapi-to-kcl.md | 64 - .../tools/cli/openapi/quick-start.md | 49 - .../version-0.5.4/tools/cli/openapi/spec.md | 438 --- .../user_docs/concepts/_category_.json | 4 - .../user_docs/concepts/concepts.md | 3 - .../user_docs/concepts/package-and-module.md | 156 - .../user_docs/getting-started/_category_.json | 4 - .../user_docs/getting-started/index.md | 3 - .../user_docs/getting-started/install.md | 140 - .../user_docs/getting-started/intro.md | 199 - .../getting-started/kcl-quick-start.md | 166 - .../user_docs/guides/_category_.json | 4 - .../_working-with-terraform/1-overview.md | 8 - .../_working-with-terraform/2-abstraction.md | 8 - .../_working-with-terraform/3-coverter.md | 8 - .../_working-with-terraform/_category_.json | 4 - .../user_docs/guides/automation.md | 189 - .../guides/ci-integration/_3-jenkins-ci.md | 12 - .../guides/ci-integration/_category_.json | 4 - .../user_docs/guides/configuration.md | 129 - .../user_docs/guides/gitops/_category_.json | 4 - .../version-0.5.4/user_docs/guides/index.md | 1 - .../guides/package-management/1-overview.md | 3 - .../package-management/2-installation.md | 55 - .../package-management/3-quick-start.md | 112 - .../4-how-to/4-share_your_pkg.md | 73 - .../4-how-to/5-share_your_pkg_docker.md | 66 - .../4-how-to/6-push_github_action.md | 81 - .../4-how-to/_category_.json | 4 - .../guides/package-management/_category_.json | 4 - .../guides/secret-management/_category_.json | 4 - .../user_docs/guides/validation.md | 99 - .../1-adopt-from-kubernetes.md | 66 - .../2-generate-k8s-manifests.md | 249 -- .../1-kubectl-kcl-plugin.md | 100 - .../3-mutate-manifests/2-helm-kcl-plugin.md | 100 - .../3-kustomize-kcl-plugin.md | 105 - .../3-mutate-manifests/4-kpt-kcl-sdk.md | 96 - .../3-mutate-manifests/_category_.json | 4 - .../guides/working-with-k8s/_category_.json | 4 - .../guides/working-with-k8s/index.md | 1 - .../guides/working-with-konfig/1-overview.md | 30 - .../guides/working-with-konfig/2-structure.md | 98 - .../working-with-konfig/3-quick-start.md | 198 - .../working-with-konfig/4-best-practice.md | 449 --- .../working-with-konfig/_category_.json | 4 - .../working-with-kusion/_category_.json | 4 - .../guides/working-with-kusion/index.md | 15 - .../user_docs/support/_category_.json | 4 - .../user_docs/support/faq-cli.md | 107 - .../user_docs/support/faq-install.md | 29 - .../user_docs/support/faq-kcl.md | 2341 ------------ .../user_docs/support/faq-yaml.md | 102 - .../user_docs/support/support.md | 3 - .../community/contribute/_category_.json | 4 - .../community/contribute/contribute-code.md | 19 - .../community/contribute/contribute-docs.md | 52 - .../community/contribute/contribute.md | 3 - .../community/contribute/git-guideline.md | 130 - .../community/intro/_category_.json | 4 - .../version-0.5.5/community/intro/intro.md | 9 - .../version-0.5.5/community/intro/license.md | 211 -- .../version-0.5.5/community/intro/support.md | 21 - .../community/release-policy/_category_.json | 4 - .../community/release-policy/index.md | 3 - .../community/release-policy/kcl.md | 39 - .../community/release-policy/roadmap.md | 3 - .../_advanced-concepts/_category_.json | 4 - .../_advanced-concepts/build_cache.md | 1 - .../version-0.5.5/reference/_category_.json | 4 - .../reference/cheatsheets/_category_.json | 4 - .../reference/cheatsheets/index.md | 5 - .../reference/lang/_category_.json | 4 - .../reference/lang/codelab/_category_.json | 4 - .../reference/lang/codelab/collaborative.md | 345 -- .../reference/lang/codelab/index.md | 1 - .../reference/lang/codelab/schema.md | 817 ---- .../reference/lang/codelab/simple.md | 495 --- .../reference/lang/error/_category_.json | 4 - .../reference/lang/error/exception.md | 1427 ------- .../reference/lang/error/index.md | 1 - .../reference/lang/spec/_category_.json | 4 - .../reference/lang/spec/codestyle.md | 608 --- .../reference/lang/spec/datatypes.md | 452 --- .../reference/lang/spec/error.md | 53 - .../reference/lang/spec/index.md | 1 - .../reference/lang/spec/kcl-spec.md | 343 -- .../reference/lang/spec/lexical.md | 213 -- .../reference/lang/spec/modules.md | 621 --- .../reference/lang/spec/schema.md | 916 ----- .../reference/lang/spec/statements.md | 185 - .../reference/lang/spec/variables.md | 68 - .../version-0.5.5/reference/lang/tour.md | 3324 ----------------- .../reference/lang/types/_category_.json | 4 - .../reference/lang/types/types.md | 1381 ------- .../reference/model/_category_.json | 4 - .../version-0.5.5/reference/model/base64.md | 19 - .../version-0.5.5/reference/model/builtin.md | 386 -- .../version-0.5.5/reference/model/crypto.md | 43 - .../version-0.5.5/reference/model/datetime.md | 31 - .../version-0.5.5/reference/model/index.md | 3 - .../version-0.5.5/reference/model/json.md | 40 - .../reference/model/manifests.md | 89 - .../version-0.5.5/reference/model/math.md | 102 - .../version-0.5.5/reference/model/net.md | 103 - .../version-0.5.5/reference/model/overview.md | 15 - .../version-0.5.5/reference/model/regex.md | 43 - .../version-0.5.5/reference/model/units.md | 41 - .../version-0.5.5/reference/model/yaml.md | 39 - .../package-management/_category_.json | 4 - .../command-reference/1.init.md | 45 - .../command-reference/10.help.md | 21 - .../command-reference/2.add.md | 53 - .../command-reference/3.pkg.md | 33 - .../command-reference/4.metadata.md | 41 - .../command-reference/5.run.md | 69 - .../command-reference/6.login.md | 68 - .../command-reference/7.logout.md | 27 - .../command-reference/8.push.md | 46 - .../command-reference/9.pull.md | 42 - .../command-reference/_category_.json | 4 - .../command-reference/index.md | 36 - .../reference/plugin/_category_.json | 4 - .../version-0.5.5/reference/plugin/index.md | 1 - .../reference/plugin/overview.md | 187 - .../reference/plugin/project_context.md | 59 - .../reference/xlang-api/_category_.json | 4 - .../reference/xlang-api/go-api.md | 665 ---- .../reference/xlang-api/index.md | 1 - .../reference/xlang-api/java-api.md | 7 - .../reference/xlang-api/overview.md | 293 -- .../reference/xlang-api/python-api.md | 7 - .../version-0.5.5/tools/Ide/_category_.json | 4 - .../version-0.5.5/tools/Ide/index.md | 6 - .../version-0.5.5/tools/_category_.json | 4 - .../version-0.5.5/tools/cli/_category_.json | 4 - .../version-0.5.5/tools/cli/index.md | 3 - .../tools/cli/kcl/_category_.json | 4 - .../version-0.5.5/tools/cli/kcl/docgen.md | 317 -- .../version-0.5.5/tools/cli/kcl/index.md | 3 - .../version-0.5.5/tools/cli/kcl/overview.md | 58 - .../version-0.5.5/tools/cli/kcl/test.md | 7 - .../version-0.5.5/tools/cli/kcl/vet.md | 87 - .../tools/cli/openapi/_category_.json | 4 - .../tools/cli/openapi/crd-to-kcl.md | 118 - .../version-0.5.5/tools/cli/openapi/index.md | 3 - .../tools/cli/openapi/openapi-to-kcl.md | 64 - .../user_docs/concepts/_category_.json | 4 - .../user_docs/concepts/concepts.md | 3 - .../user_docs/concepts/package-and-module.md | 156 - .../user_docs/getting-started/_category_.json | 4 - .../user_docs/getting-started/index.md | 3 - .../user_docs/getting-started/intro.md | 199 - .../getting-started/kcl-quick-start.md | 166 - .../user_docs/guides/_category_.json | 4 - .../_working-with-terraform/1-overview.md | 8 - .../_working-with-terraform/2-abstraction.md | 8 - .../_working-with-terraform/3-coverter.md | 8 - .../_working-with-terraform/_category_.json | 4 - .../user_docs/guides/automation.md | 189 - .../guides/ci-integration/_3-jenkins-ci.md | 12 - .../guides/ci-integration/_category_.json | 4 - .../user_docs/guides/configuration.md | 129 - .../user_docs/guides/gitops/1-quick-start.md | 163 - .../user_docs/guides/gitops/_category_.json | 4 - .../version-0.5.5/user_docs/guides/index.md | 1 - .../guides/package-management/1-overview.md | 3 - .../package-management/2-installation.md | 55 - .../package-management/3-quick-start.md | 112 - .../4-how-to/4-share_your_pkg.md | 73 - .../4-how-to/5-share_your_pkg_docker.md | 66 - .../4-how-to/6-push_github_action.md | 81 - .../4-how-to/_category_.json | 4 - .../guides/package-management/_category_.json | 4 - .../guides/secret-management/1-vault.md | 142 - .../guides/secret-management/_category_.json | 4 - .../user_docs/guides/validation.md | 99 - .../1-adopt-from-kubernetes.md | 66 - .../2-generate-k8s-manifests.md | 249 -- .../1-kubectl-kcl-plugin.md | 100 - .../3-mutate-manifests/2-helm-kcl-plugin.md | 100 - .../3-kustomize-kcl-plugin.md | 105 - .../3-mutate-manifests/4-kpt-kcl-sdk.md | 96 - .../5-helmfile-kcl-plugin.md | 113 - .../3-mutate-manifests/_category_.json | 4 - .../guides/working-with-k8s/_category_.json | 4 - .../guides/working-with-k8s/index.md | 1 - .../guides/working-with-konfig/1-overview.md | 30 - .../guides/working-with-konfig/2-structure.md | 98 - .../working-with-konfig/3-quick-start.md | 198 - .../working-with-konfig/4-best-practice.md | 449 --- .../working-with-konfig/_category_.json | 4 - .../working-with-kusion/_category_.json | 4 - .../guides/working-with-kusion/index.md | 15 - .../user_docs/support/_category_.json | 4 - .../user_docs/support/faq-cli.md | 107 - .../user_docs/support/faq-install.md | 29 - .../user_docs/support/faq-kcl.md | 2341 ------------ .../user_docs/support/faq-yaml.md | 102 - .../user_docs/support/support.md | 3 - .../community/contribute/_category_.json | 4 - .../community/contribute/contribute-code.md | 19 - .../community/contribute/contribute-docs.md | 52 - .../community/contribute/contribute.md | 3 - .../community/contribute/git-guideline.md | 130 - .../community/intro/_category_.json | 4 - .../version-0.5.6/community/intro/intro.md | 9 - .../version-0.5.6/community/intro/license.md | 211 -- .../version-0.5.6/community/intro/support.md | 21 - .../community/release-policy/_category_.json | 4 - .../community/release-policy/index.md | 3 - .../community/release-policy/kcl.md | 39 - .../community/release-policy/roadmap.md | 3 - .../_advanced-concepts/_category_.json | 4 - .../_advanced-concepts/build_cache.md | 1 - .../version-0.5.6/reference/_category_.json | 4 - .../reference/cheatsheets/_category_.json | 4 - .../reference/cheatsheets/index.md | 5 - .../reference/lang/_category_.json | 4 - .../reference/lang/codelab/_category_.json | 4 - .../reference/lang/codelab/collaborative.md | 345 -- .../reference/lang/codelab/index.md | 1 - .../reference/lang/codelab/schema.md | 817 ---- .../reference/lang/codelab/simple.md | 495 --- .../reference/lang/error/_category_.json | 4 - .../reference/lang/error/index.md | 1 - .../reference/lang/spec/_category_.json | 4 - .../reference/lang/spec/codestyle.md | 608 --- .../reference/lang/spec/datatypes.md | 452 --- .../reference/lang/spec/error.md | 53 - .../reference/lang/spec/index.md | 1 - .../reference/lang/spec/kcl-spec.md | 343 -- .../reference/lang/spec/lexical.md | 213 -- .../reference/lang/spec/modules.md | 621 --- .../reference/lang/spec/schema.md | 916 ----- .../reference/lang/spec/statements.md | 185 - .../reference/lang/spec/variables.md | 68 - .../reference/lang/types/_category_.json | 4 - .../reference/lang/types/types.md | 1381 ------- .../reference/model/_category_.json | 4 - .../version-0.5.6/reference/model/base64.md | 19 - .../version-0.5.6/reference/model/builtin.md | 386 -- .../version-0.5.6/reference/model/crypto.md | 43 - .../version-0.5.6/reference/model/index.md | 3 - .../reference/model/manifests.md | 89 - .../version-0.5.6/reference/model/net.md | 103 - .../version-0.5.6/reference/model/overview.md | 15 - .../version-0.5.6/reference/model/regex.md | 43 - .../version-0.5.6/reference/model/units.md | 41 - .../version-0.5.6/reference/model/yaml.md | 39 - .../package-management/_category_.json | 4 - .../command-reference/1.init.md | 45 - .../command-reference/10.help.md | 21 - .../command-reference/2.add.md | 53 - .../command-reference/3.pkg.md | 33 - .../command-reference/4.metadata.md | 41 - .../command-reference/5.run.md | 69 - .../command-reference/6.login.md | 68 - .../command-reference/7.logout.md | 27 - .../command-reference/8.push.md | 46 - .../command-reference/9.pull.md | 42 - .../command-reference/_category_.json | 4 - .../command-reference/index.md | 36 - .../reference/plugin/_category_.json | 4 - .../version-0.5.6/reference/plugin/index.md | 1 - .../reference/plugin/overview.md | 187 - .../reference/plugin/project_context.md | 59 - .../reference/xlang-api/_category_.json | 4 - .../reference/xlang-api/go-api.md | 665 ---- .../reference/xlang-api/index.md | 1 - .../reference/xlang-api/java-api.md | 7 - .../reference/xlang-api/overview.md | 293 -- .../reference/xlang-api/python-api.md | 7 - .../version-0.5.6/tools/Ide/_category_.json | 4 - .../version-0.5.6/tools/Ide/index.md | 6 - .../version-0.5.6/tools/Ide/vs-code.md | 59 - .../version-0.5.6/tools/_category_.json | 4 - .../version-0.5.6/tools/cli/_category_.json | 4 - .../version-0.5.6/tools/cli/index.md | 3 - .../tools/cli/kcl/_category_.json | 4 - .../version-0.5.6/tools/cli/kcl/docgen.md | 317 -- .../version-0.5.6/tools/cli/kcl/index.md | 3 - .../version-0.5.6/tools/cli/kcl/overview.md | 58 - .../version-0.5.6/tools/cli/kcl/test.md | 7 - .../version-0.5.6/tools/cli/kcl/vet.md | 87 - .../tools/cli/openapi/_category_.json | 4 - .../tools/cli/openapi/crd-to-kcl.md | 118 - .../version-0.5.6/tools/cli/openapi/index.md | 3 - .../tools/cli/openapi/openapi-to-kcl.md | 64 - .../user_docs/concepts/_category_.json | 4 - .../user_docs/concepts/concepts.md | 3 - .../user_docs/concepts/package-and-module.md | 156 - .../user_docs/getting-started/_category_.json | 4 - .../user_docs/getting-started/index.md | 3 - .../user_docs/getting-started/install.md | 148 - .../user_docs/getting-started/intro.md | 199 - .../getting-started/kcl-quick-start.md | 166 - .../user_docs/guides/_category_.json | 4 - .../_working-with-terraform/1-overview.md | 8 - .../_working-with-terraform/2-abstraction.md | 8 - .../_working-with-terraform/3-coverter.md | 8 - .../_working-with-terraform/_category_.json | 4 - .../user_docs/guides/abstraction.md | 151 - .../user_docs/guides/automation.md | 189 - .../guides/ci-integration/1-github-actions.md | 166 - .../guides/ci-integration/2-gitlab-ci.md | 139 - .../guides/ci-integration/_3-jenkins-ci.md | 12 - .../guides/ci-integration/_category_.json | 4 - .../user_docs/guides/configuration.md | 129 - .../user_docs/guides/data-integration.md | 106 - .../user_docs/guides/gitops/1-quick-start.md | 163 - .../user_docs/guides/gitops/_category_.json | 4 - .../version-0.5.6/user_docs/guides/index.md | 1 - .../guides/package-management/1-overview.md | 3 - .../package-management/2-installation.md | 55 - .../package-management/3-quick-start.md | 112 - .../guides/package-management/_category_.json | 4 - .../user_docs/guides/schema-definition.md | 139 - .../guides/secret-management/1-vault.md | 142 - .../guides/secret-management/_category_.json | 4 - .../user_docs/guides/validation.md | 99 - .../1-adopt-from-kubernetes.md | 66 - .../2-generate-k8s-manifests.md | 249 -- .../1-kubectl-kcl-plugin.md | 100 - .../3-mutate-manifests/2-helm-kcl-plugin.md | 100 - .../3-kustomize-kcl-plugin.md | 105 - .../3-mutate-manifests/4-kpt-kcl-sdk.md | 96 - .../5-helmfile-kcl-plugin.md | 113 - .../3-mutate-manifests/_category_.json | 4 - .../guides/working-with-k8s/_category_.json | 4 - .../guides/working-with-k8s/index.md | 1 - .../guides/working-with-konfig/1-overview.md | 30 - .../guides/working-with-konfig/2-structure.md | 98 - .../working-with-konfig/3-quick-start.md | 198 - .../working-with-konfig/4-best-practice.md | 449 --- .../working-with-konfig/_category_.json | 4 - .../working-with-kusion/_category_.json | 4 - .../guides/working-with-kusion/index.md | 15 - .../user_docs/support/_category_.json | 4 - .../user_docs/support/faq-cli.md | 107 - .../user_docs/support/faq-install.md | 29 - .../user_docs/support/faq-kcl.md | 2341 ------------ .../user_docs/support/faq-yaml.md | 102 - .../user_docs/support/support.md | 3 - .../community/contribute/_category_.json | 0 .../community/contribute/contribute-code.md | 0 .../community/contribute/contribute-docs.md | 0 .../community/contribute/contribute.md | 0 .../community/contribute/git-guideline.md | 0 .../community/intro/_category_.json | 0 .../community/intro/intro.md | 0 .../community/intro/license.md | 0 .../community/intro/support.md | 0 .../community/release-policy/_category_.json | 0 .../community/release-policy/index.md | 0 .../community/release-policy/kcl.md | 0 .../community/release-policy/roadmap.md | 0 .../_advanced-concepts/_category_.json | 0 .../_advanced-concepts/build_cache.md | 0 .../reference/_category_.json | 0 .../reference/cheatsheets/_category_.json | 0 .../reference/cheatsheets/index.md | 0 .../reference/lang/_category_.json | 0 .../reference/lang/codelab/_category_.json | 0 .../reference/lang/codelab/collaborative.md | 0 .../reference/lang/codelab/index.md | 0 .../reference/lang/codelab/schema.md | 0 .../reference/lang/codelab/simple.md | 0 .../reference/lang/error/_category_.json | 0 .../reference/lang/error/exception.md | 0 .../reference/lang/error/index.md | 0 .../reference/lang/spec/_category_.json | 0 .../reference/lang/spec/codestyle.md | 0 .../reference/lang/spec/datatypes.md | 0 .../version-0.5}/reference/lang/spec/error.md | 0 .../reference/lang/spec/expressions.md | 0 .../reference/lang/spec/index.md | 0 .../reference/lang/spec/kcl-spec.md | 0 .../reference/lang/spec/lexical.md | 0 .../reference/lang/spec/modules.md | 0 .../reference/lang/spec/schema.md | 0 .../reference/lang/spec/statements.md | 0 .../reference/lang/spec/variables.md | 0 .../reference/lang/tour.md | 0 .../reference/lang/types/_category_.json | 0 .../reference/lang/types/types.md | 0 .../reference/model/_category_.json | 0 .../reference/model/base64.md | 0 .../reference/model/builtin.md | 0 .../reference/model/crypto.md | 0 .../reference/model/datetime.md | 0 .../reference/model/index.md | 0 .../reference/model/json.md | 0 .../reference/model/manifests.md | 0 .../reference/model/math.md | 0 .../reference/model/net.md | 0 .../reference/model/overview.md | 0 .../reference/model/regex.md | 0 .../reference/model/units.md | 0 .../reference/model/yaml.md | 0 .../package-management/_category_.json | 0 .../command-reference/1.init.md | 0 .../command-reference/10.help.md | 0 .../command-reference/2.add.md | 0 .../command-reference/3.pkg.md | 0 .../command-reference/4.metadata.md | 0 .../command-reference/5.run.md | 0 .../command-reference/6.login.md | 0 .../command-reference/7.logout.md | 0 .../command-reference/8.push.md | 0 .../command-reference/9.pull.md | 0 .../command-reference/_category_.json | 0 .../command-reference/index.md | 0 .../reference/plugin/_category_.json | 0 .../reference/plugin/index.md | 0 .../reference/plugin/overview.md | 0 .../reference/plugin/project_context.md | 0 .../reference/xlang-api/_category_.json | 0 .../reference/xlang-api/go-api.md | 0 .../reference/xlang-api/index.md | 0 .../reference/xlang-api/java-api.md | 0 .../reference/xlang-api/overview.md | 0 .../reference/xlang-api/python-api.md | 0 .../reference/xlang-api/rest-api.md | 0 .../tools/Ide/_category_.json | 0 .../tools/Ide/index.md | 0 .../tools/Ide/intellij.md | 0 .../tools/Ide/neovim.md | 0 .../tools/Ide/vs-code.md | 0 .../tools/_category_.json | 0 .../tools/cli/_category_.json | 0 .../tools/cli/index.md | 0 .../tools/cli/kcl/_category_.json | 0 .../tools/cli/kcl/docgen.md | 0 .../tools/cli/kcl/fmt.md | 0 .../tools/cli/kcl/index.md | 0 .../tools/cli/kcl/lint.md | 0 .../tools/cli/kcl/overview.md | 0 .../tools/cli/kcl/test.md | 0 .../tools/cli/kcl/vet.md | 0 .../tools/cli/openapi/_category_.json | 0 .../tools/cli/openapi/crd-to-kcl.md | 0 .../tools/cli/openapi/index.md | 0 .../tools/cli/openapi/openapi-to-kcl.md | 0 .../tools/cli/openapi/quick-start.md | 0 .../tools/cli/openapi/spec.md | 0 .../user_docs/concepts/_category_.json | 0 .../user_docs/concepts/concepts.md | 0 .../user_docs/concepts/package-and-module.md | 0 .../user_docs/concepts/type-and-definition.md | 0 .../user_docs/getting-started/_category_.json | 0 .../user_docs/getting-started/index.md | 0 .../user_docs/getting-started/install.md | 0 .../user_docs/getting-started/intro.md | 0 .../getting-started/kcl-quick-start.md | 0 .../user_docs/guides/_category_.json | 0 .../_working-with-terraform/1-overview.md | 0 .../_working-with-terraform/2-abstraction.md | 0 .../_working-with-terraform/3-coverter.md | 0 .../_working-with-terraform/_category_.json | 0 .../user_docs/guides/abstraction.md | 0 .../user_docs/guides/automation.md | 0 .../guides/ci-integration/1-github-actions.md | 0 .../guides/ci-integration/2-gitlab-ci.md | 0 .../guides/ci-integration/_3-jenkins-ci.md | 0 .../guides/ci-integration/_category_.json | 0 .../user_docs/guides/configuration.md | 0 .../user_docs/guides/data-integration.md | 0 .../user_docs/guides/gitops/1-quick-start.md | 0 .../user_docs/guides/gitops/_category_.json | 0 .../user_docs/guides/index.md | 0 .../guides/package-management/1-overview.md | 0 .../package-management/2-installation.md | 0 .../package-management/3-quick-start.md | 0 .../guides/package-management/_category_.json | 0 .../how-to/4-share_your_pkg.md | 0 .../how-to/5-share_your_pkg_docker.md | 0 .../how-to/6-push_github_action.md | 0 .../package-management/how-to/_category_.json | 0 .../user_docs/guides/schema-definition.md | 0 .../guides/secret-management/1-vault.md | 0 .../guides/secret-management/_category_.json | 0 .../user_docs/guides/validation.md | 0 .../1-adopt-from-kubernetes.md | 0 .../2-generate-k8s-manifests.md | 0 .../1-kubectl-kcl-plugin.md | 0 .../3-mutate-manifests/2-helm-kcl-plugin.md | 0 .../3-kustomize-kcl-plugin.md | 0 .../3-mutate-manifests/4-kpt-kcl-sdk.md | 0 .../5-helmfile-kcl-plugin.md | 0 .../3-mutate-manifests/6-kcl-operator.md | 0 .../3-mutate-manifests/_category_.json | 0 .../guides/working-with-k8s/_category_.json | 0 .../guides/working-with-k8s/index.md | 0 .../guides/working-with-konfig/1-overview.md | 0 .../guides/working-with-konfig/2-structure.md | 0 .../working-with-konfig/3-quick-start.md | 0 .../working-with-konfig/4-best-practice.md | 0 .../working-with-konfig/_category_.json | 0 .../working-with-kusion/_category_.json | 0 .../guides/working-with-kusion/index.md | 0 .../user_docs/support/_category_.json | 0 .../user_docs/support/faq-cli.md | 0 .../user_docs/support/faq-install.md | 0 .../user_docs/support/faq-kcl.md | 0 .../user_docs/support/faq-yaml.md | 0 .../user_docs/support/support.md | 0 .../community/contribute/_category_.json | 4 - .../community/contribute/contribute-code.md | 19 - .../community/contribute/contribute-docs.md | 52 - .../community/contribute/contribute.md | 3 - .../community/contribute/git-guideline.md | 130 - .../community/intro/_category_.json | 4 - .../version-0.6.0/community/intro/intro.md | 9 - .../version-0.6.0/community/intro/license.md | 211 -- .../version-0.6.0/community/intro/support.md | 21 - .../community/release-policy/_category_.json | 4 - .../community/release-policy/index.md | 3 - .../community/release-policy/kcl.md | 39 - .../community/release-policy/roadmap.md | 3 - .../_advanced-concepts/_category_.json | 4 - .../_advanced-concepts/build_cache.md | 1 - .../version-0.6.0/reference/_category_.json | 4 - .../reference/cheatsheets/_category_.json | 4 - .../reference/cheatsheets/index.md | 5 - .../reference/lang/_category_.json | 4 - .../reference/lang/codelab/_category_.json | 4 - .../reference/lang/codelab/collaborative.md | 345 -- .../reference/lang/codelab/index.md | 1 - .../reference/lang/codelab/schema.md | 817 ---- .../reference/lang/codelab/simple.md | 495 --- .../reference/lang/error/_category_.json | 4 - .../reference/lang/error/index.md | 1 - .../reference/lang/spec/_category_.json | 4 - .../reference/lang/spec/codestyle.md | 608 --- .../reference/lang/spec/datatypes.md | 452 --- .../reference/lang/spec/error.md | 53 - .../reference/lang/spec/index.md | 1 - .../reference/lang/spec/kcl-spec.md | 343 -- .../reference/lang/spec/lexical.md | 213 -- .../reference/lang/spec/modules.md | 621 --- .../reference/lang/spec/schema.md | 916 ----- .../reference/lang/spec/statements.md | 185 - .../reference/lang/spec/variables.md | 68 - .../reference/lang/types/_category_.json | 4 - .../reference/lang/types/types.md | 1381 ------- .../reference/model/_category_.json | 4 - .../version-0.6.0/reference/model/base64.md | 19 - .../version-0.6.0/reference/model/builtin.md | 386 -- .../version-0.6.0/reference/model/crypto.md | 43 - .../version-0.6.0/reference/model/index.md | 3 - .../reference/model/manifests.md | 89 - .../version-0.6.0/reference/model/net.md | 103 - .../version-0.6.0/reference/model/overview.md | 15 - .../version-0.6.0/reference/model/regex.md | 43 - .../version-0.6.0/reference/model/units.md | 41 - .../version-0.6.0/reference/model/yaml.md | 39 - .../reference/plugin/_category_.json | 4 - .../version-0.6.0/reference/plugin/index.md | 1 - .../reference/plugin/overview.md | 187 - .../reference/plugin/project_context.md | 59 - .../reference/xlang-api/_category_.json | 4 - .../reference/xlang-api/go-api.md | 665 ---- .../reference/xlang-api/index.md | 1 - .../reference/xlang-api/java-api.md | 7 - .../reference/xlang-api/overview.md | 293 -- .../reference/xlang-api/python-api.md | 7 - .../reference/xlang-api/rest-api.md | 443 --- .../version-0.6.0/tools/Ide/_category_.json | 4 - .../version-0.6.0/tools/_category_.json | 4 - .../version-0.6.0/tools/cli/_category_.json | 4 - .../version-0.6.0/tools/cli/index.md | 3 - .../tools/cli/kcl/_category_.json | 4 - .../version-0.6.0/tools/cli/kcl/docgen.md | 317 -- .../version-0.6.0/tools/cli/kcl/fmt.md | 70 - .../version-0.6.0/tools/cli/kcl/index.md | 3 - .../version-0.6.0/tools/cli/kcl/lint.md | 56 - .../version-0.6.0/tools/cli/kcl/overview.md | 58 - .../version-0.6.0/tools/cli/kcl/test.md | 7 - .../version-0.6.0/tools/cli/kcl/vet.md | 87 - .../tools/cli/openapi/_category_.json | 4 - .../tools/cli/openapi/crd-to-kcl.md | 118 - .../version-0.6.0/tools/cli/openapi/index.md | 3 - .../tools/cli/openapi/openapi-to-kcl.md | 64 - .../tools/cli/openapi/quick-start.md | 53 - .../cli/package-management/_category_.json | 4 - .../command-reference/1.init.md | 45 - .../command-reference/10.help.md | 21 - .../command-reference/2.add.md | 53 - .../command-reference/3.pkg.md | 33 - .../command-reference/4.metadata.md | 41 - .../command-reference/5.run.md | 69 - .../command-reference/6.login.md | 68 - .../command-reference/7.logout.md | 27 - .../command-reference/8.push.md | 46 - .../command-reference/9.pull.md | 42 - .../command-reference/_category_.json | 4 - .../command-reference/index.md | 36 - .../user_docs/concepts/_category_.json | 4 - .../user_docs/concepts/concepts.md | 3 - .../user_docs/concepts/package-and-module.md | 156 - .../user_docs/getting-started/_category_.json | 4 - .../user_docs/getting-started/index.md | 3 - .../getting-started/kcl-quick-start.md | 166 - .../user_docs/guides/_category_.json | 4 - .../_working-with-terraform/1-overview.md | 8 - .../_working-with-terraform/2-abstraction.md | 8 - .../_working-with-terraform/3-coverter.md | 8 - .../_working-with-terraform/_category_.json | 4 - .../user_docs/guides/abstraction.md | 151 - .../user_docs/guides/automation.md | 189 - .../guides/ci-integration/1-github-actions.md | 166 - .../guides/ci-integration/2-gitlab-ci.md | 139 - .../guides/ci-integration/_3-jenkins-ci.md | 12 - .../guides/ci-integration/_category_.json | 4 - .../user_docs/guides/configuration.md | 129 - .../user_docs/guides/data-integration.md | 106 - .../user_docs/guides/gitops/1-quick-start.md | 163 - .../user_docs/guides/gitops/_category_.json | 4 - .../version-0.6.0/user_docs/guides/index.md | 1 - .../guides/package-management/1-overview.md | 3 - .../package-management/2-installation.md | 55 - .../package-management/3-quick-start.md | 112 - .../4-how-to/_category_.json | 4 - .../guides/package-management/_category_.json | 4 - .../user_docs/guides/schema-definition.md | 139 - .../guides/secret-management/1-vault.md | 142 - .../guides/secret-management/_category_.json | 4 - .../user_docs/guides/validation.md | 99 - .../2-generate-k8s-manifests.md | 249 -- .../1-kubectl-kcl-plugin.md | 100 - .../3-mutate-manifests/2-helm-kcl-plugin.md | 100 - .../3-kustomize-kcl-plugin.md | 105 - .../3-mutate-manifests/4-kpt-kcl-sdk.md | 96 - .../5-helmfile-kcl-plugin.md | 113 - .../3-mutate-manifests/6-kcl-operator.md | 92 - .../3-mutate-manifests/_category_.json | 4 - .../guides/working-with-k8s/_category_.json | 4 - .../guides/working-with-k8s/index.md | 1 - .../working-with-konfig/4-best-practice.md | 449 --- .../working-with-konfig/_category_.json | 4 - .../working-with-kusion/_category_.json | 4 - .../guides/working-with-kusion/index.md | 15 - .../user_docs/support/_category_.json | 4 - .../user_docs/support/faq-cli.md | 107 - .../user_docs/support/faq-yaml.md | 102 - .../user_docs/support/support.md | 3 - .../community/contribute/_category_.json | 0 .../community/contribute/contribute-code.md | 0 .../community/contribute/contribute-docs.md | 0 .../community/contribute/contribute.md | 0 .../community/contribute/git-guideline.md | 0 .../community/intro/_category_.json | 0 .../community/intro/intro.md | 0 .../community/intro/license.md | 0 .../community/intro/support.md | 0 .../community/release-policy/_category_.json | 0 .../community/release-policy/index.md | 0 .../community/release-policy/kcl.md | 0 .../community/release-policy/roadmap.md | 0 .../_advanced-concepts/_category_.json | 0 .../_advanced-concepts/build_cache.md | 0 .../reference/_category_.json | 0 .../reference/cheatsheets/_category_.json | 0 .../reference/cheatsheets/index.md | 0 .../reference/lang/_category_.json | 0 .../reference/lang/codelab/_category_.json | 0 .../reference/lang/codelab/collaborative.md | 0 .../reference/lang/codelab/index.md | 0 .../reference/lang/codelab/schema.md | 0 .../reference/lang/codelab/simple.md | 0 .../reference/lang/error/_category_.json | 0 .../reference/lang/error/exception.md | 0 .../reference/lang/error/index.md | 0 .../reference/lang/spec/_category_.json | 0 .../reference/lang/spec/codestyle.md | 0 .../reference/lang/spec/datatypes.md | 0 .../version-0.6}/reference/lang/spec/error.md | 0 .../reference/lang/spec/expressions.md | 0 .../reference/lang/spec/index.md | 0 .../reference/lang/spec/kcl-spec.md | 0 .../reference/lang/spec/lexical.md | 0 .../reference/lang/spec/modules.md | 0 .../reference/lang/spec/schema.md | 0 .../reference/lang/spec/statements.md | 0 .../reference/lang/spec/variables.md | 0 .../reference/lang/tour.md | 0 .../reference/lang/types/_category_.json | 0 .../reference/lang/types/types.md | 0 .../reference/model/_category_.json | 0 .../reference/model/base64.md | 0 .../reference/model/builtin.md | 0 .../reference/model/crypto.md | 0 .../reference/model/datetime.md | 0 .../reference/model/index.md | 0 .../reference/model/json.md | 0 .../reference/model/manifests.md | 0 .../reference/model/math.md | 0 .../reference/model/net.md | 0 .../reference/model/overview.md | 0 .../reference/model/regex.md | 0 .../reference/model/units.md | 0 .../reference/model/yaml.md | 0 .../reference/plugin/_category_.json | 0 .../reference/plugin/index.md | 0 .../reference/plugin/overview.md | 0 .../reference/plugin/project_context.md | 0 .../reference/xlang-api/_category_.json | 0 .../reference/xlang-api/go-api.md | 0 .../reference/xlang-api/index.md | 0 .../reference/xlang-api/java-api.md | 0 .../reference/xlang-api/overview.md | 0 .../reference/xlang-api/python-api.md | 0 .../reference/xlang-api/rest-api.md | 0 .../tools/Ide/_category_.json | 0 .../tools/Ide/index.md | 0 .../tools/Ide/intellij.md | 0 .../tools/Ide/neovim.md | 0 .../tools/Ide/vs-code.md | 0 .../tools/_category_.json | 0 .../tools/cli/_category_.json | 0 .../tools/cli/index.md | 0 .../tools/cli/kcl/_category_.json | 0 .../tools/cli/kcl/docgen.md | 0 .../tools/cli/kcl/fmt.md | 0 .../tools/cli/kcl/index.md | 0 .../tools/cli/kcl/lint.md | 0 .../tools/cli/kcl/overview.md | 0 .../tools/cli/kcl/test.md | 0 .../tools/cli/kcl/vet.md | 0 .../tools/cli/openapi/_category_.json | 0 .../tools/cli/openapi/crd-to-kcl.md | 0 .../tools/cli/openapi/index.md | 0 .../tools/cli/openapi/openapi-to-kcl.md | 0 .../tools/cli/openapi/quick-start.md | 0 .../tools/cli/openapi/spec.md | 0 .../cli}/package-management/_category_.json | 0 .../command-reference/1.init.md | 0 .../command-reference/10.help.md | 0 .../command-reference/2.add.md | 0 .../command-reference/3.pkg.md | 0 .../command-reference/4.metadata.md | 0 .../command-reference/5.run.md | 0 .../command-reference/6.login.md | 0 .../command-reference/7.logout.md | 0 .../command-reference/8.push.md | 0 .../command-reference/9.pull.md | 0 .../command-reference/_category_.json | 0 .../command-reference/index.md | 0 .../user_docs/concepts/_category_.json | 0 .../user_docs/concepts/concepts.md | 0 .../user_docs/concepts/package-and-module.md | 0 .../user_docs/concepts/type-and-definition.md | 0 .../user_docs/getting-started/_category_.json | 0 .../user_docs/getting-started/index.md | 0 .../user_docs/getting-started/install.md | 0 .../user_docs/getting-started/intro.md | 0 .../getting-started/kcl-quick-start.md | 0 .../user_docs/guides/_category_.json | 0 .../_working-with-terraform/1-overview.md | 0 .../_working-with-terraform/2-abstraction.md | 0 .../_working-with-terraform/3-coverter.md | 0 .../_working-with-terraform/_category_.json | 0 .../user_docs/guides/abstraction.md | 0 .../user_docs/guides/automation.md | 0 .../guides/ci-integration/1-github-actions.md | 0 .../guides/ci-integration/2-gitlab-ci.md | 0 .../guides/ci-integration/_3-jenkins-ci.md | 0 .../guides/ci-integration/_category_.json | 0 .../user_docs/guides/configuration.md | 0 .../user_docs/guides/data-integration.md | 0 .../user_docs/guides/gitops/1-quick-start.md | 0 .../user_docs/guides/gitops/_category_.json | 0 .../user_docs/guides/index.md | 0 .../guides/package-management/1-overview.md | 0 .../package-management/2-installation.md | 0 .../package-management/3-quick-start.md | 0 .../4-how-to/4-share_your_pkg.md | 0 .../4-how-to/5-share_your_pkg_docker.md | 0 .../4-how-to/6-push_github_action.md | 0 .../4-how-to/_category_.json | 0 .../guides/package-management/_category_.json | 0 .../user_docs/guides/schema-definition.md | 0 .../guides/secret-management/1-vault.md | 0 .../guides/secret-management/_category_.json | 0 .../user_docs/guides/validation.md | 0 .../1-adopt-from-kubernetes.md | 0 .../2-generate-k8s-manifests.md | 0 .../1-kubectl-kcl-plugin.md | 0 .../3-mutate-manifests/2-helm-kcl-plugin.md | 0 .../3-kustomize-kcl-plugin.md | 0 .../3-mutate-manifests/4-kpt-kcl-sdk.md | 0 .../5-helmfile-kcl-plugin.md | 0 .../3-mutate-manifests/6-kcl-operator.md | 0 .../3-mutate-manifests/_category_.json | 0 .../guides/working-with-k8s/_category_.json | 0 .../guides/working-with-k8s/index.md | 0 .../guides/working-with-konfig/1-overview.md | 0 .../guides/working-with-konfig/2-structure.md | 0 .../working-with-konfig/3-quick-start.md | 0 .../working-with-konfig/4-best-practice.md | 0 .../working-with-konfig/_category_.json | 0 .../working-with-kusion/_category_.json | 0 .../guides/working-with-kusion/index.md | 0 .../working-with-terraform/3-validation.md | 0 .../_1-adopt-from-terraform.md | 0 .../working-with-terraform/_2-abstraction.md | 0 .../working-with-terraform/_category_.json | 0 .../user_docs/support/_category_.json | 0 .../user_docs/support/faq-cli.md | 0 .../user_docs/support/faq-install.md | 0 .../user_docs/support/faq-kcl.md | 0 .../user_docs/support/faq-yaml.md | 0 .../user_docs/support/support.md | 0 .../community/contribute/_category_.json | 4 - .../community/contribute/contribute-code.md | 19 - .../community/contribute/contribute-docs.md | 52 - .../community/contribute/contribute.md | 3 - .../community/intro/_category_.json | 4 - .../version-0.7.0/community/intro/intro.md | 9 - .../version-0.7.0/community/intro/license.md | 211 -- .../version-0.7.0/community/intro/support.md | 21 - .../community/release-policy/_category_.json | 4 - .../community/release-policy/index.md | 3 - .../_advanced-concepts/_category_.json | 4 - .../_advanced-concepts/build_cache.md | 1 - .../version-0.7.0/reference/_category_.json | 4 - .../reference/cheatsheets/_category_.json | 4 - .../reference/cheatsheets/index.md | 5 - .../reference/lang/_category_.json | 4 - .../reference/lang/codelab/_category_.json | 4 - .../reference/lang/codelab/collaborative.md | 345 -- .../reference/lang/codelab/index.md | 1 - .../reference/lang/codelab/schema.md | 817 ---- .../reference/lang/codelab/simple.md | 495 --- .../reference/lang/error/_category_.json | 4 - .../reference/lang/error/index.md | 1 - .../reference/lang/spec/_category_.json | 4 - .../reference/lang/spec/codestyle.md | 608 --- .../reference/lang/spec/datatypes.md | 452 --- .../reference/lang/spec/index.md | 1 - .../reference/lang/spec/lexical.md | 213 -- .../reference/lang/spec/variables.md | 68 - .../reference/lang/types/_category_.json | 4 - .../reference/lang/types/types.md | 1381 ------- .../reference/model/_category_.json | 4 - .../version-0.7.0/reference/model/base64.md | 19 - .../version-0.7.0/reference/model/builtin.md | 386 -- .../version-0.7.0/reference/model/crypto.md | 43 - .../reference/model/manifests.md | 89 - .../version-0.7.0/reference/model/net.md | 103 - .../version-0.7.0/reference/model/regex.md | 43 - .../version-0.7.0/reference/model/units.md | 41 - .../reference/plugin/_category_.json | 4 - .../version-0.7.0/reference/plugin/index.md | 1 - .../reference/plugin/project_context.md | 59 - .../reference/xlang-api/_category_.json | 4 - .../reference/xlang-api/index.md | 1 - .../reference/xlang-api/java-api.md | 7 - .../reference/xlang-api/overview.md | 293 -- .../reference/xlang-api/python-api.md | 7 - .../version-0.7.0/tools/Ide/_category_.json | 4 - .../version-0.7.0/tools/_category_.json | 4 - .../version-0.7.0/tools/cli/_category_.json | 4 - .../version-0.7.0/tools/cli/index.md | 3 - .../tools/cli/kcl/_category_.json | 4 - .../tools/cli/openapi/_category_.json | 4 - .../version-0.7.0/tools/cli/openapi/index.md | 3 - .../command-reference/_category_.json | 4 - .../user_docs/concepts/_category_.json | 4 - .../user_docs/concepts/package-and-module.md | 156 - .../user_docs/concepts/type-and-definition.md | 94 - .../user_docs/getting-started/_category_.json | 4 - .../getting-started/kcl-quick-start.md | 166 - .../user_docs/guides/_category_.json | 4 - .../user_docs/guides/abstraction.md | 151 - .../guides/ci-integration/1-github-actions.md | 166 - .../guides/ci-integration/2-gitlab-ci.md | 139 - .../guides/ci-integration/_3-jenkins-ci.md | 12 - .../guides/ci-integration/_category_.json | 4 - .../user_docs/guides/data-integration.md | 106 - .../user_docs/guides/gitops/1-quick-start.md | 163 - .../user_docs/guides/gitops/_category_.json | 4 - .../4-how-to/_category_.json | 4 - .../guides/package-management/_category_.json | 4 - .../user_docs/guides/schema-definition.md | 139 - .../guides/secret-management/1-vault.md | 142 - .../guides/secret-management/_category_.json | 4 - .../3-mutate-manifests/_category_.json | 4 - .../guides/working-with-k8s/_category_.json | 4 - .../guides/working-with-k8s/index.md | 1 - .../working-with-konfig/4-best-practice.md | 449 --- .../working-with-konfig/_category_.json | 4 - .../working-with-kusion/_category_.json | 4 - .../guides/working-with-kusion/index.md | 15 - .../user_docs/support/_category_.json | 4 - .../user_docs/support/faq-cli.md | 107 - .../user_docs/support/faq-yaml.md | 102 - .../community/contribute/_category_.json | 0 .../community/contribute/contribute-code.md | 0 .../community/contribute/contribute-docs.md | 0 .../community/contribute/contribute.md | 0 .../community/contribute/git-guideline.md | 0 .../community/intro/_category_.json | 0 .../community/intro/intro.md | 0 .../community/intro/license.md | 0 .../community/intro/support.md | 0 .../community/release-policy/_category_.json | 0 .../community/release-policy/index.md | 0 .../community/release-policy/kcl.md | 0 .../community/release-policy/roadmap.md | 0 .../_advanced-concepts/_category_.json | 0 .../_advanced-concepts/build_cache.md | 0 .../reference/_category_.json | 0 .../reference/cheatsheets/_category_.json | 0 .../reference/cheatsheets/index.md | 0 .../reference/lang/_category_.json | 0 .../reference/lang/codelab/_category_.json | 0 .../reference/lang/codelab/collaborative.md | 0 .../reference/lang/codelab/index.md | 0 .../reference/lang/codelab/schema.md | 0 .../reference/lang/codelab/simple.md | 0 .../reference/lang/error/_category_.json | 0 .../reference/lang/error/exception.md | 0 .../reference/lang/error/index.md | 0 .../reference/lang/spec/_category_.json | 0 .../reference/lang/spec/codestyle.md | 0 .../reference/lang/spec/datatypes.md | 0 .../reference/lang/spec/error.md | 0 .../reference/lang/spec/expressions.md | 0 .../reference/lang/spec/index.md | 0 .../reference/lang/spec/kcl-spec.md | 0 .../reference/lang/spec/lexical.md | 0 .../reference/lang/spec/modules.md | 0 .../reference/lang/spec/schema.md | 0 .../reference/lang/spec/statements.md | 0 .../reference/lang/spec/variables.md | 0 .../reference/lang/tour.md | 0 .../reference/lang/types/_category_.json | 0 .../reference/lang/types/types.md | 0 .../reference/model/_category_.json | 0 .../reference/model/base64.md | 0 .../reference/model/builtin.md | 0 .../reference/model/crypto.md | 0 .../reference/model/datetime.md | 0 .../reference/model/json.md | 0 .../reference/model/manifests.md | 0 .../reference/model/math.md | 0 .../reference/model/net.md | 0 .../reference/model/overview.md | 0 .../reference/model/regex.md | 0 .../reference/model/units.md | 0 .../reference/model/yaml.md | 0 .../reference/plugin/_category_.json | 0 .../reference/plugin/index.md | 0 .../reference/plugin/overview.md | 0 .../reference/plugin/project_context.md | 0 .../reference/xlang-api/_category_.json | 0 .../reference/xlang-api/go-api.md | 0 .../reference/xlang-api/index.md | 0 .../reference/xlang-api/java-api.md | 0 .../reference/xlang-api/overview.md | 0 .../reference/xlang-api/python-api.md | 0 .../reference/xlang-api/rest-api.md | 0 .../tools/Ide/_category_.json | 0 .../tools/Ide/index.md | 0 .../tools/Ide/intellij.md | 0 .../tools/Ide/neovim.md | 0 .../tools/Ide/vs-code.md | 0 .../tools/_category_.json | 0 .../tools/cli/_category_.json | 0 .../tools/cli/index.md | 0 .../tools/cli/kcl/_category_.json | 0 .../tools/cli/kcl/docgen.md | 0 .../tools/cli/kcl/fmt.md | 0 .../tools/cli/kcl/import.md | 0 .../tools/cli/kcl/index.md | 0 .../tools/cli/kcl/lint.md | 0 .../tools/cli/kcl/overview.md | 0 .../tools/cli/kcl/run.md | 0 .../tools/cli/kcl/test.md | 0 .../tools/cli/kcl/vet.md | 0 .../tools/cli/openapi/_category_.json | 0 .../tools/cli/openapi/crd-to-kcl.md | 0 .../tools/cli/openapi/index.md | 0 .../tools/cli/openapi/openapi-to-kcl.md | 0 .../tools/cli/openapi/spec.md | 0 .../cli/package-management/_category_.json | 0 .../command-reference/1.init.md | 0 .../command-reference/10.help.md | 0 .../command-reference/11.update.md | 0 .../command-reference/2.add.md | 0 .../command-reference/3.pkg.md | 0 .../command-reference/4.metadata.md | 0 .../command-reference/6.login.md | 0 .../command-reference/7.logout.md | 0 .../command-reference/8.push.md | 0 .../command-reference/9.pull.md | 0 .../command-reference/_category_.json | 0 .../user_docs/concepts/_category_.json | 0 .../user_docs/concepts/concepts.md | 0 .../user_docs/concepts/package-and-module.md | 0 .../user_docs/concepts/type-and-definition.md | 0 .../user_docs/getting-started/_category_.json | 0 .../user_docs/getting-started/index.md | 0 .../user_docs/getting-started/install.md | 0 .../user_docs/getting-started/intro.md | 0 .../getting-started/kcl-quick-start.md | 0 .../user_docs/guides/_category_.json | 0 .../user_docs/guides/abstraction.md | 0 .../user_docs/guides/automation.md | 0 .../guides/ci-integration/1-github-actions.md | 0 .../guides/ci-integration/2-gitlab-ci.md | 0 .../guides/ci-integration/_3-jenkins-ci.md | 0 .../guides/ci-integration/_category_.json | 0 .../user_docs/guides/configuration.md | 0 .../user_docs/guides/data-integration.md | 0 .../user_docs/guides/gitops/1-quick-start.md | 0 .../user_docs/guides/gitops/_category_.json | 0 .../user_docs/guides/index.md | 0 .../package-management/3-quick-start.md | 0 .../4-how-to/4-share_your_pkg.md | 0 .../4-how-to/5-share_your_pkg_docker.md | 0 .../4-how-to/6-push_github_action.md | 0 .../4-how-to/7-publish_pkg_to_ah.md | 0 .../package-management/4-how-to/8-kcl_mod.md | 0 .../package-management/4-how-to/9-kpm_oci.md | 0 .../4-how-to/_category_.json | 0 .../guides/package-management/_category_.json | 0 .../user_docs/guides/schema-definition.md | 0 .../guides/secret-management/1-vault.md | 0 .../guides/secret-management/_category_.json | 0 .../user_docs/guides/validation.md | 0 .../guides/working-with-k8s/0-overview.md | 0 .../1-adopt-from-kubernetes.md | 0 .../2-generate-k8s-manifests.md | 0 .../1-kubectl-kcl-plugin.md | 0 .../3-mutate-manifests/2-helm-kcl-plugin.md | 0 .../3-kustomize-kcl-plugin.md | 0 .../3-mutate-manifests/4-kpt-kcl-sdk.md | 0 .../5-helmfile-kcl-plugin.md | 0 .../3-mutate-manifests/6-kcl-operator.md | 0 .../7-crossplane-kcl-function.md | 0 .../3-mutate-manifests/_category_.json | 0 .../guides/working-with-k8s/_category_.json | 0 .../guides/working-with-k8s/index.md | 0 .../guides/working-with-konfig/1-overview.md | 0 .../guides/working-with-konfig/2-structure.md | 0 .../working-with-konfig/3-quick-start.md | 0 .../working-with-konfig/4-best-practice.md | 0 .../working-with-konfig/_category_.json | 0 .../working-with-kubevela/_category_.json | 0 .../guides/working-with-kubevela/index.md | 0 .../working-with-kusion/_category_.json | 0 .../guides/working-with-kusion/index.md | 0 .../working-with-terraform/3-validation.md | 0 .../_1-adopt-from-terraform.md | 0 .../working-with-terraform/_2-abstraction.md | 0 .../working-with-terraform/_category_.json | 0 .../user_docs/support/_category_.json | 0 .../user_docs/support/faq-cli.md | 0 .../user_docs/support/faq-install.md | 0 .../user_docs/support/faq-kcl.md | 0 .../user_docs/support/faq-yaml.md | 0 .../user_docs/support/support.md | 0 .../community/contribute/_category_.json | 4 - .../community/contribute/contribute-code.md | 19 - .../community/contribute/contribute-docs.md | 52 - .../community/contribute/contribute.md | 3 - .../community/intro/_category_.json | 4 - .../version-0.8.0/community/intro/intro.md | 9 - .../version-0.8.0/community/intro/license.md | 211 -- .../version-0.8.0/community/intro/support.md | 21 - .../community/release-policy/_category_.json | 4 - .../community/release-policy/index.md | 3 - .../_advanced-concepts/_category_.json | 4 - .../_advanced-concepts/build_cache.md | 1 - .../version-0.8.0/reference/_category_.json | 4 - .../reference/cheatsheets/_category_.json | 4 - .../reference/cheatsheets/index.md | 5 - .../reference/lang/_category_.json | 4 - .../reference/lang/codelab/_category_.json | 4 - .../reference/lang/codelab/collaborative.md | 345 -- .../reference/lang/codelab/index.md | 1 - .../reference/lang/codelab/schema.md | 817 ---- .../reference/lang/codelab/simple.md | 495 --- .../reference/lang/error/_category_.json | 4 - .../reference/lang/error/index.md | 1 - .../reference/lang/spec/_category_.json | 4 - .../reference/lang/spec/datatypes.md | 452 --- .../reference/lang/spec/expressions.md | 913 ----- .../reference/lang/spec/index.md | 1 - .../reference/lang/spec/lexical.md | 213 -- .../reference/lang/spec/variables.md | 68 - .../reference/lang/types/_category_.json | 4 - .../reference/lang/types/types.md | 1381 ------- .../reference/model/_category_.json | 4 - .../version-0.8.0/reference/model/base64.md | 19 - .../version-0.8.0/reference/model/builtin.md | 386 -- .../reference/model/manifests.md | 89 - .../version-0.8.0/reference/model/net.md | 103 - .../version-0.8.0/reference/model/regex.md | 43 - .../version-0.8.0/reference/model/units.md | 41 - .../reference/plugin/_category_.json | 4 - .../reference/xlang-api/_category_.json | 4 - .../reference/xlang-api/java-api.md | 7 - .../reference/xlang-api/python-api.md | 7 - .../version-0.8.0/tools/Ide/_category_.json | 4 - .../version-0.8.0/tools/Ide/intellij.md | 9 - .../version-0.8.0/tools/Ide/neovim.md | 9 - .../version-0.8.0/tools/_category_.json | 4 - .../version-0.8.0/tools/cli/_category_.json | 4 - .../version-0.8.0/tools/cli/index.md | 3 - .../tools/cli/kcl/_category_.json | 4 - .../tools/cli/openapi/_category_.json | 4 - .../version-0.8.0/tools/cli/openapi/spec.md | 438 --- .../command-reference/_category_.json | 4 - .../user_docs/concepts/_category_.json | 4 - .../user_docs/concepts/package-and-module.md | 156 - .../user_docs/concepts/type-and-definition.md | 94 - .../user_docs/getting-started/_category_.json | 4 - .../getting-started/kcl-quick-start.md | 166 - .../user_docs/guides/_category_.json | 4 - .../user_docs/guides/abstraction.md | 151 - .../guides/ci-integration/1-github-actions.md | 166 - .../guides/ci-integration/2-gitlab-ci.md | 139 - .../guides/ci-integration/_3-jenkins-ci.md | 12 - .../guides/ci-integration/_category_.json | 4 - .../user_docs/guides/data-integration.md | 106 - .../user_docs/guides/gitops/_category_.json | 4 - .../4-how-to/_category_.json | 4 - .../guides/package-management/_category_.json | 4 - .../user_docs/guides/schema-definition.md | 139 - .../guides/secret-management/1-vault.md | 142 - .../guides/secret-management/_category_.json | 4 - .../3-mutate-manifests/_category_.json | 4 - .../guides/working-with-k8s/_category_.json | 4 - .../working-with-konfig/4-best-practice.md | 449 --- .../working-with-konfig/_category_.json | 4 - .../working-with-kusion/_category_.json | 4 - .../guides/working-with-kusion/index.md | 15 - .../user_docs/support/_category_.json | 4 - .../user_docs/support/faq-cli.md | 107 - .../user_docs/support/faq-yaml.md | 102 - .../community/contribute/_category_.json | 0 .../community/contribute/contribute-code.md | 0 .../community/contribute/contribute-docs.md | 0 .../community/contribute/contribute.md | 0 .../community/contribute/git-guideline.md | 0 .../community/intro/_category_.json | 0 .../community/intro/intro.md | 0 .../community/intro/license.md | 0 .../community/intro/support.md | 0 .../community/release-policy/_category_.json | 0 .../community/release-policy/index.md | 0 .../community/release-policy/kcl.md | 0 .../community/release-policy/roadmap.md | 0 .../_advanced-concepts/_category_.json | 0 .../_advanced-concepts/build_cache.md | 0 .../reference/_category_.json | 0 .../reference/cheatsheets/_category_.json | 0 .../reference/cheatsheets/index.md | 0 .../reference/lang/_category_.json | 0 .../reference/lang/codelab/_category_.json | 0 .../reference/lang/codelab/collaborative.md | 0 .../reference/lang/codelab/index.md | 0 .../reference/lang/codelab/schema.md | 0 .../reference/lang/codelab/simple.md | 0 .../reference/lang/error/_category_.json | 0 .../reference/lang/error/exception.md | 0 .../reference/lang/error/index.md | 0 .../reference/lang/spec/_category_.json | 0 .../reference/lang/spec/codestyle.md | 0 .../reference/lang/spec/datatypes.md | 0 .../reference/lang/spec/error.md | 0 .../reference/lang/spec/expressions.md | 0 .../reference/lang/spec/index.md | 0 .../reference/lang/spec/kcl-spec.md | 0 .../reference/lang/spec/lexical.md | 0 .../reference/lang/spec/modules.md | 0 .../reference/lang/spec/schema.md | 0 .../reference/lang/spec/statements.md | 0 .../reference/lang/spec/variables.md | 0 .../reference/lang/tour.md | 0 .../reference/lang/types/_category_.json | 0 .../reference/lang/types/types.md | 0 .../reference/model/_category_.json | 0 .../reference/model/base64.md | 0 .../reference/model/builtin.md | 0 .../reference/model/crypto.md | 0 .../reference/model/datetime.md | 0 .../reference/model/file.md | 0 .../reference/model/json.md | 0 .../reference/model/manifests.md | 0 .../reference/model/math.md | 0 .../reference/model/net.md | 0 .../reference/model/overview.md | 0 .../reference/model/regex.md | 0 .../reference/model/units.md | 0 .../reference/model/yaml.md | 0 .../reference/plugin/_category_.json | 0 .../reference/plugin/overview.md | 0 .../reference/xlang-api/_category_.json | 0 .../reference/xlang-api/go-api.md | 0 .../reference/xlang-api/java-api.md | 0 .../reference/xlang-api/overview.md | 0 .../reference/xlang-api/python-api.md | 0 .../reference/xlang-api/rest-api.md | 0 .../tools/Ide/_category_.json | 0 .../tools/Ide/index.md | 0 .../tools/Ide/intellij.md | 0 .../tools/Ide/neovim.md | 0 .../tools/Ide/vs-code.md | 0 .../tools/_category_.json | 0 .../tools/cli/_category_.json | 0 .../tools/cli/index.md | 0 .../tools/cli/kcl/_category_.json | 0 .../tools/cli/kcl/docgen.md | 0 .../tools/cli/kcl/fmt.md | 0 .../tools/cli/kcl/import.md | 0 .../tools/cli/kcl/index.md | 0 .../tools/cli/kcl/lint.md | 0 .../tools/cli/kcl/overview.md | 0 .../tools/cli/kcl/run.md | 0 .../tools/cli/kcl/test.md | 0 .../tools/cli/kcl/vet.md | 0 .../tools/cli/openapi/_category_.json | 0 .../tools/cli/openapi/crd-to-kcl.md | 0 .../tools/cli/openapi/openapi-to-kcl.md | 0 .../tools/cli/openapi/spec.md | 0 .../cli/package-management/_category_.json | 0 .../command-reference/1.init.md | 0 .../command-reference/10.help.md | 0 .../command-reference/11.update.md | 0 .../command-reference/2.add.md | 0 .../command-reference/3.pkg.md | 0 .../command-reference/4.metadata.md | 0 .../command-reference/6.login.md | 0 .../command-reference/7.logout.md | 0 .../command-reference/8.push.md | 0 .../command-reference/9.pull.md | 0 .../command-reference/_category_.json | 0 .../user_docs/concepts/_category_.json | 0 .../user_docs/concepts/concepts.md | 0 .../user_docs/concepts/package-and-module.md | 0 .../user_docs/concepts/type-and-definition.md | 0 .../user_docs/getting-started/_category_.json | 0 .../user_docs/getting-started/index.md | 0 .../user_docs/getting-started/install.md | 0 .../user_docs/getting-started/intro.md | 0 .../getting-started/kcl-quick-start.md | 0 .../user_docs/guides/_category_.json | 0 .../user_docs/guides/abstraction.md | 0 .../user_docs/guides/automation.md | 0 .../guides/ci-integration/1-github-actions.md | 0 .../guides/ci-integration/2-gitlab-ci.md | 0 .../guides/ci-integration/_3-jenkins-ci.md | 0 .../guides/ci-integration/_category_.json | 0 .../user_docs/guides/configuration.md | 0 .../user_docs/guides/data-integration.md | 0 .../user_docs/guides/gitops/1-argocd.md | 0 .../user_docs/guides/gitops/2-fluxcd.md | 0 .../user_docs/guides/gitops/_category_.json | 0 .../user_docs/guides/index.md | 0 .../package-management/3-quick-start.md | 0 .../4-how-to/4-share_your_pkg.md | 0 .../4-how-to/5-share_your_pkg_docker.md | 0 .../4-how-to/6-push_github_action.md | 0 .../4-how-to/7-publish_pkg_to_ah.md | 0 .../package-management/4-how-to/8-kcl_mod.md | 0 .../package-management/4-how-to/9-kpm_oci.md | 0 .../4-how-to/_category_.json | 0 .../guides/package-management/_category_.json | 0 .../user_docs/guides/schema-definition.md | 0 .../guides/secret-management/1-vault.md | 0 .../guides/secret-management/_category_.json | 0 .../user_docs/guides/validation.md | 0 .../guides/working-with-k8s/0-overview.md | 0 .../1-adopt-from-kubernetes.md | 0 .../2-generate-k8s-manifests.md | 0 .../1-kubectl-kcl-plugin.md | 0 .../3-mutate-manifests/2-helm-kcl-plugin.md | 0 .../3-kustomize-kcl-plugin.md | 0 .../3-mutate-manifests/4-kpt-kcl-sdk.md | 0 .../5-helmfile-kcl-plugin.md | 0 .../3-mutate-manifests/6-kcl-operator.md | 0 .../7-crossplane-kcl-function.md | 0 .../3-mutate-manifests/_category_.json | 0 .../guides/working-with-k8s/_category_.json | 0 .../guides/working-with-konfig/1-overview.md | 0 .../guides/working-with-konfig/2-structure.md | 0 .../working-with-konfig/3-quick-start.md | 0 .../working-with-konfig/4-best-practice.md | 0 .../working-with-konfig/_category_.json | 0 .../working-with-kubevela/_category_.json | 0 .../guides/working-with-kubevela/index.md | 0 .../working-with-kusion/_category_.json | 0 .../guides/working-with-kusion/index.md | 0 .../working-with-terraform/3-validation.md | 0 .../_1-adopt-from-terraform.md | 0 .../working-with-terraform/_2-abstraction.md | 0 .../working-with-terraform/_category_.json | 0 .../user_docs/support/_category_.json | 0 .../user_docs/support/faq-cli.md | 0 .../user_docs/support/faq-install.md | 0 .../user_docs/support/faq-kcl.md | 0 .../user_docs/support/faq-yaml.md | 0 .../user_docs/support/support.md | 0 ...idebars.json => version-0.5-sidebars.json} | 0 .../version-0.5.4-sidebars.json | 32 - .../version-0.5.5-sidebars.json | 32 - .../version-0.5.6-sidebars.json | 32 - ...idebars.json => version-0.6-sidebars.json} | 0 .../version-0.6.0-sidebars.json | 32 - ...idebars.json => version-0.7-sidebars.json} | 0 .../version-0.7.0-sidebars.json | 32 - ...idebars.json => version-0.8-sidebars.json} | 0 .../version-0.8.0-sidebars.json | 32 - versions.json | 14 +- 3249 files changed, 40 insertions(+), 287741 deletions(-) delete mode 100644 .github/workflows/check.yml delete mode 100644 .github/workflows/install-kusion.yml delete mode 100644 CHANGELOG.md delete mode 100644 i18n/en/docusaurus-plugin-content-docs/version-0.5.0.json delete mode 100644 i18n/en/docusaurus-plugin-content-docs/version-0.5.3.json delete mode 100644 i18n/en/docusaurus-plugin-content-docs/version-0.5.4.json delete mode 100644 i18n/en/docusaurus-plugin-content-docs/version-0.5.5.json delete mode 100644 i18n/en/docusaurus-plugin-content-docs/version-0.5.6.json rename i18n/en/docusaurus-plugin-content-docs/{version-0.5.2.json => version-0.5.json} (99%) rename i18n/en/docusaurus-plugin-content-docs/{version-0.6.0.json => version-0.6.json} (99%) rename i18n/en/docusaurus-plugin-content-docs/{version-0.7.0.json => version-0.7.json} (99%) rename i18n/en/docusaurus-plugin-content-docs/{version-0.5.1.json => version-0.8.json} (96%) delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/error/exception.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/tour.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/datetime.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/json.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/yaml.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/Ide/intellij.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/Ide/vs-code.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/kcl/overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/getting-started/install.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/abstraction.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/automation.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/ci-integration/1-github-actions.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/configuration.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/data-integration.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/gitops/1-quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/schema-definition.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/validation.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-kusion/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/error/exception.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/tour.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/datetime.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/json.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/yaml.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/Ide/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/Ide/intellij.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/Ide/vs-code.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/getting-started/install.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/getting-started/intro.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/abstraction.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/automation.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/ci-integration/1-github-actions.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/configuration.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/data-integration.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/gitops/1-quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/package-management/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/schema-definition.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/validation.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-konfig/1-overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-konfig/2-structure.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-konfig/3-quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/support/faq-install.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/support/faq-kcl.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/release-policy/roadmap.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/error/exception.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/tour.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/datetime.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/json.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/yaml.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/1.init.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/10.help.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/2.add.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/3.pkg.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/4.metadata.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/5.run.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/6.login.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/7.logout.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/8.push.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/9.pull.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/plugin/overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/xlang-api/rest-api.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/Ide/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/Ide/intellij.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/Ide/vs-code.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/docgen.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/fmt.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/lint.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/test.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/vet.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/openapi/crd-to-kcl.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/openapi/openapi-to-kcl.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/openapi/quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/concepts/concepts.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/getting-started/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/getting-started/install.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/getting-started/intro.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/package-management/1-overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/package-management/2-installation.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/package-management/3-quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/package-management/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-konfig/1-overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-konfig/2-structure.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-konfig/3-quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/support/faq-install.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/support/faq-kcl.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/support/support.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/release-policy/roadmap.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/error/_error.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/error/exception.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/tour.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/crypto.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/datetime.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/json.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/yaml.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/1.init.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/10.help.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/2.add.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/3.pkg.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/4.metadata.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/5.run.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/6.login.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/7.logout.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/8.push.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/9.pull.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/plugin/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/plugin/overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/xlang-api/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/xlang-api/overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/xlang-api/rest-api.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/Ide/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/Ide/intellij.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/Ide/vs-code.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/docgen.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/fmt.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/lint.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/test.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/vet.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/openapi/crd-to-kcl.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/openapi/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/openapi/openapi-to-kcl.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/openapi/quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/concepts/concepts.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/getting-started/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/getting-started/install.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/getting-started/intro.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/automation.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/package-management/1-overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/package-management/2-installation.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/package-management/3-quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/package-management/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-konfig/1-overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-konfig/2-structure.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-konfig/3-quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/support/faq-install.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/support/faq-kcl.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/support/support.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/contribute/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/contribute/contribute-code.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/contribute/contribute-docs.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/contribute/contribute.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/contribute/git-guideline.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/intro/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/intro/intro.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/intro/license.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/intro/support.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/release-policy/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/release-policy/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/release-policy/kcl.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/release-policy/roadmap.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/cheatsheets/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/cheatsheets/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/codelab/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/codelab/collaborative.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/codelab/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/codelab/schema.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/codelab/simple.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/error/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/error/_error.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/error/exception.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/error/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/error.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/expressions.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/kcl-spec.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/lexical.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/modules.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/schema.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/statements.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/tour.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/types/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/types/types.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/base64.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/builtin.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/crypto.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/datetime.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/json.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/manifests.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/math.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/net.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/regex.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/units.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/yaml.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/1.init.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/10.help.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/2.add.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/3.pkg.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/4.metadata.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/5.run.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/6.login.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/7.logout.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/8.push.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/9.pull.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/plugin/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/plugin/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/plugin/overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/go-api.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/java-api.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/python-api.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/rest-api.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/Ide/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/Ide/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/Ide/intellij.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/Ide/vs-code.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/docgen.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/fmt.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/lint.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/test.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/vet.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/openapi/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/openapi/crd-to-kcl.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/openapi/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/openapi/openapi-to-kcl.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/openapi/quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/openapi/spec.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/concepts/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/concepts/concepts.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/concepts/package-and-module.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/getting-started/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/getting-started/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/getting-started/install.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/getting-started/intro.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/getting-started/kcl-quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/automation.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/ci-integration/_2-gitlab-ci.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/1-overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/2-installation.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/3-quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/4-how-to/6-push_github_action.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/4-how-to/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/validation.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-konfig/1-overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-konfig/2-structure.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-konfig/3-quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-konfig/4-best-practice.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-kusion/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/support/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/support/faq-cli.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/support/faq-install.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/support/faq-kcl.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/support/faq-yaml.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/support/support.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/contribute/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/contribute/contribute-code.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/contribute/contribute-docs.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/contribute/contribute.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/contribute/git-guideline.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/intro/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/intro/intro.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/intro/license.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/intro/support.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/release-policy/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/release-policy/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/release-policy/kcl.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/release-policy/roadmap.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/cheatsheets/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/cheatsheets/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/codelab/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/codelab/collaborative.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/codelab/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/codelab/schema.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/codelab/simple.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/error/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/error/_error.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/error/exception.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/error/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/error.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/expressions.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/kcl-spec.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/lexical.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/modules.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/schema.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/statements.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/tour.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/types/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/types/types.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/base64.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/builtin.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/crypto.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/datetime.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/json.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/manifests.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/math.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/net.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/regex.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/units.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/yaml.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/1.init.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/10.help.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/2.add.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/3.pkg.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/4.metadata.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/5.run.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/6.login.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/7.logout.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/8.push.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/9.pull.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/plugin/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/plugin/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/plugin/overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/go-api.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/java-api.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/python-api.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/rest-api.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/Ide/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/Ide/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/docgen.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/fmt.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/lint.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/test.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/vet.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/openapi/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/openapi/crd-to-kcl.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/openapi/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/openapi/openapi-to-kcl.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/openapi/quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/openapi/spec.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/concepts/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/concepts/concepts.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/concepts/package-and-module.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/getting-started/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/getting-started/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/getting-started/intro.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/getting-started/kcl-quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/automation.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/ci-integration/_2-gitlab-ci.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/gitops/1-quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/1-overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/2-installation.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/3-quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/4-how-to/6-push_github_action.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/4-how-to/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/secret-management/1-vault.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/validation.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-konfig/1-overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-konfig/2-structure.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-konfig/3-quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-konfig/4-best-practice.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-kusion/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/support/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/support/faq-cli.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/support/faq-install.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/support/faq-kcl.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/support/faq-yaml.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/support/support.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/contribute/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/contribute/contribute-code.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/contribute/contribute-docs.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/contribute/contribute.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/contribute/git-guideline.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/intro/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/intro/intro.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/intro/license.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/intro/support.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/release-policy/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/release-policy/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/release-policy/kcl.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/release-policy/roadmap.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/cheatsheets/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/cheatsheets/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/codelab/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/codelab/collaborative.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/codelab/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/codelab/schema.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/codelab/simple.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/error/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/error/_error.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/error/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/codestyle.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/error.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/expressions.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/kcl-spec.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/lexical.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/modules.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/schema.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/statements.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/types/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/types/types.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/base64.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/builtin.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/crypto.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/manifests.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/math.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/net.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/regex.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/units.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/1.init.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/10.help.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/2.add.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/3.pkg.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/4.metadata.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/5.run.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/6.login.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/7.logout.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/8.push.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/9.pull.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/plugin/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/plugin/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/plugin/overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/plugin/project_context.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/go-api.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/java-api.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/python-api.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/rest-api.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/Ide/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/Ide/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/Ide/vs-code.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/docgen.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/fmt.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/lint.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/test.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/vet.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/openapi/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/openapi/crd-to-kcl.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/openapi/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/openapi/openapi-to-kcl.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/openapi/quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/openapi/spec.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/concepts/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/concepts/concepts.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/concepts/package-and-module.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/getting-started/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/getting-started/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/getting-started/install.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/getting-started/intro.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/getting-started/kcl-quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/abstraction.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/automation.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/ci-integration/1-github-actions.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/ci-integration/_2-gitlab-ci.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/configuration.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/data-integration.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/gitops/1-quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/1-overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/2-installation.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/3-quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/4-how-to/6-push_github_action.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/4-how-to/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/schema-definition.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/secret-management/1-vault.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/validation.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-konfig/1-overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-konfig/2-structure.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-konfig/3-quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-konfig/4-best-practice.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-kusion/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/support/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/support/faq-cli.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/support/faq-install.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/support/faq-kcl.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/support/faq-yaml.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/support/support.md rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0.json => version-0.5.json} (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/community/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/community/contribute/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/community/contribute/contribute-code.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/community/contribute/contribute-docs.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/community/contribute/contribute.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/community/contribute/git-guideline.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/community/intro/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/community/intro/intro.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/community/intro/license.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/community/intro/support.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/community/release-policy/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/community/release-policy/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/community/release-policy/kcl.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/community/release-policy/roadmap.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/cheatsheets/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/cheatsheets/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/lang/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/lang/codelab/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/lang/codelab/collaborative.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/lang/codelab/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/lang/codelab/schema.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/lang/codelab/simple.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/lang/error/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/lang/error/_error.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.6 => version-0.5}/reference/lang/error/exception.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/lang/error/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/lang/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/lang/spec/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/lang/spec/codestyle.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/lang/spec/datatypes.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/lang/spec/error.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/lang/spec/expressions.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/lang/spec/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/lang/spec/kcl-spec.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/lang/spec/lexical.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/lang/spec/modules.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/lang/spec/schema.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/lang/spec/statements.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/lang/spec/variables.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.6 => version-0.5}/reference/lang/tour.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/lang/types/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/lang/types/types.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/model/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/model/base64.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/model/builtin.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/model/crypto.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.6 => version-0.5}/reference/model/datetime.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/model/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.6 => version-0.5}/reference/model/json.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/model/manifests.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/model/math.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/model/net.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/model/overview.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/model/regex.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/model/units.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.6 => version-0.5}/reference/model/yaml.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/package-management/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/package-management/command-reference/1.init.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/package-management/command-reference/10.help.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/package-management/command-reference/2.add.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/package-management/command-reference/3.pkg.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/package-management/command-reference/4.metadata.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/package-management/command-reference/5.run.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/package-management/command-reference/6.login.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/package-management/command-reference/7.logout.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/package-management/command-reference/8.push.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/package-management/command-reference/9.pull.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/package-management/command-reference/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/package-management/command-reference/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/plugin/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/plugin/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/plugin/overview.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/plugin/project_context.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/xlang-api/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/xlang-api/go-api.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/xlang-api/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/xlang-api/java-api.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/xlang-api/overview.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/xlang-api/python-api.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/reference/xlang-api/rest-api.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/tools/Ide/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/tools/Ide/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.5 => version-0.5}/tools/Ide/intellij.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.5 => version-0.5}/tools/Ide/neovim.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.5 => version-0.5}/tools/Ide/vs-code.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/tools/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/tools/cli/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/tools/cli/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/tools/cli/kcl/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/tools/cli/kcl/docgen.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/tools/cli/kcl/fmt.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/tools/cli/kcl/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/tools/cli/kcl/lint.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.5}/tools/cli/kcl/overview.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/tools/cli/kcl/test.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/tools/cli/kcl/vet.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/tools/cli/openapi/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/tools/cli/openapi/crd-to-kcl.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/tools/cli/openapi/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/tools/cli/openapi/openapi-to-kcl.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/tools/cli/openapi/quick-start.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/tools/cli/openapi/spec.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/concepts/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/concepts/concepts.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/concepts/package-and-module.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.4 => version-0.5}/user_docs/concepts/type-and-definition.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/getting-started/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/getting-started/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.5 => version-0.5}/user_docs/getting-started/install.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/getting-started/intro.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/getting-started/kcl-quick-start.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.5}/user_docs/guides/abstraction.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.5}/user_docs/guides/automation.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.5}/user_docs/guides/ci-integration/1-github-actions.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/ci-integration/_2-gitlab-ci.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/ci-integration/_3-jenkins-ci.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/ci-integration/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.5}/user_docs/guides/configuration.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.5}/user_docs/guides/data-integration.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.5}/user_docs/guides/gitops/1-quick-start.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/gitops/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/package-management/1-overview.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/package-management/2-installation.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/package-management/3-quick-start.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/package-management/4-how-to/6-push_github_action.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/package-management/4-how-to/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/package-management/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.5}/user_docs/guides/schema-definition.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.5}/user_docs/guides/secret-management/1-vault.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.5}/user_docs/guides/secret-management/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.5}/user_docs/guides/validation.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/working-with-k8s/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/working-with-k8s/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/working-with-konfig/1-overview.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/working-with-konfig/2-structure.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/working-with-konfig/3-quick-start.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/working-with-konfig/4-best-practice.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/working-with-konfig/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.5}/user_docs/guides/working-with-kusion/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/guides/working-with-kusion/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/support/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/support/faq-cli.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/support/faq-install.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/support/faq-kcl.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/support/faq-yaml.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.0 => version-0.5}/user_docs/support/support.md (100%) delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/contribute/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/contribute/contribute-code.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/contribute/contribute-docs.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/contribute/contribute.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/contribute/git-guideline.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/intro/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/intro/intro.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/intro/license.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/intro/support.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/release-policy/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/release-policy/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/release-policy/kcl.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/release-policy/roadmap.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/cheatsheets/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/cheatsheets/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/codelab/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/codelab/collaborative.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/codelab/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/codelab/schema.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/codelab/simple.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/error/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/error/_error.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/error/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/codestyle.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/error.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/expressions.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/kcl-spec.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/lexical.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/modules.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/schema.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/statements.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/types/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/types/types.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/base64.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/builtin.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/crypto.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/manifests.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/math.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/net.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/regex.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/units.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/plugin/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/plugin/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/plugin/overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/plugin/project_context.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/go-api.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/java-api.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/python-api.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/rest-api.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/Ide/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/docgen.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/fmt.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/lint.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/test.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/vet.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/openapi/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/openapi/crd-to-kcl.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/openapi/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/openapi/openapi-to-kcl.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/openapi/quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/openapi/spec.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/1.init.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/10.help.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/2.add.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/3.pkg.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/4.metadata.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/5.run.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/6.login.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/7.logout.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/8.push.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/9.pull.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/concepts/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/concepts/concepts.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/concepts/package-and-module.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/getting-started/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/getting-started/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/getting-started/kcl-quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/abstraction.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/ci-integration/1-github-actions.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/ci-integration/_2-gitlab-ci.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/configuration.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/data-integration.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/gitops/1-quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/1-overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/2-installation.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/3-quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/4-how-to/6-push_github_action.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/4-how-to/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/schema-definition.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/secret-management/1-vault.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/validation.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-konfig/4-best-practice.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-kusion/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/support/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/support/faq-cli.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/support/faq-yaml.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/support/support.md rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.6.0.json => version-0.6.json} (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/community/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/community/contribute/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/community/contribute/contribute-code.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/community/contribute/contribute-docs.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/community/contribute/contribute.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/community/contribute/git-guideline.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/community/intro/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/community/intro/intro.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/community/intro/license.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/community/intro/support.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/community/release-policy/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/community/release-policy/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/community/release-policy/kcl.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/community/release-policy/roadmap.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/cheatsheets/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/cheatsheets/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/lang/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/lang/codelab/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/lang/codelab/collaborative.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/lang/codelab/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/lang/codelab/schema.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/lang/codelab/simple.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/lang/error/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/lang/error/_error.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.6.0 => version-0.6}/reference/lang/error/exception.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/lang/error/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/lang/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/lang/spec/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/lang/spec/codestyle.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/lang/spec/datatypes.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/lang/spec/error.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/lang/spec/expressions.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/lang/spec/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/lang/spec/kcl-spec.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/lang/spec/lexical.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/lang/spec/modules.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/lang/spec/schema.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/lang/spec/statements.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/lang/spec/variables.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.6.0 => version-0.6}/reference/lang/tour.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/lang/types/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/lang/types/types.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/model/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/model/base64.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/model/builtin.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/model/crypto.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.6.0 => version-0.6}/reference/model/datetime.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/model/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.6.0 => version-0.6}/reference/model/json.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/model/manifests.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/model/math.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/model/net.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/model/overview.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/model/regex.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/model/units.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.6.0 => version-0.6}/reference/model/yaml.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/plugin/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/plugin/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/plugin/overview.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/plugin/project_context.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/xlang-api/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/xlang-api/go-api.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/xlang-api/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/xlang-api/java-api.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/xlang-api/overview.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/xlang-api/python-api.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/reference/xlang-api/rest-api.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/tools/Ide/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.6.0 => version-0.6}/tools/Ide/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.6 => version-0.6}/tools/Ide/intellij.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.6 => version-0.6}/tools/Ide/neovim.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.6.0 => version-0.6}/tools/Ide/vs-code.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/tools/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/tools/cli/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/tools/cli/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/tools/cli/kcl/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/tools/cli/kcl/docgen.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/tools/cli/kcl/fmt.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/tools/cli/kcl/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/tools/cli/kcl/lint.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.6}/tools/cli/kcl/overview.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/tools/cli/kcl/test.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/tools/cli/kcl/vet.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/tools/cli/openapi/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/tools/cli/openapi/crd-to-kcl.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/tools/cli/openapi/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/tools/cli/openapi/openapi-to-kcl.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/tools/cli/openapi/quick-start.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/tools/cli/openapi/spec.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.6.0 => version-0.6}/tools/cli/package-management/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1/reference => version-0.6/tools/cli}/package-management/command-reference/1.init.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1/reference => version-0.6/tools/cli}/package-management/command-reference/10.help.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1/reference => version-0.6/tools/cli}/package-management/command-reference/2.add.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1/reference => version-0.6/tools/cli}/package-management/command-reference/3.pkg.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1/reference => version-0.6/tools/cli}/package-management/command-reference/4.metadata.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1/reference => version-0.6/tools/cli}/package-management/command-reference/5.run.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1/reference => version-0.6/tools/cli}/package-management/command-reference/6.login.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1/reference => version-0.6/tools/cli}/package-management/command-reference/7.logout.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1/reference => version-0.6/tools/cli}/package-management/command-reference/8.push.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1/reference => version-0.6/tools/cli}/package-management/command-reference/9.pull.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1/reference => version-0.6/tools/cli}/package-management/command-reference/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1/reference => version-0.6/tools/cli}/package-management/command-reference/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/concepts/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/concepts/concepts.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/concepts/package-and-module.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.5 => version-0.6}/user_docs/concepts/type-and-definition.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/getting-started/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/getting-started/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.6.0 => version-0.6}/user_docs/getting-started/install.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.6.0 => version-0.6}/user_docs/getting-started/intro.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/getting-started/kcl-quick-start.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/guides/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.6}/user_docs/guides/abstraction.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.6.0 => version-0.6}/user_docs/guides/automation.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.6}/user_docs/guides/ci-integration/1-github-actions.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/guides/ci-integration/_2-gitlab-ci.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/guides/ci-integration/_3-jenkins-ci.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/guides/ci-integration/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.6}/user_docs/guides/configuration.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.6}/user_docs/guides/data-integration.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.6}/user_docs/guides/gitops/1-quick-start.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/guides/gitops/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/guides/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/guides/package-management/1-overview.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/guides/package-management/2-installation.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/guides/package-management/3-quick-start.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/guides/package-management/4-how-to/6-push_github_action.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/guides/package-management/4-how-to/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.6.0 => version-0.6}/user_docs/guides/package-management/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.6}/user_docs/guides/schema-definition.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.6}/user_docs/guides/secret-management/1-vault.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.6}/user_docs/guides/secret-management/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.6}/user_docs/guides/validation.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.6.0 => version-0.6}/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/guides/working-with-k8s/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/guides/working-with-k8s/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.6.0 => version-0.6}/user_docs/guides/working-with-konfig/1-overview.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.6.0 => version-0.6}/user_docs/guides/working-with-konfig/2-structure.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.6.0 => version-0.6}/user_docs/guides/working-with-konfig/3-quick-start.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/guides/working-with-konfig/4-best-practice.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/guides/working-with-konfig/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.6}/user_docs/guides/working-with-kusion/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/guides/working-with-kusion/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/support/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/support/faq-cli.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.6.0 => version-0.6}/user_docs/support/faq-install.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.6.0 => version-0.6}/user_docs/support/faq-kcl.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/support/faq-yaml.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.1 => version-0.6}/user_docs/support/support.md (100%) delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/contribute/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/contribute/contribute-code.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/contribute/contribute-docs.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/contribute/contribute.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/contribute/git-guideline.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/intro/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/intro/intro.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/intro/license.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/intro/support.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/release-policy/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/release-policy/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/release-policy/kcl.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/cheatsheets/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/cheatsheets/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/codelab/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/codelab/collaborative.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/codelab/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/codelab/schema.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/codelab/simple.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/error/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/error/_error.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/error/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/codestyle.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/datatypes.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/expressions.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/lexical.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/variables.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/types/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/types/types.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/base64.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/builtin.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/crypto.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/manifests.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/math.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/net.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/regex.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/units.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/plugin/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/plugin/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/plugin/project_context.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/xlang-api/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/xlang-api/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/xlang-api/java-api.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/xlang-api/overview.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/xlang-api/python-api.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/Ide/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/kcl/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/openapi/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/openapi/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/openapi/spec.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/package-management/command-reference/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/concepts/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/concepts/package-and-module.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/concepts/type-and-definition.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/getting-started/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/getting-started/kcl-quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/abstraction.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/ci-integration/1-github-actions.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/ci-integration/_2-gitlab-ci.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/ci-integration/_3-jenkins-ci.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/ci-integration/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/configuration.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/data-integration.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/gitops/1-quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/gitops/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/package-management/4-how-to/6-push_github_action.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/package-management/4-how-to/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/schema-definition.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/secret-management/1-vault.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-konfig/4-best-practice.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-konfig/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-kusion/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/support/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/support/faq-cli.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/support/faq-yaml.md rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0.json => version-0.7.json} (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/community/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/community/contribute/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/community/contribute/contribute-code.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/community/contribute/contribute-docs.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/community/contribute/contribute.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/community/contribute/git-guideline.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/community/intro/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/community/intro/intro.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/community/intro/license.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/community/intro/support.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/community/release-policy/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/community/release-policy/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/community/release-policy/kcl.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/community/release-policy/roadmap.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/cheatsheets/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/cheatsheets/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/lang/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/lang/codelab/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/lang/codelab/collaborative.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/lang/codelab/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/lang/codelab/schema.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/lang/codelab/simple.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/lang/error/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/lang/error/_error.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/reference/lang/error/exception.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/lang/error/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/lang/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/lang/spec/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/lang/spec/codestyle.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/lang/spec/datatypes.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/reference/lang/spec/error.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/lang/spec/expressions.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/lang/spec/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/reference/lang/spec/kcl-spec.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/lang/spec/lexical.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/reference/lang/spec/modules.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/reference/lang/spec/schema.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/reference/lang/spec/statements.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/lang/spec/variables.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/reference/lang/tour.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/lang/types/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/lang/types/types.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/model/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/model/base64.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/model/builtin.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/model/crypto.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/reference/model/datetime.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/reference/model/json.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/model/manifests.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/model/math.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/model/net.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/reference/model/overview.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/model/regex.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/model/units.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/reference/model/yaml.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/plugin/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/plugin/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/reference/plugin/overview.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/plugin/project_context.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/xlang-api/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/reference/xlang-api/go-api.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/xlang-api/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/xlang-api/java-api.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/xlang-api/overview.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/reference/xlang-api/python-api.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/reference/xlang-api/rest-api.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/tools/Ide/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/tools/Ide/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.6.0 => version-0.7}/tools/Ide/intellij.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.6.0 => version-0.7}/tools/Ide/neovim.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/tools/Ide/vs-code.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/tools/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/tools/cli/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/tools/cli/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/tools/cli/kcl/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/tools/cli/kcl/docgen.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/tools/cli/kcl/fmt.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/tools/cli/kcl/import.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/tools/cli/kcl/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/tools/cli/kcl/lint.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/tools/cli/kcl/overview.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/tools/cli/kcl/run.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/tools/cli/kcl/test.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/tools/cli/kcl/vet.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/tools/cli/openapi/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/tools/cli/openapi/crd-to-kcl.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/tools/cli/openapi/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/tools/cli/openapi/openapi-to-kcl.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/tools/cli/openapi/spec.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/tools/cli/package-management/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/tools/cli/package-management/command-reference/1.init.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/tools/cli/package-management/command-reference/10.help.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/tools/cli/package-management/command-reference/2.add.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/tools/cli/package-management/command-reference/3.pkg.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/tools/cli/package-management/command-reference/4.metadata.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/tools/cli/package-management/command-reference/6.login.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/tools/cli/package-management/command-reference/7.logout.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/tools/cli/package-management/command-reference/8.push.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/tools/cli/package-management/command-reference/9.pull.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2/reference => version-0.7/tools/cli}/package-management/command-reference/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/user_docs/concepts/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/concepts/concepts.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/user_docs/concepts/package-and-module.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.6 => version-0.7}/user_docs/concepts/type-and-definition.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/user_docs/getting-started/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/getting-started/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/getting-started/install.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/getting-started/intro.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/user_docs/getting-started/kcl-quick-start.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/user_docs/guides/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.4 => version-0.7}/user_docs/guides/abstraction.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/guides/automation.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.4 => version-0.7}/user_docs/guides/ci-integration/1-github-actions.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/user_docs/guides/ci-integration/_2-gitlab-ci.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/user_docs/guides/ci-integration/_3-jenkins-ci.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/user_docs/guides/ci-integration/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.4 => version-0.7}/user_docs/guides/configuration.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.4 => version-0.7}/user_docs/guides/data-integration.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.4 => version-0.7}/user_docs/guides/gitops/1-quick-start.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/user_docs/guides/gitops/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/guides/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/guides/package-management/3-quick-start.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/user_docs/guides/package-management/4-how-to/6-push_github_action.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/guides/package-management/4-how-to/7-publish_pkg_to_ah.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/guides/package-management/4-how-to/8-kcl_mod.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/guides/package-management/4-how-to/9-kpm_oci.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/user_docs/guides/package-management/4-how-to/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/guides/package-management/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.4 => version-0.7}/user_docs/guides/schema-definition.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.7}/user_docs/guides/secret-management/1-vault.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.7}/user_docs/guides/secret-management/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/guides/validation.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-k8s/0-overview.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-k8s/4-publish-modules.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-k8s/_4-publish-modules.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/user_docs/guides/working-with-k8s/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/user_docs/guides/working-with-k8s/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-konfig/1-overview.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-konfig/2-structure.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-konfig/3-quick-start.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/user_docs/guides/working-with-konfig/4-best-practice.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/user_docs/guides/working-with-konfig/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-kubevela/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-kubevela/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.7}/user_docs/guides/working-with-kusion/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/user_docs/guides/working-with-kusion/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/user_docs/support/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/user_docs/support/faq-cli.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/support/faq-install.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/support/faq-kcl.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.2 => version-0.7}/user_docs/support/faq-yaml.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.7}/user_docs/support/support.md (100%) delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/contribute/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/contribute/contribute-code.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/contribute/contribute-docs.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/contribute/contribute.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/contribute/git-guideline.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/intro/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/intro/intro.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/intro/license.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/intro/support.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/release-policy/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/release-policy/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/release-policy/kcl.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/cheatsheets/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/cheatsheets/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/codelab/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/codelab/collaborative.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/codelab/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/codelab/schema.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/codelab/simple.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/error/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/error/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/datatypes.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/expressions.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/lexical.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/variables.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/types/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/types/types.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/base64.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/builtin.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/manifests.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/math.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/net.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/regex.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/units.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/plugin/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/xlang-api/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/xlang-api/java-api.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/xlang-api/python-api.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/Ide/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/Ide/intellij.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/Ide/neovim.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/kcl/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/openapi/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/openapi/spec.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/package-management/command-reference/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/concepts/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/concepts/package-and-module.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/concepts/type-and-definition.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/getting-started/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/getting-started/kcl-quick-start.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/abstraction.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/ci-integration/1-github-actions.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/ci-integration/_2-gitlab-ci.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/ci-integration/_3-jenkins-ci.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/ci-integration/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/configuration.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/data-integration.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/gitops/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/package-management/4-how-to/6-push_github_action.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/package-management/4-how-to/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/schema-definition.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/secret-management/1-vault.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/secret-management/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-konfig/4-best-practice.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-konfig/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-kusion/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-kusion/index.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/support/_category_.json delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/support/faq-cli.md delete mode 100644 i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/support/faq-yaml.md rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0.json => version-0.8.json} (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/community/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/community/contribute/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/community/contribute/contribute-code.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/community/contribute/contribute-docs.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/community/contribute/contribute.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/community/contribute/git-guideline.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/community/intro/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/community/intro/intro.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/community/intro/license.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/community/intro/support.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/community/release-policy/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/community/release-policy/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/community/release-policy/kcl.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/community/release-policy/roadmap.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/cheatsheets/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/cheatsheets/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/lang/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/lang/codelab/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/lang/codelab/collaborative.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/lang/codelab/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/lang/codelab/schema.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/lang/codelab/simple.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/lang/error/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/reference/lang/error/exception.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/lang/error/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/lang/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/lang/spec/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/reference/lang/spec/codestyle.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/lang/spec/datatypes.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/reference/lang/spec/error.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/lang/spec/expressions.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/lang/spec/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/reference/lang/spec/kcl-spec.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/lang/spec/lexical.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/reference/lang/spec/modules.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/reference/lang/spec/schema.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/reference/lang/spec/statements.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/lang/spec/variables.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/reference/lang/tour.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/lang/types/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/lang/types/types.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/model/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/model/base64.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/model/builtin.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/reference/model/crypto.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/reference/model/datetime.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/reference/model/file.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/reference/model/json.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/model/manifests.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/model/math.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/model/net.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/reference/model/overview.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/model/regex.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/model/units.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/reference/model/yaml.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/plugin/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/reference/plugin/overview.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/xlang-api/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/reference/xlang-api/go-api.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/xlang-api/java-api.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/reference/xlang-api/overview.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/reference/xlang-api/python-api.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/reference/xlang-api/rest-api.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/tools/Ide/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/tools/Ide/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.8}/tools/Ide/intellij.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.7.0 => version-0.8}/tools/Ide/neovim.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/tools/Ide/vs-code.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/tools/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/tools/cli/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/tools/cli/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/tools/cli/kcl/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/tools/cli/kcl/docgen.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/tools/cli/kcl/fmt.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/tools/cli/kcl/import.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/tools/cli/kcl/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/tools/cli/kcl/lint.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/tools/cli/kcl/overview.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/tools/cli/kcl/run.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/tools/cli/kcl/test.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/tools/cli/kcl/vet.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/tools/cli/openapi/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/tools/cli/openapi/crd-to-kcl.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/tools/cli/openapi/openapi-to-kcl.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/tools/cli/openapi/spec.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/tools/cli/package-management/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/tools/cli/package-management/command-reference/1.init.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/tools/cli/package-management/command-reference/10.help.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/tools/cli/package-management/command-reference/2.add.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/tools/cli/package-management/command-reference/3.pkg.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/tools/cli/package-management/command-reference/4.metadata.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/tools/cli/package-management/command-reference/6.login.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/tools/cli/package-management/command-reference/7.logout.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/tools/cli/package-management/command-reference/8.push.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/tools/cli/package-management/command-reference/9.pull.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3/reference => version-0.8/tools/cli}/package-management/command-reference/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/user_docs/concepts/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/concepts/concepts.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/user_docs/concepts/package-and-module.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.6.0 => version-0.8}/user_docs/concepts/type-and-definition.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/user_docs/getting-started/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/getting-started/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/getting-started/install.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/getting-started/intro.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/user_docs/getting-started/kcl-quick-start.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/user_docs/guides/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.5 => version-0.8}/user_docs/guides/abstraction.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/guides/automation.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.5 => version-0.8}/user_docs/guides/ci-integration/1-github-actions.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/user_docs/guides/ci-integration/_2-gitlab-ci.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/user_docs/guides/ci-integration/_3-jenkins-ci.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/user_docs/guides/ci-integration/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.5 => version-0.8}/user_docs/guides/configuration.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.5 => version-0.8}/user_docs/guides/data-integration.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/guides/gitops/1-argocd.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/guides/gitops/2-fluxcd.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/user_docs/guides/gitops/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/guides/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/guides/package-management/3-quick-start.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/user_docs/guides/package-management/4-how-to/6-push_github_action.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/guides/package-management/4-how-to/7-publish_pkg_to_ah.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/guides/package-management/4-how-to/8-kcl_mod.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/guides/package-management/4-how-to/9-kpm_oci.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/user_docs/guides/package-management/4-how-to/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/guides/package-management/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.5 => version-0.8}/user_docs/guides/schema-definition.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.4 => version-0.8}/user_docs/guides/secret-management/1-vault.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.4 => version-0.8}/user_docs/guides/secret-management/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/guides/validation.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-k8s/0-overview.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-k8s/4-publish-modules.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/user_docs/guides/working-with-k8s/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/user_docs/guides/working-with-k8s/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-konfig/1-overview.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-konfig/2-structure.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-konfig/3-quick-start.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/user_docs/guides/working-with-konfig/4-best-practice.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/user_docs/guides/working-with-konfig/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-kubevela/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-kubevela/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.4 => version-0.8}/user_docs/guides/working-with-kusion/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/user_docs/guides/working-with-kusion/index.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/user_docs/support/_category_.json (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/user_docs/support/faq-cli.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/support/faq-install.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/support/faq-kcl.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.5.3 => version-0.8}/user_docs/support/faq-yaml.md (100%) rename i18n/zh-CN/docusaurus-plugin-content-docs/{version-0.8.0 => version-0.8}/user_docs/support/support.md (100%) delete mode 100644 static/stack/ci-test/settings.yaml delete mode 100644 static/stack/ci-test/stdout.golden.yaml delete mode 100644 static/stack/kcl.yaml delete mode 100644 static/stack/main.k delete mode 100644 static/stack/project.yaml delete mode 100644 static/stack/stack.yaml delete mode 100644 versioned_docs/version-0.5.0/reference/lang/error/exception.md delete mode 100644 versioned_docs/version-0.5.0/reference/lang/spec/codestyle.md delete mode 100644 versioned_docs/version-0.5.0/reference/lang/spec/datatypes.md delete mode 100644 versioned_docs/version-0.5.0/reference/lang/spec/error.md delete mode 100644 versioned_docs/version-0.5.0/reference/lang/spec/expressions.md delete mode 100644 versioned_docs/version-0.5.0/reference/lang/spec/kcl-spec.md delete mode 100644 versioned_docs/version-0.5.0/reference/lang/spec/modules.md delete mode 100644 versioned_docs/version-0.5.0/reference/lang/spec/schema.md delete mode 100644 versioned_docs/version-0.5.0/reference/lang/spec/statements.md delete mode 100644 versioned_docs/version-0.5.0/reference/lang/spec/variables.md delete mode 100644 versioned_docs/version-0.5.0/reference/lang/tour.md delete mode 100644 versioned_docs/version-0.5.0/reference/model/datetime.md delete mode 100644 versioned_docs/version-0.5.0/reference/model/json.md delete mode 100644 versioned_docs/version-0.5.0/reference/model/math.md delete mode 100644 versioned_docs/version-0.5.0/reference/plugin/project_context.md delete mode 100644 versioned_docs/version-0.5.0/reference/xlang-api/go-api.md delete mode 100644 versioned_docs/version-0.5.0/reference/xlang-api/rest-api.md delete mode 100644 versioned_docs/version-0.5.0/tools/Ide/intellij.md delete mode 100644 versioned_docs/version-0.5.0/tools/Ide/vs-code.md delete mode 100644 versioned_docs/version-0.5.0/tools/cli/kcl/fmt.md delete mode 100644 versioned_docs/version-0.5.0/tools/cli/kcl/lint.md delete mode 100644 versioned_docs/version-0.5.0/tools/cli/kcl/overview.md delete mode 100644 versioned_docs/version-0.5.0/tools/cli/openapi/quick-start.md delete mode 100644 versioned_docs/version-0.5.0/tools/cli/openapi/spec.md delete mode 100644 versioned_docs/version-0.5.0/user_docs/getting-started/install.md delete mode 100644 versioned_docs/version-0.5.0/user_docs/guides/abstraction.md delete mode 100644 versioned_docs/version-0.5.0/user_docs/guides/automation.md delete mode 100644 versioned_docs/version-0.5.0/user_docs/guides/ci-integration/1-github-actions.md delete mode 100644 versioned_docs/version-0.5.0/user_docs/guides/ci-integration/2-gitlab-ci.md delete mode 100644 versioned_docs/version-0.5.0/user_docs/guides/ci-integration/_2-gitlab-ci.md delete mode 100644 versioned_docs/version-0.5.0/user_docs/guides/ci-integration/_3-jenkins-ci.md delete mode 100644 versioned_docs/version-0.5.0/user_docs/guides/ci-integration/_category_.json delete mode 100644 versioned_docs/version-0.5.0/user_docs/guides/configuration.md delete mode 100644 versioned_docs/version-0.5.0/user_docs/guides/data-integration.md delete mode 100644 versioned_docs/version-0.5.0/user_docs/guides/gitops/1-quick-start.md delete mode 100644 versioned_docs/version-0.5.0/user_docs/guides/gitops/_category_.json delete mode 100644 versioned_docs/version-0.5.0/user_docs/guides/package-management/2-installation.md delete mode 100644 versioned_docs/version-0.5.0/user_docs/guides/package-management/3-quick-start.md delete mode 100644 versioned_docs/version-0.5.0/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md delete mode 100644 versioned_docs/version-0.5.0/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md delete mode 100644 versioned_docs/version-0.5.0/user_docs/guides/package-management/4-how-to/6-push_github_action.md delete mode 100644 versioned_docs/version-0.5.0/user_docs/guides/schema-definition.md delete mode 100644 versioned_docs/version-0.5.0/user_docs/guides/validation.md delete mode 100644 versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md delete mode 100644 versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md delete mode 100644 versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md delete mode 100644 versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json delete mode 100644 versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/_category_.json delete mode 100644 versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/index.md delete mode 100644 versioned_docs/version-0.5.0/user_docs/guides/working-with-konfig/_category_.json delete mode 100644 versioned_docs/version-0.5.0/user_docs/guides/working-with-kusion/_category_.json delete mode 100644 versioned_docs/version-0.5.1/reference/lang/error/exception.md delete mode 100644 versioned_docs/version-0.5.1/reference/lang/spec/codestyle.md delete mode 100644 versioned_docs/version-0.5.1/reference/lang/spec/datatypes.md delete mode 100644 versioned_docs/version-0.5.1/reference/lang/spec/error.md delete mode 100644 versioned_docs/version-0.5.1/reference/lang/spec/expressions.md delete mode 100644 versioned_docs/version-0.5.1/reference/lang/spec/kcl-spec.md delete mode 100644 versioned_docs/version-0.5.1/reference/lang/spec/modules.md delete mode 100644 versioned_docs/version-0.5.1/reference/lang/spec/schema.md delete mode 100644 versioned_docs/version-0.5.1/reference/lang/spec/statements.md delete mode 100644 versioned_docs/version-0.5.1/reference/lang/spec/variables.md delete mode 100644 versioned_docs/version-0.5.1/reference/lang/tour.md delete mode 100644 versioned_docs/version-0.5.1/reference/model/datetime.md delete mode 100644 versioned_docs/version-0.5.1/reference/model/json.md delete mode 100644 versioned_docs/version-0.5.1/reference/model/math.md delete mode 100644 versioned_docs/version-0.5.1/reference/plugin/project_context.md delete mode 100644 versioned_docs/version-0.5.1/reference/xlang-api/go-api.md delete mode 100644 versioned_docs/version-0.5.1/reference/xlang-api/rest-api.md delete mode 100644 versioned_docs/version-0.5.1/tools/Ide/index.md delete mode 100644 versioned_docs/version-0.5.1/tools/Ide/intellij.md delete mode 100644 versioned_docs/version-0.5.1/tools/Ide/vs-code.md delete mode 100644 versioned_docs/version-0.5.1/tools/cli/kcl/fmt.md delete mode 100644 versioned_docs/version-0.5.1/tools/cli/kcl/lint.md delete mode 100644 versioned_docs/version-0.5.1/tools/cli/openapi/quick-start.md delete mode 100644 versioned_docs/version-0.5.1/tools/cli/openapi/spec.md delete mode 100644 versioned_docs/version-0.5.1/user_docs/getting-started/install.md delete mode 100644 versioned_docs/version-0.5.1/user_docs/getting-started/intro.md delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/abstraction.md delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/automation.md delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/ci-integration/1-github-actions.md delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/ci-integration/2-gitlab-ci.md delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/ci-integration/_3-jenkins-ci.md delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/ci-integration/_category_.json delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/configuration.md delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/data-integration.md delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/gitops/1-quick-start.md delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/gitops/_category_.json delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/package-management/2-installation.md delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/package-management/3-quick-start.md delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/package-management/4-how-to/6-push_github_action.md delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/schema-definition.md delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/secret-management/_category_.json delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/validation.md delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/_category_.json delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/index.md delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/working-with-konfig/1-overview.md delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/working-with-konfig/2-structure.md delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/working-with-konfig/3-quick-start.md delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/working-with-konfig/_category_.json delete mode 100644 versioned_docs/version-0.5.1/user_docs/guides/working-with-kusion/_category_.json delete mode 100644 versioned_docs/version-0.5.1/user_docs/support/faq-install.md delete mode 100644 versioned_docs/version-0.5.1/user_docs/support/faq-kcl.md delete mode 100644 versioned_docs/version-0.5.2/community/contribute/git-guideline.md delete mode 100644 versioned_docs/version-0.5.2/community/release-policy/kcl.md delete mode 100644 versioned_docs/version-0.5.2/community/release-policy/roadmap.md delete mode 100644 versioned_docs/version-0.5.2/reference/lang/error/exception.md delete mode 100644 versioned_docs/version-0.5.2/reference/lang/spec/codestyle.md delete mode 100644 versioned_docs/version-0.5.2/reference/lang/spec/datatypes.md delete mode 100644 versioned_docs/version-0.5.2/reference/lang/spec/error.md delete mode 100644 versioned_docs/version-0.5.2/reference/lang/spec/expressions.md delete mode 100644 versioned_docs/version-0.5.2/reference/lang/spec/kcl-spec.md delete mode 100644 versioned_docs/version-0.5.2/reference/lang/spec/modules.md delete mode 100644 versioned_docs/version-0.5.2/reference/lang/spec/schema.md delete mode 100644 versioned_docs/version-0.5.2/reference/lang/spec/statements.md delete mode 100644 versioned_docs/version-0.5.2/reference/lang/spec/variables.md delete mode 100644 versioned_docs/version-0.5.2/reference/lang/tour.md delete mode 100644 versioned_docs/version-0.5.2/reference/model/datetime.md delete mode 100644 versioned_docs/version-0.5.2/reference/model/index.md delete mode 100644 versioned_docs/version-0.5.2/reference/model/json.md delete mode 100644 versioned_docs/version-0.5.2/reference/model/math.md delete mode 100644 versioned_docs/version-0.5.2/reference/model/overview.md delete mode 100644 versioned_docs/version-0.5.2/reference/model/yaml.md delete mode 100644 versioned_docs/version-0.5.2/reference/package-management/_category_.json delete mode 100644 versioned_docs/version-0.5.2/reference/package-management/command-reference/1.init.md delete mode 100644 versioned_docs/version-0.5.2/reference/package-management/command-reference/10.help.md delete mode 100644 versioned_docs/version-0.5.2/reference/package-management/command-reference/2.add.md delete mode 100644 versioned_docs/version-0.5.2/reference/package-management/command-reference/3.pkg.md delete mode 100644 versioned_docs/version-0.5.2/reference/package-management/command-reference/4.metadata.md delete mode 100644 versioned_docs/version-0.5.2/reference/package-management/command-reference/5.run.md delete mode 100644 versioned_docs/version-0.5.2/reference/package-management/command-reference/6.login.md delete mode 100644 versioned_docs/version-0.5.2/reference/package-management/command-reference/7.logout.md delete mode 100644 versioned_docs/version-0.5.2/reference/package-management/command-reference/8.push.md delete mode 100644 versioned_docs/version-0.5.2/reference/package-management/command-reference/9.pull.md delete mode 100644 versioned_docs/version-0.5.2/reference/package-management/command-reference/index.md delete mode 100644 versioned_docs/version-0.5.2/reference/plugin/overview.md delete mode 100644 versioned_docs/version-0.5.2/reference/plugin/project_context.md delete mode 100644 versioned_docs/version-0.5.2/reference/xlang-api/go-api.md delete mode 100644 versioned_docs/version-0.5.2/reference/xlang-api/rest-api.md delete mode 100644 versioned_docs/version-0.5.2/tools/Ide/index.md delete mode 100644 versioned_docs/version-0.5.2/tools/Ide/intellij.md delete mode 100644 versioned_docs/version-0.5.2/tools/Ide/vs-code.md delete mode 100644 versioned_docs/version-0.5.2/tools/cli/kcl/docgen.md delete mode 100644 versioned_docs/version-0.5.2/tools/cli/kcl/fmt.md delete mode 100644 versioned_docs/version-0.5.2/tools/cli/kcl/index.md delete mode 100644 versioned_docs/version-0.5.2/tools/cli/kcl/lint.md delete mode 100644 versioned_docs/version-0.5.2/tools/cli/kcl/test.md delete mode 100644 versioned_docs/version-0.5.2/tools/cli/kcl/vet.md delete mode 100644 versioned_docs/version-0.5.2/tools/cli/openapi/crd-to-kcl.md delete mode 100644 versioned_docs/version-0.5.2/tools/cli/openapi/openapi-to-kcl.md delete mode 100644 versioned_docs/version-0.5.2/tools/cli/openapi/quick-start.md delete mode 100644 versioned_docs/version-0.5.2/tools/cli/openapi/spec.md delete mode 100644 versioned_docs/version-0.5.2/user_docs/concepts/concepts.md delete mode 100644 versioned_docs/version-0.5.2/user_docs/getting-started/index.md delete mode 100644 versioned_docs/version-0.5.2/user_docs/getting-started/install.md delete mode 100644 versioned_docs/version-0.5.2/user_docs/getting-started/intro.md delete mode 100644 versioned_docs/version-0.5.2/user_docs/guides/_working-with-terraform/1-overview.md delete mode 100644 versioned_docs/version-0.5.2/user_docs/guides/_working-with-terraform/2-abstraction.md delete mode 100644 versioned_docs/version-0.5.2/user_docs/guides/_working-with-terraform/3-coverter.md delete mode 100644 versioned_docs/version-0.5.2/user_docs/guides/_working-with-terraform/_category_.json delete mode 100644 versioned_docs/version-0.5.2/user_docs/guides/ci-integration/_3-jenkins-ci.md delete mode 100644 versioned_docs/version-0.5.2/user_docs/guides/ci-integration/_category_.json delete mode 100644 versioned_docs/version-0.5.2/user_docs/guides/gitops/_category_.json delete mode 100644 versioned_docs/version-0.5.2/user_docs/guides/index.md delete mode 100644 versioned_docs/version-0.5.2/user_docs/guides/package-management/1-overview.md delete mode 100644 versioned_docs/version-0.5.2/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md delete mode 100644 versioned_docs/version-0.5.2/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md delete mode 100644 versioned_docs/version-0.5.2/user_docs/guides/package-management/4-how-to/6-push_github_action.md delete mode 100644 versioned_docs/version-0.5.2/user_docs/guides/secret-management/_category_.json delete mode 100644 versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md delete mode 100644 versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md delete mode 100644 versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md delete mode 100644 versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md delete mode 100644 versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json delete mode 100644 versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/_category_.json delete mode 100644 versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/index.md delete mode 100644 versioned_docs/version-0.5.2/user_docs/guides/working-with-konfig/1-overview.md delete mode 100644 versioned_docs/version-0.5.2/user_docs/guides/working-with-konfig/2-structure.md delete mode 100644 versioned_docs/version-0.5.2/user_docs/guides/working-with-konfig/3-quick-start.md delete mode 100644 versioned_docs/version-0.5.2/user_docs/guides/working-with-konfig/_category_.json delete mode 100644 versioned_docs/version-0.5.2/user_docs/guides/working-with-kusion/_category_.json delete mode 100644 versioned_docs/version-0.5.2/user_docs/support/faq-install.md delete mode 100644 versioned_docs/version-0.5.2/user_docs/support/faq-kcl.md delete mode 100644 versioned_docs/version-0.5.2/user_docs/support/support.md delete mode 100644 versioned_docs/version-0.5.3/community/contribute/git-guideline.md delete mode 100644 versioned_docs/version-0.5.3/community/release-policy/kcl.md delete mode 100644 versioned_docs/version-0.5.3/community/release-policy/roadmap.md delete mode 100644 versioned_docs/version-0.5.3/reference/lang/error/exception.md delete mode 100644 versioned_docs/version-0.5.3/reference/lang/spec/codestyle.md delete mode 100644 versioned_docs/version-0.5.3/reference/lang/spec/datatypes.md delete mode 100644 versioned_docs/version-0.5.3/reference/lang/spec/error.md delete mode 100644 versioned_docs/version-0.5.3/reference/lang/spec/expressions.md delete mode 100644 versioned_docs/version-0.5.3/reference/lang/spec/kcl-spec.md delete mode 100644 versioned_docs/version-0.5.3/reference/lang/spec/modules.md delete mode 100644 versioned_docs/version-0.5.3/reference/lang/spec/schema.md delete mode 100644 versioned_docs/version-0.5.3/reference/lang/spec/statements.md delete mode 100644 versioned_docs/version-0.5.3/reference/lang/spec/variables.md delete mode 100644 versioned_docs/version-0.5.3/reference/lang/tour.md delete mode 100644 versioned_docs/version-0.5.3/reference/model/crypto.md delete mode 100644 versioned_docs/version-0.5.3/reference/model/datetime.md delete mode 100644 versioned_docs/version-0.5.3/reference/model/index.md delete mode 100644 versioned_docs/version-0.5.3/reference/model/json.md delete mode 100644 versioned_docs/version-0.5.3/reference/model/math.md delete mode 100644 versioned_docs/version-0.5.3/reference/model/overview.md delete mode 100644 versioned_docs/version-0.5.3/reference/model/yaml.md delete mode 100644 versioned_docs/version-0.5.3/reference/package-management/_category_.json delete mode 100644 versioned_docs/version-0.5.3/reference/package-management/command-reference/1.init.md delete mode 100644 versioned_docs/version-0.5.3/reference/package-management/command-reference/10.help.md delete mode 100644 versioned_docs/version-0.5.3/reference/package-management/command-reference/2.add.md delete mode 100644 versioned_docs/version-0.5.3/reference/package-management/command-reference/3.pkg.md delete mode 100644 versioned_docs/version-0.5.3/reference/package-management/command-reference/4.metadata.md delete mode 100644 versioned_docs/version-0.5.3/reference/package-management/command-reference/5.run.md delete mode 100644 versioned_docs/version-0.5.3/reference/package-management/command-reference/6.login.md delete mode 100644 versioned_docs/version-0.5.3/reference/package-management/command-reference/7.logout.md delete mode 100644 versioned_docs/version-0.5.3/reference/package-management/command-reference/8.push.md delete mode 100644 versioned_docs/version-0.5.3/reference/package-management/command-reference/9.pull.md delete mode 100644 versioned_docs/version-0.5.3/reference/package-management/command-reference/index.md delete mode 100644 versioned_docs/version-0.5.3/reference/plugin/index.md delete mode 100644 versioned_docs/version-0.5.3/reference/plugin/overview.md delete mode 100644 versioned_docs/version-0.5.3/reference/plugin/project_context.md delete mode 100644 versioned_docs/version-0.5.3/reference/xlang-api/go-api.md delete mode 100644 versioned_docs/version-0.5.3/reference/xlang-api/index.md delete mode 100644 versioned_docs/version-0.5.3/reference/xlang-api/overview.md delete mode 100644 versioned_docs/version-0.5.3/reference/xlang-api/rest-api.md delete mode 100644 versioned_docs/version-0.5.3/tools/Ide/index.md delete mode 100644 versioned_docs/version-0.5.3/tools/Ide/intellij.md delete mode 100644 versioned_docs/version-0.5.3/tools/Ide/vs-code.md delete mode 100644 versioned_docs/version-0.5.3/tools/cli/kcl/docgen.md delete mode 100644 versioned_docs/version-0.5.3/tools/cli/kcl/fmt.md delete mode 100644 versioned_docs/version-0.5.3/tools/cli/kcl/index.md delete mode 100644 versioned_docs/version-0.5.3/tools/cli/kcl/lint.md delete mode 100644 versioned_docs/version-0.5.3/tools/cli/kcl/overview.md delete mode 100644 versioned_docs/version-0.5.3/tools/cli/kcl/test.md delete mode 100644 versioned_docs/version-0.5.3/tools/cli/kcl/vet.md delete mode 100644 versioned_docs/version-0.5.3/tools/cli/openapi/crd-to-kcl.md delete mode 100644 versioned_docs/version-0.5.3/tools/cli/openapi/index.md delete mode 100644 versioned_docs/version-0.5.3/tools/cli/openapi/openapi-to-kcl.md delete mode 100644 versioned_docs/version-0.5.3/tools/cli/openapi/quick-start.md delete mode 100644 versioned_docs/version-0.5.3/tools/cli/openapi/spec.md delete mode 100644 versioned_docs/version-0.5.3/user_docs/concepts/concepts.md delete mode 100644 versioned_docs/version-0.5.3/user_docs/getting-started/index.md delete mode 100644 versioned_docs/version-0.5.3/user_docs/getting-started/install.md delete mode 100644 versioned_docs/version-0.5.3/user_docs/getting-started/intro.md delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/_working-with-terraform/1-overview.md delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/_working-with-terraform/2-abstraction.md delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/_working-with-terraform/3-coverter.md delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/_working-with-terraform/_category_.json delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/ci-integration/_3-jenkins-ci.md delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/ci-integration/_category_.json delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/gitops/_category_.json delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/index.md delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/package-management/1-overview.md delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/package-management/4-how-to/6-push_github_action.md delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/package-management/4-how-to/_category_.json delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/secret-management/_category_.json delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/_category_.json delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/index.md delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/working-with-konfig/1-overview.md delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/working-with-konfig/2-structure.md delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/working-with-konfig/3-quick-start.md delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/working-with-konfig/_category_.json delete mode 100644 versioned_docs/version-0.5.3/user_docs/guides/working-with-kusion/_category_.json delete mode 100644 versioned_docs/version-0.5.3/user_docs/support/faq-install.md delete mode 100644 versioned_docs/version-0.5.3/user_docs/support/faq-kcl.md delete mode 100644 versioned_docs/version-0.5.3/user_docs/support/support.md delete mode 100644 versioned_docs/version-0.5.4/community/contribute/_category_.json delete mode 100644 versioned_docs/version-0.5.4/community/contribute/contribute-code.md delete mode 100644 versioned_docs/version-0.5.4/community/contribute/contribute-docs.md delete mode 100644 versioned_docs/version-0.5.4/community/contribute/contribute.md delete mode 100644 versioned_docs/version-0.5.4/community/contribute/git-guideline.md delete mode 100644 versioned_docs/version-0.5.4/community/intro/_category_.json delete mode 100644 versioned_docs/version-0.5.4/community/intro/intro.md delete mode 100644 versioned_docs/version-0.5.4/community/intro/license.md delete mode 100644 versioned_docs/version-0.5.4/community/intro/support.md delete mode 100644 versioned_docs/version-0.5.4/community/release-policy/_category_.json delete mode 100644 versioned_docs/version-0.5.4/community/release-policy/index.md delete mode 100644 versioned_docs/version-0.5.4/community/release-policy/kcl.md delete mode 100644 versioned_docs/version-0.5.4/community/release-policy/roadmap.md delete mode 100644 versioned_docs/version-0.5.4/reference/_advanced-concepts/_category_.json delete mode 100644 versioned_docs/version-0.5.4/reference/_advanced-concepts/build_cache.md delete mode 100644 versioned_docs/version-0.5.4/reference/_category_.json delete mode 100644 versioned_docs/version-0.5.4/reference/cheatsheets/_category_.json delete mode 100644 versioned_docs/version-0.5.4/reference/cheatsheets/index.md delete mode 100644 versioned_docs/version-0.5.4/reference/lang/_category_.json delete mode 100644 versioned_docs/version-0.5.4/reference/lang/codelab/_category_.json delete mode 100644 versioned_docs/version-0.5.4/reference/lang/codelab/collaborative.md delete mode 100644 versioned_docs/version-0.5.4/reference/lang/codelab/index.md delete mode 100644 versioned_docs/version-0.5.4/reference/lang/codelab/schema.md delete mode 100644 versioned_docs/version-0.5.4/reference/lang/codelab/simple.md delete mode 100644 versioned_docs/version-0.5.4/reference/lang/error/_category_.json delete mode 100644 versioned_docs/version-0.5.4/reference/lang/error/exception.md delete mode 100644 versioned_docs/version-0.5.4/reference/lang/error/index.md delete mode 100644 versioned_docs/version-0.5.4/reference/lang/spec/_category_.json delete mode 100644 versioned_docs/version-0.5.4/reference/lang/spec/codestyle.md delete mode 100644 versioned_docs/version-0.5.4/reference/lang/spec/datatypes.md delete mode 100644 versioned_docs/version-0.5.4/reference/lang/spec/error.md delete mode 100644 versioned_docs/version-0.5.4/reference/lang/spec/expressions.md delete mode 100644 versioned_docs/version-0.5.4/reference/lang/spec/index.md delete mode 100644 versioned_docs/version-0.5.4/reference/lang/spec/kcl-spec.md delete mode 100644 versioned_docs/version-0.5.4/reference/lang/spec/lexical.md delete mode 100644 versioned_docs/version-0.5.4/reference/lang/spec/modules.md delete mode 100644 versioned_docs/version-0.5.4/reference/lang/spec/schema.md delete mode 100644 versioned_docs/version-0.5.4/reference/lang/spec/statements.md delete mode 100644 versioned_docs/version-0.5.4/reference/lang/spec/variables.md delete mode 100644 versioned_docs/version-0.5.4/reference/lang/tour.md delete mode 100644 versioned_docs/version-0.5.4/reference/lang/types/_category_.json delete mode 100644 versioned_docs/version-0.5.4/reference/lang/types/types.md delete mode 100644 versioned_docs/version-0.5.4/reference/model/_category_.json delete mode 100644 versioned_docs/version-0.5.4/reference/model/base64.md delete mode 100644 versioned_docs/version-0.5.4/reference/model/builtin.md delete mode 100644 versioned_docs/version-0.5.4/reference/model/crypto.md delete mode 100644 versioned_docs/version-0.5.4/reference/model/datetime.md delete mode 100644 versioned_docs/version-0.5.4/reference/model/index.md delete mode 100644 versioned_docs/version-0.5.4/reference/model/json.md delete mode 100644 versioned_docs/version-0.5.4/reference/model/manifests.md delete mode 100644 versioned_docs/version-0.5.4/reference/model/math.md delete mode 100644 versioned_docs/version-0.5.4/reference/model/net.md delete mode 100644 versioned_docs/version-0.5.4/reference/model/overview.md delete mode 100644 versioned_docs/version-0.5.4/reference/model/regex.md delete mode 100644 versioned_docs/version-0.5.4/reference/model/units.md delete mode 100644 versioned_docs/version-0.5.4/reference/model/yaml.md delete mode 100644 versioned_docs/version-0.5.4/reference/package-management/_category_.json delete mode 100644 versioned_docs/version-0.5.4/reference/package-management/command-reference/1.init.md delete mode 100644 versioned_docs/version-0.5.4/reference/package-management/command-reference/10.help.md delete mode 100644 versioned_docs/version-0.5.4/reference/package-management/command-reference/2.add.md delete mode 100644 versioned_docs/version-0.5.4/reference/package-management/command-reference/3.pkg.md delete mode 100644 versioned_docs/version-0.5.4/reference/package-management/command-reference/4.metadata.md delete mode 100644 versioned_docs/version-0.5.4/reference/package-management/command-reference/5.run.md delete mode 100644 versioned_docs/version-0.5.4/reference/package-management/command-reference/6.login.md delete mode 100644 versioned_docs/version-0.5.4/reference/package-management/command-reference/7.logout.md delete mode 100644 versioned_docs/version-0.5.4/reference/package-management/command-reference/8.push.md delete mode 100644 versioned_docs/version-0.5.4/reference/package-management/command-reference/9.pull.md delete mode 100644 versioned_docs/version-0.5.4/reference/package-management/command-reference/_category_.json delete mode 100644 versioned_docs/version-0.5.4/reference/package-management/command-reference/index.md delete mode 100644 versioned_docs/version-0.5.4/reference/plugin/_category_.json delete mode 100644 versioned_docs/version-0.5.4/reference/plugin/index.md delete mode 100644 versioned_docs/version-0.5.4/reference/plugin/overview.md delete mode 100644 versioned_docs/version-0.5.4/reference/plugin/project_context.md delete mode 100644 versioned_docs/version-0.5.4/reference/xlang-api/_category_.json delete mode 100644 versioned_docs/version-0.5.4/reference/xlang-api/go-api.md delete mode 100644 versioned_docs/version-0.5.4/reference/xlang-api/index.md delete mode 100644 versioned_docs/version-0.5.4/reference/xlang-api/java-api.md delete mode 100644 versioned_docs/version-0.5.4/reference/xlang-api/overview.md delete mode 100644 versioned_docs/version-0.5.4/reference/xlang-api/python-api.md delete mode 100644 versioned_docs/version-0.5.4/reference/xlang-api/rest-api.md delete mode 100644 versioned_docs/version-0.5.4/tools/Ide/_category_.json delete mode 100644 versioned_docs/version-0.5.4/tools/Ide/index.md delete mode 100644 versioned_docs/version-0.5.4/tools/Ide/intellij.md delete mode 100644 versioned_docs/version-0.5.4/tools/Ide/vs-code.md delete mode 100644 versioned_docs/version-0.5.4/tools/_category_.json delete mode 100644 versioned_docs/version-0.5.4/tools/cli/_category_.json delete mode 100644 versioned_docs/version-0.5.4/tools/cli/index.md delete mode 100644 versioned_docs/version-0.5.4/tools/cli/kcl/_category_.json delete mode 100644 versioned_docs/version-0.5.4/tools/cli/kcl/docgen.md delete mode 100644 versioned_docs/version-0.5.4/tools/cli/kcl/fmt.md delete mode 100644 versioned_docs/version-0.5.4/tools/cli/kcl/index.md delete mode 100644 versioned_docs/version-0.5.4/tools/cli/kcl/lint.md delete mode 100644 versioned_docs/version-0.5.4/tools/cli/kcl/overview.md delete mode 100644 versioned_docs/version-0.5.4/tools/cli/kcl/test.md delete mode 100644 versioned_docs/version-0.5.4/tools/cli/kcl/vet.md delete mode 100644 versioned_docs/version-0.5.4/tools/cli/openapi/_category_.json delete mode 100644 versioned_docs/version-0.5.4/tools/cli/openapi/crd-to-kcl.md delete mode 100644 versioned_docs/version-0.5.4/tools/cli/openapi/index.md delete mode 100644 versioned_docs/version-0.5.4/tools/cli/openapi/openapi-to-kcl.md delete mode 100644 versioned_docs/version-0.5.4/tools/cli/openapi/quick-start.md delete mode 100644 versioned_docs/version-0.5.4/tools/cli/openapi/spec.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/concepts/_category_.json delete mode 100644 versioned_docs/version-0.5.4/user_docs/concepts/concepts.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/concepts/package-and-module.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/getting-started/_category_.json delete mode 100644 versioned_docs/version-0.5.4/user_docs/getting-started/index.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/getting-started/install.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/getting-started/intro.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/getting-started/kcl-quick-start.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/_category_.json delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/_working-with-terraform/1-overview.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/_working-with-terraform/2-abstraction.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/_working-with-terraform/3-coverter.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/_working-with-terraform/_category_.json delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/automation.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/ci-integration/_3-jenkins-ci.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/ci-integration/_category_.json delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/configuration.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/gitops/_category_.json delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/index.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/package-management/1-overview.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/package-management/2-installation.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/package-management/3-quick-start.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/package-management/4-how-to/6-push_github_action.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/package-management/4-how-to/_category_.json delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/package-management/_category_.json delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/secret-management/_category_.json delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/validation.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/_category_.json delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/index.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/working-with-konfig/1-overview.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/working-with-konfig/2-structure.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/working-with-konfig/3-quick-start.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/working-with-konfig/4-best-practice.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/working-with-konfig/_category_.json delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/working-with-kusion/_category_.json delete mode 100644 versioned_docs/version-0.5.4/user_docs/guides/working-with-kusion/index.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/support/_category_.json delete mode 100644 versioned_docs/version-0.5.4/user_docs/support/faq-cli.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/support/faq-install.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/support/faq-kcl.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/support/faq-yaml.md delete mode 100644 versioned_docs/version-0.5.4/user_docs/support/support.md delete mode 100644 versioned_docs/version-0.5.5/community/contribute/_category_.json delete mode 100644 versioned_docs/version-0.5.5/community/contribute/contribute-code.md delete mode 100644 versioned_docs/version-0.5.5/community/contribute/contribute-docs.md delete mode 100644 versioned_docs/version-0.5.5/community/contribute/contribute.md delete mode 100644 versioned_docs/version-0.5.5/community/contribute/git-guideline.md delete mode 100644 versioned_docs/version-0.5.5/community/intro/_category_.json delete mode 100644 versioned_docs/version-0.5.5/community/intro/intro.md delete mode 100644 versioned_docs/version-0.5.5/community/intro/license.md delete mode 100644 versioned_docs/version-0.5.5/community/intro/support.md delete mode 100644 versioned_docs/version-0.5.5/community/release-policy/_category_.json delete mode 100644 versioned_docs/version-0.5.5/community/release-policy/index.md delete mode 100644 versioned_docs/version-0.5.5/community/release-policy/kcl.md delete mode 100644 versioned_docs/version-0.5.5/community/release-policy/roadmap.md delete mode 100644 versioned_docs/version-0.5.5/reference/_advanced-concepts/_category_.json delete mode 100644 versioned_docs/version-0.5.5/reference/_advanced-concepts/build_cache.md delete mode 100644 versioned_docs/version-0.5.5/reference/_category_.json delete mode 100644 versioned_docs/version-0.5.5/reference/cheatsheets/_category_.json delete mode 100644 versioned_docs/version-0.5.5/reference/cheatsheets/index.md delete mode 100644 versioned_docs/version-0.5.5/reference/lang/_category_.json delete mode 100644 versioned_docs/version-0.5.5/reference/lang/codelab/_category_.json delete mode 100644 versioned_docs/version-0.5.5/reference/lang/codelab/collaborative.md delete mode 100644 versioned_docs/version-0.5.5/reference/lang/codelab/index.md delete mode 100644 versioned_docs/version-0.5.5/reference/lang/codelab/schema.md delete mode 100644 versioned_docs/version-0.5.5/reference/lang/codelab/simple.md delete mode 100644 versioned_docs/version-0.5.5/reference/lang/error/_category_.json delete mode 100644 versioned_docs/version-0.5.5/reference/lang/error/exception.md delete mode 100644 versioned_docs/version-0.5.5/reference/lang/error/index.md delete mode 100644 versioned_docs/version-0.5.5/reference/lang/spec/_category_.json delete mode 100644 versioned_docs/version-0.5.5/reference/lang/spec/codestyle.md delete mode 100644 versioned_docs/version-0.5.5/reference/lang/spec/datatypes.md delete mode 100644 versioned_docs/version-0.5.5/reference/lang/spec/error.md delete mode 100644 versioned_docs/version-0.5.5/reference/lang/spec/index.md delete mode 100644 versioned_docs/version-0.5.5/reference/lang/spec/kcl-spec.md delete mode 100644 versioned_docs/version-0.5.5/reference/lang/spec/lexical.md delete mode 100644 versioned_docs/version-0.5.5/reference/lang/spec/modules.md delete mode 100644 versioned_docs/version-0.5.5/reference/lang/spec/schema.md delete mode 100644 versioned_docs/version-0.5.5/reference/lang/spec/statements.md delete mode 100644 versioned_docs/version-0.5.5/reference/lang/spec/variables.md delete mode 100644 versioned_docs/version-0.5.5/reference/lang/tour.md delete mode 100644 versioned_docs/version-0.5.5/reference/lang/types/_category_.json delete mode 100644 versioned_docs/version-0.5.5/reference/lang/types/types.md delete mode 100644 versioned_docs/version-0.5.5/reference/model/_category_.json delete mode 100644 versioned_docs/version-0.5.5/reference/model/base64.md delete mode 100644 versioned_docs/version-0.5.5/reference/model/builtin.md delete mode 100644 versioned_docs/version-0.5.5/reference/model/crypto.md delete mode 100644 versioned_docs/version-0.5.5/reference/model/datetime.md delete mode 100644 versioned_docs/version-0.5.5/reference/model/index.md delete mode 100644 versioned_docs/version-0.5.5/reference/model/json.md delete mode 100644 versioned_docs/version-0.5.5/reference/model/manifests.md delete mode 100644 versioned_docs/version-0.5.5/reference/model/math.md delete mode 100644 versioned_docs/version-0.5.5/reference/model/net.md delete mode 100644 versioned_docs/version-0.5.5/reference/model/overview.md delete mode 100644 versioned_docs/version-0.5.5/reference/model/regex.md delete mode 100644 versioned_docs/version-0.5.5/reference/model/units.md delete mode 100644 versioned_docs/version-0.5.5/reference/model/yaml.md delete mode 100644 versioned_docs/version-0.5.5/reference/package-management/_category_.json delete mode 100644 versioned_docs/version-0.5.5/reference/package-management/command-reference/1.init.md delete mode 100644 versioned_docs/version-0.5.5/reference/package-management/command-reference/10.help.md delete mode 100644 versioned_docs/version-0.5.5/reference/package-management/command-reference/2.add.md delete mode 100644 versioned_docs/version-0.5.5/reference/package-management/command-reference/3.pkg.md delete mode 100644 versioned_docs/version-0.5.5/reference/package-management/command-reference/4.metadata.md delete mode 100644 versioned_docs/version-0.5.5/reference/package-management/command-reference/5.run.md delete mode 100644 versioned_docs/version-0.5.5/reference/package-management/command-reference/6.login.md delete mode 100644 versioned_docs/version-0.5.5/reference/package-management/command-reference/7.logout.md delete mode 100644 versioned_docs/version-0.5.5/reference/package-management/command-reference/8.push.md delete mode 100644 versioned_docs/version-0.5.5/reference/package-management/command-reference/9.pull.md delete mode 100644 versioned_docs/version-0.5.5/reference/package-management/command-reference/_category_.json delete mode 100644 versioned_docs/version-0.5.5/reference/package-management/command-reference/index.md delete mode 100644 versioned_docs/version-0.5.5/reference/plugin/_category_.json delete mode 100644 versioned_docs/version-0.5.5/reference/plugin/index.md delete mode 100644 versioned_docs/version-0.5.5/reference/plugin/overview.md delete mode 100644 versioned_docs/version-0.5.5/reference/plugin/project_context.md delete mode 100644 versioned_docs/version-0.5.5/reference/xlang-api/_category_.json delete mode 100644 versioned_docs/version-0.5.5/reference/xlang-api/go-api.md delete mode 100644 versioned_docs/version-0.5.5/reference/xlang-api/index.md delete mode 100644 versioned_docs/version-0.5.5/reference/xlang-api/java-api.md delete mode 100644 versioned_docs/version-0.5.5/reference/xlang-api/overview.md delete mode 100644 versioned_docs/version-0.5.5/reference/xlang-api/python-api.md delete mode 100644 versioned_docs/version-0.5.5/tools/Ide/_category_.json delete mode 100644 versioned_docs/version-0.5.5/tools/Ide/index.md delete mode 100644 versioned_docs/version-0.5.5/tools/_category_.json delete mode 100644 versioned_docs/version-0.5.5/tools/cli/_category_.json delete mode 100644 versioned_docs/version-0.5.5/tools/cli/index.md delete mode 100644 versioned_docs/version-0.5.5/tools/cli/kcl/_category_.json delete mode 100644 versioned_docs/version-0.5.5/tools/cli/kcl/docgen.md delete mode 100644 versioned_docs/version-0.5.5/tools/cli/kcl/index.md delete mode 100644 versioned_docs/version-0.5.5/tools/cli/kcl/overview.md delete mode 100644 versioned_docs/version-0.5.5/tools/cli/kcl/test.md delete mode 100644 versioned_docs/version-0.5.5/tools/cli/kcl/vet.md delete mode 100644 versioned_docs/version-0.5.5/tools/cli/openapi/_category_.json delete mode 100644 versioned_docs/version-0.5.5/tools/cli/openapi/crd-to-kcl.md delete mode 100644 versioned_docs/version-0.5.5/tools/cli/openapi/index.md delete mode 100644 versioned_docs/version-0.5.5/tools/cli/openapi/openapi-to-kcl.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/concepts/_category_.json delete mode 100644 versioned_docs/version-0.5.5/user_docs/concepts/concepts.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/concepts/package-and-module.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/getting-started/_category_.json delete mode 100644 versioned_docs/version-0.5.5/user_docs/getting-started/index.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/getting-started/intro.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/getting-started/kcl-quick-start.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/_category_.json delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/_working-with-terraform/1-overview.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/_working-with-terraform/2-abstraction.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/_working-with-terraform/3-coverter.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/_working-with-terraform/_category_.json delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/automation.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/ci-integration/_3-jenkins-ci.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/ci-integration/_category_.json delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/configuration.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/gitops/1-quick-start.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/gitops/_category_.json delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/index.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/package-management/1-overview.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/package-management/2-installation.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/package-management/3-quick-start.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/package-management/4-how-to/6-push_github_action.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/package-management/4-how-to/_category_.json delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/package-management/_category_.json delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/secret-management/1-vault.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/secret-management/_category_.json delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/validation.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/_category_.json delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/index.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/working-with-konfig/1-overview.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/working-with-konfig/2-structure.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/working-with-konfig/3-quick-start.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/working-with-konfig/4-best-practice.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/working-with-konfig/_category_.json delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/working-with-kusion/_category_.json delete mode 100644 versioned_docs/version-0.5.5/user_docs/guides/working-with-kusion/index.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/support/_category_.json delete mode 100644 versioned_docs/version-0.5.5/user_docs/support/faq-cli.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/support/faq-install.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/support/faq-kcl.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/support/faq-yaml.md delete mode 100644 versioned_docs/version-0.5.5/user_docs/support/support.md delete mode 100644 versioned_docs/version-0.5.6/community/contribute/_category_.json delete mode 100644 versioned_docs/version-0.5.6/community/contribute/contribute-code.md delete mode 100644 versioned_docs/version-0.5.6/community/contribute/contribute-docs.md delete mode 100644 versioned_docs/version-0.5.6/community/contribute/contribute.md delete mode 100644 versioned_docs/version-0.5.6/community/contribute/git-guideline.md delete mode 100644 versioned_docs/version-0.5.6/community/intro/_category_.json delete mode 100644 versioned_docs/version-0.5.6/community/intro/intro.md delete mode 100644 versioned_docs/version-0.5.6/community/intro/license.md delete mode 100644 versioned_docs/version-0.5.6/community/intro/support.md delete mode 100644 versioned_docs/version-0.5.6/community/release-policy/_category_.json delete mode 100644 versioned_docs/version-0.5.6/community/release-policy/index.md delete mode 100644 versioned_docs/version-0.5.6/community/release-policy/kcl.md delete mode 100644 versioned_docs/version-0.5.6/community/release-policy/roadmap.md delete mode 100644 versioned_docs/version-0.5.6/reference/_advanced-concepts/_category_.json delete mode 100644 versioned_docs/version-0.5.6/reference/_advanced-concepts/build_cache.md delete mode 100644 versioned_docs/version-0.5.6/reference/_category_.json delete mode 100644 versioned_docs/version-0.5.6/reference/cheatsheets/_category_.json delete mode 100644 versioned_docs/version-0.5.6/reference/cheatsheets/index.md delete mode 100644 versioned_docs/version-0.5.6/reference/lang/_category_.json delete mode 100644 versioned_docs/version-0.5.6/reference/lang/codelab/_category_.json delete mode 100644 versioned_docs/version-0.5.6/reference/lang/codelab/collaborative.md delete mode 100644 versioned_docs/version-0.5.6/reference/lang/codelab/index.md delete mode 100644 versioned_docs/version-0.5.6/reference/lang/codelab/schema.md delete mode 100644 versioned_docs/version-0.5.6/reference/lang/codelab/simple.md delete mode 100644 versioned_docs/version-0.5.6/reference/lang/error/_category_.json delete mode 100644 versioned_docs/version-0.5.6/reference/lang/error/index.md delete mode 100644 versioned_docs/version-0.5.6/reference/lang/spec/_category_.json delete mode 100644 versioned_docs/version-0.5.6/reference/lang/spec/codestyle.md delete mode 100644 versioned_docs/version-0.5.6/reference/lang/spec/datatypes.md delete mode 100644 versioned_docs/version-0.5.6/reference/lang/spec/error.md delete mode 100644 versioned_docs/version-0.5.6/reference/lang/spec/index.md delete mode 100644 versioned_docs/version-0.5.6/reference/lang/spec/kcl-spec.md delete mode 100644 versioned_docs/version-0.5.6/reference/lang/spec/lexical.md delete mode 100644 versioned_docs/version-0.5.6/reference/lang/spec/modules.md delete mode 100644 versioned_docs/version-0.5.6/reference/lang/spec/schema.md delete mode 100644 versioned_docs/version-0.5.6/reference/lang/spec/statements.md delete mode 100644 versioned_docs/version-0.5.6/reference/lang/spec/variables.md delete mode 100644 versioned_docs/version-0.5.6/reference/lang/types/_category_.json delete mode 100644 versioned_docs/version-0.5.6/reference/lang/types/types.md delete mode 100644 versioned_docs/version-0.5.6/reference/model/_category_.json delete mode 100644 versioned_docs/version-0.5.6/reference/model/base64.md delete mode 100644 versioned_docs/version-0.5.6/reference/model/builtin.md delete mode 100644 versioned_docs/version-0.5.6/reference/model/crypto.md delete mode 100644 versioned_docs/version-0.5.6/reference/model/index.md delete mode 100644 versioned_docs/version-0.5.6/reference/model/manifests.md delete mode 100644 versioned_docs/version-0.5.6/reference/model/net.md delete mode 100644 versioned_docs/version-0.5.6/reference/model/overview.md delete mode 100644 versioned_docs/version-0.5.6/reference/model/regex.md delete mode 100644 versioned_docs/version-0.5.6/reference/model/units.md delete mode 100644 versioned_docs/version-0.5.6/reference/model/yaml.md delete mode 100644 versioned_docs/version-0.5.6/reference/package-management/_category_.json delete mode 100644 versioned_docs/version-0.5.6/reference/package-management/command-reference/1.init.md delete mode 100644 versioned_docs/version-0.5.6/reference/package-management/command-reference/10.help.md delete mode 100644 versioned_docs/version-0.5.6/reference/package-management/command-reference/2.add.md delete mode 100644 versioned_docs/version-0.5.6/reference/package-management/command-reference/3.pkg.md delete mode 100644 versioned_docs/version-0.5.6/reference/package-management/command-reference/4.metadata.md delete mode 100644 versioned_docs/version-0.5.6/reference/package-management/command-reference/5.run.md delete mode 100644 versioned_docs/version-0.5.6/reference/package-management/command-reference/6.login.md delete mode 100644 versioned_docs/version-0.5.6/reference/package-management/command-reference/7.logout.md delete mode 100644 versioned_docs/version-0.5.6/reference/package-management/command-reference/8.push.md delete mode 100644 versioned_docs/version-0.5.6/reference/package-management/command-reference/9.pull.md delete mode 100644 versioned_docs/version-0.5.6/reference/package-management/command-reference/_category_.json delete mode 100644 versioned_docs/version-0.5.6/reference/package-management/command-reference/index.md delete mode 100644 versioned_docs/version-0.5.6/reference/plugin/_category_.json delete mode 100644 versioned_docs/version-0.5.6/reference/plugin/index.md delete mode 100644 versioned_docs/version-0.5.6/reference/plugin/overview.md delete mode 100644 versioned_docs/version-0.5.6/reference/plugin/project_context.md delete mode 100644 versioned_docs/version-0.5.6/reference/xlang-api/_category_.json delete mode 100644 versioned_docs/version-0.5.6/reference/xlang-api/go-api.md delete mode 100644 versioned_docs/version-0.5.6/reference/xlang-api/index.md delete mode 100644 versioned_docs/version-0.5.6/reference/xlang-api/java-api.md delete mode 100644 versioned_docs/version-0.5.6/reference/xlang-api/overview.md delete mode 100644 versioned_docs/version-0.5.6/reference/xlang-api/python-api.md delete mode 100644 versioned_docs/version-0.5.6/tools/Ide/_category_.json delete mode 100644 versioned_docs/version-0.5.6/tools/Ide/index.md delete mode 100644 versioned_docs/version-0.5.6/tools/Ide/vs-code.md delete mode 100644 versioned_docs/version-0.5.6/tools/_category_.json delete mode 100644 versioned_docs/version-0.5.6/tools/cli/_category_.json delete mode 100644 versioned_docs/version-0.5.6/tools/cli/index.md delete mode 100644 versioned_docs/version-0.5.6/tools/cli/kcl/_category_.json delete mode 100644 versioned_docs/version-0.5.6/tools/cli/kcl/docgen.md delete mode 100644 versioned_docs/version-0.5.6/tools/cli/kcl/index.md delete mode 100644 versioned_docs/version-0.5.6/tools/cli/kcl/overview.md delete mode 100644 versioned_docs/version-0.5.6/tools/cli/kcl/test.md delete mode 100644 versioned_docs/version-0.5.6/tools/cli/kcl/vet.md delete mode 100644 versioned_docs/version-0.5.6/tools/cli/openapi/_category_.json delete mode 100644 versioned_docs/version-0.5.6/tools/cli/openapi/crd-to-kcl.md delete mode 100644 versioned_docs/version-0.5.6/tools/cli/openapi/index.md delete mode 100644 versioned_docs/version-0.5.6/tools/cli/openapi/openapi-to-kcl.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/concepts/_category_.json delete mode 100644 versioned_docs/version-0.5.6/user_docs/concepts/concepts.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/concepts/package-and-module.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/getting-started/_category_.json delete mode 100644 versioned_docs/version-0.5.6/user_docs/getting-started/index.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/getting-started/install.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/getting-started/intro.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/getting-started/kcl-quick-start.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/_category_.json delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/_working-with-terraform/1-overview.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/_working-with-terraform/2-abstraction.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/_working-with-terraform/3-coverter.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/_working-with-terraform/_category_.json delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/abstraction.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/automation.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/ci-integration/1-github-actions.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/ci-integration/2-gitlab-ci.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/ci-integration/_3-jenkins-ci.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/ci-integration/_category_.json delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/configuration.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/data-integration.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/gitops/1-quick-start.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/gitops/_category_.json delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/index.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/package-management/1-overview.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/package-management/2-installation.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/package-management/3-quick-start.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/package-management/_category_.json delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/schema-definition.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/secret-management/1-vault.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/secret-management/_category_.json delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/validation.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/_category_.json delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/index.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/working-with-konfig/1-overview.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/working-with-konfig/2-structure.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/working-with-konfig/3-quick-start.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/working-with-konfig/4-best-practice.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/working-with-konfig/_category_.json delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/working-with-kusion/_category_.json delete mode 100644 versioned_docs/version-0.5.6/user_docs/guides/working-with-kusion/index.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/support/_category_.json delete mode 100644 versioned_docs/version-0.5.6/user_docs/support/faq-cli.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/support/faq-install.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/support/faq-kcl.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/support/faq-yaml.md delete mode 100644 versioned_docs/version-0.5.6/user_docs/support/support.md rename versioned_docs/{version-0.5.0 => version-0.5}/community/contribute/_category_.json (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/community/contribute/contribute-code.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/community/contribute/contribute-docs.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/community/contribute/contribute.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/community/contribute/git-guideline.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/community/intro/_category_.json (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/community/intro/intro.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/community/intro/license.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/community/intro/support.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/community/release-policy/_category_.json (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/community/release-policy/index.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/community/release-policy/kcl.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/community/release-policy/roadmap.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/_advanced-concepts/_category_.json (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/_advanced-concepts/build_cache.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/_category_.json (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/cheatsheets/_category_.json (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/cheatsheets/index.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/lang/_category_.json (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/lang/codelab/_category_.json (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/lang/codelab/collaborative.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/lang/codelab/index.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/lang/codelab/schema.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/lang/codelab/simple.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/lang/error/_category_.json (100%) rename versioned_docs/{version-0.5.6 => version-0.5}/reference/lang/error/exception.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/lang/error/index.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/lang/spec/_category_.json (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3 => versioned_docs/version-0.5}/reference/lang/spec/codestyle.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4 => versioned_docs/version-0.5}/reference/lang/spec/datatypes.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2 => versioned_docs/version-0.5}/reference/lang/spec/error.md (100%) rename versioned_docs/{version-0.5.5 => version-0.5}/reference/lang/spec/expressions.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/lang/spec/index.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2 => versioned_docs/version-0.5}/reference/lang/spec/kcl-spec.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/lang/spec/lexical.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2 => versioned_docs/version-0.5}/reference/lang/spec/modules.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2 => versioned_docs/version-0.5}/reference/lang/spec/schema.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2 => versioned_docs/version-0.5}/reference/lang/spec/statements.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4 => versioned_docs/version-0.5}/reference/lang/spec/variables.md (100%) rename versioned_docs/{version-0.5.6 => version-0.5}/reference/lang/tour.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/lang/types/_category_.json (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/lang/types/types.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/model/_category_.json (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/model/base64.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/model/builtin.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/model/crypto.md (100%) rename versioned_docs/{version-0.5.6 => version-0.5}/reference/model/datetime.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/model/index.md (100%) rename versioned_docs/{version-0.5.6 => version-0.5}/reference/model/json.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/model/manifests.md (100%) rename versioned_docs/{version-0.5.6 => version-0.5}/reference/model/math.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/model/net.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/model/overview.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/model/regex.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/model/units.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/model/yaml.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/package-management/_category_.json (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/package-management/command-reference/1.init.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/package-management/command-reference/10.help.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/package-management/command-reference/2.add.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/package-management/command-reference/3.pkg.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/package-management/command-reference/4.metadata.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/package-management/command-reference/5.run.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/package-management/command-reference/6.login.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/package-management/command-reference/7.logout.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/package-management/command-reference/8.push.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/package-management/command-reference/9.pull.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/package-management/command-reference/_category_.json (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/package-management/command-reference/index.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/plugin/_category_.json (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/plugin/index.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/plugin/overview.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3 => versioned_docs/version-0.5}/reference/plugin/project_context.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/xlang-api/_category_.json (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2 => versioned_docs/version-0.5}/reference/xlang-api/go-api.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/xlang-api/index.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/xlang-api/java-api.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/xlang-api/overview.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/reference/xlang-api/python-api.md (100%) rename versioned_docs/{version-0.5.5 => version-0.5}/reference/xlang-api/rest-api.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/tools/Ide/_category_.json (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/tools/Ide/index.md (100%) rename versioned_docs/{version-0.5.5 => version-0.5}/tools/Ide/intellij.md (100%) rename versioned_docs/{version-0.5.5 => version-0.5}/tools/Ide/neovim.md (100%) rename versioned_docs/{version-0.5.5 => version-0.5}/tools/Ide/vs-code.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/tools/_category_.json (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/tools/cli/_category_.json (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/tools/cli/index.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/tools/cli/kcl/_category_.json (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/tools/cli/kcl/docgen.md (100%) rename versioned_docs/{version-0.5.5 => version-0.5}/tools/cli/kcl/fmt.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/tools/cli/kcl/index.md (100%) rename versioned_docs/{version-0.5.5 => version-0.5}/tools/cli/kcl/lint.md (100%) rename versioned_docs/{version-0.5.1 => version-0.5}/tools/cli/kcl/overview.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/tools/cli/kcl/test.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/tools/cli/kcl/vet.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/tools/cli/openapi/_category_.json (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/tools/cli/openapi/crd-to-kcl.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/tools/cli/openapi/index.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/tools/cli/openapi/openapi-to-kcl.md (100%) rename versioned_docs/{version-0.5.5 => version-0.5}/tools/cli/openapi/quick-start.md (100%) rename versioned_docs/{version-0.5.5 => version-0.5}/tools/cli/openapi/spec.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/concepts/_category_.json (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/concepts/concepts.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/concepts/package-and-module.md (100%) rename versioned_docs/{version-0.5.4 => version-0.5}/user_docs/concepts/type-and-definition.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/getting-started/_category_.json (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/getting-started/index.md (100%) rename versioned_docs/{version-0.5.5 => version-0.5}/user_docs/getting-started/install.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/getting-started/intro.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/getting-started/kcl-quick-start.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/guides/_category_.json (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/guides/_working-with-terraform/1-overview.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/guides/_working-with-terraform/2-abstraction.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/guides/_working-with-terraform/3-coverter.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/guides/_working-with-terraform/_category_.json (100%) rename versioned_docs/{version-0.5.2 => version-0.5}/user_docs/guides/abstraction.md (100%) rename versioned_docs/{version-0.5.2 => version-0.5}/user_docs/guides/automation.md (100%) rename versioned_docs/{version-0.5.2 => version-0.5}/user_docs/guides/ci-integration/1-github-actions.md (100%) rename versioned_docs/{version-0.5.2 => version-0.5}/user_docs/guides/ci-integration/2-gitlab-ci.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4 => versioned_docs/version-0.5}/user_docs/guides/ci-integration/_3-jenkins-ci.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4 => versioned_docs/version-0.5}/user_docs/guides/ci-integration/_category_.json (100%) rename versioned_docs/{version-0.5.2 => version-0.5}/user_docs/guides/configuration.md (100%) rename versioned_docs/{version-0.5.2 => version-0.5}/user_docs/guides/data-integration.md (100%) rename versioned_docs/{version-0.5.2 => version-0.5}/user_docs/guides/gitops/1-quick-start.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4 => versioned_docs/version-0.5}/user_docs/guides/gitops/_category_.json (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/guides/index.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/guides/package-management/1-overview.md (100%) rename versioned_docs/{version-0.5.2 => version-0.5}/user_docs/guides/package-management/2-installation.md (100%) rename versioned_docs/{version-0.5.2 => version-0.5}/user_docs/guides/package-management/3-quick-start.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/guides/package-management/_category_.json (100%) rename versioned_docs/{version-0.5.6 => version-0.5}/user_docs/guides/package-management/how-to/4-share_your_pkg.md (100%) rename versioned_docs/{version-0.5.6 => version-0.5}/user_docs/guides/package-management/how-to/5-share_your_pkg_docker.md (100%) rename versioned_docs/{version-0.5.6 => version-0.5}/user_docs/guides/package-management/how-to/6-push_github_action.md (100%) rename versioned_docs/{version-0.5.6 => version-0.5}/user_docs/guides/package-management/how-to/_category_.json (100%) rename versioned_docs/{version-0.5.2 => version-0.5}/user_docs/guides/schema-definition.md (100%) rename versioned_docs/{version-0.5.1 => version-0.5}/user_docs/guides/secret-management/1-vault.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5 => versioned_docs/version-0.5}/user_docs/guides/secret-management/_category_.json (100%) rename versioned_docs/{version-0.5.2 => version-0.5}/user_docs/guides/validation.md (100%) rename versioned_docs/{version-0.5.2 => version-0.5}/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md (100%) rename versioned_docs/{version-0.5.2 => version-0.5}/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md (100%) rename versioned_docs/{version-0.5.2 => version-0.5}/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md (100%) rename versioned_docs/{version-0.5.5 => version-0.5}/user_docs/guides/working-with-k8s/3-mutate-manifests/6-kcl-operator.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4 => versioned_docs/version-0.5}/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4 => versioned_docs/version-0.5}/user_docs/guides/working-with-k8s/_category_.json (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4 => versioned_docs/version-0.5}/user_docs/guides/working-with-k8s/index.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/guides/working-with-konfig/1-overview.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/guides/working-with-konfig/2-structure.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/guides/working-with-konfig/3-quick-start.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/guides/working-with-konfig/4-best-practice.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4 => versioned_docs/version-0.5}/user_docs/guides/working-with-konfig/_category_.json (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5 => versioned_docs/version-0.5}/user_docs/guides/working-with-kusion/_category_.json (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/guides/working-with-kusion/index.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/support/_category_.json (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/support/faq-cli.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/support/faq-install.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/support/faq-kcl.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/support/faq-yaml.md (100%) rename versioned_docs/{version-0.5.0 => version-0.5}/user_docs/support/support.md (100%) delete mode 100644 versioned_docs/version-0.6.0/community/contribute/_category_.json delete mode 100644 versioned_docs/version-0.6.0/community/contribute/contribute-code.md delete mode 100644 versioned_docs/version-0.6.0/community/contribute/contribute-docs.md delete mode 100644 versioned_docs/version-0.6.0/community/contribute/contribute.md delete mode 100644 versioned_docs/version-0.6.0/community/contribute/git-guideline.md delete mode 100644 versioned_docs/version-0.6.0/community/intro/_category_.json delete mode 100644 versioned_docs/version-0.6.0/community/intro/intro.md delete mode 100644 versioned_docs/version-0.6.0/community/intro/license.md delete mode 100644 versioned_docs/version-0.6.0/community/intro/support.md delete mode 100644 versioned_docs/version-0.6.0/community/release-policy/_category_.json delete mode 100644 versioned_docs/version-0.6.0/community/release-policy/index.md delete mode 100644 versioned_docs/version-0.6.0/community/release-policy/kcl.md delete mode 100644 versioned_docs/version-0.6.0/community/release-policy/roadmap.md delete mode 100644 versioned_docs/version-0.6.0/reference/_advanced-concepts/_category_.json delete mode 100644 versioned_docs/version-0.6.0/reference/_advanced-concepts/build_cache.md delete mode 100644 versioned_docs/version-0.6.0/reference/_category_.json delete mode 100644 versioned_docs/version-0.6.0/reference/cheatsheets/_category_.json delete mode 100644 versioned_docs/version-0.6.0/reference/cheatsheets/index.md delete mode 100644 versioned_docs/version-0.6.0/reference/lang/_category_.json delete mode 100644 versioned_docs/version-0.6.0/reference/lang/codelab/_category_.json delete mode 100644 versioned_docs/version-0.6.0/reference/lang/codelab/collaborative.md delete mode 100644 versioned_docs/version-0.6.0/reference/lang/codelab/index.md delete mode 100644 versioned_docs/version-0.6.0/reference/lang/codelab/schema.md delete mode 100644 versioned_docs/version-0.6.0/reference/lang/codelab/simple.md delete mode 100644 versioned_docs/version-0.6.0/reference/lang/error/_category_.json delete mode 100644 versioned_docs/version-0.6.0/reference/lang/error/index.md delete mode 100644 versioned_docs/version-0.6.0/reference/lang/spec/_category_.json delete mode 100644 versioned_docs/version-0.6.0/reference/lang/spec/codestyle.md delete mode 100644 versioned_docs/version-0.6.0/reference/lang/spec/datatypes.md delete mode 100644 versioned_docs/version-0.6.0/reference/lang/spec/error.md delete mode 100644 versioned_docs/version-0.6.0/reference/lang/spec/index.md delete mode 100644 versioned_docs/version-0.6.0/reference/lang/spec/kcl-spec.md delete mode 100644 versioned_docs/version-0.6.0/reference/lang/spec/lexical.md delete mode 100644 versioned_docs/version-0.6.0/reference/lang/spec/modules.md delete mode 100644 versioned_docs/version-0.6.0/reference/lang/spec/schema.md delete mode 100644 versioned_docs/version-0.6.0/reference/lang/spec/statements.md delete mode 100644 versioned_docs/version-0.6.0/reference/lang/spec/variables.md delete mode 100644 versioned_docs/version-0.6.0/reference/lang/types/_category_.json delete mode 100644 versioned_docs/version-0.6.0/reference/lang/types/types.md delete mode 100644 versioned_docs/version-0.6.0/reference/model/_category_.json delete mode 100644 versioned_docs/version-0.6.0/reference/model/base64.md delete mode 100644 versioned_docs/version-0.6.0/reference/model/builtin.md delete mode 100644 versioned_docs/version-0.6.0/reference/model/crypto.md delete mode 100644 versioned_docs/version-0.6.0/reference/model/index.md delete mode 100644 versioned_docs/version-0.6.0/reference/model/manifests.md delete mode 100644 versioned_docs/version-0.6.0/reference/model/net.md delete mode 100644 versioned_docs/version-0.6.0/reference/model/overview.md delete mode 100644 versioned_docs/version-0.6.0/reference/model/regex.md delete mode 100644 versioned_docs/version-0.6.0/reference/model/units.md delete mode 100644 versioned_docs/version-0.6.0/reference/model/yaml.md delete mode 100644 versioned_docs/version-0.6.0/reference/plugin/_category_.json delete mode 100644 versioned_docs/version-0.6.0/reference/plugin/index.md delete mode 100644 versioned_docs/version-0.6.0/reference/plugin/overview.md delete mode 100644 versioned_docs/version-0.6.0/reference/plugin/project_context.md delete mode 100644 versioned_docs/version-0.6.0/reference/xlang-api/_category_.json delete mode 100644 versioned_docs/version-0.6.0/reference/xlang-api/go-api.md delete mode 100644 versioned_docs/version-0.6.0/reference/xlang-api/index.md delete mode 100644 versioned_docs/version-0.6.0/reference/xlang-api/java-api.md delete mode 100644 versioned_docs/version-0.6.0/reference/xlang-api/overview.md delete mode 100644 versioned_docs/version-0.6.0/reference/xlang-api/python-api.md delete mode 100644 versioned_docs/version-0.6.0/reference/xlang-api/rest-api.md delete mode 100644 versioned_docs/version-0.6.0/tools/Ide/_category_.json delete mode 100644 versioned_docs/version-0.6.0/tools/_category_.json delete mode 100644 versioned_docs/version-0.6.0/tools/cli/_category_.json delete mode 100644 versioned_docs/version-0.6.0/tools/cli/index.md delete mode 100644 versioned_docs/version-0.6.0/tools/cli/kcl/_category_.json delete mode 100644 versioned_docs/version-0.6.0/tools/cli/kcl/docgen.md delete mode 100644 versioned_docs/version-0.6.0/tools/cli/kcl/fmt.md delete mode 100644 versioned_docs/version-0.6.0/tools/cli/kcl/index.md delete mode 100644 versioned_docs/version-0.6.0/tools/cli/kcl/lint.md delete mode 100644 versioned_docs/version-0.6.0/tools/cli/kcl/overview.md delete mode 100644 versioned_docs/version-0.6.0/tools/cli/kcl/test.md delete mode 100644 versioned_docs/version-0.6.0/tools/cli/kcl/vet.md delete mode 100644 versioned_docs/version-0.6.0/tools/cli/openapi/_category_.json delete mode 100644 versioned_docs/version-0.6.0/tools/cli/openapi/crd-to-kcl.md delete mode 100644 versioned_docs/version-0.6.0/tools/cli/openapi/index.md delete mode 100644 versioned_docs/version-0.6.0/tools/cli/openapi/openapi-to-kcl.md delete mode 100644 versioned_docs/version-0.6.0/tools/cli/openapi/quick-start.md delete mode 100644 versioned_docs/version-0.6.0/tools/cli/package-management/_category_.json delete mode 100644 versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/1.init.md delete mode 100644 versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/10.help.md delete mode 100644 versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/2.add.md delete mode 100644 versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/3.pkg.md delete mode 100644 versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/4.metadata.md delete mode 100644 versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/5.run.md delete mode 100644 versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/6.login.md delete mode 100644 versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/7.logout.md delete mode 100644 versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/8.push.md delete mode 100644 versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/9.pull.md delete mode 100644 versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/_category_.json delete mode 100644 versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/index.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/concepts/_category_.json delete mode 100644 versioned_docs/version-0.6.0/user_docs/concepts/concepts.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/concepts/package-and-module.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/getting-started/_category_.json delete mode 100644 versioned_docs/version-0.6.0/user_docs/getting-started/index.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/getting-started/kcl-quick-start.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/_category_.json delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/_working-with-terraform/1-overview.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/_working-with-terraform/2-abstraction.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/_working-with-terraform/3-coverter.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/_working-with-terraform/_category_.json delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/abstraction.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/automation.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/ci-integration/1-github-actions.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/ci-integration/2-gitlab-ci.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/ci-integration/_3-jenkins-ci.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/ci-integration/_category_.json delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/configuration.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/data-integration.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/gitops/1-quick-start.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/gitops/_category_.json delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/index.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/package-management/1-overview.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/package-management/2-installation.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/package-management/3-quick-start.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/package-management/4-how-to/_category_.json delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/package-management/_category_.json delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/schema-definition.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/secret-management/1-vault.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/secret-management/_category_.json delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/validation.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/6-kcl-operator.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/_category_.json delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/index.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/working-with-konfig/4-best-practice.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/working-with-konfig/_category_.json delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/working-with-kusion/_category_.json delete mode 100644 versioned_docs/version-0.6.0/user_docs/guides/working-with-kusion/index.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/support/_category_.json delete mode 100644 versioned_docs/version-0.6.0/user_docs/support/faq-cli.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/support/faq-yaml.md delete mode 100644 versioned_docs/version-0.6.0/user_docs/support/support.md rename versioned_docs/{version-0.5.1 => version-0.6}/community/contribute/_category_.json (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/community/contribute/contribute-code.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/community/contribute/contribute-docs.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/community/contribute/contribute.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/community/contribute/git-guideline.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/community/intro/_category_.json (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/community/intro/intro.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/community/intro/license.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/community/intro/support.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/community/release-policy/_category_.json (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/community/release-policy/index.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/community/release-policy/kcl.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/community/release-policy/roadmap.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/_advanced-concepts/_category_.json (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/_advanced-concepts/build_cache.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/_category_.json (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/cheatsheets/_category_.json (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/cheatsheets/index.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/lang/_category_.json (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/lang/codelab/_category_.json (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/lang/codelab/collaborative.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/lang/codelab/index.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/lang/codelab/schema.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/lang/codelab/simple.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/lang/error/_category_.json (100%) rename versioned_docs/{version-0.6.0 => version-0.6}/reference/lang/error/exception.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/lang/error/index.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/lang/spec/_category_.json (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4 => versioned_docs/version-0.6}/reference/lang/spec/codestyle.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5 => versioned_docs/version-0.6}/reference/lang/spec/datatypes.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3 => versioned_docs/version-0.6}/reference/lang/spec/error.md (100%) rename versioned_docs/{version-0.5.6 => version-0.6}/reference/lang/spec/expressions.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/lang/spec/index.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3 => versioned_docs/version-0.6}/reference/lang/spec/kcl-spec.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/lang/spec/lexical.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3 => versioned_docs/version-0.6}/reference/lang/spec/modules.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3 => versioned_docs/version-0.6}/reference/lang/spec/schema.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3 => versioned_docs/version-0.6}/reference/lang/spec/statements.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5 => versioned_docs/version-0.6}/reference/lang/spec/variables.md (100%) rename versioned_docs/{version-0.6.0 => version-0.6}/reference/lang/tour.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/lang/types/_category_.json (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/lang/types/types.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/model/_category_.json (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/model/base64.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/model/builtin.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/model/crypto.md (100%) rename versioned_docs/{version-0.6.0 => version-0.6}/reference/model/datetime.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/model/index.md (100%) rename versioned_docs/{version-0.6.0 => version-0.6}/reference/model/json.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/model/manifests.md (100%) rename versioned_docs/{version-0.6.0 => version-0.6}/reference/model/math.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/model/net.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/model/overview.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/model/regex.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/model/units.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/model/yaml.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/plugin/_category_.json (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/plugin/index.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/plugin/overview.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4 => versioned_docs/version-0.6}/reference/plugin/project_context.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/xlang-api/_category_.json (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3 => versioned_docs/version-0.6}/reference/xlang-api/go-api.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/xlang-api/index.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/xlang-api/java-api.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/xlang-api/overview.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/reference/xlang-api/python-api.md (100%) rename versioned_docs/{version-0.5.6 => version-0.6}/reference/xlang-api/rest-api.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/tools/Ide/_category_.json (100%) rename versioned_docs/{version-0.6.0 => version-0.6}/tools/Ide/index.md (100%) rename versioned_docs/{version-0.5.6 => version-0.6}/tools/Ide/intellij.md (100%) rename versioned_docs/{version-0.5.6 => version-0.6}/tools/Ide/neovim.md (100%) rename versioned_docs/{version-0.6.0 => version-0.6}/tools/Ide/vs-code.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/tools/_category_.json (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/tools/cli/_category_.json (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/tools/cli/index.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/tools/cli/kcl/_category_.json (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/tools/cli/kcl/docgen.md (100%) rename versioned_docs/{version-0.5.6 => version-0.6}/tools/cli/kcl/fmt.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/tools/cli/kcl/index.md (100%) rename versioned_docs/{version-0.5.6 => version-0.6}/tools/cli/kcl/lint.md (100%) rename versioned_docs/{version-0.5.2 => version-0.6}/tools/cli/kcl/overview.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/tools/cli/kcl/test.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/tools/cli/kcl/vet.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/tools/cli/openapi/_category_.json (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/tools/cli/openapi/crd-to-kcl.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/tools/cli/openapi/index.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/tools/cli/openapi/openapi-to-kcl.md (100%) rename versioned_docs/{version-0.5.6 => version-0.6}/tools/cli/openapi/quick-start.md (100%) rename versioned_docs/{version-0.5.6 => version-0.6}/tools/cli/openapi/spec.md (100%) rename versioned_docs/{version-0.5.1/reference => version-0.6/tools/cli}/package-management/_category_.json (100%) rename versioned_docs/{version-0.5.1/reference => version-0.6/tools/cli}/package-management/command-reference/1.init.md (100%) rename versioned_docs/{version-0.5.1/reference => version-0.6/tools/cli}/package-management/command-reference/10.help.md (100%) rename versioned_docs/{version-0.5.1/reference => version-0.6/tools/cli}/package-management/command-reference/2.add.md (100%) rename versioned_docs/{version-0.5.1/reference => version-0.6/tools/cli}/package-management/command-reference/3.pkg.md (100%) rename versioned_docs/{version-0.5.1/reference => version-0.6/tools/cli}/package-management/command-reference/4.metadata.md (100%) rename versioned_docs/{version-0.5.1/reference => version-0.6/tools/cli}/package-management/command-reference/5.run.md (100%) rename versioned_docs/{version-0.5.1/reference => version-0.6/tools/cli}/package-management/command-reference/6.login.md (100%) rename versioned_docs/{version-0.5.1/reference => version-0.6/tools/cli}/package-management/command-reference/7.logout.md (100%) rename versioned_docs/{version-0.5.1/reference => version-0.6/tools/cli}/package-management/command-reference/8.push.md (100%) rename versioned_docs/{version-0.5.1/reference => version-0.6/tools/cli}/package-management/command-reference/9.pull.md (100%) rename versioned_docs/{version-0.5.1/reference => version-0.6/tools/cli}/package-management/command-reference/_category_.json (100%) rename versioned_docs/{version-0.5.1/reference => version-0.6/tools/cli}/package-management/command-reference/index.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/user_docs/concepts/_category_.json (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/user_docs/concepts/concepts.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/user_docs/concepts/package-and-module.md (100%) rename versioned_docs/{version-0.5.5 => version-0.6}/user_docs/concepts/type-and-definition.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/user_docs/getting-started/_category_.json (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/user_docs/getting-started/index.md (100%) rename versioned_docs/{version-0.6.0 => version-0.6}/user_docs/getting-started/install.md (100%) rename versioned_docs/{version-0.6.0 => version-0.6}/user_docs/getting-started/intro.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/user_docs/getting-started/kcl-quick-start.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/user_docs/guides/_category_.json (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/user_docs/guides/_working-with-terraform/1-overview.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/user_docs/guides/_working-with-terraform/2-abstraction.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/user_docs/guides/_working-with-terraform/3-coverter.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/user_docs/guides/_working-with-terraform/_category_.json (100%) rename versioned_docs/{version-0.5.3 => version-0.6}/user_docs/guides/abstraction.md (100%) rename versioned_docs/{version-0.5.3 => version-0.6}/user_docs/guides/automation.md (100%) rename versioned_docs/{version-0.5.3 => version-0.6}/user_docs/guides/ci-integration/1-github-actions.md (100%) rename versioned_docs/{version-0.5.3 => version-0.6}/user_docs/guides/ci-integration/2-gitlab-ci.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5 => versioned_docs/version-0.6}/user_docs/guides/ci-integration/_3-jenkins-ci.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5 => versioned_docs/version-0.6}/user_docs/guides/ci-integration/_category_.json (100%) rename versioned_docs/{version-0.5.3 => version-0.6}/user_docs/guides/configuration.md (100%) rename versioned_docs/{version-0.5.3 => version-0.6}/user_docs/guides/data-integration.md (100%) rename versioned_docs/{version-0.5.3 => version-0.6}/user_docs/guides/gitops/1-quick-start.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5 => versioned_docs/version-0.6}/user_docs/guides/gitops/_category_.json (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/user_docs/guides/index.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/user_docs/guides/package-management/1-overview.md (100%) rename versioned_docs/{version-0.5.3 => version-0.6}/user_docs/guides/package-management/2-installation.md (100%) rename versioned_docs/{version-0.5.3 => version-0.6}/user_docs/guides/package-management/3-quick-start.md (100%) rename versioned_docs/{version-0.6.0 => version-0.6}/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md (100%) rename versioned_docs/{version-0.6.0 => version-0.6}/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md (100%) rename versioned_docs/{version-0.6.0 => version-0.6}/user_docs/guides/package-management/4-how-to/6-push_github_action.md (100%) rename versioned_docs/{version-0.5.0 => version-0.6}/user_docs/guides/package-management/4-how-to/_category_.json (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/user_docs/guides/package-management/_category_.json (100%) rename versioned_docs/{version-0.5.3 => version-0.6}/user_docs/guides/schema-definition.md (100%) rename versioned_docs/{version-0.5.2 => version-0.6}/user_docs/guides/secret-management/1-vault.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6 => versioned_docs/version-0.6}/user_docs/guides/secret-management/_category_.json (100%) rename versioned_docs/{version-0.5.3 => version-0.6}/user_docs/guides/validation.md (100%) rename versioned_docs/{version-0.6.0 => version-0.6}/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md (100%) rename versioned_docs/{version-0.5.3 => version-0.6}/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md (100%) rename versioned_docs/{version-0.5.4 => version-0.6}/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md (100%) rename versioned_docs/{version-0.5.6 => version-0.6}/user_docs/guides/working-with-k8s/3-mutate-manifests/6-kcl-operator.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5 => versioned_docs/version-0.6}/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5 => versioned_docs/version-0.6}/user_docs/guides/working-with-k8s/_category_.json (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5 => versioned_docs/version-0.6}/user_docs/guides/working-with-k8s/index.md (100%) rename versioned_docs/{version-0.6.0 => version-0.6}/user_docs/guides/working-with-konfig/1-overview.md (100%) rename versioned_docs/{version-0.6.0 => version-0.6}/user_docs/guides/working-with-konfig/2-structure.md (100%) rename versioned_docs/{version-0.6.0 => version-0.6}/user_docs/guides/working-with-konfig/3-quick-start.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/user_docs/guides/working-with-konfig/4-best-practice.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5 => versioned_docs/version-0.6}/user_docs/guides/working-with-konfig/_category_.json (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6 => versioned_docs/version-0.6}/user_docs/guides/working-with-kusion/_category_.json (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/user_docs/guides/working-with-kusion/index.md (100%) rename versioned_docs/{version-0.6.0 => version-0.6}/user_docs/guides/working-with-terraform/3-validation.md (100%) rename versioned_docs/{version-0.6.0 => version-0.6}/user_docs/guides/working-with-terraform/_1-adopt-from-terraform.md (100%) rename versioned_docs/{version-0.6.0 => version-0.6}/user_docs/guides/working-with-terraform/_2-abstraction.md (100%) rename versioned_docs/{version-0.6.0 => version-0.6}/user_docs/guides/working-with-terraform/_category_.json (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/user_docs/support/_category_.json (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/user_docs/support/faq-cli.md (100%) rename versioned_docs/{version-0.6.0 => version-0.6}/user_docs/support/faq-install.md (100%) rename versioned_docs/{version-0.6.0 => version-0.6}/user_docs/support/faq-kcl.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/user_docs/support/faq-yaml.md (100%) rename versioned_docs/{version-0.5.1 => version-0.6}/user_docs/support/support.md (100%) delete mode 100644 versioned_docs/version-0.7.0/community/contribute/_category_.json delete mode 100644 versioned_docs/version-0.7.0/community/contribute/contribute-code.md delete mode 100644 versioned_docs/version-0.7.0/community/contribute/contribute-docs.md delete mode 100644 versioned_docs/version-0.7.0/community/contribute/contribute.md delete mode 100644 versioned_docs/version-0.7.0/community/intro/_category_.json delete mode 100644 versioned_docs/version-0.7.0/community/intro/intro.md delete mode 100644 versioned_docs/version-0.7.0/community/intro/license.md delete mode 100644 versioned_docs/version-0.7.0/community/intro/support.md delete mode 100644 versioned_docs/version-0.7.0/community/release-policy/_category_.json delete mode 100644 versioned_docs/version-0.7.0/community/release-policy/index.md delete mode 100644 versioned_docs/version-0.7.0/reference/_advanced-concepts/_category_.json delete mode 100644 versioned_docs/version-0.7.0/reference/_advanced-concepts/build_cache.md delete mode 100644 versioned_docs/version-0.7.0/reference/_category_.json delete mode 100644 versioned_docs/version-0.7.0/reference/cheatsheets/_category_.json delete mode 100644 versioned_docs/version-0.7.0/reference/cheatsheets/index.md delete mode 100644 versioned_docs/version-0.7.0/reference/lang/_category_.json delete mode 100644 versioned_docs/version-0.7.0/reference/lang/codelab/_category_.json delete mode 100644 versioned_docs/version-0.7.0/reference/lang/codelab/collaborative.md delete mode 100644 versioned_docs/version-0.7.0/reference/lang/codelab/index.md delete mode 100644 versioned_docs/version-0.7.0/reference/lang/codelab/schema.md delete mode 100644 versioned_docs/version-0.7.0/reference/lang/codelab/simple.md delete mode 100644 versioned_docs/version-0.7.0/reference/lang/error/_category_.json delete mode 100644 versioned_docs/version-0.7.0/reference/lang/error/index.md delete mode 100644 versioned_docs/version-0.7.0/reference/lang/spec/_category_.json delete mode 100644 versioned_docs/version-0.7.0/reference/lang/spec/codestyle.md delete mode 100644 versioned_docs/version-0.7.0/reference/lang/spec/datatypes.md delete mode 100644 versioned_docs/version-0.7.0/reference/lang/spec/index.md delete mode 100644 versioned_docs/version-0.7.0/reference/lang/spec/lexical.md delete mode 100644 versioned_docs/version-0.7.0/reference/lang/spec/variables.md delete mode 100644 versioned_docs/version-0.7.0/reference/lang/types/_category_.json delete mode 100644 versioned_docs/version-0.7.0/reference/lang/types/types.md delete mode 100644 versioned_docs/version-0.7.0/reference/model/_category_.json delete mode 100644 versioned_docs/version-0.7.0/reference/model/base64.md delete mode 100644 versioned_docs/version-0.7.0/reference/model/builtin.md delete mode 100644 versioned_docs/version-0.7.0/reference/model/crypto.md delete mode 100644 versioned_docs/version-0.7.0/reference/model/manifests.md delete mode 100644 versioned_docs/version-0.7.0/reference/model/net.md delete mode 100644 versioned_docs/version-0.7.0/reference/model/regex.md delete mode 100644 versioned_docs/version-0.7.0/reference/model/units.md delete mode 100644 versioned_docs/version-0.7.0/reference/plugin/_category_.json delete mode 100644 versioned_docs/version-0.7.0/reference/plugin/index.md delete mode 100644 versioned_docs/version-0.7.0/reference/plugin/project_context.md delete mode 100644 versioned_docs/version-0.7.0/reference/xlang-api/_category_.json delete mode 100644 versioned_docs/version-0.7.0/reference/xlang-api/index.md delete mode 100644 versioned_docs/version-0.7.0/reference/xlang-api/java-api.md delete mode 100644 versioned_docs/version-0.7.0/reference/xlang-api/overview.md delete mode 100644 versioned_docs/version-0.7.0/reference/xlang-api/python-api.md delete mode 100644 versioned_docs/version-0.7.0/tools/Ide/_category_.json delete mode 100644 versioned_docs/version-0.7.0/tools/_category_.json delete mode 100644 versioned_docs/version-0.7.0/tools/cli/_category_.json delete mode 100644 versioned_docs/version-0.7.0/tools/cli/index.md delete mode 100644 versioned_docs/version-0.7.0/tools/cli/kcl/_category_.json delete mode 100644 versioned_docs/version-0.7.0/tools/cli/openapi/_category_.json delete mode 100644 versioned_docs/version-0.7.0/tools/cli/openapi/index.md delete mode 100644 versioned_docs/version-0.7.0/tools/cli/package-management/command-reference/_category_.json delete mode 100644 versioned_docs/version-0.7.0/user_docs/concepts/_category_.json delete mode 100644 versioned_docs/version-0.7.0/user_docs/concepts/package-and-module.md delete mode 100644 versioned_docs/version-0.7.0/user_docs/concepts/type-and-definition.md delete mode 100644 versioned_docs/version-0.7.0/user_docs/getting-started/_category_.json delete mode 100644 versioned_docs/version-0.7.0/user_docs/getting-started/kcl-quick-start.md delete mode 100644 versioned_docs/version-0.7.0/user_docs/guides/_category_.json delete mode 100644 versioned_docs/version-0.7.0/user_docs/guides/abstraction.md delete mode 100644 versioned_docs/version-0.7.0/user_docs/guides/ci-integration/1-github-actions.md delete mode 100644 versioned_docs/version-0.7.0/user_docs/guides/ci-integration/2-gitlab-ci.md delete mode 100644 versioned_docs/version-0.7.0/user_docs/guides/ci-integration/_3-jenkins-ci.md delete mode 100644 versioned_docs/version-0.7.0/user_docs/guides/ci-integration/_category_.json delete mode 100644 versioned_docs/version-0.7.0/user_docs/guides/data-integration.md delete mode 100644 versioned_docs/version-0.7.0/user_docs/guides/gitops/1-quick-start.md delete mode 100644 versioned_docs/version-0.7.0/user_docs/guides/gitops/_category_.json delete mode 100644 versioned_docs/version-0.7.0/user_docs/guides/package-management/4-how-to/_category_.json delete mode 100644 versioned_docs/version-0.7.0/user_docs/guides/package-management/_category_.json delete mode 100644 versioned_docs/version-0.7.0/user_docs/guides/schema-definition.md delete mode 100644 versioned_docs/version-0.7.0/user_docs/guides/secret-management/1-vault.md delete mode 100644 versioned_docs/version-0.7.0/user_docs/guides/secret-management/_category_.json delete mode 100644 versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json delete mode 100644 versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/_category_.json delete mode 100644 versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/index.md delete mode 100644 versioned_docs/version-0.7.0/user_docs/guides/working-with-konfig/4-best-practice.md delete mode 100644 versioned_docs/version-0.7.0/user_docs/guides/working-with-konfig/_category_.json delete mode 100644 versioned_docs/version-0.7.0/user_docs/guides/working-with-kusion/_category_.json delete mode 100644 versioned_docs/version-0.7.0/user_docs/guides/working-with-kusion/index.md delete mode 100644 versioned_docs/version-0.7.0/user_docs/support/_category_.json delete mode 100644 versioned_docs/version-0.7.0/user_docs/support/faq-cli.md delete mode 100644 versioned_docs/version-0.7.0/user_docs/support/faq-yaml.md rename versioned_docs/{version-0.5.2 => version-0.7}/community/contribute/_category_.json (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/community/contribute/contribute-code.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/community/contribute/contribute-docs.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/community/contribute/contribute.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/community/contribute/git-guideline.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/community/intro/_category_.json (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/community/intro/intro.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/community/intro/license.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/community/intro/support.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/community/release-policy/_category_.json (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/community/release-policy/index.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/community/release-policy/kcl.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/community/release-policy/roadmap.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/_advanced-concepts/_category_.json (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/_advanced-concepts/build_cache.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/_category_.json (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/cheatsheets/_category_.json (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/cheatsheets/index.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/lang/_category_.json (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/lang/codelab/_category_.json (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/lang/codelab/collaborative.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/lang/codelab/index.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/lang/codelab/schema.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/lang/codelab/simple.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/lang/error/_category_.json (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/reference/lang/error/exception.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/lang/error/index.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/lang/spec/_category_.json (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5 => versioned_docs/version-0.7}/reference/lang/spec/codestyle.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6 => versioned_docs/version-0.7}/reference/lang/spec/datatypes.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/reference/lang/spec/error.md (100%) rename versioned_docs/{version-0.6.0 => version-0.7}/reference/lang/spec/expressions.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/lang/spec/index.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/reference/lang/spec/kcl-spec.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/lang/spec/lexical.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/reference/lang/spec/modules.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/reference/lang/spec/schema.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/reference/lang/spec/statements.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6 => versioned_docs/version-0.7}/reference/lang/spec/variables.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/reference/lang/tour.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/lang/types/_category_.json (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/lang/types/types.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/model/_category_.json (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/model/base64.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/model/builtin.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/model/crypto.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/reference/model/datetime.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/reference/model/json.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/model/manifests.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/reference/model/math.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/model/net.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/reference/model/overview.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/model/regex.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/model/units.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/reference/model/yaml.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/plugin/_category_.json (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/plugin/index.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/reference/plugin/overview.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5 => versioned_docs/version-0.7}/reference/plugin/project_context.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/xlang-api/_category_.json (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/reference/xlang-api/go-api.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/xlang-api/index.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/xlang-api/java-api.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/xlang-api/overview.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/reference/xlang-api/python-api.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/reference/xlang-api/rest-api.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/tools/Ide/_category_.json (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/tools/Ide/index.md (100%) rename versioned_docs/{version-0.6.0 => version-0.7}/tools/Ide/intellij.md (100%) rename versioned_docs/{version-0.6.0 => version-0.7}/tools/Ide/neovim.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/tools/Ide/vs-code.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/tools/_category_.json (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/tools/cli/_category_.json (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/tools/cli/index.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/tools/cli/kcl/_category_.json (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/tools/cli/kcl/docgen.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/tools/cli/kcl/fmt.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/tools/cli/kcl/import.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/tools/cli/kcl/index.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/tools/cli/kcl/lint.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/tools/cli/kcl/overview.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/tools/cli/kcl/run.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/tools/cli/kcl/test.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/tools/cli/kcl/vet.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/tools/cli/openapi/_category_.json (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/tools/cli/openapi/crd-to-kcl.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/tools/cli/openapi/index.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/tools/cli/openapi/openapi-to-kcl.md (100%) rename versioned_docs/{version-0.6.0 => version-0.7}/tools/cli/openapi/spec.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/tools/cli/package-management/_category_.json (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/tools/cli/package-management/command-reference/1.init.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/tools/cli/package-management/command-reference/10.help.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/tools/cli/package-management/command-reference/11.update.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/tools/cli/package-management/command-reference/2.add.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/tools/cli/package-management/command-reference/3.pkg.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/tools/cli/package-management/command-reference/4.metadata.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/tools/cli/package-management/command-reference/6.login.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/tools/cli/package-management/command-reference/7.logout.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/tools/cli/package-management/command-reference/8.push.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/tools/cli/package-management/command-reference/9.pull.md (100%) rename versioned_docs/{version-0.5.2/reference => version-0.7/tools/cli}/package-management/command-reference/_category_.json (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/user_docs/concepts/_category_.json (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/concepts/concepts.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/user_docs/concepts/package-and-module.md (100%) rename versioned_docs/{version-0.5.6 => version-0.7}/user_docs/concepts/type-and-definition.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/user_docs/getting-started/_category_.json (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/getting-started/index.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/getting-started/install.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/getting-started/intro.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/user_docs/getting-started/kcl-quick-start.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/user_docs/guides/_category_.json (100%) rename versioned_docs/{version-0.5.4 => version-0.7}/user_docs/guides/abstraction.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/automation.md (100%) rename versioned_docs/{version-0.5.4 => version-0.7}/user_docs/guides/ci-integration/1-github-actions.md (100%) rename versioned_docs/{version-0.5.4 => version-0.7}/user_docs/guides/ci-integration/2-gitlab-ci.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6 => versioned_docs/version-0.7}/user_docs/guides/ci-integration/_3-jenkins-ci.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6 => versioned_docs/version-0.7}/user_docs/guides/ci-integration/_category_.json (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/configuration.md (100%) rename versioned_docs/{version-0.5.4 => version-0.7}/user_docs/guides/data-integration.md (100%) rename versioned_docs/{version-0.5.4 => version-0.7}/user_docs/guides/gitops/1-quick-start.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6 => versioned_docs/version-0.7}/user_docs/guides/gitops/_category_.json (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/index.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/package-management/3-quick-start.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/package-management/4-how-to/6-push_github_action.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/package-management/4-how-to/7-publish_pkg_to_ah.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/package-management/4-how-to/8-kcl_mod.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/package-management/4-how-to/9-kpm_oci.md (100%) rename versioned_docs/{version-0.5.1 => version-0.7}/user_docs/guides/package-management/4-how-to/_category_.json (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/user_docs/guides/package-management/_category_.json (100%) rename versioned_docs/{version-0.5.4 => version-0.7}/user_docs/guides/schema-definition.md (100%) rename versioned_docs/{version-0.5.3 => version-0.7}/user_docs/guides/secret-management/1-vault.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0 => versioned_docs/version-0.7}/user_docs/guides/secret-management/_category_.json (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/validation.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-k8s/0-overview.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-k8s/3-mutate-manifests/6-kcl-operator.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-k8s/3-mutate-manifests/7-crossplane-kcl-function.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6 => versioned_docs/version-0.7}/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6 => versioned_docs/version-0.7}/user_docs/guides/working-with-k8s/_category_.json (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6 => versioned_docs/version-0.7}/user_docs/guides/working-with-k8s/index.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-konfig/1-overview.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-konfig/2-structure.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-konfig/3-quick-start.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/user_docs/guides/working-with-konfig/4-best-practice.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6 => versioned_docs/version-0.7}/user_docs/guides/working-with-konfig/_category_.json (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-kubevela/_category_.json (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-kubevela/index.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0 => versioned_docs/version-0.7}/user_docs/guides/working-with-kusion/_category_.json (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/user_docs/guides/working-with-kusion/index.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-terraform/3-validation.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-terraform/_1-adopt-from-terraform.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-terraform/_2-abstraction.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/guides/working-with-terraform/_category_.json (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/user_docs/support/_category_.json (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/user_docs/support/faq-cli.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/support/faq-install.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/support/faq-kcl.md (100%) rename versioned_docs/{version-0.5.2 => version-0.7}/user_docs/support/faq-yaml.md (100%) rename versioned_docs/{version-0.7.0 => version-0.7}/user_docs/support/support.md (100%) delete mode 100644 versioned_docs/version-0.8.0/community/contribute/_category_.json delete mode 100644 versioned_docs/version-0.8.0/community/contribute/contribute-code.md delete mode 100644 versioned_docs/version-0.8.0/community/contribute/contribute-docs.md delete mode 100644 versioned_docs/version-0.8.0/community/contribute/contribute.md delete mode 100644 versioned_docs/version-0.8.0/community/intro/_category_.json delete mode 100644 versioned_docs/version-0.8.0/community/intro/intro.md delete mode 100644 versioned_docs/version-0.8.0/community/intro/license.md delete mode 100644 versioned_docs/version-0.8.0/community/intro/support.md delete mode 100644 versioned_docs/version-0.8.0/community/release-policy/_category_.json delete mode 100644 versioned_docs/version-0.8.0/community/release-policy/index.md delete mode 100644 versioned_docs/version-0.8.0/reference/_advanced-concepts/_category_.json delete mode 100644 versioned_docs/version-0.8.0/reference/_advanced-concepts/build_cache.md delete mode 100644 versioned_docs/version-0.8.0/reference/_category_.json delete mode 100644 versioned_docs/version-0.8.0/reference/cheatsheets/_category_.json delete mode 100644 versioned_docs/version-0.8.0/reference/cheatsheets/index.md delete mode 100644 versioned_docs/version-0.8.0/reference/lang/_category_.json delete mode 100644 versioned_docs/version-0.8.0/reference/lang/codelab/_category_.json delete mode 100644 versioned_docs/version-0.8.0/reference/lang/codelab/collaborative.md delete mode 100644 versioned_docs/version-0.8.0/reference/lang/codelab/index.md delete mode 100644 versioned_docs/version-0.8.0/reference/lang/codelab/schema.md delete mode 100644 versioned_docs/version-0.8.0/reference/lang/codelab/simple.md delete mode 100644 versioned_docs/version-0.8.0/reference/lang/error/_category_.json delete mode 100644 versioned_docs/version-0.8.0/reference/lang/error/index.md delete mode 100644 versioned_docs/version-0.8.0/reference/lang/spec/_category_.json delete mode 100644 versioned_docs/version-0.8.0/reference/lang/spec/datatypes.md delete mode 100644 versioned_docs/version-0.8.0/reference/lang/spec/expressions.md delete mode 100644 versioned_docs/version-0.8.0/reference/lang/spec/index.md delete mode 100644 versioned_docs/version-0.8.0/reference/lang/spec/lexical.md delete mode 100644 versioned_docs/version-0.8.0/reference/lang/spec/variables.md delete mode 100644 versioned_docs/version-0.8.0/reference/lang/types/_category_.json delete mode 100644 versioned_docs/version-0.8.0/reference/lang/types/types.md delete mode 100644 versioned_docs/version-0.8.0/reference/model/_category_.json delete mode 100644 versioned_docs/version-0.8.0/reference/model/base64.md delete mode 100644 versioned_docs/version-0.8.0/reference/model/builtin.md delete mode 100644 versioned_docs/version-0.8.0/reference/model/manifests.md delete mode 100644 versioned_docs/version-0.8.0/reference/model/net.md delete mode 100644 versioned_docs/version-0.8.0/reference/model/regex.md delete mode 100644 versioned_docs/version-0.8.0/reference/model/units.md delete mode 100644 versioned_docs/version-0.8.0/reference/plugin/_category_.json delete mode 100644 versioned_docs/version-0.8.0/reference/xlang-api/_category_.json delete mode 100644 versioned_docs/version-0.8.0/reference/xlang-api/java-api.md delete mode 100644 versioned_docs/version-0.8.0/reference/xlang-api/python-api.md delete mode 100644 versioned_docs/version-0.8.0/tools/Ide/_category_.json delete mode 100644 versioned_docs/version-0.8.0/tools/Ide/intellij.md delete mode 100644 versioned_docs/version-0.8.0/tools/Ide/neovim.md delete mode 100644 versioned_docs/version-0.8.0/tools/_category_.json delete mode 100644 versioned_docs/version-0.8.0/tools/cli/_category_.json delete mode 100644 versioned_docs/version-0.8.0/tools/cli/index.md delete mode 100644 versioned_docs/version-0.8.0/tools/cli/kcl/_category_.json delete mode 100644 versioned_docs/version-0.8.0/tools/cli/openapi/_category_.json delete mode 100644 versioned_docs/version-0.8.0/tools/cli/openapi/spec.md delete mode 100644 versioned_docs/version-0.8.0/tools/cli/package-management/command-reference/_category_.json delete mode 100644 versioned_docs/version-0.8.0/user_docs/concepts/_category_.json delete mode 100644 versioned_docs/version-0.8.0/user_docs/concepts/package-and-module.md delete mode 100644 versioned_docs/version-0.8.0/user_docs/concepts/type-and-definition.md delete mode 100644 versioned_docs/version-0.8.0/user_docs/getting-started/_category_.json delete mode 100644 versioned_docs/version-0.8.0/user_docs/getting-started/kcl-quick-start.md delete mode 100644 versioned_docs/version-0.8.0/user_docs/guides/_category_.json delete mode 100644 versioned_docs/version-0.8.0/user_docs/guides/abstraction.md delete mode 100644 versioned_docs/version-0.8.0/user_docs/guides/ci-integration/1-github-actions.md delete mode 100644 versioned_docs/version-0.8.0/user_docs/guides/ci-integration/2-gitlab-ci.md delete mode 100644 versioned_docs/version-0.8.0/user_docs/guides/ci-integration/_3-jenkins-ci.md delete mode 100644 versioned_docs/version-0.8.0/user_docs/guides/ci-integration/_category_.json delete mode 100644 versioned_docs/version-0.8.0/user_docs/guides/data-integration.md delete mode 100644 versioned_docs/version-0.8.0/user_docs/guides/gitops/_category_.json delete mode 100644 versioned_docs/version-0.8.0/user_docs/guides/package-management/4-how-to/_category_.json delete mode 100644 versioned_docs/version-0.8.0/user_docs/guides/package-management/_category_.json delete mode 100644 versioned_docs/version-0.8.0/user_docs/guides/schema-definition.md delete mode 100644 versioned_docs/version-0.8.0/user_docs/guides/secret-management/1-vault.md delete mode 100644 versioned_docs/version-0.8.0/user_docs/guides/secret-management/_category_.json delete mode 100644 versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json delete mode 100644 versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/_category_.json delete mode 100644 versioned_docs/version-0.8.0/user_docs/guides/working-with-konfig/4-best-practice.md delete mode 100644 versioned_docs/version-0.8.0/user_docs/guides/working-with-konfig/_category_.json delete mode 100644 versioned_docs/version-0.8.0/user_docs/guides/working-with-kusion/_category_.json delete mode 100644 versioned_docs/version-0.8.0/user_docs/guides/working-with-kusion/index.md delete mode 100644 versioned_docs/version-0.8.0/user_docs/support/_category_.json delete mode 100644 versioned_docs/version-0.8.0/user_docs/support/faq-cli.md delete mode 100644 versioned_docs/version-0.8.0/user_docs/support/faq-yaml.md rename versioned_docs/{version-0.5.3 => version-0.8}/community/contribute/_category_.json (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/community/contribute/contribute-code.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/community/contribute/contribute-docs.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/community/contribute/contribute.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/community/contribute/git-guideline.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/community/intro/_category_.json (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/community/intro/intro.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/community/intro/license.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/community/intro/support.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/community/release-policy/_category_.json (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/community/release-policy/index.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/community/release-policy/kcl.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/community/release-policy/roadmap.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/_advanced-concepts/_category_.json (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/_advanced-concepts/build_cache.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/_category_.json (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/cheatsheets/_category_.json (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/cheatsheets/index.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/lang/_category_.json (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/lang/codelab/_category_.json (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/lang/codelab/collaborative.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/lang/codelab/index.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/lang/codelab/schema.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/lang/codelab/simple.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/lang/error/_category_.json (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/reference/lang/error/exception.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/lang/error/index.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/lang/spec/_category_.json (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/reference/lang/spec/codestyle.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0 => versioned_docs/version-0.8}/reference/lang/spec/datatypes.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/reference/lang/spec/error.md (100%) rename versioned_docs/{version-0.7.0 => version-0.8}/reference/lang/spec/expressions.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/lang/spec/index.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/reference/lang/spec/kcl-spec.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/lang/spec/lexical.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/reference/lang/spec/modules.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/reference/lang/spec/schema.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/reference/lang/spec/statements.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0 => versioned_docs/version-0.8}/reference/lang/spec/variables.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/reference/lang/tour.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/lang/types/_category_.json (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/lang/types/types.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/model/_category_.json (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/model/base64.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/model/builtin.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/reference/model/crypto.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/reference/model/datetime.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/reference/model/file.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/reference/model/json.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/model/manifests.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/reference/model/math.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/model/net.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/reference/model/overview.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/model/regex.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/model/units.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/reference/model/yaml.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/plugin/_category_.json (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/reference/plugin/overview.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/xlang-api/_category_.json (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/reference/xlang-api/go-api.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/xlang-api/java-api.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/reference/xlang-api/overview.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/reference/xlang-api/python-api.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/reference/xlang-api/rest-api.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/tools/Ide/_category_.json (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/tools/Ide/index.md (100%) rename versioned_docs/{version-0.7.0 => version-0.8}/tools/Ide/intellij.md (100%) rename versioned_docs/{version-0.7.0 => version-0.8}/tools/Ide/neovim.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/tools/Ide/vs-code.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/tools/_category_.json (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/tools/cli/_category_.json (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/tools/cli/index.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/tools/cli/kcl/_category_.json (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/tools/cli/kcl/docgen.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/tools/cli/kcl/fmt.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/tools/cli/kcl/import.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/tools/cli/kcl/index.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/tools/cli/kcl/lint.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/tools/cli/kcl/overview.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/tools/cli/kcl/run.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/tools/cli/kcl/test.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/tools/cli/kcl/vet.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/tools/cli/openapi/_category_.json (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/tools/cli/openapi/crd-to-kcl.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/tools/cli/openapi/openapi-to-kcl.md (100%) rename versioned_docs/{version-0.7.0 => version-0.8}/tools/cli/openapi/spec.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/tools/cli/package-management/_category_.json (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/tools/cli/package-management/command-reference/1.init.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/tools/cli/package-management/command-reference/10.help.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/tools/cli/package-management/command-reference/11.update.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/tools/cli/package-management/command-reference/2.add.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/tools/cli/package-management/command-reference/3.pkg.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/tools/cli/package-management/command-reference/4.metadata.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/tools/cli/package-management/command-reference/6.login.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/tools/cli/package-management/command-reference/7.logout.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/tools/cli/package-management/command-reference/8.push.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/tools/cli/package-management/command-reference/9.pull.md (100%) rename versioned_docs/{version-0.5.3/reference => version-0.8/tools/cli}/package-management/command-reference/_category_.json (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/user_docs/concepts/_category_.json (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/concepts/concepts.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/user_docs/concepts/package-and-module.md (100%) rename versioned_docs/{version-0.6.0 => version-0.8}/user_docs/concepts/type-and-definition.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/user_docs/getting-started/_category_.json (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/getting-started/index.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/getting-started/install.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/getting-started/intro.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/user_docs/getting-started/kcl-quick-start.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/user_docs/guides/_category_.json (100%) rename versioned_docs/{version-0.5.5 => version-0.8}/user_docs/guides/abstraction.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/automation.md (100%) rename versioned_docs/{version-0.5.5 => version-0.8}/user_docs/guides/ci-integration/1-github-actions.md (100%) rename versioned_docs/{version-0.5.5 => version-0.8}/user_docs/guides/ci-integration/2-gitlab-ci.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0 => versioned_docs/version-0.8}/user_docs/guides/ci-integration/_3-jenkins-ci.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0 => versioned_docs/version-0.8}/user_docs/guides/ci-integration/_category_.json (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/configuration.md (100%) rename versioned_docs/{version-0.5.5 => version-0.8}/user_docs/guides/data-integration.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/gitops/1-argocd.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/gitops/2-fluxcd.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0 => versioned_docs/version-0.8}/user_docs/guides/gitops/_category_.json (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/index.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/package-management/3-quick-start.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/package-management/4-how-to/6-push_github_action.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/package-management/4-how-to/7-publish_pkg_to_ah.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/package-management/4-how-to/8-kcl_mod.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/package-management/4-how-to/9-kpm_oci.md (100%) rename versioned_docs/{version-0.5.2 => version-0.8}/user_docs/guides/package-management/4-how-to/_category_.json (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/user_docs/guides/package-management/_category_.json (100%) rename versioned_docs/{version-0.5.5 => version-0.8}/user_docs/guides/schema-definition.md (100%) rename versioned_docs/{version-0.5.4 => version-0.8}/user_docs/guides/secret-management/1-vault.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0 => versioned_docs/version-0.8}/user_docs/guides/secret-management/_category_.json (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/validation.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-k8s/0-overview.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-k8s/3-mutate-manifests/6-kcl-operator.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-k8s/3-mutate-manifests/7-crossplane-kcl-function.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0 => versioned_docs/version-0.8}/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0 => versioned_docs/version-0.8}/user_docs/guides/working-with-k8s/_category_.json (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-konfig/1-overview.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-konfig/2-structure.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-konfig/3-quick-start.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/user_docs/guides/working-with-konfig/4-best-practice.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0 => versioned_docs/version-0.8}/user_docs/guides/working-with-konfig/_category_.json (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-kubevela/_category_.json (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-kubevela/index.md (100%) rename {i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0 => versioned_docs/version-0.8}/user_docs/guides/working-with-kusion/_category_.json (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/user_docs/guides/working-with-kusion/index.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-terraform/3-validation.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-terraform/_1-adopt-from-terraform.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-terraform/_2-abstraction.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/guides/working-with-terraform/_category_.json (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/user_docs/support/_category_.json (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/user_docs/support/faq-cli.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/support/faq-install.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/support/faq-kcl.md (100%) rename versioned_docs/{version-0.5.3 => version-0.8}/user_docs/support/faq-yaml.md (100%) rename versioned_docs/{version-0.8.0 => version-0.8}/user_docs/support/support.md (100%) rename versioned_sidebars/{version-0.5.0-sidebars.json => version-0.5-sidebars.json} (100%) delete mode 100644 versioned_sidebars/version-0.5.4-sidebars.json delete mode 100644 versioned_sidebars/version-0.5.5-sidebars.json delete mode 100644 versioned_sidebars/version-0.5.6-sidebars.json rename versioned_sidebars/{version-0.5.1-sidebars.json => version-0.6-sidebars.json} (100%) delete mode 100644 versioned_sidebars/version-0.6.0-sidebars.json rename versioned_sidebars/{version-0.5.2-sidebars.json => version-0.7-sidebars.json} (100%) delete mode 100644 versioned_sidebars/version-0.7.0-sidebars.json rename versioned_sidebars/{version-0.5.3-sidebars.json => version-0.8-sidebars.json} (100%) delete mode 100644 versioned_sidebars/version-0.8.0-sidebars.json diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml deleted file mode 100644 index c541242e..00000000 --- a/.github/workflows/check.yml +++ /dev/null @@ -1,63 +0,0 @@ -name: check -on: - pull_request: - branches: - - main - push: - branches: - - main -jobs: - LinkCheck: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v1 - with: - go-version: "1.16.6" - - name: Check Link - run: make check-link - - # Lints Pull Request commits with commitlint. - # - # Rules can be referenced: - # https://github.com/conventional-changelog/commitlint/tree/master/%40commitlint/config-conventional - # CommitLint: - # name: Commit Lint - # runs-on: ubuntu-latest - # if: contains(fromJSON('["pull_request"]'), github.event_name) - # steps: - # - uses: actions/checkout@v3 - # - name: Checkout - # uses: actions/checkout@v3 - # with: - # fetch-depth: 0 - # - uses: wagoid/commitlint-github-action@v5 - - # LicenseCheck: - # name: License Check - # runs-on: ubuntu-latest - # env: - # TERM: xterm - # steps: - # - uses: actions/checkout@v3 - # with: - # fetch-depth: 0 - # - uses: apache/skywalking-eyes@main - - # The TruffleHog OSS Github Action can be used to scan a range of commits for leaked credentials. The action will fail if any results are found. - # More see: https://github.com/marketplace/actions/trufflehog-oss - SecretScan: - name: Secret Scan - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - name: TruffleHog OSS - uses: trufflesecurity/trufflehog@main - with: - path: ./ - base: ${{ github.event.repository.default_branch }} - head: HEAD - extra_args: --debug --json diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index dd691550..f0b5904b 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -19,7 +19,7 @@ jobs: path-to-document: 'https://github.com/kcl-lang/.github/blob/main/CLA.md' # e.g. a CLA or a DCO document # branch should not be protected - lock-pullrequest-aftermerge: True + lock-pullrequest-aftermerge: false path-to-signatures: 'signatures/version1/cla.json' remote-organization-name: kcl-lang remote-repository-name: cla.db diff --git a/.github/workflows/install-kusion.yml b/.github/workflows/install-kusion.yml deleted file mode 100644 index c4c464ab..00000000 --- a/.github/workflows/install-kusion.yml +++ /dev/null @@ -1,79 +0,0 @@ -name: script-kusion -on: - push: - branches: - - main -jobs: - check-kusion-script-install: - strategy: - matrix: - os: [macos-11, macos-12, macos-latest] - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v3 - - name: Check Install Script - run: curl https://www.kusionstack.io/scripts/install.sh | sh - - name: Check Kusion run - shell: bash -leo pipefail {0} - run: | - sudo kusion version - sudo kusion build -w static/stack -o stdout - cd static/stack && sudo kusion build - - name: Uninstall Kusion - run: curl https://www.kusionstack.io/scripts/uninstall.sh | sh - - check-kusion-brew-install: - strategy: - matrix: - os: [macos-11, macos-12, macos-latest] - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v3 - - - name: Check Brew Installation - working-directory: . - run: | - brew install KusionStack/tap/kusion - echo "brew installed successfully" - kusion version - kusion build -w static/stack -o stdout - cd static/stack && kusion build - brew uninstall KusionStack/tap/kusion - - check-kusion-go-install: - strategy: - matrix: - os: [macos-11, macos-12, ubuntu-latest] - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v3 - - - uses: actions/setup-python@v4 - with: - python-version: '3.9' - - uses: actions/setup-go@v1 - with: - go-version: "1.21" - - - name: Check Go Installation - working-directory: . - run: | - go install kusionstack.io/kusion@latest - echo "go installed successfully" - $HOME/go/bin/kusion version - $HOME/go/bin/kusion build -w static/stack -o stdout - cd static/stack && $HOME/go/bin/kusion build - - check-kusion-scoop-install: - runs-on: windows-latest - steps: - - uses: actions/checkout@v3 - - name: Check Scoop Install - shell: powershell - run: | - iwr -useb get.scoop.sh -outfile 'install.ps1' - .\install.ps1 -RunAsAdmin - scoop bucket add KusionStack https://github.com/KusionStack/scoop-bucket.git - scoop install KusionStack/kusion - mkdir C:\Users\runneradmin\go - kusion build -w static/stack -o stdout diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 0ba6459e..00000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,16 +0,0 @@ -# KCL Changelog - -- KCL v0.8.0 - https://github.com/kcl-lang/kcl/releases/tag/v0.8.0 -- KCL v0.7.0 - https://github.com/kcl-lang/kcl/releases/tag/v0.7.0 -- KCL v0.6.0 - https://github.com/kcl-lang/kcl/releases/tag/v0.6.0 -- KCL v0.5.6 - https://github.com/kcl-lang/kcl/releases/tag/v0.5.6 -- KCL v0.5.5 - https://github.com/kcl-lang/kcl/releases/tag/v0.5.5 -- KCL v0.5.4 - https://github.com/kcl-lang/kcl/releases/tag/v0.5.4 -- KCL v0.5.3 - https://github.com/kcl-lang/kcl/releases/tag/v0.5.3 -- KCL v0.5.2 - https://github.com/kcl-lang/kcl/releases/tag/v0.5.2 -- KCL v0.5.1 - https://github.com/kcl-lang/kcl/releases/tag/v0.5.1 -- KCL v0.5.0 - https://github.com/kcl-lang/kcl/releases/tag/v0.5.0 -- KCL v0.4.6 - https://github.com/kcl-lang/kcl/releases/tag/v0.4.6 -- KCL v0.4.5 - https://github.com/kcl-lang/kcl/releases/tag/v0.4.5 -- KCL v0.4.4 - https://github.com/kcl-lang/kcl/releases/tag/v0.4.4 -- KCL v0.4.3 - https://github.com/kcl-lang/kcl/releases/tag/v0.4.3 diff --git a/VERSION b/VERSION index a3df0a69..ce609caf 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.8.0 +0.8 \ No newline at end of file diff --git a/i18n/en/docusaurus-plugin-content-docs/version-0.5.0.json b/i18n/en/docusaurus-plugin-content-docs/version-0.5.0.json deleted file mode 100644 index 9ab84a2f..00000000 --- a/i18n/en/docusaurus-plugin-content-docs/version-0.5.0.json +++ /dev/null @@ -1,246 +0,0 @@ -{ - "version.label": { - "message": "0.5.0", - "description": "The label for version 0.5.0" - }, - "sidebar.docs.category.Tools": { - "message": "Tools", - "description": "The label for category Tools in sidebar docs" - }, - "sidebar.docs.category.Command Line Tools": { - "message": "Command Line Tools", - "description": "The label for category Command Line Tools in sidebar docs" - }, - "sidebar.docs.category.KCL Tools": { - "message": "KCL Tools", - "description": "The label for category KCL Tools in sidebar docs" - }, - "sidebar.docs.category.OpenAPI Tools": { - "message": "OpenAPI Tools", - "description": "The label for category OpenAPI Tools in sidebar docs" - }, - "sidebar.docs.category.IDE": { - "message": "IDE", - "description": "The label for category IDE in sidebar docs" - }, - "sidebar.docs.category.Reference": { - "message": "Reference", - "description": "The label for category Reference in sidebar docs" - }, - "sidebar.docs.category.Tutorial": { - "message": "Tutorial", - "description": "The label for category Tutorial in sidebar docs" - }, - "sidebar.docs.category.Code Lab": { - "message": "Code Lab", - "description": "The label for category Code Lab in sidebar docs" - }, - "sidebar.docs.category.Spec": { - "message": "Spec", - "description": "The label for category Spec in sidebar docs" - }, - "sidebar.docs.category.Errors and Warnings": { - "message": "Errors and Warnings", - "description": "The label for category Errors and Warnings in sidebar docs" - }, - "sidebar.docs.category.System Package": { - "message": "System Package", - "description": "The label for category System Package in sidebar docs" - }, - "sidebar.docs.category.Plugin System": { - "message": "Plugin System", - "description": "The label for category Plugin System in sidebar docs" - }, - "sidebar.docs.category.Multi-Language": { - "message": "Multi-Language", - "description": "The label for category Multi-Language in sidebar docs" - }, - "sidebar.docs.category.community": { - "message": "community", - "description": "The label for category community in sidebar docs" - }, - "sidebar.docs.category.Community": { - "message": "Community", - "description": "The label for category Community in sidebar docs" - }, - "sidebar.docs.category.Release Policy": { - "message": "Release Policy", - "description": "The label for category Release Policy in sidebar docs" - }, - "sidebar.docs.category.Contribution Guide": { - "message": "Contribution Guide", - "description": "The label for category Contribution Guide in sidebar docs" - }, - "sidebar.docs.category.user_docs": { - "message": "user_docs", - "description": "The label for category user_docs in sidebar docs" - }, - "sidebar.docs.category.Get Started": { - "message": "Get Started", - "description": "The label for category Get Started in sidebar docs" - }, - "sidebar.docs.category.User Guide": { - "message": "User Guide", - "description": "The label for category User Guide in sidebar docs" - }, - "sidebar.docs.category.Package Management": { - "message": "Package Management", - "description": "The label for category Package Management in sidebar docs" - }, - "sidebar.docs.category.Kubernetes": { - "message": "Kubernetes", - "description": "The label for category Kubernetes in sidebar docs" - }, - "sidebar.docs.category.Konfig": { - "message": "Konfig", - "description": "The label for category Konfig in sidebar docs" - }, - "sidebar.docs.category.Concepts": { - "message": "Concepts", - "description": "The label for category Concepts in sidebar docs" - }, - "sidebar.docs.category.FAQ": { - "message": "FAQ", - "description": "The label for category FAQ in sidebar docs" - }, - "sidebar.user_docs.category.Get Started": { - "message": "Get Started", - "description": "The label for category Get Started in sidebar user_docs" - }, - "sidebar.user_docs.category.User Guide": { - "message": "User Guide", - "description": "The label for category User Guide in sidebar user_docs" - }, - "sidebar.user_docs.category.Package Management": { - "message": "Package Management", - "description": "The label for category Package Management in sidebar user_docs" - }, - "sidebar.user_docs.category.Kubernetes": { - "message": "Kubernetes", - "description": "The label for category Kubernetes in sidebar user_docs" - }, - "sidebar.user_docs.category.Konfig": { - "message": "Konfig", - "description": "The label for category Konfig in sidebar user_docs" - }, - "sidebar.user_docs.category.Concepts": { - "message": "Concepts", - "description": "The label for category Concepts in sidebar user_docs" - }, - "sidebar.user_docs.category.FAQ": { - "message": "FAQ", - "description": "The label for category FAQ in sidebar user_docs" - }, - "sidebar.reference.category.Tutorial": { - "message": "Tutorial", - "description": "The label for category Tutorial in sidebar reference" - }, - "sidebar.reference.category.Code Lab": { - "message": "Code Lab", - "description": "The label for category Code Lab in sidebar reference" - }, - "sidebar.reference.category.Spec": { - "message": "Spec", - "description": "The label for category Spec in sidebar reference" - }, - "sidebar.reference.category.Errors and Warnings": { - "message": "Errors and Warnings", - "description": "The label for category Errors and Warnings in sidebar reference" - }, - "sidebar.reference.category.System Package": { - "message": "System Package", - "description": "The label for category System Package in sidebar reference" - }, - "sidebar.reference.category.Plugin System": { - "message": "Plugin System", - "description": "The label for category Plugin System in sidebar reference" - }, - "sidebar.reference.category.Multi-Language": { - "message": "Multi-Language", - "description": "The label for category Multi-Language in sidebar reference" - }, - "sidebar.tools.category.Command Line Tools": { - "message": "Command Line Tools", - "description": "The label for category Command Line Tools in sidebar tools" - }, - "sidebar.tools.category.KCL Tools": { - "message": "KCL Tools", - "description": "The label for category KCL Tools in sidebar tools" - }, - "sidebar.tools.category.OpenAPI Tools": { - "message": "OpenAPI Tools", - "description": "The label for category OpenAPI Tools in sidebar tools" - }, - "sidebar.tools.category.IDE": { - "message": "IDE", - "description": "The label for category IDE in sidebar tools" - }, - "sidebar.community.category.Community": { - "message": "Community", - "description": "The label for category Community in sidebar community" - }, - "sidebar.community.category.Release Policy": { - "message": "Release Policy", - "description": "The label for category Release Policy in sidebar community" - }, - "sidebar.community.category.Contribution Guide": { - "message": "Contribution Guide", - "description": "The label for category Contribution Guide in sidebar community" - }, - "sidebar.docs.category.Command Reference": { - "message": "Command Reference", - "description": "The label for category Command Reference in sidebar docs" - }, - "sidebar.reference.category.Package Management": { - "message": "Package Management", - "description": "The label for category Package Management in sidebar reference" - }, - "sidebar.reference.category.Command Reference": { - "message": "Command Reference", - "description": "The label for category Command Reference in sidebar reference" - }, - "sidebar.docs.category.GitOps": { - "message": "GitOps", - "description": "The label for category GitOps in sidebar docs" - }, - "sidebar.docs.category.CI Integration": { - "message": "CI Integration", - "description": "The label for category CI Integration in sidebar docs" - }, - "sidebar.user_docs.category.GitOps": { - "message": "GitOps", - "description": "The label for category GitOps in sidebar user_docs" - }, - "sidebar.user_docs.category.CI Integration": { - "message": "CI Integration", - "description": "The label for category CI Integration in sidebar user_docs" - }, - "sidebar.docs.category.Mutate or Validate Kubernetes Manifests": { - "message": "Mutate or Validate Kubernetes Manifests", - "description": "The label for category Mutate or Validate Kubernetes Manifests in sidebar docs" - }, - "sidebar.user_docs.category.Mutate or Validate Kubernetes Manifests": { - "message": "Mutate or Validate Kubernetes Manifests", - "description": "The label for category Mutate or Validate Kubernetes Manifests in sidebar user_docs" - }, - "sidebar.docs.category.Package Management Tools": { - "message": "Package Management Tools", - "description": "The label for category Package Management Tools in sidebar docs" - }, - "sidebar.docs.category.How to": { - "message": "How to", - "description": "The label for category How to in sidebar docs" - }, - "sidebar.user_docs.category.Package Management Tools": { - "message": "Package Management Tools", - "description": "The label for category Package Management Tools in sidebar user_docs" - }, - "sidebar.user_docs.category.How to": { - "message": "How to", - "description": "The label for category How to in sidebar user_docs" - }, - "sidebar.reference.category.Package Management Tools": { - "message": "Package Management Tools", - "description": "The label for category Package Management Tools in sidebar reference" - } -} diff --git a/i18n/en/docusaurus-plugin-content-docs/version-0.5.3.json b/i18n/en/docusaurus-plugin-content-docs/version-0.5.3.json deleted file mode 100644 index b49f7f07..00000000 --- a/i18n/en/docusaurus-plugin-content-docs/version-0.5.3.json +++ /dev/null @@ -1,254 +0,0 @@ -{ - "version.label": { - "message": "0.5.3", - "description": "The label for version 0.5.3" - }, - "sidebar.docs.category.Tools": { - "message": "Tools", - "description": "The label for category Tools in sidebar docs" - }, - "sidebar.docs.category.Command Line Tools": { - "message": "Command Line Tools", - "description": "The label for category Command Line Tools in sidebar docs" - }, - "sidebar.docs.category.KCL Tools": { - "message": "KCL Tools", - "description": "The label for category KCL Tools in sidebar docs" - }, - "sidebar.docs.category.OpenAPI Tools": { - "message": "OpenAPI Tools", - "description": "The label for category OpenAPI Tools in sidebar docs" - }, - "sidebar.docs.category.IDE": { - "message": "IDE", - "description": "The label for category IDE in sidebar docs" - }, - "sidebar.docs.category.Reference": { - "message": "Reference", - "description": "The label for category Reference in sidebar docs" - }, - "sidebar.docs.category.Tutorial": { - "message": "Tutorial", - "description": "The label for category Tutorial in sidebar docs" - }, - "sidebar.docs.category.Code Lab": { - "message": "Code Lab", - "description": "The label for category Code Lab in sidebar docs" - }, - "sidebar.docs.category.Spec": { - "message": "Spec", - "description": "The label for category Spec in sidebar docs" - }, - "sidebar.docs.category.Errors and Warnings": { - "message": "Errors and Warnings", - "description": "The label for category Errors and Warnings in sidebar docs" - }, - "sidebar.docs.category.System Package": { - "message": "System Package", - "description": "The label for category System Package in sidebar docs" - }, - "sidebar.docs.category.Package Management": { - "message": "Package Management", - "description": "The label for category Package Management in sidebar docs" - }, - "sidebar.docs.category.Command Reference": { - "message": "Command Reference", - "description": "The label for category Command Reference in sidebar docs" - }, - "sidebar.docs.category.Plugin System": { - "message": "Plugin System", - "description": "The label for category Plugin System in sidebar docs" - }, - "sidebar.docs.category.Multi-Language": { - "message": "Multi-Language", - "description": "The label for category Multi-Language in sidebar docs" - }, - "sidebar.docs.category.community": { - "message": "community", - "description": "The label for category community in sidebar docs" - }, - "sidebar.docs.category.Community": { - "message": "Community", - "description": "The label for category Community in sidebar docs" - }, - "sidebar.docs.category.Release Policy": { - "message": "Release Policy", - "description": "The label for category Release Policy in sidebar docs" - }, - "sidebar.docs.category.Contribution Guide": { - "message": "Contribution Guide", - "description": "The label for category Contribution Guide in sidebar docs" - }, - "sidebar.docs.category.user_docs": { - "message": "user_docs", - "description": "The label for category user_docs in sidebar docs" - }, - "sidebar.docs.category.Get Started": { - "message": "Get Started", - "description": "The label for category Get Started in sidebar docs" - }, - "sidebar.docs.category.User Guide": { - "message": "User Guide", - "description": "The label for category User Guide in sidebar docs" - }, - "sidebar.docs.category.Kubernetes": { - "message": "Kubernetes", - "description": "The label for category Kubernetes in sidebar docs" - }, - "sidebar.docs.category.Mutate or Validate Kubernetes Manifests": { - "message": "Mutate or Validate Kubernetes Manifests", - "description": "The label for category Mutate or Validate Kubernetes Manifests in sidebar docs" - }, - "sidebar.docs.category.Konfig": { - "message": "Konfig", - "description": "The label for category Konfig in sidebar docs" - }, - "sidebar.docs.category.GitOps": { - "message": "GitOps", - "description": "The label for category GitOps in sidebar docs" - }, - "sidebar.docs.category.CI Integration": { - "message": "CI Integration", - "description": "The label for category CI Integration in sidebar docs" - }, - "sidebar.docs.category.Secret Management": { - "message": "Secret Management", - "description": "The label for category Secret Management in sidebar docs" - }, - "sidebar.docs.category.Concepts": { - "message": "Concepts", - "description": "The label for category Concepts in sidebar docs" - }, - "sidebar.docs.category.FAQ": { - "message": "FAQ", - "description": "The label for category FAQ in sidebar docs" - }, - "sidebar.user_docs.category.Get Started": { - "message": "Get Started", - "description": "The label for category Get Started in sidebar user_docs" - }, - "sidebar.user_docs.category.User Guide": { - "message": "User Guide", - "description": "The label for category User Guide in sidebar user_docs" - }, - "sidebar.user_docs.category.Package Management": { - "message": "Package Management", - "description": "The label for category Package Management in sidebar user_docs" - }, - "sidebar.user_docs.category.Kubernetes": { - "message": "Kubernetes", - "description": "The label for category Kubernetes in sidebar user_docs" - }, - "sidebar.user_docs.category.Mutate or Validate Kubernetes Manifests": { - "message": "Mutate or Validate Kubernetes Manifests", - "description": "The label for category Mutate or Validate Kubernetes Manifests in sidebar user_docs" - }, - "sidebar.user_docs.category.Konfig": { - "message": "Konfig", - "description": "The label for category Konfig in sidebar user_docs" - }, - "sidebar.user_docs.category.GitOps": { - "message": "GitOps", - "description": "The label for category GitOps in sidebar user_docs" - }, - "sidebar.user_docs.category.CI Integration": { - "message": "CI Integration", - "description": "The label for category CI Integration in sidebar user_docs" - }, - "sidebar.user_docs.category.Secret Management": { - "message": "Secret Management", - "description": "The label for category Secret Management in sidebar user_docs" - }, - "sidebar.user_docs.category.Concepts": { - "message": "Concepts", - "description": "The label for category Concepts in sidebar user_docs" - }, - "sidebar.user_docs.category.FAQ": { - "message": "FAQ", - "description": "The label for category FAQ in sidebar user_docs" - }, - "sidebar.reference.category.Tutorial": { - "message": "Tutorial", - "description": "The label for category Tutorial in sidebar reference" - }, - "sidebar.reference.category.Code Lab": { - "message": "Code Lab", - "description": "The label for category Code Lab in sidebar reference" - }, - "sidebar.reference.category.Spec": { - "message": "Spec", - "description": "The label for category Spec in sidebar reference" - }, - "sidebar.reference.category.Errors and Warnings": { - "message": "Errors and Warnings", - "description": "The label for category Errors and Warnings in sidebar reference" - }, - "sidebar.reference.category.System Package": { - "message": "System Package", - "description": "The label for category System Package in sidebar reference" - }, - "sidebar.reference.category.Package Management": { - "message": "Package Management", - "description": "The label for category Package Management in sidebar reference" - }, - "sidebar.reference.category.Command Reference": { - "message": "Command Reference", - "description": "The label for category Command Reference in sidebar reference" - }, - "sidebar.reference.category.Plugin System": { - "message": "Plugin System", - "description": "The label for category Plugin System in sidebar reference" - }, - "sidebar.reference.category.Multi-Language": { - "message": "Multi-Language", - "description": "The label for category Multi-Language in sidebar reference" - }, - "sidebar.tools.category.Command Line Tools": { - "message": "Command Line Tools", - "description": "The label for category Command Line Tools in sidebar tools" - }, - "sidebar.tools.category.KCL Tools": { - "message": "KCL Tools", - "description": "The label for category KCL Tools in sidebar tools" - }, - "sidebar.tools.category.OpenAPI Tools": { - "message": "OpenAPI Tools", - "description": "The label for category OpenAPI Tools in sidebar tools" - }, - "sidebar.tools.category.IDE": { - "message": "IDE", - "description": "The label for category IDE in sidebar tools" - }, - "sidebar.community.category.Community": { - "message": "Community", - "description": "The label for category Community in sidebar community" - }, - "sidebar.community.category.Release Policy": { - "message": "Release Policy", - "description": "The label for category Release Policy in sidebar community" - }, - "sidebar.community.category.Contribution Guide": { - "message": "Contribution Guide", - "description": "The label for category Contribution Guide in sidebar community" - }, - "sidebar.docs.category.Package Management Tools": { - "message": "Package Management Tools", - "description": "The label for category Package Management Tools in sidebar docs" - }, - "sidebar.docs.category.How to": { - "message": "How to", - "description": "The label for category How to in sidebar docs" - }, - "sidebar.user_docs.category.Package Management Tools": { - "message": "Package Management Tools", - "description": "The label for category Package Management Tools in sidebar user_docs" - }, - "sidebar.user_docs.category.How to": { - "message": "How to", - "description": "The label for category How to in sidebar user_docs" - }, - "sidebar.reference.category.Package Management Tools": { - "message": "Package Management Tools", - "description": "The label for category Package Management Tools in sidebar reference" - } -} diff --git a/i18n/en/docusaurus-plugin-content-docs/version-0.5.4.json b/i18n/en/docusaurus-plugin-content-docs/version-0.5.4.json deleted file mode 100644 index 3cff1f6c..00000000 --- a/i18n/en/docusaurus-plugin-content-docs/version-0.5.4.json +++ /dev/null @@ -1,254 +0,0 @@ -{ - "version.label": { - "message": "0.5.4", - "description": "The label for version 0.5.4" - }, - "sidebar.docs.category.Tools": { - "message": "Tools", - "description": "The label for category Tools in sidebar docs" - }, - "sidebar.docs.category.Command Line Tools": { - "message": "Command Line Tools", - "description": "The label for category Command Line Tools in sidebar docs" - }, - "sidebar.docs.category.KCL Tools": { - "message": "KCL Tools", - "description": "The label for category KCL Tools in sidebar docs" - }, - "sidebar.docs.category.OpenAPI Tools": { - "message": "OpenAPI Tools", - "description": "The label for category OpenAPI Tools in sidebar docs" - }, - "sidebar.docs.category.IDE": { - "message": "IDE", - "description": "The label for category IDE in sidebar docs" - }, - "sidebar.docs.category.Reference": { - "message": "Reference", - "description": "The label for category Reference in sidebar docs" - }, - "sidebar.docs.category.Tutorial": { - "message": "Tutorial", - "description": "The label for category Tutorial in sidebar docs" - }, - "sidebar.docs.category.Code Lab": { - "message": "Code Lab", - "description": "The label for category Code Lab in sidebar docs" - }, - "sidebar.docs.category.Spec": { - "message": "Spec", - "description": "The label for category Spec in sidebar docs" - }, - "sidebar.docs.category.Errors and Warnings": { - "message": "Errors and Warnings", - "description": "The label for category Errors and Warnings in sidebar docs" - }, - "sidebar.docs.category.System Package": { - "message": "System Package", - "description": "The label for category System Package in sidebar docs" - }, - "sidebar.docs.category.Package Management": { - "message": "Package Management", - "description": "The label for category Package Management in sidebar docs" - }, - "sidebar.docs.category.Command Reference": { - "message": "Command Reference", - "description": "The label for category Command Reference in sidebar docs" - }, - "sidebar.docs.category.Plugin System": { - "message": "Plugin System", - "description": "The label for category Plugin System in sidebar docs" - }, - "sidebar.docs.category.Multi-Language": { - "message": "Multi-Language", - "description": "The label for category Multi-Language in sidebar docs" - }, - "sidebar.docs.category.community": { - "message": "community", - "description": "The label for category community in sidebar docs" - }, - "sidebar.docs.category.Community": { - "message": "Community", - "description": "The label for category Community in sidebar docs" - }, - "sidebar.docs.category.Release Policy": { - "message": "Release Policy", - "description": "The label for category Release Policy in sidebar docs" - }, - "sidebar.docs.category.Contribution Guide": { - "message": "Contribution Guide", - "description": "The label for category Contribution Guide in sidebar docs" - }, - "sidebar.docs.category.user_docs": { - "message": "user_docs", - "description": "The label for category user_docs in sidebar docs" - }, - "sidebar.docs.category.Get Started": { - "message": "Get Started", - "description": "The label for category Get Started in sidebar docs" - }, - "sidebar.docs.category.User Guide": { - "message": "User Guide", - "description": "The label for category User Guide in sidebar docs" - }, - "sidebar.docs.category.Kubernetes": { - "message": "Kubernetes", - "description": "The label for category Kubernetes in sidebar docs" - }, - "sidebar.docs.category.Mutate or Validate Kubernetes Manifests": { - "message": "Mutate or Validate Kubernetes Manifests", - "description": "The label for category Mutate or Validate Kubernetes Manifests in sidebar docs" - }, - "sidebar.docs.category.Konfig": { - "message": "Konfig", - "description": "The label for category Konfig in sidebar docs" - }, - "sidebar.docs.category.GitOps": { - "message": "GitOps", - "description": "The label for category GitOps in sidebar docs" - }, - "sidebar.docs.category.CI Integration": { - "message": "CI Integration", - "description": "The label for category CI Integration in sidebar docs" - }, - "sidebar.docs.category.Secret Management": { - "message": "Secret Management", - "description": "The label for category Secret Management in sidebar docs" - }, - "sidebar.docs.category.Concepts": { - "message": "Concepts", - "description": "The label for category Concepts in sidebar docs" - }, - "sidebar.docs.category.FAQ": { - "message": "FAQ", - "description": "The label for category FAQ in sidebar docs" - }, - "sidebar.user_docs.category.Get Started": { - "message": "Get Started", - "description": "The label for category Get Started in sidebar user_docs" - }, - "sidebar.user_docs.category.User Guide": { - "message": "User Guide", - "description": "The label for category User Guide in sidebar user_docs" - }, - "sidebar.user_docs.category.Package Management": { - "message": "Package Management", - "description": "The label for category Package Management in sidebar user_docs" - }, - "sidebar.user_docs.category.Kubernetes": { - "message": "Kubernetes", - "description": "The label for category Kubernetes in sidebar user_docs" - }, - "sidebar.user_docs.category.Mutate or Validate Kubernetes Manifests": { - "message": "Mutate or Validate Kubernetes Manifests", - "description": "The label for category Mutate or Validate Kubernetes Manifests in sidebar user_docs" - }, - "sidebar.user_docs.category.Konfig": { - "message": "Konfig", - "description": "The label for category Konfig in sidebar user_docs" - }, - "sidebar.user_docs.category.GitOps": { - "message": "GitOps", - "description": "The label for category GitOps in sidebar user_docs" - }, - "sidebar.user_docs.category.CI Integration": { - "message": "CI Integration", - "description": "The label for category CI Integration in sidebar user_docs" - }, - "sidebar.user_docs.category.Secret Management": { - "message": "Secret Management", - "description": "The label for category Secret Management in sidebar user_docs" - }, - "sidebar.user_docs.category.Concepts": { - "message": "Concepts", - "description": "The label for category Concepts in sidebar user_docs" - }, - "sidebar.user_docs.category.FAQ": { - "message": "FAQ", - "description": "The label for category FAQ in sidebar user_docs" - }, - "sidebar.reference.category.Tutorial": { - "message": "Tutorial", - "description": "The label for category Tutorial in sidebar reference" - }, - "sidebar.reference.category.Code Lab": { - "message": "Code Lab", - "description": "The label for category Code Lab in sidebar reference" - }, - "sidebar.reference.category.Spec": { - "message": "Spec", - "description": "The label for category Spec in sidebar reference" - }, - "sidebar.reference.category.Errors and Warnings": { - "message": "Errors and Warnings", - "description": "The label for category Errors and Warnings in sidebar reference" - }, - "sidebar.reference.category.System Package": { - "message": "System Package", - "description": "The label for category System Package in sidebar reference" - }, - "sidebar.reference.category.Package Management": { - "message": "Package Management", - "description": "The label for category Package Management in sidebar reference" - }, - "sidebar.reference.category.Command Reference": { - "message": "Command Reference", - "description": "The label for category Command Reference in sidebar reference" - }, - "sidebar.reference.category.Plugin System": { - "message": "Plugin System", - "description": "The label for category Plugin System in sidebar reference" - }, - "sidebar.reference.category.Multi-Language": { - "message": "Multi-Language", - "description": "The label for category Multi-Language in sidebar reference" - }, - "sidebar.tools.category.Command Line Tools": { - "message": "Command Line Tools", - "description": "The label for category Command Line Tools in sidebar tools" - }, - "sidebar.tools.category.KCL Tools": { - "message": "KCL Tools", - "description": "The label for category KCL Tools in sidebar tools" - }, - "sidebar.tools.category.OpenAPI Tools": { - "message": "OpenAPI Tools", - "description": "The label for category OpenAPI Tools in sidebar tools" - }, - "sidebar.tools.category.IDE": { - "message": "IDE", - "description": "The label for category IDE in sidebar tools" - }, - "sidebar.community.category.Community": { - "message": "Community", - "description": "The label for category Community in sidebar community" - }, - "sidebar.community.category.Release Policy": { - "message": "Release Policy", - "description": "The label for category Release Policy in sidebar community" - }, - "sidebar.community.category.Contribution Guide": { - "message": "Contribution Guide", - "description": "The label for category Contribution Guide in sidebar community" - }, - "sidebar.docs.category.Package Management Tools": { - "message": "Package Management Tools", - "description": "The label for category Package Management Tools in sidebar docs" - }, - "sidebar.docs.category.How to": { - "message": "How to", - "description": "The label for category How to in sidebar docs" - }, - "sidebar.user_docs.category.Package Management Tools": { - "message": "Package Management Tools", - "description": "The label for category Package Management Tools in sidebar user_docs" - }, - "sidebar.user_docs.category.How to": { - "message": "How to", - "description": "The label for category How to in sidebar user_docs" - }, - "sidebar.reference.category.Package Management Tools": { - "message": "Package Management Tools", - "description": "The label for category Package Management Tools in sidebar reference" - } -} diff --git a/i18n/en/docusaurus-plugin-content-docs/version-0.5.5.json b/i18n/en/docusaurus-plugin-content-docs/version-0.5.5.json deleted file mode 100644 index 92531b80..00000000 --- a/i18n/en/docusaurus-plugin-content-docs/version-0.5.5.json +++ /dev/null @@ -1,254 +0,0 @@ -{ - "version.label": { - "message": "0.5.5", - "description": "The label for version 0.5.5" - }, - "sidebar.docs.category.Tools": { - "message": "Tools", - "description": "The label for category Tools in sidebar docs" - }, - "sidebar.docs.category.Command Line Tools": { - "message": "Command Line Tools", - "description": "The label for category Command Line Tools in sidebar docs" - }, - "sidebar.docs.category.KCL Tools": { - "message": "KCL Tools", - "description": "The label for category KCL Tools in sidebar docs" - }, - "sidebar.docs.category.OpenAPI Tools": { - "message": "OpenAPI Tools", - "description": "The label for category OpenAPI Tools in sidebar docs" - }, - "sidebar.docs.category.IDE": { - "message": "IDE", - "description": "The label for category IDE in sidebar docs" - }, - "sidebar.docs.category.Reference": { - "message": "Reference", - "description": "The label for category Reference in sidebar docs" - }, - "sidebar.docs.category.Tutorial": { - "message": "Tutorial", - "description": "The label for category Tutorial in sidebar docs" - }, - "sidebar.docs.category.Code Lab": { - "message": "Code Lab", - "description": "The label for category Code Lab in sidebar docs" - }, - "sidebar.docs.category.Spec": { - "message": "Spec", - "description": "The label for category Spec in sidebar docs" - }, - "sidebar.docs.category.Errors and Warnings": { - "message": "Errors and Warnings", - "description": "The label for category Errors and Warnings in sidebar docs" - }, - "sidebar.docs.category.System Package": { - "message": "System Package", - "description": "The label for category System Package in sidebar docs" - }, - "sidebar.docs.category.Package Management": { - "message": "Package Management", - "description": "The label for category Package Management in sidebar docs" - }, - "sidebar.docs.category.Command Reference": { - "message": "Command Reference", - "description": "The label for category Command Reference in sidebar docs" - }, - "sidebar.docs.category.Plugin System": { - "message": "Plugin System", - "description": "The label for category Plugin System in sidebar docs" - }, - "sidebar.docs.category.Multi-Language": { - "message": "Multi-Language", - "description": "The label for category Multi-Language in sidebar docs" - }, - "sidebar.docs.category.community": { - "message": "community", - "description": "The label for category community in sidebar docs" - }, - "sidebar.docs.category.Community": { - "message": "Community", - "description": "The label for category Community in sidebar docs" - }, - "sidebar.docs.category.Release Policy": { - "message": "Release Policy", - "description": "The label for category Release Policy in sidebar docs" - }, - "sidebar.docs.category.Contribution Guide": { - "message": "Contribution Guide", - "description": "The label for category Contribution Guide in sidebar docs" - }, - "sidebar.docs.category.user_docs": { - "message": "user_docs", - "description": "The label for category user_docs in sidebar docs" - }, - "sidebar.docs.category.Get Started": { - "message": "Get Started", - "description": "The label for category Get Started in sidebar docs" - }, - "sidebar.docs.category.User Guide": { - "message": "User Guide", - "description": "The label for category User Guide in sidebar docs" - }, - "sidebar.docs.category.Kubernetes": { - "message": "Kubernetes", - "description": "The label for category Kubernetes in sidebar docs" - }, - "sidebar.docs.category.Mutate or Validate Kubernetes Manifests": { - "message": "Mutate or Validate Kubernetes Manifests", - "description": "The label for category Mutate or Validate Kubernetes Manifests in sidebar docs" - }, - "sidebar.docs.category.Konfig": { - "message": "Konfig", - "description": "The label for category Konfig in sidebar docs" - }, - "sidebar.docs.category.GitOps": { - "message": "GitOps", - "description": "The label for category GitOps in sidebar docs" - }, - "sidebar.docs.category.CI Integration": { - "message": "CI Integration", - "description": "The label for category CI Integration in sidebar docs" - }, - "sidebar.docs.category.Secret Management": { - "message": "Secret Management", - "description": "The label for category Secret Management in sidebar docs" - }, - "sidebar.docs.category.Concepts": { - "message": "Concepts", - "description": "The label for category Concepts in sidebar docs" - }, - "sidebar.docs.category.FAQ": { - "message": "FAQ", - "description": "The label for category FAQ in sidebar docs" - }, - "sidebar.user_docs.category.Get Started": { - "message": "Get Started", - "description": "The label for category Get Started in sidebar user_docs" - }, - "sidebar.user_docs.category.User Guide": { - "message": "User Guide", - "description": "The label for category User Guide in sidebar user_docs" - }, - "sidebar.user_docs.category.Package Management": { - "message": "Package Management", - "description": "The label for category Package Management in sidebar user_docs" - }, - "sidebar.user_docs.category.Kubernetes": { - "message": "Kubernetes", - "description": "The label for category Kubernetes in sidebar user_docs" - }, - "sidebar.user_docs.category.Mutate or Validate Kubernetes Manifests": { - "message": "Mutate or Validate Kubernetes Manifests", - "description": "The label for category Mutate or Validate Kubernetes Manifests in sidebar user_docs" - }, - "sidebar.user_docs.category.Konfig": { - "message": "Konfig", - "description": "The label for category Konfig in sidebar user_docs" - }, - "sidebar.user_docs.category.GitOps": { - "message": "GitOps", - "description": "The label for category GitOps in sidebar user_docs" - }, - "sidebar.user_docs.category.CI Integration": { - "message": "CI Integration", - "description": "The label for category CI Integration in sidebar user_docs" - }, - "sidebar.user_docs.category.Secret Management": { - "message": "Secret Management", - "description": "The label for category Secret Management in sidebar user_docs" - }, - "sidebar.user_docs.category.Concepts": { - "message": "Concepts", - "description": "The label for category Concepts in sidebar user_docs" - }, - "sidebar.user_docs.category.FAQ": { - "message": "FAQ", - "description": "The label for category FAQ in sidebar user_docs" - }, - "sidebar.reference.category.Tutorial": { - "message": "Tutorial", - "description": "The label for category Tutorial in sidebar reference" - }, - "sidebar.reference.category.Code Lab": { - "message": "Code Lab", - "description": "The label for category Code Lab in sidebar reference" - }, - "sidebar.reference.category.Spec": { - "message": "Spec", - "description": "The label for category Spec in sidebar reference" - }, - "sidebar.reference.category.Errors and Warnings": { - "message": "Errors and Warnings", - "description": "The label for category Errors and Warnings in sidebar reference" - }, - "sidebar.reference.category.System Package": { - "message": "System Package", - "description": "The label for category System Package in sidebar reference" - }, - "sidebar.reference.category.Package Management": { - "message": "Package Management", - "description": "The label for category Package Management in sidebar reference" - }, - "sidebar.reference.category.Command Reference": { - "message": "Command Reference", - "description": "The label for category Command Reference in sidebar reference" - }, - "sidebar.reference.category.Plugin System": { - "message": "Plugin System", - "description": "The label for category Plugin System in sidebar reference" - }, - "sidebar.reference.category.Multi-Language": { - "message": "Multi-Language", - "description": "The label for category Multi-Language in sidebar reference" - }, - "sidebar.tools.category.Command Line Tools": { - "message": "Command Line Tools", - "description": "The label for category Command Line Tools in sidebar tools" - }, - "sidebar.tools.category.KCL Tools": { - "message": "KCL Tools", - "description": "The label for category KCL Tools in sidebar tools" - }, - "sidebar.tools.category.OpenAPI Tools": { - "message": "OpenAPI Tools", - "description": "The label for category OpenAPI Tools in sidebar tools" - }, - "sidebar.tools.category.IDE": { - "message": "IDE", - "description": "The label for category IDE in sidebar tools" - }, - "sidebar.community.category.Community": { - "message": "Community", - "description": "The label for category Community in sidebar community" - }, - "sidebar.community.category.Release Policy": { - "message": "Release Policy", - "description": "The label for category Release Policy in sidebar community" - }, - "sidebar.community.category.Contribution Guide": { - "message": "Contribution Guide", - "description": "The label for category Contribution Guide in sidebar community" - }, - "sidebar.docs.category.Package Management Tools": { - "message": "Package Management Tools", - "description": "The label for category Package Management Tools in sidebar docs" - }, - "sidebar.docs.category.How to": { - "message": "How to", - "description": "The label for category How to in sidebar docs" - }, - "sidebar.user_docs.category.Package Management Tools": { - "message": "Package Management Tools", - "description": "The label for category Package Management Tools in sidebar user_docs" - }, - "sidebar.user_docs.category.How to": { - "message": "How to", - "description": "The label for category How to in sidebar user_docs" - }, - "sidebar.reference.category.Package Management Tools": { - "message": "Package Management Tools", - "description": "The label for category Package Management Tools in sidebar reference" - } -} diff --git a/i18n/en/docusaurus-plugin-content-docs/version-0.5.6.json b/i18n/en/docusaurus-plugin-content-docs/version-0.5.6.json deleted file mode 100644 index 3e5f0a89..00000000 --- a/i18n/en/docusaurus-plugin-content-docs/version-0.5.6.json +++ /dev/null @@ -1,254 +0,0 @@ -{ - "version.label": { - "message": "0.5.6", - "description": "The label for version 0.5.6" - }, - "sidebar.docs.category.Tools": { - "message": "Tools", - "description": "The label for category Tools in sidebar docs" - }, - "sidebar.docs.category.Command Line Tools": { - "message": "Command Line Tools", - "description": "The label for category Command Line Tools in sidebar docs" - }, - "sidebar.docs.category.KCL Tools": { - "message": "KCL Tools", - "description": "The label for category KCL Tools in sidebar docs" - }, - "sidebar.docs.category.OpenAPI Tools": { - "message": "OpenAPI Tools", - "description": "The label for category OpenAPI Tools in sidebar docs" - }, - "sidebar.docs.category.IDE": { - "message": "IDE", - "description": "The label for category IDE in sidebar docs" - }, - "sidebar.docs.category.Reference": { - "message": "Reference", - "description": "The label for category Reference in sidebar docs" - }, - "sidebar.docs.category.Tutorial": { - "message": "Tutorial", - "description": "The label for category Tutorial in sidebar docs" - }, - "sidebar.docs.category.Code Lab": { - "message": "Code Lab", - "description": "The label for category Code Lab in sidebar docs" - }, - "sidebar.docs.category.Spec": { - "message": "Spec", - "description": "The label for category Spec in sidebar docs" - }, - "sidebar.docs.category.Errors and Warnings": { - "message": "Errors and Warnings", - "description": "The label for category Errors and Warnings in sidebar docs" - }, - "sidebar.docs.category.System Package": { - "message": "System Package", - "description": "The label for category System Package in sidebar docs" - }, - "sidebar.docs.category.Package Management": { - "message": "Package Management", - "description": "The label for category Package Management in sidebar docs" - }, - "sidebar.docs.category.Command Reference": { - "message": "Command Reference", - "description": "The label for category Command Reference in sidebar docs" - }, - "sidebar.docs.category.Plugin System": { - "message": "Plugin System", - "description": "The label for category Plugin System in sidebar docs" - }, - "sidebar.docs.category.Multi-Language": { - "message": "Multi-Language", - "description": "The label for category Multi-Language in sidebar docs" - }, - "sidebar.docs.category.community": { - "message": "community", - "description": "The label for category community in sidebar docs" - }, - "sidebar.docs.category.Community": { - "message": "Community", - "description": "The label for category Community in sidebar docs" - }, - "sidebar.docs.category.Release Policy": { - "message": "Release Policy", - "description": "The label for category Release Policy in sidebar docs" - }, - "sidebar.docs.category.Contribution Guide": { - "message": "Contribution Guide", - "description": "The label for category Contribution Guide in sidebar docs" - }, - "sidebar.docs.category.user_docs": { - "message": "user_docs", - "description": "The label for category user_docs in sidebar docs" - }, - "sidebar.docs.category.Get Started": { - "message": "Get Started", - "description": "The label for category Get Started in sidebar docs" - }, - "sidebar.docs.category.User Guide": { - "message": "User Guide", - "description": "The label for category User Guide in sidebar docs" - }, - "sidebar.docs.category.Kubernetes": { - "message": "Kubernetes", - "description": "The label for category Kubernetes in sidebar docs" - }, - "sidebar.docs.category.Mutate or Validate Kubernetes Manifests": { - "message": "Mutate or Validate Kubernetes Manifests", - "description": "The label for category Mutate or Validate Kubernetes Manifests in sidebar docs" - }, - "sidebar.docs.category.Konfig": { - "message": "Konfig", - "description": "The label for category Konfig in sidebar docs" - }, - "sidebar.docs.category.GitOps": { - "message": "GitOps", - "description": "The label for category GitOps in sidebar docs" - }, - "sidebar.docs.category.CI Integration": { - "message": "CI Integration", - "description": "The label for category CI Integration in sidebar docs" - }, - "sidebar.docs.category.Secret Management": { - "message": "Secret Management", - "description": "The label for category Secret Management in sidebar docs" - }, - "sidebar.docs.category.Concepts": { - "message": "Concepts", - "description": "The label for category Concepts in sidebar docs" - }, - "sidebar.docs.category.FAQ": { - "message": "FAQ", - "description": "The label for category FAQ in sidebar docs" - }, - "sidebar.user_docs.category.Get Started": { - "message": "Get Started", - "description": "The label for category Get Started in sidebar user_docs" - }, - "sidebar.user_docs.category.User Guide": { - "message": "User Guide", - "description": "The label for category User Guide in sidebar user_docs" - }, - "sidebar.user_docs.category.Package Management": { - "message": "Package Management", - "description": "The label for category Package Management in sidebar user_docs" - }, - "sidebar.user_docs.category.Kubernetes": { - "message": "Kubernetes", - "description": "The label for category Kubernetes in sidebar user_docs" - }, - "sidebar.user_docs.category.Mutate or Validate Kubernetes Manifests": { - "message": "Mutate or Validate Kubernetes Manifests", - "description": "The label for category Mutate or Validate Kubernetes Manifests in sidebar user_docs" - }, - "sidebar.user_docs.category.Konfig": { - "message": "Konfig", - "description": "The label for category Konfig in sidebar user_docs" - }, - "sidebar.user_docs.category.GitOps": { - "message": "GitOps", - "description": "The label for category GitOps in sidebar user_docs" - }, - "sidebar.user_docs.category.CI Integration": { - "message": "CI Integration", - "description": "The label for category CI Integration in sidebar user_docs" - }, - "sidebar.user_docs.category.Secret Management": { - "message": "Secret Management", - "description": "The label for category Secret Management in sidebar user_docs" - }, - "sidebar.user_docs.category.Concepts": { - "message": "Concepts", - "description": "The label for category Concepts in sidebar user_docs" - }, - "sidebar.user_docs.category.FAQ": { - "message": "FAQ", - "description": "The label for category FAQ in sidebar user_docs" - }, - "sidebar.reference.category.Tutorial": { - "message": "Tutorial", - "description": "The label for category Tutorial in sidebar reference" - }, - "sidebar.reference.category.Code Lab": { - "message": "Code Lab", - "description": "The label for category Code Lab in sidebar reference" - }, - "sidebar.reference.category.Spec": { - "message": "Spec", - "description": "The label for category Spec in sidebar reference" - }, - "sidebar.reference.category.Errors and Warnings": { - "message": "Errors and Warnings", - "description": "The label for category Errors and Warnings in sidebar reference" - }, - "sidebar.reference.category.System Package": { - "message": "System Package", - "description": "The label for category System Package in sidebar reference" - }, - "sidebar.reference.category.Package Management": { - "message": "Package Management", - "description": "The label for category Package Management in sidebar reference" - }, - "sidebar.reference.category.Command Reference": { - "message": "Command Reference", - "description": "The label for category Command Reference in sidebar reference" - }, - "sidebar.reference.category.Plugin System": { - "message": "Plugin System", - "description": "The label for category Plugin System in sidebar reference" - }, - "sidebar.reference.category.Multi-Language": { - "message": "Multi-Language", - "description": "The label for category Multi-Language in sidebar reference" - }, - "sidebar.tools.category.Command Line Tools": { - "message": "Command Line Tools", - "description": "The label for category Command Line Tools in sidebar tools" - }, - "sidebar.tools.category.KCL Tools": { - "message": "KCL Tools", - "description": "The label for category KCL Tools in sidebar tools" - }, - "sidebar.tools.category.OpenAPI Tools": { - "message": "OpenAPI Tools", - "description": "The label for category OpenAPI Tools in sidebar tools" - }, - "sidebar.tools.category.IDE": { - "message": "IDE", - "description": "The label for category IDE in sidebar tools" - }, - "sidebar.community.category.Community": { - "message": "Community", - "description": "The label for category Community in sidebar community" - }, - "sidebar.community.category.Release Policy": { - "message": "Release Policy", - "description": "The label for category Release Policy in sidebar community" - }, - "sidebar.community.category.Contribution Guide": { - "message": "Contribution Guide", - "description": "The label for category Contribution Guide in sidebar community" - }, - "sidebar.docs.category.Package Management Tools": { - "message": "Package Management Tools", - "description": "The label for category Package Management Tools in sidebar docs" - }, - "sidebar.docs.category.How to": { - "message": "How to", - "description": "The label for category How to in sidebar docs" - }, - "sidebar.user_docs.category.Package Management Tools": { - "message": "Package Management Tools", - "description": "The label for category Package Management Tools in sidebar user_docs" - }, - "sidebar.user_docs.category.How to": { - "message": "How to", - "description": "The label for category How to in sidebar user_docs" - }, - "sidebar.reference.category.Package Management Tools": { - "message": "Package Management Tools", - "description": "The label for category Package Management Tools in sidebar reference" - } -} diff --git a/i18n/en/docusaurus-plugin-content-docs/version-0.5.2.json b/i18n/en/docusaurus-plugin-content-docs/version-0.5.json similarity index 99% rename from i18n/en/docusaurus-plugin-content-docs/version-0.5.2.json rename to i18n/en/docusaurus-plugin-content-docs/version-0.5.json index 1e0227b5..49cd36b5 100644 --- a/i18n/en/docusaurus-plugin-content-docs/version-0.5.2.json +++ b/i18n/en/docusaurus-plugin-content-docs/version-0.5.json @@ -1,7 +1,7 @@ { "version.label": { - "message": "0.5.2", - "description": "The label for version 0.5.2" + "message": "0.5", + "description": "The label for version 0.5" }, "sidebar.docs.category.Tools": { "message": "Tools", diff --git a/i18n/en/docusaurus-plugin-content-docs/version-0.6.0.json b/i18n/en/docusaurus-plugin-content-docs/version-0.6.json similarity index 99% rename from i18n/en/docusaurus-plugin-content-docs/version-0.6.0.json rename to i18n/en/docusaurus-plugin-content-docs/version-0.6.json index b58048f9..984e0523 100644 --- a/i18n/en/docusaurus-plugin-content-docs/version-0.6.0.json +++ b/i18n/en/docusaurus-plugin-content-docs/version-0.6.json @@ -1,7 +1,7 @@ { "version.label": { - "message": "0.6.0", - "description": "The label for version 0.6.0" + "message": "0.6", + "description": "The label for version 0.6" }, "sidebar.docs.category.Tools": { "message": "Tools", diff --git a/i18n/en/docusaurus-plugin-content-docs/version-0.7.0.json b/i18n/en/docusaurus-plugin-content-docs/version-0.7.json similarity index 99% rename from i18n/en/docusaurus-plugin-content-docs/version-0.7.0.json rename to i18n/en/docusaurus-plugin-content-docs/version-0.7.json index f94dbafa..d83e92a9 100644 --- a/i18n/en/docusaurus-plugin-content-docs/version-0.7.0.json +++ b/i18n/en/docusaurus-plugin-content-docs/version-0.7.json @@ -1,7 +1,7 @@ { "version.label": { - "message": "0.7.0", - "description": "The label for version 0.7.0" + "message": "0.7", + "description": "The label for version 0.7" }, "sidebar.docs.category.参考手册": { "message": "Reference", diff --git a/i18n/en/docusaurus-plugin-content-docs/version-0.5.1.json b/i18n/en/docusaurus-plugin-content-docs/version-0.8.json similarity index 96% rename from i18n/en/docusaurus-plugin-content-docs/version-0.5.1.json rename to i18n/en/docusaurus-plugin-content-docs/version-0.8.json index a6da0fd9..c8a9cf2f 100644 --- a/i18n/en/docusaurus-plugin-content-docs/version-0.5.1.json +++ b/i18n/en/docusaurus-plugin-content-docs/version-0.8.json @@ -1,7 +1,7 @@ { "version.label": { - "message": "0.5.1", - "description": "The label for version 0.5.1" + "message": "0.8", + "description": "The label for version 0.8" }, "sidebar.docs.category.参考手册": { "message": "Reference", @@ -19,6 +19,10 @@ "message": "OpenAPI Tools", "description": "The label for category OpenAPI 工具 in sidebar docs" }, + "sidebar.docs.category.包管理工具": { + "message": "Package Management Tools", + "description": "The label for category OpenAPI 工具 in sidebar docs" + }, "sidebar.docs.category.核心模型库": { "message": "Core Model", "description": "The label for category 核心模型库 in sidebar docs" @@ -247,6 +251,10 @@ "message": "OpenAPI Tools", "description": "The label for category OpenAPI 工具 in sidebar reference" }, + "sidebar.reference.category.包管理工具": { + "message": "Package Management Tools", + "description": "The label for category OpenAPI 工具 in sidebar reference" + }, "sidebar.reference.category.核心模型库": { "message": "Code Model", "description": "The label for category 核心模型库 in sidebar reference" @@ -691,6 +699,10 @@ "message": "Package Management", "description": "The label for category Package Management in sidebar user_docs" }, + "sidebar.user_docs.category.Package Management Tools": { + "message": "Package Management Tools", + "description": "The label for category Package Management Tools in sidebar user_docs" + }, "sidebar.user_docs.category.Konfig": { "message": "Konfig", "description": "The label for category Konfig in sidebar user_docs" @@ -747,16 +759,24 @@ "message": "How to", "description": "The label for category How to in sidebar docs" }, - "sidebar.user_docs.category.Package Management Tools": { - "message": "Package Management Tools", - "description": "The label for category Package Management Tools in sidebar user_docs" + "sidebar.docs.category.Terraform": { + "message": "Terraform", + "description": "The label for category Terraform in sidebar docs" }, "sidebar.user_docs.category.How to": { "message": "How to", "description": "The label for category How to in sidebar user_docs" }, - "sidebar.reference.category.Package Management Tools": { + "sidebar.user_docs.category.Terraform": { + "message": "Terraform", + "description": "The label for category Terraform in sidebar user_docs" + }, + "sidebar.tools.category.Command Reference": { + "message": "Command Reference", + "description": "The label for category Command Reference in sidebar tools" + }, + "sidebar.tools.category.Package Management Tools": { "message": "Package Management Tools", - "description": "The label for category Package Management Tools in sidebar reference" + "description": "The label for category Package Management Tools in sidebar tools" } } diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/error/exception.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/error/exception.md deleted file mode 100644 index cd18995f..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/error/exception.md +++ /dev/null @@ -1,1584 +0,0 @@ ---- -title: "KCL 错误与警告" -linkTitle: "KCL 错误与警告" -type: "docs" -weight: 2 -description: KCL 错误与警告 ---- - -# KCL 错误与警告 - -文档的此部分中的文章介绍了由 KCL 生成的诊断错误和警告消息。 - -**注意:** -**KCL 可以报告多种错误和警告。找到错误或警告后,KCL 可能会对代码意向作出假设并尝试继续,以便可以同时报告更多问题。 如果工具做出错误假设,则后续错误或警告可能不适应与当前 KCL 程序。 因此,纠正项目中的问题时,请先纠正第一个错误或警告,然后重新运行获取新的错误信息。 一个修补程序可能会导致后续错误消失。** - -此部分文档的主要内容包括: - -[KCL 语法错误 (E1xxx)](#11-kcl-%E8%AF%AD%E6%B3%95%E9%94%99%E8%AF%AF-e1xxx) : 如果 KCL 在当前 KCL 程序中发现了非法的 KCL 语法,KCL 就会停止运行并输出 KCL 程序语法错误的提示信息. - -[KCL 编译错误 (E2xxx)](#12-kcl-%E7%BC%96%E8%AF%91%E9%94%99%E8%AF%AF-e2xxx) : 如果 KCL 在一个不包含语法错误的 KCL 程序中发现了与 KCL 语义不符的代码,KCL 就会停止运行并输出编译错误的提示信息。 - -[KCL 运行时错误 (E3xxx)](#13-kcl-%E8%BF%90%E8%A1%8C%E6%97%B6%E9%94%99%E8%AF%AF-e3xxx) : KCL 程序通过编译后会生成 KCL 字节码,如果 KCL 在执行 KCL 字节码过程中出现错误,KCL 就会停止运行并输出运行时错误的提示信息. - -[KCL 编译警告 (W2xxx)](#14-kcl-%E7%BC%96%E8%AF%91%E8%AD%A6%E5%91%8A-w2xxx) : 当 KCL 发现可能导致运行失败的 KCL 代码,KCL 不会立即停止运行,但是会输出潜在错误的警告提示。 - -## 1.1 KCL 语法错误 (E1xxx) - -KCL 会出现的语法错误信息如下表所示: - -| ewcode | KCL exception | messages | -| ------ | ------------------------------------------------------------------- | ----------------------- | -| E1001 | [InvalidSyntaxError](#111-invalidsyntaxerror-e1001) | Invalid syntax | -| E1002 | [KCLTabError](#112-kcltaberror-e1002) | Tab Error | -| E1003 | [KCLIndentationError](#113-kclindentationerror-e1003) | Indentation Error | -| E1I37 | [IllegalArgumentSyntaxError](#114-illegalargumentsyntaxerror-e1i37) | Illegal argument syntax | - -### 1.1.1 InvalidSyntaxError [E1001] - -如果在运行 KCL 时遇到错误: - -- `InvalidSyntaxError`, 对应的 encode 为 `E1001` - -那么此时 KCL 程序中出现了 - -- 非法的 KCL 语法。 - -可能出现错误的 KCL 程序片段如下: - -```python -a, b = 1, 2 # 通过 “=” 赋值多个变量在KCL中是非法的。 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> /syntax_error/general/multiple_assign/case0/main.k:1:2 - | -1 | a, b = 1, 2 # Multiple assign is illegal in KCL syntax - | ^ expected statement - | -``` - -### 1.1.2 KCLTabError - -如果在运行 KCL 时遇到错误: `KCLTabError` - -那么此时 KCL 程序中出现了 - -- Tab 与空格混用的问题。KCL 中禁止在代码缩进中混用 Tab 和空格。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - name: str # 通过tab表示缩进 - age: int # 通过四个空格标识缩进, - # 在当前运行环境中的四个空格与tab不同 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> File /syntax_error/tab/tab_error_0/main.k:6:5 - | -3 | age: int = 1 - | ^ inconsistent use of tabs and spaces in indentation - | -``` - -可以尝试以下步骤来修复这个错误: - -- 在 KCL 程序中全部使用 Tab 或者全部使用四个空格,不要混用。 - -### 1.1.3 KCLIndentationError - -如果在运行 KCL 时遇到错误: `KCLIndentationError` - -那么此时 KCL 程序中出现了 - -- 程序缩进错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - name: str # 使用一个tab或者四个空格表示缩进 - age: int # KCL不支持使用三个空格表示缩进 - info: str # KCL不支持使用两个空格表示缩进 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> /syntax_error/indent/indent_error_0/main.k:3:4 - | -3 | age: int # three white spaces are illegal - | ^ unindent 3 does not match any outer indentation level - | -``` - -可以尝试以下步骤来修复这个错误: - -- 在 KCL 程序中全部使用 Tab 或者全部使用四个空格来表示缩进。 - -### 1.1.4 IllegalArgumentSyntaxError - -如果在运行 KCL 时遇到错误: `IllegalArgumentSyntaxError` - -那么此时 KCL 程序中出现了 - -- 参数语法错误 - -可能出现错误的 KCL 程序片段如下: - -```python -# KCL中带有keyword的参数必须出现在不带有keyword参数后面 -# 带有keyword的参数: type="list", default={"key": "value"} -# 不带有keyword的参数: "key1" -a = option(type="list", default={"key": "value"}, "key1") -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> /option/type_convert_fail_2/main.k:3:57 - | -3 | a = option(type="list", default={"key": "value"}, "key1") - | ^ positional argument follows keyword argument - | -``` - -可以尝试以下步骤来修复这个错误: - -- KCL 中带有 keyword 的参数必须出现在不带有 keyword 参数后面, 参数正常顺序: - -```python -func(input_1, ..., input_n, param_with_key_1 = input_with_key_1, ..., param_with_key_n = input_with_key_n) -``` - -## 1.2 KCL 编译错误 (E2xxx) - -KCL 会出现的编译错误信息如下表所示: - -| ewcode | KCL exception | messages | -| ------ | ----------------------------------------------------------------------- | --------------------------------------------------- | -| E2F04 | [CannotFindModule](#121-cannotfindmodule-e2f04) | Cannot find the module | -| E2F05 | [FailedLoadModule](#122-failedloadmodule-e2f05) | Failed to load module | -| E2H13 | [UnKnownDecoratorError](#123-unknowndecoratorerror-e2h13) | UnKnown decorator | -| E2H14 | [InvalidDecoratorTargetError](#124-invaliddecoratortargeterror-e2h14) | Invalid Decorator Target | -| E2C15 | [MixinNamingError](#125-mixinnamingerror-e2c15) | Illegal mixin naming | -| E2C16 | [MixinStructureIllegal](#126-mixinstructureillegal-e2c16) | Illegal mixin structure | -| E2B17 | [CannotAddMembersComplieError](#127-cannotaddmemberscomplieerror-e2b17) | Cannot add members to a schema | -| E2B20 | [IndexSignatureError](#128-indexsignatureerror-e2b20) | Invalid index signature | -| E2G22 | [TypeComplieError](#129-typecomplieerror-e2g22) | The type got is inconsistent with the type expected | -| E2L23 | [CompileError](#1210-compileerror-e2l23) | A complie error occurs during compiling | -| E2L25 | [KCLNameError](#1211-kclnameerror-e2l25) | Name Error | -| E2L26 | [KCLValueError](#1212-kclvalueerror-e2l26) | Value Error | -| E2L27 | [KCLKeyError](#1213-kclkeyerror-e2l27) | Key Error | -| E2L28 | [UniqueKeyError](#1214-uniquekeyerror-e2l28) | Unique key error | -| E2A29 | [KCLAttributeComplieError](#1215-kclattributecomplieerror-e2a29) | Attribute error occurs during compiling | -| E2D32 | [MultiInheritError](#1216-multiinheriterror-e2d32) | Multiple inheritance is illegal | -| E2D34 | [IllegalInheritError](#1217-illegalinheriterror-e2d34) | Illegal inheritance | -| E2I36 | [IllegalArgumentComplieError](#1218-illegalargumentcomplieerror-e2i36) | Illegal argument during compiling | -| E3L41 | [ImmutableCompileError](#1219-immutablecompileerror-e3l41) | Immutable variable is modified | - -### 1.2.1 CannotFindModule [E2F04] - -如果在运行 KCL 时遇到错误: - -- `CannotFindModule`, 对应的 encode 为 `E2F04` - -那么此时 KCL 程序中出现了 - -- 无法找到导入模块错误 - -可能出现错误的 KCL 程序片段如下: - -```python -import .some0.pkg1 as some00 # some0 not found in package - -Name1 = some00.Name # some0.pkg1.name -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2F04]: CannotFindModule - --> import_abs_fail_0/app-main/main.k:1:1 - | -1 | import .some0.pkg1 as some00 # some0 not found in package - | Cannot find the module .some0.pkg1 - | -``` - -可以尝试以下步骤来修复这个错误: - -- 在 import 路径下添加导入模块文件。 - -### 1.2.2 FailedLoadModule [E2F05] - -如果在运行 KCL 时遇到错误: - -- `FailedLoadModule`, 对应的 encode 为 `E2F05` - -那么此时 KCL 程序中出现了 - -- 导入模块加载错误 - -可以尝试以下步骤来修复这个错误: - -- 查看文件是否可读 -- 查看文件是否为 kcl 文件 - -### 1.2.3 UnKnownDecoratorError - -如果在运行 KCL 时遇到错误: - -- `UnKnownDecoratorError`, 对应的 encode 为 `E2H13` - -那么此时 KCL 程序中出现了 - -- 未知的装饰器错误 - -可能出现错误的 KCL 程序片段如下: - -```python -@err_deprecated # 这是一个非法的装饰器 -schema Person: - firstName: str = "John" - lastName: str - name: str - -JohnDoe = Person { - name: "deprecated" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> deprecated/unknown_fail_1/main.k:1:2 - | -1 | @err_deprecated # 这是一个非法的装饰器 - | ^ UnKnown decorator err_deprecated - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查装饰器是否存在。 - -### 1.2.4 InvalidDecoratorTargetError [E2H14] - -如果在运行 KCL 时遇到错误: - -- `InvalidDecoratorTargetError`, 对应的 encode 为 `E2H14` - -那么此时 KCL 程序中出现了 - -- 无效的装饰器目标错误。 - -可以尝试以下步骤来修复这个错误: - -- 检查使用装饰器的 KCL 代码是否出现异常。 - -### 1.2.5 MixinNamingError [E2C15] - -如果在运行 KCL 时遇到错误: - -- `MixinNamingError`, 对应的 encode 为 `E2C15` - -那么此时 KCL 程序中出现了 - -- Mixin 命名错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - firstName: str - lastName: str - fullName: str - -schema Fullname: # Mixin的名称应该以Mixin结尾 - fullName = "{} {}".format(firstName, lastName) - -schema Scholar(Person): - mixin [Fullname] - school: str - -JohnDoe = Scholar { - "firstName": "John", - "lastName": "Doe", - "fullName": "Doe Jon" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2D34]: IllegalInheritError - --> mixin/invalid_name_failure/main.k:10:12 - | -10 | mixin [Fullname] - | ^ illegal schema mixin object type 'Fullname' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 如果 schema 是一个 mixin,那么这个 schema 的名称应该以 Mixin 结尾。 - -### 1.2.6 MixinStructureIllegal [E2C16] - -如果在运行 KCL 时遇到错误: - -- `MixinStructureIllegal`, 对应的 encode 为 `E2C16` - -那么此时 KCL 程序中出现了 - -- Mixin 结构错误。 - -可以尝试以下步骤来修复这个错误: - -- 检查作为 Mixin 的 Schema 的结构。 - -### 1.2.7 CannotAddMembersComplieError [E2B17] - -如果在运行 KCL 时遇到错误: - -- `CannotAddMembersComplieError`, 对应的 encode 为 `E2B17` - -那么此时 KCL 程序中出现了 - -- 使用 Schema 中不存在的成员。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Girl: - gender: str = "female" - -alice = Girl { - "first": "alice", # Schema中没有成员“first” - "last": " Green", # Schema中没有成员“last” - "age": 10 # Schema中没有成员“age” -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:5:5 - | -5 | "first": "alice", - | ^ Cannot add member 'first' to schema 'Girl' - | - -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:6:5 - | -6 | "last": " Green", - | ^ Cannot add member 'last' to schema 'Girl' - | - -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:7:5 - | -7 | "age": 10 - | ^ Cannot add member 'age' to schema 'Girl' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 为 Schema 添加缺少的成员。 -- 不要使用 Schema 中不存在的成员。 - -### 1.2.8 IndexSignatureError [E2B20] - -如果在运行 KCL 时遇到错误: - -- `IndexSignatureError`, 对应的 encode 为 `E2B20` - -那么此时 KCL 程序中出现了 - -1. 在一个 schema 中使用多个索引签名。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Data: - [str]: str - [str]: int # 在同一个schema中使用了多个索引签名 - -data = Data { - name: "test" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError ----> index_signature/fail_1/main.k:3:5 - | -3 | [str]: int - | 5 ^ only one index signature is allowed in the schema - | -``` - -可以尝试以下步骤来修复这个错误: - -- 删除多余的索引签名。 - -2. schema 中索引签名的名称与 schema 中其他属性的名称存在同名冲突。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Data: - name: str # name - [name: str]: str # 已有名称为name的schema属性 - -data = Data { - name: "test" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: IndexSignatureError - --> index_signature/fail_2/main.k:3:5 - | -3 | [name: str]: str # the same name with the above attribute - | ^ index signature attribute name 'name' cannot have the same name as schema attributes - | -``` - -可以尝试以下步骤来修复这个错误: - -- 删除 schema 中出现同名冲突的属性或者索引签名,或者为它们更换不同的名称。 - -3. schema 索引签名的类型与 schema 实例化的属性类型冲突。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Data: - [str]: int - -data = Data { - name: "test" # 索引签名为 [str]:int, "test"的类型不是int. -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> index_signature/fail_3/main.k:5:5 - | -5 | name: "test" # Conflict with [str]:int, "test" is a string. - | ^ expected int, got str(test) - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 schema 索引签名的类型与 schema 实例中的属性类型是否一致。 - -4. Schema 中的属性与索引签名冲突 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Data: - count: int # int 和 str 冲突 - [str]: str - -data = Data { - count: 1 -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: IndexSignatureError - --> index_signature/fail_4/main.k:2:5 - | -2 | count: int - | ^ the type 'int' of schema attribute 'count' does not meet the index signature definition [str]: str - | -``` - -可以尝试以下步骤来修复这个错误: - -- 调整 Schema 属性或者调整索引签名。 - -### 1.2.9 TypeComplieError [E2G22] - -如果在运行 KCL 时遇到错误: - -- `TypeComplieError`, 对应的 encode 为 `E2G22` - -那么此时 KCL 程序中出现了 - -- 静态类型检查错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - firstName: str - lastName: int - -JohnDoe = Person { - "firstName": "John", - "lastName": "Doe" # Schema中定义lastName: int -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> type/type_fail_0/main.k:7:5 - | -7 | "lastName": "Doe" # Type Error,lastName: int,“Doe” is a string. - | ^ expected int, got str(Doe) - | - - --> type/type_fail_0/main.k:3:5 - | -3 | lastName: int - | ^ variable is defined here, its type is int, but got str(Doe) - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查赋给某个变量的值的类型与这个变量的类型是否一致。 - -### 1.2.10 CompileError [E2L23] - -如果在运行 KCL 时遇到错误: - -- `CompileError`, 对应的 encode 为 `E2L23` - -那么此时 KCL 程序中出现了 - -1. 不支持的类型合并 - -可能出现错误的 KCL 程序片段如下: - -```python -_data = [1, 2, 3] -_data |= "value" -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> union/fail/fail_1/main.k:2:1 - | -2 | _data |= "value" - | ^ unsupported operand type(s) for |: '[int]' and 'str(value)' - | -``` - -1. 不支持的操作符类型 - -可能出现错误的 KCL 程序片段如下: - -```python -a = None -b = 1 + None # KCL中不支持None和int之间进行+操作 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> operator/operator_fail_0/main.k:2:5 - | -2 | b = 1 + None # Unsupport operand type + for int and None - | ^ unsupported operand type(s) for +: 'int(1)' and 'NoneType' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 调整操作符号,使其同时支持两个操作数的类型。 -- 调整操作数,使其同时符合操作符号的约束。 - -1. 没有定义的变量 - -可能出现错误的 KCL 程序片段如下: - -```python -a = 1 -b = "${c + 1}" # 'c' 没有定义 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> var_not_define_fail_0/main.k:2:8 - | -2 | b = "${c + 1}" # 'c' is not defined - | ^ name 'c' is not defined - | -``` - -可以尝试以下步骤来修复这个错误: - -- 对未定义的变量进行定义。 -- 在表达式中去掉对未定义变量的操作。 - -4. 无效的赋值表达式 - -可能出现错误的 KCL 程序片段如下: - -```python -# pkg.k -a = 1 - -# main.k -import pkg -pkg.a |= 2 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> pkg_inplace_modify_1/main.k:3:1 - | -6 | pkg |= 2 - | ^ unsupported operand type(s) for |: 'module 'pkg'' and 'int(2)' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查赋值表达式的内容。 - -1. 无效的字符串表达式 - -可能出现错误的 KCL 程序片段如下: - -```python -a = 1 -b = "${b = a + 1}" # Invalid string interpolation expression -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> invalid_format_value_fail_0/main.k:2:5 - | -2 | b = "${b = a + 1}" - | 5 ^ invalid string interpolation expression 'b = a + 1' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查字符串表达式的内容。 - -1. 无效的循环变量 - -可能出现错误的 KCL 程序片段如下: - -```python -data = {"key1": "value1", "key2": "value2"} -dataLoop = [i for i, j, k in data] # the number of loop variables can only be 1 or 2 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> dict/invalid_loop_var_fail_0/main.k:2:25 - | -2 | dataLoop = [i for i, j, k in data] # the number of loop variables can only be 1 or 2 - | ^ the number of loop variables is 3, which can only be 1 or 2 - | -``` - -### 1.2.11 KCLNameError [E2L25] - -如果在运行 KCL 时遇到错误: - -- `KCLNameError`, 对应的 encode 为 `E2L25` - -那么此时 KCL 程序中出现了 - -- 试图访问的变量名不存在 - -可以尝试以下步骤来修复这个错误: - -- 检查报错信息中出现的变量是否存在。 - -### 1.2.12 KCLValueError [E2L26] - -如果在运行 KCL 时遇到错误: - -- `KCLValueError`, 对应的 encode 为 `E2L26` - -那么此时 KCL 程序中出现了 - -- 值错误,传给参数的类型不正确 - -可以尝试以下步骤来修复这个错误: - -- 检查参数的具体类型。 - -### 1.2.13 KCLKeyError [E2L27] - -如果在运行 KCL 时遇到错误: - -- `KCLKeyError`, 对应的 encode 为 `E2L27` - -那么此时 KCL 程序中出现了 - -- 使用了 dict 中不存在的 key 时引发的 key 错误 - -可以尝试以下步骤来修复这个错误: - -- 检查字典中是否存在 key。 - -### 1.2.14 UniqueKeyError [E2L28] - -如果在运行 KCL 时遇到错误: - -- `UniqueKeyError`, 对应的 encode 为 `E2L28` - -那么此时 KCL 程序中出现了 - -- 变量同名或重复定义。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - name: str = "kcl" - age: int = 1 - -schema Person: - aa: int - -x0 = Person{} -x1 = Person{age:101} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L28]: UniqueKeyError - --> /schema/same_name/main.k:5:8 - | -5 | schema Person: - | ^ Unique key error name 'Person' - | - - --> /schema/same_name/main.k:1:8 - | -1 | schema Person: - | ^ The variable 'Person' is declared here - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查出现错误的名称是否已经被使用。 - -### 1.2.15 KCLAttributeComplieError [E2A29] - -如果在运行 KCL 时遇到错误: - -- `KCLAttributeComplieError`, 对应的 encode 为 `E2A29` - -那么此时 KCL 程序中出现了 - -- Schema 的属性错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -# pkg -schema A: - field_A: str - -# main -import pkg as p - -a = p.D + 1 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> /import/module/no_module_attr_fail_0/main.k:4:5 - | -4 | a = p.D + 1 - | ^ module 'pkg' has no attribute D - | -``` - -可以尝试以下步骤来修复这个错误: - -- 在使用 Schema 属性时检查这个属性是否存在。 - -### 1.2.16 MultiInheritError [E2D32] - -如果在运行 KCL 时遇到错误: - -- `MultiInheritError`, 对应的 encode 为 `E2D32` - -那么此时 KCL 程序中出现了 - -- 多继承错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - firstName: str - lastName: str - -schema KnowledgeMixin: - firstName: int - subject: str - -schema Scholar(KnowledgeMixin, Person): # KCL中不支持多继承 - school: str -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> /schema/inherit/multi_inherit_fail_1/main.k:9:30 - | -9 | schema Scholar(KnowledgeMixin, Person): - | ^ expected one of [")"] got , - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查程序的继承结构,KCL 中不支持多继承。 - -### 1.2.17 IllegalInheritError [E2D34] - -如果在运行 KCL 时遇到错误: - -- `IllegalInheritError`, 对应的 encode 为 `E2D34` - -那么此时 KCL 程序中出现了 - -- 不合法的继承结构 - -可能出现错误的 KCL 程序片段如下: - -```python -schema FullnameMixin: - fullName = "{} {}".format(firstName, lastName) - -schema Scholar(FullnameMixin): # KCL中不支持Schema继承Mixin - school: str -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError -Invalid value for top level arguments -``` - -可以尝试以下步骤来修复这个错误: - -- KCL 中 Schema 支持单继承 Schema。 - -### 1.2.18 IllegalArgumentComplieError [E2I36] - -如果在运行 KCL 时遇到错误: - -- `IllegalArgumentComplieError`, 对应的 encode 为 `E2I36` - -那么此时 KCL 程序中出现了 - -- 参数错误 - -可能出现错误的 KCL 程序片段如下: - -```python -a = option("key") - -# kcl main.k -D key=value= -# key=value= is an illegal expression -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError -Invalid value for top level arguments -``` - -可以尝试以下步骤来修复这个错误: - -- 检查通过命令设置的 KCL option 参数是否为合法参数。 - -### 1.2.19 ImmutableCompileError [E3L41] - -如果在运行 KCL 时遇到错误: - -- `ImmutableCompileError`, 对应的 encode 为 `E3L41` - -那么此时 KCL 程序中出现了 - -- 不可变量的值发生改变 - -可能出现错误的 KCL 程序片段如下: - -```python -a = 2147483646 -a += 1 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: ImmutableError - --> augment_assign/main.k:2:1 - | -2 | a += 1 - | ^ Immutable variable 'a' is modified during compiling - | - - --> augment_assign/main.k:1:1 - | -1 | a = 2147483646 - | ^ The variable 'a' is declared here firstly - | -note: change the variable name to '_a' to make it mutable -``` - -可以尝试以下步骤来修复这个错误: - -- 将被改变的不可变量设置为私有或者去掉对不可变量值的改动。 - -## 1.3 KCL 运行时错误 (E3xxx) - -KCL 会出现的运行时错误信息如下表所示: - -| ewcode | KCL exception | messages | -| ------ | ----------------------------------------------------------------------- | --------------------------------------------------- | -| E3F06 | [RecursiveLoad](#131-recursiveload-e3f06) | Recursively loading module | -| E3K04 | [FloatOverflow](#132-floatoverflow-e3k04) | Float overflow | -| E3K09 | [IntOverflow](#133-intoverflow-e3k09) | Integer overflow | -| E3N11 | [DeprecatedError](#134-deprecatederror-e3n11) | Deprecated error | -| E3A30 | [KCLAttributeRuntimeError](#135-kclattributeruntimeerror-e3a30) | Attribute error occurs at runtime | -| E3G21 | [TypeRuntimeError](#136-typeruntimeerror-e3g21) | The type got is inconsistent with the type expected | -| E3B17 | [SchemaCheckFailure](#137-schemacheckfailure-e3b17) | Schema check is failed to check condition | -| E3B19 | [CannotAddMembersRuntimeError](#138-cannotaddmembersruntimeerror-e3b19) | Cannot add members to a schema | -| E3M38 | [EvaluationError](#139-evaluationerror-e3m38) | Evaluation failure | -| E3M39 | [InvalidFormatSpec](#1310-invalidformatspec-e3m39) | Invalid format specification | -| E3M40 | [KCLAssertionError](#1311-kclassertionerror-e3m40) | Assertion failure | -| E3M44 | [ImmutableRuntimeError](#1312-immutableruntimeerror-e3m44) | Immutable variable is modified | -| E2D33 | [CycleInheritError](#1313-cycleinheriterror-e2d33) | Cycle Inheritance is illegal | -| E3M42 | [KCLRecursionError](#1314-kclrecursionerror-e3m42) | Recursively reference | - -### 1.3.1 RecursiveLoad [E3F06] - -如果在运行 KCL 时遇到错误: - -- `RecursiveLoad`, 对应的 encode 为 `E3F06` - -那么此时 KCL 程序中出现了 - -- 循环导入错误 - -可能出现错误的 KCL 程序片段如下: - -``` -# module.k -import main # module.k 导入了 main.k - -print('module') - -# main.k -import module # main.k 导入了 module.k - -print('main') -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /import/recursive_import_fail/main.k:4 - | -2 | import module # main.k imports module.k - | ^ There is a circular import reference between module main and module - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查包的导入部分是否存在循环导入的问题。 - -### 1.3.2 FloatOverflow [E3K04] - -如果在运行 KCL 时遇到错误: - -- `FloatOverflow`, 对应的 encode 为 `E3K04` - -那么此时 KCL 程序中出现了 - -- 浮点数溢出 - -可能出现错误的 KCL 程序片段如下: - -```python -uplimit = 3.402823466e+39 -epsilon = 2.220446049250313e-16 -a = uplimit * (1 + epsilon) - -# kcl main.k -r -d -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /range_check_float/overflow/number_0/main.k:3:1 - | -3 | a = uplimit * (1 + epsilon) - | 3.4028234660000003e+39: A 32-bit floating point number overflow - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查浮点数的值是否在 KCL 支持的数字范围内。 - -### 1.3.3 IntOverflow [E3K09] - -如果在运行 KCL 时遇到错误: - -- `IntOverflow`, 对应的 encode 为 `E3K09` - -那么此时 KCL 程序中出现了 - -- 整数溢出 - -可能出现错误的 KCL 程序片段如下: - -```python -_a = 9223372036854775807 -_a += 1 - -# kcl test.k -d -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /range_check_int/augment_assign_fail_1/main.k:2:1 - | -2 | _a += 1 - | 9223372036854775808: A 64 bit integer overflow - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查整数的值是否在 KCL 支持的数字范围内。 - -### 1.3.4 DeprecatedError [E3N11] - -如果在运行 KCL 时遇到错误: - -- `DeprecatedError`, 对应的 encode 为 `E3N11` - -那么此时 KCL 程序中出现了 - -- 使用废弃代码 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - firstName: str = "John" - lastName: str - @deprecated(version="1.16", reason="use firstName and lastName instead", strict=True) - name: str - -JohnDoe = Person { - name: "deprecated" # name已经被过时,并且strict设置为True -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /range_check_float/overflow/number_0/main.k:7:1 - | -7 | JohnDoe = Person { - | name was deprecated since version 1.16, use firstName and lastName instead - | -``` - -可以尝试以下步骤来修复这个错误: - -- strict 设置为 True 时无法使用过时的代码,可以将 strict 设置为 False,将不会出现错误,而是输出一个警告。 -- 调整代码,不使用已经过时的代码。 - -### 1.3.5 KCLAttributeRuntimeError [E3A30] - -如果在运行 KCL 时遇到错误: - -- `KCLAttributeRuntimeError`, 对应的 encode 为 `E3A30` - -那么此时 KCL 程序中出现了 - -- 属性错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -import math - -a = math.err_func(1) # err_func is not found in math -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /import/module/no_module_attr_fail_2/main.k:3:5 - | -3 | a = math.err_func(1) # err_func is not found in math - | ^ module 'math' has no attribute err_func - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查属性调用是否正确。 - -### 1.3.6 TypeRuntimeError [E3G21] - -如果在运行 KCL 时遇到错误: - -- `TypeRuntimeError`, 对应的 encode 为 `E3G21` - -那么此时 KCL 程序中出现了 - -- 类型检查错误 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - name: str = "Alice" - -_personA = Person {} -_personA |= {"name" = 123.0} # name: str = "Alice" -personA = _personA -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /fail/fail_4/main.k:2:1 - | -2 | name: str = "Alice" - | expect str, got float - | -``` - -可以尝试以下步骤来修复这个错误: - -- 停止错误的类型合并或者将类型调整为 KCL 支持的类型合并。 - -### 1.3.7 SchemaCheckFailure [E3B17] - -如果在运行 KCL 时遇到错误: - -- `SchemaCheckFailure`, 对应的 encode 为 `E3B17` - -那么此时 KCL 程序中出现了 - -- Schema 中的 check 条件冲突 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - lastName: str - age: int - check: - age < 140, "age is too large" - -JohnDoe = Person { - "lastName": "Doe", - "age": 1000 # Schema中的check条件为: age < 140 -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /check_block/check_block_fail_1/main.k:7:11 - | -7 | JohnDoe = Person { - | ^ Instance check failed - | - - --> /check_block/check_block_fail_1/main.k:5:1 - | -5 | age < 140, "age is too large" - | Check failed on the condition - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 Schema 的属性与 check 中的条件是否符合 - -### 1.3.8 CannotAddMembersRuntimeError [E3B19] - -如果在运行 KCL 时遇到错误: - -- `CannotAddMembersRuntimeError`, 对应的 encode 为 `E3B19` - -那么此时 KCL 程序中出现了 - -- 访问 Schema 中不存在的成员 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Name: - name: str - -schema Person: - name: Name - -person = Person { - name.err_name: "Alice" # err_name is not found in schema Name -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /nest_var/nest_var_fail_1/main.k:8:5 - | -8 | name.err_name: "Alice" # err_name is not found in schema Name - | ^ Cannot add member 'err_name' to schema 'Name' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 为 Schema 添加不存在的成员。 -- 访问 Schema 中存在的成员。 - -### 1.3.9 EvaluationError [E3M38] - -如果在运行 KCL 时遇到错误: - -- `EvaluationError`, 对应的 encode 为 `E3M38` - -那么此时 KCL 程序中出现了 - -- 当 KCL 中数值计算过程出现了错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -_list1 = [1, 2, 3] # _list1 is a variable, and its type can only be known at runtime -_list2 = None # _list1 is a variable, and its type can only be known at runtime - -result2 = _list1 + _list2 # list + NoneType is illegal -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /datatype/list/add_None_fail/main.k:1 - | -4 | result2 = _list1 + _list2 # list + NoneType is illegal - | can only concatenate list (not "NoneType") to list - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查表达式中是否存在变量为 None,或者非法的计算过程。 - -### 1.3.10 InvalidFormatSpec [E3M39] - -如果在运行 KCL 时遇到错误: - -- `InvalidFormatSpec`, 对应的 encode 为 `E3M39` - -那么此时 KCL 程序中出现了 - -- 非法的字符串格式 - -可能出现错误的 KCL 程序片段如下: - -```python -a = 1 -b = 1 -data = "${a: #js}" + " $$ " # KCL插值字符串中,#js是非法的 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /datatype/str_interpolation/invalid_format_spec_fail_0/main.k:3 - | -3 | data = "${a: #js}" + " $$ " # #js is illegal string - | ^ #js is a invalid format spec - | -``` - -可以尝试以下步骤来修复这个错误: - -- 将非法 String 调整为 KCL 标准支持的 String。 - -### 1.3.11 KCLAssertionError [E3M40] - -如果在运行 KCL 时遇到错误: - -- `KCLAssertionError`, 对应的 encode 为 `E3M40` - -那么此时 KCL 程序中出现了 - -- Assert False - -可能出现错误的 KCL 程序片段如下: - -```python -assert False -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /assert/invalid/fail_0/main.k:1 - | -1 | assert False - | - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 Assert 的条件,Assert 条件为 False 时,就会出现此类错误,去掉 Assert 语句或改变条件为 True。 - -### 1.3.12 ImmutableRuntimeError [E3M44] - -如果在运行 KCL 时遇到错误: - -- `ImmutableRuntimeError`, 对应的 encode 为 `E3M44` - -那么此时 KCL 程序中出现了 - -- 不可变量的值发生改变 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - final firstName : str - lastName : str - - -schema Scholar(Person): - firstName = "CBA" - - -scholar = Scholar { - "firstName": "ABC" # firstName in schema Person is final. -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /final/fail_lazy_init_0/main.k:8:1 - | -8 | scholar = Scholar { - | attribute 'lastName' of Scholar is required and can't be None or Undefined - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 final 修饰的不可变量是否出现了赋值等改变值的操作。 - -### 1.3.13 CycleInheritError [E2D33] - -如果在运行 KCL 时遇到错误: - -- `CycleInheritError`, 对应的 encode 为 `E2D33` - -那么此时 KCL 程序中出现了 - -- 循环继承 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Parent(Son): - parent_field: str - -schema Son(GrandSon): - son_field: str - -schema GrandSon(Parent): - grandson_field: str - -parent = Parent { - parent_field: "" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /inherit/cycle_inherit_fail_1/main.k:7:8 - | -7 | schema GrandSon(Parent): - | ^ There is a circular reference between schema GrandSon and Parent - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 Schema 的继承关系,避免出现 A 继承 B,B 继承 A 的情况。 - -### 1.3.14 KCLRecursionError [E3M42] - -如果在运行 KCL 时遇到错误: - -- `KCLRecursionError`, 对应的 encode 为 `E3M42` - -那么此时 KCL 程序中出现了 - -- 循环引用 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Parent(Son): - parent_field: str - son: Son = Son { # Parent has attribute Son - parent: Parent { - parent_field: "123" - } - } - -schema Son: - son_field: str - parent: Parent = Parent { # Son has attribute Parent - son: Son { - son_field: "123" - } - } - -parent = Parent { - parent_field: "", -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -thread 'main' has overflowed its stack -fatal runtime error: stack overflow -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 Schema 中的属性成员,避免出现循环引用的问题。 - -## 1.4 KCL 编译警告 (W2xxx) - -KCL 中的编译警告如下表所示: - -| ewcode | KCL exception | messages | -| ------ | ------------------------------------------------- | ------------------ | -| W2K04 | [FloatUnderflow](#141-floatunderflow-w2k08) | Float underflow | -| W2P10 | [InvalidDocstring](#142-invaliddocstring-w2p10) | Invalid docstring | -| W2N12 | [DeprecatedWarning](#143-deprecatedwarning-w2n12) | Deprecated warning | - -### 1.4.1 FloatUnderflow [W2K08] - -如果在运行 KCL 时遇到错误: - -- `FloatUnderflow`, 对应的 encode 为 `W2K08` - -可以尝试以下步骤来修复这个错误: - -- 检查浮点数的值是否在 KCL 支持的数字范围内。 - -### 1.4.2 InvalidDocstring [W2P10] - -如果在运行 KCL 时遇到错误: - -- `InvalidDocstring`, 对应的 encode 为 `W2P10` - -那么此时 KCL 程序中出现了 - -- 无效的 doc 内容 - -可以尝试以下步骤来修复这个错误: - -- 请按照 KCL 标准编写 doc。 - -### 1.4.3 DeprecatedWarning [W2N12] - -如果在运行 KCL 时遇到错误: - -- `DeprecatedWarning`, 对应的 encode 为 `W2N12` - -那么此时 KCL 程序中出现了 - -- 过时的代码警告 - -可以尝试以下步骤来修复这个错误: - -- 尽量不要使用已经过时的代码。如果将 strict 设置为 True,KCL 将会输出错误,并停止运行。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/tour.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/tour.md deleted file mode 100644 index 1de64a32..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/tour.md +++ /dev/null @@ -1,3201 +0,0 @@ ---- -title: "KCL 之旅" -sidebar_position: 1 ---- - -本文展示了如何使用 KCL 的核心特性,包含变量、运算符、schema 和库,前提是您有使用其他语言编程的经验。KCL 主要受 Python 启发,了解 Python 对学习 KCL 非常有帮助。 - -### 重要概念 - -在学习 KCL 语言时,请牢记以下事实和概念: - -- KCL 是一种配置策略语言。它为编写配置和策略提供了简单且自洽的语言设计和库支持。它不能用于应用程序开发或其他通用编程语言(GPL)支持的场景。 -- KCL 吸收了经典 **OOP** 的元素,并且提供了**类型**、**复用**和**合并**等简单、开发人员友好、可靠且利于传播的配置编写实践。 -- KCL 更倾向于**不可变性**,建议使用**合并**来添加增量的变更。不可变性降低了副作用,例如不可预测的问题。 -- KCL 的 **schema** 结构体定义了严格的属性和静态类型,并且支持表达式验证。**schema** 结构体主要由带类型的属性、schema 上下文和检查块构成。 -- KCL 的 **config** 是一个类 **JSON** 表达式,通过它我们可以复用 schema 的完整定义。KCL 通过分离 schema 和 config 来提供定义和配置的能力。 -- KCL 的 **rule** 是一个书写规则约束表达式的结构,可用于数据校验和策略编写。 -- KCL 的代码文件以包(目录)和模块(文件)的形式进行管理。同一包中的 schema 彼此可见;跨包的数据需要通过 **import 语句**导入。包级变量虽然可以导出,但是它们不能被其他包修改。 -- KCL 语法定义主要使用声明式表达式,并且只提供少量必要的声明式语句,例如 import、 if...else、assert、assignment 以及 schema。 -- 没有主函数,每个 `.k` 文件可以作为单独的配置文件执行。 -- 支持**内置函数**和**插件**以简化编写。 - -### 关键字 - -下表列出了 KCL 语言的关键字。 - -```txt -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -### 标识符 - -在 KCL 中, 标识符是标识一个值的名称,可以带有选择器。 - -- 标识符由字母、数字、下划线或前缀 `$` 组成。 -- 标识符不能与关键字重复,除非它们有 `$` 前缀。 -- 标识符不得包含任何嵌入的空格或符号。 -- 可以在标识符中的任何位置使用字母和下划线。 -- 数字不能放在标识符的第一位。 -- `$` 字符只能放在标识符的第一个位置。 - -示例: - -```python -x -a -b1 -b_2 -_c -$if -``` - -为了简化限定标识符(例如 `pkg.type`)的定义,我们还定义了 `qualified identifier`: - -示例: - -```python -pkg.a -``` - -在 `qualified identifier` 中的包名必须通过 `import` 关键字导入。 - -#### 标识符前缀 - -使用 `$` 前缀符号定义关键字标识符。 - -```python -$if = 1 -$else = "s" -``` - -请注意,非关键字标识符是否有 `$` 符号都是同样的效果。 - -```python -_a = 1 -$_a = 2 # equal to `_a = 2` -``` - -### 变量 - -以下是如何创建并实例化变量的例子: - -```python -name = "Foo" # Declare a variable named `name` and its value is a string literal "Foo" -``` - -它对应了如下 YAML 输出: - -```yaml -name: Foo -``` - -在 KCL 中,我们可以通过定义包级变量将变量导出为配置数据。使其直接、清晰、可维护。导出的变量是不可变的。因此一旦声明它,就无法对其进行修改,例如,假设我们有一个名为 `example.k` 的配置文件,变量 `name` 在声明后就禁止修改,就像标准的命令式语言一样。 - -```python -name = "Foo" # exported - -... - -name = "Bar" # error: a exported declaration variable can only be set once. -``` - -作为补充,我们可以在模块级别定义一个非导出变量,这个变量是可变的,不会显示在 YAML 输出当中。 - -```python -_name = "Foo" # _ variables are not output to YAML and are mutable -_name = "Bar" -``` - -请注意,变量的名称不能为 `True`、`False`、`None` 或者 `Undefined`,因为它们与 KCL 内置的名称常量之间存在二义性。 - -```python -False = 1 # Error -True = False # Error -None = Undefined # Error -Undefined = None # Error -``` - -### 内置类型 - -KCL 支持以下类型: - -- 数字 -- 字符串 -- 布尔 -- 列表 -- 字典 - -#### 数字 - -KCL 的数字类型有两种形式: - -- 64 位有符号整数。值的范围为 -9223372036854775808~9223372036854775807. -- 64 位浮点数,遵循 IEEE 754 标准。我们不建议在配置中使用 float 类型,我们可以使用字符串代替并在运行时进行解析。 - -整数和浮点数都支持基本运算符,例如 `+`,`-`,`/` 和 `*`,而复杂的运算,例如 `abs()`, `ceil()` 和 `floor()`,都是通过内置的数学库来支持。 - -整数是不带小数点的数字。以下是一些定义整数的例子: - -```python -a = 1 -b = -1 -c = 0x10 # hexadecimal literal -d = 0o10 # octal literal -e = 010 # octal literal -f = 0b10 # binary literal -g = int("10") # int constructor -``` - -如果一个数字包含小数点,则它是浮点数。以下是一些浮点数的示例: - -```python -a = 1.10 -b = 1.0 -c = -35.59 -d = 32.3e+18 -f = -90. -h = 70.2E-12 -i = float("112") # float constructor -``` - -内置数学库可用于数字类型: - -```python -import math - -assert abs(-40) == 40 -assert round(70.23456) == 70 -assert min(80, 100, 1000) == 80 -assert max(80, 100, 1000) == 1000 -assert sum([0,1,2]) == 3 -assert math.ceil(100.12) == 101.0 -assert math.floor(100.12) == 100.0 -assert math.pow(100, 2) == 10000.0 -``` - -KCL 默认使用 64 位数字类型。我们可以在 KCL 命令行使用 `-r` 参数执行严格的 32 位范围检查。 - -```bash -kcl main.k -r -d -``` - -请注意,为了性能考虑该功能只能在 `debug` 模式中使用。 - -##### 单位字面值 - -在 KCL 中,我们可以给一个整数添加如下的单位后缀,这不影响它的真实值。 - -- 通用整形和定点数: `P`, `T`, `G`, `M`, `K`, `k`, `m`, `u`, `n` -- 2 的幂: `Pi`, `Ti`, `Gi`, `Mi`, `Ki` - -```python -# SI -n = 1n # 1e-09 -u = 1u # 1e-06 -m = 1m # 1e-03 -k = 1k # 1000 -K = 1K # 1000 -M = 1M # 1000000 -G = 1G # 1000000000 -T = 1T # 100000000000 -P = 1P # 1000000000000000 -# IEC -Ki = 1Ki # 1024 -Mi = 1Mi # 1024 ** 2 -Gi = 1Gi # 1024 ** 3 -Ti = 1Ti # 1024 ** 4 -Pi = 1Pi # 1024 ** 5 -``` - -此外,我们还可以使用定义在 `units` 模块中的单位常量: - -```python -import units - -n = 1 * units.n # 1e-09 -u = 1 * units.u # 1e-06 -m = 1 * units.m # 1e-03 -k = 1 * units.k # 1000 -K = 1 * units.K # 1000 -M = 1 * units.M # 1000000 -G = 1 * units.G # 1000000000 -T = 1 * units.T # 1000000000000 -P = 1 * units.P # 1000000000000000 -# IEC -Ki = 1 * units.Ki # 1024 -Mi = 1 * units.Mi # 1024 ** 2 -Gi = 1 * units.Gi # 1024 ** 3 -Ti = 1 * units.Ti # 1024 ** 4 -Pi = 1 * units.Pi # 1024 ** 5 -``` - -我们还可以使用定义在 `units` 模块内的整数和单位字符串之间的转换函数 - -```python -import units -# SI -K = units.to_K(1000) # "1K" -M = units.to_M(1000000) # "1M" -G = units.to_G(1000000000) # "1G" -T = units.to_T(1000000000000) # "1T" -P = units.to_P(1000000000000000) # "1P" -# IEC -Ki = units.to_Ki(1024) # "1Ki" -Mi = units.to_Mi(1024 ** 2) # "1Mi" -Gi = units.to_Gi(1024 ** 3) # "1Gi" -Ti = units.to_Ti(1024 ** 4) # "1Ti" -Pi = units.to_Pi(1024 ** 5) # "1Pi" -``` - -```python -import units -# SI -K = units.to_K(int("1M")) # "1000K" -M = units.to_M(int("1G")) # "1000M" -G = units.to_G(int("1T")) # "1000G" -T = units.to_T(int("1P")) # "1000T" -P = units.to_P(int("10P")) # "10P" -# IEC -Ki = units.to_Ki(int("1Mi")) # "1024Ki" -Mi = units.to_Mi(int("1Gi")) # "1024Mi" -Gi = units.to_Gi(int("1Ti")) # "1024Gi" -Ti = units.to_Ti(int("1Pi")) # "1024Ti" -Pi = units.to_Pi(int("10Pi")) # "10Pi" -``` - -单位类型定义在 `units` 模块中,单位类型的值不能进行任何四则运算。 - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -x0: NumberMultiplier = 1M # Ok -x1: NumberMultiplier = x0 # Ok -x2 = x0 + x1 # Error: unsupported operand type(s) for +: 'number_multiplier(1M)' and 'number_multiplier(1M)' -``` - -我们可以使用 `int()`、`float()` 和 `str()` 函数将数值单位类型转换为数字类型或字符串类型。 - -```python -a: int = int(1Ki) # 1024 -b: float = float(1Ki) # 1024.0 -c: str = str(1Mi) # "1Mi" -``` - -#### 字符串 - -字符串是一个不可变的 Unicode 字符序列。我们可以使用单引号或双引号创建字符串: - -```python -'allows embedded "double" quotes' # Single quotes -"allows embedded 'single' quotes" # Double quotes -'''Three single quotes''', """Three double quotes""" # Triple quoted -``` - -三引号用于定义多行字符串。 - -```python -"""This is a long triple quoted string -may span multiple lines. -""" -``` - -请注意,KCL 的单引号和双引号字符串的使用几乎没有区别。唯一可以简化的是,我们不需要在单引号字符串中转义双引号,也不需要在双引号中转义单引号。 - -```python -'This is my book named "foo"' # Don’t need to escape double quotes in single quoted strings. -"This is my book named 'foo'" # Don’t need to escape single quotes in double quoted strings. -``` - -我们可以使用 `+` 操作符连接字符串: - -```python -x = 'The + operator ' + 'works, as well.' -``` - -我们可以使用 `str` 内置函数将 int 或 float 转为字符串: - -```python -x = str(3.5) # "3.5" -``` - -可以使用很多内置的字符串函数: - -```python -x = "length" -assert len(x) == 6 # True -assert x.capitalize() == "Length" -assert x.count("gt") == 1 -assert x.endswith("th") == True -assert x.find("gth") == 3 -assert "{} {}".format("hello", "world") == 'hello world' -assert x.index("gth") == 3 -assert x.isalnum() == True -assert x.isalpha() == True -assert "123456".isdigit() == True -assert x.islower() == True -assert " ".isspace() == True -assert "This Is Title Example".istitle() == True -assert x.isupper() == False -assert "|".join(["a", "b", "c"]) == "a|b|c" -assert "LENGTH".lower() == "length" -assert ' spacious '.lstrip() == 'spacious ' -assert x.replace("th", "ht") == "lenght" -assert "lengthlength".rfind("le") == 6 -assert "lengthlength".rindex("le") == 6 -assert "length length".rsplit() == ["length", "length"] -assert "length ".rstrip() == "length" -assert "length length".split() == ["length", "length"] -assert 'ab c\n\nde fg\rkl\r\n'.splitlines() == ['ab c', '', 'de fg', 'kl'] -assert "length".startswith('len') == True -assert "***length***".strip('*') == "length" -assert "length length".title() == "Length Length" -assert x.upper() == "LENGTH" -``` - -格式化字符串有两种使用方法: 使用 `"{}".format()` 内置函数, 或者使用花括号指定变量并使用 `$` 标记取变量值。在 KCL 中叫做**插值字符串**。在下面的例子中,`a` 和 `b` 的值都是 `"hello world"`。 - -此外,要序列化的变量可以以特殊的数据格式提取,例如 YAML 或 JSON。在这种情况中,`#yaml` 或 `#json` 可以包含在花括号中。 - -具体来说,当 `$` 符号本身需要出现在**插值字符串**中,需要使用 `$$` 转义。或者使用 `+` 符号连接 `$` 符号和插值字符串来避免转义。在以下示例中,`c` 和 `c2` 的值都是 `$hello world$`。 - -```python -world = "world" -a = "hello {}".format(world) # "hello world" -b = "hello ${world}" # "hello world" -c = "$$hello ${world}$$" # "$hello world$" -c2 = "$" + "hello ${world}" + "$" # "$hello world$" - -myDict = { - "key1" = "value1" - "key2" = "value2" -} - -d = "here is myDict in json: ${myDict: #json}" -# d: 'here is myDict in json: {"key1": "value1", "key2": "value2"}' - -e = "here is myDict in yaml:\n${myDict: #yaml}" -# e: | -# here is myDict in yaml: -# key1: value1 -# key2: value2 -``` - -此外,我们可以在上面的示例代码输出 **YAML 字符串** 中看到一些符号,例如 `|`、`>`、`+`、`-`。 - -- `|` 表示 **块文字样式**,指示块内换行符的行为方式。 -- `>` 表示块标量中的**块折叠样式**,换行符将被空格替换。 -- `+` 和 `-` 是 **block chomping 指示符**,用于控制字符串末尾的换行符。 默认值 **clip** 在字符串的末尾放置一个换行符。 要删除所有换行符,请通过在样式指示符 `|` 或 `>` 后面添加 `-` 来**删除**它们。 clip 和 strip 都忽略块末尾实际有多少换行符; 在样式指示符后面添加一个 `+` 来**保留**它们。 - -例如,**strip 块文字样式** yaml 字符串是 - -```yaml -example: |- - Several lines of text, - with some "quotes" of various 'types', - and also a blank line: - - plus another line at the end. -``` - -结果为: - -```plain -Several lines of text, -with some "quotes" of various 'types', -and also a blank line: - -plus another line at the end. -``` - -更多信息可见 [Yaml Multiline String](https://yaml-multiline.info/) 和 [YAML Specification v1.2](https://yaml.org/spec/1.2.1/) 。 - -##### 原始字符串 - -KCL 原始字符串是通过在字符串字面值前加上 `'r'` 或 `'R'` 来创建的。 KCL 原始字符串将反斜杠 (`\`) 和字符串插值 (`${}`) 视为普通的非字符。当我们想要一个包含反斜杠、字符串插值的字符串并且不希望它们被视为转义字符时,原始字符串是很有用的。 - -- 对于包含反斜杠(`\`)的原始字符串,KCL 代码和输出 YAML 如下: - -```python -s = "Hi\nHello" -raw_s = r"Hi\nHello" # This is a KCL raw string with the `r` prefix. -``` - -```yaml -s: |- - Hi - Hello -raw_s: Hi\nHello -``` - -- 对于包含字符串插值(`${}`)的原始字符串,KCL 代码和输出 YAML 如下: - -```python -worldString = "world" -s = "Hello ${worldString}" -raw_s = r"Hello ${worldString}" # This is a KCL raw string with the `r` prefix. -``` - -```yaml -worldString: world -s: Hello world -raw_s: Hello ${worldString} -``` - -此外,原始字符串最常用的场景是在正则表达式中使用: - -```python -import regex - -key = "key" -result = regex.match(key, r"[A-Za-z0-9_.-]*") # True -``` - -#### 布尔值 - -布尔值有两个常量对象:`False` 和 `True`. - -```python -a = True -b = False -``` - -#### List - -List 是一个序列,通常用于存储同质项的集合。下面是一个简单的 KCL 列表的例子: - -```python -list = [1, 2, 3] -assert len(list) == 3 # True -assert list[0] == 1 # True -``` - -我们可以使用列表推导式构建列表: - -```python -list = [ _x for _x in range(20) if _x % 2 == 0] -assert list == [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] # True -``` - -并且还可以使用嵌套的列表推导式: - -```python -matrix = [[1, 2], [3,4], [5,6], [7,8]] -transpose = [[row[_i] for row in matrix] for _i in range(2)] -assert transpose == [[1, 3, 5, 7], [2, 4, 6, 8]] # True -``` - -此外,我们可以在列表推导式中使用两个变量。第一个变量表示列表中的索引,第二个变量表示列表中的项。 - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use `_` to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -我们可以通过 `+` 连接列表: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -joined_list = _list0 + _list1 # [1, 2, 3, 4, 5, 6] -``` - -我们可以使用解包操作符 `*` 合并多个列表: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -union_list = [*_list0, *_list1] # [1, 2, 3, 4, 5, 6] -``` - -我们可以使用 `if` 表达式动态的将元素添加到列表,符合条件的元素会被添加到列表,不符合条件的元素会被忽略。 - -```python -a = 1 # 1 -data = [ - 1 - if a == 1: 2 - if a > 0: 3 - if a < 0: 4 -] # [1, 2, 3] -``` - -```python -a = 1 # 1 -data1 = [ - 1 - if a == 1: - 2 - elif a == 2: - 3 - else: - 3 -] # [1, 2] -data2 = [ - 1 - if a == 1: 2 - elif a == 2: 2 - else: 3 -] # [1, 2] -``` - -我们可以合并(union)列表: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -union_list = _list0 | _list1 # [4, 5, 6] -``` - -我们可以使用 `for k in list_var` 表达式遍历列表: - -```python -data = [1, 2, 3] -dataAnother = [val * 2 for val in data] # [2, 4, 6] -``` - -#### Dict - -Dict 是将可哈希的值映射到任意对象的映射对象。字典是有序的。键的顺序遵循其声明的顺序: - -这里有几个简单的 KCL 字典: - -```python -a = {"one" = 1, "two" = 2, "three" = 3} -b = {'one' = 1, 'two' = 2, 'three' = 3} -assert a == b # True -assert len(a) == 3 # True -``` - -在写多行的键-值时,可以省略每个键-值对行尾的逗号 `,`: - -```python -data = { - "key1" = "value1" # Ignore the comma ',' at the end of line - "key2" = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -在 Dict 键上使用简单的字面值时可以省略引号: - -```python -data = { - key1 = "value1" # Ignore key quotation '"' - key2 = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -此外,**选择表达式**可以用于定义包含嵌套键 dict 实例。 - -```python -person = { - base.count = 2 - base.value = "value" - labels.key = "value" -} # {"base": {"count": 2, "value": "value"}, "labels": {"key": "value"}} -``` - -输出 YAML 为: - -```yaml -person: - base: - count: 2 - value: value - labels: - key: value -``` - -在 KCL 中,dict 中的不同的字段可以直接引用,比如如下的例子 - -```python -config = { - name = "me" - metadata.name = name # Reference `name` with the value `"me"` in `config` directly. -} -``` - -输出 YAML 为: - -```yaml -config: - name: me - metadata: - name: me -``` - -我们可以使用字典推导式构建字典: - -```python -x = {str(i): 2 * i for i in range(3)} -assert x == {"0" = 0, "1" = 2, "2" = 4} -``` - -此外,我们可以在字典推导式中使用两个变量。第一个变量表示字典的键,第二个变量表示字典中键对应的值。 - -```python -data = {key1 = "value1", key2 = "value2"} -# Single variable loop -dataKeys1 = {k: k for k in data} # {"key1": "key1", "key2": "key2"} -dataValues1 = {k: data[k] for k in data} # {"key1": "value1", "key2": "value2"} -# Double variable loop -dataKeys2 = {k: k for k, v in data} # {"key1": "key1", "key2": "key2"} -dataValues2 = {v: v for k, v in data} # {"value1": "value1", "value2": "value2"} -dataFilter = {k: v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use `_` to ignore loop variables -dataKeys3 = {k: k for k, _ in data} # {"key1": "key1", "key2": "key2"} -dataValues3 = {v: v for _, v in data} # {"value1": "value1", "value2": "value2"} -``` - -我们可以使用解包操作符 `**` 来合并字典: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = {**_part1, **_part2} # {"a: "b", "c": "d"} -``` - -此外,union 操作符 `|` 也能达到同样的效果: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = _part1 | _part2 # {"a: "b", "c": "d"} -``` - -我们可以使用 `if` 表达式动态的将元素添加到字典,符合条件的元素会被添加到字典,不符合条件的元素会被忽略。 - -```python -a = 1 # 1 -data = { - key1 = "value1" - if a == 1: key2 = "value2" - if a > 0: key3 = "value3" - if a < 0: key4 = "value4" -} # {"key1": "value1", "key2": "value2", "key3": "value3"} -``` - -```python -a = 1 # 1 -data1 = { - key1 = "value1" - if a == 1: - key2 = "value2" - elif a > 0: - key3 = "value3" - else: - key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -data2 = { - key1 = "value1" - if a == 1: key2 = "value2" - elif a > 0: key3 = "value3" - else: key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -``` - -我们可以使用 `for k in dict_var` 表达式来遍历字典, 并且可以使用 `in` 操作符来判断 dict 是否包含某个键。 - -```python -data = {key1 = "value1", key2 = "value2"} -dataAnother = {k: data[k] + "suffix" for k in data} # {"key1": "value1suffix", "key2": "value2suffix"} -containsKey1 = "key1" in data # True -containsKey2 = "key" in data # False -``` - -#### None - -在 KCL 中, `None` 表示对象的值为空, 这与 Go 中的 `nil` 和 Java 中的 `null` 一样,并且对应于 YAML 中的 `null`。 - -```python -a = None -b = [1, 2, None] -c = {key1 = "value1", key2 = None} -``` - -输出如下: - -```yaml -a: null -b: - - 1 - - 2 - - null -c: - key1: value1 - key2: null -``` - -请注意,`None` 不能参与四则运算,但它可以参与逻辑运算和比较运算。 - -```python -a = 1 + None # error -b = int(None) # error -c = not None # True -d = None == None # True -e = None or 1 # 1 -f = str(None) # None -``` - -#### Undefined - -`Undefined` 与 `None` 类似,但其语义是变量没有分配任何值,也不会输出到 YAML。 - -```python -a = Undefined -b = [1, 2, Undefined] -c = {key1 = "value1", key2 = Undefined} -``` - -输出如下: - -```yaml -b: - - 1 - - 2 -c: - key1: value1 -``` - -请注意,`Undefined` 不能参与四则运算,但它可以参与逻辑运算和比较运算。 - -```python -a = 1 + Undefined # error -b = int(Undefined) # error -c = not Undefined # True -d = Undefined == Undefined # True -e = Undefined or 1 # 1 -f = str(Undefined) # Undefined -``` - -### 运算符 - -以下字符表示运算符: - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != @ \ -``` - -#### 算数运算符 - -KCL 支持常见的算数运算符: - -```python -assert 2 + 3 == 5 -assert 2 - 3 == -1 -assert 2 * 3 == 6 -assert 5 / 2 == 2.5 -assert 5 // 2 == 2 -assert 5 % 2 == 1 -``` - -#### 相等和关系运算符 - -KCL 支持相等和关系运算符: - -```python -assert 2 == 2 -assert 2 != 3 -assert 3 > 2 -assert 2 < 3 -assert 3 >= 3 -assert 2 <= 3 -``` - -#### 逻辑运算符 - -我们可以使用逻辑运算符反转或组合布尔表达式,例如:`and` 和 `or`: - -```python -if not done and (col == 0 or col == 3): - # ...Do something... - -``` - -#### 位运算符和移位运算符 - -以下是位运算符和移位运算符的例子: - -```python -value = 0x22 -bitmask = 0x0f - -assert (value & bitmask) == 0x02 -assert (value & ~bitmask) == 0x20 -assert (value | bitmask) == 0x2f -assert (value ^ bitmask) == 0x2d -assert (value << 4) == 0x220 -assert (value >> 4) == 0x02 -``` - -`|` 运算符可用于位运算,合并基本类型和集合及结构化数据,例如**列表**、**字典**和 **schema**。 - -位运算示例: - -```python -0x12345678 | 0xFF # 0x123456FF -``` - -联合基本类型示例: - -```python -schema x: - a: int | str # attribute a could be a int or string -``` - -#### 赋值运算符 - -以下 token 作为语法中的分隔符: - -```txt - ( ) [ ] { } - , : . ; = -> - += -= *= /= //= %= - &= ^= >>= <<= **= -``` - -以下是使用赋值和参数赋值赋值运算符的例子: - -```python -_a = 2 -_a *= 3 -_a += 1 -assert _a == 7 -``` - -#### Identity 运算符 - -以下关键字作为语法中的 identity 运算符: - -```python -is, is not -``` - -Identity 运算符检查右侧和左侧是否时同一对象。它们通常用于检查某个变量是否是 `None/Undefined/True/False`。以下是一些例子: - -```python -empty_String = "" -empty_String is not None # True -``` - -#### 成员运算符 - -以下关键字作为语法中的成员运算符: - -```python -in, not in -``` - -- `in` 运算符计算了第一个操作数是否是第二个操作数的成员,第二个运算符必须是 list、dict、schema 或 string。 -- `not in` 运算符与 `in` 相反。它们都返回一个布尔值。 - -成员的含义因第二个操作数的类型而异:列表的成员是其元素;字典的成员是其键;字符串的成员是其所有子字符串。 - -```python -1 in [1, 2, 3] # True - -d = {one = 1, two = 2} -"one" in d # True -"three" in d # False -1 in d # False -[] in d # False - -"nasty" in "dynasty" # True -"a" in "banana" # True -"f" not in "way" # True - -d = Data {one = 1, two = 2} # Data is a schema with attributes one and two -"one" in d # True -"three" in d # False -``` - -#### 推导式 - -一个推导表达式通过遍历一个或多个迭代项并计算表达式生成的结果来生成连续的元素,并以此构造新的列表或字典。 - -我们可以如下使用列表和字典的推导表达式: - -```python -listVar = [_x for _x in range(20) if _x % 2 == 0] # list comprehension -dictVar = {str(_i): 2*_i for _i in range(3)} # dict comprehension -``` - -#### 其他运算符 - -- 使用 **()** 表示函数调用, 例如 `"{} {}".format("hello", world)`。 -- 使用 **[]** 引用列表中指定索引处的值。 -- 使用 **:** 定义类型注解。 -- 使用 **.** 引用成员字段。 -- 使用 **\\** 续行符编写长表达式。 - -```python -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " -``` - -### 表达式 - -#### 条件表达式 - -条件表达式的形式为 `a if cond else b`。它首先计算条件 `cond`。如果为真,则会计算 `a` 并生成它的值;否则,它会生成 `b` 的值。 - -示例: - -```python -x = True if enabled else False # If enabled is True, x is True, otherwise x is False -``` - -#### 索引表达式 - -索引表达式 `a[i]` 生成可索引类型的第 `i` 个元素,例如字符串或数组。索引 `i` 必须是 `-n` ≤ `i` < `n` 范围内的 `int` 值,其中 `n` 等于 `len(a)`。其他任何索引都会导致错误。 - -有效的负索引的行为类似于 `n+i`,允许方便的对序列末尾进行索引。 - -```python -val = "abc" -list = ["zero", "one", "two"] -str_0 = val[0] # "a" -str_1 = val[1] # "b" -str_n1 = val[-1] # "c" - -list_0 = list[0] # "zero" -list_1 = list[1] # "one" -list_n1 = list[-1] # "two" -``` - -索引表达式 `d[key]` 也可以用于字典 `d`,以获取指定键对应的值。如果字典中不包含这个键则会返回 `Undefined` - -出现在赋值符左侧的索引表达式会更新指定的列表或字典元素。 - -```python -d = {key1 = "value1", key2 = "value2"} -key1value = d["key1"] # value1 -key2value = d["key2"] # value2 -``` - -尝试更新不可变类型的元素值(如列表或字符串)或可变类型的不可变变量会产生错误。 - -#### 切片表达式 - -切片表达式 `a[start:stop:step]` 会生成 `a` 包含的一个子序列,其中 `a` 必须是字符串或者数组。 - -`start`、`stop` 和 `step` 三个操作数都是可选的。如果有的话,每个值都必须为整数。`step` 的默认值为 1。如果 `step` 未指定,它前面的冒号也可以省略。指定 `step` 为 0 会产生错误。 - -从概念上来说,这些操作数指定了一系列值,索引 `i` 从 `start` 开始,每次增加 `step` 直到 `i` 到达或超过 `stop`。结果由有效的 `i` 的 `a[i]` 组成。 - -如下所示,从三个操作数计算有效的开始和结束的索引。`n` 是序列的长度。 - -```python -val = "abc" -len = len(val) -a = val[1:len] # "bc" (remove first element) -b = val[0:-1] # "ab" (remove last element) -c = val[1:-1] # "b" (remove first and last element) -``` - -```python -"abc"[1:] # "bc" (remove first element) -"abc"[:-1] # "ab" (remove last element) -"abc"[1:-1] # "b" (remove first and last element) -"banana"[1::2] # "aaa" (select alternate elements starting at index 1) -"banana"[4::-2] # "nnb" (select alternate elements in reverse, starting at index 4) -``` - -KCL 禁止将切片表达式定义为左值。原因是列表和字符串是不可变的,重新切片可以直接操作操作数,以确保更好的性能。 - -#### 函数调用 - -KCL 允许调用内置函数,或者调用内置和系统模块中的函数。 - -调用函数的基本方法如下所示: - -```python -import math - -a = math.pow(2, 3) # 2 powers 3 is 8. -b = len([1, 2, 3]) # the length of [1, 2, 3] is 3 -``` - -参数以 `,` 分隔,并且 KCL 还支持位置参数和键-值对形式的参数。 - -```python -print("hello world", end="") -``` - -请注意: - -- 有些函数参数具有默认值。 -- 一些函数接受可变参数。 - -如果没有为没有默认值的参数提供参数,则会抛出错误。 - -#### 选择表达式 - -选择表达式选择值的属性或方法。KCL 提供了许多识别或过滤属性的方法: - -`x.y` - -- dict: 表示字典 `x` 中键 `y` 对应的值。 -- schema: 表示 schema `x` 中 `y` 属性的值。 -- package: 表示 package `x` 中 `y` 标示的标识符。 - -示例: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -name = person.name # "Alice" -age = person.age # 18 - -myDict = { - key = "value" -} -result = myDict.key # "value" -``` - -`x?.y` - -`x` 可以是 schema 实例或 dict。当 `x` 可能为 `None` 或者键 `y` 不在 `x` 中时这非常有用。 - -```python -# Example of dict: -data = {"key" = "value"} -a = data?.key # "value" -b = data?.name # Undefined - -# example of schema instance: -schema Company: - name: str - address: str - -schema Person: - name: str - job?: Company - -alice = Person { - name = "alice" -} - -if alice?.job?.name == "Group": - print("work in Group") -``` - -#### Quantifier 表达式 - -Quantifier 表达式用于集合:列表或字典。通常用于在处理集合后获得某个结果,主要有以下四种形式: - -- **all** - - 用于检测集合中所有元素都满足给定的逻辑表达式,并且返回一个布尔值作为结果。 - - 只有集合中所有元素都满足表达式为 true 时,`all` 表达式为 true,否则为 false。 - - 如果集合为空,返回 true。 - - 支持表达式执行期间逻辑表达式的短路。 -- **any** - - 用于检测集合中至少一个元素都满足给定的逻辑表达式,并且返回一个布尔值作为结果。 - - 当集合中至少一个元素都满足表达式为 true 时,`any` 表达式为 true,否则 false。 - - 如果集合为空,返回 false。 - - 支持表达式执行期间逻辑表达式的短路。 -- **map** - - 映射集合中的元素生成新的列表。 - - 新列表的长度严格等于原列表的长度。 -- **filter** - - 通过逻辑判断筛选原集合中的元素,返回一个经过筛选的子集合。 - - 当表达式为 true 时才将元素添加到子集合。 - - 产生的新集合的类型(list, dict 和 schema)与原集合的类型完全一致,并且长度为 `[0, len(original-collection)]`。 - -**all** 和 **any** 表达式的示例代码: - -```python -schema Config: - volumes: [{str:}] - services: [{str:}] - - check: - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - }, "invalid cluster ip" - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } -``` - -**map** 和 **filter** 表达式的示例代码: - -```python -a = map e in [{name = "1", value = 1}, {name = "2", value = 2}] { - {name = e.name, value = int(e.value) ** 2} -} # [{"name": "1", value: 1}, {"name": "2", "value": 4}] - -b = map k, v in {a = "foo", b = "bar"} { v } # ["foo", "bar"] - -c = filter e in [{name = "1", value = 1}, {name = "2", value = 2}] { - int(e.value) > 1 -} # [{"name": "2", "value": 2}] - -d = filter _, v in {a = "foo", b = "bar"} { - v == "foo" -} # {"a": "foo"} -``` - -请注意,区分 any 表达式和 any 类型的区别。当 `any` 在类型注解中使用,意味着变量的值是任意的,而 any 表达式意味着集合中的至少一个元素满足条件。 - -### 流程控制表达式 - -#### If 和 Else - -KCL 支持 `if` 表达式和可选的 `elif` 和 `else` 表达式, 示例如下: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - print("maybe a is negative") -else: - print("a >= 100") -``` - -`elif` 的例子: - -```python -_result = 0 -if condition == "one": - _result = 1 -elif condition == "two": - _result = 2 -elif condition == "three": - _result = 3 -else: - _result = 4 -``` - -`if-elif-else` 表达式可以嵌套,示例如下: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - if a < 0: - print("a is negative") - print("No matter a is negative or positive, this message is printed") -else: - print("a >= 100") -``` - -此外,对于简单的 `if` 表达式如下: - -```python -if success: - _result = "success" -else: - _result = "failed" -``` - -我们可以使用 ` if else ` 的形式将它们写在一行: - -```python -_result = "success" if success else "failed" -``` - -`if` 或 `elif` 语句计算一个给定的表达式。当表达式的计算结果为 `True`, `:` 之后的语句将被计算,而当表达式为 `False` ,后面的语句不会被计算。 - -请注意,常量 `False`, `None`, 数字 `0`, 空列表 `[]`, 空字典 `{}` 和空字符串 `""` 都被视为 `False` 。 - -```python -_emptyStr = "" -_emptyList = [] -_emptyDict = {} -isEmptyStr = False if _emptyStr else True -isEmptyList = False if _emptyList else True -isEmptyDict = False if _emptyDict else True -``` - -结果为: - -```yaml -isEmptyStr: true -isEmptyList: true -isEmptyDict: true -``` - -### 断言语句 - -当发生错误时,开发人员应该能够检测到错误并终止执行。因此,KCL 引入了 `assert` 语法,示例如下: - -```python -a = 1 -b = 3 -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -``` - -此外,我们可以为 assert 语声明一个条件,当条件满足时,才进行 assert 断言 - -- 使用 if 语句书写条件断言 - -```python -a = None -if a: - assert a > 2: -``` - -- 使用 if 表达式书写条件断言 - -```python -a = None -assert a > 2 if a -``` - -### 函数 - -KCL 支持使用 lambda 关键字定义一个函数 - -```python -func = lambda x: int, y: int -> int { - x + y -} -a = func(1, 1) # 2 -``` - -lambda 函数具有如下特性: - -- lambda 函数将最后一个表达式的值作为函数的返回值,空函数体返回 None -- 返回值类型注解可以省略,返回值类型为最后一个表达式值的类型 -- 函数体中没有与顺序无关的特性,所有的表达式都是按顺序执行的 - -```python -_func = lambda x: int, y: int -> int { - x + y -} # Define a function using the lambda expression -_func = lambda x: int, y: int -> int { - x - y -} # Ok -_func = lambda x: int, y: int -> str { - str(x + y) -} # Error (int, int) -> str can't be assigned to (int, int) -> int -``` - -lambda 函数对象不能参与任何计算,只能在赋值语句和调用语句中使用。 - -```python -func = lambda x: int, y: int -> int { - x + y -} -x = func + 1 # Error: unsupported operand type(s) for +: 'function' and 'int(1)' -``` - -lambda 函数支持捕获其外部作用域的变量,并且可以作为其他函数的参数进行传递 - -```python -a = 1 -func = lambda x: int { - x + a -} -funcOther = lambda f, para: int { - f(para) -} -r0 = funcOther(func, 1) # 2 -r1 = funcOther(lambda x: int { - x + a -}, 1) # 2 -``` - -输出为: - -```yaml -a: 1 -r: 2 -``` - -此外,可以定义一个匿名函数并直接调用。 - -```python -result = (lambda x, y { - z = 2 * x - z + y -})(1, 1) # 3 -``` - -并且还可以在 for 循环使用使用匿名函数 - -```python -result = [(lambda x, y { - x + y -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 3, 3, 4] -``` - -请注意,KCL 中定义的函数的均为纯函数: - -- 函数的返回结果只依赖于它的参数。 -- 函数执行过程里面没有副作用。 - -因此,KCL 函数不能修改外部的变量,只能引用外部的变量,比如如下代码会发生错误: - -```python -globalVar = 1 -func = lambda { - x = globalVar # Ok - globalVar = 1 # Error -} -``` - -### 类型系统 - -#### 类型注解 - -类型注解可用于包级变量,schema 属性和参数。 - -- 属性可以是基本类型,例如字符串(`string`),浮点数(`float`),定点数(`int`) 或布尔值(`bool`)。 -- 属性可以是字面值类型,例如字符串文本(`"TCP"` 和 `"UDP"`),数字文本 (`"1"` 和 `"1.2"`),布尔值文本(`True` 和 `False`)。 -- 属性也可以是列表或字典: - - 未指定元素类型的列表为 `[]`。 - - 元素类型为 `t` 的列表为 `[t]`。这里 `t` 是另一种类型。 - - 键的类型为 `kt` 且值的类型为 `vt` 的字典为 `{kt:vt}`。 - - `kt`, `vt` 或两者都可以为空, 就像列表未指定元素类型一样。 -- 属性可以是由 `|` 定义的 **联合类型** ,例如 `a | b`, 意为类型可以是 a 或 b。 - - 联合类型可以包含 `int`, `str`, `float`, `bool`, `list`, `dict`, 字面值类型和 schema 类型,并且支持类型的嵌套,例如: `{str:str|int}`、`[[int|str]|str|float]` 和 `2 | 4 | 6` 等。 -- 属性可以是 schema 类型。在这种情况下,使用包名 + schema 名称作为类型名。 -- 属性可以声明为任意类型,例如 `any`。 - -示例 - -- 基本类型 - -```python -"""Top level variable type annotation""" -a: int = 1 # Declare a variable `a` that has the type `int` and the value `1` -b: str = "s" # Declare a variable `b` that has the type `str` and the value `"s"` -c: float = 1.0 # Declare a variable `c` that has the type `float` and the value `1.0` -d: bool = True # Declare a variable `d` that has the type `bool` and the value `True` -``` - -- List/Dict/Schema 类型 - -```python -schema Person: - name: str = "Alice" - age: int = 10 - -a: [int] = [1, 2, 3] # Declare a variable `a` that has the list type `[int]` and the value `[1, 2, 3]` -b: {str:str} = {k1 = "v1", k2 = "v2"} # Declare a variable `b` that has the dict type `{str:str}` and the value `{k1 = "v1", k2 = "v2"}` -c: Person = Person {} # Declare a variable `c` that has the schema type `Person` and the value `Person {}` -``` - -- 联合类型 - -```python -# Basic union types -schema x[argc: int]: # Schema argument type annotation - p: int | str # Schema attribute type annotation -``` - -```python -# Literal union types -schema LiteralType: - # String literal union types, x_01 can be one of "TCP" and "UDP" - x_01: "TCP" | "UDP" - # Number literal union types, x_02 can be one of 2, 4, and 6 - x_02: 2 | 4 | 6 - # Unit union types, x_03 can be one of 1Gi, 2Gi and 4Gi - x_03: 1Gi | 2Gi | 4Gi - -x = LiteralType { - x_01 = "TCP" - x_02 = 2 - x_03 = 1Gi -} -``` - -当属性的值不符合联合类型定义时,编译器会抛出错误: - -```python -# Literal union types -schema LiteralType: - # String literal union types, x_01 can be one of "TCP" and "UDP" - x_01: "TCP" | "UDP" - -x = LiteralType { - x_01 = "HTTP" # Error: the type got is inconsistent with the type expected, expect str(TCP)|str(UDP), got str(HTTP) -} -``` - -- Any 类型 - -```python -# Any type -schema Config: - literalConf: any = 1 - dictConf: {str:any} = {key = "value"} - listConf: [any] = [1, "2", True] - -config = Config {} -``` - -请注意,一般在配置编写中不提倡使用 `float` 和 `any` 类型,因为它们都存在一定的不稳定因素,比如精度丢失,无法进行静态类型检查等。 - -此外在 KCL 中,不允许修改一个变量的类型。如果在重新分配值时不满足类型,将引发类型错误。 - -```python -_a = 1 # The type of `_a` is `int` -_a = "s" # Error: expect int, got str(s) -``` - -变量可以赋值给其上界类型,但不能赋值给它的特化类型。 - -`None` 和 `Undefined` 可以赋值给任何类型: - -- 任何类型都可以赋值给 `any` 类型, `None` 和 `Undefined` 可以赋值给 `any` 类型。 - -```python -a: int = None -b: str = Undefined -c: any = 1 -d: any = "s" -e: any = None -``` - -- `int` 类型可以赋值给 `float` 类型, `float` 类型不能赋值给 `int` 类型. - -```python -a: float = 1 -b: int = 1.0 # Error: expect int, got float(1.0) -``` - -- `int` 类型可以赋值给 `int|str` 类型, `int|str` 不能赋值给 `int` 类型. - -```python -a: int | str = 1 -b: int = 1 if a else "s" # Error: expect int, got int(1)|str(s) -``` - -请注意,在 KCL 中虽然提供了 any 类型,但是它仍然是静态类型,所有变量的类型在编译期间不可变。 - -#### 类型推导 - -如果顶层或 schema 中的变量或常量声明没有使用显式的类型注解,则会从初始值推断类型。 - -- 整形数值被推断为 `int`。 - -```python -a = 1 # The variable `a` has the type `int` -``` - -- 浮点数被推断为 `float`。 - -```python -a = 1.0 # The variable `a` has the type `float` -``` - -- 字符串被推断为 `str`。 - -```python -a = "s" # The variable `a` has the type `str` -``` - -- 布尔值被推断为 `bool`。 - -```python -a = True # The variable `a` has the type `bool` -b = False # The variable `b` has the type `bool` -``` - -- `None` 和 `Undefined` 被推断为 `any`。 - -```python -a = None # The variable `a` has the type `any` -b = Undefined # The variable `b` has the type `any` -``` - -- 列表的类型根据元素类型推断,并且是可变大小的。 - -```python -a = [1, 2, 3] # The variable `a` has the type `[int]` -b = [1, 2, True] # The variable `b` has the list union type `[int|bool]` -c = ["s", 1] # The variable `c` has the list union type `[int|str]` -``` - -请注意,空列表将被推导为 `[any]` 类型。 - -```python -a = [] # The variable `a` has the type `[any]` -``` - -- 字典的类型是根据元素的键和值推断的,并且是可变大小的。 - -```python -a = {key = "value"} # The variable `a` has the type `{str:str}` -b = {key = 1} # The variable `b` has the type `{str:int}` -c = {key1 = 1, key2 = "s"} # The variable `c` has the type `{str:int|str}` -``` - -请注意,空字典将被推导为 `{any:any}` 类型。 - -```python -a = {} # The variable `a` has the type `{any:any}` -``` - -- 携带运行时值的 if 条件表达式的类型将被静态推断为所有可能结果的联合类型。 - -```python -a: bool = True # The variable `a` has the type `bool` -b = 1 if a else "s" # The variable `b` has the type `int|str` -``` - -当变量被推导为某个类型时,它的类型不能再改变。 - -```python -_a = 1 -_a = "s" # Error: expect int, got str(1) -``` - -#### 类型别名 - -在 KCL 中,我们可以使用 `type` 关键字为所有类型声明一个类型别名简化复杂类型的书写。 - -```python -type Int = int -type String = str -type StringOrInt = String | Int -type IntList = [int] -type StringAnyDict = {str:} -``` - -我们可以从一个包中导入一个类型并为它定义一个别名。 - -```py -import pkg - -type Data = pkg.Data -``` - -此外,我们还可以使用类型别名和字面值联合类型充当近似枚举的效果。 - -```python -# A type alias of string literal union types -type Color = "Red" | "Yellow" | "Blue" - -schema Config: - color: Color = "Red" # The type of color is `"Red" | "Yellow" | "Blue"`, and it has an alias `Color`, whose default value is `"Red"` - -config = Config { - color = "Blue" -} -``` - -上述代码执行的输出结果为: - -```yaml -config: - color: Blue -``` - -请注意,类型别名不能与已有的内置类型 `any`、`int`、`float`、`bool` 和 `str` 等相同 - -```python -type any = int | str # Error -type int = str # Error -type float = int # Error -type bool = True # Error -type str = "A" | "B" | "C" # Error -``` - -#### 类型守卫 - -KCL 支持在程序中使用 `typeof` 函数对任意值求得其运行时的类型。 - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person {} -t3 = typeof(_x1) - -_x2 = pkg.Person {} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# Output -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -除此之外,我们可以使用 `as` 关键字在运行时作类型转换。`as` 关键字的一般用法如下: - -- 具有偏序关系的基础类型,比如 `float -> int` -- 具有偏序关系的联合类型,比如 `int | str -> str` -- 对类型上界 `any` 的转换,比如 `any -> int` -- 具有偏序关系的结构类型,比如 `base-schema -> sub-schema` - -```python -schema Data1: - id?: int - -schema Data2: - name?: str - -data: Data1 | Data2 = Data1 {} - -if typeof(a) == "Data1": - data1 = data as Data1 # The type of `data1` is `Data1` -elif typeof(a) == "Data2": - data2 = data as Data2 # The type of `data2` is `Data2` -``` - -当类型转换失败时,一个运行时错误将被抛出。 - -```python -a: any = "s" -b: int = a as int # Error: The `str` type cannot be converted to the `int` type -``` - -如果不想要运行时类型转换失败,我们可以添加 `if` 防御式代码进行检查。 - -```python -a: any = "s" -b = a as int if typeof(a) == "int" else None # The type of b is `int` -``` - -请注意,`as` 转换的目标类型不能是字面值类型或者联合类型,因为它们在运行时不具有一个完全确定的类型。 - -### Schema - -#### 概述 - -Schema 是定义复杂配置的语言元素。我们可以定义带类型的属性,初始值和验证规则。此外,KCL 支持 schema 单继承、mixin 和 protocol 实现复杂配置的复用。 - -#### 基础部分 - -##### 属性 - -以下是 schema 基础定义的示例: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 -``` - -在 KCL 中, 我们可以使用类型注解在 schema 中定义一些属性,每个属性都可以设置一个可选的默认值(比如上述代码中的 `age` 属性,它的默认值是 `0`),没有设置默认值的属性的初始值为 `Undefined`, 它们不会在 YAML 当中进行输出。 - -###### 不可变性 - -schema 中属性的不可变性遵循和全局变量不可变性一样的规则,只有 schema 中的可变属性可以在 schema 中修改。此外,schema 的属性默认值可被 schema 配置值修改: - -```python -schema Person: - age: int = 1 # Immutable attribute - _name: str = "Alice" # Mutable attribute - - age = 10 # Error, can't change the default value of the attribute `age` in the schema context. - _name = "Bob" # Ok - -person = Person { - age = 3 # Ok, can change the default value of the attribute `age` in the schema config. -} -``` - -###### 可选属性 - -schema 实例中每个属性 **必须** 赋值一个非 `None`/`Undefined` 的值,否则编译器会抛出错误,除非它被 `?` 符号标记为可选属性。 - -示例: - -```python -schema Employee: - bankCard: int # bankCard is a required attribute, and it can NOT be None or Undefined - nationality?: str # nationality is an optional attribute, and it can be None or Undefined - -employee = Employee { - bankCard = None # Error, attribute 'bankCard' of Employee is required and can't be None or Undefined - nationality = None # Ok -} -``` - -##### 顺序无关计算 - -schema 中顺序无关计算表示 schema 内部属性之间的引用关系。例如,当我们声明一个形式为 `a = b + 1` 的表达式时,`a` 值的计算依赖于 `b` 值的计算。当编译器计算 `a` 的值并且 `a` 的值取决于 `b` 的值时,编译器会选择先计算 `b` 的值,然后根据 `b` 的值计算 a 的值表达式 `a = b + 1`,这与传统过程语言的计算方法略有不同。 - -由于 schema 中值的计算是基于依赖关系的,就像有向无环图按照拓扑排序的顺序遍历图中的每个节点一样, schema 中属性的声明顺序并不那么重要,因此特征称为顺序无关计算。 - -请注意,不同 schema 属性值之间不能有循环引用。 - -我们可以通过下面的例子看到这个特性。 - -```python -schema Fib: - n1: int = n - 1 # Refers to the attribute `n` declared after `n1` - n2: int = n1 - 1 - n: int - value: int = 1 if n <= 2 else Fib {n = n1}.value + Fib {n = n2}.value - -fib8 = Fib {n = 8}.value -``` - -结果为: - -```yaml -fib8: 21 -``` - -在 schema 中,我们只需要简单的指定属性之间的依赖关系,编译器就会根据依赖关系自动计算出值,这样可以帮助我们节省大量的样板代码,减少配置编写难度。 - -##### Schema 上下文 - -我们可以定义 schema 的上下文来管理 schema 的属性,可以直接在 schema 中编写 schema 参数、临时变量和表达式等: - -```python -schema Person[_name: str]: # define a schema argument - name: str = _name # define a schema attribute - age: int = 10 # define a schema attribute with default value - hands: [int] = [i for i in [1, 2, 3]] # define a for statement -``` - -然后,我们可以通过如下代码实例化一个 `Person` 并将其赋值给 `alice` 变量: - -```python -alice = Person("alice") -``` - -可以得到如下 YAML 输出: - -```yaml -alice: - name: alice - age: 10 - hands: - - 1 - - 2 - - 3 -``` - -##### 校验 - -KCL 中为了确保代码稳定性,除了使用 **静态类型** (类型注解) 和 **不可变性**,还支持在 **check** 块中定义验证规则 (KCL 几乎原生支持所有 [OpenAPI](https://www.openapis.org/) 的验证能力): - -```python -import regex - -schema Sample: - foo: str - bar: int - fooList: [str] - - check: - bar > 0 # Minimum, also support the exclusive case - bar < 100 # Maximum, also support the exclusive case - len(fooList) > 0 # Min length, also support exclusive case - len(fooList) < 100 # Max length, also support exclusive case - regex.match(foo, "^The.*Foo$") # Regex match - isunique(fooList) # Unique - bar in range(100) # Range - bar in [2, 4, 6, 8] # Enum - multiplyof(bar, 2) # MultipleOf -``` - -使用 schema, 所有的实例将在编译时验证: - -```python -# Ok -goodSample = Sample { - foo = "The Foo" - bar = 2 - fooList = ["foo0", "foo1"] -} - -# Error: validation failure: Check failed on check conditions: bar < 100. -badSample = Sample { - foo = "The Foo" - bar = 123 - fooList = ["foo0", "foo1"] -} -``` - -此外,我们可以使用 **and**, **or**, **if** 来构建更复杂的检查逻辑: - -```python -schema Sample: - bar: int - foo: str - doCheck: bool - - check: - regex.match(foo, "^The.*Foo$") and bar in [2, 4, 6, 8] if doCheck -``` - -为了确保所有检查规则都能很好地发挥其相应的作用,我们可以通过编写 KCL 测试用例来测试不同数据组合的合理性和正确性,并通过 kcl test tool 运行所有测试用例。 - -##### 文档 - -通常在我们写好 schema 模型之后,我们会为 schema 写文档注释,可以用一个三引号字符串来完成,如下所示: - -```python -schema Server: - """Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - - Attributes - ---------- - workloadType : str, default is Deployment - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - name : str, default is None - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - labels : {str:str}, optional, default is None - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - - Examples - ---------------------- - myCustomApp = AppConfiguration { - name = "componentName" - } - """ - workloadType: str = "Deployment" - name: str - labels?: {str:str} -``` - -更多详细内容可见 Doc tools。 - -##### 配置 - -假设我们有如下 schema 定义: - -```python -schema Person: - firstName: str - lastName: str - labels?: {str:str} -``` - -可以用类 JSON 的表达式定义配置: - -```python -person = Person { - firstName = "firstName" - lastName = "lastName" -} -``` - -schema 遵循严格的属性定义,配置未定义的属性将触发编译错误: - -```python -person = Person { - firstName = "firstName" - lastName = "lastName" - fullName = "fullName" # Error: Cannot add member 'fullName' to schema 'Person', 'fullName' is not defined in schema 'Person' -} -``` - -此外,我们可以使用 `if` 表达式将元素动态的添加到 schema 实例中,将满足条件的元素添加到 schema 实例并忽略不满足条件的元素。并且除了使用一个 schema 类型实例化一个 schema,我们也可以通过 schema 实例得到一个新的实例。 - -```python -env = "prod" -person = Person { - firstName = "firstName" - lastName = "lastName" - if env == "prod": - labels.env = env - else: - labels.env = "other" -} -# We can use the person instance to get a new instance named `personx` directly. -personx = person { - firstName = "NewFirstName" -} -``` - -输出为: - -```yaml -env: prod -person: - firstName: firstName - lastName: lastName - labels: - env: prod -personx: - firstName: NewFirstName - lastName: lastName - labels: - env: prod -``` - -#### 高级功能 - -##### Protocol & Mixin - -除了 schema, 在 KCL 中还提供了一种额外的类型定义方式 `protocol`,它的性质如下: - -- 在 protocol 中,只能定义属性及其类型,不能书写复杂的逻辑与 check 表达式,也不能使用 mixin。 -- protocol 只能对非 `_` 开头的属性进行约束。 -- protocol 只能继承自或者引用 protocol, 不能继承自或者引用 schema。 - -此外,我们可以使用可选的 **mixin** 组装复杂的 schema,并使用 **protocol** 为 **mixin** 添加可选的宿主类型, 使用 `for` 关键字为 **mixin** 定义宿主类型,并且在 mixin 内部它将从宿主类型中查询到属性的类型。 - -```python -schema Person: - mixin [FullNameMixin] - - firstName: str # Required - lastName: str # Required - fullName?: str # Optional -``` - -FullNameMixin 是一个产生 fullName 字段的简单例子: - -```python -protocol PersonProtocol: - firstName: str - lastName: str - fullName?: str - -mixin FullNameMixin for PersonProtocol: - fullName = "{} {}".format(firstName, lastName) -``` - -然后我们可以通过一下方式获取 schema 实例: - -```python -person = Person { - firstName = "John" - lastName = "Doe" -} -``` - -输出结果为: - -```yaml -person: - firstName: John - lastName: Doe - fullName: John Doe -``` - -请注意,宿主类型 **protocol** 只能用于 **mixin** 的定义 (后缀名为 `Mixin`), 否则将会报错。 - -```python -protocol DataProtocol: - data: str - -schema Data for DataProtocol: # Error: only schema mixin can inherit from protocol - x: str = data -``` - -##### 索引签名 - -在 KCL schema 中可以定义索引签名,这意味着索引签名的键-值约束可用于构造具有 schema 类型的字典。或者可以将其他检查添加到额外的 schema 属性中,以增强 KCL 类型和语义检查。 - -###### 基本用法 - -使用 `[{attr_alias}: {key_type}]: {value_type}` 的形式去定义 schema 的类型注解, 其中 `{attr_alias}` 可以省略。 - -```python -schema Map: - """ - Map is a schema with a key of str type and a value of str type - """ - [str]: str # `{attr_alias}` can be omitted. - -data = Map { - key1 = "value1" - key2 = "value2" -} -``` - -###### 同时定义属性和索引签名 - -可以在 schema 中同时定义 schema 属性和索引签名,通常用于表示 schema 中额外属性的类型约束,比如如下代码 - -```python -schema Person: - name: str - age: int - [...str]: str # Except for the `name` and `age` attributes, the key type of all other attributes of the schema must be `str`, and the value type must also be `str`. -``` - -###### 定义索引签名别名 - -可以为索引签名定义类型注解的属性别名,并将其与检查块一起使用。 - -```python -schema Data: - [dataName: str]: str - check: - dataName in ["Alice", "Bob", "John"] # We can use the index signature key name in the check block. - -data = Data { - Alice = "10" - Bob = "12" - Jonn = "8" # Error: Jonn not in ["Alice", "Bob", "John"] -} -``` - -##### 继承 - -类似于其他面向对象语言,KCL 提供了基础且有限的面向对象支持,例如 **属性复用**,**私有和公有变量**和**单继承**。KCL 不支持多继承。 - -以下是单继承的例子: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 - -# An employee **is** a person, and has some additional information. -schema Employee(Person): - bankCard: int - nationality?: str - -employee = Employee { - firstName = "Bob" - lastName = "Green" - age = 18 - bankCard = 123456 -} -``` - -结果为: - -```yaml -employee: - firstName: Bob - lastName: Green - age: 18 - bankCard: 123456 - nationality: null -``` - -请注意,KCL 只支持 schema 的 **单继承**。 - -此外,当 schema 存在继承关系时,可选属性的性质如下: - -- 如果该属性在基类 schema 中是可选的,则它在子类 schema 中是可选的,也可以是子类 schema 中必选的。 -- 如果该属性在基类 schema 中是必选的,则它在子类 schema 中也是必选的。 - -```python -schema Person: - bankCard?: int - nationality: str - -schema Employee(Person): - bankCard: int # Valid, both `bankCard: int` and `bankCard?: int` are allowed - nationality?: str # Error, only `nationality: str` is allowed -``` - -##### Schema 函数 - -schema 映射到函数上非常好用;它可以有任意数量的输入和输出参数。 例如,Fibonacci 函数可以使用递归 schema 如下编写: - -```python -schema Fib[n: int]: - n1 = n - 1 - n2 = n - 2 - if n == 0: - value = 0 - elif n == 1: - value = 1 - else: - value = Fib(n1).value + Fib(n2).value - -fib8 = Fib(8).value # 21 -``` - -##### 装饰器 - -像 Python 一样, KCL 支持在 schema 上使用装饰器。KCL 装饰器动态地改变 schema 的功能,而不必直接使用子 schema 或更改被装饰的 schema 的源代码。 和函数调用一样,装饰器支持传入额外的参数。 - -内置的 schema 装饰器: - -- `@deprecated` - 标识 schema 或 schema 属性被废弃. `@deprecated` 装饰器支持三种参数: - - **version** - 字符串类型,表示版本信息。 默认值为空。 - - **reason** - 字符串类型,表示不推荐使用的原因。 默认值为空。 - - **strict** - bool 类型,表示是报错还是警告。 默认值是 true。 如果 `strict` 为 `True` 并且抛出错误,程序将被中断。 如果 `strict` 为 `False`,则会输出警告并且不会中断程序。 - -示例: - -```python -@deprecated -schema ObsoleteSchema: - attr: str - -schema Person: - firstName: str = "John" - lastName: str - @deprecated(version="1.16", reason="use firstName and lastName instead", strict=True) - name: str - attrs: ObsoleteSchema = { # Error: ObsoleteSchema was deprecated - attr = "value" - } - -JohnDoe = Person { # Error: name was deprecated since version 1.16, use firstName and lastName instead - name = "deprecated" -} -``` - -- `@info` - 给 schema 或 schema 属性标识额外的信息,支持任意参数,用于语言静态分析 schema 或 schema 属性的扩展标记信息 - -示例: - -```python -@info(version="v1") -schema Person: - @info(message="name") - name: str - age: int -``` - -请注意,当前版本的 KCL 尚不支持用户自己定义装饰器。 - -##### 成员函数 - -内置函数和 schema 成员 - -- instances() - 返回 schema 的现有实例列表。 - -```python -schema Person: - name: str - age: int - -alice = Person { - name = "Alice" - age = 18 -} - -bob = Person { - name = "Bob" - age = 10 -} - -aliceAndBob = Person.instances() # Person is a schema type, instances() is its member method -``` - -输出为: - -```yaml -alice: - name: Alice - age: 18 -bob: - name: Bob - age: 10 -aliceAndBob: - - name: Alice - age: 18 - - name: Bob - age: 10 -``` - -### 配置操作 - -#### 配置合并 - -##### | 运算符 - -在 KCL 中,我们可以使用合并运算符 `|` 来合并配置。union 运算符支持的类型包括如下: - -```txt -SchemaInstance | SchemaInstance -SchemaInstance | Dict -Dict | Dict -List | List -``` - -合并集合和结构化数据: - -- 合并 List。使用 `|` 运算符右边的列表表达式按照**索引**逐一覆盖左边列表表达式中的元素。 - -```python -_a = [1, 2, 3] -_b = [4, 5, 6, 7] -x = _a | _b # [4, 5, 6, 7] 1 -> 4; 2 -> 5; 3 -> 6; Undefined -> 7 -``` - -合并特定索引或所有元素仍在讨论中。 - -- 合并 Dict. 使用 `|` 运算符右边的列表表达式按照**键**逐一覆盖左边列表表达式中的元素。 - -```python -_a = {key1 = "value1"} -_b = {key1 = "overwrite", key2 = "value2"} -x = _a | _b # {"key1": "overwrite", "key2": "value2"} -``` - -集合和 schema 的合并是一个新的集合,其属性是将 b 合并到 a,保留从左到右的操作数顺序。 - -- 合并 schema。Schema 的合并与 dict 相似。 - -Schema 的合并操作如下: - -```python -schema Person: - firstName?: str - lastName?: str - -_a = Person { - firstName = "John" -} -_b = {lastName = "Doe"} -_c = _a | _b # {"firstName": "John", "lastName": "Doe"} -_d = _a | None # {"firstName": "John"} -_e = _a | Undefined # {"firstName": "John"} -_f = None | _a # {"firstName": "John"} -_g = Undefined | _a # {"firstName": "John"} -``` - -请注意,当 union 运算符的左右操作数之一为 None 时,将立即返回另一个操作数。 - -```python -data1 = {key = "value"} | None # {"key": "value"} -data2 = None | [1, 2, 3] # [1, 2, 3] -data3 = None | None # None -``` - -输出如下: - -```yaml -data1: - key: value -data2: - - 1 - - 2 - - 3 -data3: null -``` - -##### : 运算符 - -模式: `identifier : E` - -表达式 `E` 的值将被合并到元素值。 - -示例: - -```python -schema Data: - labels: {str:} = {key1 = "value1"} - -data = Data { - # union {key2: "value2"} into the attribute labels of the schema Data. - labels: {key2 = "value2"} -} -``` - -输出: - -```yaml -data: - labels: - key1: value1 - key2: value2 -``` - -除了在 schema 属性上使用属性运算符之外,还可以使用属性运算符对配置块执行不同的操作。 - -- schema 外部使用合并运算符 `:` - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - data: Data - -# This is one configuration that will be merged. -config: Config { - data.d1 = 1 -} -# This is another configuration that will be merged. -config: Config { - data.d2 = 2 -} -``` - -与它等效的配置代码可以表示为: - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - data: Data - -config: Config { - data.d1 = 1 - data.d2 = 1 -} -``` - -输出结果为: - -```yaml -config: - data: - d1: 1 - d2: 1 -``` - -- schema 内部使用合并运算符 `:` - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - # This is one configuration that will be merged. - data: Data { - d1 = 1 - } - # This is another configuration that will be merged. - data: Data { - d2 = 1 - } - -config: Config {} -``` - -#### 配置覆盖 - -##### = 运算符 - -模式: `identifier = E` - -表达式 `E` 的值将覆盖元素值。 - -示例: - -```python -schema Data: - labels: {str:} = {key1 = "value1"} - -data = Data { - # override {key2: "value2"} into the attribute labels of the schema Data. - labels = {key2 = "value2"} -} -``` - -输出: - -```yaml -data: - labels: - key2: value2 -``` - -请注意,可以使用 `Undefined` 来覆盖,来“删除”内容。例如 `{ a = Undefined }`。 - -#### 配置添加 - -##### += 运算符 - -模式: `identifier += E` - -插入只能用于列表类型的 `identifier`. - -`E` 将插入到列表 `identifier` 指定索引后,并且索引以后的属性将自动后移。 - -示例: - -```python -schema Data: - labels: {str:} = {key1 = [0]} - -data = Data { - # insert [1] into the attribute labels.key1 of the schema Data. - labels: {key1 += [1]} -} -``` - -输出: - -```yaml -data: - labels: - key1: - - 0 - - 1 -``` - -如果没有定义索引,将使用最后一个索引。 - -#### 注意事项 - -合并运算符 `:` 是一个可交换的幂等运算符,当合并的值发生值的冲突时会发生值冲突错误,因此我们需要 `=` 和 `+=` 运算符表示配置的覆盖,添加和删除操作。 - -```python -data0 = {id: 1} | {id: 2} # Error:conflicting values between {'id': 2} and {'id': 1} -data1 = {id: 1} | {id = 2} # Ok, the value of `data` is {"id": 2} -``` - -`:` 运算符冲突检查的规则如下: - -- `None` 和 `Undefined` 不与任何值冲突 - -```python -data0 = None | {id: 1} # Ok -``` - -- 对于 `int`、`float`、`str` 和 `bool` 类型的变量,当它们的值不相同时发生冲突错误。 - -```python -data0 = 1 | 1 # Ok -data1 = 1 | "s" # Error -``` - -- 对于列表类型 - - 当它们的长度不相同时,它们被认为是冲突的 - - 当它们的长度相同时,当且仅当它们的任意一个子元素值冲突时,它们自身是冲突的 - -```python -data0 = [1] | [1] # Ok -data1 = [1, 2] | [1] # Error -``` - -- 对于 dict/schema 类型 - - 对于相同的 key,key 的值冲突时,它们自身是冲突的,否则是不冲突的 - -```python -data0 = {id: 1} | {id: 1} # Ok -data1 = {id: 1} | {id: 2} # Error -data1 = {id: 1} | {idAnother: 1} # Ok -``` - -### Rule - -KCL 支持使用 rule 关键字定义校验块,可用于数据校验,用法类似于 schema 中的 check 表达式。 - -```python -rule SomeRule: - age > 0, "rule check failure message" -``` - -可以像 schema 实例化那样调用一个 rule 进行校验 - -```python -age = 0 -name = "Bob" -rule SomeRule: - age > 0, "rule check failure message" - name == "Alice" - -rule1 = SomeRule() # Rule call -rule2 = SomeRule {} -``` - -可以使用 protocol 和 for 绑定语句为 rule 增加类型约束: - -```python -# Schema definition -protocol Service: - clusterIp: str - $type: str - -# Schema definition -protocol Volume: - mountPath: [str] - -# Protocol -protocol SomeProtocol: - id: int - env: {str: any} - services: [Service] - volumes: [Volume] - -rule SomeChecker for SomeProtocol: - id > 0, "id must >0" - - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - } - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } - -# Call rule to check with config parameter -SomeChecker { - id = 1 - env = { - MY_ENV = "MY_ENV_VALUE" - } - services = [ - { - type = "ClusterIP" - clusterIP = "NONE" - } - ] - volumes = [ - { - mountPath = "/home/admin" - } - { - mountPath = "/home/myapp" - } - ] -} -``` - -请注意,`protocol` 和 `rule` 的组合方式可以使属性和其约束定义进行分离,我们可以在不同的包中定义不同的 `rule` 和 `protocol` 按需进行组合,这与 schema 中的 check 表达式只能与 schema 属性定义在一起是不同的。 - -此外,有两种复用不同 rule 的方式 - -- 直接调用 - -```python -weather = "sunny" -day = "wednesday" - -rule IsSunny: - weather == "sunny" - -rule IsWednesday: - day == "wednesday" - -rule Main: - IsSunny() # Rule inline call - IsWednesday() # Rule inline call - -Main() # Rule call -``` - -使用 rule 的继承 (rule 不同于 schema, 可以多继承混用) - -```python -weather = "sunny" -day = "wednesday" - -rule IsSunny: - weather == "sunny" - -rule IsWednesday: - day == "wednesday" - -rule Main(IsSunny, IsWednesday): - id == 1 - -Main() -``` - -可以使用 option 函数与命令行 `-D` 参数获得外部数据进行校验 - -- 一个简单例子 - -```python -schema Day: - day: str - homework: str - -days: [Day] = option("days") - -rule Main: - filter d in days { - d.day not in ["saturday", "sunday"] and d.homework - } - -Main() -``` - -- 一个复杂例子 - -```python -data = option("data") -input = option("input") - -rule Allow: - UserIsAdmin() - any grant in UserIsGranted() { - input.action == grant.action and input.type == grant.type - } - -rule UserIsAdmin: - any user in data.user_roles[input.user] { - user == "admin" - } - -rule UserIsGranted: - [ - grant - for role in data.user_roles[input.user] - for grant in data.role_grants[role] - ] - -allow = Allow() or False -``` - -### 模块 - -KCL 配置文件以 **模块** 形式组织。 单个 KCL 文件被认为是一个 module,一个目录被认为是一个包。 - -同一个包内的模块是可见的,跨包引用需要通过导入可见。 - -```bash -. -└── root - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -model1.k: - -```python -# schema CatalogItem in model1.k - -schema CatalogItem: - id: int - image: CatalogItemImage # CatalogItemImage is defined in the module of the same package e.g., model2.k in package model - title: str -``` - -service1.k: - -```python -import ..model as model # cross-package references - -schema ImageService: - image: model.CatalogItemImage # CatalogItemImage is imported from another package e.g., model2.k in package model - name: str -``` - -#### 相对路径引用 - -我们可以使用 `.` 运算符来实现 KCL 入口文件的相对路径导入。 - -main.k: - -```python -import .model1 # Current directory module -import ..service # Parent directory -import ...root # Parent of parent directory - -s = service.ImageService {} -m = root.Schema {} -``` - -#### 绝对路径引用 - -`import a.b.c.d` 的语义为: - -1. 如果 `kcl.mod` 文件不存在,将当前目录作为包的根路径,并从当前目前查找 `a/b/c/d` 路径 -2. 如果 `kcl.mod` 文件存在,从 `ROOT_PATH/a/b/c/d` 查找,否则抛出一个导入错误 - -根路径 `ROOT_PATH` 的定义为: - -从当前目录或者父级目录中查找 `kcl.mod` 文件对应的目录。 - -```bash -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -main.k: - -```python -import service # `root package` and `kcl.mod` are in the same directory -import mixin # `root package` and `kcl.mod` are in the same directory - -myModel = model.CatalogItem {} -``` - -请注意,对于 KCL 入口文件 `main.k`,不能导入所在文件夹,否则会出现递归导入错误: - -```python -import model # Error: recursively loading -``` - -### 动态参数 - -假设某些字段需要像用户输入一样动态传入,我们可以在模块中定义一个动态参数: - -```python -bankCard = option("bankCard") # Get bankCard through the option function. -``` - -我们可以如下使用 module: - -```bash -kcl employee.k -D bankCard=123 -``` - -目前,支持顶级参数的类型有数字、字符串、布尔、列表和字典。 - -```bash -kcl main.k -D list_key='[1,2,3]' -D dict_key='{"key":"value"}' -``` - -请注意,命令行中引号 `"` 等符号需要使用 `\` 进行转义 - -#### Setting 文件形式的参数 - -此外,它还支持输入一个 YAML 文件作为顶级参数。 - -```yaml -kcl_options: - - key: key_number - value: 1 - - key: key_dict - value: - innerDictKey: innerDictValue - - key: key_list - value: - - 1 - - 2 - - 3 - - key: bankCard - value: 123 -``` - -```bash -kcl -Y setting.yaml employee.k -``` - -此外,setting 文件还支持配置命令行编译参数如下: - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - disable_none: true - strict_range_check: true - debug: 1 - verbose: 1 - output: ./stdout.golden -kcl_options: - - key: image - value: docker.io/kcllang/kcl:latest -``` - -KCL CLI -Y 参数还支持多文件配置,并支持编译参数和顶级参数的单独写入与合并。 - -```bash -kcl -Y compile_setting.yaml option_setting.yaml -``` - -- `compile_setting.yaml` - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - disable_none: true - strict_range_check: true - debug: 1 - verbose: 1 - output: ./stdout.golden -``` - -- `option_setting.yaml` - -```yaml -kcl_options: - - key: image - value: docker.io/kcllang/kcl:latest -``` - -我们可以使用以下指令获取每个参数的含义 - -```bash -kcl --help -``` - -#### Option Functions - -我们可以在 KCL 代码中使用 `option` 获取顶级参数。 - -```python -value = option(key="key", type='str', default="default_value", required=True, help="Set key value") -``` - -参数 - -- **key**: 参数的键。 -- **type**: 要转换的参数类型。 -- **default**: 参数默认值。 -- **required**: 当未提供参数且参数的 required 为 True 是报告错误。 -- **help**: 帮助信息。 - -### 多文件编译 - -除了上面的 KCL 单文件执行之外,我们还可以使用以下命令同时编译多个 KCL 入口文件: - -```bash -kcl main_1.k main_2.k ... main_n.k -``` - -main_1.k - -```python -a = 1 -b = 2 -``` - -main_2.k - -```python -c = 3 -d = 4 -``` - -输出结果为: - -```yaml -a: 1 -b: 2 -c: 3 -d: 4 -``` - -利用**多文件编译**,我们可以组合多个 KCL 文件,而无需使用 import 管理文件。 我们来看一个结合**多文件编译**和 **schema 实例**的例子。 - -model.k - -```python -schema Model: - name: str - labels?: {str:} - annotations?: {str:} - replicas: int - -_model1 = Model { - name = "model1" - labels.key1 = "value1" - labels.key2 = "value2" - annotations.key = "value" - replicas = 2 -} - -_model2 = Model { - name = "model2" - replicas = 3 -} -``` - -backend.k - -```python -import yaml - -schema Backend: - apiVersion: str = "v1" - kind: str = "Deployment" - metadata: {str:} - spec: {str:} = { - minReadySeconds = 0 - paused = False - progressDeadlineSeconds = 600 - replicas = 1 - revisionHistoryLimit = 10 - selector = {} - } - -_backends = [Backend { - metadata.name = model.name - metadata.labels = model.labels - metadata.annotations = model.annotations - spec.selector.matchLabels: model.labels - spec.replicas = model.replicas -} for model in Model.instances()] # Schema Model is defined in model.k -print("---\n".join([yaml.encode(_b, ignore_private=True) for _b in _backends])) -``` - -命令为: - -```bash -kcl model.k backend.k -``` - -输出为: - -```yaml -apiVersion: v1 -kind: Deployment -metadata: - name: model1 - labels: - key1: value1 - key2: value2 - annotations: - key: value -spec: - minReadySeconds: 0 - paused: false - progressDeadlineSeconds: 600 - replicas: 2 - revisionHistoryLimit: 10 - selector: - matchLabels: - key1: value1 - key2: value2 ---- -apiVersion: v1 -kind: Deployment -metadata: - name: model2 -spec: - minReadySeconds: 0 - paused: false - progressDeadlineSeconds: 600 - replicas: 3 - revisionHistoryLimit: 10 - selector: {} -``` - -### KCL 变量查询 - -我们可以在 KCL CLI 使用 `-S|--path-selector` 参数从 KCL 模型中查询一个或多个值。 - -变量查询形式如下: - -`var.name` - -#### 示例 - -Code structure: - -```bash -. -├── kcl.mod -└── main.k - └── pkg - └── model.k -``` - -pkg/model.k: - -```python -schema Person: - name: str - age: int - -var = Person { - name = "Alice" - age = 18 -} -``` - -main.k - -```python -import pkg - -var = pkg.Person { - name = "Bob" - age = 10 -} -``` - -命令为: - -```bash -kcl main.k -S var -``` - -输出结果为: - -```yaml -var: - name: Bob ---- -var: - name: Alice - age: 18 -``` - -### KCL 变量修改 - -除了变量查询,KCL 还允许我们通过 KCL CLI 的 `-O|--overrides` 参数直接修改配置模型中的值。 - -变量修改参数的使用与变量查询类似,参数包含三部分,如 `pkg`、`identifier`、`attribute` 和 `override_value` . - -```bash -kcl main.k -O override_spec -``` - -- `override_spec`: 表示需要修改的配置模型字段和值的统一表示 - -```txt -override_spec: [[pkgpath] ":"] identifier ("=" value | "-") -``` - -- `pkgpath`: 表示需要修改标识符的包路径,通常为 `a.b.c` 的形式,对于 main 包,`pkgpath` 表示为 `__main__`, 可省略,省略不写时表示 main 包 -- `identifier`: 表示需要修改配置的标识符,通常为 `a.b.c` 的形式 -- `value`: 表示需要修改配置的值,可以是任意合法的 KCL 表达式,比如数字/字符串字面值,list/dict/schema 表达式等 -- `=`: 表示修改identifier的值 - - 当 identifier 存在时,修改已有 identifier的值为 value - - 当 identifier 不存在时,添加 identifier属性,并将其值设置为 value -- `-`: 表示删除 identifier属性 - - 当 identifier 存在时,直接进行删除 - - 当 identifier 不存在时,对配置不作任何修改 - -请注意,当 `identifier` 出现多次时,修改/删除全部 `identifier` 的值 - -此外,在 KCL 中还提供了 API 用于变量查询和修改,详见 [API 文档](../xlang-api/go-api.md) - -#### 示例 - -##### 修改示例 - -KCL 代码: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -``` - -命令为: - -```bash -kcl main.k -O :person.name=Bob -O :person.age=10 -``` - -输出结果为: - -```yaml -person: - name: Bob - age: 10 -``` - -此外,当我们使用 KCL CLI `-d` 参数时,KCL 文件将同时修改为以下内容 - -```bash -kcl main.k -O :person.name=Bob -O :person.age=10 -d -``` - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Bob" - age = 10 -} -``` - -##### 删除示例 - -KCL 代码: - -```python -schema Config: - x?: int = 1 - y?: str = "s" - -config = Config { - x = 2 -} -``` - -命令为: - -```bash -kcl main.k -O config.x- -``` - -输出结果为: - -```yaml -config: - x: 1 - y: s -``` - -### 总结 - -本页总结了 KCL 语言中的常用功能。 KCL 作为一种新的语言,会根据配置场景的需求,逐步增加功能特性。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/datetime.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/datetime.md deleted file mode 100644 index 66cb4bca..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/datetime.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: "datetime" -linkTitle: "datetime" -type: "docs" -description: datetime 包 - 时间处理 -weight: 100 ---- - -## time - -`ticks() -> float` - -返回从 1970 年 1 月 1 日 0 时 0 分 0 秒(Epoch)开始到当前时间经过的秒数。如果系统时钟能提供更精确的时间,则秒数后可能会有小数部分。 - -## date - -`date() -> str` - -返回以 `%Y-%m-%d %H:%M:%S` 格式表示的时间。 - -## now - -`now() -> str` - -返回当地时间,例如 `'Sat Jun 06 16:26:11 1998'`。 - -## today - -`today() -> str` - -返回以 `%Y-%m-%d %H:%M:%S.%{ticks}` 格式表示的时间。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/json.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/json.md deleted file mode 100644 index b19bdc88..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/json.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: "json" -linkTitle: "json" -type: "docs" -description: JSON 编码解码 -weight: 100 ---- - -## encode - -``` -encode( - data: any, - sort_keys: bool = False, - indent: int = None, - ignore_private: bool = False, - ignore_none: bool = False -) -> str -``` - -将 KCL 对象 `data` 序列化为 JSON 格式的字符串。 - -## decode - -`decode(value: str) -> any` - -反序列化 `value`(一个包含 JSON 格式文档的字符串实例)为一个 KCL 对象。 - -## dump_to_file - -``` -dump_to_file( - data: any, - filename: str, - ignore_private: bool = False, - ignore_none: bool = False -) -> None -``` - -将 KCL 对象 `data` 序列化为 JSON 格式的字符串,并将其写入文件 `filename` 中。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/yaml.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/yaml.md deleted file mode 100644 index e0faf129..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/yaml.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: "yaml" -linkTitle: "yaml" -type: "docs" -description: yaml 编码解码 -weight: 300 ---- - -## encode - -``` -encode( - data: any, - sort_keys: bool = False, - ignore_private: bool = False, - ignore_none: bool = False -) -> str -``` - -将 KCL 对象 `data` 序列化为 YAML 格式的字符串。 - -## decode - -`decode(value: str) -> any` - -反序列化 `value`(一个包含 YAML 格式文档的字符串实例)为一个 KCL 对象。 - -## dump_to_file - -``` -dump_to_file( - data: any, - filename: str, - ignore_private: bool = False, - ignore_none: bool = False -) -> None -``` - -将 KCL 对象 `data` 序列化为 YAML 格式的字符串,并将其写入文件 `filename` 中。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/Ide/intellij.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/Ide/intellij.md deleted file mode 100644 index be637514..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/Ide/intellij.md +++ /dev/null @@ -1,3 +0,0 @@ -# IntelliJ IDEA - -- IntelliJ Plugin: https://github.com/kcl-lang/intellij-kcl diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/Ide/vs-code.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/Ide/vs-code.md deleted file mode 100644 index d3db7e01..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/Ide/vs-code.md +++ /dev/null @@ -1,54 +0,0 @@ -# Visual Studio Code KCL 插件 - -## 快速开始 - -- 1. [安装 KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) 并检查 `kcl` 和 `kcl-language-server` 命令在您的 PATH 中: - - ```bash - which kcl - which kcl-language-server - ``` - -- 2. 安装 [VS Code KCL 插件](https://marketplace.visualstudio.com/items?itemName=kcl.kcl-vscode-extension). 需要您的 VS Code 版本大于 1.50+ -- 3. 重新打开 VS Code 并创建一个 KCL 文件验证 IDE 插件功能 - -## 特性 - -此扩展提供了一些 KCL 编码帮助,包括以下功能: - -- **语法高亮** - ![Highlight](/img/docs/tools/Ide/vs-code/Highlight.png) -- **跳转** - ![Goto Definition](/img/docs/tools/Ide/vs-code/GotoDef.gif) -- **补全** - ![Completion](/img/docs/tools/Ide/vs-code/Completion.gif) -- **大纲** - ![Outline](/img/docs/tools/Ide/vs-code/Outline.gif) -- **悬停** - ![Hover](/img/docs/tools/Ide/vs-code/Hover.gif) -- **诊断** - ![Diagnostics](/img/docs/tools/Ide/vs-code/Diagnostics.gif) - -> 提示:您可以通过安装 [Error Lens 插件](https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens) 来增强诊断效果 - -其他一些有用的功能,如代码重构和智能感知等正在开发中。 - -## 最小依赖 - -我们建议您使用最新版本的 KCL,但此扩展所需的 KCL 最低版本为 v0.4.6。如果您使用的是更早期版本,则此扩展可能无法正常工作。 - -## 已知问题 - -[详见](https://github.com/kcl-lang/kcl/issues/524) - -## 寻求帮助 - -如果扩展没有如您所期望的那样工作,请通过[社区](https://kcl-lang.io/docs/community/intro/support)与我们联系和寻求帮助。 - -## 参与贡献 - -目前 VS Code KCL 插件处于早期版本,我们正在积极改进 VS Code KCL 插件体验,欢迎参考[贡献指南](https://kcl-lang.io/docs/community/contribute) 一起共建! - -## 许可 - -Apache License 2.0 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/kcl/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/kcl/overview.md deleted file mode 100644 index c0ceee17..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/kcl/overview.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 概览 - -KCL 工具链是 KCL 语言的工具集合,旨在提升 KCL 的批量迁移、编写、编译和测试的效率。 - -| 类别 | 工具名称 | 说明 | -| ---------- | ---------------------- | --------------------------------------------------------- | -| 主工具集 | **kcl** | kcl 命令行工具提供对基于 KCL 语言的配置编写、编译和运行。 | -| | kcl-test | 即将提供 | -| | kcl-fmt | kcl-fmt 工具提供对 KCL 代码的格式化 | -| | kcl-lint | kcl-lint 工具提供对 KCL 代码的 lint 检查和自动修复 | -| | kcl-doc | kcl-doc 工具提供对 KCL 代码的文档解析和生成 | -| | kcl-vet | 使用 KCL 代码校验诸如 JSON 和 YAML 的数据格式 | -| ide 插件集 | IntelliJ IDEA KCL 插件 | 提供 IntelliJ IDEA 平台的 KCL 编写、编译辅助 | -| | VS Code KCL 插件 | 提供 VS Code 平台的 KCL 编写、编译辅助 | diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/getting-started/install.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/getting-started/install.md deleted file mode 100644 index 74510232..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/getting-started/install.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -sidebar_position: 2 ---- - -# 安装 - -## 1. 安装 KCL - -### 二进制下载 - -KCL 的每个版本都包含各种操作系统和体系结构。这些二进制版本可以从 [Github](https://github.com/kcl-lang/kcl/releases/) 或者 [Gitee](https://gitee.com/kusionstack/kcl/releases) 手动下载并安装,下载完成后将 `{install-location}/kclvm/bin` 添加到环境变量 PATH 中。 - -> ⚠️ 如果您不能成功访问 Github, 也可以访问 Gitee 获得二进制进行安装 - -#### MacOS & Linux - -```bash -export PATH=$PATH:{install-location}/kclvm/bin -``` - -#### Windows - -```powershell -$env:PATH += ";{install-location}\kclvm\bin;" -``` - -### 使用脚本安装最新版本 - -#### MacOS - -将 KCL darwin 最新版本安装到 /usr/local/kclvm/bin - -```bash -curl -fsSL https://kcl-lang.io/script/install.sh | /bin/bash -``` - -#### Linux - -将 KCL linux 最新版本安装到 /usr/local/kclvm/bin - -```bash -wget -q https://kcl-lang.io/script/install.sh -O - | /bin/bash -``` - -#### Windows - -将 KCL windows 最新版本安装到 $Env:SystemDrive\kclvm\bin,并将该目录添加到用户 PATH 环境变量中。 - -```bash -powershell -Command "iwr -useb https://kcl-lang.io/script/install.ps1 | iex" -``` - -### Homebrew (MacOS) - -- 安装 - -```bash -brew install kcl-lang/tap/kcl -``` - -- 升级 - -```bash -brew upgrade kcl-lang/tap/kcl -``` - -- 卸载 - -```bash -brew uninstall kcl-lang/tap/kcl -``` - -### Scoop (Windows) - -首先安装 [Scoop](https://scoop.sh/), 然后通过如下命令安装 `kcl`: - -```bash -scoop bucket add kcl-lang https://github.com/kcl-lang/scoop-bucket.git -scoop install kcl-lang/kcl -``` - -### 使用 Go 安装 - -通过 `Go` 命令安装 (Go 要求 1.18+) - -```bash -go install kcl-lang.io/kcl-go/cmds/kcl-go@main -``` - -添加一个 kcl 命令的别名 (可选) - -```bash -alias kcl='kcl-go run' -``` - -> 注意:`kcl-go` 并不依赖是否安装了 `kcl`,但如果 PATH 中存在 `kcl`,`kcl-go` 将优先使用 `PATH` 中的 `kcl`。 - -### 使用 Docker 镜像安装 - -- 基本命令 - -```bash -docker run --rm -it kcllang/kcl -``` - -- 更新镜像 - -```bash -docker pull kcllang/kcl -``` - -### 注意 - -可以执行运行如下命令确保 KCL 已经正确安装 - -```bash -kcl -V -``` - -如果安装成功,输出可能为如下形式 (不同版本结果可能稍微不同): - -```bash -Version: {kcl version} -Platform: {your platform} -GitCommit: {git commit} -``` - -对于上述所有安装方式, 如果您想使用 [KCL Python 插件](/docs/reference/plugin/overview), 需要确保您已经安装了 Python 3.7+ 并将 python3 命令添加到您的 PATH 中。 - -## 2. 安装 KCL IDE 插件 - -### VS Code - -KCL 为 VS Code 本地版本提供了插件支持,并提供了高亮、自动补全、跳转、悬停、大纲等功能。您可以[点击这里](/docs/tools/Ide/vs-code)进行安装。 - -![Completion](/img/docs/tools/Ide/vs-code/Completion.gif) - -### IntelliJ IDEA - -从[这里](https://github.com/kcl-lang/intellij-kcl/releases)下载发行版,在 IntelliJ IDEA 中,点击 Preference -> plugins -> install Plugin from Disk... -> 选择 kcl-idea-plugin zip -> 重启 IDE。此插件需要 IntelliJ IDEA 2020.2+ diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/abstraction.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/abstraction.md deleted file mode 100644 index 7450d42e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/abstraction.md +++ /dev/null @@ -1,145 +0,0 @@ ---- -title: "抽象" -sidebar_position: 3 ---- - -## 什么是抽象 - -抽象是指一个实体的简化表示,它允许隐藏特定的具体细节,同时向程序员提供最相关的信息。每一个抽象都是为满足特定需求而定制的,并且可以极大地提高给定实体的可用性。在 KCL 的上下文中,抽象可以使代码更容易理解和维护,同时也可以简化用户界面。 - -需要注意的是,代码抽象并不是为了减少代码大小,而是为了提高代码的可维护性和可扩展性。在抽象代码的过程中,应考虑可重用性、可读性和可扩展性等因素,并根据需要对代码进行不断优化。 - -良好的抽象可以提供如下价值 - -1. 提供不同的焦点,不同角色和场景关注点分离。 -2. 屏蔽较低级别的细节,避免潜在的错误。 -3. 提升用户界面和自动化友好性。 - -KCL 自身可能不会评估用户定义模型抽象的合理性,但它提供了技术解决方案来帮助用户构建抽象。 - -## 使用 KCL 进行抽象 - -现在,让我们将 Docker Compose 和 Kubernetes 资源抽象为应用程序配置 - -`Docker Compose` 是一个用于定义和运行多容器 Docker 应用程序的工具。使用 Docker Compose,您可以在一个文件中定义应用程序的服务、网络和卷,然后使用它作为一个单元启动和停止应用程序。Docker Compose 通过处理网络、存储和其他基础设施问题的细节,简化了运行复杂的多容器应用程序的过程。 - -Kubernetes 清单是定义 Kubernete 对象(如 Pods、Deployments 和 Services)的 YAML 文件。清单提供了一种声明性的方法来定义应用程序的所需状态,包括副本数量、要使用的镜像和网络配置。Kubernetes 使用清单来创建和管理部署和运行应用程序所需的资源。 - -以下是一些参考资料,可以帮助了解更多关于 Docker Compose 和 Kubernetes 相关的信息: - -- [Docker Compose 文档](https://docs.docker.com/compose/) -- [Kubernetes 对象文档](https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/) - -以应用程序为中心的开发使开发人员能够专注于其工作负载的体系结构,而不是目标环境、基础设施或平台中的技术栈。我们用 `App` 结构定义了应用程序模型,然后使用 KCL CLI 将其翻译到多个平台,例如不同版本的 `Docker Compose` 或 `Kubernetes`。该应用程序模型旨在通过只需定义一个跨多个平台工作的 KCL 文件来减少开发人员的工作量和认知负荷。现在,让我们学习如何做到这一点。 - -### 1. 获取示例 - -首先,我们执行 git 命令获得用例 - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/abstraction -``` - -我们可以运行以下命令来显示配置。 - -```bash -cat main.k -``` - -输出为 - -```python -import .app - -app.App { - name = "app" - containers.nginx = { - image = "nginx" - ports = [{containerPort = 80}] - } - service.ports = [{ port = 80 }] -} -``` - -在上面的代码中,我们使用 `App` schema 定义了一个配置,其中我们配置了一个 `nginx` 容器,并开启 `80` 端口配置。 - -此外,KCL 允许开发人员以声明式的方式定义应用程序所需的资源,并允许生成特定于平台的配置文件,如 `docker_compose.yaml` 或 Kubernetes `manifests.yaml` 文件。接下来,让我们生成相应的配置。 - -### 2. 将应用配置转换为 Docker Compose 配置 - -如果我们想将应用程序配置转换为 Docker Compose 配置,我们可以简单地运行如下命令: - -```shell -kcl main.k docker_compose_render.k -``` - -输出为 - -```yaml -services: - app: - image: nginx - ports: - - published: 80 - target: 80 - protocol: TCP -``` - -### 3. 将应用配置转换为 Kubernetes Deployment and Service 资源清单 - -如果我们想将应用程序配置转换为 Kubernetes 清单,我们可以简单地运行如下命令: - -```shell -kcl main.k kubernetes_render.k -``` - -输出为 - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: app - labels: - app: app -spec: - replicas: 1 - selector: - matchLabels: - app: app - template: - metadata: - labels: - app: app - spec: - containers: - - name: nginx - image: nginx - ports: - - protocol: TCP - containerPort: 80 ---- -apiVersion: v1 -kind: Service -metadata: - name: app - labels: - app: app -spec: - selector: - app: app - ports: - - port: 80 - protocol: TCP -``` - -如果您想了解有关应用程序模型的更多信息,可以参考[此处](https://github.com/kcl-lang/kcl-lang.io/tree/main/examples/abstraction). - -## 小结 - -通过使用 KCL,我们能够分离模型的抽象和实现细节,允许将抽象模型映射到各种基础设施或平台。这是通过不同实现之间的灵活切换和 KCL 组合编译来实现的,以屏蔽配置差异,减轻认知负担。 - -## 更多信息 - -除了手动维护配置外,我们还可以使用 KCL API 将**自动配置更改能力**集成到我们的应用程序中。有关 KCL 自动化能力的相关说明,请参阅[此处](/docs/user_docs/guides/automation)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/automation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/automation.md deleted file mode 100644 index b8fa8d6f..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/automation.md +++ /dev/null @@ -1,201 +0,0 @@ ---- -title: "自动化" -sidebar_position: 6 ---- - -## 简介 - -在 KCL 中提供了很多自动化相关的能力,主要包括工具和多语言 API。 通过 `package_identifier : key_identifier`的模式支持对任意配置键值的索引,从而完成对任意键值的增删改查。比如下图所示修改某个应用配置的镜像内容,可以直接执行如下指令修改镜像,修改前后的 diff 如下图所示。 - -![](/img/blog/2022-09-15-declarative-config-overview/14-kcl-image-update.png) - -此外,KCL 的自动化能力也可以被集成到 CI/CD 中。 - -![](/img/blog/2022-09-15-declarative-config-overview/15-kcl-automation.png) - -## 使用 KCL 进行自动化 - -### 1. 获得示例 - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/automation -``` - -我们可以执行如下命令显示配置 - -```bash -cat main.k -``` - -输出为 - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "app" - replicas = 1 - labels.key = "value" -} -``` - -我们可以执行如下命令输出配置 - -```bash -kcl main.k -``` - -输出为 - -```yaml -app: - name: app - replicas: 1 - labels: - app: app - key: value -``` - -### 2. 使用 KCL CLI 进行自动化 - -KCL 允许使用通过 CLI `-O|--overrides` 参数修改配置模型中的值,这个参数通常由三个部分组成: 包名 `pkg`, 配置标识符 `identifier`, 配置属性 `attribute` 和覆盖值 `override_value` - -```bash -kcl main.k -O override_spec -``` - -- `override_spec`: 表示需要修改的配置模型字段和值的统一表示 - -```bash -override_spec: [[pkgpath] ":"] identifier ("=" value | "-") -``` - -- `pkgpath`: 表示需要修改标识符的包路径,通常为 `a.b.c` 的形式,对于 main 包,`pkgpath` 表示为 `__main__`, 可省略,省略不写时表示 main 包 -- `identifier`: 表示需要修改配置的标识符,通常为 `a.b.c` 的形式 -- `value`: 表示需要修改配置的值,可以是任意合法的 KCL 表达式,比如数字/字符串字面值,`list`/`dict`/`schema` 表达式等 -- `=`: 表示修改identifier的值 -- `-`: 表示删除 identifier 属性 - -请注意,当 `identifier` 多次出现时,修改/删除全部 `identifier` 的值 - -#### 修改配置 - -执行如下命令可以更新应用名称: - -```bash -kcl main.k -O app.name='new_app' -``` - -输出为 - -```yaml -app: - name: new_app - replicas: 1 - labels: - app: new_app - key: value -``` - -可以看出 `app` 的 `name` 属性的值被修改为了 `new_app` - -此外,当我们使用 KCL CLI `-d` 参数时,KCL 文件将同时修改为以下内容 - -```bash -kcl main.k -O app.name='new_app' -d -``` - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "new_app" - replicas = 1 - labels: {key = "value"} -} -``` - -#### 删除配置 - -执行如下命令可以删除 `labels` 中的 `key` 字段 - -```bash -kcl main.k -O app.labels.key- -``` - -输出为: - -```yaml -app: - name: app - replicas: 1 - labels: - app: app -``` - -执行如下命令 - -```bash -kcl main.k -O config.x- -``` - -输出结果为: - -```yaml -config: - x: 1 - y: s -``` - -### 3. 使用 KCL API 进行自动化 - -此外,我们还可以通过[多语言 API](/docs/reference/xlang-api/overview) 自动修改配置属性 - -以 RestAPI 为例 - -执行如下命令启动 RestAPI 服务端 - -```bash -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -通过如下命令 POST 命令请求配置修改服务 - -```bash -curl -X POST http://127.0.0.1:2021/api:protorpc/KclvmService.OverrideFile -H 'content-type: accept/json' -d '{ - "file": "main.k", - "specs": ["app.name=\"nginx\""] -}' -``` - -服务调用完成后,`main.k` 会被修改为如下形式: - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "nginx" - replicas = 1 - labels: { - "key" = "value" - } -} -``` - -## 小结 - -该文档介绍了KCL的自动化功能,包括工具和多语言 API。它支持对任何配置的键值进行索引,允许添加、删除、修改和查询任何键值。它也可以集成到 CI/CD 中。本文档提供了一个使用 KCL 自动化配置管理的示例,包括使用 KCL CLI/API 覆盖和删除配置。更多信息请参阅[此处](/docs/reference/lang/tour#KCL-cli-variable-Override)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/ci-integration/1-github-actions.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/ci-integration/1-github-actions.md deleted file mode 100644 index afb57d80..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/ci-integration/1-github-actions.md +++ /dev/null @@ -1,162 +0,0 @@ ---- -id: github-actions -sidebar_label: Github Actions ---- - -# Github Actions 集成 - -## 简介 - -在 GitOps 章节,我们介绍了如何将 KCL 与 GitOps 进行集成。在本文中,我们将继续提供 KCL 和 CI 集成的示例方案,希望通过使用容器、用于生成的持续集成 (CI) 和用于持续部署 (CD) 的 GitOps 来实现端到端应用程序开发流程。在此方案中,我们使用一个 Flask 应用和 Github Actions 将用作示例。 - -> 注意:你可以在此方案中使用任何容器化应用以及不同的 CI 系统如 Gitlab CI,Jenkins CI 等。 - -整体工作流程如下: - -- 应用代码开发并提交到提交到 GitHub 存储库 -- GitHub Actions 从应用代码生成容器镜像,并将容器镜像推送到 docker.io 容器注册表 -- GitHub Actions 根据 docker.io 容器注册表中容器镜像的版本号并同步更新 KCL 清单部署文件 - -## 具体步骤 - -### 1. 获得示例 - -我们将业务源码和部署清单放在不同仓库,可以分不同角色进行分别维护,实现关注点分离。 - -- 获得业务源码 - -```shell -git clone https://github.com/kcl-lang/flask-demo.git/ -cd flask-demo -``` - -这是一个使用 Python 编写的 Web 应用,我们可以使用应用目录的 `Dockerfile` 来生成这个应用的容器镜像,同时可以通过 Github CI 自动构建 `flask_demo` 镜像,CI 配置如下 - -```yaml -# This is a basic workflow to help you get started with Actions - -name: CI - -# Controls when the workflow will run -on: - # Triggers the workflow on push or pull request events but only for the main branch - push: - branches: [main] - pull_request: - branches: [main] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "build" - build: - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - - - name: Docker Login - uses: docker/login-action@v1.10.0 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - logout: true - - # Runs a set of commands using the runners shell - - name: build image - run: | - make image - docker tag flask_demo:latest ${{ secrets.DOCKER_USERNAME }}/flask_demo:${{ github.sha }} - docker push ${{ secrets.DOCKER_USERNAME }}/flask_demo:${{ github.sha }} - - # Trigger KCL manifest - - name: Trigger CI - uses: InformaticsMatters/trigger-ci-action@1.0.1 - with: - ci-owner: kcl-lang - ci-repository: flask-demo-kcl-manifests - ci-ref: refs/heads/main - ci-user: kcl-bot - ci-user-token: ${{ secrets.DEPLOY_ACCESS_TOKEN }} - ci-name: CI - ci-inputs: >- - image=${{ secrets.DOCKER_USERNAME }}/flask_demo - sha-tag=${{ github.sha }} -``` - -我们需要源码仓库的工作流自动触发部署清单仓库中的工作流,此时需要创建具有 Github CI 操作权限的 `secrets.DEPLOY_ACCESS_TOKEN` 以及 Docker Hub 镜像推送的账号信息 `secrets.DOCKER_USERNAME` 和 `secrets.DOCKER_PASSWORD`, 这些可以在 Github 仓库的 `Secrets and variables` 设置中进行配置,如下图所示 - -![](/img/docs/user_docs/guides/ci-integration/github-secrets.png) - -### 2. 提交应用代码 - -flask-demo 仓库提交代码后,Github 会自动构建容器镜像,并将制品推送到 Docker hub 中,会再触发 flask-demo-kcl-manifests 仓库的 Action,[通过 KCL 自动化 API](/docs/user_docs/guides/automation) 修改部署清单仓库中的镜像地址。现在让我们为 flask-demo 仓库创建一个提交,我们可以看到代码提交后触发业务仓库 Github CI 流程 - -![](/img/docs/user_docs/guides/ci-integration/app-ci.png) - -### 3. 配置自动更新 - -当业务仓库 Github CI 流程执行完成后,会自动在存放 KCL 资源配置的仓库触发一个 CI 自动更新配置并提交到 flask-demo-kcl-manifests main 分支,commit 信息如下 - -![](/img/docs/user_docs/guides/ci-integration/image-auto-update.png) - -- 我们可以获得部署清单源码进行编译验证 - -```shell -git clone https://github.com/kcl-lang/flask-demo-kcl-manifests.git/ -cd flask-demo-kcl-manifests -git checkout main && git pull && kcl -``` - -输出 YAML 为 - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - replicas: 1 - selector: - matchLabels: - app: flask_demo - template: - metadata: - labels: - app: flask_demo - spec: - containers: - - name: flask_demo - image: "kcllang/flask_demo:6428cff4309afc8c1c40ad180bb9cfd82546be3e" - ports: - - protocol: TCP - containerPort: 5000 ---- -apiVersion: v1 -kind: Service -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - type: NodePort - selector: - app: flask_demo - ports: - - port: 5000 - protocol: TCP - targetPort: 5000 -``` - -从上述配置可以看出资源的镜像确实自动更新为了新构建的镜像内容。此外,我们还可以使用 Argo CD KCL 插件 自动从 Git 存储库同步或从中拉取数据并将应用部署到 Kubernetes 集群。 - -## 小结 - -通过将 KCL 和 Github CI 集成,我们能够将任意的业务代码的产出容器化镜像进行自动化修改并部署配置,以实现端到端应用程序开发流程并提升研发部署效率。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/configuration.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/configuration.md deleted file mode 100644 index 5769d366..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/configuration.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -title: "配置" -sidebar_position: 1 ---- - -## 简介 - -配置是软件系统的一个重要方面,由于不断发展的业务需求、基础设施需求和其他因素,这些系统会不断发生变化。通常,快速改变这些系统的行为可能具有挑战性,尤其是当这样做需要昂贵且耗时的重建和重新部署过程时。在这种情况下,仅仅对业务代码进行更改可能是不够的。幸运的是,配置提供了一种低开销的方式来修改系统功能。 - -我们可以根据需要将静态配置存储在 JSON 或 YAML 等文件中。此外,配置也可以存储在高级语言中,从而实现更灵活的配置。这种语言可以进行编码、呈现和静态配置。KCL 是一种提供此类功能的配置语言。开发人员可以编写 KCL 代码来生成JSON/YAML 和其他配置。 - -## 使用 KCL 编写配置代码 - -KCL 的核心特性是其**建模**和**约束**能力,KCL 核心功能基本围绕 KCL 这个两个核心特性展开,对于代码而言(包括配置代码)都存在对配置数据约束的需求,比如类型约束、配置字段必选/可选约束、范围约束、不可变性约束等,这也是 KCL 致力于解决的核心问题之一。 - -现在我们已经了解了 KCL 的基本功能,让我们探索如何使用它来生成配置。 - -### 1. 获取示例 - -首先,执行如下命令获取示例 - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/configuration -``` - -我们可以执行如下命令显示配置代码 - -```shell -cat nginx.k -``` - -输出为: - -```python -schema Nginx: - """Schema for Nginx configuration files""" - http: Http - -schema Http: - server: Server - -schema Server: - listen: int | str # The attribute `listen` can be int type or a string type. - location?: Location # Optional, but must be non-empty when specified - -schema Location: - root: str - index: str - -nginx = Nginx { - http.server = { - listen = 80 - location = { - root = "/var/www/html" - index = "index.html" - } - } -} -``` - -### 2. 使用 KCL 生成 YAML - -执行如下命令: - -```bash -kcl nginx.k -``` - -我们可以获得如下 YAML 输出 - -```yaml -nginx: - http: - server: - listen: 80 - location: - root: /var/www/html - index: index.html -``` - -### 3. 为配置添加动态参数 - -此外,我们可以通过 KCL 内置函数 `option` 动态接收外部参数。例如,对于下面的 KCL 文件(db.k),我们可以使用命令行 `-D` 标志来接收外部动态参数。 - -```python -env: str = option("env") or "dev" # The attribute `env` has a default value "den" -database: str = option("database") -hosts = { - dev = "postgres.dev" - stage = "postgres.stage" - prod = "postgres.prod" -} -dbConfig = { - host = hosts[env] - database = database - port = "2023" - conn = "postgres://${host}:${port}/${database}" -} -``` - -```bash -# Use the `-D` flag to input external parameters. -kcl db.k -D database="foo" -``` - -输出为 - -```yaml -env: dev -database: foo -hosts: - dev: postgres.dev - stage: postgres.stage - prod: postgres.prod -dbConfig: - host: postgres.dev - database: foo - port: "2023" - conn: "postgres://postgres.dev:2023/foo" -``` - -## 小结 - -通过使用KCL,我们可以生成更低低级别的数据配置。此外啊,我们通过 `-D` 标志设置动态参数以满足不同的场景需求。有关更多 KCL 的功能和教程,请参阅[此处](/docs/reference/lang/tour)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/data-integration.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/data-integration.md deleted file mode 100644 index dfe18b03..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/data-integration.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: "数据集成" -sidebar_position: 4 ---- - -## 简介 - -在 KCL 中,不仅可以将 KCL 编写的配置代码编译输出为 YAML 格式的数据,还可以将 JSON/YAML 等数据直接嵌入到 KCL 语言当中。 - -## 使用 KCL 进行数据集成 - -### 1. 获得示例 - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/data-integration -``` - -### 2. YAML 集成 - -我们可以运行以下命令来显示 KCL YAML 集成配置。 - -```bash -cat yaml.k -``` - -```python -import yaml - -schema Server: - ports: [int] - -server: Server = yaml.decode("""\ -ports: -- 80 -- 8080 -""") -server_yaml = yaml.encode({ - ports = [80, 8080] -}) -``` - -在上述代码中,我们通过 KCL 内置的 `yaml` 模块以及其中的 `yaml.decode` 直接完成 YAML 数据的集成,并且使用 `Server` schema 对集成的 YAML 数据直接进行校验。此外,我们可以使用 `yaml.encode` 完成 YAML 数据的序列化。 - -我们通过如下命令可以获得配置输出: - -```shell -kcl yaml.k -``` - -输出为 - -```yaml -server: - ports: - - 80 - - 8080 -server_yaml: | - ports: - - 80 - - 8080 -``` - -### 3. JSON 集成 - -同样的,对于 JSON 数据,我们可以使用 `json.encode` 和 `json.decode` 函数以同样的方式进行数据集成。 - -我们可以运行以下命令来显示 KCL JSON 集成配置。 - -```bash -cat json.k -``` - -```python -import json - -schema Server: - ports: [int] - -server: Server = json.decode('{"ports": [80, 8080]}') -server_json = json.encode({ - ports = [80, 8080] -}) -``` - -执行命令输出为: - -```shell -kcl json.k -``` - -```yaml -server: - ports: - - 80 - - 8080 -server_json: '{"ports": [80, 8080]}' -``` - -## 小结 - -本文介绍了如何在 KCL 中进行数据集成,使用 KCL 内置的 yaml 和 json 包将 YAML 和 JSON 数据直接集成到 KCL 语言中,并使用相应的解码和编码功能对其进行验证和序列化。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/gitops/1-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/gitops/1-quick-start.md deleted file mode 100644 index e4888bd3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/gitops/1-quick-start.md +++ /dev/null @@ -1,141 +0,0 @@ ---- -id: gitops-quick-start -sidebar_label: 快速开始 ---- - -# 快速开始 - -## 简介 - -### 什么是 GitOps - -GitOps 是一种实现持续交付的现代方式。它的核心思想是拥有一个包含环境和应用程序配置的 Git 存储库。通过更改应用存储库中的文件,可以自动部署应用程序。应用 GitOps 的好处包括: - -- 提高生产力,持续交付可以加快部署时间。 -- 降低开发人员部署的障碍。通过推送代码而不是容器配置,开发人员可以在不知道其内部实现的情况下轻松部署 Kubernetes 集群和应用。 -- 追踪变更记录。使用 Git 管理配置使每一项更改都具有可跟踪性,从而增强审计跟踪。 - -### 将 KCL 与 ArgoCD 一起使用 - -将 [KCL](https://github.com/kcl-lang/kcl) 与 [ArgoCD](https://github.com/argoproj/argo-cd) 等 GitOps 工具一起使用具有如下好处: - -- 通过 KCL 语言的[抽象能力](/docs/user_docs/guides/abstraction)和可编程能力可以帮助我们**简化复杂的 Kubernetes 部署配置文件**,降低手动编写 YAML 文件的错误率,消除多余的配置模版,提升多环境多租户的配置扩展能力,同时提高配置的可读性和可维护性。 -- KCL 允许开发人员以声明式的方式定义应用程序所需的资源,通过将 KCL 和 ArgoCD 相结合可以帮助我们更好地实现**基础设施即代码(IaC)**,提高部署效率,简化应用程序的配置管理。 -- ArgoCD 可以**自动化**地实现应用程序的连续部署,并提供友好的可视化界面。 - -使用 GitOps,开发人员和运维团队可以通过分别修改应用和配置代码来管理应用程序的部署,GitOps 工具链将自动同步对配置的更改,从而实现持续部署并确保一致性。如果出现问题,可以使用 GitOps 工具链快速回滚。 - -## 快速开始 - -### 1. 获取示例 - -首先,我们执行 git 命令获得用例 - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/gitops -``` - -我们可以运行以下命令来显示配置 - -```bash -cat config/main.k -``` - -The output is - -```python -import .app - -config = app.App { - name = "kcl-guestbook-ui" - containers.guestbook = { - image = "gcr.io/heptio-images/ks-guestbook-demo:0.2" - ports = [{containerPort = 80}] - } - service.ports = [{ port = 80 }] - service.type = "LoadBalancer" -} -``` - -在上述代码中,我们定义使用 `App` schema 定义了应用的配置,其中我们配置了一个镜像为 `gcr.io/heptio-images/ks-guestbook-demo:0.2` 容器,并启用了 `80` 端口。 - -### 2. 安装 Kubernetes 和 GitOps 工具 - -#### 配置 Kubernetes 集群和 ArgoCD 控制器 - -- 安装 [K3d](https://github.com/k3d-io/k3d) 并创建一个集群 - -```bash -k3d cluster create mycluster -``` - -> 注意:你可以在此方案中使用其他方式创建您自己的 Kubernetes 集群,如 kind, minikube 等。 - -- 安装 [ArgoCD](https://github.com/argoproj/argo-cd/releases/). - -```bash -kubectl create namespace argocd -kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml -``` - -- 安装 ArgoCD KCL 插件 - -```bash -kubectl apply -f ./install/kcl-cmp.yaml && kubectl -n argocd patch deploy/argocd-repo-server -p "$(cat ./install/patch-argocd-repo-server.yaml)" -``` - -- 通过 `kubectl get` 命令查看 argocd 控制器容器是否初始化完成进入运行(Running)状态。 - -```bash -kubectl get pod -n argocd -l app.kubernetes.io/name=argocd-repo-server -``` - -- 通过如下命令打开 ArgoCD UI - -```bash -kubectl port-forward svc/argocd-server -n argocd 8080:443 -``` - -- 打开浏览器 `https://localhost:8080` 输入用户名 "admin" 和密码登陆 ArgoCD UI,密码可以通过如下命令得到: - -```bash -kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d -``` - -#### 安装 ArgoCD 客户端工具 - -- 安装 [ArgoCD 客户端工具](https://github.com/argoproj/argo-cd/releases) - -- 使用用户名 "admin" 和刚才得到的密码登陆 - -```bash -argocd login localhost:8080 -``` - -通过如下命令创建一个 ArgoCD KCL 应用 - -```bash -argocd app create guestbook \ ---repo https://github.com/kcl-lang/kcl-lang.io \ ---path examples/gitops/config \ ---dest-namespace default \ ---dest-server https://kubernetes.default.svc \ ---config-management-plugin kcl-v1.0 -``` - -如果创建成功,您可以看到如下输出: - -```bash -application 'guestbook' created -``` - -> 如果您使用的是私有存储库,则在执行 create 命令之前,需要使用私钥凭据配置专用私有存储库访问权限。请参阅[这里](https://argo-cd.readthedocs.io/en/stable/user-guide/private-repositories/)以获取更多详细信息。 - -通过 ArgoCD UI,您可以看到创建的应用程序尚未同步,您可以手动进行配置同步或设置为自动同步。 - -![](/img/docs/user_docs/guides/gitops/argocd-kcl-app.jpg) - -有关同步策略的更多信息,可以请参阅[这里](https://argo-cd.readthedocs.io/en/stable/user-guide/sync-options/) - -![](/img/docs/user_docs/guides/gitops/argocd-kcl-app-dashboard.jpg) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/schema-definition.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/schema-definition.md deleted file mode 100644 index f62d7815..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/schema-definition.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: "模型定义" -sidebar_position: 3 ---- - -## 简介 - -KCL 的核心场景是写配置和校验,因此 KCL 被设计之初的一个核心特性就是**建模**,对应到 KCL 的关键字 `schema`,`schema` 可以被用于定义结构和约束,比如字段的类型,默认值,字段的范围和各种其他约束等内容。此外,使用 KCL schema 定义的结构可以反过来用于验证实现、验证输入(JSON、YAML 等结构化数据)或生成代码(生成多语言结构体、OpenAPI 等)。 - -## 使用 KCL 定义结构和约束 - -### 1. 获得示例 - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/definition -``` - -我们可以执行如下命令显示配置 - -```bash -cat main.k -``` - -输出为 - -```python -import .app_module # A relative path import - -app: app_module.App { - domainType = "Standard" - containerPort = 80 - volumes = [ - { - mountPath = "/tmp" - } - ] - services = [ - { - clusterIP = "None" - $type = "ClusterIP" - } - ] -} -``` - -我们将 `App` 模型放入单独的 `app_module.k` 中,在需要时我们可以在 `main.k` 中使用 `import` 关键字进行模块化管理,比如下面的文件结构 - -``` -. -├── app_module.k -└── main.k -``` - -其中 `app_module.k` 的内容为 - -```python -schema App: - domainType: "Standard" | "Customized" | "Global" - containerPort: int - volumes: [Volume] - services: [Service] - - check: - 1 <= containerPort <= 65535 - -schema Service: - clusterIP: str - $type: str - - check: - clusterIP == "None" if $type == "ClusterIP" - -schema Volume: - container: str = "*" # `container` 的默认值为 "*" - mountPath: str - - check: - mountPath not in ["/", "/boot", "/home", "dev", "/etc", "/root"] -``` - -在上面的文件中。在其中,我们使用 `schema` 关键字定义了三个模型 `App`,`Service` 和 `Volume`。并且 `App` 模型具有四个属性 `domainType`, `containerPort`, `volumes` 和 `services`,其中 - -- `domainType` 的类型为字符串字面值联合类型,与“枚举”类似,这表明 `domainType` 的值只能取 `"Standard"`, `"Customized"` 和 `"Global"` 中的一个 -- `containerPort` 的类型为整数 `int`, 此外我们使用 `check` 关键字定义了其取值范围 1 ~ 65535 -- `services` 的类型为 `Service` 列表类型,`Service`,并且我们用 `?` 标记了它是一个可选属性,这意味着我们可以不为其赋值。 -- `volumes` 的类型为 `Volume` 列表类型,并且我们用 `?` 标记了它是一个可选属性,这意味着我们可以不为其赋值。 - -### 2. 输出配置 - -我们可以使用如下命令行可以获得 `app` 实例的 YAML 输出 - -```shell -kcl main.k -``` - -输出为 - -```yaml -app: - domainType: Standard - containerPort: 80 - volumes: - - container: "*" - mountPath: /tmp - services: - - clusterIP: None - type: ClusterIP -``` - -## 小结 - -KCL 是一种用于定义配置和约束的语言,其核心功能是使用 schema 关键字进行建模,schema 允许定义具有属性、默认值、范围检查和其他约束的结构。使用 KCL schema 定义的结构可以用于验数据或生成代码。该文档演示了如何使用 schema 定义模型,使用 import 导入模型进行模块化管理,并使用 kcl 命令输出已定义结构实例的 YAML 配置。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/validation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/validation.md deleted file mode 100644 index 6e879c47..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/validation.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: "校验" -sidebar_position: 2 ---- - -## 简介 - -验证是校验数据是否准确、可靠并满足某些要求或限制的过程,包括检查数据的完整性、一致性、准确性和相关性。进行数据验证是为了确保数据符合其预期目的,并能有效使用。 - -我们可以使用 KCL 及其校验工具手动或自动进行数据验证,以确保数据的一致性。 - -## 使用 KCL 校验数据 - -除了使用 KCL 代码生成 JSON/YAML 等配置格式,KCL 还支持对 JSON/YAML 数据进行格式校验。作为一种配置语言,KCL 在验证方面几乎涵盖了 OpenAPI 的所有功能。在 KCL 中可以通过一个结构定义来约束配置数据,同时支持通过 check 块自定义约束规则,在 schema 中书写校验表达式对 schema 定义的属性进行校验和约束。通过 check 表达式可以非常清晰简单地校验输入的 JSON/YAML 是否满足相应的 schema 结构定义与 check 约束。 - -### 1. 获得示例 - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/validation -``` - -我们可以执行如下命令显示配置 - -```bash -cat schema.k -``` - -输出为 - -```python -schema User: - name: str - age: int - message?: str - data: Data - labels: {str:} - hc: [int] - - check: - age > 10, "age must > 10" - -schema Data: - id: int - value: str -``` - -在 schema 中,我们可以使用 `check` 关键字来编写每个 schema 属性的验证规则。`check` 块中的每一行都对应于一个条件表达式。当满足条件时,验证成功。条件表达式后面可以跟 `, "报错信息"`,以指示检查失败时要给用户显示的消息。 - -综上所述,KCL Schema 中支持的校验类型为: - -| 校验类型 | 使用方法 | -| -------- | ---------------------------------------------------------- | -| 范围校验 | 使用 `<`, `>` 等比较运算符 | -| 正则校验 | 使用 `regex` 系统库中的 `match` 等方法 | -| 长度校验 | 使用 `len` 内置函数,可以求 `list/dict/str` 类型的变量长度 | -| 枚举校验 | 使用字面值联合类型 | -| 非空校验 | 使用 schema 的可选/必选属性 | -| 条件校验 | 使用 check if 条件表达式 | - -### 2. 验证数据 - -新建一个名为 `data.json` 的 JSON 配置文件: - -```json -{ - "name": "Alice", - "age": 18, - "message": "This is Alice", - "data": { - "id": 1, - "value": "value1" - }, - "labels": { - "key": "value" - }, - "hc": [1, 2, 3] -} -``` - -执行如下命令获得校验结果 - -```bash -kcl-vet data.json schema.k -``` - -## 小结 - -KCL 是一种配置语言,通过其结构定义和用户定义的约束规则来支持数据验证。KCL Schema 中支持的验证类型包括范围、正则表达式、长度、枚举、可选/必需和条件。并且可以使用 KCL 验证工具或在此基础上构建的可视化产品来验证数据。 - -## 未来计划 - -KCL 校验能力的提升将逐渐围绕"静态化"方面展开工作,即在编译时,结合形式化验证的能力直接分析得出数据是否满足约束条件、约束条件是否冲突等结论,并且可以通过 IDE 实时透出约束错误,而无需在运行时发现错误。 - -我们还期望 KCL Schema 和约束可以作为一个包来管理(这个包只有 KCL 文件)。例如,Kubernetes 模型和约束可以开箱即用。用户可以生成配置或验证现有配置,并且可以通过 KCL 继承简单地扩展用户想要的模型和约束。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-kusion/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-kusion/_category_.json deleted file mode 100644 index 89134bd9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-kusion/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KusionStack", - "position": 13 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1.json deleted file mode 100644 index a9e8bfe5..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "sidebar.user_docs.category.Get Started": { - "message": "快速开始" - }, - "sidebar.user_docs.category.Introduction": { - "message": "简介" - }, - "sidebar.user_docs.category.User Guide": { - "message": "用户手册" - }, - "sidebar.user_docs.guides.category.Automation": { - "message": "自动化" - }, - "sidebar.user_docs.category.Configuration": { - "message": "配置" - }, - "sidebar.user_docs.category.Data Integration": { - "message": "数据集成" - }, - "sidebar.user_docs.category.Package Management": { - "message": "包管理工具" - }, - "sidebar.user_docs.category.How to": { - "message": "如何使用" - }, - "sidebar.user_docs.category.Schema Definition": { - "message": "模型定义" - }, - "sidebar.user_docs.category.Validation": { - "message": "验证" - }, - "sidebar.user_docs.category.Concepts": { - "message": "核心概念" - }, - "sidebar.user_docs.category.FAQ": { - "message": "常见问答" - }, - "sidebar.reference.category.Tutorial": { - "message": "教程" - }, - "sidebar.reference.category.Code Lab": { - "message": "代码实验室" - }, - "sidebar.reference.category.Spec": { - "message": "语言规范" - }, - "sidebar.reference.category.Errors and Warnings": { - "message": "错误与警告" - }, - "sidebar.reference.category.Types": { - "message": "类型系统" - }, - "sidebar.reference.category.System Package": { - "message": "系统模块" - }, - "sidebar.reference.category.Plugin System": { - "message": "插件系统" - }, - "sidebar.reference.category.Multi-Language": { - "message": "多语言集成" - }, - "sidebar.reference.category.Cheat Sheet": { - "message": "备忘表" - }, - "sidebar.reference.category.Package Management": { - "message": "包管理工具" - }, - "sidebar.reference.category.Command Reference": { - "message": "命令参考" - }, - "sidebar.reference.category.Advanced-Concepts": { - "message": "进阶概念" - }, - "sidebar.reference.category.Best-Practices": { - "message": "最佳实践" - }, - "sidebar.tools.category.Command Line Tools": { - "message": "命令行工具" - }, - "sidebar.tools.category.KCL Tools": { - "message": "语言工具" - }, - "sidebar.tools.category.OpenAPI Tools": { - "message": "OpenAPI 工具" - }, - "sidebar.community.category.Community": { - "message": "简介" - }, - "sidebar.community.category.Types": { - "message": "类型系统" - }, - "sidebar.community.category.Contribution Guide": { - "message": "贡献指南" - }, - "sidebar.community.category.Release Policy": { - "message": "发布策略" - }, - "sidebar.docs.category.GitOps": { - "message": "GitOps", - "description": "The label for category GitOps in sidebar docs" - }, - "sidebar.docs.category.CI Integration": { - "message": "CI 集成", - "description": "The label for category CI Integration in sidebar docs" - }, - "sidebar.user_docs.category.GitOps": { - "message": "GitOps", - "description": "The label for category GitOps in sidebar user_docs" - }, - "sidebar.user_docs.category.CI Integration": { - "message": "CI 集成", - "description": "The label for category CI Integration in sidebar user_docs" - }, - "sidebar.docs.category.Mutate or Validate Kubernetes Manifests": { - "message": "编辑或验证 Kubernetes 资源", - "description": "The label for category Mutate or Validate Kubernetes Manifests in sidebar docs" - }, - "sidebar.user_docs.category.Mutate or Validate Kubernetes Manifests": { - "message": "编辑或验证 Kubernetes 资源", - "description": "The label for category Mutate or Validate Kubernetes Manifests in sidebar user_docs" - }, - "sidebar.docs.category.Secret Management": { - "message": "敏感信息管理", - "description": "The label for category Secret Management in sidebar docs" - }, - "sidebar.user_docs.category.Secret Management": { - "message": "敏感信息管理", - "description": "The label for category Secret Management in sidebar user_docs" - } -} \ No newline at end of file diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/error/exception.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/error/exception.md deleted file mode 100644 index cd18995f..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/error/exception.md +++ /dev/null @@ -1,1584 +0,0 @@ ---- -title: "KCL 错误与警告" -linkTitle: "KCL 错误与警告" -type: "docs" -weight: 2 -description: KCL 错误与警告 ---- - -# KCL 错误与警告 - -文档的此部分中的文章介绍了由 KCL 生成的诊断错误和警告消息。 - -**注意:** -**KCL 可以报告多种错误和警告。找到错误或警告后,KCL 可能会对代码意向作出假设并尝试继续,以便可以同时报告更多问题。 如果工具做出错误假设,则后续错误或警告可能不适应与当前 KCL 程序。 因此,纠正项目中的问题时,请先纠正第一个错误或警告,然后重新运行获取新的错误信息。 一个修补程序可能会导致后续错误消失。** - -此部分文档的主要内容包括: - -[KCL 语法错误 (E1xxx)](#11-kcl-%E8%AF%AD%E6%B3%95%E9%94%99%E8%AF%AF-e1xxx) : 如果 KCL 在当前 KCL 程序中发现了非法的 KCL 语法,KCL 就会停止运行并输出 KCL 程序语法错误的提示信息. - -[KCL 编译错误 (E2xxx)](#12-kcl-%E7%BC%96%E8%AF%91%E9%94%99%E8%AF%AF-e2xxx) : 如果 KCL 在一个不包含语法错误的 KCL 程序中发现了与 KCL 语义不符的代码,KCL 就会停止运行并输出编译错误的提示信息。 - -[KCL 运行时错误 (E3xxx)](#13-kcl-%E8%BF%90%E8%A1%8C%E6%97%B6%E9%94%99%E8%AF%AF-e3xxx) : KCL 程序通过编译后会生成 KCL 字节码,如果 KCL 在执行 KCL 字节码过程中出现错误,KCL 就会停止运行并输出运行时错误的提示信息. - -[KCL 编译警告 (W2xxx)](#14-kcl-%E7%BC%96%E8%AF%91%E8%AD%A6%E5%91%8A-w2xxx) : 当 KCL 发现可能导致运行失败的 KCL 代码,KCL 不会立即停止运行,但是会输出潜在错误的警告提示。 - -## 1.1 KCL 语法错误 (E1xxx) - -KCL 会出现的语法错误信息如下表所示: - -| ewcode | KCL exception | messages | -| ------ | ------------------------------------------------------------------- | ----------------------- | -| E1001 | [InvalidSyntaxError](#111-invalidsyntaxerror-e1001) | Invalid syntax | -| E1002 | [KCLTabError](#112-kcltaberror-e1002) | Tab Error | -| E1003 | [KCLIndentationError](#113-kclindentationerror-e1003) | Indentation Error | -| E1I37 | [IllegalArgumentSyntaxError](#114-illegalargumentsyntaxerror-e1i37) | Illegal argument syntax | - -### 1.1.1 InvalidSyntaxError [E1001] - -如果在运行 KCL 时遇到错误: - -- `InvalidSyntaxError`, 对应的 encode 为 `E1001` - -那么此时 KCL 程序中出现了 - -- 非法的 KCL 语法。 - -可能出现错误的 KCL 程序片段如下: - -```python -a, b = 1, 2 # 通过 “=” 赋值多个变量在KCL中是非法的。 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> /syntax_error/general/multiple_assign/case0/main.k:1:2 - | -1 | a, b = 1, 2 # Multiple assign is illegal in KCL syntax - | ^ expected statement - | -``` - -### 1.1.2 KCLTabError - -如果在运行 KCL 时遇到错误: `KCLTabError` - -那么此时 KCL 程序中出现了 - -- Tab 与空格混用的问题。KCL 中禁止在代码缩进中混用 Tab 和空格。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - name: str # 通过tab表示缩进 - age: int # 通过四个空格标识缩进, - # 在当前运行环境中的四个空格与tab不同 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> File /syntax_error/tab/tab_error_0/main.k:6:5 - | -3 | age: int = 1 - | ^ inconsistent use of tabs and spaces in indentation - | -``` - -可以尝试以下步骤来修复这个错误: - -- 在 KCL 程序中全部使用 Tab 或者全部使用四个空格,不要混用。 - -### 1.1.3 KCLIndentationError - -如果在运行 KCL 时遇到错误: `KCLIndentationError` - -那么此时 KCL 程序中出现了 - -- 程序缩进错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - name: str # 使用一个tab或者四个空格表示缩进 - age: int # KCL不支持使用三个空格表示缩进 - info: str # KCL不支持使用两个空格表示缩进 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> /syntax_error/indent/indent_error_0/main.k:3:4 - | -3 | age: int # three white spaces are illegal - | ^ unindent 3 does not match any outer indentation level - | -``` - -可以尝试以下步骤来修复这个错误: - -- 在 KCL 程序中全部使用 Tab 或者全部使用四个空格来表示缩进。 - -### 1.1.4 IllegalArgumentSyntaxError - -如果在运行 KCL 时遇到错误: `IllegalArgumentSyntaxError` - -那么此时 KCL 程序中出现了 - -- 参数语法错误 - -可能出现错误的 KCL 程序片段如下: - -```python -# KCL中带有keyword的参数必须出现在不带有keyword参数后面 -# 带有keyword的参数: type="list", default={"key": "value"} -# 不带有keyword的参数: "key1" -a = option(type="list", default={"key": "value"}, "key1") -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> /option/type_convert_fail_2/main.k:3:57 - | -3 | a = option(type="list", default={"key": "value"}, "key1") - | ^ positional argument follows keyword argument - | -``` - -可以尝试以下步骤来修复这个错误: - -- KCL 中带有 keyword 的参数必须出现在不带有 keyword 参数后面, 参数正常顺序: - -```python -func(input_1, ..., input_n, param_with_key_1 = input_with_key_1, ..., param_with_key_n = input_with_key_n) -``` - -## 1.2 KCL 编译错误 (E2xxx) - -KCL 会出现的编译错误信息如下表所示: - -| ewcode | KCL exception | messages | -| ------ | ----------------------------------------------------------------------- | --------------------------------------------------- | -| E2F04 | [CannotFindModule](#121-cannotfindmodule-e2f04) | Cannot find the module | -| E2F05 | [FailedLoadModule](#122-failedloadmodule-e2f05) | Failed to load module | -| E2H13 | [UnKnownDecoratorError](#123-unknowndecoratorerror-e2h13) | UnKnown decorator | -| E2H14 | [InvalidDecoratorTargetError](#124-invaliddecoratortargeterror-e2h14) | Invalid Decorator Target | -| E2C15 | [MixinNamingError](#125-mixinnamingerror-e2c15) | Illegal mixin naming | -| E2C16 | [MixinStructureIllegal](#126-mixinstructureillegal-e2c16) | Illegal mixin structure | -| E2B17 | [CannotAddMembersComplieError](#127-cannotaddmemberscomplieerror-e2b17) | Cannot add members to a schema | -| E2B20 | [IndexSignatureError](#128-indexsignatureerror-e2b20) | Invalid index signature | -| E2G22 | [TypeComplieError](#129-typecomplieerror-e2g22) | The type got is inconsistent with the type expected | -| E2L23 | [CompileError](#1210-compileerror-e2l23) | A complie error occurs during compiling | -| E2L25 | [KCLNameError](#1211-kclnameerror-e2l25) | Name Error | -| E2L26 | [KCLValueError](#1212-kclvalueerror-e2l26) | Value Error | -| E2L27 | [KCLKeyError](#1213-kclkeyerror-e2l27) | Key Error | -| E2L28 | [UniqueKeyError](#1214-uniquekeyerror-e2l28) | Unique key error | -| E2A29 | [KCLAttributeComplieError](#1215-kclattributecomplieerror-e2a29) | Attribute error occurs during compiling | -| E2D32 | [MultiInheritError](#1216-multiinheriterror-e2d32) | Multiple inheritance is illegal | -| E2D34 | [IllegalInheritError](#1217-illegalinheriterror-e2d34) | Illegal inheritance | -| E2I36 | [IllegalArgumentComplieError](#1218-illegalargumentcomplieerror-e2i36) | Illegal argument during compiling | -| E3L41 | [ImmutableCompileError](#1219-immutablecompileerror-e3l41) | Immutable variable is modified | - -### 1.2.1 CannotFindModule [E2F04] - -如果在运行 KCL 时遇到错误: - -- `CannotFindModule`, 对应的 encode 为 `E2F04` - -那么此时 KCL 程序中出现了 - -- 无法找到导入模块错误 - -可能出现错误的 KCL 程序片段如下: - -```python -import .some0.pkg1 as some00 # some0 not found in package - -Name1 = some00.Name # some0.pkg1.name -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2F04]: CannotFindModule - --> import_abs_fail_0/app-main/main.k:1:1 - | -1 | import .some0.pkg1 as some00 # some0 not found in package - | Cannot find the module .some0.pkg1 - | -``` - -可以尝试以下步骤来修复这个错误: - -- 在 import 路径下添加导入模块文件。 - -### 1.2.2 FailedLoadModule [E2F05] - -如果在运行 KCL 时遇到错误: - -- `FailedLoadModule`, 对应的 encode 为 `E2F05` - -那么此时 KCL 程序中出现了 - -- 导入模块加载错误 - -可以尝试以下步骤来修复这个错误: - -- 查看文件是否可读 -- 查看文件是否为 kcl 文件 - -### 1.2.3 UnKnownDecoratorError - -如果在运行 KCL 时遇到错误: - -- `UnKnownDecoratorError`, 对应的 encode 为 `E2H13` - -那么此时 KCL 程序中出现了 - -- 未知的装饰器错误 - -可能出现错误的 KCL 程序片段如下: - -```python -@err_deprecated # 这是一个非法的装饰器 -schema Person: - firstName: str = "John" - lastName: str - name: str - -JohnDoe = Person { - name: "deprecated" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> deprecated/unknown_fail_1/main.k:1:2 - | -1 | @err_deprecated # 这是一个非法的装饰器 - | ^ UnKnown decorator err_deprecated - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查装饰器是否存在。 - -### 1.2.4 InvalidDecoratorTargetError [E2H14] - -如果在运行 KCL 时遇到错误: - -- `InvalidDecoratorTargetError`, 对应的 encode 为 `E2H14` - -那么此时 KCL 程序中出现了 - -- 无效的装饰器目标错误。 - -可以尝试以下步骤来修复这个错误: - -- 检查使用装饰器的 KCL 代码是否出现异常。 - -### 1.2.5 MixinNamingError [E2C15] - -如果在运行 KCL 时遇到错误: - -- `MixinNamingError`, 对应的 encode 为 `E2C15` - -那么此时 KCL 程序中出现了 - -- Mixin 命名错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - firstName: str - lastName: str - fullName: str - -schema Fullname: # Mixin的名称应该以Mixin结尾 - fullName = "{} {}".format(firstName, lastName) - -schema Scholar(Person): - mixin [Fullname] - school: str - -JohnDoe = Scholar { - "firstName": "John", - "lastName": "Doe", - "fullName": "Doe Jon" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2D34]: IllegalInheritError - --> mixin/invalid_name_failure/main.k:10:12 - | -10 | mixin [Fullname] - | ^ illegal schema mixin object type 'Fullname' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 如果 schema 是一个 mixin,那么这个 schema 的名称应该以 Mixin 结尾。 - -### 1.2.6 MixinStructureIllegal [E2C16] - -如果在运行 KCL 时遇到错误: - -- `MixinStructureIllegal`, 对应的 encode 为 `E2C16` - -那么此时 KCL 程序中出现了 - -- Mixin 结构错误。 - -可以尝试以下步骤来修复这个错误: - -- 检查作为 Mixin 的 Schema 的结构。 - -### 1.2.7 CannotAddMembersComplieError [E2B17] - -如果在运行 KCL 时遇到错误: - -- `CannotAddMembersComplieError`, 对应的 encode 为 `E2B17` - -那么此时 KCL 程序中出现了 - -- 使用 Schema 中不存在的成员。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Girl: - gender: str = "female" - -alice = Girl { - "first": "alice", # Schema中没有成员“first” - "last": " Green", # Schema中没有成员“last” - "age": 10 # Schema中没有成员“age” -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:5:5 - | -5 | "first": "alice", - | ^ Cannot add member 'first' to schema 'Girl' - | - -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:6:5 - | -6 | "last": " Green", - | ^ Cannot add member 'last' to schema 'Girl' - | - -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:7:5 - | -7 | "age": 10 - | ^ Cannot add member 'age' to schema 'Girl' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 为 Schema 添加缺少的成员。 -- 不要使用 Schema 中不存在的成员。 - -### 1.2.8 IndexSignatureError [E2B20] - -如果在运行 KCL 时遇到错误: - -- `IndexSignatureError`, 对应的 encode 为 `E2B20` - -那么此时 KCL 程序中出现了 - -1. 在一个 schema 中使用多个索引签名。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Data: - [str]: str - [str]: int # 在同一个schema中使用了多个索引签名 - -data = Data { - name: "test" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError ----> index_signature/fail_1/main.k:3:5 - | -3 | [str]: int - | 5 ^ only one index signature is allowed in the schema - | -``` - -可以尝试以下步骤来修复这个错误: - -- 删除多余的索引签名。 - -2. schema 中索引签名的名称与 schema 中其他属性的名称存在同名冲突。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Data: - name: str # name - [name: str]: str # 已有名称为name的schema属性 - -data = Data { - name: "test" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: IndexSignatureError - --> index_signature/fail_2/main.k:3:5 - | -3 | [name: str]: str # the same name with the above attribute - | ^ index signature attribute name 'name' cannot have the same name as schema attributes - | -``` - -可以尝试以下步骤来修复这个错误: - -- 删除 schema 中出现同名冲突的属性或者索引签名,或者为它们更换不同的名称。 - -3. schema 索引签名的类型与 schema 实例化的属性类型冲突。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Data: - [str]: int - -data = Data { - name: "test" # 索引签名为 [str]:int, "test"的类型不是int. -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> index_signature/fail_3/main.k:5:5 - | -5 | name: "test" # Conflict with [str]:int, "test" is a string. - | ^ expected int, got str(test) - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 schema 索引签名的类型与 schema 实例中的属性类型是否一致。 - -4. Schema 中的属性与索引签名冲突 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Data: - count: int # int 和 str 冲突 - [str]: str - -data = Data { - count: 1 -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: IndexSignatureError - --> index_signature/fail_4/main.k:2:5 - | -2 | count: int - | ^ the type 'int' of schema attribute 'count' does not meet the index signature definition [str]: str - | -``` - -可以尝试以下步骤来修复这个错误: - -- 调整 Schema 属性或者调整索引签名。 - -### 1.2.9 TypeComplieError [E2G22] - -如果在运行 KCL 时遇到错误: - -- `TypeComplieError`, 对应的 encode 为 `E2G22` - -那么此时 KCL 程序中出现了 - -- 静态类型检查错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - firstName: str - lastName: int - -JohnDoe = Person { - "firstName": "John", - "lastName": "Doe" # Schema中定义lastName: int -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> type/type_fail_0/main.k:7:5 - | -7 | "lastName": "Doe" # Type Error,lastName: int,“Doe” is a string. - | ^ expected int, got str(Doe) - | - - --> type/type_fail_0/main.k:3:5 - | -3 | lastName: int - | ^ variable is defined here, its type is int, but got str(Doe) - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查赋给某个变量的值的类型与这个变量的类型是否一致。 - -### 1.2.10 CompileError [E2L23] - -如果在运行 KCL 时遇到错误: - -- `CompileError`, 对应的 encode 为 `E2L23` - -那么此时 KCL 程序中出现了 - -1. 不支持的类型合并 - -可能出现错误的 KCL 程序片段如下: - -```python -_data = [1, 2, 3] -_data |= "value" -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> union/fail/fail_1/main.k:2:1 - | -2 | _data |= "value" - | ^ unsupported operand type(s) for |: '[int]' and 'str(value)' - | -``` - -1. 不支持的操作符类型 - -可能出现错误的 KCL 程序片段如下: - -```python -a = None -b = 1 + None # KCL中不支持None和int之间进行+操作 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> operator/operator_fail_0/main.k:2:5 - | -2 | b = 1 + None # Unsupport operand type + for int and None - | ^ unsupported operand type(s) for +: 'int(1)' and 'NoneType' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 调整操作符号,使其同时支持两个操作数的类型。 -- 调整操作数,使其同时符合操作符号的约束。 - -1. 没有定义的变量 - -可能出现错误的 KCL 程序片段如下: - -```python -a = 1 -b = "${c + 1}" # 'c' 没有定义 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> var_not_define_fail_0/main.k:2:8 - | -2 | b = "${c + 1}" # 'c' is not defined - | ^ name 'c' is not defined - | -``` - -可以尝试以下步骤来修复这个错误: - -- 对未定义的变量进行定义。 -- 在表达式中去掉对未定义变量的操作。 - -4. 无效的赋值表达式 - -可能出现错误的 KCL 程序片段如下: - -```python -# pkg.k -a = 1 - -# main.k -import pkg -pkg.a |= 2 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> pkg_inplace_modify_1/main.k:3:1 - | -6 | pkg |= 2 - | ^ unsupported operand type(s) for |: 'module 'pkg'' and 'int(2)' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查赋值表达式的内容。 - -1. 无效的字符串表达式 - -可能出现错误的 KCL 程序片段如下: - -```python -a = 1 -b = "${b = a + 1}" # Invalid string interpolation expression -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> invalid_format_value_fail_0/main.k:2:5 - | -2 | b = "${b = a + 1}" - | 5 ^ invalid string interpolation expression 'b = a + 1' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查字符串表达式的内容。 - -1. 无效的循环变量 - -可能出现错误的 KCL 程序片段如下: - -```python -data = {"key1": "value1", "key2": "value2"} -dataLoop = [i for i, j, k in data] # the number of loop variables can only be 1 or 2 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> dict/invalid_loop_var_fail_0/main.k:2:25 - | -2 | dataLoop = [i for i, j, k in data] # the number of loop variables can only be 1 or 2 - | ^ the number of loop variables is 3, which can only be 1 or 2 - | -``` - -### 1.2.11 KCLNameError [E2L25] - -如果在运行 KCL 时遇到错误: - -- `KCLNameError`, 对应的 encode 为 `E2L25` - -那么此时 KCL 程序中出现了 - -- 试图访问的变量名不存在 - -可以尝试以下步骤来修复这个错误: - -- 检查报错信息中出现的变量是否存在。 - -### 1.2.12 KCLValueError [E2L26] - -如果在运行 KCL 时遇到错误: - -- `KCLValueError`, 对应的 encode 为 `E2L26` - -那么此时 KCL 程序中出现了 - -- 值错误,传给参数的类型不正确 - -可以尝试以下步骤来修复这个错误: - -- 检查参数的具体类型。 - -### 1.2.13 KCLKeyError [E2L27] - -如果在运行 KCL 时遇到错误: - -- `KCLKeyError`, 对应的 encode 为 `E2L27` - -那么此时 KCL 程序中出现了 - -- 使用了 dict 中不存在的 key 时引发的 key 错误 - -可以尝试以下步骤来修复这个错误: - -- 检查字典中是否存在 key。 - -### 1.2.14 UniqueKeyError [E2L28] - -如果在运行 KCL 时遇到错误: - -- `UniqueKeyError`, 对应的 encode 为 `E2L28` - -那么此时 KCL 程序中出现了 - -- 变量同名或重复定义。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - name: str = "kcl" - age: int = 1 - -schema Person: - aa: int - -x0 = Person{} -x1 = Person{age:101} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L28]: UniqueKeyError - --> /schema/same_name/main.k:5:8 - | -5 | schema Person: - | ^ Unique key error name 'Person' - | - - --> /schema/same_name/main.k:1:8 - | -1 | schema Person: - | ^ The variable 'Person' is declared here - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查出现错误的名称是否已经被使用。 - -### 1.2.15 KCLAttributeComplieError [E2A29] - -如果在运行 KCL 时遇到错误: - -- `KCLAttributeComplieError`, 对应的 encode 为 `E2A29` - -那么此时 KCL 程序中出现了 - -- Schema 的属性错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -# pkg -schema A: - field_A: str - -# main -import pkg as p - -a = p.D + 1 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> /import/module/no_module_attr_fail_0/main.k:4:5 - | -4 | a = p.D + 1 - | ^ module 'pkg' has no attribute D - | -``` - -可以尝试以下步骤来修复这个错误: - -- 在使用 Schema 属性时检查这个属性是否存在。 - -### 1.2.16 MultiInheritError [E2D32] - -如果在运行 KCL 时遇到错误: - -- `MultiInheritError`, 对应的 encode 为 `E2D32` - -那么此时 KCL 程序中出现了 - -- 多继承错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - firstName: str - lastName: str - -schema KnowledgeMixin: - firstName: int - subject: str - -schema Scholar(KnowledgeMixin, Person): # KCL中不支持多继承 - school: str -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> /schema/inherit/multi_inherit_fail_1/main.k:9:30 - | -9 | schema Scholar(KnowledgeMixin, Person): - | ^ expected one of [")"] got , - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查程序的继承结构,KCL 中不支持多继承。 - -### 1.2.17 IllegalInheritError [E2D34] - -如果在运行 KCL 时遇到错误: - -- `IllegalInheritError`, 对应的 encode 为 `E2D34` - -那么此时 KCL 程序中出现了 - -- 不合法的继承结构 - -可能出现错误的 KCL 程序片段如下: - -```python -schema FullnameMixin: - fullName = "{} {}".format(firstName, lastName) - -schema Scholar(FullnameMixin): # KCL中不支持Schema继承Mixin - school: str -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError -Invalid value for top level arguments -``` - -可以尝试以下步骤来修复这个错误: - -- KCL 中 Schema 支持单继承 Schema。 - -### 1.2.18 IllegalArgumentComplieError [E2I36] - -如果在运行 KCL 时遇到错误: - -- `IllegalArgumentComplieError`, 对应的 encode 为 `E2I36` - -那么此时 KCL 程序中出现了 - -- 参数错误 - -可能出现错误的 KCL 程序片段如下: - -```python -a = option("key") - -# kcl main.k -D key=value= -# key=value= is an illegal expression -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError -Invalid value for top level arguments -``` - -可以尝试以下步骤来修复这个错误: - -- 检查通过命令设置的 KCL option 参数是否为合法参数。 - -### 1.2.19 ImmutableCompileError [E3L41] - -如果在运行 KCL 时遇到错误: - -- `ImmutableCompileError`, 对应的 encode 为 `E3L41` - -那么此时 KCL 程序中出现了 - -- 不可变量的值发生改变 - -可能出现错误的 KCL 程序片段如下: - -```python -a = 2147483646 -a += 1 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: ImmutableError - --> augment_assign/main.k:2:1 - | -2 | a += 1 - | ^ Immutable variable 'a' is modified during compiling - | - - --> augment_assign/main.k:1:1 - | -1 | a = 2147483646 - | ^ The variable 'a' is declared here firstly - | -note: change the variable name to '_a' to make it mutable -``` - -可以尝试以下步骤来修复这个错误: - -- 将被改变的不可变量设置为私有或者去掉对不可变量值的改动。 - -## 1.3 KCL 运行时错误 (E3xxx) - -KCL 会出现的运行时错误信息如下表所示: - -| ewcode | KCL exception | messages | -| ------ | ----------------------------------------------------------------------- | --------------------------------------------------- | -| E3F06 | [RecursiveLoad](#131-recursiveload-e3f06) | Recursively loading module | -| E3K04 | [FloatOverflow](#132-floatoverflow-e3k04) | Float overflow | -| E3K09 | [IntOverflow](#133-intoverflow-e3k09) | Integer overflow | -| E3N11 | [DeprecatedError](#134-deprecatederror-e3n11) | Deprecated error | -| E3A30 | [KCLAttributeRuntimeError](#135-kclattributeruntimeerror-e3a30) | Attribute error occurs at runtime | -| E3G21 | [TypeRuntimeError](#136-typeruntimeerror-e3g21) | The type got is inconsistent with the type expected | -| E3B17 | [SchemaCheckFailure](#137-schemacheckfailure-e3b17) | Schema check is failed to check condition | -| E3B19 | [CannotAddMembersRuntimeError](#138-cannotaddmembersruntimeerror-e3b19) | Cannot add members to a schema | -| E3M38 | [EvaluationError](#139-evaluationerror-e3m38) | Evaluation failure | -| E3M39 | [InvalidFormatSpec](#1310-invalidformatspec-e3m39) | Invalid format specification | -| E3M40 | [KCLAssertionError](#1311-kclassertionerror-e3m40) | Assertion failure | -| E3M44 | [ImmutableRuntimeError](#1312-immutableruntimeerror-e3m44) | Immutable variable is modified | -| E2D33 | [CycleInheritError](#1313-cycleinheriterror-e2d33) | Cycle Inheritance is illegal | -| E3M42 | [KCLRecursionError](#1314-kclrecursionerror-e3m42) | Recursively reference | - -### 1.3.1 RecursiveLoad [E3F06] - -如果在运行 KCL 时遇到错误: - -- `RecursiveLoad`, 对应的 encode 为 `E3F06` - -那么此时 KCL 程序中出现了 - -- 循环导入错误 - -可能出现错误的 KCL 程序片段如下: - -``` -# module.k -import main # module.k 导入了 main.k - -print('module') - -# main.k -import module # main.k 导入了 module.k - -print('main') -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /import/recursive_import_fail/main.k:4 - | -2 | import module # main.k imports module.k - | ^ There is a circular import reference between module main and module - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查包的导入部分是否存在循环导入的问题。 - -### 1.3.2 FloatOverflow [E3K04] - -如果在运行 KCL 时遇到错误: - -- `FloatOverflow`, 对应的 encode 为 `E3K04` - -那么此时 KCL 程序中出现了 - -- 浮点数溢出 - -可能出现错误的 KCL 程序片段如下: - -```python -uplimit = 3.402823466e+39 -epsilon = 2.220446049250313e-16 -a = uplimit * (1 + epsilon) - -# kcl main.k -r -d -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /range_check_float/overflow/number_0/main.k:3:1 - | -3 | a = uplimit * (1 + epsilon) - | 3.4028234660000003e+39: A 32-bit floating point number overflow - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查浮点数的值是否在 KCL 支持的数字范围内。 - -### 1.3.3 IntOverflow [E3K09] - -如果在运行 KCL 时遇到错误: - -- `IntOverflow`, 对应的 encode 为 `E3K09` - -那么此时 KCL 程序中出现了 - -- 整数溢出 - -可能出现错误的 KCL 程序片段如下: - -```python -_a = 9223372036854775807 -_a += 1 - -# kcl test.k -d -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /range_check_int/augment_assign_fail_1/main.k:2:1 - | -2 | _a += 1 - | 9223372036854775808: A 64 bit integer overflow - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查整数的值是否在 KCL 支持的数字范围内。 - -### 1.3.4 DeprecatedError [E3N11] - -如果在运行 KCL 时遇到错误: - -- `DeprecatedError`, 对应的 encode 为 `E3N11` - -那么此时 KCL 程序中出现了 - -- 使用废弃代码 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - firstName: str = "John" - lastName: str - @deprecated(version="1.16", reason="use firstName and lastName instead", strict=True) - name: str - -JohnDoe = Person { - name: "deprecated" # name已经被过时,并且strict设置为True -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /range_check_float/overflow/number_0/main.k:7:1 - | -7 | JohnDoe = Person { - | name was deprecated since version 1.16, use firstName and lastName instead - | -``` - -可以尝试以下步骤来修复这个错误: - -- strict 设置为 True 时无法使用过时的代码,可以将 strict 设置为 False,将不会出现错误,而是输出一个警告。 -- 调整代码,不使用已经过时的代码。 - -### 1.3.5 KCLAttributeRuntimeError [E3A30] - -如果在运行 KCL 时遇到错误: - -- `KCLAttributeRuntimeError`, 对应的 encode 为 `E3A30` - -那么此时 KCL 程序中出现了 - -- 属性错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -import math - -a = math.err_func(1) # err_func is not found in math -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /import/module/no_module_attr_fail_2/main.k:3:5 - | -3 | a = math.err_func(1) # err_func is not found in math - | ^ module 'math' has no attribute err_func - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查属性调用是否正确。 - -### 1.3.6 TypeRuntimeError [E3G21] - -如果在运行 KCL 时遇到错误: - -- `TypeRuntimeError`, 对应的 encode 为 `E3G21` - -那么此时 KCL 程序中出现了 - -- 类型检查错误 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - name: str = "Alice" - -_personA = Person {} -_personA |= {"name" = 123.0} # name: str = "Alice" -personA = _personA -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /fail/fail_4/main.k:2:1 - | -2 | name: str = "Alice" - | expect str, got float - | -``` - -可以尝试以下步骤来修复这个错误: - -- 停止错误的类型合并或者将类型调整为 KCL 支持的类型合并。 - -### 1.3.7 SchemaCheckFailure [E3B17] - -如果在运行 KCL 时遇到错误: - -- `SchemaCheckFailure`, 对应的 encode 为 `E3B17` - -那么此时 KCL 程序中出现了 - -- Schema 中的 check 条件冲突 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - lastName: str - age: int - check: - age < 140, "age is too large" - -JohnDoe = Person { - "lastName": "Doe", - "age": 1000 # Schema中的check条件为: age < 140 -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /check_block/check_block_fail_1/main.k:7:11 - | -7 | JohnDoe = Person { - | ^ Instance check failed - | - - --> /check_block/check_block_fail_1/main.k:5:1 - | -5 | age < 140, "age is too large" - | Check failed on the condition - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 Schema 的属性与 check 中的条件是否符合 - -### 1.3.8 CannotAddMembersRuntimeError [E3B19] - -如果在运行 KCL 时遇到错误: - -- `CannotAddMembersRuntimeError`, 对应的 encode 为 `E3B19` - -那么此时 KCL 程序中出现了 - -- 访问 Schema 中不存在的成员 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Name: - name: str - -schema Person: - name: Name - -person = Person { - name.err_name: "Alice" # err_name is not found in schema Name -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /nest_var/nest_var_fail_1/main.k:8:5 - | -8 | name.err_name: "Alice" # err_name is not found in schema Name - | ^ Cannot add member 'err_name' to schema 'Name' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 为 Schema 添加不存在的成员。 -- 访问 Schema 中存在的成员。 - -### 1.3.9 EvaluationError [E3M38] - -如果在运行 KCL 时遇到错误: - -- `EvaluationError`, 对应的 encode 为 `E3M38` - -那么此时 KCL 程序中出现了 - -- 当 KCL 中数值计算过程出现了错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -_list1 = [1, 2, 3] # _list1 is a variable, and its type can only be known at runtime -_list2 = None # _list1 is a variable, and its type can only be known at runtime - -result2 = _list1 + _list2 # list + NoneType is illegal -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /datatype/list/add_None_fail/main.k:1 - | -4 | result2 = _list1 + _list2 # list + NoneType is illegal - | can only concatenate list (not "NoneType") to list - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查表达式中是否存在变量为 None,或者非法的计算过程。 - -### 1.3.10 InvalidFormatSpec [E3M39] - -如果在运行 KCL 时遇到错误: - -- `InvalidFormatSpec`, 对应的 encode 为 `E3M39` - -那么此时 KCL 程序中出现了 - -- 非法的字符串格式 - -可能出现错误的 KCL 程序片段如下: - -```python -a = 1 -b = 1 -data = "${a: #js}" + " $$ " # KCL插值字符串中,#js是非法的 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /datatype/str_interpolation/invalid_format_spec_fail_0/main.k:3 - | -3 | data = "${a: #js}" + " $$ " # #js is illegal string - | ^ #js is a invalid format spec - | -``` - -可以尝试以下步骤来修复这个错误: - -- 将非法 String 调整为 KCL 标准支持的 String。 - -### 1.3.11 KCLAssertionError [E3M40] - -如果在运行 KCL 时遇到错误: - -- `KCLAssertionError`, 对应的 encode 为 `E3M40` - -那么此时 KCL 程序中出现了 - -- Assert False - -可能出现错误的 KCL 程序片段如下: - -```python -assert False -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /assert/invalid/fail_0/main.k:1 - | -1 | assert False - | - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 Assert 的条件,Assert 条件为 False 时,就会出现此类错误,去掉 Assert 语句或改变条件为 True。 - -### 1.3.12 ImmutableRuntimeError [E3M44] - -如果在运行 KCL 时遇到错误: - -- `ImmutableRuntimeError`, 对应的 encode 为 `E3M44` - -那么此时 KCL 程序中出现了 - -- 不可变量的值发生改变 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - final firstName : str - lastName : str - - -schema Scholar(Person): - firstName = "CBA" - - -scholar = Scholar { - "firstName": "ABC" # firstName in schema Person is final. -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /final/fail_lazy_init_0/main.k:8:1 - | -8 | scholar = Scholar { - | attribute 'lastName' of Scholar is required and can't be None or Undefined - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 final 修饰的不可变量是否出现了赋值等改变值的操作。 - -### 1.3.13 CycleInheritError [E2D33] - -如果在运行 KCL 时遇到错误: - -- `CycleInheritError`, 对应的 encode 为 `E2D33` - -那么此时 KCL 程序中出现了 - -- 循环继承 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Parent(Son): - parent_field: str - -schema Son(GrandSon): - son_field: str - -schema GrandSon(Parent): - grandson_field: str - -parent = Parent { - parent_field: "" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /inherit/cycle_inherit_fail_1/main.k:7:8 - | -7 | schema GrandSon(Parent): - | ^ There is a circular reference between schema GrandSon and Parent - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 Schema 的继承关系,避免出现 A 继承 B,B 继承 A 的情况。 - -### 1.3.14 KCLRecursionError [E3M42] - -如果在运行 KCL 时遇到错误: - -- `KCLRecursionError`, 对应的 encode 为 `E3M42` - -那么此时 KCL 程序中出现了 - -- 循环引用 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Parent(Son): - parent_field: str - son: Son = Son { # Parent has attribute Son - parent: Parent { - parent_field: "123" - } - } - -schema Son: - son_field: str - parent: Parent = Parent { # Son has attribute Parent - son: Son { - son_field: "123" - } - } - -parent = Parent { - parent_field: "", -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -thread 'main' has overflowed its stack -fatal runtime error: stack overflow -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 Schema 中的属性成员,避免出现循环引用的问题。 - -## 1.4 KCL 编译警告 (W2xxx) - -KCL 中的编译警告如下表所示: - -| ewcode | KCL exception | messages | -| ------ | ------------------------------------------------- | ------------------ | -| W2K04 | [FloatUnderflow](#141-floatunderflow-w2k08) | Float underflow | -| W2P10 | [InvalidDocstring](#142-invaliddocstring-w2p10) | Invalid docstring | -| W2N12 | [DeprecatedWarning](#143-deprecatedwarning-w2n12) | Deprecated warning | - -### 1.4.1 FloatUnderflow [W2K08] - -如果在运行 KCL 时遇到错误: - -- `FloatUnderflow`, 对应的 encode 为 `W2K08` - -可以尝试以下步骤来修复这个错误: - -- 检查浮点数的值是否在 KCL 支持的数字范围内。 - -### 1.4.2 InvalidDocstring [W2P10] - -如果在运行 KCL 时遇到错误: - -- `InvalidDocstring`, 对应的 encode 为 `W2P10` - -那么此时 KCL 程序中出现了 - -- 无效的 doc 内容 - -可以尝试以下步骤来修复这个错误: - -- 请按照 KCL 标准编写 doc。 - -### 1.4.3 DeprecatedWarning [W2N12] - -如果在运行 KCL 时遇到错误: - -- `DeprecatedWarning`, 对应的 encode 为 `W2N12` - -那么此时 KCL 程序中出现了 - -- 过时的代码警告 - -可以尝试以下步骤来修复这个错误: - -- 尽量不要使用已经过时的代码。如果将 strict 设置为 True,KCL 将会输出错误,并停止运行。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/tour.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/tour.md deleted file mode 100644 index 93a080e5..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/tour.md +++ /dev/null @@ -1,3208 +0,0 @@ ---- -title: "KCL 之旅" -sidebar_position: 1 ---- - -本文展示了如何使用 KCL 的核心特性,包含变量、运算符、schema 和库,前提是您有使用其他语言编程的经验。KCL 主要受 Python 启发,了解 Python 对学习 KCL 非常有帮助。 - -### 重要概念 - -在学习 KCL 语言时,请牢记以下事实和概念: - -- KCL 是一种配置策略语言。它为编写配置和策略提供了简单且自洽的语言设计和库支持。它不能用于应用程序开发或其他通用编程语言(GPL)支持的场景。 -- KCL 吸收了经典 **OOP** 的元素,并且提供了**类型**、**复用**和**合并**等简单、开发人员友好、可靠且利于传播的配置编写实践。 -- KCL 更倾向于**不可变性**,建议使用**合并**来添加增量的变更。不可变性降低了副作用,例如不可预测的问题。 -- KCL 的 **schema** 结构体定义了严格的属性和静态类型,并且支持表达式验证。**schema** 结构体主要由带类型的属性、schema 上下文和检查块构成。 -- KCL 的 **config** 是一个类 **JSON** 表达式,通过它我们可以复用 schema 的完整定义。KCL 通过分离 schema 和 config 来提供定义和配置的能力。 -- KCL 的 **rule** 是一个书写规则约束表达式的结构,可用于数据校验和策略编写。 -- KCL 的代码文件以包(目录)和模块(文件)的形式进行管理。同一包中的 schema 彼此可见;跨包的数据需要通过 **import 语句**导入。包级变量虽然可以导出,但是它们不能被其他包修改。 -- KCL 语法定义主要使用声明式表达式,并且只提供少量必要的声明式语句,例如 import、 if...else、assert、assignment 以及 schema。 -- 没有主函数,每个 `.k` 文件可以作为单独的配置文件执行。 -- 支持**内置函数**和**插件**以简化编写。 - -### 关键字 - -下表列出了 KCL 语言的关键字。 - -```txt -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -### 标识符 - -在 KCL 中, 标识符是标识一个值的名称,可以带有选择器。 - -- 标识符由字母、数字、下划线或前缀 `$` 组成。 -- 标识符不能与关键字重复,除非它们有 `$` 前缀。 -- 标识符不得包含任何嵌入的空格或符号。 -- 可以在标识符中的任何位置使用字母和下划线。 -- 数字不能放在标识符的第一位。 -- `$` 字符只能放在标识符的第一个位置。 - -示例: - -```python -x -a -b1 -b_2 -_c -$if -``` - -为了简化限定标识符(例如 `pkg.type`)的定义,我们还定义了 `qualified identifier`: - -示例: - -```python -pkg.a -``` - -在 `qualified identifier` 中的包名必须通过 `import` 关键字导入。 - -#### 标识符前缀 - -使用 `$` 前缀符号定义关键字标识符。 - -```python -$if = 1 -$else = "s" -``` - -请注意,非关键字标识符是否有 `$` 符号都是同样的效果。 - -```python -_a = 1 -$_a = 2 # equal to `_a = 2` -``` - -### 变量 - -以下是如何创建并实例化变量的例子: - -```python -name = "Foo" # Declare a variable named `name` and its value is a string literal "Foo" -``` - -它对应了如下 YAML 输出: - -```yaml -name: Foo -``` - -在 KCL 中,我们可以通过定义包级变量将变量导出为配置数据。使其直接、清晰、可维护。导出的变量是不可变的。因此一旦声明它,就无法对其进行修改,例如,假设我们有一个名为 `example.k` 的配置文件,变量 `name` 在声明后就禁止修改,就像标准的命令式语言一样。 - -```python -name = "Foo" # exported - -... - -name = "Bar" # error: a exported declaration variable can only be set once. -``` - -作为补充,我们可以在模块级别定义一个非导出变量,这个变量是可变的,不会显示在 YAML 输出当中。 - -```python -_name = "Foo" # _ variables are not output to YAML and are mutable -_name = "Bar" -``` - -请注意,变量的名称不能为 `True`、`False`、`None` 或者 `Undefined`,因为它们与 KCL 内置的名称常量之间存在二义性。 - -```python -False = 1 # Error -True = False # Error -None = Undefined # Error -Undefined = None # Error -``` - -### 内置类型 - -KCL 支持以下类型: - -- 数字 -- 字符串 -- 布尔 -- 列表 -- 字典 - -#### 数字 - -KCL 的数字类型有两种形式: - -- 64 位有符号整数。值的范围为 -9223372036854775808~9223372036854775807. -- 64 位浮点数,遵循 IEEE 754 标准。我们不建议在配置中使用 float 类型,我们可以使用字符串代替并在运行时进行解析。 - -整数和浮点数都支持基本运算符,例如 `+`,`-`,`/` 和 `*`,而复杂的运算,例如 `abs()`, `ceil()` 和 `floor()`,都是通过内置的数学库来支持。 - -整数是不带小数点的数字。以下是一些定义整数的例子: - -```python -a = 1 -b = -1 -c = 0x10 # hexadecimal literal -d = 0o10 # octal literal -e = 010 # octal literal -f = 0b10 # binary literal -g = int("10") # int constructor -``` - -如果一个数字包含小数点,则它是浮点数。以下是一些浮点数的示例: - -```python -a = 1.10 -b = 1.0 -c = -35.59 -d = 32.3e+18 -f = -90. -h = 70.2E-12 -i = float("112") # float constructor -``` - -内置数学库可用于数字类型: - -```python -import math - -assert abs(-40) == 40 -assert round(70.23456) == 70 -assert min(80, 100, 1000) == 80 -assert max(80, 100, 1000) == 1000 -assert sum([0,1,2]) == 3 -assert math.ceil(100.12) == 101.0 -assert math.floor(100.12) == 100.0 -assert math.pow(100, 2) == 10000.0 -``` - -KCL 默认使用 64 位数字类型。我们可以在 KCL 命令行使用 `-r` 参数执行严格的 32 位范围检查。 - -```bash -kcl main.k -r -d -``` - -请注意,为了性能考虑该功能只能在 `debug` 模式中使用。 - -##### 单位字面值 - -在 KCL 中,我们可以给一个整数添加如下的单位后缀,这不影响它的真实值。 - -- 通用整形和定点数: `P`, `T`, `G`, `M`, `K`, `k`, `m`, `u`, `n` -- 2 的幂: `Pi`, `Ti`, `Gi`, `Mi`, `Ki` - -```python -# SI -n = 1n # 1e-09 -u = 1u # 1e-06 -m = 1m # 1e-03 -k = 1k # 1000 -K = 1K # 1000 -M = 1M # 1000000 -G = 1G # 1000000000 -T = 1T # 100000000000 -P = 1P # 1000000000000000 -# IEC -Ki = 1Ki # 1024 -Mi = 1Mi # 1024 ** 2 -Gi = 1Gi # 1024 ** 3 -Ti = 1Ti # 1024 ** 4 -Pi = 1Pi # 1024 ** 5 -``` - -此外,我们还可以使用定义在 `units` 模块中的单位常量: - -```python -import units - -n = 1 * units.n # 1e-09 -u = 1 * units.u # 1e-06 -m = 1 * units.m # 1e-03 -k = 1 * units.k # 1000 -K = 1 * units.K # 1000 -M = 1 * units.M # 1000000 -G = 1 * units.G # 1000000000 -T = 1 * units.T # 1000000000000 -P = 1 * units.P # 1000000000000000 -# IEC -Ki = 1 * units.Ki # 1024 -Mi = 1 * units.Mi # 1024 ** 2 -Gi = 1 * units.Gi # 1024 ** 3 -Ti = 1 * units.Ti # 1024 ** 4 -Pi = 1 * units.Pi # 1024 ** 5 -``` - -我们还可以使用定义在 `units` 模块内的整数和单位字符串之间的转换函数 - -```python -import units -# SI -K = units.to_K(1000) # "1K" -M = units.to_M(1000000) # "1M" -G = units.to_G(1000000000) # "1G" -T = units.to_T(1000000000000) # "1T" -P = units.to_P(1000000000000000) # "1P" -# IEC -Ki = units.to_Ki(1024) # "1Ki" -Mi = units.to_Mi(1024 ** 2) # "1Mi" -Gi = units.to_Gi(1024 ** 3) # "1Gi" -Ti = units.to_Ti(1024 ** 4) # "1Ti" -Pi = units.to_Pi(1024 ** 5) # "1Pi" -``` - -```python -import units -# SI -K = units.to_K(int("1M")) # "1000K" -M = units.to_M(int("1G")) # "1000M" -G = units.to_G(int("1T")) # "1000G" -T = units.to_T(int("1P")) # "1000T" -P = units.to_P(int("10P")) # "10P" -# IEC -Ki = units.to_Ki(int("1Mi")) # "1024Ki" -Mi = units.to_Mi(int("1Gi")) # "1024Mi" -Gi = units.to_Gi(int("1Ti")) # "1024Gi" -Ti = units.to_Ti(int("1Pi")) # "1024Ti" -Pi = units.to_Pi(int("10Pi")) # "10Pi" -``` - -单位类型定义在 `units` 模块中,单位类型的值不能进行任何四则运算。 - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -x0: NumberMultiplier = 1M # Ok -x1: NumberMultiplier = x0 # Ok -x2 = x0 + x1 # Error: unsupported operand type(s) for +: 'number_multiplier(1M)' and 'number_multiplier(1M)' -``` - -我们可以使用 `int()`、`float()` 和 `str()` 函数将数值单位类型转换为数字类型或字符串类型。 - -```python -a: int = int(1Ki) # 1024 -b: float = float(1Ki) # 1024.0 -c: str = str(1Mi) # "1Mi" -``` - -#### 字符串 - -字符串是一个不可变的 Unicode 字符序列。我们可以使用单引号或双引号创建字符串: - -```python -'allows embedded "double" quotes' # Single quotes -"allows embedded 'single' quotes" # Double quotes -'''Three single quotes''', """Three double quotes""" # Triple quoted -``` - -三引号用于定义多行字符串。 - -```python -"""This is a long triple quoted string -may span multiple lines. -""" -``` - -请注意,KCL 的单引号和双引号字符串的使用几乎没有区别。唯一可以简化的是,我们不需要在单引号字符串中转义双引号,也不需要在双引号中转义单引号。 - -```python -'This is my book named "foo"' # Don’t need to escape double quotes in single quoted strings. -"This is my book named 'foo'" # Don’t need to escape single quotes in double quoted strings. -``` - -我们可以使用 `+` 操作符连接字符串: - -```python -x = 'The + operator ' + 'works, as well.' -``` - -我们可以使用 `str` 内置函数将 int 或 float 转为字符串: - -```python -x = str(3.5) # "3.5" -``` - -可以使用很多内置的字符串函数: - -```python -x = "length" -assert len(x) == 6 # True -assert x.capitalize() == "Length" -assert x.count("gt") == 1 -assert x.endswith("th") == True -assert x.find("gth") == 3 -assert "{} {}".format("hello", "world") == 'hello world' -assert x.index("gth") == 3 -assert x.isalnum() == True -assert x.isalpha() == True -assert "123456".isdigit() == True -assert x.islower() == True -assert " ".isspace() == True -assert "This Is Title Example".istitle() == True -assert x.isupper() == False -assert "|".join(["a", "b", "c"]) == "a|b|c" -assert "LENGTH".lower() == "length" -assert ' spacious '.lstrip() == 'spacious ' -assert x.replace("th", "ht") == "lenght" -assert "lengthlength".rfind("le") == 6 -assert "lengthlength".rindex("le") == 6 -assert "length length".rsplit() == ["length", "length"] -assert "length ".rstrip() == "length" -assert "length length".split() == ["length", "length"] -assert 'ab c\n\nde fg\rkl\r\n'.splitlines() == ['ab c', '', 'de fg', 'kl'] -assert "length".startswith('len') == True -assert "***length***".strip('*') == "length" -assert "length length".title() == "Length Length" -assert x.upper() == "LENGTH" -``` - -格式化字符串有两种使用方法: 使用 `"{}".format()` 内置函数, 或者使用花括号指定变量并使用 `$` 标记取变量值。在 KCL 中叫做**插值字符串**。在下面的例子中,`a` 和 `b` 的值都是 `"hello world"`。 - -此外,要序列化的变量可以以特殊的数据格式提取,例如 YAML 或 JSON。在这种情况中,`#yaml` 或 `#json` 可以包含在花括号中。 - -具体来说,当 `$` 符号本身需要出现在**插值字符串**中,需要使用 `$$` 转义。或者使用 `+` 符号连接 `$` 符号和插值字符串来避免转义。在以下示例中,`c` 和 `c2` 的值都是 `$hello world$`。 - -```python -world = "world" -a = "hello {}".format(world) # "hello world" -b = "hello ${world}" # "hello world" -c = "$$hello ${world}$$" # "$hello world$" -c2 = "$" + "hello ${world}" + "$" # "$hello world$" - -myDict = { - "key1" = "value1" - "key2" = "value2" -} - -d = "here is myDict in json: ${myDict: #json}" -# d: 'here is myDict in json: {"key1": "value1", "key2": "value2"}' - -e = "here is myDict in yaml:\n${myDict: #yaml}" -# e: | -# here is myDict in yaml: -# key1: value1 -# key2: value2 -``` - -此外,我们可以在上面的示例代码输出 **YAML 字符串** 中看到一些符号,例如 `|`、`>`、`+`、`-`。 - -- `|` 表示 **块文字样式**,指示块内换行符的行为方式。 -- `>` 表示块标量中的**块折叠样式**,换行符将被空格替换。 -- `+` 和 `-` 是 **block chomping 指示符**,用于控制字符串末尾的换行符。 默认值 **clip** 在字符串的末尾放置一个换行符。 要删除所有换行符,请通过在样式指示符 `|` 或 `>` 后面添加 `-` 来**删除**它们。 clip 和 strip 都忽略块末尾实际有多少换行符; 在样式指示符后面添加一个 `+` 来**保留**它们。 - -例如,**strip 块文字样式** yaml 字符串是 - -```yaml -example: |- - Several lines of text, - with some "quotes" of various 'types', - and also a blank line: - - plus another line at the end. -``` - -结果为: - -```plain -Several lines of text, -with some "quotes" of various 'types', -and also a blank line: - -plus another line at the end. -``` - -更多信息可见 [Yaml Multiline String](https://yaml-multiline.info/) 和 [YAML Specification v1.2](https://yaml.org/spec/1.2.1/) 。 - -##### 原始字符串 - -KCL 原始字符串是通过在字符串字面值前加上 `'r'` 或 `'R'` 来创建的。 KCL 原始字符串将反斜杠 (`\`) 和字符串插值 (`${}`) 视为普通的非字符。当我们想要一个包含反斜杠、字符串插值的字符串并且不希望它们被视为转义字符时,原始字符串是很有用的。 - -- 对于包含反斜杠(`\`)的原始字符串,KCL 代码和输出 YAML 如下: - -```python -s = "Hi\nHello" -raw_s = r"Hi\nHello" # This is a KCL raw string with the `r` prefix. -``` - -```yaml -s: |- - Hi - Hello -raw_s: Hi\nHello -``` - -- 对于包含字符串插值(`${}`)的原始字符串,KCL 代码和输出 YAML 如下: - -```python -worldString = "world" -s = "Hello ${worldString}" -raw_s = r"Hello ${worldString}" # This is a KCL raw string with the `r` prefix. -``` - -```yaml -worldString: world -s: Hello world -raw_s: Hello ${worldString} -``` - -此外,原始字符串最常用的场景是在正则表达式中使用: - -```python -import regex - -key = "key" -result = regex.match(key, r"[A-Za-z0-9_.-]*") # True -``` - -#### 布尔值 - -布尔值有两个常量对象:`False` 和 `True`. - -```python -a = True -b = False -``` - -#### List - -List 是一个序列,通常用于存储同质项的集合。下面是一个简单的 KCL 列表的例子: - -```python -list = [1, 2, 3] -assert len(list) == 3 # True -assert list[0] == 1 # True -``` - -我们可以使用列表推导式构建列表: - -```python -list = [ _x for _x in range(20) if _x % 2 == 0] -assert list == [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] # True -``` - -并且还可以使用嵌套的列表推导式: - -```python -matrix = [[1, 2], [3,4], [5,6], [7,8]] -transpose = [[row[_i] for row in matrix] for _i in range(2)] -assert transpose == [[1, 3, 5, 7], [2, 4, 6, 8]] # True -``` - -此外,我们可以在列表推导式中使用两个变量。第一个变量表示列表中的索引,第二个变量表示列表中的项。 - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use `_` to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -我们可以通过 `+` 连接列表: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -joined_list = _list0 + _list1 # [1, 2, 3, 4, 5, 6] -``` - -我们可以使用解包操作符 `*` 合并多个列表: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -union_list = [*_list0, *_list1] # [1, 2, 3, 4, 5, 6] -``` - -我们可以使用 `if` 表达式动态的将元素添加到列表,符合条件的元素会被添加到列表,不符合条件的元素会被忽略。 - -```python -a = 1 # 1 -data = [ - 1 - if a == 1: 2 - if a > 0: 3 - if a < 0: 4 -] # [1, 2, 3] -``` - -```python -a = 1 # 1 -data1 = [ - 1 - if a == 1: - 2 - elif a == 2: - 3 - else: - 3 -] # [1, 2] -data2 = [ - 1 - if a == 1: 2 - elif a == 2: 2 - else: 3 -] # [1, 2] -``` - -我们可以合并(union)列表: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -union_list = _list0 | _list1 # [4, 5, 6] -``` - -我们可以使用 `for k in list_var` 表达式遍历列表: - -```python -data = [1, 2, 3] -dataAnother = [val * 2 for val in data] # [2, 4, 6] -``` - -#### Dict - -Dict 是将可哈希的值映射到任意对象的映射对象。字典是有序的。键的顺序遵循其声明的顺序: - -这里有几个简单的 KCL 字典: - -```python -a = {"one" = 1, "two" = 2, "three" = 3} -b = {'one' = 1, 'two' = 2, 'three' = 3} -assert a == b # True -assert len(a) == 3 # True -``` - -在写多行的键-值时,可以省略每个键-值对行尾的逗号 `,`: - -```python -data = { - "key1" = "value1" # Ignore the comma ',' at the end of line - "key2" = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -在 Dict 键上使用简单的字面值时可以省略引号: - -```python -data = { - key1 = "value1" # Ignore key quotation '"' - key2 = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -此外,**选择表达式**可以用于定义包含嵌套键 dict 实例。 - -```python -person = { - base.count = 2 - base.value = "value" - labels.key = "value" -} # {"base": {"count": 2, "value": "value"}, "labels": {"key": "value"}} -``` - -输出 YAML 为: - -```yaml -person: - base: - count: 2 - value: value - labels: - key: value -``` - -在 KCL 中,dict 中的不同的字段可以直接引用,比如如下的例子 - -```python -config = { - name = "me" - metadata.name = name # Reference `name` with the value `"me"` in `config` directly. -} -``` - -输出 YAML 为: - -```yaml -config: - name: me - metadata: - name: me -``` - -我们可以使用字典推导式构建字典: - -```python -x = {str(i): 2 * i for i in range(3)} -assert x == {"0" = 0, "1" = 2, "2" = 4} -``` - -此外,我们可以在字典推导式中使用两个变量。第一个变量表示字典的键,第二个变量表示字典中键对应的值。 - -```python -data = {key1 = "value1", key2 = "value2"} -# Single variable loop -dataKeys1 = {k: k for k in data} # {"key1": "key1", "key2": "key2"} -dataValues1 = {k: data[k] for k in data} # {"key1": "value1", "key2": "value2"} -# Double variable loop -dataKeys2 = {k: k for k, v in data} # {"key1": "key1", "key2": "key2"} -dataValues2 = {v: v for k, v in data} # {"value1": "value1", "value2": "value2"} -dataFilter = {k: v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use `_` to ignore loop variables -dataKeys3 = {k: k for k, _ in data} # {"key1": "key1", "key2": "key2"} -dataValues3 = {v: v for _, v in data} # {"value1": "value1", "value2": "value2"} -``` - -我们可以使用解包操作符 `**` 来合并字典: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = {**_part1, **_part2} # {"a: "b", "c": "d"} -``` - -此外,union 操作符 `|` 也能达到同样的效果: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = _part1 | _part2 # {"a: "b", "c": "d"} -``` - -我们可以使用 `if` 表达式动态的将元素添加到字典,符合条件的元素会被添加到字典,不符合条件的元素会被忽略。 - -```python -a = 1 # 1 -data = { - key1 = "value1" - if a == 1: key2 = "value2" - if a > 0: key3 = "value3" - if a < 0: key4 = "value4" -} # {"key1": "value1", "key2": "value2", "key3": "value3"} -``` - -```python -a = 1 # 1 -data1 = { - key1 = "value1" - if a == 1: - key2 = "value2" - elif a > 0: - key3 = "value3" - else: - key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -data2 = { - key1 = "value1" - if a == 1: key2 = "value2" - elif a > 0: key3 = "value3" - else: key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -``` - -我们可以使用 `for k in dict_var` 表达式来遍历字典, 并且可以使用 `in` 操作符来判断 dict 是否包含某个键。 - -```python -data = {key1 = "value1", key2 = "value2"} -dataAnother = {k: data[k] + "suffix" for k in data} # {"key1": "value1suffix", "key2": "value2suffix"} -containsKey1 = "key1" in data # True -containsKey2 = "key" in data # False -``` - -#### None - -在 KCL 中, `None` 表示对象的值为空, 这与 Go 中的 `nil` 和 Java 中的 `null` 一样,并且对应于 YAML 中的 `null`。 - -```python -a = None -b = [1, 2, None] -c = {key1 = "value1", key2 = None} -``` - -输出如下: - -```yaml -a: null -b: - - 1 - - 2 - - null -c: - key1: value1 - key2: null -``` - -请注意,`None` 不能参与四则运算,但它可以参与逻辑运算和比较运算。 - -```python -a = 1 + None # error -b = int(None) # error -c = not None # True -d = None == None # True -e = None or 1 # 1 -f = str(None) # None -``` - -#### Undefined - -`Undefined` 与 `None` 类似,但其语义是变量没有分配任何值,也不会输出到 YAML。 - -```python -a = Undefined -b = [1, 2, Undefined] -c = {key1 = "value1", key2 = Undefined} -``` - -输出如下: - -```yaml -b: - - 1 - - 2 -c: - key1: value1 -``` - -请注意,`Undefined` 不能参与四则运算,但它可以参与逻辑运算和比较运算。 - -```python -a = 1 + Undefined # error -b = int(Undefined) # error -c = not Undefined # True -d = Undefined == Undefined # True -e = Undefined or 1 # 1 -f = str(Undefined) # Undefined -``` - -### 运算符 - -以下字符表示运算符: - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != @ \ -``` - -#### 算数运算符 - -KCL 支持常见的算数运算符: - -```python -assert 2 + 3 == 5 -assert 2 - 3 == -1 -assert 2 * 3 == 6 -assert 5 / 2 == 2.5 -assert 5 // 2 == 2 -assert 5 % 2 == 1 -``` - -#### 相等和关系运算符 - -KCL 支持相等和关系运算符: - -```python -assert 2 == 2 -assert 2 != 3 -assert 3 > 2 -assert 2 < 3 -assert 3 >= 3 -assert 2 <= 3 -``` - -#### 逻辑运算符 - -我们可以使用逻辑运算符反转或组合布尔表达式,例如:`and` 和 `or`: - -```python -if not done and (col == 0 or col == 3): - # ...Do something... - -``` - -#### 位运算符和移位运算符 - -以下是位运算符和移位运算符的例子: - -```python -value = 0x22 -bitmask = 0x0f - -assert (value & bitmask) == 0x02 -assert (value & ~bitmask) == 0x20 -assert (value | bitmask) == 0x2f -assert (value ^ bitmask) == 0x2d -assert (value << 4) == 0x220 -assert (value >> 4) == 0x02 -``` - -`|` 运算符可用于位运算,合并基本类型和集合及结构化数据,例如**列表**、**字典**和 **schema**。 - -位运算示例: - -```python -0x12345678 | 0xFF # 0x123456FF -``` - -联合基本类型示例: - -```python -schema x: - a: int | str # attribute a could be a int or string -``` - -#### 赋值运算符 - -以下 token 作为语法中的分隔符: - -```txt - ( ) [ ] { } - , : . ; = -> - += -= *= /= //= %= - &= ^= >>= <<= **= -``` - -以下是使用赋值和参数赋值赋值运算符的例子: - -```python -_a = 2 -_a *= 3 -_a += 1 -assert _a == 7 -``` - -#### Identity 运算符 - -以下关键字作为语法中的 identity 运算符: - -```python -is, is not -``` - -Identity 运算符检查右侧和左侧是否时同一对象。它们通常用于检查某个变量是否是 `None/Undefined/True/False`。以下是一些例子: - -```python -empty_String = "" -empty_String is not None # True -``` - -#### 成员运算符 - -以下关键字作为语法中的成员运算符: - -```python -in, not in -``` - -- `in` 运算符计算了第一个操作数是否是第二个操作数的成员,第二个运算符必须是 list、dict、schema 或 string。 -- `not in` 运算符与 `in` 相反。它们都返回一个布尔值。 - -成员的含义因第二个操作数的类型而异:列表的成员是其元素;字典的成员是其键;字符串的成员是其所有子字符串。 - -```python -1 in [1, 2, 3] # True - -d = {one = 1, two = 2} -"one" in d # True -"three" in d # False -1 in d # False -[] in d # False - -"nasty" in "dynasty" # True -"a" in "banana" # True -"f" not in "way" # True - -d = Data {one = 1, two = 2} # Data is a schema with attributes one and two -"one" in d # True -"three" in d # False -``` - -#### 推导式 - -一个推导表达式通过遍历一个或多个迭代项并计算表达式生成的结果来生成连续的元素,并以此构造新的列表或字典。 - -我们可以如下使用列表和字典的推导表达式: - -```python -listVar = [_x for _x in range(20) if _x % 2 == 0] # list comprehension -dictVar = {str(_i): 2*_i for _i in range(3)} # dict comprehension -``` - -#### 其他运算符 - -- 使用 **()** 表示函数调用, 例如 `"{} {}".format("hello", world)`。 -- 使用 **[]** 引用列表中指定索引处的值。 -- 使用 **:** 定义类型注解。 -- 使用 **.** 引用成员字段。 -- 使用 **\\** 续行符编写长表达式。 - -```python -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " -``` - -### 表达式 - -#### 条件表达式 - -条件表达式的形式为 `a if cond else b`。它首先计算条件 `cond`。如果为真,则会计算 `a` 并生成它的值;否则,它会生成 `b` 的值。 - -示例: - -```python -x = True if enabled else False # If enabled is True, x is True, otherwise x is False -``` - -#### 索引表达式 - -索引表达式 `a[i]` 生成可索引类型的第 `i` 个元素,例如字符串或数组。索引 `i` 必须是 `-n` ≤ `i` < `n` 范围内的 `int` 值,其中 `n` 等于 `len(a)`。其他任何索引都会导致错误。 - -有效的负索引的行为类似于 `n+i`,允许方便的对序列末尾进行索引。 - -```python -val = "abc" -list = ["zero", "one", "two"] -str_0 = val[0] # "a" -str_1 = val[1] # "b" -str_n1 = val[-1] # "c" - -list_0 = list[0] # "zero" -list_1 = list[1] # "one" -list_n1 = list[-1] # "two" -``` - -索引表达式 `d[key]` 也可以用于字典 `d`,以获取指定键对应的值。如果字典中不包含这个键则会返回 `Undefined` - -出现在赋值符左侧的索引表达式会更新指定的列表或字典元素。 - -```python -d = {key1 = "value1", key2 = "value2"} -key1value = d["key1"] # value1 -key2value = d["key2"] # value2 -``` - -尝试更新不可变类型的元素值(如列表或字符串)或可变类型的不可变变量会产生错误。 - -#### 切片表达式 - -切片表达式 `a[start:stop:step]` 会生成 `a` 包含的一个子序列,其中 `a` 必须是字符串或者数组。 - -`start`、`stop` 和 `step` 三个操作数都是可选的。如果有的话,每个值都必须为整数。`step` 的默认值为 1。如果 `step` 未指定,它前面的冒号也可以省略。指定 `step` 为 0 会产生错误。 - -从概念上来说,这些操作数指定了一系列值,索引 `i` 从 `start` 开始,每次增加 `step` 直到 `i` 到达或超过 `stop`。结果由有效的 `i` 的 `a[i]` 组成。 - -如下所示,从三个操作数计算有效的开始和结束的索引。`n` 是序列的长度。 - -```python -val = "abc" -len = len(val) -a = val[1:len] # "bc" (remove first element) -b = val[0:-1] # "ab" (remove last element) -c = val[1:-1] # "b" (remove first and last element) -``` - -```python -"abc"[1:] # "bc" (remove first element) -"abc"[:-1] # "ab" (remove last element) -"abc"[1:-1] # "b" (remove first and last element) -"banana"[1::2] # "aaa" (select alternate elements starting at index 1) -"banana"[4::-2] # "nnb" (select alternate elements in reverse, starting at index 4) -``` - -KCL 禁止将切片表达式定义为左值。原因是列表和字符串是不可变的,重新切片可以直接操作操作数,以确保更好的性能。 - -#### 函数调用 - -KCL 允许调用内置函数,或者调用内置和系统模块中的函数。 - -调用函数的基本方法如下所示: - -```python -import math - -a = math.pow(2, 3) # 2 powers 3 is 8. -b = len([1, 2, 3]) # the length of [1, 2, 3] is 3 -``` - -参数以 `,` 分隔,并且 KCL 还支持位置参数和键-值对形式的参数。 - -```python -print("hello world", end="") -``` - -请注意: - -- 有些函数参数具有默认值。 -- 一些函数接受可变参数。 - -如果没有为没有默认值的参数提供参数,则会抛出错误。 - -#### 选择表达式 - -选择表达式选择值的属性或方法。KCL 提供了许多识别或过滤属性的方法: - -`x.y` - -- dict: 表示字典 `x` 中键 `y` 对应的值。 -- schema: 表示 schema `x` 中 `y` 属性的值。 -- package: 表示 package `x` 中 `y` 标示的标识符。 - -示例: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -name = person.name # "Alice" -age = person.age # 18 - -myDict = { - key = "value" -} -result = myDict.key # "value" -``` - -`x?.y` - -`x` 可以是 schema 实例或 dict。当 `x` 可能为 `None` 或者键 `y` 不在 `x` 中时这非常有用。 - -```python -# Example of dict: -data = {"key" = "value"} -a = data?.key # "value" -b = data?.name # Undefined - -# example of schema instance: -schema Company: - name: str - address: str - -schema Person: - name: str - job?: Company - -alice = Person { - name = "alice" -} - -if alice?.job?.name == "Group": - print("work in Group") -``` - -#### Quantifier 表达式 - -Quantifier 表达式用于集合:列表或字典。通常用于在处理集合后获得某个结果,主要有以下四种形式: - -- **all** - - 用于检测集合中所有元素都满足给定的逻辑表达式,并且返回一个布尔值作为结果。 - - 只有集合中所有元素都满足表达式为 true 时,`all` 表达式为 true,否则为 false。 - - 如果集合为空,返回 true。 - - 支持表达式执行期间逻辑表达式的短路。 -- **any** - - 用于检测集合中至少一个元素都满足给定的逻辑表达式,并且返回一个布尔值作为结果。 - - 当集合中至少一个元素都满足表达式为 true 时,`any` 表达式为 true,否则 false。 - - 如果集合为空,返回 false。 - - 支持表达式执行期间逻辑表达式的短路。 -- **map** - - 映射集合中的元素生成新的列表。 - - 新列表的长度严格等于原列表的长度。 -- **filter** - - 通过逻辑判断筛选原集合中的元素,返回一个经过筛选的子集合。 - - 当表达式为 true 时才将元素添加到子集合。 - - 产生的新集合的类型(list, dict 和 schema)与原集合的类型完全一致,并且长度为 `[0, len(original-collection)]`。 - -**all** 和 **any** 表达式的示例代码: - -```python -schema Config: - volumes: [{str:}] - services: [{str:}] - - check: - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - }, "invalid cluster ip" - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } -``` - -**map** 和 **filter** 表达式的示例代码: - -```python -a = map e in [{name = "1", value = 1}, {name = "2", value = 2}] { - {name = e.name, value = int(e.value) ** 2} -} # [{"name": "1", value: 1}, {"name": "2", "value": 4}] - -b = map k, v in {a = "foo", b = "bar"} { v } # ["foo", "bar"] - -c = filter e in [{name = "1", value = 1}, {name = "2", value = 2}] { - int(e.value) > 1 -} # [{"name": "2", "value": 2}] - -d = filter _, v in {a = "foo", b = "bar"} { - v == "foo" -} # {"a": "foo"} -``` - -请注意,区分 any 表达式和 any 类型的区别。当 `any` 在类型注解中使用,意味着变量的值是任意的,而 any 表达式意味着集合中的至少一个元素满足条件。 - -### 流程控制表达式 - -#### If 和 Else - -KCL 支持 `if` 表达式和可选的 `elif` 和 `else` 表达式, 示例如下: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - print("maybe a is negative") -else: - print("a >= 100") -``` - -`elif` 的例子: - -```python -_result = 0 -if condition == "one": - _result = 1 -elif condition == "two": - _result = 2 -elif condition == "three": - _result = 3 -else: - _result = 4 -``` - -`if-elif-else` 表达式可以嵌套,示例如下: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - if a < 0: - print("a is negative") - print("No matter a is negative or positive, this message is printed") -else: - print("a >= 100") -``` - -此外,对于简单的 `if` 表达式如下: - -```python -if success: - _result = "success" -else: - _result = "failed" -``` - -我们可以使用 ` if else ` 的形式将它们写在一行: - -```python -_result = "success" if success else "failed" -``` - -`if` 或 `elif` 语句计算一个给定的表达式。当表达式的计算结果为 `True`, `:` 之后的语句将被计算,而当表达式为 `False` ,后面的语句不会被计算。 - -请注意,常量 `False`, `None`, 数字 `0`, 空列表 `[]`, 空字典 `{}` 和空字符串 `""` 都被视为 `False` 。 - -```python -_emptyStr = "" -_emptyList = [] -_emptyDict = {} -isEmptyStr = False if _emptyStr else True -isEmptyList = False if _emptyList else True -isEmptyDict = False if _emptyDict else True -``` - -结果为: - -```yaml -isEmptyStr: true -isEmptyList: true -isEmptyDict: true -``` - -### 断言语句 - -当发生错误时,开发人员应该能够检测到错误并终止执行。因此,KCL 引入了 `assert` 语法,示例如下: - -```python -a = 1 -b = 3 -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -``` - -此外,我们可以为 assert 语声明一个条件,当条件满足时,才进行 assert 断言 - -- 使用 if 语句书写条件断言 - -```python -a = None -if a: - assert a > 2: -``` - -- 使用 if 表达式书写条件断言 - -```python -a = None -assert a > 2 if a -``` - -### 函数 - -KCL 支持使用 lambda 关键字定义一个函数 - -```python -func = lambda x: int, y: int -> int { - x + y -} -a = func(1, 1) # 2 -``` - -lambda 函数具有如下特性: - -- lambda 函数将最后一个表达式的值作为函数的返回值,空函数体返回 None -- 返回值类型注解可以省略,返回值类型为最后一个表达式值的类型 -- 函数体中没有与顺序无关的特性,所有的表达式都是按顺序执行的 - -```python -_func = lambda x: int, y: int -> int { - x + y -} # Define a function using the lambda expression -_func = lambda x: int, y: int -> int { - x - y -} # Ok -_func = lambda x: int, y: int -> str { - str(x + y) -} # Error (int, int) -> str can't be assigned to (int, int) -> int -``` - -lambda 函数对象不能参与任何计算,只能在赋值语句和调用语句中使用。 - -```python -func = lambda x: int, y: int -> int { - x + y -} -x = func + 1 # Error: unsupported operand type(s) for +: 'function' and 'int(1)' -``` - -lambda 函数支持捕获其外部作用域的变量,并且可以作为其他函数的参数进行传递 - -```python -a = 1 -func = lambda x: int { - x + a -} -funcOther = lambda f, para: int { - f(para) -} -r0 = funcOther(func, 1) # 2 -r1 = funcOther(lambda x: int { - x + a -}, 1) # 2 -``` - -输出为: - -```yaml -a: 1 -r: 2 -``` - -此外,可以定义一个匿名函数并直接调用。 - -```python -result = (lambda x, y { - z = 2 * x - z + y -})(1, 1) # 3 -``` - -并且还可以在 for 循环使用使用匿名函数 - -```python -result = [(lambda x, y { - x + y -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 3, 3, 4] -``` - -请注意,KCL 中定义的函数的均为纯函数: - -- 函数的返回结果只依赖于它的参数。 -- 函数执行过程里面没有副作用。 - -因此,KCL 函数不能修改外部的变量,只能引用外部的变量,比如如下代码会发生错误: - -```python -globalVar = 1 -func = lambda { - x = globalVar # Ok - globalVar = 1 # Error -} -``` - -### 类型系统 - -#### 类型注解 - -类型注解可用于包级变量,schema 属性和参数。 - -- 属性可以是基本类型,例如字符串(`string`),浮点数(`float`),定点数(`int`) 或布尔值(`bool`)。 -- 属性可以是字面值类型,例如字符串文本(`"TCP"` 和 `"UDP"`),数字文本 (`"1"` 和 `"1.2"`),布尔值文本(`True` 和 `False`)。 -- 属性也可以是列表或字典: - - 未指定元素类型的列表为 `[]`。 - - 元素类型为 `t` 的列表为 `[t]`。这里 `t` 是另一种类型。 - - 键的类型为 `kt` 且值的类型为 `vt` 的字典为 `{kt:vt}`。 - - `kt`, `vt` 或两者都可以为空, 就像列表未指定元素类型一样。 -- 属性可以是由 `|` 定义的 **联合类型** ,例如 `a | b`, 意为类型可以是 a 或 b。 - - 联合类型可以包含 `int`, `str`, `float`, `bool`, `list`, `dict`, 字面值类型和 schema 类型,并且支持类型的嵌套,例如: `{str:str|int}`、`[[int|str]|str|float]` 和 `2 | 4 | 6` 等。 -- 属性可以是 schema 类型。在这种情况下,使用包名 + schema 名称作为类型名。 -- 属性可以声明为任意类型,例如 `any`。 - -示例 - -- 基本类型 - -```python -"""Top level variable type annotation""" -a: int = 1 # Declare a variable `a` that has the type `int` and the value `1` -b: str = "s" # Declare a variable `b` that has the type `str` and the value `"s"` -c: float = 1.0 # Declare a variable `c` that has the type `float` and the value `1.0` -d: bool = True # Declare a variable `d` that has the type `bool` and the value `True` -``` - -- List/Dict/Schema 类型 - -```python -schema Person: - name: str = "Alice" - age: int = 10 - -a: [int] = [1, 2, 3] # Declare a variable `a` that has the list type `[int]` and the value `[1, 2, 3]` -b: {str:str} = {k1 = "v1", k2 = "v2"} # Declare a variable `b` that has the dict type `{str:str}` and the value `{k1 = "v1", k2 = "v2"}` -c: Person = Person {} # Declare a variable `c` that has the schema type `Person` and the value `Person {}` -``` - -- 联合类型 - -```python -# Basic union types -schema x[argc: int]: # Schema argument type annotation - p: int | str # Schema attribute type annotation -``` - -```python -# Literal union types -schema LiteralType: - # String literal union types, x_01 can be one of "TCP" and "UDP" - x_01: "TCP" | "UDP" - # Number literal union types, x_02 can be one of 2, 4, and 6 - x_02: 2 | 4 | 6 - # Unit union types, x_03 can be one of 1Gi, 2Gi and 4Gi - x_03: 1Gi | 2Gi | 4Gi - -x = LiteralType { - x_01 = "TCP" - x_02 = 2 - x_03 = 1Gi -} -``` - -当属性的值不符合联合类型定义时,编译器会抛出错误: - -```python -# Literal union types -schema LiteralType: - # String literal union types, x_01 can be one of "TCP" and "UDP" - x_01: "TCP" | "UDP" - -x = LiteralType { - x_01 = "HTTP" # Error: the type got is inconsistent with the type expected, expect str(TCP)|str(UDP), got str(HTTP) -} -``` - -- Any 类型 - -```python -# Any type -schema Config: - literalConf: any = 1 - dictConf: {str:any} = {key = "value"} - listConf: [any] = [1, "2", True] - -config = Config {} -``` - -请注意,一般在配置编写中不提倡使用 `float` 和 `any` 类型,因为它们都存在一定的不稳定因素,比如精度丢失,无法进行静态类型检查等。 - -此外在 KCL 中,不允许修改一个变量的类型。如果在重新分配值时不满足类型,将引发类型错误。 - -```python -_a = 1 # The type of `_a` is `int` -_a = "s" # Error: expect int, got str(s) -``` - -变量可以赋值给其上界类型,但不能赋值给它的特化类型。 - -`None` 和 `Undefined` 可以赋值给任何类型: - -- 任何类型都可以赋值给 `any` 类型, `None` 和 `Undefined` 可以赋值给 `any` 类型。 - -```python -a: int = None -b: str = Undefined -c: any = 1 -d: any = "s" -e: any = None -``` - -- `int` 类型可以赋值给 `float` 类型, `float` 类型不能赋值给 `int` 类型. - -```python -a: float = 1 -b: int = 1.0 # Error: expect int, got float(1.0) -``` - -- `int` 类型可以赋值给 `int|str` 类型, `int|str` 不能赋值给 `int` 类型. - -```python -a: int | str = 1 -b: int = 1 if a else "s" # Error: expect int, got int(1)|str(s) -``` - -请注意,在 KCL 中虽然提供了 any 类型,但是它仍然是静态类型,所有变量的类型在编译期间不可变。 - -#### 类型推导 - -如果顶层或 schema 中的变量或常量声明没有使用显式的类型注解,则会从初始值推断类型。 - -- 整形数值被推断为 `int`。 - -```python -a = 1 # The variable `a` has the type `int` -``` - -- 浮点数被推断为 `float`。 - -```python -a = 1.0 # The variable `a` has the type `float` -``` - -- 字符串被推断为 `str`。 - -```python -a = "s" # The variable `a` has the type `str` -``` - -- 布尔值被推断为 `bool`。 - -```python -a = True # The variable `a` has the type `bool` -b = False # The variable `b` has the type `bool` -``` - -- `None` 和 `Undefined` 被推断为 `any`。 - -```python -a = None # The variable `a` has the type `any` -b = Undefined # The variable `b` has the type `any` -``` - -- 列表的类型根据元素类型推断,并且是可变大小的。 - -```python -a = [1, 2, 3] # The variable `a` has the type `[int]` -b = [1, 2, True] # The variable `b` has the list union type `[int|bool]` -c = ["s", 1] # The variable `c` has the list union type `[int|str]` -``` - -请注意,空列表将被推导为 `[any]` 类型。 - -```python -a = [] # The variable `a` has the type `[any]` -``` - -- 字典的类型是根据元素的键和值推断的,并且是可变大小的。 - -```python -a = {key = "value"} # The variable `a` has the type `{str:str}` -b = {key = 1} # The variable `b` has the type `{str:int}` -c = {key1 = 1, key2 = "s"} # The variable `c` has the type `{str:int|str}` -``` - -请注意,空字典将被推导为 `{any:any}` 类型。 - -```python -a = {} # The variable `a` has the type `{any:any}` -``` - -- 携带运行时值的 if 条件表达式的类型将被静态推断为所有可能结果的联合类型。 - -```python -a: bool = True # The variable `a` has the type `bool` -b = 1 if a else "s" # The variable `b` has the type `int|str` -``` - -当变量被推导为某个类型时,它的类型不能再改变。 - -```python -_a = 1 -_a = "s" # Error: expect int, got str(1) -``` - -#### 类型别名 - -在 KCL 中,我们可以使用 `type` 关键字为所有类型声明一个类型别名简化复杂类型的书写。 - -```python -type Int = int -type String = str -type StringOrInt = String | Int -type IntList = [int] -type StringAnyDict = {str:} -``` - -我们可以从一个包中导入一个类型并为它定义一个别名。 - -```py -import pkg - -type Data = pkg.Data -``` - -此外,我们还可以使用类型别名和字面值联合类型充当近似枚举的效果。 - -```python -# A type alias of string literal union types -type Color = "Red" | "Yellow" | "Blue" - -schema Config: - color: Color = "Red" # The type of color is `"Red" | "Yellow" | "Blue"`, and it has an alias `Color`, whose default value is `"Red"` - -config = Config { - color = "Blue" -} -``` - -上述代码执行的输出结果为: - -```yaml -config: - color: Blue -``` - -请注意,类型别名不能与已有的内置类型 `any`、`int`、`float`、`bool` 和 `str` 等相同 - -```python -type any = int | str # Error -type int = str # Error -type float = int # Error -type bool = True # Error -type str = "A" | "B" | "C" # Error -``` - -#### 类型守卫 - -KCL 支持在程序中使用 `typeof` 函数对任意值求得其运行时的类型。 - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person {} -t3 = typeof(_x1) - -_x2 = pkg.Person {} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# Output -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -除此之外,我们可以使用 `as` 关键字在运行时作类型转换。`as` 关键字的一般用法如下: - -- 具有偏序关系的基础类型,比如 `float -> int` -- 具有偏序关系的联合类型,比如 `int | str -> str` -- 对类型上界 `any` 的转换,比如 `any -> int` -- 具有偏序关系的结构类型,比如 `base-schema -> sub-schema` - -```python -schema Data1: - id?: int - -schema Data2: - name?: str - -data: Data1 | Data2 = Data1 {} - -if typeof(a) == "Data1": - data1 = data as Data1 # The type of `data1` is `Data1` -elif typeof(a) == "Data2": - data2 = data as Data2 # The type of `data2` is `Data2` -``` - -当类型转换失败时,一个运行时错误将被抛出。 - -```python -a: any = "s" -b: int = a as int # Error: The `str` type cannot be converted to the `int` type -``` - -如果不想要运行时类型转换失败,我们可以添加 `if` 防御式代码进行检查。 - -```python -a: any = "s" -b = a as int if typeof(a) == "int" else None # The type of b is `int` -``` - -请注意,`as` 转换的目标类型不能是字面值类型或者联合类型,因为它们在运行时不具有一个完全确定的类型。 - -### Schema - -#### 概述 - -Schema 是定义复杂配置的语言元素。我们可以定义带类型的属性,初始值和验证规则。此外,KCL 支持 schema 单继承、mixin 和 protocol 实现复杂配置的复用。 - -#### 基础部分 - -##### 属性 - -以下是 schema 基础定义的示例: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 -``` - -在 KCL 中, 我们可以使用类型注解在 schema 中定义一些属性,每个属性都可以设置一个可选的默认值(比如上述代码中的 `age` 属性,它的默认值是 `0`),没有设置默认值的属性的初始值为 `Undefined`, 它们不会在 YAML 当中进行输出。 - -###### 不可变性 - -schema 中属性的不可变性遵循和全局变量不可变性一样的规则,只有 schema 中的可变属性可以在 schema 中修改。此外,schema 的属性默认值可被 schema 配置值修改: - -```python -schema Person: - age: int = 1 # Immutable attribute - _name: str = "Alice" # Mutable attribute - - age = 10 # Error, can't change the default value of the attribute `age` in the schema context. - _name = "Bob" # Ok - -person = Person { - age = 3 # Ok, can change the default value of the attribute `age` in the schema config. -} -``` - -###### 可选属性 - -schema 实例中每个属性 **必须** 赋值一个非 `None`/`Undefined` 的值,否则编译器会抛出错误,除非它被 `?` 符号标记为可选属性。 - -示例: - -```python -schema Employee: - bankCard: int # bankCard is a required attribute, and it can NOT be None or Undefined - nationality?: str # nationality is an optional attribute, and it can be None or Undefined - -employee = Employee { - bankCard = None # Error, attribute 'bankCard' of Employee is required and can't be None or Undefined - nationality = None # Ok -} -``` - -##### 顺序无关计算 - -schema 中顺序无关计算表示 schema 内部属性之间的引用关系。例如,当我们声明一个形式为 `a = b + 1` 的表达式时,`a` 值的计算依赖于 `b` 值的计算。当编译器计算 `a` 的值并且 `a` 的值取决于 `b` 的值时,编译器会选择先计算 `b` 的值,然后根据 `b` 的值计算 a 的值表达式 `a = b + 1`,这与传统过程语言的计算方法略有不同。 - -由于 schema 中值的计算是基于依赖关系的,就像有向无环图按照拓扑排序的顺序遍历图中的每个节点一样, schema 中属性的声明顺序并不那么重要,因此特征称为顺序无关计算。 - -请注意,不同 schema 属性值之间不能有循环引用。 - -我们可以通过下面的例子看到这个特性。 - -```python -schema Fib: - n1: int = n - 1 # Refers to the attribute `n` declared after `n1` - n2: int = n1 - 1 - n: int - value: int = 1 if n <= 2 else Fib {n = n1}.value + Fib {n = n2}.value - -fib8 = Fib {n = 8}.value -``` - -结果为: - -```yaml -fib8: 21 -``` - -在 schema 中,我们只需要简单的指定属性之间的依赖关系,编译器就会根据依赖关系自动计算出值,这样可以帮助我们节省大量的样板代码,减少配置编写难度。 - -##### Schema 上下文 - -我们可以定义 schema 的上下文来管理 schema 的属性,可以直接在 schema 中编写 schema 参数、临时变量和表达式等: - -```python -schema Person[_name: str]: # define a schema argument - name: str = _name # define a schema attribute - age: int = 10 # define a schema attribute with default value - hands: [int] = [i for i in [1, 2, 3]] # define a for statement -``` - -然后,我们可以通过如下代码实例化一个 `Person` 并将其赋值给 `alice` 变量: - -```python -alice = Person("alice") -``` - -可以得到如下 YAML 输出: - -```yaml -alice: - name: alice - age: 10 - hands: - - 1 - - 2 - - 3 -``` - -##### 校验 - -KCL 中为了确保代码稳定性,除了使用 **静态类型** (类型注解) 和 **不可变性**,还支持在 **check** 块中定义验证规则 (KCL 几乎原生支持所有 [OpenAPI](https://www.openapis.org/) 的验证能力): - -```python -import regex - -schema Sample: - foo: str - bar: int - fooList: [str] - - check: - bar > 0 # Minimum, also support the exclusive case - bar < 100 # Maximum, also support the exclusive case - len(fooList) > 0 # Min length, also support exclusive case - len(fooList) < 100 # Max length, also support exclusive case - regex.match(foo, "^The.*Foo$") # Regex match - isunique(fooList) # Unique - bar in range(100) # Range - bar in [2, 4, 6, 8] # Enum - multiplyof(bar, 2) # MultipleOf -``` - -使用 schema, 所有的实例将在编译时验证: - -```python -# Ok -goodSample = Sample { - foo = "The Foo" - bar = 2 - fooList = ["foo0", "foo1"] -} - -# Error: validation failure: Check failed on check conditions: bar < 100. -badSample = Sample { - foo = "The Foo" - bar = 123 - fooList = ["foo0", "foo1"] -} -``` - -此外,我们可以使用 **and**, **or**, **if** 来构建更复杂的检查逻辑: - -```python -schema Sample: - bar: int - foo: str - doCheck: bool - - check: - regex.match(foo, "^The.*Foo$") and bar in [2, 4, 6, 8] if doCheck -``` - -为了确保所有检查规则都能很好地发挥其相应的作用,我们可以通过编写 KCL 测试用例来测试不同数据组合的合理性和正确性,并通过 kcl test tool 运行所有测试用例。 - -##### 文档 - -通常在我们写好 schema 模型之后,我们会为 schema 写文档注释,可以用一个三引号字符串来完成,如下所示: - -```python -schema Server: - """Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - - Attributes - ---------- - workloadType : str, default is Deployment - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - name : str, default is None - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - labels : {str:str}, optional, default is None - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - - Examples - ---------------------- - myCustomApp = AppConfiguration { - name = "componentName" - } - """ - workloadType: str = "Deployment" - name: str - labels?: {str:str} -``` - -更多详细内容可见 Doc tools。 - -##### 配置 - -假设我们有如下 schema 定义: - -```python -schema Person: - firstName: str - lastName: str - labels?: {str:str} -``` - -可以用类 JSON 的表达式定义配置: - -```python -person = Person { - firstName = "firstName" - lastName = "lastName" -} -``` - -schema 遵循严格的属性定义,配置未定义的属性将触发编译错误: - -```python -person = Person { - firstName = "firstName" - lastName = "lastName" - fullName = "fullName" # Error: Cannot add member 'fullName' to schema 'Person', 'fullName' is not defined in schema 'Person' -} -``` - -此外,我们可以使用 `if` 表达式将元素动态的添加到 schema 实例中,将满足条件的元素添加到 schema 实例并忽略不满足条件的元素。并且除了使用一个 schema 类型实例化一个 schema,我们也可以通过 schema 实例得到一个新的实例。 - -```python -env = "prod" -person = Person { - firstName = "firstName" - lastName = "lastName" - if env == "prod": - labels.env = env - else: - labels.env = "other" -} -# We can use the person instance to get a new instance named `personx` directly. -personx = person { - firstName = "NewFirstName" -} -``` - -输出为: - -```yaml -env: prod -person: - firstName: firstName - lastName: lastName - labels: - env: prod -personx: - firstName: NewFirstName - lastName: lastName - labels: - env: prod -``` - -#### 高级功能 - -##### Protocol & Mixin - -除了 schema, 在 KCL 中还提供了一种额外的类型定义方式 `protocol`,它的性质如下: - -- 在 protocol 中,只能定义属性及其类型,不能书写复杂的逻辑与 check 表达式,也不能使用 mixin。 -- protocol 只能对非 `_` 开头的属性进行约束。 -- protocol 只能继承自或者引用 protocol, 不能继承自或者引用 schema。 - -此外,我们可以使用可选的 **mixin** 组装复杂的 schema,并使用 **protocol** 为 **mixin** 添加可选的宿主类型, 使用 `for` 关键字为 **mixin** 定义宿主类型,并且在 mixin 内部它将从宿主类型中查询到属性的类型。 - -```python -schema Person: - mixin [FullNameMixin] - - firstName: str # Required - lastName: str # Required - fullName?: str # Optional -``` - -FullNameMixin 是一个产生 fullName 字段的简单例子: - -```python -protocol PersonProtocol: - firstName: str - lastName: str - fullName?: str - -mixin FullNameMixin for PersonProtocol: - fullName = "{} {}".format(firstName, lastName) -``` - -然后我们可以通过一下方式获取 schema 实例: - -```python -person = Person { - firstName = "John" - lastName = "Doe" -} -``` - -输出结果为: - -```yaml -person: - firstName: John - lastName: Doe - fullName: John Doe -``` - -请注意,宿主类型 **protocol** 只能用于 **mixin** 的定义 (后缀名为 `Mixin`), 否则将会报错。 - -```python -protocol DataProtocol: - data: str - -schema Data for DataProtocol: # Error: only schema mixin can inherit from protocol - x: str = data -``` - -##### 索引签名 - -在 KCL schema 中可以定义索引签名,这意味着索引签名的键-值约束可用于构造具有 schema 类型的字典。或者可以将其他检查添加到额外的 schema 属性中,以增强 KCL 类型和语义检查。 - -###### 基本用法 - -使用 `[{attr_alias}: {key_type}]: {value_type}` 的形式去定义 schema 的类型注解, 其中 `{attr_alias}` 可以省略。 - -```python -schema Map: - """ - Map is a schema with a key of str type and a value of str type - """ - [str]: str # `{attr_alias}` can be omitted. - -data = Map { - key1 = "value1" - key2 = "value2" -} -``` - -###### 同时定义属性和索引签名 - -可以在 schema 中同时定义 schema 属性和索引签名,通常用于表示 schema 中额外属性的类型约束,比如如下代码 - -```python -schema Person: - name: str - age: int - [...str]: str # Except for the `name` and `age` attributes, the key type of all other attributes of the schema must be `str`, and the value type must also be `str`. -``` - -###### 定义索引签名别名 - -可以为索引签名定义类型注解的属性别名,并将其与检查块一起使用。 - -```python -schema Data: - [dataName: str]: str - check: - dataName in ["Alice", "Bob", "John"] # We can use the index signature key name in the check block. - -data = Data { - Alice = "10" - Bob = "12" - Jonn = "8" # Error: Jonn not in ["Alice", "Bob", "John"] -} -``` - -##### 继承 - -类似于其他面向对象语言,KCL 提供了基础且有限的面向对象支持,例如 **属性复用**,**私有和公有变量**和**单继承**。KCL 不支持多继承。 - -以下是单继承的例子: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 - -# An employee **is** a person, and has some additional information. -schema Employee(Person): - bankCard: int - nationality?: str - -employee = Employee { - firstName = "Bob" - lastName = "Green" - age = 18 - bankCard = 123456 -} -``` - -结果为: - -```yaml -employee: - firstName: Bob - lastName: Green - age: 18 - bankCard: 123456 - nationality: null -``` - -请注意,KCL 只支持 schema 的 **单继承**。 - -此外,当 schema 存在继承关系时,可选属性的性质如下: - -- 如果该属性在基类 schema 中是可选的,则它在子类 schema 中是可选的,也可以是子类 schema 中必选的。 -- 如果该属性在基类 schema 中是必选的,则它在子类 schema 中也是必选的。 - -```python -schema Person: - bankCard?: int - nationality: str - -schema Employee(Person): - bankCard: int # Valid, both `bankCard: int` and `bankCard?: int` are allowed - nationality?: str # Error, only `nationality: str` is allowed -``` - -##### Schema 函数 - -schema 映射到函数上非常好用;它可以有任意数量的输入和输出参数。 例如,Fibonacci 函数可以使用递归 schema 如下编写: - -```python -schema Fib[n: int]: - n1 = n - 1 - n2 = n - 2 - if n == 0: - value = 0 - elif n == 1: - value = 1 - else: - value = Fib(n1).value + Fib(n2).value - -fib8 = Fib(8).value # 21 -``` - -##### 装饰器 - -像 Python 一样, KCL 支持在 schema 上使用装饰器。KCL 装饰器动态地改变 schema 的功能,而不必直接使用子 schema 或更改被装饰的 schema 的源代码。 和函数调用一样,装饰器支持传入额外的参数。 - -内置的 schema 装饰器: - -- `@deprecated` - 标识 schema 或 schema 属性被废弃. `@deprecated` 装饰器支持三种参数: - - **version** - 字符串类型,表示版本信息。 默认值为空。 - - **reason** - 字符串类型,表示不推荐使用的原因。 默认值为空。 - - **strict** - bool 类型,表示是报错还是警告。 默认值是 true。 如果 `strict` 为 `True` 并且抛出错误,程序将被中断。 如果 `strict` 为 `False`,则会输出警告并且不会中断程序。 - -示例: - -```python -@deprecated -schema ObsoleteSchema: - attr: str - -schema Person: - firstName: str = "John" - lastName: str - @deprecated(version="1.16", reason="use firstName and lastName instead", strict=True) - name: str - attrs: ObsoleteSchema = { # Error: ObsoleteSchema was deprecated - attr = "value" - } - -JohnDoe = Person { # Error: name was deprecated since version 1.16, use firstName and lastName instead - name = "deprecated" -} -``` - -- `@info` - 给 schema 或 schema 属性标识额外的信息,支持任意参数,用于语言静态分析 schema 或 schema 属性的扩展标记信息 - -示例: - -```python -@info(version="v1") -schema Person: - @info(message="name") - name: str - age: int -``` - -请注意,当前版本的 KCL 尚不支持用户自己定义装饰器。 - -##### 成员函数 - -内置函数和 schema 成员 - -- instances() - 返回 schema 的现有实例列表。 - -```python -schema Person: - name: str - age: int - -alice = Person { - name = "Alice" - age = 18 -} - -bob = Person { - name = "Bob" - age = 10 -} - -aliceAndBob = Person.instances() # Person is a schema type, instances() is its member method -``` - -输出为: - -```yaml -alice: - name: Alice - age: 18 -bob: - name: Bob - age: 10 -aliceAndBob: - - name: Alice - age: 18 - - name: Bob - age: 10 -``` - -### 配置操作 - -#### 配置合并 - -##### | 运算符 - -在 KCL 中,我们可以使用合并运算符 `|` 来合并配置。union 运算符支持的类型包括如下: - -```txt -SchemaInstance | SchemaInstance -SchemaInstance | Dict -Dict | Dict -List | List -``` - -合并集合和结构化数据: - -- 合并 List。使用 `|` 运算符右边的列表表达式按照**索引**逐一覆盖左边列表表达式中的元素。 - -```python -_a = [1, 2, 3] -_b = [4, 5, 6, 7] -x = _a | _b # [4, 5, 6, 7] 1 -> 4; 2 -> 5; 3 -> 6; Undefined -> 7 -``` - -合并特定索引或所有元素仍在讨论中。 - -- 合并 Dict. 使用 `|` 运算符右边的列表表达式按照**键**逐一覆盖左边列表表达式中的元素。 - -```python -_a = {key1 = "value1"} -_b = {key1 = "overwrite", key2 = "value2"} -x = _a | _b # {"key1": "overwrite", "key2": "value2"} -``` - -集合和 schema 的合并是一个新的集合,其属性是将 b 合并到 a,保留从左到右的操作数顺序。 - -- 合并 schema。Schema 的合并与 dict 相似。 - -Schema 的合并操作如下: - -```python -schema Person: - firstName?: str - lastName?: str - -_a = Person { - firstName = "John" -} -_b = {lastName = "Doe"} -_c = _a | _b # {"firstName": "John", "lastName": "Doe"} -_d = _a | None # {"firstName": "John"} -_e = _a | Undefined # {"firstName": "John"} -_f = None | _a # {"firstName": "John"} -_g = Undefined | _a # {"firstName": "John"} -``` - -请注意,当 union 运算符的左右操作数之一为 None 时,将立即返回另一个操作数。 - -```python -data1 = {key = "value"} | None # {"key": "value"} -data2 = None | [1, 2, 3] # [1, 2, 3] -data3 = None | None # None -``` - -输出如下: - -```yaml -data1: - key: value -data2: - - 1 - - 2 - - 3 -data3: null -``` - -##### : 运算符 - -模式: `identifier : E` - -表达式 `E` 的值将被合并到元素值。 - -示例: - -```python -schema Data: - labels: {str:} = {key1 = "value1"} - -data = Data { - # union {key2: "value2"} into the attribute labels of the schema Data. - labels: {key2 = "value2"} -} -``` - -输出: - -```yaml -data: - labels: - key1: value1 - key2: value2 -``` - -除了在 schema 属性上使用属性运算符之外,还可以使用属性运算符对配置块执行不同的操作。 - -- schema 外部使用合并运算符 `:` - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - data: Data - -# This is one configuration that will be merged. -config: Config { - data.d1 = 1 -} -# This is another configuration that will be merged. -config: Config { - data.d2 = 2 -} -``` - -与它等效的配置代码可以表示为: - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - data: Data - -config: Config { - data.d1 = 1 - data.d2 = 1 -} -``` - -输出结果为: - -```yaml -config: - data: - d1: 1 - d2: 1 -``` - -- schema 内部使用合并运算符 `:` - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - # This is one configuration that will be merged. - data: Data { - d1 = 1 - } - # This is another configuration that will be merged. - data: Data { - d2 = 1 - } - -config: Config {} -``` - -#### 配置覆盖 - -##### = 运算符 - -模式: `identifier = E` - -表达式 `E` 的值将覆盖元素值。 - -示例: - -```python -schema Data: - labels: {str:} = {key1 = "value1"} - -data = Data { - # override {key2: "value2"} into the attribute labels of the schema Data. - labels = {key2 = "value2"} -} -``` - -输出: - -```yaml -data: - labels: - key2: value2 -``` - -请注意,可以使用 `Undefined` 来覆盖,来“删除”内容。例如 `{ a = Undefined }`。 - -#### 配置添加 - -##### += 运算符 - -模式: `identifier += E` - -插入只能用于列表类型的 `identifier`. - -`E` 将插入到列表 `identifier` 指定索引后,并且索引以后的属性将自动后移。 - -示例: - -```python -schema Data: - labels: {str:} = {key1 = [0]} - -data = Data { - # insert [1] into the attribute labels.key1 of the schema Data. - labels: {key1 += [1]} -} -``` - -输出: - -```yaml -data: - labels: - key1: - - 0 - - 1 -``` - -如果没有定义索引,将使用最后一个索引。 - -#### 注意事项 - -合并运算符 `:` 是一个可交换的幂等运算符,当合并的值发生值的冲突时会发生值冲突错误,因此我们需要 `=` 和 `+=` 运算符表示配置的覆盖,添加和删除操作。 - -```python -data0 = {id: 1} | {id: 2} # Error:conflicting values between {'id': 2} and {'id': 1} -data1 = {id: 1} | {id = 2} # Ok, the value of `data` is {"id": 2} -``` - -`:` 运算符冲突检查的规则如下: - -- `None` 和 `Undefined` 不与任何值冲突 - -```python -data0 = None | {id: 1} # Ok -``` - -- 对于 `int`、`float`、`str` 和 `bool` 类型的变量,当它们的值不相同时发生冲突错误。 - -```python -data0 = 1 | 1 # Ok -data1 = 1 | "s" # Error -``` - -- 对于列表类型 - - 当它们的长度不相同时,它们被认为是冲突的 - - 当它们的长度相同时,当且仅当它们的任意一个子元素值冲突时,它们自身是冲突的 - -```python -data0 = [1] | [1] # Ok -data1 = [1, 2] | [1] # Error -``` - -- 对于 dict/schema 类型 - - 对于相同的 key,key 的值冲突时,它们自身是冲突的,否则是不冲突的 - -```python -data0 = {id: 1} | {id: 1} # Ok -data1 = {id: 1} | {id: 2} # Error -data1 = {id: 1} | {idAnother: 1} # Ok -``` - -### Rule - -KCL 支持使用 rule 关键字定义校验块,可用于数据校验,用法类似于 schema 中的 check 表达式。 - -```python -rule SomeRule: - age > 0, "rule check failure message" -``` - -可以像 schema 实例化那样调用一个 rule 进行校验 - -```python -age = 0 -name = "Bob" -rule SomeRule: - age > 0, "rule check failure message" - name == "Alice" - -rule1 = SomeRule() # Rule call -rule2 = SomeRule {} -``` - -可以使用 protocol 和 for 绑定语句为 rule 增加类型约束: - -```python -# Schema definition -protocol Service: - clusterIp: str - $type: str - -# Schema definition -protocol Volume: - mountPath: [str] - -# Protocol -protocol SomeProtocol: - id: int - env: {str: any} - services: [Service] - volumes: [Volume] - -rule SomeChecker for SomeProtocol: - id > 0, "id must >0" - - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - } - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } - -# Call rule to check with config parameter -SomeChecker { - id = 1 - env = { - MY_ENV = "MY_ENV_VALUE" - } - services = [ - { - type = "ClusterIP" - clusterIP = "NONE" - } - ] - volumes = [ - { - mountPath = "/home/admin" - } - { - mountPath = "/home/myapp" - } - ] -} -``` - -请注意,`protocol` 和 `rule` 的组合方式可以使属性和其约束定义进行分离,我们可以在不同的包中定义不同的 `rule` 和 `protocol` 按需进行组合,这与 schema 中的 check 表达式只能与 schema 属性定义在一起是不同的。 - -此外,有两种复用不同 rule 的方式 - -- 直接调用 - -```python -weather = "sunny" -day = "wednesday" - -rule IsSunny: - weather == "sunny" - -rule IsWednesday: - day == "wednesday" - -rule Main: - IsSunny() # Rule inline call - IsWednesday() # Rule inline call - -Main() # Rule call -``` - -使用 rule 的继承 (rule 不同于 schema, 可以多继承混用) - -```python -weather = "sunny" -day = "wednesday" - -rule IsSunny: - weather == "sunny" - -rule IsWednesday: - day == "wednesday" - -rule Main(IsSunny, IsWednesday): - id == 1 - -Main() -``` - -可以使用 option 函数与命令行 `-D` 参数获得外部数据进行校验 - -- 一个简单例子 - -```python -schema Day: - day: str - homework: str - -days: [Day] = option("days") - -rule Main: - filter d in days { - d.day not in ["saturday", "sunday"] and d.homework - } - -Main() -``` - -- 一个复杂例子 - -```python -data = option("data") -input = option("input") - -rule Allow: - UserIsAdmin() - any grant in UserIsGranted() { - input.action == grant.action and input.type == grant.type - } - -rule UserIsAdmin: - any user in data.user_roles[input.user] { - user == "admin" - } - -rule UserIsGranted: - [ - grant - for role in data.user_roles[input.user] - for grant in data.role_grants[role] - ] - -allow = Allow() or False -``` - -### 模块 - -KCL 配置文件以 **模块** 形式组织。 单个 KCL 文件被认为是一个 module,一个目录被认为是一个包。 - -同一个包内的模块是可见的,跨包引用需要通过导入可见。 - -```bash -. -└── root - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -model1.k: - -```python -# schema CatalogItem in model1.k - -schema CatalogItem: - id: int - image: CatalogItemImage # CatalogItemImage is defined in the module of the same package e.g., model2.k in package model - title: str -``` - -service1.k: - -```python -import ..model as model # cross-package references - -schema ImageService: - image: model.CatalogItemImage # CatalogItemImage is imported from another package e.g., model2.k in package model - name: str -``` - -#### 相对路径引用 - -我们可以使用 `.` 运算符来实现 KCL 入口文件的相对路径导入。 - -main.k: - -```python -import .model1 # Current directory module -import ..service # Parent directory -import ...root # Parent of parent directory - -s = service.ImageService {} -m = root.Schema {} -``` - -#### 绝对路径引用 - -`import a.b.c.d` 的语义为: - -1. 如果 `kcl.mod` 文件不存在,将当前目录作为包的根路径,并从当前目前查找 `a/b/c/d` 路径 -2. 如果 `kcl.mod` 文件存在,从 `ROOT_PATH/a/b/c/d` 查找,否则抛出一个导入错误 - -根路径 `ROOT_PATH` 的定义为: - -从当前目录或者父级目录中查找 `kcl.mod` 文件对应的目录。 - -```bash -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -main.k: - -```python -import service # `root package` and `kcl.mod` are in the same directory -import mixin # `root package` and `kcl.mod` are in the same directory - -myModel = model.CatalogItem {} -``` - -请注意,对于 KCL 入口文件 `main.k`,不能导入所在文件夹,否则会出现递归导入错误: - -```python -import model # Error: recursively loading -``` - -### 动态参数 - -假设某些字段需要像用户输入一样动态传入,我们可以在模块中定义一个动态参数: - -```python -bankCard = option("bankCard") # Get bankCard through the option function. -``` - -我们可以如下使用 module: - -```bash -kcl employee.k -D bankCard=123 -``` - -目前,支持顶级参数的类型有数字、字符串、布尔、列表和字典。 - -```bash -kcl main.k -D list_key='[1,2,3]' -D dict_key='{"key":"value"}' -``` - -请注意,命令行中引号 `"` 等符号需要使用 `\` 进行转义 - -#### Setting 文件形式的参数 - -此外,它还支持输入一个 YAML 文件作为顶级参数。 - -```yaml -kcl_options: - - key: key_number - value: 1 - - key: key_dict - value: - innerDictKey: innerDictValue - - key: key_list - value: - - 1 - - 2 - - 3 - - key: bankCard - value: 123 -``` - -```bash -kcl -Y setting.yaml employee.k -``` - -此外,setting 文件还支持配置命令行编译参数如下: - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - disable_none: true - strict_range_check: true - debug: 1 - verbose: 1 - sort_keys: true - output: ./stdout.golden - overrides: - - app.image=new_image - path_selector: - - config - package_maps: - k8s: /Users/.kcl/kpm/k8s_1.24 -kcl_options: - - key: image - value: docker.io/kcllang/kcl:latest -``` - -KCL CLI -Y 参数还支持多文件配置,并支持编译参数和顶级参数的单独写入与合并。 - -```bash -kcl -Y compile_setting.yaml option_setting.yaml -``` - -- `compile_setting.yaml` - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - disable_none: true - strict_range_check: true - debug: 1 - verbose: 1 - output: ./stdout.golden -``` - -- `option_setting.yaml` - -```yaml -kcl_options: - - key: image - value: docker.io/kcllang/kcl:latest -``` - -我们可以使用以下指令获取每个参数的含义 - -```bash -kcl --help -``` - -#### Option Functions - -我们可以在 KCL 代码中使用 `option` 获取顶级参数。 - -```python -value = option(key="key", type='str', default="default_value", required=True, help="Set key value") -``` - -参数 - -- **key**: 参数的键。 -- **type**: 要转换的参数类型。 -- **default**: 参数默认值。 -- **required**: 当未提供参数且参数的 required 为 True 是报告错误。 -- **help**: 帮助信息。 - -### 多文件编译 - -除了上面的 KCL 单文件执行之外,我们还可以使用以下命令同时编译多个 KCL 入口文件: - -```bash -kcl main_1.k main_2.k ... main_n.k -``` - -main_1.k - -```python -a = 1 -b = 2 -``` - -main_2.k - -```python -c = 3 -d = 4 -``` - -输出结果为: - -```yaml -a: 1 -b: 2 -c: 3 -d: 4 -``` - -利用**多文件编译**,我们可以组合多个 KCL 文件,而无需使用 import 管理文件。 我们来看一个结合**多文件编译**和 **schema 实例**的例子。 - -model.k - -```python -schema Model: - name: str - labels?: {str:} - annotations?: {str:} - replicas: int - -_model1 = Model { - name = "model1" - labels.key1 = "value1" - labels.key2 = "value2" - annotations.key = "value" - replicas = 2 -} - -_model2 = Model { - name = "model2" - replicas = 3 -} -``` - -backend.k - -```python -import yaml - -schema Backend: - apiVersion: str = "v1" - kind: str = "Deployment" - metadata: {str:} - spec: {str:} = { - minReadySeconds = 0 - paused = False - progressDeadlineSeconds = 600 - replicas = 1 - revisionHistoryLimit = 10 - selector = {} - } - -_backends = [Backend { - metadata.name = model.name - metadata.labels = model.labels - metadata.annotations = model.annotations - spec.selector.matchLabels: model.labels - spec.replicas = model.replicas -} for model in Model.instances()] # Schema Model is defined in model.k -print("---\n".join([yaml.encode(_b, ignore_private=True) for _b in _backends])) -``` - -命令为: - -```bash -kcl model.k backend.k -``` - -输出为: - -```yaml -apiVersion: v1 -kind: Deployment -metadata: - name: model1 - labels: - key1: value1 - key2: value2 - annotations: - key: value -spec: - minReadySeconds: 0 - paused: false - progressDeadlineSeconds: 600 - replicas: 2 - revisionHistoryLimit: 10 - selector: - matchLabels: - key1: value1 - key2: value2 ---- -apiVersion: v1 -kind: Deployment -metadata: - name: model2 -spec: - minReadySeconds: 0 - paused: false - progressDeadlineSeconds: 600 - replicas: 3 - revisionHistoryLimit: 10 - selector: {} -``` - -### KCL 变量查询 - -我们可以在 KCL CLI 使用 `-S|--path-selector` 参数从 KCL 模型中查询一个或多个值。 - -变量查询形式如下: - -`var.name` - -#### 示例 - -Code structure: - -```bash -. -├── kcl.mod -└── main.k - └── pkg - └── model.k -``` - -pkg/model.k: - -```python -schema Person: - name: str - age: int - -var = Person { - name = "Alice" - age = 18 -} -``` - -main.k - -```python -import pkg - -var = pkg.Person { - name = "Bob" - age = 10 -} -``` - -命令为: - -```bash -kcl main.k -S var -``` - -输出结果为: - -```yaml -var: - name: Bob ---- -var: - name: Alice - age: 18 -``` - -### KCL 变量修改 - -除了变量查询,KCL 还允许我们通过 KCL CLI 的 `-O|--overrides` 参数直接修改配置模型中的值。 - -变量修改参数的使用与变量查询类似,参数包含三部分,如 `pkg`、`identifier`、`attribute` 和 `override_value` . - -```bash -kcl main.k -O override_spec -``` - -- `override_spec`: 表示需要修改的配置模型字段和值的统一表示 - -```txt -override_spec: [[pkgpath] ":"] identifier ("=" value | "-") -``` - -- `pkgpath`: 表示需要修改标识符的包路径,通常为 `a.b.c` 的形式,对于 main 包,`pkgpath` 表示为 `__main__`, 可省略,省略不写时表示 main 包 -- `identifier`: 表示需要修改配置的标识符,通常为 `a.b.c` 的形式 -- `value`: 表示需要修改配置的值,可以是任意合法的 KCL 表达式,比如数字/字符串字面值,list/dict/schema 表达式等 -- `=`: 表示修改identifier的值 - - 当 identifier 存在时,修改已有 identifier的值为 value - - 当 identifier 不存在时,添加 identifier属性,并将其值设置为 value -- `-`: 表示删除 identifier属性 - - 当 identifier 存在时,直接进行删除 - - 当 identifier 不存在时,对配置不作任何修改 - -请注意,当 `identifier` 出现多次时,修改/删除全部 `identifier` 的值 - -此外,在 KCL 中还提供了 API 用于变量查询和修改,详见 [API 文档](../xlang-api/go-api.md) - -#### 示例 - -##### 修改示例 - -KCL 代码: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -``` - -命令为: - -```bash -kcl main.k -O :person.name=Bob -O :person.age=10 -``` - -输出结果为: - -```yaml -person: - name: Bob - age: 10 -``` - -此外,当我们使用 KCL CLI `-d` 参数时,KCL 文件将同时修改为以下内容 - -```bash -kcl main.k -O :person.name=Bob -O :person.age=10 -d -``` - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Bob" - age = 10 -} -``` - -##### 删除示例 - -KCL 代码: - -```python -schema Config: - x?: int = 1 - y?: str = "s" - -config = Config { - x = 2 -} -``` - -命令为: - -```bash -kcl main.k -O config.x- -``` - -输出结果为: - -```yaml -config: - x: 1 - y: s -``` - -### 总结 - -本页总结了 KCL 语言中的常用功能。 KCL 作为一种新的语言,会根据配置场景的需求,逐步增加功能特性。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/datetime.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/datetime.md deleted file mode 100644 index 66cb4bca..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/datetime.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: "datetime" -linkTitle: "datetime" -type: "docs" -description: datetime 包 - 时间处理 -weight: 100 ---- - -## time - -`ticks() -> float` - -返回从 1970 年 1 月 1 日 0 时 0 分 0 秒(Epoch)开始到当前时间经过的秒数。如果系统时钟能提供更精确的时间,则秒数后可能会有小数部分。 - -## date - -`date() -> str` - -返回以 `%Y-%m-%d %H:%M:%S` 格式表示的时间。 - -## now - -`now() -> str` - -返回当地时间,例如 `'Sat Jun 06 16:26:11 1998'`。 - -## today - -`today() -> str` - -返回以 `%Y-%m-%d %H:%M:%S.%{ticks}` 格式表示的时间。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/json.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/json.md deleted file mode 100644 index b19bdc88..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/json.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: "json" -linkTitle: "json" -type: "docs" -description: JSON 编码解码 -weight: 100 ---- - -## encode - -``` -encode( - data: any, - sort_keys: bool = False, - indent: int = None, - ignore_private: bool = False, - ignore_none: bool = False -) -> str -``` - -将 KCL 对象 `data` 序列化为 JSON 格式的字符串。 - -## decode - -`decode(value: str) -> any` - -反序列化 `value`(一个包含 JSON 格式文档的字符串实例)为一个 KCL 对象。 - -## dump_to_file - -``` -dump_to_file( - data: any, - filename: str, - ignore_private: bool = False, - ignore_none: bool = False -) -> None -``` - -将 KCL 对象 `data` 序列化为 JSON 格式的字符串,并将其写入文件 `filename` 中。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/yaml.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/yaml.md deleted file mode 100644 index e0faf129..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/yaml.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: "yaml" -linkTitle: "yaml" -type: "docs" -description: yaml 编码解码 -weight: 300 ---- - -## encode - -``` -encode( - data: any, - sort_keys: bool = False, - ignore_private: bool = False, - ignore_none: bool = False -) -> str -``` - -将 KCL 对象 `data` 序列化为 YAML 格式的字符串。 - -## decode - -`decode(value: str) -> any` - -反序列化 `value`(一个包含 YAML 格式文档的字符串实例)为一个 KCL 对象。 - -## dump_to_file - -``` -dump_to_file( - data: any, - filename: str, - ignore_private: bool = False, - ignore_none: bool = False -) -> None -``` - -将 KCL 对象 `data` 序列化为 YAML 格式的字符串,并将其写入文件 `filename` 中。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/_category_.json deleted file mode 100644 index edfe989e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "包管理", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/Ide/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/Ide/index.md deleted file mode 100644 index 2ba6e5b4..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/Ide/index.md +++ /dev/null @@ -1,6 +0,0 @@ -# IDE - -我们为 KCL 提供了两种简单的 IDE 插件。您可以通过以下链接获得更多帮助信息: - -- IntelliJ 插件: https://github.com/kcl-lang/intellij-kcl -- VSCode 插件: https://github.com/kcl-lang/vscode-kcl diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/Ide/intellij.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/Ide/intellij.md deleted file mode 100644 index be637514..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/Ide/intellij.md +++ /dev/null @@ -1,3 +0,0 @@ -# IntelliJ IDEA - -- IntelliJ Plugin: https://github.com/kcl-lang/intellij-kcl diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/Ide/vs-code.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/Ide/vs-code.md deleted file mode 100644 index d3db7e01..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/Ide/vs-code.md +++ /dev/null @@ -1,54 +0,0 @@ -# Visual Studio Code KCL 插件 - -## 快速开始 - -- 1. [安装 KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) 并检查 `kcl` 和 `kcl-language-server` 命令在您的 PATH 中: - - ```bash - which kcl - which kcl-language-server - ``` - -- 2. 安装 [VS Code KCL 插件](https://marketplace.visualstudio.com/items?itemName=kcl.kcl-vscode-extension). 需要您的 VS Code 版本大于 1.50+ -- 3. 重新打开 VS Code 并创建一个 KCL 文件验证 IDE 插件功能 - -## 特性 - -此扩展提供了一些 KCL 编码帮助,包括以下功能: - -- **语法高亮** - ![Highlight](/img/docs/tools/Ide/vs-code/Highlight.png) -- **跳转** - ![Goto Definition](/img/docs/tools/Ide/vs-code/GotoDef.gif) -- **补全** - ![Completion](/img/docs/tools/Ide/vs-code/Completion.gif) -- **大纲** - ![Outline](/img/docs/tools/Ide/vs-code/Outline.gif) -- **悬停** - ![Hover](/img/docs/tools/Ide/vs-code/Hover.gif) -- **诊断** - ![Diagnostics](/img/docs/tools/Ide/vs-code/Diagnostics.gif) - -> 提示:您可以通过安装 [Error Lens 插件](https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens) 来增强诊断效果 - -其他一些有用的功能,如代码重构和智能感知等正在开发中。 - -## 最小依赖 - -我们建议您使用最新版本的 KCL,但此扩展所需的 KCL 最低版本为 v0.4.6。如果您使用的是更早期版本,则此扩展可能无法正常工作。 - -## 已知问题 - -[详见](https://github.com/kcl-lang/kcl/issues/524) - -## 寻求帮助 - -如果扩展没有如您所期望的那样工作,请通过[社区](https://kcl-lang.io/docs/community/intro/support)与我们联系和寻求帮助。 - -## 参与贡献 - -目前 VS Code KCL 插件处于早期版本,我们正在积极改进 VS Code KCL 插件体验,欢迎参考[贡献指南](https://kcl-lang.io/docs/community/contribute) 一起共建! - -## 许可 - -Apache License 2.0 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/getting-started/install.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/getting-started/install.md deleted file mode 100644 index 74510232..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/getting-started/install.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -sidebar_position: 2 ---- - -# 安装 - -## 1. 安装 KCL - -### 二进制下载 - -KCL 的每个版本都包含各种操作系统和体系结构。这些二进制版本可以从 [Github](https://github.com/kcl-lang/kcl/releases/) 或者 [Gitee](https://gitee.com/kusionstack/kcl/releases) 手动下载并安装,下载完成后将 `{install-location}/kclvm/bin` 添加到环境变量 PATH 中。 - -> ⚠️ 如果您不能成功访问 Github, 也可以访问 Gitee 获得二进制进行安装 - -#### MacOS & Linux - -```bash -export PATH=$PATH:{install-location}/kclvm/bin -``` - -#### Windows - -```powershell -$env:PATH += ";{install-location}\kclvm\bin;" -``` - -### 使用脚本安装最新版本 - -#### MacOS - -将 KCL darwin 最新版本安装到 /usr/local/kclvm/bin - -```bash -curl -fsSL https://kcl-lang.io/script/install.sh | /bin/bash -``` - -#### Linux - -将 KCL linux 最新版本安装到 /usr/local/kclvm/bin - -```bash -wget -q https://kcl-lang.io/script/install.sh -O - | /bin/bash -``` - -#### Windows - -将 KCL windows 最新版本安装到 $Env:SystemDrive\kclvm\bin,并将该目录添加到用户 PATH 环境变量中。 - -```bash -powershell -Command "iwr -useb https://kcl-lang.io/script/install.ps1 | iex" -``` - -### Homebrew (MacOS) - -- 安装 - -```bash -brew install kcl-lang/tap/kcl -``` - -- 升级 - -```bash -brew upgrade kcl-lang/tap/kcl -``` - -- 卸载 - -```bash -brew uninstall kcl-lang/tap/kcl -``` - -### Scoop (Windows) - -首先安装 [Scoop](https://scoop.sh/), 然后通过如下命令安装 `kcl`: - -```bash -scoop bucket add kcl-lang https://github.com/kcl-lang/scoop-bucket.git -scoop install kcl-lang/kcl -``` - -### 使用 Go 安装 - -通过 `Go` 命令安装 (Go 要求 1.18+) - -```bash -go install kcl-lang.io/kcl-go/cmds/kcl-go@main -``` - -添加一个 kcl 命令的别名 (可选) - -```bash -alias kcl='kcl-go run' -``` - -> 注意:`kcl-go` 并不依赖是否安装了 `kcl`,但如果 PATH 中存在 `kcl`,`kcl-go` 将优先使用 `PATH` 中的 `kcl`。 - -### 使用 Docker 镜像安装 - -- 基本命令 - -```bash -docker run --rm -it kcllang/kcl -``` - -- 更新镜像 - -```bash -docker pull kcllang/kcl -``` - -### 注意 - -可以执行运行如下命令确保 KCL 已经正确安装 - -```bash -kcl -V -``` - -如果安装成功,输出可能为如下形式 (不同版本结果可能稍微不同): - -```bash -Version: {kcl version} -Platform: {your platform} -GitCommit: {git commit} -``` - -对于上述所有安装方式, 如果您想使用 [KCL Python 插件](/docs/reference/plugin/overview), 需要确保您已经安装了 Python 3.7+ 并将 python3 命令添加到您的 PATH 中。 - -## 2. 安装 KCL IDE 插件 - -### VS Code - -KCL 为 VS Code 本地版本提供了插件支持,并提供了高亮、自动补全、跳转、悬停、大纲等功能。您可以[点击这里](/docs/tools/Ide/vs-code)进行安装。 - -![Completion](/img/docs/tools/Ide/vs-code/Completion.gif) - -### IntelliJ IDEA - -从[这里](https://github.com/kcl-lang/intellij-kcl/releases)下载发行版,在 IntelliJ IDEA 中,点击 Preference -> plugins -> install Plugin from Disk... -> 选择 kcl-idea-plugin zip -> 重启 IDE。此插件需要 IntelliJ IDEA 2020.2+ diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/getting-started/intro.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/getting-started/intro.md deleted file mode 100644 index aaa364e3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/getting-started/intro.md +++ /dev/null @@ -1,199 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 简介 - -## KCL 是什么? - -[KCL](https://github.com/kcl-lang/kcl) 是一个开源的基于约束的记录及函数语言。KCL 通过成熟的编程语言技术和实践来改进对大量繁杂配置比如云原生 Kubernetes 配置场景的编写,致力于构建围绕配置的更好的模块化、扩展性和稳定性,更简单的逻辑编写,以及更简单的自动化和生态工具集成。 - -## 为什么使用 KCL? - -KCL 期望通过更现代化的声明式配置语言在 Kubernetes 资源管理解决如下问题: - -- 通过**代码抽象**等手段屏蔽基础设施和平台的细节,降低研发者负担 -- **编辑**和**校验**已有的存量配置或模版 -- 通过配置语言无副作用地管理跨团队的大规模配置数据,提升团队协作效率 - - 用**生产级高性能编程语言**以**编写代码**的方式提升配置的灵活度,比如条件语句、循环、函数、包管理等特性提升配置重用的能力 - - 在代码层面提升**配置语义验证**的能力,比如字段可选/必选、类型、范围等配置检查能力 - - 提供**配置分块编写、组合和抽象的能力**,比如结构定义、结构继承、约束定义等能力 - - 通过**多语言 SDK**,**KCL 语言插件**等手段提升其**自动化**集成能力 - -您可以将 KCL 用于 - -- 生成静态配置数据如 JSON, YAML 等 -- 使用 schema 对配置数据进行建模并减少配置数据中的样板文件 -- 为配置数据定义带有规则约束的 schema 并对数据进行自动验证 -- 无副作用地组织、简化、统一和管理庞大的配置 -- 通过分块编写配置数据可扩展地管理庞大的配置 -- 与 [KusionStack](https://kusionstack.io) 一起,用作平台工程语言来交付现代应用程序 - -除了语言自身,KCL 还提供了许多额外的工具如格式化,测试、文档、包管理等工具帮助您使用、理解和检查编写的配置或策略;通过 VS Code 等 IDE 插件和 Playground 降低配置编写、分享的成本;通过 Rust, Go, 和 Python 多语言 SDK 自动化地管理和执行配置。 - -![](/img/docs/user_docs/intro/kcl-overview.png) - -此外,KCL 是一种现代高级领域编程语言,并且它是一种编译静态的强类型语言。KCL 为开发人员提供了通过记录和函数语言设计将**配置(config)**、**建模抽象(schema)**、**逻辑(lambda)**和**策略(rule)**作为核心能力。 - -![](/img/docs/user_docs/intro/kcl-concepts.png) - -KCL 试图提供独立于运行时的可编程性,不在本地提供线程和IO等系统功能,但支持云本地操作场景的功能,并试图为解决领域问题并提供稳定、安全、低噪声、低副作用、易于自动化和易于管理的编程支持。 - -总之,KCL 具备如下特点: - -- **简单易用**:源于 Python、Golang 等高级语言,采纳函数式编程语言特性,低副作用 -- **设计良好**:独立的 Spec 驱动的语法、语义、运行时和系统库设计 -- **快速建模**:以 [Schema](https://kcl-lang.io/docs/reference/lang/tour#schema) 为中心的配置类型及模块化抽象 -- **功能完备**:基于 [Config](https://kcl-lang.io/docs/reference/lang/tour#config-operations)、[Schema](https://kcl-lang.io/docs/reference/lang/tour#schema)、[Lambda](https://kcl-lang.io/docs/reference/lang/tour#function)、[Rule](https://kcl-lang.io/docs/reference/lang/tour#rule) 的配置及其模型、逻辑和策略编写 -- **可靠稳定**:依赖[静态类型系统](https://kcl-lang.io/docs/reference/lang/tour/#type-system)、[约束](https://kcl-lang.io/docs/reference/lang/tour/#validation)和[自定义规则](https://kcl-lang.io/docs/reference/lang/tour#rule)的配置稳定性 -- **强可扩展**:通过独立配置块[自动合并机制](https://kcl-lang.io/docs/reference/lang/tour/#-operators-1)保证配置编写的高可扩展性 -- **易自动化**:[CRUD APIs](https://kcl-lang.io/docs/reference/lang/tour/#kcl-cli-variable-override),[多语言 SDK](https://kcl-lang.io/docs/reference/xlang-api/overview),[语言插件](https://github.com/kcl-lang/kcl-plugin) 构成的梯度自动化方案 -- **极致性能**:使用 Rust & C,[LLVM](https://llvm.org/) 实现,支持编译到本地代码和 [WASM](https://webassembly.org/) 的高性能编译时和运行时 -- **API 亲和**:原生支持 [OpenAPI](https://github.com/kcl-lang/kcl-openapi)、 Kubernetes CRD, Kubernetes YAML 等 API 生态规范 -- **开发友好**:[语言工具](https://kcl-lang.io/docs/tools/cli/kcl/) (Format,Lint,Test,Vet,Doc 等)、 [IDE 插件](https://github.com/kcl-lang/vscode-kcl) 构建良好的研发体验 -- **安全可控**:面向领域,不原生提供线程、IO 等系统级功能,低噪音,低安全风险,易维护,易治理 -- **多语言 SDK**:[Go](https://kcl-lang.io/docs/reference/xlang-api/go-api),[Python](https://kcl-lang.io/docs/reference/xlang-api/python-api),[Java](https://kcl-lang.io/docs/reference/xlang-api/java-api) 和 [REST API](https://kcl-lang.io/docs/reference/xlang-api/rest-api) 满足不同场景和应用使用需求 -- **生态集成**:通过 [Kustomize KCL 插件](https://github.com/kcl-lang/kustomize-kcl), [Helm KCL 插件](https://github.com/kcl-lang/helm-kcl) 或者 [KPT KCL SDK](https://github.com/kcl-lang/kpt-kcl-sdk) 直接编辑或校验资源 -- **生产可用**:广泛应用在蚂蚁集团平台工程及自动化的生产环境实践中 - -虽然 KCL 不是通用语言,但它有相应的应用场景。开发人员可以通过 KCL 编写**config**、**schema**、**function**和**rule**,其中 config 用于定义数据,schema 用于描述数据的模型定义,rule 用于验证数据,schema 和 rule 还可以组合使用模型和约束来充分描述数据。此外,还可以使用 KCL 中的 lambda 纯函数来组织数据代码,封装通用代码,并在需要时直接调用它。 - -KCL 配置通常遵循如下模式: - -$$ -k = (T) v -$$ - -其中,$k$ 是属性名称,$v$ 是属性值,$T$ 是类型注解。由于 KCL 具有类型推导的能力,因此 $T$ 通常可以省略。 - -下面是一个用 KCL 生成 kubernetes 资源的例子 - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = name -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -我们可以使用上述 KCL 代码生成一个 Kubernetes YAML 配置 - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## 如何选择 - -目前社区已经进行了大量的尝试来改进其配置技术,主要可分为三类: - -- 用于模板、修补和验证的基于低级数据格式的工具,使用外部工具来增强重用和验证。 -- 领域特定语言(DSL)和配置语言(CL),以增强语言能力。 -- 基于通用语言(GPL)的解决方案,使用 GPL 的云开发工具包(CDK)或框架来定义配置。 - -简单的选择答案: - -- 如果您需要编写结构化的静态的 K-V,或使用 Kubernetes 原生的技术工具,建议选择 YAML。 -- 如果您希望引入编程语言便利性以消除文本(如 YAML、JSON) 模板,有良好的可读性,或者你已是 Terraform 的用户,建议选择 HCL。 -- 如果您希望引入类型功能提升稳定性,维护可扩展的配置文件,建议选择 CUE。 -- 如果您希望以现代语言方式编写复杂类型和建模,维护可扩展的配置文件,原生的纯函数和策略,和生产级的性能和自动化,建议直接选择 KCL 或将 KCL 用于对已有配置手段或工具进行增强。 - -### vs. YAML/JSON - -YAML/JSON 适用于小型配置场景。对于需要频繁修改的大型云原生配置场景,它们更适合 KCL。所涉及的主要区别是配置数据抽象和部署之间的区别: - -使用 KCL 进行配置的优点是:对于静态数据,抽象一层的优点意味着整个系统具有部署灵活性。不同的配置环境、租户和运行时可能对静态数据有不同的要求,甚至不同的组织可能有不同的规范和产品要求。KCL 可用于公开最需要的和经常修改的配置。 - -### vs. Jsonnet/GCL - -GCL 是一种用 Python 实现的声明式配置语言,它提供了支持模板抽象的必要语言功能。然而 GCL 编译器本身是用Python编写的,且语言本身是解释执行的。对于大型模板实例(如 kubernetes 模型),性能较差。 - -Jsonnet 是一种用 C++ 实现的数据模板语言,适用于应用程序和工具开发人员,可以生成配置数据并通过代码组织、简化和管理大型配置,而不会产生副作用。 - -Jsonnet 和 GCL 非常擅长减少样板。它们都可以使用代码生成配置,就像工程师只需要编写高级 GPL 代码,而不是手动编写容易出错且难以理解的服务器二进制代码一样。Jsonnet 减少了 GCL 的一些复杂性,但在很大程度上属于同一类别。两者都有许多运行时错误,类型检查和约束能力不足。 - -### vs. HCL - -HCL 是一种 Go 实现的结构化配置语言。HCL 的原生语法受到 libucl 和 nginx 配置的启发。它用于创建一种对人类和机器友好的结构化配置语言,作为 [Terraform 语言](https://www.terraform.io/language)主要用于 DevOps工具、服务器配置和资源配置等。 - -HCL 的用户界面不能通过 Terraform 提供者 Schema 定义直接感知。此外,在编写复杂对象和必需/可选字段定义时,用户界面很麻烦。动态参数受变量的条件字段约束。资源本身的约束需要由提供程序模式定义,或者与 Sentinel/Rego 和其他策略语言相结合。语言本身的完整性不能自我封闭,其实现方法也不统一。 - -### vs. CUE - -CUE 可以通过结构、无继承和其他特性用作建模,当模型定义之间没有冲突时可以实现高度抽象。因为 CUE 在运行时执行所有约束检查,所以它在大规模配置建模场景中可能存在性能瓶颈。CUE 将类型和值组合为一个概念,并通过各种语法简化了约束的编写。例如,不需要泛型类型和枚举,求和类型和空值合并是一回事。CUE 支持配置合并,但它是完全幂等的。它可能无法满足复杂的多租户和多环境配置场景的要求。对于复杂的循环和约束场景,编写起来很复杂,编写需要精确配置修改或者 Patch 的场景也很麻烦。 - -对于 KCL,建模是通过 KCL Schema 进行的,通过语言级工程和一些面向对象的特性(如单一继承、Mixin 复用)可以实现高模型抽象。KCL 是一种静态编译语言,用于大规模建模场景是运行时开销较低 (性能更高,更低的内存消耗)。KCL 提供了更丰富的检查声明性约束语法,这使得配置和策略编写更加容易。对于一些配置字段组合约束,它更容易编写(与 CUE 相比,KCL 提供了更多的 if-guard 组合约束、all/any/map/filter 表达式和其他集合约束编写方法,这使得编写更容易)。 - -### vs. Dhall - -Dhall 是一种可编程配置语言,它组合了 JSON、函数、类型和 imports 导入等功能, 本身风格偏向函数式,如果您学过 Haskell 等函数式风格语言,可能会对它感到熟悉的。相比于 Dhall, KCL 也提供了类似功能的组合,提供给用户配置可编程和抽象的能力,不过 KCL 在建模、约束检查、自动化等方面做了更多的改进,同时能够通过包管理手段进行模型共享。此外,KCL 的语法语义更贴近于面向对象语言,在一定程度上会比纯函数式风格接受程度更高。 - -### vs. Nickel - -Nickel 是一种简单的配置语言。它的目的是自动生成静态配置文件,本质上是带有函数和类型的 JSON。 - -KCL 和 Nickel 都有类似的渐进式类型系统(静态+动态)、合并策略、函数和约束定义。不同之处在于 KCL 是一种类似 Python 的语言,而 Nickel 是一种类似 JSON 的语言。此外,KCL 提供了 schema 关键字来区分配置定义和配置数据,以避免混合使用。 - -### vs. Starlark - -Starlark 主要用作 Bazel 的配置语言并且是 Python 的一种方言。它没有类型,并且禁止递归。 - -KCL 一定程度上也可以看作 Python 的变种,但是它极大地增强了静态类型和配置扩展性相关的设计,并且是一个编译型语言,这与 Starlark 有着本质的不同。 - -### vs. Kustomize - -Kustomize 的核心功能是其文件级覆盖功能。但是它存在多个覆盖链的问题,因为找到特定属性值的语句不能保证它是最终值,因为其他地方出现的另一个特定值可以覆盖它。对于复杂的场景,Kustomsize 文件的继承链的检索通常不如 KCL 代码的继承链检索方便,需要仔细考虑指定的配置文件覆盖顺序。此外,Kustomize 无法解决 YAML 配置编写、约束验证、模型抽象和开发等问题,更适合于简单的配置场景。 - -在 KCL 中,配置合并操作可以对代码中的每个配置属性进行细粒度处理,合并策略可以灵活设置,而不限于整体资源,配置之间的依赖关系可以通过KCL的import语句进行静态分析。 - -### vs. Helm - -Helm 的概念源于操作系统的包管理机制。它是一个基于模板化 YAML 文件的包管理工具,支持包中资源的执行和管理。 - -KCL 自然提供了 Helm 功能的超集,因此您可以直接使用 KCL 作为替代。对于采用 Helm 的用户,KCL 中的堆栈编译结果可以打包并以 Helm 格式使用,通过 kpm 包管理工具进行分发复用。此外,我们还可以直接使用 Helm-KCL 插件直接对已有的 Helm Charts 进行无侵入的可编程扩展。 - -### vs. CDK - -用CDK的高级语言编写可以很好地集成到应用程序项目中,这实际上是客户端运行时的一部分。对于KCL,由KCL编写的外部配置和策略与客户端运行时分离。 - -通用语言通常远远超出了需要解决的问题,例如安全问腿、能力边界问题(启动本地线程、访问IO、网络、代码无限循环和其他安全风险)。例如,在音乐领域,有专门的音符来表达音乐,这便于学习和交流,它不能用一般语言表达清楚。 - -此外,由于通用语言风格多样,需要统一维护、管理和自动化。通用语言通常用于编写客户端运行时,它是服务器运行时的延续,不适合编写独立于运行时的配置,被编译成二进制文件,并最终从进程开始运行。此外,GPL 稳定性和可扩展性不易控制。然而,KCL 配置语言通常用于编写数据,将数据与简单逻辑相结合,它描述了预期的最终结果,然后由编译器或引擎使用,既具备丰富的编程抽象能力,又具备方便的数据处理方式。 - -### vs. OPA/Rego - -Rego 起源于逻辑编程,它基于 Datalog,是一种受限制的 Prolog 形式,而 KCL 基于静态类型结构,具备部分 OOP 特性。Rego 类型化特征结构的设计是为了解决 Prolog 在人类语言编码应用中的缺点,将 Datalog 变量用于编程本质上是约束验证任务,Datalog 是一种优秀的查询语言。但对于约束强制执行,它有点麻烦,因为实际上首先需要查询要应用约束的值才能进行校验。 - -此外,KCL 的方法更易于找到规范化、简化、面向人类易读,面向运行时性能优良的约束和校验表示,具备静态类型,并且它更适合于从 OpenAPI 生成或者创建 OpenAPI。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/abstraction.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/abstraction.md deleted file mode 100644 index 7450d42e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/abstraction.md +++ /dev/null @@ -1,145 +0,0 @@ ---- -title: "抽象" -sidebar_position: 3 ---- - -## 什么是抽象 - -抽象是指一个实体的简化表示,它允许隐藏特定的具体细节,同时向程序员提供最相关的信息。每一个抽象都是为满足特定需求而定制的,并且可以极大地提高给定实体的可用性。在 KCL 的上下文中,抽象可以使代码更容易理解和维护,同时也可以简化用户界面。 - -需要注意的是,代码抽象并不是为了减少代码大小,而是为了提高代码的可维护性和可扩展性。在抽象代码的过程中,应考虑可重用性、可读性和可扩展性等因素,并根据需要对代码进行不断优化。 - -良好的抽象可以提供如下价值 - -1. 提供不同的焦点,不同角色和场景关注点分离。 -2. 屏蔽较低级别的细节,避免潜在的错误。 -3. 提升用户界面和自动化友好性。 - -KCL 自身可能不会评估用户定义模型抽象的合理性,但它提供了技术解决方案来帮助用户构建抽象。 - -## 使用 KCL 进行抽象 - -现在,让我们将 Docker Compose 和 Kubernetes 资源抽象为应用程序配置 - -`Docker Compose` 是一个用于定义和运行多容器 Docker 应用程序的工具。使用 Docker Compose,您可以在一个文件中定义应用程序的服务、网络和卷,然后使用它作为一个单元启动和停止应用程序。Docker Compose 通过处理网络、存储和其他基础设施问题的细节,简化了运行复杂的多容器应用程序的过程。 - -Kubernetes 清单是定义 Kubernete 对象(如 Pods、Deployments 和 Services)的 YAML 文件。清单提供了一种声明性的方法来定义应用程序的所需状态,包括副本数量、要使用的镜像和网络配置。Kubernetes 使用清单来创建和管理部署和运行应用程序所需的资源。 - -以下是一些参考资料,可以帮助了解更多关于 Docker Compose 和 Kubernetes 相关的信息: - -- [Docker Compose 文档](https://docs.docker.com/compose/) -- [Kubernetes 对象文档](https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/) - -以应用程序为中心的开发使开发人员能够专注于其工作负载的体系结构,而不是目标环境、基础设施或平台中的技术栈。我们用 `App` 结构定义了应用程序模型,然后使用 KCL CLI 将其翻译到多个平台,例如不同版本的 `Docker Compose` 或 `Kubernetes`。该应用程序模型旨在通过只需定义一个跨多个平台工作的 KCL 文件来减少开发人员的工作量和认知负荷。现在,让我们学习如何做到这一点。 - -### 1. 获取示例 - -首先,我们执行 git 命令获得用例 - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/abstraction -``` - -我们可以运行以下命令来显示配置。 - -```bash -cat main.k -``` - -输出为 - -```python -import .app - -app.App { - name = "app" - containers.nginx = { - image = "nginx" - ports = [{containerPort = 80}] - } - service.ports = [{ port = 80 }] -} -``` - -在上面的代码中,我们使用 `App` schema 定义了一个配置,其中我们配置了一个 `nginx` 容器,并开启 `80` 端口配置。 - -此外,KCL 允许开发人员以声明式的方式定义应用程序所需的资源,并允许生成特定于平台的配置文件,如 `docker_compose.yaml` 或 Kubernetes `manifests.yaml` 文件。接下来,让我们生成相应的配置。 - -### 2. 将应用配置转换为 Docker Compose 配置 - -如果我们想将应用程序配置转换为 Docker Compose 配置,我们可以简单地运行如下命令: - -```shell -kcl main.k docker_compose_render.k -``` - -输出为 - -```yaml -services: - app: - image: nginx - ports: - - published: 80 - target: 80 - protocol: TCP -``` - -### 3. 将应用配置转换为 Kubernetes Deployment and Service 资源清单 - -如果我们想将应用程序配置转换为 Kubernetes 清单,我们可以简单地运行如下命令: - -```shell -kcl main.k kubernetes_render.k -``` - -输出为 - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: app - labels: - app: app -spec: - replicas: 1 - selector: - matchLabels: - app: app - template: - metadata: - labels: - app: app - spec: - containers: - - name: nginx - image: nginx - ports: - - protocol: TCP - containerPort: 80 ---- -apiVersion: v1 -kind: Service -metadata: - name: app - labels: - app: app -spec: - selector: - app: app - ports: - - port: 80 - protocol: TCP -``` - -如果您想了解有关应用程序模型的更多信息,可以参考[此处](https://github.com/kcl-lang/kcl-lang.io/tree/main/examples/abstraction). - -## 小结 - -通过使用 KCL,我们能够分离模型的抽象和实现细节,允许将抽象模型映射到各种基础设施或平台。这是通过不同实现之间的灵活切换和 KCL 组合编译来实现的,以屏蔽配置差异,减轻认知负担。 - -## 更多信息 - -除了手动维护配置外,我们还可以使用 KCL API 将**自动配置更改能力**集成到我们的应用程序中。有关 KCL 自动化能力的相关说明,请参阅[此处](/docs/user_docs/guides/automation)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/automation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/automation.md deleted file mode 100644 index b8fa8d6f..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/automation.md +++ /dev/null @@ -1,201 +0,0 @@ ---- -title: "自动化" -sidebar_position: 6 ---- - -## 简介 - -在 KCL 中提供了很多自动化相关的能力,主要包括工具和多语言 API。 通过 `package_identifier : key_identifier`的模式支持对任意配置键值的索引,从而完成对任意键值的增删改查。比如下图所示修改某个应用配置的镜像内容,可以直接执行如下指令修改镜像,修改前后的 diff 如下图所示。 - -![](/img/blog/2022-09-15-declarative-config-overview/14-kcl-image-update.png) - -此外,KCL 的自动化能力也可以被集成到 CI/CD 中。 - -![](/img/blog/2022-09-15-declarative-config-overview/15-kcl-automation.png) - -## 使用 KCL 进行自动化 - -### 1. 获得示例 - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/automation -``` - -我们可以执行如下命令显示配置 - -```bash -cat main.k -``` - -输出为 - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "app" - replicas = 1 - labels.key = "value" -} -``` - -我们可以执行如下命令输出配置 - -```bash -kcl main.k -``` - -输出为 - -```yaml -app: - name: app - replicas: 1 - labels: - app: app - key: value -``` - -### 2. 使用 KCL CLI 进行自动化 - -KCL 允许使用通过 CLI `-O|--overrides` 参数修改配置模型中的值,这个参数通常由三个部分组成: 包名 `pkg`, 配置标识符 `identifier`, 配置属性 `attribute` 和覆盖值 `override_value` - -```bash -kcl main.k -O override_spec -``` - -- `override_spec`: 表示需要修改的配置模型字段和值的统一表示 - -```bash -override_spec: [[pkgpath] ":"] identifier ("=" value | "-") -``` - -- `pkgpath`: 表示需要修改标识符的包路径,通常为 `a.b.c` 的形式,对于 main 包,`pkgpath` 表示为 `__main__`, 可省略,省略不写时表示 main 包 -- `identifier`: 表示需要修改配置的标识符,通常为 `a.b.c` 的形式 -- `value`: 表示需要修改配置的值,可以是任意合法的 KCL 表达式,比如数字/字符串字面值,`list`/`dict`/`schema` 表达式等 -- `=`: 表示修改identifier的值 -- `-`: 表示删除 identifier 属性 - -请注意,当 `identifier` 多次出现时,修改/删除全部 `identifier` 的值 - -#### 修改配置 - -执行如下命令可以更新应用名称: - -```bash -kcl main.k -O app.name='new_app' -``` - -输出为 - -```yaml -app: - name: new_app - replicas: 1 - labels: - app: new_app - key: value -``` - -可以看出 `app` 的 `name` 属性的值被修改为了 `new_app` - -此外,当我们使用 KCL CLI `-d` 参数时,KCL 文件将同时修改为以下内容 - -```bash -kcl main.k -O app.name='new_app' -d -``` - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "new_app" - replicas = 1 - labels: {key = "value"} -} -``` - -#### 删除配置 - -执行如下命令可以删除 `labels` 中的 `key` 字段 - -```bash -kcl main.k -O app.labels.key- -``` - -输出为: - -```yaml -app: - name: app - replicas: 1 - labels: - app: app -``` - -执行如下命令 - -```bash -kcl main.k -O config.x- -``` - -输出结果为: - -```yaml -config: - x: 1 - y: s -``` - -### 3. 使用 KCL API 进行自动化 - -此外,我们还可以通过[多语言 API](/docs/reference/xlang-api/overview) 自动修改配置属性 - -以 RestAPI 为例 - -执行如下命令启动 RestAPI 服务端 - -```bash -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -通过如下命令 POST 命令请求配置修改服务 - -```bash -curl -X POST http://127.0.0.1:2021/api:protorpc/KclvmService.OverrideFile -H 'content-type: accept/json' -d '{ - "file": "main.k", - "specs": ["app.name=\"nginx\""] -}' -``` - -服务调用完成后,`main.k` 会被修改为如下形式: - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "nginx" - replicas = 1 - labels: { - "key" = "value" - } -} -``` - -## 小结 - -该文档介绍了KCL的自动化功能,包括工具和多语言 API。它支持对任何配置的键值进行索引,允许添加、删除、修改和查询任何键值。它也可以集成到 CI/CD 中。本文档提供了一个使用 KCL 自动化配置管理的示例,包括使用 KCL CLI/API 覆盖和删除配置。更多信息请参阅[此处](/docs/reference/lang/tour#KCL-cli-variable-Override)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/ci-integration/1-github-actions.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/ci-integration/1-github-actions.md deleted file mode 100644 index afb57d80..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/ci-integration/1-github-actions.md +++ /dev/null @@ -1,162 +0,0 @@ ---- -id: github-actions -sidebar_label: Github Actions ---- - -# Github Actions 集成 - -## 简介 - -在 GitOps 章节,我们介绍了如何将 KCL 与 GitOps 进行集成。在本文中,我们将继续提供 KCL 和 CI 集成的示例方案,希望通过使用容器、用于生成的持续集成 (CI) 和用于持续部署 (CD) 的 GitOps 来实现端到端应用程序开发流程。在此方案中,我们使用一个 Flask 应用和 Github Actions 将用作示例。 - -> 注意:你可以在此方案中使用任何容器化应用以及不同的 CI 系统如 Gitlab CI,Jenkins CI 等。 - -整体工作流程如下: - -- 应用代码开发并提交到提交到 GitHub 存储库 -- GitHub Actions 从应用代码生成容器镜像,并将容器镜像推送到 docker.io 容器注册表 -- GitHub Actions 根据 docker.io 容器注册表中容器镜像的版本号并同步更新 KCL 清单部署文件 - -## 具体步骤 - -### 1. 获得示例 - -我们将业务源码和部署清单放在不同仓库,可以分不同角色进行分别维护,实现关注点分离。 - -- 获得业务源码 - -```shell -git clone https://github.com/kcl-lang/flask-demo.git/ -cd flask-demo -``` - -这是一个使用 Python 编写的 Web 应用,我们可以使用应用目录的 `Dockerfile` 来生成这个应用的容器镜像,同时可以通过 Github CI 自动构建 `flask_demo` 镜像,CI 配置如下 - -```yaml -# This is a basic workflow to help you get started with Actions - -name: CI - -# Controls when the workflow will run -on: - # Triggers the workflow on push or pull request events but only for the main branch - push: - branches: [main] - pull_request: - branches: [main] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "build" - build: - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - - - name: Docker Login - uses: docker/login-action@v1.10.0 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - logout: true - - # Runs a set of commands using the runners shell - - name: build image - run: | - make image - docker tag flask_demo:latest ${{ secrets.DOCKER_USERNAME }}/flask_demo:${{ github.sha }} - docker push ${{ secrets.DOCKER_USERNAME }}/flask_demo:${{ github.sha }} - - # Trigger KCL manifest - - name: Trigger CI - uses: InformaticsMatters/trigger-ci-action@1.0.1 - with: - ci-owner: kcl-lang - ci-repository: flask-demo-kcl-manifests - ci-ref: refs/heads/main - ci-user: kcl-bot - ci-user-token: ${{ secrets.DEPLOY_ACCESS_TOKEN }} - ci-name: CI - ci-inputs: >- - image=${{ secrets.DOCKER_USERNAME }}/flask_demo - sha-tag=${{ github.sha }} -``` - -我们需要源码仓库的工作流自动触发部署清单仓库中的工作流,此时需要创建具有 Github CI 操作权限的 `secrets.DEPLOY_ACCESS_TOKEN` 以及 Docker Hub 镜像推送的账号信息 `secrets.DOCKER_USERNAME` 和 `secrets.DOCKER_PASSWORD`, 这些可以在 Github 仓库的 `Secrets and variables` 设置中进行配置,如下图所示 - -![](/img/docs/user_docs/guides/ci-integration/github-secrets.png) - -### 2. 提交应用代码 - -flask-demo 仓库提交代码后,Github 会自动构建容器镜像,并将制品推送到 Docker hub 中,会再触发 flask-demo-kcl-manifests 仓库的 Action,[通过 KCL 自动化 API](/docs/user_docs/guides/automation) 修改部署清单仓库中的镜像地址。现在让我们为 flask-demo 仓库创建一个提交,我们可以看到代码提交后触发业务仓库 Github CI 流程 - -![](/img/docs/user_docs/guides/ci-integration/app-ci.png) - -### 3. 配置自动更新 - -当业务仓库 Github CI 流程执行完成后,会自动在存放 KCL 资源配置的仓库触发一个 CI 自动更新配置并提交到 flask-demo-kcl-manifests main 分支,commit 信息如下 - -![](/img/docs/user_docs/guides/ci-integration/image-auto-update.png) - -- 我们可以获得部署清单源码进行编译验证 - -```shell -git clone https://github.com/kcl-lang/flask-demo-kcl-manifests.git/ -cd flask-demo-kcl-manifests -git checkout main && git pull && kcl -``` - -输出 YAML 为 - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - replicas: 1 - selector: - matchLabels: - app: flask_demo - template: - metadata: - labels: - app: flask_demo - spec: - containers: - - name: flask_demo - image: "kcllang/flask_demo:6428cff4309afc8c1c40ad180bb9cfd82546be3e" - ports: - - protocol: TCP - containerPort: 5000 ---- -apiVersion: v1 -kind: Service -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - type: NodePort - selector: - app: flask_demo - ports: - - port: 5000 - protocol: TCP - targetPort: 5000 -``` - -从上述配置可以看出资源的镜像确实自动更新为了新构建的镜像内容。此外,我们还可以使用 Argo CD KCL 插件 自动从 Git 存储库同步或从中拉取数据并将应用部署到 Kubernetes 集群。 - -## 小结 - -通过将 KCL 和 Github CI 集成,我们能够将任意的业务代码的产出容器化镜像进行自动化修改并部署配置,以实现端到端应用程序开发流程并提升研发部署效率。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/configuration.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/configuration.md deleted file mode 100644 index 5769d366..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/configuration.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -title: "配置" -sidebar_position: 1 ---- - -## 简介 - -配置是软件系统的一个重要方面,由于不断发展的业务需求、基础设施需求和其他因素,这些系统会不断发生变化。通常,快速改变这些系统的行为可能具有挑战性,尤其是当这样做需要昂贵且耗时的重建和重新部署过程时。在这种情况下,仅仅对业务代码进行更改可能是不够的。幸运的是,配置提供了一种低开销的方式来修改系统功能。 - -我们可以根据需要将静态配置存储在 JSON 或 YAML 等文件中。此外,配置也可以存储在高级语言中,从而实现更灵活的配置。这种语言可以进行编码、呈现和静态配置。KCL 是一种提供此类功能的配置语言。开发人员可以编写 KCL 代码来生成JSON/YAML 和其他配置。 - -## 使用 KCL 编写配置代码 - -KCL 的核心特性是其**建模**和**约束**能力,KCL 核心功能基本围绕 KCL 这个两个核心特性展开,对于代码而言(包括配置代码)都存在对配置数据约束的需求,比如类型约束、配置字段必选/可选约束、范围约束、不可变性约束等,这也是 KCL 致力于解决的核心问题之一。 - -现在我们已经了解了 KCL 的基本功能,让我们探索如何使用它来生成配置。 - -### 1. 获取示例 - -首先,执行如下命令获取示例 - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/configuration -``` - -我们可以执行如下命令显示配置代码 - -```shell -cat nginx.k -``` - -输出为: - -```python -schema Nginx: - """Schema for Nginx configuration files""" - http: Http - -schema Http: - server: Server - -schema Server: - listen: int | str # The attribute `listen` can be int type or a string type. - location?: Location # Optional, but must be non-empty when specified - -schema Location: - root: str - index: str - -nginx = Nginx { - http.server = { - listen = 80 - location = { - root = "/var/www/html" - index = "index.html" - } - } -} -``` - -### 2. 使用 KCL 生成 YAML - -执行如下命令: - -```bash -kcl nginx.k -``` - -我们可以获得如下 YAML 输出 - -```yaml -nginx: - http: - server: - listen: 80 - location: - root: /var/www/html - index: index.html -``` - -### 3. 为配置添加动态参数 - -此外,我们可以通过 KCL 内置函数 `option` 动态接收外部参数。例如,对于下面的 KCL 文件(db.k),我们可以使用命令行 `-D` 标志来接收外部动态参数。 - -```python -env: str = option("env") or "dev" # The attribute `env` has a default value "den" -database: str = option("database") -hosts = { - dev = "postgres.dev" - stage = "postgres.stage" - prod = "postgres.prod" -} -dbConfig = { - host = hosts[env] - database = database - port = "2023" - conn = "postgres://${host}:${port}/${database}" -} -``` - -```bash -# Use the `-D` flag to input external parameters. -kcl db.k -D database="foo" -``` - -输出为 - -```yaml -env: dev -database: foo -hosts: - dev: postgres.dev - stage: postgres.stage - prod: postgres.prod -dbConfig: - host: postgres.dev - database: foo - port: "2023" - conn: "postgres://postgres.dev:2023/foo" -``` - -## 小结 - -通过使用KCL,我们可以生成更低低级别的数据配置。此外啊,我们通过 `-D` 标志设置动态参数以满足不同的场景需求。有关更多 KCL 的功能和教程,请参阅[此处](/docs/reference/lang/tour)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/data-integration.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/data-integration.md deleted file mode 100644 index dfe18b03..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/data-integration.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: "数据集成" -sidebar_position: 4 ---- - -## 简介 - -在 KCL 中,不仅可以将 KCL 编写的配置代码编译输出为 YAML 格式的数据,还可以将 JSON/YAML 等数据直接嵌入到 KCL 语言当中。 - -## 使用 KCL 进行数据集成 - -### 1. 获得示例 - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/data-integration -``` - -### 2. YAML 集成 - -我们可以运行以下命令来显示 KCL YAML 集成配置。 - -```bash -cat yaml.k -``` - -```python -import yaml - -schema Server: - ports: [int] - -server: Server = yaml.decode("""\ -ports: -- 80 -- 8080 -""") -server_yaml = yaml.encode({ - ports = [80, 8080] -}) -``` - -在上述代码中,我们通过 KCL 内置的 `yaml` 模块以及其中的 `yaml.decode` 直接完成 YAML 数据的集成,并且使用 `Server` schema 对集成的 YAML 数据直接进行校验。此外,我们可以使用 `yaml.encode` 完成 YAML 数据的序列化。 - -我们通过如下命令可以获得配置输出: - -```shell -kcl yaml.k -``` - -输出为 - -```yaml -server: - ports: - - 80 - - 8080 -server_yaml: | - ports: - - 80 - - 8080 -``` - -### 3. JSON 集成 - -同样的,对于 JSON 数据,我们可以使用 `json.encode` 和 `json.decode` 函数以同样的方式进行数据集成。 - -我们可以运行以下命令来显示 KCL JSON 集成配置。 - -```bash -cat json.k -``` - -```python -import json - -schema Server: - ports: [int] - -server: Server = json.decode('{"ports": [80, 8080]}') -server_json = json.encode({ - ports = [80, 8080] -}) -``` - -执行命令输出为: - -```shell -kcl json.k -``` - -```yaml -server: - ports: - - 80 - - 8080 -server_json: '{"ports": [80, 8080]}' -``` - -## 小结 - -本文介绍了如何在 KCL 中进行数据集成,使用 KCL 内置的 yaml 和 json 包将 YAML 和 JSON 数据直接集成到 KCL 语言中,并使用相应的解码和编码功能对其进行验证和序列化。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/gitops/1-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/gitops/1-quick-start.md deleted file mode 100644 index e4888bd3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/gitops/1-quick-start.md +++ /dev/null @@ -1,141 +0,0 @@ ---- -id: gitops-quick-start -sidebar_label: 快速开始 ---- - -# 快速开始 - -## 简介 - -### 什么是 GitOps - -GitOps 是一种实现持续交付的现代方式。它的核心思想是拥有一个包含环境和应用程序配置的 Git 存储库。通过更改应用存储库中的文件,可以自动部署应用程序。应用 GitOps 的好处包括: - -- 提高生产力,持续交付可以加快部署时间。 -- 降低开发人员部署的障碍。通过推送代码而不是容器配置,开发人员可以在不知道其内部实现的情况下轻松部署 Kubernetes 集群和应用。 -- 追踪变更记录。使用 Git 管理配置使每一项更改都具有可跟踪性,从而增强审计跟踪。 - -### 将 KCL 与 ArgoCD 一起使用 - -将 [KCL](https://github.com/kcl-lang/kcl) 与 [ArgoCD](https://github.com/argoproj/argo-cd) 等 GitOps 工具一起使用具有如下好处: - -- 通过 KCL 语言的[抽象能力](/docs/user_docs/guides/abstraction)和可编程能力可以帮助我们**简化复杂的 Kubernetes 部署配置文件**,降低手动编写 YAML 文件的错误率,消除多余的配置模版,提升多环境多租户的配置扩展能力,同时提高配置的可读性和可维护性。 -- KCL 允许开发人员以声明式的方式定义应用程序所需的资源,通过将 KCL 和 ArgoCD 相结合可以帮助我们更好地实现**基础设施即代码(IaC)**,提高部署效率,简化应用程序的配置管理。 -- ArgoCD 可以**自动化**地实现应用程序的连续部署,并提供友好的可视化界面。 - -使用 GitOps,开发人员和运维团队可以通过分别修改应用和配置代码来管理应用程序的部署,GitOps 工具链将自动同步对配置的更改,从而实现持续部署并确保一致性。如果出现问题,可以使用 GitOps 工具链快速回滚。 - -## 快速开始 - -### 1. 获取示例 - -首先,我们执行 git 命令获得用例 - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/gitops -``` - -我们可以运行以下命令来显示配置 - -```bash -cat config/main.k -``` - -The output is - -```python -import .app - -config = app.App { - name = "kcl-guestbook-ui" - containers.guestbook = { - image = "gcr.io/heptio-images/ks-guestbook-demo:0.2" - ports = [{containerPort = 80}] - } - service.ports = [{ port = 80 }] - service.type = "LoadBalancer" -} -``` - -在上述代码中,我们定义使用 `App` schema 定义了应用的配置,其中我们配置了一个镜像为 `gcr.io/heptio-images/ks-guestbook-demo:0.2` 容器,并启用了 `80` 端口。 - -### 2. 安装 Kubernetes 和 GitOps 工具 - -#### 配置 Kubernetes 集群和 ArgoCD 控制器 - -- 安装 [K3d](https://github.com/k3d-io/k3d) 并创建一个集群 - -```bash -k3d cluster create mycluster -``` - -> 注意:你可以在此方案中使用其他方式创建您自己的 Kubernetes 集群,如 kind, minikube 等。 - -- 安装 [ArgoCD](https://github.com/argoproj/argo-cd/releases/). - -```bash -kubectl create namespace argocd -kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml -``` - -- 安装 ArgoCD KCL 插件 - -```bash -kubectl apply -f ./install/kcl-cmp.yaml && kubectl -n argocd patch deploy/argocd-repo-server -p "$(cat ./install/patch-argocd-repo-server.yaml)" -``` - -- 通过 `kubectl get` 命令查看 argocd 控制器容器是否初始化完成进入运行(Running)状态。 - -```bash -kubectl get pod -n argocd -l app.kubernetes.io/name=argocd-repo-server -``` - -- 通过如下命令打开 ArgoCD UI - -```bash -kubectl port-forward svc/argocd-server -n argocd 8080:443 -``` - -- 打开浏览器 `https://localhost:8080` 输入用户名 "admin" 和密码登陆 ArgoCD UI,密码可以通过如下命令得到: - -```bash -kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d -``` - -#### 安装 ArgoCD 客户端工具 - -- 安装 [ArgoCD 客户端工具](https://github.com/argoproj/argo-cd/releases) - -- 使用用户名 "admin" 和刚才得到的密码登陆 - -```bash -argocd login localhost:8080 -``` - -通过如下命令创建一个 ArgoCD KCL 应用 - -```bash -argocd app create guestbook \ ---repo https://github.com/kcl-lang/kcl-lang.io \ ---path examples/gitops/config \ ---dest-namespace default \ ---dest-server https://kubernetes.default.svc \ ---config-management-plugin kcl-v1.0 -``` - -如果创建成功,您可以看到如下输出: - -```bash -application 'guestbook' created -``` - -> 如果您使用的是私有存储库,则在执行 create 命令之前,需要使用私钥凭据配置专用私有存储库访问权限。请参阅[这里](https://argo-cd.readthedocs.io/en/stable/user-guide/private-repositories/)以获取更多详细信息。 - -通过 ArgoCD UI,您可以看到创建的应用程序尚未同步,您可以手动进行配置同步或设置为自动同步。 - -![](/img/docs/user_docs/guides/gitops/argocd-kcl-app.jpg) - -有关同步策略的更多信息,可以请参阅[这里](https://argo-cd.readthedocs.io/en/stable/user-guide/sync-options/) - -![](/img/docs/user_docs/guides/gitops/argocd-kcl-app-dashboard.jpg) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/package-management/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/package-management/_category_.json deleted file mode 100644 index d1600bfd..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/package-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "包管理", - "position": 7 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/schema-definition.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/schema-definition.md deleted file mode 100644 index f62d7815..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/schema-definition.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: "模型定义" -sidebar_position: 3 ---- - -## 简介 - -KCL 的核心场景是写配置和校验,因此 KCL 被设计之初的一个核心特性就是**建模**,对应到 KCL 的关键字 `schema`,`schema` 可以被用于定义结构和约束,比如字段的类型,默认值,字段的范围和各种其他约束等内容。此外,使用 KCL schema 定义的结构可以反过来用于验证实现、验证输入(JSON、YAML 等结构化数据)或生成代码(生成多语言结构体、OpenAPI 等)。 - -## 使用 KCL 定义结构和约束 - -### 1. 获得示例 - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/definition -``` - -我们可以执行如下命令显示配置 - -```bash -cat main.k -``` - -输出为 - -```python -import .app_module # A relative path import - -app: app_module.App { - domainType = "Standard" - containerPort = 80 - volumes = [ - { - mountPath = "/tmp" - } - ] - services = [ - { - clusterIP = "None" - $type = "ClusterIP" - } - ] -} -``` - -我们将 `App` 模型放入单独的 `app_module.k` 中,在需要时我们可以在 `main.k` 中使用 `import` 关键字进行模块化管理,比如下面的文件结构 - -``` -. -├── app_module.k -└── main.k -``` - -其中 `app_module.k` 的内容为 - -```python -schema App: - domainType: "Standard" | "Customized" | "Global" - containerPort: int - volumes: [Volume] - services: [Service] - - check: - 1 <= containerPort <= 65535 - -schema Service: - clusterIP: str - $type: str - - check: - clusterIP == "None" if $type == "ClusterIP" - -schema Volume: - container: str = "*" # `container` 的默认值为 "*" - mountPath: str - - check: - mountPath not in ["/", "/boot", "/home", "dev", "/etc", "/root"] -``` - -在上面的文件中。在其中,我们使用 `schema` 关键字定义了三个模型 `App`,`Service` 和 `Volume`。并且 `App` 模型具有四个属性 `domainType`, `containerPort`, `volumes` 和 `services`,其中 - -- `domainType` 的类型为字符串字面值联合类型,与“枚举”类似,这表明 `domainType` 的值只能取 `"Standard"`, `"Customized"` 和 `"Global"` 中的一个 -- `containerPort` 的类型为整数 `int`, 此外我们使用 `check` 关键字定义了其取值范围 1 ~ 65535 -- `services` 的类型为 `Service` 列表类型,`Service`,并且我们用 `?` 标记了它是一个可选属性,这意味着我们可以不为其赋值。 -- `volumes` 的类型为 `Volume` 列表类型,并且我们用 `?` 标记了它是一个可选属性,这意味着我们可以不为其赋值。 - -### 2. 输出配置 - -我们可以使用如下命令行可以获得 `app` 实例的 YAML 输出 - -```shell -kcl main.k -``` - -输出为 - -```yaml -app: - domainType: Standard - containerPort: 80 - volumes: - - container: "*" - mountPath: /tmp - services: - - clusterIP: None - type: ClusterIP -``` - -## 小结 - -KCL 是一种用于定义配置和约束的语言,其核心功能是使用 schema 关键字进行建模,schema 允许定义具有属性、默认值、范围检查和其他约束的结构。使用 KCL schema 定义的结构可以用于验数据或生成代码。该文档演示了如何使用 schema 定义模型,使用 import 导入模型进行模块化管理,并使用 kcl 命令输出已定义结构实例的 YAML 配置。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/validation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/validation.md deleted file mode 100644 index 6e879c47..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/validation.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: "校验" -sidebar_position: 2 ---- - -## 简介 - -验证是校验数据是否准确、可靠并满足某些要求或限制的过程,包括检查数据的完整性、一致性、准确性和相关性。进行数据验证是为了确保数据符合其预期目的,并能有效使用。 - -我们可以使用 KCL 及其校验工具手动或自动进行数据验证,以确保数据的一致性。 - -## 使用 KCL 校验数据 - -除了使用 KCL 代码生成 JSON/YAML 等配置格式,KCL 还支持对 JSON/YAML 数据进行格式校验。作为一种配置语言,KCL 在验证方面几乎涵盖了 OpenAPI 的所有功能。在 KCL 中可以通过一个结构定义来约束配置数据,同时支持通过 check 块自定义约束规则,在 schema 中书写校验表达式对 schema 定义的属性进行校验和约束。通过 check 表达式可以非常清晰简单地校验输入的 JSON/YAML 是否满足相应的 schema 结构定义与 check 约束。 - -### 1. 获得示例 - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/validation -``` - -我们可以执行如下命令显示配置 - -```bash -cat schema.k -``` - -输出为 - -```python -schema User: - name: str - age: int - message?: str - data: Data - labels: {str:} - hc: [int] - - check: - age > 10, "age must > 10" - -schema Data: - id: int - value: str -``` - -在 schema 中,我们可以使用 `check` 关键字来编写每个 schema 属性的验证规则。`check` 块中的每一行都对应于一个条件表达式。当满足条件时,验证成功。条件表达式后面可以跟 `, "报错信息"`,以指示检查失败时要给用户显示的消息。 - -综上所述,KCL Schema 中支持的校验类型为: - -| 校验类型 | 使用方法 | -| -------- | ---------------------------------------------------------- | -| 范围校验 | 使用 `<`, `>` 等比较运算符 | -| 正则校验 | 使用 `regex` 系统库中的 `match` 等方法 | -| 长度校验 | 使用 `len` 内置函数,可以求 `list/dict/str` 类型的变量长度 | -| 枚举校验 | 使用字面值联合类型 | -| 非空校验 | 使用 schema 的可选/必选属性 | -| 条件校验 | 使用 check if 条件表达式 | - -### 2. 验证数据 - -新建一个名为 `data.json` 的 JSON 配置文件: - -```json -{ - "name": "Alice", - "age": 18, - "message": "This is Alice", - "data": { - "id": 1, - "value": "value1" - }, - "labels": { - "key": "value" - }, - "hc": [1, 2, 3] -} -``` - -执行如下命令获得校验结果 - -```bash -kcl-vet data.json schema.k -``` - -## 小结 - -KCL 是一种配置语言,通过其结构定义和用户定义的约束规则来支持数据验证。KCL Schema 中支持的验证类型包括范围、正则表达式、长度、枚举、可选/必需和条件。并且可以使用 KCL 验证工具或在此基础上构建的可视化产品来验证数据。 - -## 未来计划 - -KCL 校验能力的提升将逐渐围绕"静态化"方面展开工作,即在编译时,结合形式化验证的能力直接分析得出数据是否满足约束条件、约束条件是否冲突等结论,并且可以通过 IDE 实时透出约束错误,而无需在运行时发现错误。 - -我们还期望 KCL Schema 和约束可以作为一个包来管理(这个包只有 KCL 文件)。例如,Kubernetes 模型和约束可以开箱即用。用户可以生成配置或验证现有配置,并且可以通过 KCL 继承简单地扩展用户想要的模型和约束。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md deleted file mode 100644 index 5ebfe83c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: "从 Kubernetes 迁移" -sidebar_position: 1 ---- - -## 简介 - -KCL 对 Kubernetes 配置提供了许多开箱即用的支持,通过 KCL 工具,我们可以将 Kubernetes Schema 和 配置集成到 KCL 中,本节内容将介绍如何使用 KCL 对 Kubernetes 进行集成 - -### 1. Kubernetes OpenAPI Spec - -从 Kubernetes 1.4 开始,引入了对 OpenAPI 规范(在捐赠给 Open API Initiative 之前称为 swagger 2.0)的 alpha 支持,API 描述遵循 [OpenAPI 规范 2.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md),从 Kubernetes 1.5 开始,Kubernetes 能够直接从[源码自动地提取模型并生成 OpenAPI 规范](https://github.com/kubernetes/kube-openapi),自动化地保证了规范和文档与操作/模型的更新完全同步。 - -此外,Kubernetes CRD 使用 [OpenAPI v3.0 validation](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation) 来描述(除内置属性 apiVersion、kind、metadata 之外的)自定义 schema,在 CR 的创建和更新阶段,APIServer 会使用这个 schema 对 CR 的内容进行校验。 - -### 2. KCL OpenAPI 支持 - -KCLOpenAPI 工具支持从 OpenAPI/CRD 定义提取并生成 KCL schema. 在 KCLOpenAPI Spec 中明确定义了 OpenAPI 规范与 KCL 语言之间的映射关系。 - -### 3. 从 Kubernetes 模型迁移到 KCL - -#### 3.1 基于 kusion_models 编写配置 - -我们为你提供了一个开箱即用的 `kusion_models` 包,让你可以快速开始。其中包含一个精心设计的前端模型,称为[服务器模型](https://github.com/KusionStack/konfig/blob/main/base/pkg/kusion_models/kube/frontend/server.k)(Server schema)。你可以通过初始化 `Server schema` 来声明其配置。有关模式及其属性的说明和用法,请参阅 [Server schema 文档](https://kusionstack.io/docs/reference/model/kusion_models/kube/frontend/doc_server)。 - -#### 3.2 创建自定义的 models 前端模型 - -现有的 `kusion_models` 模型可能无法满足你的特定业务需求,那么你也可以设计自定义前端模型包。 您可基于预先生成的 Kubernetes KCL 包自定义您的前端模型。您还可以仿照`kube2kcl` 工具的模式,开发自定义脚本,完成配置数据的迁移。 - -##### 3.2.1 获取 Kubernetes KCL 模型 - -我们提供了预生成的各版本[Kubernetes KCL模型](https://github.com/orgs/KusionStack/packages/container/package/k8s),您可以在项目下执行 `kpm add k8s:` 来获得它。有关 kpm 使用的详细信息,请参考 [kpm快速入门指南](https://github.com/kcl-lang/kpm#quick-start)。 - -或者,如果您需要自己生成这些包,请参考[从 Kubernetes OpenAPI 文件生成 KCL 包](https://github.com/kcl-lang/kcl-openapi/blob/main/docs/generate_from_k8s_spec.md)。 - -##### 3.2.2 编写自定义前端模型 - -由于 Kubernetes 内置模型较为原子化和复杂,我们推荐以 Kubernetes 原生模型作为后端输出的模型,对其进一步抽象,而向用户暴露一份更为友好和简单的前端模型界面,具体您可参照 Konfig 仓库中 [kusion_models Server](https://github.com/KusionStack/konfig/blob/main/base/pkg/kusion_models/kube/frontend/server.k) 模型的设计方式进行。 - -##### 3.2.3 迁移配置数据 - -对于存量的 Kubernetes 配置数据,您可以仿照 kube2Kcl 工具的做法,编写自定义的转换脚本,进行一键迁移。Kusion 后续将提供该脚本的编写脚手架和编写指南。 - -### 4. 从 Kubernetes CRD 迁移 - -如果您的项目中使用了 CRD,也可以采用类似的模式,生成 CRD 对应的 KCL schema,并基于该 schema 声明 CR。 - -- 从 CRD 生成 KCL Schema - - ``` - kcl-openapi generate model --crd --skip-validation -f your_crd.yaml - ``` - -- 使用 KCL 声明 CR - - 使用 KCL 声明 CR 的模式与声明 Kubernetes 内置模型配置的模式相同,在此不做赘述。 - -## 小结 - -本节介绍了如何使用 kcl-openapi 工具将 OpenAPI 规范映射到 KCL 语言特性,此外提供了将 KCL 与 OpenAPI 和 Kubernetes CRD 一起使用的快速入门指南帮助从 Kubernetes 进行迁移或集成。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-konfig/1-overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-konfig/1-overview.md deleted file mode 100644 index b112e946..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-konfig/1-overview.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -id: overview -sidebar_label: 概述 ---- - -# Konfig 概述 - -在 KCL 中推荐通过**配置库**的方式统一管理所有的配置清单和模型库,即不仅存放抽象模型本身的 KCL 定义,还存放各种类型的配置清单,比如应用的运维配置、策略配置等。配置大库推荐托管在各类 VCS 系统中,以方便做配置的回滚和漂移检查。配置大库的最佳实践代号为 Konfig,仓库托管在 [Github](https://github.com/KusionStack/konfig)。 - -⚡️ 配置大库主要包括: - -- KCL 模块声明文件(kcl.mod) -- KCL 领域模型库 (Kubernetes, Prometheus 等) -- 各类配置清单目录 (应用运维配置等) -- 配置构建和测试脚本 (Makefile,Github CI 文件等) - -之所以用一个统一的仓库管理全部的 KCL 配置代码,是由于不同代码包的研发主体不同,会引发出包管理和版本管理的问题。将业务配置代码、基础配置代码在一个统一仓库中,代码间的版本依赖管理会比较简单,通过定位唯一代码库的目录及文件即可,可以将配置代码统一管理,便于查找、修改、维护。 - -下面是配置大库(Konfig)的架构图: - -![](/img/docs/user_docs/guides/konfig/konfig-arch.png) - -Konfig 提供给用户开箱即用、高度抽象的配置界面,模型库最初朴素的出发点就是改善 YAML 用户的效率和体验,我们希望通过将代码更繁杂的模型抽象封装到统一的模型中,从而简化用户侧配置代码的编写。Konfig 由以下部分组成: - -- **核心模型**: - - **前端模型**:前端模型即「用户界面」,包含平台侧暴露给用户的所有可配置属性,其中省略了一些重复的、可推导的配置,抽象出必要属性暴露给用户,具有用户友好的特性,比如 server.k。 - - **后端模型**:后端模型是「模型实现」,是让前端模型属性生效的模型,主要包含前端模型实例的渲染逻辑,后端模型中可借助 KCL 编写校验和逻辑判断等以提高配置代码复用性和健壮性,对用户不感知,比如 server_backend.k -- **领域模型**:是不包含任何实现逻辑和抽象的模型,往往由工具转换生成,无需修改,和真正生效的 YAML 属性一一对应,底层模型需要经过进一步抽象,一般不直接被用户使用。比如,kusion_kubernetes 是 Kubernetes 场景的底层模型库。 - -此外,核心模型内部通过前端模型和后端模型两层抽象简化前端用户的配置代码,底层模型则是通过 KCL OpenAPI 工具自动生成。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-konfig/2-structure.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-konfig/2-structure.md deleted file mode 100644 index cc54087e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-konfig/2-structure.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -id: structure -sidebar_label: 工程结构 ---- - -# Konfig 工程结构 - -本文主要解释 Konfig 配置大库的目录和代码结构 - -## 整体结构 - -```bash -. -├── .github # CI 脚本 -├── Makefile # 通过 Makefile 封装常用命令 -├── README.md # 配置大库说明 -├── appops # 应用运维目录,用来放置所有应用的 KCL 运维配置 -│ ├── clickhouse-operator -│ ├── code-city -│ ├── guestbook -│ ├── http-echo -│ └── nginx-example -├── base # 模型库 -│ ├── examples # 样例代码 -│ │ ├── monitoring # 监控配置样例 -│ │ ├── native # Kubernetes 资源配置样例 -│ │ ├── provider # 基础资源配置样例 -│ │ └── server # 云原生应用运维配置模型样例 -│ └── pkg -│ ├── kusion_kubernetes # Kubernetes 底层模型库 -│ ├── kusion_models # 核心模型库 -│ ├── kusion_prometheus # Prometheus 底层模型库 -│ └── kusion_provider # 基础资源 底层模型库 -└── kcl.mod # 大库配置文件,通常用来标识大库根目录位置以及大库所需依赖 -``` - -## 核心模型库结构 - -核心模型库一般命名为 kusion_models,主要包含前端模型、后端模型、Mixin、渲染器等,目录结构为: - -```bash -├── commons # 基础资源核心模型库 -├── kube # 云原生资源核心模型库 -│ ├── backend # 后端模型 -│ ├── frontend # 前端模型 -│ │ ├── common # 通用前端模型 -│ │ ├── configmap # ConfigMap 前端模型 -│ │ ├── container # 容器前端模型 -│ │ ├── ingress # Ingress 前端模型 -│ │ ├── resource # 资源规格前端模型 -│ │ ├── secret # Secret 前端模型 -│ │ ├── service # Service 前端模型 -│ │ ├── sidecar # Sidecar 容器前端模型 -│ │ ├── strategy # 策略前端模型 -│ │ ├── volume # Volume 前端模型 -│ │ └── server.k # 云原生应用运维前端模型 -│ ├── metadata # 应用运维的元数据模型 -│ ├── mixins # 统一放置可复用的 Mixin -│ ├── render # 渲染器,把前后端模型联系在一起的桥梁 -│ ├── templates # 静态配置 -│ └── utils # 工具方法 -└── metadata # 通用元数据模型 -``` - -## Project 和 Stack 结构 - -![](/img/docs/user_docs/concepts/project-stack.png) - -Project 和 Stack 是用于组织 Konfig 的逻辑隔离概念。 - -### Project - -任何包含文件 "project.yaml" 的文件夹都将被视为一个 Project,"project.yaml" 用于描述此 Project 的元数据,如 "name" 和 "tenant" 等。项目必须具有明确的业务语义,用户可以将应用程序或运维场景映射到项目。 - -### Stack - -与Project一样,包含文件 "stack.yaml" 的任何文件夹都将被视为一个 Stack,"stack.yaml" 用于描述此 Stack 的元数据。Stack 是一组 KCL 文件,表示可以单独配置和部署的最小操作单元,它通常代表 CI/CD 过程中的不同阶段。 - -### Project 与 Stack 之间的关系 - -一个 Project 包含一个或多个 Stack,Stack 必须属于且只能属于一个 Project。用户可以根据自己的需要解释 Project 和 Stack 的含义,并灵活组织 Konfig 结构。根据我们的经验,我们提供以下示例作为最佳实践: - -```bash -├── README.md # Project 介绍文件 -├── base # 各环境通用配置 -│ └── base.k # 通用 KCL 配置 -├── dev # 环境特有配置 -│ ├── ci-test # 测试目录 -│ │ ├── settings.yaml # 测试数据 -│ │ └── stdout.golden.yaml # 测试期望结果 -│ ├── kcl.yaml # 多文件编译配置,是 KCL 编译的入口 -│ ├── main.k # 当前环境 KCL 配置 -│ └── stack.yaml # Stack 配置文件 -└── project.yaml # Project 配置文件 -``` - -Project 通常表示一个应用程序,Stack 表示该应用程序的不同环境的配置,例如 dev、pre 和 prod 等。通用配置可以存储在该 Project 下的 "base" 目录中。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-konfig/3-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-konfig/3-quick-start.md deleted file mode 100644 index 92c9849d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-konfig/3-quick-start.md +++ /dev/null @@ -1,198 +0,0 @@ ---- -id: guide -sidebar_label: 快速开始 ---- - -# 简介 - -本篇指南向你展示,如何使用 KCL 语言与其相对应的 CLI 工具,完成一个运行在 Kubernetes 中的 Long-Running 应用的部署,我们将组织配置的单位叫做应用(Application),描述应用部署和运维细节的配置集合叫做应用服务(Server),它本质上是通过 KCL 定义的运维模型。 - -要将一个运行在 Kubernetes 中的应用完全部署起来,一般需要下发多个 Kubernetes 资源,本次演示的样例涉及以下 Kubernetes 资源: - -- 命名空间(Namespace) -- 无状态工作负载(Deployment) -- 服务(Service) - -> 不清楚相关概念的,可以前往 Kubernetes 官方网站,查看相关说明: - -- [Learn Kubernetes Basics](https://kubernetes.io/docs/tutorials/kubernetes-basics/) -- [Namespace](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/) -- [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) -- [Service](https://kubernetes.io/docs/concepts/services-networking/service/) - -## 准备工作 - -在开始之前,我们需要做以下准备工作: - -1. 安装 KCL, 详情信息请参阅[下载和安装](/docs/user_docs/getting-started/install)。 - -2. 下载开源 Konfig 大库,仓库地址: [https://github.com/KusionStack/konfig.git](https://github.com/KusionStack/konfig.git) - -```shell -git clone https://github.com/KusionStack/konfig.git && cd konfig -``` - -## 快速开始 - -### 1. 配置编译 - -Konfig 的编程语言是 KCL,不是 Kubernetes 认识的 JSON/YAML,因此还需要编译得到最终输出。 - -进入到项目的 Stack 目录(`appops/nginx-example/dev`)并执行编译: - -```bash -cd appops/nginx-example/dev && kcl -Y kcl.yaml -D __konfig_output_format__=raw -``` - -可以获得如下 YAML 输出: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-exampledev - namespace: nginx-example -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - template: - metadata: - labels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - spec: - containers: - - image: nginx:1.7.8 - name: main - ports: - - containerPort: 80 - protocol: TCP - resources: - limits: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi - requests: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi ---- -apiVersion: v1 -kind: Namespace -metadata: - name: nginx-example ---- -apiVersion: v1 -kind: Service -metadata: - name: nginx-example - namespace: nginx-example -spec: - ports: - - nodePort: 30201 - port: 80 - targetPort: 80 - selector: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - type: NodePort -``` - -完成编译,可以看到 3 个资源: - -- 一个 name 为 nginx-exampledev 的 Deployment -- 一个 name 为 nginx-example 的 Namespace -- 一个 name 为 nginx-example 的 Service - -以上就完成了配置生效,后续可以使用 `kubectl apply` 等命令下发并检查资源的实际状态,本文不在赘述。 - -### 2. 配置修改 - -Server 模型中的 image 属性用于声明应用的业务容器镜像,我们可以修改 base/main.k 中的 image 的值进行镜像修改或升级: - -```diff -14c14 -< image = "nginx:1.7.8" ---- -> image = "nginx:latest" -``` - -重新编译配置代码可以获得修改后的 YAML 输出: - -```shell -kcl -Y kcl.yaml -D __konfig_output_format__=raw -``` - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-exampledev - namespace: nginx-example -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - template: - metadata: - labels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - spec: - containers: - - image: nginx:latest - name: main - ports: - - containerPort: 80 - protocol: TCP - resources: - limits: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi - requests: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi ---- -apiVersion: v1 -kind: Namespace -metadata: - name: nginx-example ---- -apiVersion: v1 -kind: Service -metadata: - name: nginx-example - namespace: nginx-example -spec: - ports: - - nodePort: 30201 - port: 80 - targetPort: 80 - selector: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - type: NodePort -``` - -## 小结 - -本文主要介绍了如何使用 KCL 语言与其相对应的 Konfig 库,完成一个运行在 Kubernetes 中的 Long-Running 应用的部署。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/support/faq-install.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/support/faq-install.md deleted file mode 100644 index 1c98f224..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/support/faq-install.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -sidebar_position: 5 ---- - -# 安装问题 - -## MacOS 提示无法打开 "kcl",因为 Apple 无法检查其是否包含恶意软件 - -MacOS 提示无法打开 "kcl",因为 Apple 无法检查其是否包含恶意软件。这个错误是因为 macOS 操作系统中的 Gatekeeper 安全功能阻止了应用程序的运行。要解决此问题,请按照以下步骤操作: - -打开"系统偏好设置"并点击"安全性与隐私"。 在"通用"选项卡中,您将看到一个消息:"kcl" 已被阻止。单击"仍要打开"。 或者,你可以单击"打开任何方式"以打开你的应用程序。(可能需要使用管理员权限来打开应用程序。) - -如果不想在每次打开应用程序时都执行这些步骤,则可以的应用程序添加到白名单中,以便在不受阻止的情况下运行。要将您的应用程序添加到白名单中,请执行以下操作: - -打开终端并输入以下命令: - -```shell -xattr -rd com.apple.quarantine /path/to/kcl -``` - -其中,/path/to/kcl 是 kcl 应用程序的完整路径。运行命令后,应用程序将被添加到白名单中,Gatekeeper 将不再阻止其运行。 - -## 在 Windows/Linux/MacOS 平台上抱 program not found 或者 run linker failed 错误 - -请确保如下依赖在您的 PATH 中 - -- MacOS: `clang` -- Linux: `gcc` -- Windows: `cl.exe` (可以通过安装 MSVC 获得) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/support/faq-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/support/faq-kcl.md deleted file mode 100644 index 8330dfd6..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/support/faq-kcl.md +++ /dev/null @@ -1,2355 +0,0 @@ ---- -sidebar_position: 2 ---- - -# KCL 语法 - -## 1. 如何用 KCL 写一个简单的 key-value 对配置 - -创建一个名为 `config.k` 的文件 - -```python -cpu = 256 -memory = 512 -image = "nginx:1.14.2" -service = "my-service" -``` - -上述 KCL 代码中,定义了 4 个变量 `cpu` 和 `memory` 被声明为整数类型,并且它们的值分别为 `256` 和 `512`,而 `image` 和 `service` 是字符串类型,它们的值分别为 `image` 和 `service` - -使用如下命令可以将上述 KCL 文件编译为 YAML 进行输出 - -``` -kcl config.k -``` - -得到的 YAML 输出为: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -如果想要输出到文件,可以使用 `-o|--output` 参数: - -``` -kcl config.k -o config.yaml -``` - -## 2. KCL 中有哪些基本的数据类型? - -KCL 目前的基本数值类型和值包含: - -- 整数类型 `int` - - 举例: 十进制正整数 `1`, 十进制负整数 `-1`, 十六进制整数 `0x10`, 八进制整数 `0o10`, 二进制整数 `0b10` -- 浮点数类型 `float` - - 举例: 正浮点数 `1.10`, `1.0`, 负浮点数 `-35.59`, `-90.`, 科学记数法浮点数 `32.3e+18`, `70.2E-12` -- 布尔类型 `bool` - - 举例: 真值 `True`, 假值 `False` -- 字符串类型 `str` - 使用引号 `'`, `"` 标记 - - 举例: 双引号字符串 `"string"`, `"""string"""`, 单引号字符串 `'string'`, `'''string'''` -- 列表类型 `list` - 使用 `[`, `]` 标记 - - 举例: 空列表 `[]`, 字符串列表 `["string1", "string2", "string3"]` -- 字典类型 `dict` - 使用 `{`, `}` 标记 - - 举例: 空字典 `{}`, 键值均为字符串类型的字典 `{"key1": "value1", "key2": "value2"}` -- 结构类型 `schema` - 使用关键字 `schema` 定义,并使用相应的 schema 名称进行实例化 -- 空值类型 `None` - 用于表示一个变量的值为空,与输出 YAML 的 `null` 值对应 -- 未定义值类型 `Undefined` - 用于表示一个变量未被赋值,值为 `Undefined` 的变量不会被输出到 YAML 中 - -```python -schema Person: - name: str - age: int - -alice = Person { - name = "Alice" - age = 18 -} -bob = Person { - name = "Bob" - age = 10 -} -``` - -注意: 所有 KCL 类型的变量均可赋值为空值 `None` 和未定义的值 `Undefined` - -## 3. 有些 KCL 变量名带 `_` 下划线前缀表示什么?和不带 `_` 下划线前缀的区别是什么?分别适合什么场景下使用? - -KCL 中带下划线前缀的变量表示一个**隐藏**的,**可变**的变量,**隐藏**表示带下划线前缀的变量不会被输出到 YAML 当中,包括包级别的下划线前缀变量和 schema 当中的下划线前缀变量。**可变**表示带下划线前缀的变量可被多次重复赋值,不带下划线前缀的变量被赋值后不可变。 - -带 `_` 下划线前缀的变量与不带 `_` 下划线前缀变量的区别是: 不带 `_` 下划线前缀变量默认是导出到 YAML 当中的,并且具有强不可变性;带 `_` 下划线前缀变量是不导出的,可变的。 - -```python -name = 'Foo' # 导出变量,不可变变量 -name = 'Bar' # 错误:导出变量只能设置一次 -``` - -```python -_name = 'Foo' # 隐藏变量,可变变量 -_name = 'Bar' - -schema Person: - _name: str # hidden and mutable -``` - -## 4. 如何向 dict 中添加元素? - -可以使用 union 运算符 `|`, 或者 dict 解包运算符 `**` 来向 dict 中添加一个元素,并且可以使用 `in`,`not in` 等关键字判断 dict 变量当中是否包含某一个键值 - -```python -_left = {key: {key1 = "value1"}, intKey = 1} # 注意使用 = 表示覆盖 -_right = {key: {key2 = "value2"}, intKey = 2} -dataUnion = _left | _right # {"key": {"key1": "value1", "key2": "value2"}, "intKey": 2} -dataUnpack = {**_left, **_right} # {"key": {"key1": "value1", "key2": "value2"}, "intKey": 2} -``` - -输出 YAML 为: - -```yaml -dataUnion: - key: - key1: value1 - key2: value2 - intKey: 2 -dataUnpack: - key: - key1: value1 - key2: value2 - intKey: 2 -``` - -此外还可以使用 `字符串插值` 或者字符串 `format` 成员函数特性向 kcl dict 添加变量键值对 - -```python -dictKey1 = "key1" -dictKey2 = "key2" -data = { - "${dictKey1}" = "value1" - "{}".format(dictKey2) = "value2" -} -``` - -输出 YAML 为: - -```yaml -dictKey1: key1 -dictKey2: key2 -data: - key1: value1 - key2: value2 -``` - -## 5. 如何修改 dict 中的元素? - -我们可以使用 union 运算符 `|`, 或者解包运算符 `**` 修改 dict 当中的元素 - -```python -_data = {key = "value"} # {"key": "value"} -_data = _data | {key = "override_value1"} # {"key": "override_value1"} -_data = {**_data, **{key = "override_value2"}} # {"key": "override_value2"} -``` - -如果想要删除 dict 中某个键为 `key` 的值,可以使用解包运算符 `**{key = Undefined}` 或者合并运算符 `| {key = Undefined}` 进行覆盖,覆盖后 key 的值为 Undefined,不会进行 YAML 输出。 - -## 6. 如何向 list 中添加元素? - -在 list 中添加元素有两种方式: - -- 使用 `+`, `+=` 和 slice 切片连接组装 list 变量达到向 list 中添加元素的目的 - -```python -_args = ["a", "b", "c"] -_args += ["end"] # 在list尾部添加元素"end", ["a", "b", "c", "end"] -_args = _args[:2] + ["x"] + _args[2:] # 在list索引为2的地方插入元素"x", ["a", "b", "x", "c", "end"] -_args = ["start"] + _args # 在list头部添加元素"start", ["start", "a", "b", "x", "c", "end"] -``` - -- 使用 `*` 解包运算符连接合并 list - -```python -_args = ["a", "b", "c"] -_args = [*_args, "end"] # 在list尾部添加元素"end", ["a", "b", "c", "end"] -_args = ["start", *_args] # 在list头部添加元素"start", ["start", "a", "b", "c", "end"] -``` - -注意:当接连的变量为 `None/Undefined` 时,使用 `+` 可能会发生错误,这时使用 list 解包运算符 `*` 或者使用 `or` 运算符取 list 的默认值可以避免空值判断 - -```python -data1 = [1, 2, 3] -data2 = None -data3 = [*data1, *data2] # Right [1, 2, 3] -data4 = data1 + data2 or [] # Right [1, 2, 3], 使用 or 取 data2 的默认值为 [], 当 data2 为 None/Undefined 时,取空列表 [] 进行计算 -data5 = data1 + data2 # Error: can only concatenate list (not "NoneType") to list -``` - -## 7. 如何修改/删除 list 中的元素? - -修改 list 中的元素分为两种方式: - -- 直接修改 list 某个索引处的值,使用 slice 切片 - -```python -_index = 1 -_args = ["a", "b", "c"] -_args = _args[:index] + ["x"] + _args[index+1:] # 修改list索引为1的元素为"x", ["a", "x", "c"] -``` - -- 根据某个条件修改 list 当中的元素,使用 list comprehension 列表推导式 - -```python -_args = ["a", "b", "c"] -_args = ["x" if a == "b" else a for a in _args] # 将list当中值为"b"的值都修改为"x", ["a", "x", "c"] -``` - -删除 list 中的元素分为两种方式: - -- 使用 list for 推导表达式中 if 过滤条件 -- 使用 filter 表达式对 list 进行元素过滤 - -比如想要删除一个列表 `[1, 2, 3, 4, 5]` 中大于 2 的数字,则在 KCL 中可以写为: - -```python -originList = [1, 2, 3, 4, 5] -oneWayDeleteListItem = [item for item in originList if item <= 2] -anotherWayDeleteListItem = filter item in originList { - item <= 2 -} -``` - -输出如下结果 - -```yaml -originList: - - 1 - - 2 - - 3 - - 4 - - 5 -oneWayDeleteListItem: - - 1 - - 2 -anotherWayDeleteListItem: - - 1 - - 2 -``` - -## 8. 怎样写 for 循环?怎样理解和使用 list comprehension 列表推导式 和 dict comprehension 字典推导式 ? - -KCL 目前仅支持函数式/声明式的推导式 for 循环方式,可以按照如下方式遍历 dict 和 list 变量: - -list 推导式具体形式为(其中推导式两边使用方括号 `[]`): - -```txt -[expression for expr in sequence1 - if condition1 - for expr2 in sequence2 - if condition2 - for expr3 in sequence3 ... - if condition3 - for exprN in sequenceN - if conditionN] -``` - -dict 推导式具体形式为(其中推导式两边使用花括号 `{}`): - -```txt -{expression for expr in sequence1 - if condition1 - for expr2 in sequence2 - if condition2 - for expr3 in sequence3 ... - if condition3 - for exprN in sequenceN - if conditionN} -``` - -上述推导式中的 `if` 表示过滤条件,满足条件的表达式 `expr` 才会生成到新的 list 或 dict 中 - -list 推导式举例: - -```python -_listData = [1, 2, 3, 4, 5, 6] -_listData = [l * 2 for l in _listData] # _listData中所有元素都乘以2,[2, 4, 6, 8, 10, 12] -_listData = [l for l in _listData if l % 4 == 0] # 筛选出_listData中可以被4整除的所有元素,[4, 8, 12] -_listData = [l + 100 if l % 8 == 0 else l for l in _listData] # 遍历_listData, 当其中的元素可以被8整除时,将该元素加100,否则保持不变, [4, 108, 12] -``` - -注意上述代码中第 3 行和第 4 行两个 `if` 的区别: - -- 第一个 `if` 表示 list 变量 `_listData` 本身的推导式过滤条件,后不能跟 `else`,满足该过滤条件的元素会继续放在该列表中,不满足条件的元素被剔除,有可能会使列表长度发生变化 -- 第二个 `if` 表示 list 迭代变量 `l` 的选择条件,表示 `if-else` 三元表达式,后必须跟 `else`,不论是否满足该条件,产生的元素仍然在该列表中,列表长度不变 - -dict 推导式举例: - -```python -_dictData = {key1 = "value1", key2 = "value2"} -_dictData = {k = _dictData[k] for k in _dictData if k == "key1" and _dictData[k] == "value1"} # 将_dictData中key为"key1", value为"value1"的元素筛选出来, {"key1": "value1"} -``` - -使用推导式获得 dict 所有 key: - -```python -dictData = {key1 = "value1", key2 = "value2"} -dictDataKeys = [k for k in _dictData] # ["key1", "key2"] -``` - -使用推导式对 dict 按照 key 的字典序升序进行排序: - -```python -dictData = {key3 = "value3", key2 = "value2", key1 = "value1"} # {'key3': 'value3', 'key2': 'value2', 'key1': 'value1'} -dictSortedData = {k = dictData[k] for k in sorted(dictData)} # {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'} -``` - -多级推导式举例: - -```python -array1 = [1, 2, 3] -array2 = [4, 5, 6] -data = [a1 + a2 for a1 in array1 for a2 in array2] # [5, 6, 7, 6, 7, 8, 7, 8, 9] len(data) == len(array1) * len(array2) -``` - -双变量循环(for 推导表达式支持 list 的索引迭代以及 dict 的 value 迭代,可以简化 list/dict 迭代过程代码书写): - -- list - -```python -data = [1000, 2000, 3000] -# 单变量循环 -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# 双变量循环 -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# 使用_忽略循环变量 -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -- dict - -```python -data = {key1 = "value1", key2 = "value2"} -# 单变量循环 -dataKeys1 = [k for k in data] # ["key1", "key2"] -dataValues1 = [data[k] for k in data] # ["value1", "value2"] -# 双变量循环 -dataKeys2 = [k for k, v in data] # ["key1", "key2"] -dataValues2 = [v for k, v in data] # ["value1", "value2"] -dataFilter = {k = v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# 使用_忽略循环变量 -dataKeys3 = [k for k, _ in data] # ["key1", "key2"] -dataValues3 = [v for _, v in data] # ["value1", "value2"] -``` - -## 9. 怎样写 if 条件语句? - -KCL 支持两种方式书写 if 条件语句: - -- if-elif-else 块语句,其中 elif 和 else 块均可省略,并且 elif 块可以使用多次 - -```python -success = True -_result = "failed" -if success: - _result = "success" -``` - -```python -success = True -if success: - _result = "success" -else: - _result = "failed" -``` - -```python -_result = 0 -if condition == "one": - _result = 1 -elif condition == "two": - _result = 2 -elif condition == "three": - _result = 3 -else: - _result = 4 -``` - -- 条件表达式 ` if else `, 类似于 C 语言当中的 ` ? : ` 三元表达式 - -```python -success = True -_result = "success" if success else "failed" -``` - -注意:在书写 if-elif-else 块语句时注意书写 if 条件后的冒号 `:` 以及保持缩进的统一 - -除此之外,还可以在 list 或者 dict 结构中直接书写条件表达式(不同的是,在结构中书写的 if 表达式中需要书写的值而不是语句): - -- list - -```python -env = "prod" -data = [ - "env_value" - ":" - if env == "prod": - "prod" # 书写需要添加到 data 中的值,而不是语句 - else: - "other_prod" -] # ["env_value", ":", "prod"] -``` - -- dict - -```python -env = "prod" -config = { - if env == "prod": - MY_PROD_ENV = "prod_value" # 书写需要添加到 config 中的键-值对,而不是语句 - else: - OTHER_ENV = "other_value" -} # {"MY_PROD_ENV": "prod_value"} -``` - -## 10. 怎样表达 "与" "或" "非" 等逻辑运算? - -在 KCL 中,使用 `and` 表示"逻辑与", 使用 `or` 表示"逻辑或", 使用 `not` 表示"非", 与 C 语言当中的 `&&`, `||` 和 `~` 语义一致; - -```python -done = True -col == 0 -if done and (col == 0 or col == 3): - ok = 1 -``` - -对于整数的"按位与", "按位或"和"按位异或",在 KCL 中使用 `&`, `|` 和 `^` 运算符表示, 与 C 语言当中的 `&`, `|` 和 `^` 语义一致; - -```python -value = 0x22 -bitmask = 0x0f - -assert (value & bitmask) == 0x02 -assert (value & ~bitmask) == 0x20 -assert (value | bitmask) == 0x2f -assert (value ^ bitmask) == 0x2d -``` - -"逻辑或" `or` 的妙用:当需要书写诸如 `A if A else B` 类似的模式时,可以使用 `A or B` 进行简化,比如如下代码: - -```python -value = [0] -default = [1] -x0 = value if value else default -x1 = value or default # 使用 value or default 代替 value if value else default -``` - -## 11. 如何判断变量是否为 None/Undefined、字符串/dict/list 是否为空? - -请注意,在 if 表达式的条件判断中,`False`、`None`、`Undefined`、数字 `0`、空列表 `[]`、空字典 `{}` 和空字符串 `""`, `''`, `""""""`, `''''''` 都被视为值为 `假` 的表达式。 - -比如判断一个字符串变量 `strData` 既不为 `None/Undefined` 也不为空字符串时(字符串长度大于 0),就可以简单的使用如下表达式: - -```python -strData = "value" -if strData: - isEmptyStr = False -``` - -空字典和空列表判断举例: - -```python -_emptyList = [] -_emptyDict = {} -isEmptyList = False if _emptyList else True -isEmptyDict = False if _emptyDict else True -``` - -YAML 输出为: - -```yaml -isEmptyList: true -isEmptyDict: true -``` - -或者使用布尔函数 `bool` 进行判断 - -```python -_emptyList = [] -_emptyDict = {} -isEmptyList = bool(_emptyList) -isEmptyDict = bool(_emptyDict) -``` - -## 12. 字符串怎样拼接、怎样格式化字符串、怎样检查字符串前缀、后缀?怎样替换字符串内容? - -- KCL 中可以使用 `+` 运算符连接两个字符串 - -```python -data1 = "string1" + "string2" # "string1string2" -data2 = "string1" + " " + "string2" # "string1 string2" -``` - -- KCL 中目前存在两种格式化字符串的方式: - - 字符串变量的 format 方法 `"{}".format()` - - 字符串插值 `${}` - -```python -hello = "hello" -a = "{} world".format(hello) -b = "${hello} world" -``` - -注意,如果想在 `"{}".format()` 中单独使用 `{` 字符或者 `}`, 则需要使用 `{{` 和 `}}` 分别对 `{` 和 `}` 进行转义,比如转义一个 JSON 字符串如下代码: - -```python -data = "value" -jsonData = '{{"key": "{}"}}'.format(data) -``` - -输出 YAML 为: - -```yaml -data: value -jsonData: '{"key": "value"}' -``` - -注意,如果想在 `${}` 插值字符串中单独使用 `$` 字符,则需要使用 `$$` 对 `$` 进行转义 - -```python -world = "world" -a = "hello {}".format(world) # "hello world" -b = "hello ${world}" # "hello world" -c = "$$hello ${world}$$" # "$hello world$" -c2 = "$" + "hello ${world}" + "$" # "$hello world$" -``` - -输出 YAML 为: - -```yaml -world: world -a: hello world -b: hello world -c: $hello world$ -c2: $hello world$ -``` - -- KCL 中使用字符串的 `startswith` 和 `endswith` 方法检查字符串的前缀和后缀 - -```python -data = "length" -isEndsWith = data.endswith("th") # True -isStartsWith = "length".startswith('len') # True -``` - -- KCL 中使用字符串的 replace 方法或者 regex.replace 函数替换字符串的内容 - -```python -import regex -data1 = "length".replace("len", "xxx") # 使用"xxx"替换"len", "xxxgth" -data2 = regex.replace("abc123", r"\D", "0") # 替换"abc123"中的所有非数字为"0", "000123" -``` - -其中,`r"\D"` 表示不需要使用 `\\` 转义 `\D` 中的反斜杠 `\`,多用于正则表达式字符串中 - -此外,我们可以在字符串格式化表达式中插入索引占位符或者关键字占位符用于格式化多个字符串 - -- 索引占位符 - -```python -x = '{2} {1} {0}'.format('directions', 'the', 'Read') -y = '{0} {0} {0}'.format('string') -``` - -输出为: - -```yaml -x: Read the directions -y: string string string -``` - -- 关键字占位符 - -```python -x = 'a: {a}, b: {b}, c: {c}'.format(a = 1, b = 'Two', c = 12.3) -``` - -输出为: - -```yaml -x: "a: 1, b: Two, c: 12.3" -``` - -## 13. 字符串中使用单引号和双引号的区别是什么? - -KCL 单引号和双引号字符串几乎没有区别。唯一的区别是,不需要在单引号字符串中使用 `\"` 转义双引号 `"`,不需要在双引号字符串中使用 `\'` 转义单引号引号 `'`。 - -```python -singleQuotedString = 'This is my book named "foo"' # Don’t need to escape double quotes in single quoted strings. -doubleQuotedString = "This is my book named 'foo'" # Don’t need to escape single quotes in double quoted strings. -``` - -此外在 KCL 中,使用三个单引号或者三个双引号组成的长字符串,无需在其中对单引号或者三引号进行转义 (除字符串首尾),比如如下例子: - -```python -longStrWithQuote0 = """Double quotes in long strings "(not at the beginning and end)""" -longStrWithQuote1 = '''Double quotes in long strings "(not at the beginning and end)''' -longStrWithQuote2 = """Single quotes in long strings '(not at the beginning and end)""" -longStrWithQuote3 = '''Single quotes in long strings '(not at the beginning and end)''' -``` - -输出 YAML: - -```yaml -longStrWithQuote0: Double quotes in long strings "(not at the beginning and end) -longStrWithQuote1: Double quotes in long strings "(not at the beginning and end) -longStrWithQuote2: Single quotes in long strings '(not at the beginning and end) -longStrWithQuote3: Single quotes in long strings '(not at the beginning and end) -``` - -## 14. 如何编写跨行的长字符串? - -KCL 中可以使用单引号字符串 + 换行符 `\n` 或者三引号字符串书写一个多行字符串,并且可以借助续行符 `\` 优化 KCL 字符串的形式,比如对于如下代码中的三个多行字符串变量,它们的制是相同的: - -```python -string1 = "The first line\nThe second line\nThe third line\n" -string2 = """The first line -The second line -The third line -""" -string3 = """\ -The first line -The second line -The third line -""" # 推荐使用 string3 长字符串的书写形式 -``` - -输出 YAML 为: - -```yaml -string1: | - The first line - The second line - The third line -string2: | - The first line - The second line - The third line -string3: | - The first line - The second line - The third line -``` - -## 15. 如何使用正则表达式? - -通过在 KCL 中导入正则表达式库 `import regex` 即可使用正则表达式,其中包含了如下函数: - -- **match**: 正则表达式匹配函数,根据正则表达式对输入字符串进行匹配,返回 bool 类型表示是否匹配成功 -- **split**: 正则表达式分割函数,根据正则表达式分割字符串,返回分割字串的列表 -- **replace**: 正则表达式替换函数,替换字符串中所有满足正则表达式的子串,返回被替换的字符串 -- **compile**: 正则表达式编译函数,返回 bool 类型表示是否是一个合法的正则表达式 -- **search**: 正则表达式搜索函数,搜索所有满足正则表达式的子串,返回子串的列表 - -使用举例: - -```python -import regex - -regex_source = "Apple,Google,Baidu,Xiaomi" -regex_split = regex.split(regex_source, ",") -regex_replace = regex.replace(regex_source, ",", "|") -regex_compile = regex.compile("$^") -regex_search = regex.search("aaaa", "a") -regex_find_all = regex.findall("aaaa", "a") -regex_result = regex.match("192.168.0.1", "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$") # 判断是否是一个IP字符串 -regex_result_false = regex.match("192.168.0,1", "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$") # 判断是否是一个IP字符串 -``` - -输出 YAML: - -```yaml -regex_source: Apple,Google,Baidu,Xiaomi -regex_split: - - Apple - - Google - - Baidu - - Xiaomi -regex_replace: Apple|Google|Baidu|Xiaomi -regex_compile: true -regex_search: true -regex_find_all: - - a - - a - - a - - a -regex_result: true -regex_result_false: false -``` - -对于比较长的正则表达式,还可以使用 r-string 忽略 `\` 符号的转义简化正则表达式字符串的书写: - -```python -import regex - -isIp = regex.match("192.168.0.1", r"^(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)$") # 判断是否是一个IP字符串 -``` - -更多举例: - -```python -import regex - -schema Resource: - cpu: str = "1" - memory: str = "1024Mi" - disk: str = "10Gi" - check: - regex.match(cpu, r"^([+-]?[0-9.]+)([m]*[-+]?[0-9]*)$"), "cpu must match specific regular expression" - regex.match(memory, r"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"), "memory must match specific regular expression" - regex.match(disk, r"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"), "disk must match specific regular expression" -``` - -```python -import regex - -schema Env: - name: str - value?: str - check: - len(name) <= 63, "a valid env name must be no more than 63 characters" - regex.match(name, r"[A-Za-z_][A-Za-z0-9_]*"), "a valid env name must start with alphabetic character or '_', followed by a string of alphanumeric characters or '_'" -``` - -## 16. KCL 当中的 schema 是什么含义? - -schema 是 KCL 中一种语言元素,用于定义配置数据的类型,像 C 语言中的 struct 或者 Java 中的 class 一样,在其中可以定义属性,每种属性具有相应的类型。 - -## 17. 如何声明 schema? - -KCL 中使用 schema 关键字可以定义一个结构,在其中可以申明 schema 的各个属性 - -```python -# 一个Person结构,其中具有属性字符串类型的firstName, 字符串类型的lastName, 整数类型的age -schema Person: - firstName: str - lastName: str - # age属性的默认值为0 - age: int = 0 -``` - -一个复杂例子: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels: {str:str} -``` - -在上面的代码中,`cpu` 和 `memory` 被定义为整数 int 类型;`name`,`image` 和 `service` 是字符串 str 类型; `command` 是字符串类型的列表; labels 是字典类型,其键类型和值类型均为字符串。 - -## 18. 如何为 schema 属性添加 "不可变"、"必选" 约束? - -KCL 中使用 `?` 运算符定义一个 schema 的"可选"约束,schema 属性默认都是"必选"的 - -```python -# 一个Person结构,其中具有属性字符串类型的firstName, 字符串类型的lastName, 整数类型的age -schema Person: - firstName?: str # firstName是一个可选属性,可以赋值为None/Undefined - lastName?: str # age是一个可选属性,可以赋值为None/Undefined - # age属性的默认值为0 - age: int = 18 # age是一个必选属性,不能赋值为None/Undefined,并且是一个不可变属性 - age = 10 # Error, age是一个不可变的属性 -``` - -## 19. 如何为 schema 中的属性编写校验规则? - -在 schema 定义当中可以使用 check 关键字编写 schema 属性的校验规则, 如下所示,check 代码块中的每一行都对应一个条件表达式,当满足条件时校验成功,当不满足条件时校验失败。条件表达式后可跟 `, "check error message"` 表示当校验失败时需要显示的信息 - -```python -import regex - -schema Sample: - foo: str # Required, 不能为None/Undefined, 且类型必须为str - bar: int # Required, 不能为None/Undefined, 且类型必须为int - fooList: [int] # Required, 不能为None/Undefined, 且类型必须为int列表 - color: "Red" | "Yellow" | "Blue" # Required, 字面值联合类型,且必须为"Red", "Yellow", "Blue"中的一个,枚举作用 - id?: int # Optional,可以留空,类型必须为int - - check: - bar >= 0 # bar必须大于等于0 - bar < 100 # bar必须小于100 - len(fooList) > 0 # fooList不能为None/Undefined,并且长度必须大于0 - len(fooList) < 100 # fooList不能为None/Undefined,并且长度必须小于100 - regex.match(foo, "^The.*Foo$") # regex 正则表达式匹配 - bar in range(100) # range, bar范围只能为1到99 - bar in [2, 4, 6, 8] # enum, bar只能取2, 4, 6, 8 - bar % 2 == 0 # bar必须为2的倍数 - all foo in fooList { - foo > 1 - } # fooList中的所有元素必须大于1 - any foo in fooList { - foo > 10 - } # fooList中至少有一个元素必须大于10 - abs(id) > 10 if id # check if 表达式,当 id 不为空时,id的绝对值必须大于10 -``` - -此外,上述 check 当中比较表达式还可以简写为: - -```python -0 <= bar < 100 -0 < len(fooList) < 100 -``` - -综上所述,KCL Schema 中支持的校验类型为: - -| 校验类型 | 使用方法 | -| -------- | ---------------------------------------------------------- | -| 范围校验 | 使用 `<`, `>` 等比较运算符 | -| 正则校验 | 使用 `regex` 系统库中的 `match` 等方法 | -| 长度校验 | 使用 `len` 内置函数,可以求 `list/dict/str` 类型的变量长度 | -| 枚举校验 | 使用字面值联合类型 | -| 非空校验 | 使用 schema 的可选/必选属性 | -| 条件校验 | 使用 check if 条件表达式 | - -## 20. 如何为 schema 及其属性添加文档注释? - -一个完整的 schema 属性注释使用三引号字符串表示,其中的结构如下所示: - -```python -schema Person: - """The schema person definition - - Attributes - ---------- - name : str - The name of the person - age : int - The age of the person - - See Also - -------- - Son: - Sub-schema Son of the schema Person. - - Examples - -------- - person = Person { - name = "Alice" - age = 18 - } - """ - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -``` - -## 21. 如何基于 schema 编写配置?多个配置之间如何复用公共的配置? - -在 schema 实例化的过程中可以使用解包运算符 `**` 对公共的配置进行展开 - -```python -schema Boy: - name: str - age: int - hc: int - -schema Girl: - name: str - age: int - hc: int - -config = { - age = 18 - hc = 10 -} - -boy = Boy { - **config - name = "Bob" -} -girl = Girl { - **config - name = "Alice" -} -``` - -输出 YAML 为: - -```yaml -config: - age: 18 - hc: 10 -boy: - name: Bob - age: 18 - hc: 10 -girl: - name: Alice - age: 18 - hc: 10 -``` - -## 22. 基于 schema 编写配置时如何覆盖 schema 属性的默认值? - -在定义 schema 后,可以使用 schema 名称实例化相应的配置,使用 `:` 运算符对 schema 默认值进行 union, 使用 `=` 对 schema 默认值进行覆盖。对于 int/float/bool/str 类型的 schema 属性,union 和覆盖的效果相同; 对于 list/dict/schema 类型的 schema 属性,union 和覆盖的效果不同; - -```python -schema Meta: - labels: {str:str} = {"key1" = "value1"} - annotations: {str:str} = {"key1" = "value1"} - -meta = Meta { - labels: {"key2": "value2"} - annotations = {"key2" = "value2"} -} -``` - -输出 YAML 为: - -```yaml -meta: - labels: - key1: value1 - key2: value2 - annotations: - key2: value2 -``` - -## 23. 如何通过继承来复用 schema 定义? - -可以在 schema 定义处声明 schema 需要继承的 schema 名称: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 - -# An employee **is** a person, and has some additional information. -schema Employee(Person): - bankCard: int - nationality: str - -employee = Employee { - firstName = "Bob" - lastName = "Green" - age = 18 - bankCard = 123456 - nationality = "China" -} -``` - -输出 YAML 为: - -```yaml -employee: - firstName: Bob - lastName: Green - age: 18 - bankCard: 123456 - nationality: China -``` - -注意: KCL 只允许 schema 单继承 - -## 24. 如何通过组合复用 schema 逻辑? - -可以使用 KCL schema mixin 复用 schema 逻辑,mixin 一般被用于 schema 内部属性的分离数据,和数据映射等功能,可以使 KCL 代码更具模块化和声明性。注意不同的 mixin 之间的混入属性不建议定义依赖关系,会使得 mixin 使用方式复杂,一般一个 mixin 中作不超过三个属性混入即可。 - -```python -schema Person: - mixin [FullNameMixin, UpperMixin] - - firstName: str - lastName: str - fullName: str - upper: str - -schema FullNameMixin: - fullName = "{} {}".format(firstName, lastName) - -schema UpperMixin: - upper = fullName.upper() - -person = Person { - firstName = "John" - lastName = "Doe" -} -``` - -输出 YAML 为: - -```yaml -person: - firstName: John - lastName: Doe - fullName: John Doe - upper: JOHN DOE -``` - -## 25. 如何导入其他 KCL 文件? - -通过 import 关键字可以导入其他 KCL 文件,KCL 配置文件被组织为模块。单个 KCL 文件被视为一个模块,目录被视为一个包,作为一个特殊的模块。import 关键字支持相对路径导入和绝对路径导入两种方式 - -比如对于如下目录结构: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ │── service1.k - │ └── service2.k - └── mixin - └── mixin1.k -``` - -对于 `main.k`, 相对路径导入和绝对路径导入分别可以表示为: - -```python -import service # 绝对路径导入, 根目录为kcl.mod所在的路径 -import mixin # 绝对路径导入, 根目录为kcl.mod所在的路径 - -import .model1 # 相对路径导入, 当前目录模块 -import ..service # 相对路径导入, 父目录 -import ...root # 相对路径导入, 父目录的父目录 -``` - -注意,对于 KCL 的入口文件 `main.k`, 其不能导入自身所在的文件夹,否则会发生循环导入错误: - -```python -import model # Error: recursively loading -``` - -## 26. 什么情况下可以省略 import ? - -除了 main 包当中的同一文件夹下的 KCL 可以相互引用而不需通过 import 相互引用,比如对于如下目录结构: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ │── service1.k - │ └── service2.k - └── mixin - └── mixin1.k -``` - -当 main.k 作为 KCL 命令行入口文件时, model 文件夹中的 main.k, model1.k 和 model2.k 中的变量不能相互引用,需要通过 import 导入,但是 service 文件夹中的 service1.k 和 service2.k 当中的变量可以互相引用,忽略 import - -service1.k - -```python -schema BaseService: - name: str - namespace: str -``` - -service2.k - -```python -schema Service(BaseService): - id: str -``` - -## 27. 有一行代码太长了,如何在语法正确的情况下优雅地换行? - -在 KCL 中可以使用续行符 `\` 进行换行, 并且在字符串中也可以使用 `\` 表示续行 - -长字符串连接续行举例: - -```python -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " -``` - -推导表达式续行举例: - -```python -data = [1, 2, 3, 4] -dataNew = [ - d + 2 \ - for d in data \ - if d % 2 == 0 -] -``` - -if 表达式续行举例: - -```python -condition = 1 -data1 = 1 \ - if condition \ - else 2 -data2 = 2 \ -if condition \ -else 1 -``` - -三引号字符串内部续行举例: - -```python -longString = """\ -The first line\ -The continue second line\ -""" -``` - -注意: 使用续行符 `\` 的同时缩进的保持, 如下所示: - -错误用例: - -```python -data1 = [ - 1, 2, - 3, 4 \ -] # Error, 需要保持右方括号]的缩进 - -data2 = [ - 1, 2, - 3, 4 -] # Error, 需要数字1和3的缩进统一 -``` - -正确用例: - -```python -data1 = [ - 1, 2, - 3, 4 -] # Right, 带缩进的列表定义 - -data2 = [ \ - 1, 2, \ - 3, 4 \ -] # Right, 使用续行符的列表定义, 实际效果是单行列表 - -data3 = [ \ - 1, 2, \ - 3, 4 \ -] # Right, 使用续行符的列表定义, 无需保持缩进, 实际效果是单行列表 -``` - -## 28. \*_, _ 这些符号是什么意思? - -- `**`, `*` 出现在 dict/list 外部时分别表示乘方运算符和乘法运算符 - -```python -data1 = 2 ** 4 # 2的4次方等于16 -data2 = 2 * 3 # 2乘以3等于6 -``` - -- `**`, `*` 出现在 dict/list 内部时表示解包运算符,经常用于 list/dict 的解包和合并, 与 Python 当中的解包运算符用法相同 - -dict 的解包: - -```python -data = {"key1" = "value1"} -dataUnpack = {**data, "key2" = "value2"} # 将data解包合并入dataUnpack中, {"key1": "value1", "key2": "value2"} -``` - -list 的解包: - -```python -data = [1, 2, 3] -dataUnpack = [*data, 4, 5, 6] # 将data解包合并入dataUnpack中, [1, 2, 3, 4, 5, 6] -``` - -## 29. 如何取 list/dict/schema 的子元素 - -在 KCL 中可以使用 select 表达式或者 subscript 表达式取 list/dict/schema 的子元素 - -- 对于 list 类型,可以使用 `[]` 取列表中的某一个元素或者某一些元素 - -```python -data = [1, 2, 3] # 定义一个整数类型的数组 -theFirstItem = data[0] # 取数组中索引为0的元素,即第一个元素 1 -theSecondItem = data[1] # 取数组中索引为1的元素,即第一个元素 2 -``` - -注意:索引的取值不能超出列表的长度,否则会发生错误,可以使用 `len` 函数获得数组的长度 - -```python -data = [1, 2, 3] -dataLength = len(data) # 数组长度为3 -item = data[3] # 发生数组索引越界错误 -``` - -此外,还可以使用负数索引倒序获得列表中的元素 - -```python -data = [1, 2, 3] -item1 = data[-1] # 取数组中索引为-1的元素,即最后一个元素 3 -item2 = data[-2] # 取数组中索引为-2的元素,即倒数第二个元素 2 -``` - -综上,列表索引的取值范围为 `[-len, len - 1]` - -当想要取得列表的一部分时,可以在 `[]` 中使用切片表达式,其具体语法为 `[<列表开始索引>:<列表终止索引>:<列表遍历步长>]`,注意索引开始终止的取值区间为 `左闭右开[<列表开始索引>, <列表终止索引>)`,注意三个参数均可省略不写 - -```python -data = [1, 2, 3, 4, 5] -dataSlice0 = data[1:2] # 取列表中索引开始为 1, 终止索引为 2 的元素集合 [2] -dataSlice1 = data[1:3] # 取列表中索引开始为 1, 终止索引为 3 的元素集合 [2, 3] -dataSlice2 = data[1:] # 取列表中索引开始为 1, 终止索引为 最后一个索引 的元素集合 [2, 3, 4, 5] -dataSlice3 = data[:3] # 取列表中索引开始为 第一个索引, 终止索引为 3 的元素集合 [1, 2, 3] -dataSlice4 = data[::2] # 取列表中索引开始为 第一个索引, 终止索引为 最后一个索引 的元素集合(步长为2) [1, 3, 5] -dataSlice5 = data[::-1] # 反转一个列表,[5, 4, 3, 2, 1] -dataSlice6 = data[2:1] # 当开始,终止,步长三个参数组合不满足条件时返回空列表 [] - -``` - -- 对于 dict/schema 类型,可以使用 `[]` 和 `.` 两种方式取 dict/schema 中的子元素 - -```python -data = {key1: "value1", key2: "value2"} -data1 = data["key1"] # "value1" -data2 = data.key1 # "value1" -data3 = data["key2"] # "value2" -data4 = data.key2 # "value2" -``` - -```python -schema Person: - name: str = "Alice" - age: int = 18 - -person = Person {} -name1 = person.name # "Alice" -name2 = person["name"] # "Alice" -age1 = person.age # 18 -age2 = person.age # 18 -``` - -当键值在 dict 中不存在时,返回未定义值 `Undefined` - -```python -data = {key1 = "value1", key2 = "value2"} -data1 = data["not_exist_key"] # Undefined -data2 = data.not_exist_key # Undefined -``` - -可以使用 `in` 关键字判断某个键值是否在 dict/schema 中存在 - -```python -data = {key1 = "value1", key2 = "value2"} -exist1 = "key1" in data # True -exist2 = "not_exist_key" in data # False -``` - -当键值中存在 `.` 时或者需要运行时取一个键值变量对应的值时,只能使用 `[]` 方式,如无特殊情况,使用 `.` 即可: - -```python -name = "key1" -data = {key1 = "value1", key2 = "value2", "contains.dot" = "value3"} -data1 = data[name] # "value1" -data2 = data["contains.dot"] # "value3" -# 注意这样子是不对的 data3 = data.contains.dot -``` - -注意:上述取子元素的运算符不能对非 list/dict/schema 集合类型的值进行操作,比如整数,空值等。 - -```python -data = 1 -data1 = 1[0] # error -``` - -```python -data = None -data1 = None[0] # error -``` - -在取集合类型的子元素时往往要进行非空或者长度判断: - -```python -data = [] -item = data[0] if data else None -``` - -可以使用非空判断符 `?` 添加在 `[]`, `.` 的前面表示进行 if 非空判断,当不满足条件时返回 None,比如上述代码可以简化为: - -```python -data = [] -item1 = data?[0] # 当data为空时,返回空值 None -item2 = data?[0] or 1 # 当data为空时,返回空值 None, 如果不想返回 None, 还可与 or 运算符连用返回其他默认值 -``` - -使用 `?` 可以进行递归调用, 避免复杂繁琐的非空判断 - -```python -data = {key1.key2.key3 = []} -item = data?.key1?.key2?.key3?[0] -``` - -## 30. 如何在 KCL 代码中判断变量的类型 - -KCL typeof built-in 函数可以在该函数执行时立即返回一个变量的类型(字符串表示)用于类型断言 - -用法举例: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person{} -t3 = typeof(_x1) - -_x2 = pkg.Person{} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# 输出 -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -## 31. 关键字和 KCL 变量名冲突了可以怎么解决? - -对于与关键字冲突的标识符,可以在标识符前添加 `$` 前缀用于定义一个关键字标识符,比如如下代码中使用了 `if`, `else` 等关键字作为标识符并且可以得到相应的 YAML 输出 - -```python -$if = 1 -$else = "s" - -schema Data: - $filter: str = "filter" - -data = Data {} -``` - -输出 YAML: - -```yaml -data: - filter: filter -if: 1 -else: s -``` - -注意:在非关键字标识符前添加 `$` 前缀的效果与不添加相同 - -```python -_a = 1 -$_a = 2 # 等效于 `_a = 2` -``` - -## 32. KCL 的内置类型是 KCL 的关键字吗?是否可用于变量的定义 - -KCL 的内置类型包括 `int`, `float`, `bool` 和 `str` 四种类型,它们不是 KCL 的关键字,可用于变量的定义,比如如下代码: - -```py -int = 1 -str = 2 -``` - -输出 YAML 为: - -```yaml -int: 1 -str: 2 -``` - -注意:如无特殊需求,不建议变量的名称取这些内置类型,因为在有些语言当中,它们作为关键字存在 - -## 33. 如何在 KCL 中实现类似 Enum 枚举的功能 - -有两种方式可以在 KCL 中实现 Enum 枚举的方式 - -- (推荐)使用**字面值类型**的**联合类型** - -```python -schema Person: - name: str - gender: "Male" | "Female" - -person = Person { - name = "Alice" - gender = "Male" # gender 只能为 "Male" 或者 "Female" -} -``` - -一个复杂例子 - -```python -schema Config: - colors: ["Red" | "Yellow" | "Blue"] # colors 是一个枚举数组 - -config = Config { - colors = [ - "Red" - "Blue" - ] -} -``` - -- 使用 schema 的 check 表达式 - -```python -schema Person: - name: str - gender: "Male" | "Female" - - check: - gender in ["Male", "Female"] - -person = Person { - name = "Alice" - gender = "Male" # gender 只能为 "Male" 或者 "Female" -} -``` - -## 34. 如何求字典 dict 的长度 - -在 KCL 中可以使用 `len` 内置函数直接求 dict 的长度 - -```python -len1 = len({k1: "v1"}) # 1 -len2 = len({k1: "v1", k2: "v2"}) # 2 -varDict = {k1 = 1, k2 = 2, k3 = 3} -len3 = len(varDict) # 3 -``` - -此外,使用 `len` 函数还可以求 `str` 和 `list` 类型长度 - -```python -len1 = len("hello") # 5 -len2 = len([1, 2, 3]) # 3 -``` - -## 35. 如何在 KCL 中编写带条件的配置 - -在 KCL 中,除了支持在顶级的语句中书写 `if-elif-else` 条件表达式以外,还支持在 KCL 复杂结构(list/dict/schema)中书写条件表达式,支持带条件的配置书写。 - -```python -x = 1 -# List 结构中的 if 条件语句 -dataList = [ - if x == 1: 1 -] -# Dict 结构中的 if 条件语句 -dataDict = { - if x == 1: key1 = "value1" # 可以同一行书写 - elif x == 2: - key2 = "value2" # 可以跨行书写 -} -# Schema 结构中的 if 条件语句 -schema Config: - id?: int -env = "prod" -dataSchema = Config { - if env == "prod": - id = 1 - elif env == "pre": - id = 2 - elif env == "test": - id = 3 -} -``` - -## 36. KCL 中的 == 运算符会作深度比较嘛? - -KCL 中的 `==` 运算符 - -- 对于基本类型 `int`, `float`, `bool`, `str` 的变量是直接比较它们的值是否相等 -- 对于复合类型 `list`, `dict`, `schema` 的变量会深度递归地比较其中的子元素是否相等 - - `list` 类型深度递归递归比较每个索引的值以及长度 - - `dict`/`schema` 类型深度递归比较每个属性的值(与属性出现的顺序无关) - -```python -print([1, 2] == [1, 2]) # True -print([[0, 1], 1] == [[0, 1], 1]) # True -print({k1 = 1, k2 = 2} == {k2 = 2, k1 = 1}) # True - -print([1, 2] == [1, 2, 3]) # False -print({k1 = 1, k2 = 2, k3 = 3} == {k2 = 2, k1 = 1}) # False -``` - -## 37. 如何对 KCL 中已有的配置块进行修改 - -在 KCL 中,存在三种**属性运算符** `=`、`+=`、`:`,可以用来对已有配置块进行修改,并且可以使用**解包运算符** `**` 等"继承"一个配置块的所有属性字段和值。 - -- `=` 属性运算符表示覆盖,使用 `=` 运算符可以对属性进行有优先级的覆盖/删除,(如果是用 `Undefined` 覆盖则表示删除) -- `+=` 属性运算符表示添加,一般用于对 list 类型的属性添加子元素,`+=` 属性运算符后跟的操作数类型也只能为 list 类型 -- `:` 属性运算符表示幂等合并,当值发生冲突时进行报错,不冲突时进行合并 - -### 覆盖属性运算符= - -最常使用的属性运算符是 `=`,表示一个属性的赋值,多次对同一个属性进行使用时表示覆盖,对于 `{}` 外的全局变量或者 `{}` 内的属性均表示使用值覆盖这个全局变量或者属性 - -```python -data = { # 定义一个字典类型的变量 data - a = 1 # 使用 = 在 data 中声明一个值为 1 的属性 a - b = 2 # 使用 = 在 data 中声明一个值为 1 的属性 b -} # 最终 data 的值为 {"a": 1, "b": 1} -``` - -在 schema 实例化处也可以使用覆盖属性运算符实现对 schema 默认值的覆盖效果,一般在创建新的 schema 实例时如无特殊的需求,一般使用 `=` 即可 - -```python -schema Person: - name: str = "Alice" # schema Person 的 name 属性具有默认值 "Alice" - age: int = 18 # schema Person 的 age 属性具有默认值 18 - -bob = Person { - name = "Bob" # "Bob" -> "Alice", 属性 name 的值 "Bob" 的值会覆盖 schema Person name 属性的默认值 "Alice" - age = 10 # 10 -> 18, 属性 age 的值 10 的值会覆盖 schema Person age 属性的默认值 18 -} # 最终 bob 的值为 {"name": "Bob", age: 10} -``` - -### 插入属性运算符 += - -插入属性运算符表示对一个属性的值进行原地添加,比如向一个 list 类型的属性添加新的元素 - -```python -data = { - args = ["kcl"] # 使用 = 在 data 中声明一个值为 ["kcl"] 的属性 args - args += ["-Y", "settings.yaml"] # 使用 += 运算符向属性 args 中添加两个元素"-Y", "settings.yaml" -} # 最终 data 的值为 {"args": ["kcl", "-Y", "settings.yaml"]} -``` - -### 合并属性运算符: - -合并属性运算符表示对一个属性的不同配置块值进行幂等的合并,当需要合并的值发生冲突时进行报错,多用于复杂配置合并场景 - -```python -data = { - labels: {key1: "value1"} # 定义一个 labels, 它的类型为 dict, 值为 {"key1": "value1"} - labels: {key2: "value2"} # 使用 : 将 labels 不同的配置值进行合并 -} # 最终 data 的值为 {"labels": {"key1": "value1", "key2": "value2"}} -``` - -合并属性运算符属于幂等运算符,需要合并的配置块的书写顺序不影响其最终结果,比如上述例子中的两个 `labels` 属性也可以调换顺序书写 - -```python -data = { # 同一个属性 labels 的合并书写顺序不影响最终结果 - labels: {key2: "value2"} # 定义一个 labels, 它的类型为 dict, 值为 {"key2": "value2"} - labels: {key1: "value1"} # 使用 : 将 labels 不同的配置值进行合并 -} # 最终 data 的值为 {"labels": {"key1": "value1", "key2": "value2"}} -``` - -注意:合并属性运算符会对合并的值进行冲突检查,当需要合并的配置值发生冲突时进行报错 - -```python -data = { - a: 1 # a 的值为 1 - a: 2 # Error: a 的值 2 不能与 a 的值 1 进行合并,因为其结果存在冲突,且合并是不可交换的 -} -``` - -```python -data = { - labels: {key: "value"} - labels: {key: "override_value"} # Error: 两个 labels 的 key 属性的值 "value" 和 "override_value" 是冲突的,不可合并 -} -``` - -合并运算符对不同类型的使用方式不同 - -- 不同类型的属性不能进行合并 -- 当属性为 int/float/str/bool 等基本类型时,运算符会判断需要合并的值是否相等,不相等时发生合并冲突错误 - -```python -data = { - a: 1 - a: 1 # Ok - a: 2 # Error -} -``` - -- 当属性为 list 类型时 - - 当需要合并的两个 list 长度不相等时,发生合并冲突错误 - - 当需要合并的两个 list 长度相等时,按照索引递归地合并 list 当中的每一个元素 - -```python -data = { - args: ["kcl"] - args: ["-Y", "settings.yaml"] # Error: 两个 args 属性的长度不相同,不能进行合并 - env: [{key1: "value1"}] - env: [{key2: "value2"}] # Ok: 最终 env 属性的值为 [{"key1": "value1"}, {"key2": "value2"}] -} -``` - -- 当属性为 dict/schema 类型时,按照 key 递归地合并 dict/schema 当中的每一个元素 - -```python -data = { - labels: {key1: "value1"} - labels: {key2: "value2"} - labels: {key3: "value3"} -} # 最终 data 的值为 {"labels": {"key1": "value1", "key2": "value2", "key3": "value3"}} -``` - -- 任意类型的属性与 None/Undefined 合并的结果都是其自身 - -```python -data = { - args: ["kcl"] - args: None # Ok - args: Undefined #Ok -} # 最终 data 的值为 {"args": ["kcl"]} -``` - -支持顶级变量使用 `:` 属性声明与合并(仍然可使用 `config = Config {}` 的方式声明一个配置块) - -```python -schema Config: - id: int - value: str - -config: Config { - id: 1 -} -config: Config { - value: "1" -} -""" -此处定义了两个 Config 配置块,使用 : 运算符将可以两个配置块合并在一起,其合并的等效代码如下: -config: Config { - id: 1 - value: "1" -} -""" -``` - -综上所述,合并属性运算符 `:` 的使用场景主要为复杂数据结构 list/dict/schema 的合并操作,一般情况如无特殊需求使用 `=` 和 `+=` 两种属性运算符即可,因此属性运算符的最佳实践如下 - -- 对于基本类型,采用 `=` 运算符 -- 对于 list 类型,一般采用 `=` 和 `+=` 运算符,使用 `=` 表示完全覆盖 list 属性,使用 `+=` 表示向 list 中添加元素 -- 对于 dict/schema 类型,一般采用 `:` 运算符 - -此外,当已经存在一个配置时,可以使用解包运算符 `**` 获得此配置的所有字段值并对其中的字段使用不同属性运算符进行修改,并获得一个新的配置 - -```python -configBase = { - intKey = 1 # 一个 int 类型的属性 - floatKey = 1.0 # 一个 float 类型的属性 - listKey = [0] # 一个 list 类型的属性 - dictKey = {key1: "value1"} # 一个 dict 类型的属性 -} -configNew = { - **configBase # 将 configBase 解包内联到 configNew 中 - intKey = 0 # 使用 覆盖属性运算符 = 将 intKey 属性覆盖为 1 - floatKey = Undefined # 使用 覆盖属性运算符 = 删除 floatKey 属性 - listKey += [1] # 使用 添加属性运算符 += 为 listKey 属性尾部添加一个属性 1 - dictKey: {key2: "value2"} # 使用 合并属性运算符 : 为 dictKey 属性扩展一个键-值对 -} -``` - -输出的 YAML 结果为: - -```yaml -configBase: - intKey: 1 - floatKey: 1.0 - listKey: - - 0 - dictKey: - key1: value1 -configNew: - intKey: 0 - listKey: - - 0 - - 1 - dictKey: - key1: value1 - key2: value2 -``` - -或者可以使用 `|` 运算符对两个配置块合并: - -```python -configBase = { - intKey = 1 # 一个 int 类型的属性 - floatKey = 1.0 # 一个 float 类型的属性 - listKey = [0] # 一个 list 类型的属性 - dictKey = {key1: "value1"} # 一个 dict 类型的属性 -} -configNew = configBase | { # 使用 | 进行合并 - intKey = 0 # 使用 覆盖属性运算符 = 将 intKey 属性覆盖为 1 - floatKey = Undefined # 使用 覆盖属性运算符 = 删除 floatKey 属性 - listKey += [1] # 使用 添加属性运算符 += 为 listKey 属性尾部添加一个属性 1 - dictKey: {key2: "value2"} # 使用 合并属性运算符 : 为 dictKey 属性扩展一个键-值对 -} -``` - -输出的 YAML 结果为: - -```yaml -configBase: - intKey: 1 - floatKey: 1.0 - listKey: - - 0 - dictKey: - key1: value1 -configNew: - intKey: 0 - listKey: - - 0 - - 1 - dictKey: - key1: value1 - key2: value2 -``` - -### KCL 发生 conflicting values on the attribute 'attr' between {value1} and {value2} 错误的解决方式 - -当 KCL 发生类似 conflicting values on the attribute 'attr' between {value1} and {value2} 错误时,一般是合并属性运算符 `:` 的使用问题,表明 `value1` 和 `value2` 配置进行合并时在属性 `attr` 处发生了冲突错误。一般情况将 value2 的 attr 属性修改为其他属性运算符即可,使用 `=` 表示覆盖,使用 `+=` 表示添加 - -比如对于如下代码: - -```python -data = {k: 1} | {k: 2} # Error: conflicting values on the attribute 'k' between {'k': 1} and {'k': 2} -``` - -则可以使用 `=` 属性运算符修改为如下形式 - -```python -data = {k: 1} | {k = 2} # Ok: the value 2 will override the value 1 through the `=` operator -``` - -## 38. KCL 中如何同时遍历多个元素 - -KCL 中可以使用 for 推导表达式遍历多个元素 - -- 举例 1: 使用 for 进行 2 维元素遍历 - -```python -dimension1 = [1, 2, 3] # dimension1 列表的长度是 3 -dimension2 = [1, 2, 3] # dimension2 列表的长度是 3 -matrix = [x + y for x in dimension1 for y in dimension2] # matrix 列表的长度是 9 = 3 * 3 -``` - -输出结果如下: - -```yaml -dimension1: - - 1 - - 2 - - 3 -dimension2: - - 1 - - 2 - - 3 -matrix: - - 2 - - 3 - - 4 - - 3 - - 4 - - 5 - - 4 - - 5 - - 6 -``` - -- 举例 2: 使用 for 循环配合 zip 内置函数按照索引一一对应对多个列表进行遍历 - -```python -dimension1 = [1, 2, 3] # dimension1 列表的长度是 3 -dimension2 = [1, 2, 3] # dimension2 列表的长度是 3 -dimension3 = [d[0] + d[1] for d in zip(dimension1, dimension2)] # dimension3 列表的长度是 3 -``` - -输出结果如下: - -```yaml -dimension1: - - 1 - - 2 - - 3 -dimension2: - - 1 - - 2 - - 3 -dimension3: - - 2 - - 4 - - 6 -``` - -## 39. KCL 中如何为 option 函数设定默认值 - -在 KCL 中,当 option 属性的值为 None/Undefined 空时,可以使用逻辑或 `or` 直接指定一个默认值 - -```python -value = option("key") or "default_value" # 当 key 的值存在时,取 option("key") 的值,否则取 "default_value" -``` - -或者使用 option 函数的 default 参数 - -```python -value = option("key", default="default_value") # 当 key 的值存在时,取 option("key") 的值,否则取 "default_value" -``` - -## 40. KCL 中 schema 怎么检查多个属性不能同时为空或同时设置 - -在 KCL 中,对于 schema 的单个属性不能为空可以使用属性非空标记 - -```python -schema Person: - name: str # required. name 不能为空 - age: int # required. age 不能为空 - id?: int # optional. id 可以留空 -``` - -而对于需要检查 schema 属性不能同时为空或者只能有一者为空的情况时,需要借助 schema check 表达式进行书写,下面以同一个 schema Config 的两个属性 a, b 为例进行说明 - -- Config 的 a, b 属性不能同时为空 - -```python -schema Config: - a?: str - b?: str - - check: - a or b, "a属性和b属性不能同时为空" -``` - -- Config 的 a, b 属性只能有一个为空或者都为空(不能同时存在或不为空) - -```python -schema Config: - a?: str - b?: str - - check: - not a or not b, "a属性和b属性不能同时填写" -``` - -## 41. KCL 中 import 了某个文件但是找不到其同目录下其他 KCL 文件定义的 schema 可能是什么原因 - -可能是与使用 import 仅导入了这个文件夹的这一个文件导致,在 KCL 中,import 支持导入整个文件夹,也支持导入某一个文件夹下的的某一个 KCL 文件,比如对于如下目录结构 - -``` -. -├── kcl.mod -├── main.k -└── pkg - ├── pkg1.k - ├── pkg2.k - └── pkg3.k -``` - -在根目录下存在入口文件 main.k,可以在 main.k 中书写如下代码导入整个 pkg 文件夹,此时 pkg 文件夹下的所有 schema 定义互相可见 - -```python -import pkg -``` - -还可以书写如下代码导入单个文件 pkg/pkg1.k,此时 pkg1.k 不能找到其他文件即 pkg2.k/pkg3.k 下的 schema 定义 - -```python -import pkg.pkg1 -``` - -## 42. KCL 中的缩进是如何处理的? - -在 KCL 中,在出现冒号 `:`、中括号对 `[]` 以及大括号对 `{}` 时,一般需要使用换行 + 缩进,同一缩进级的缩进空格数需要保持一致,一个缩进级一般采用 4 个空格表示 - -- 冒号 `:` 后跟换行 + 缩进 - -```python -"""if 语句中的缩进""" -_a = 1 -_b = 1 -if _a >= 1: # 冒号后跟换行+缩进 - if _a > 8: - _b = 2 - elif a > 6: - _b = 3 - -"""schema 定义中的缩进""" -schema Person: # 冒号后跟换行+缩进 - name: str - age: int -``` - -- 中括号对 `[]` 后跟换行 + 缩进 - -```python -data = [ # 左中括号 [ 后跟换行+缩进 - 1 - 2 - 3 -] # 右中括号 ] 前取消缩进 -``` - -```python -data = [ # 左中括号 [ 后跟换行+缩进 - i * 2 for i in range(5) -] # 右中括号 ] 前取消缩进 -``` - -- 大括号对 `{}` 后跟换行 + 缩进 - -```python -data = { # 左大括号 { 后跟换行+缩进 - k1 = "v1" - k2 = "v2" -} # 右大括号 } 前取消缩进 -``` - -```python -data = { # 左大括号 { 后跟换行+缩进 - str(i): i * 2 for i in range(5) -} # 右大括号 } 前取消缩进 -``` - -## 43. 如何为 KCL 代码编写简单的测试? - -KCL 目前的版本还不支持内部程序调试,可以使用 assert 语句以及 print 函数实现数据的断言和打印查看 - -```python -a = 1 -print("The value of a is", a) -assert a == 1 -``` - -此外,还可以借助 kcl-test 测试工具编写 KCL 内部编写测试用例 - -假设有 hello.k 文件,代码如下: - -```python -schema Person: - name: str = "kcl" - age: int = 1 - -hello = Person { - name = "hello kcl" - age = 102 -} -``` - -构造 hello_test.k 测试文件,内容如下: - -```python -schema TestPerson: - a = Person{} - assert a.name == 'kcl' - -schema TestPerson_age: - a = Person{} - assert a.age == 1 - -schema TestPerson_ok: - a = Person{} - assert a.name == "kcl" - assert a.age == 1 -``` - -然后在目录下执行 kcl-test 命令: - -``` -$ kcl-test -ok /pkg/to/app [365.154142ms] -$ -``` - -## 44. KCL 中如何定义函数或定义方法? - -schema 结构在一定程度上充当了函数的功能,并且这个函数具有多个输入参数和多个输出参数的能力,比如如下代码可以实现一个斐波那契数列的功能: - -```python -schema Fib: - n: int - value: int = 1 if n <= 2 else (Fib {n: n - 1}).value + (Fib {n: n - 2}).value - -fib8 = (Fib {n: 8}).value -``` - -输出结果为: - -```yaml -fib8: 21 -``` - -一个合并列表为字典的 schema 函数 - -```python -schema UnionAll[data, n]: - _?: [] = data - value?: {:} = ((UnionAll(data=data, n=n - 1) {}).value | data[n] if n > 0 else data[0]) if data else {} - -schema MergeList[data]: - """Union一个列表中的所有元素返回合并字典 - - [{"key1": "value1"}, {"key2": "value2"}, {"key3": "value3"}] -> {"key1": "value1", "key2": "value2", "key3": "value3"} - """ - _?: [] = data - value?: {:} = (UnionAll(data=data, n=len(data) - 1) {}).value if data else {} -``` - -此外,KCL 支持使用 `lambda` 关键字定义一个函数: - -```python -func = lambda x: int, y: int -> int { - x + y -} -a = func(1, 1) # 2 -``` - -lambda 函数具有如下特性: - -- lambda 函数将最后一个表达式的值作为函数的返回值,空函数体返回 None。 -- 返回值类型注解可以省略,返回值类型为最后一个表达式值的类型 -- 函数体中没有与顺序无关的特性,所有的表达式都是按顺序执行的 - -```python -_func = lambda x: int, y: int -> int { - x + y -} # 使用 lambda 表达式定义一个函数 -_func = lambda x: int, y: int -> int { - x - y -} # Ok -_func = lambda x: int, y: int -> str { - str(x + y) -} # Error (int, int) -> str can't be assigned to (int, int) -> int -``` - -lambda 函数对象不能参与任何计算,只能在赋值语句和调用语句中使用。 - -```python -func = lambda x: int, y: int -> int { - x + y -} -x = func + 1 # Error: unsupported operand type(s) for +: 'function' and 'int(1)' -``` - -```python -a = 1 -func = lambda x: int { - x + a -} -funcOther = lambda f, para: int { - f(para) -} -r = funcOther(func, 1) # 2 -``` - -输出为: - -```python -a: 1 -r: 2 -``` - -可以定义一个匿名函数并直接调用 - -```python -result = (lambda x, y { - z = 2 * x - z + y -})(1, 1) # 3 -``` - -可以在 for 循环使用使用匿名函数 - -```python -result = [(lambda x, y { - x + y -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 3, 3, 4] -``` - -可以在 KCL schema 中定义并使用函数 - -```python -_funcOutOfSchema = lambda x: int, y: int { - x + y -} -schema Data: - _funcInSchema = lambda x: int, y: int { - x + y - } - id0: int = _funcOutOfSchema(1, 1) - id1: int = _funcInSchema(1, 1) - id2: int = (lambda x: int, y: int { - x + y - })(1, 1) -``` - -输出 YAML 为: - -```yaml -data: - id0: 2 - id1: 2 - id2: 2 -``` - -## 45. 为什么变量赋值为枚举类型(字面值联合类型)时会报错 - -在 KCL 中,被定义为字面值联合类型的属性,在赋值时仅允许接收一个字面值或者同为字面值联合类型的变量,比如如下代码是正确的: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -data = Data { - color = "Red" # Ok, 赋值为 "Red"、"Yellow" 和 "Blue" 均可 -} -``` - -然而以下代码是错误的: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -_color = "Red" - -data = Data { - color = _color # Error: expect str(Red)|str(Yellow)|str(Blue), got str -} -``` - -这是因为没有为变量 `_color` 申明一个类型,它会被 KCL 编译器推导为 `str` 字符串类型,因此当一个 “较大” 的类型 `str` 赋值为一个 “较小” 的类型时 `"Red" | "Yellow" | "Blue"` 会报错,一个解决方式是为 `_color` 变量声明一个类型,以下代码是正确的: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -_color: "Red" | "Yellow" | "Blue" = "Red" - -data = Data { - color = _color # Ok -} -``` - -进一步地,我们可以使用类型别名来简化枚举(字面值联合类型的书写),比如如下代码: - -```python -type Color = "Red" | "Yellow" | "Blue" # 定义一个类型别名,可以在不同的地方重复使用,降低代码书写量 - -schema Data: - color: Color - -_color: Color = "Red" - -data = Data { - color = _color # Ok -} -``` - -## 46. 过程式的 for 循环 - -KCL 中为何不支持过程式的 for 循环! - -KCL 提供了推导表达式以及 all/any/map/filter 表达式等用于对一个集合元素进行处理,满足大部分需求,提供过程式的 for 循环体从目前场景看需求暂时不强烈,因此暂未提供过程式的 for 循环支持 - -此外,KCL 中虽然没有支持过程式的 for 循环,但是可以通过 for 循环和 lambda 函数“构造”相应的过程式 for 循环 - -```python -result = [(lambda x: int, y: int -> int { - # 在其中书写过程式的 for 循环逻辑 - z = x + y - x * 2 -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 2, 4, 4] -``` - -## 47. 默认变量不可变 - -KCL 变量不可变性是指 KCL 顶层结构中的非下划线 `_` 开头的导出变量初始化后不能被改变。 - -```python -schema Person: - name: str - age: int - -a = 1 # a会输出到YAML中,一旦赋值不可修改 -_b = 1 # _b变量以下划线开头命名,不会输出到YAML中, 可多次赋值修改 -_b = 2 -alice = Person { - name = "Alice" - age = 18 -} -``` - -规定变量不可变的方式分为两类: - -- schema 外的非下划线顶层变量 - -```python -a = 1 # 不可变导出变量 -_b = 2 # 可变非导出变量 -``` - -## 48. 在 KCL 中存在类似 Go `interface{}`/`any` 或者 Java `Object` 的类型嘛? - -在 KCL 中,我们可以使用 `any` 类型注解来定义一个变量存储任意类型比如整数、字符串、schema 结构等数据。比如如下例子: - -```python -schema Data: - id: int = 1 - -var_list: [any] = [1, "12", Data {}] -``` - -输出 YAML 为: - -```yaml -var_list: - - 1 - - "12" - - id: 1 -``` - -此外,我们可以使用 `typeof` 函数来判断 KCL 变量的类型: - -```python -schema Data1: - id: int = 1 - -schema Data2: - name: str = "name" - -data_list: [any] = [Data1 {}, Data2 {}] -data_type_list: [str] = [typeof(data) for data in data_list] -``` - -输出 YAML 为: - -```yaml -data_list: - - id: 1 - - name: name -data_type_list: - - Data1 - - Data2 -``` - -## 49. 如何通过编写 KCL 插件进行扩展? - -KCL 插件在 KCL 的 plugins 子目录(通常安装在 `$HOME/.kcl/plugins` 目录),或者通过 `$KCL_PLUGINS_ROOT` 环境变量设置(环境变量优先级更高)。对于插件开发人员,插件都在 [Git 仓库](https://github.com/kcl-lang/kcl-plugin)管理,可以将插件仓库克隆到该目录进行开发。 - -KCL 内置了 kcl-plugin 脚手架命令用于辅助用户使用 Python 语言编写 KCL 插件,以便在 KCL 文件当中调用相应的插件对 KCL 语言本身进行增强,比如访问网络,读写 IO,CMDB 查询和加密解密等功能。 - -``` -usage: kcl-plugin [-h] {list,init,info,gendoc,test} ... - -positional arguments: - {list,init,info,gendoc,test} - kcl plugin sub commands - list list all plugins - init init a new plugin - info show plugin document - gendoc gen all plugins document - test test plugin - -optional arguments: - -h, --help show this help message and exit -``` - -比如想要开发一个名为 io 插件,就可以使用如下命令成功新建一个 io 插件 - -``` -kcl-plugin init io -``` - -然后可以使用如下命令获得 plugin 的根路径并 cd 到相应的 io 插件目录进行开发 - -``` -kcl-plugin info -``` - -比如想要开发一个读文件的函数 read_file,就可以在 `$plugin_root/io` 的 `plugin.py` 中进行 python 代码编写: - -```python -# Copyright 2020 The KCL Authors. All rights reserved. - -import pathlib - -INFO = { - 'name': 'io', - 'describe': 'my io plugin description test', - 'long_describe': 'my io plugin long description test', - 'version': '0.0.1', -} - - -def read_file(file: str) -> str: - """Read string from file""" - return pathlib.Path(file).read_text() - -``` - -另外可以在 `plugin_test.py` 中编写相应的测试函数,也可以直接编写如下所示 KCL 文件进行测试: - -```python -import kcl_plugin.io - -text = io.read_file('test.txt') -``` - -还可以使用 info 命令查看 io 插件的信息 - -``` -kcl-plugin info io -``` - -``` -{ - "name": "io", - "describe": "my io plugin description test", - "long_describe": "my io plugin long description test", - "version": "0.0.1", - "method": { - "read_file": "Read string from file" - } -} -``` - -最后将编写测试完成的插件在 `kcl_plugins` 仓库提 MR 合并即可 - -## 50. 如何在 KCL 中进行基本类型转换 - -可以使用`int()`, `float()`和`str()` 这些内置的方法来进行 `int`, `float` 和 `str` 之间的基本类型转换. - -``` -_t = 1 - -t_str: str = str(_t) # 输出的 t_str 为一个字符串 "t_str: '1'" -t_int: int = int(t_str) # 输出的 t_int 为一个整型 "t_int: 1" -t_float: float = float(t_str) # 输出的 t_float 为一个浮点型 "t_float: 1.0" -``` - -如果您想查看更多详细的关于KCL类型系统和类型转换的内容,您可以查阅 [KCL 内置类型](https://kcl-lang.io/docs/reference/lang/tour#built-in-types) 和 [KCL 类型系统](https://kcl-lang.io/docs/reference/lang/tour#type-system)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2.json deleted file mode 100644 index a9e8bfe5..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "sidebar.user_docs.category.Get Started": { - "message": "快速开始" - }, - "sidebar.user_docs.category.Introduction": { - "message": "简介" - }, - "sidebar.user_docs.category.User Guide": { - "message": "用户手册" - }, - "sidebar.user_docs.guides.category.Automation": { - "message": "自动化" - }, - "sidebar.user_docs.category.Configuration": { - "message": "配置" - }, - "sidebar.user_docs.category.Data Integration": { - "message": "数据集成" - }, - "sidebar.user_docs.category.Package Management": { - "message": "包管理工具" - }, - "sidebar.user_docs.category.How to": { - "message": "如何使用" - }, - "sidebar.user_docs.category.Schema Definition": { - "message": "模型定义" - }, - "sidebar.user_docs.category.Validation": { - "message": "验证" - }, - "sidebar.user_docs.category.Concepts": { - "message": "核心概念" - }, - "sidebar.user_docs.category.FAQ": { - "message": "常见问答" - }, - "sidebar.reference.category.Tutorial": { - "message": "教程" - }, - "sidebar.reference.category.Code Lab": { - "message": "代码实验室" - }, - "sidebar.reference.category.Spec": { - "message": "语言规范" - }, - "sidebar.reference.category.Errors and Warnings": { - "message": "错误与警告" - }, - "sidebar.reference.category.Types": { - "message": "类型系统" - }, - "sidebar.reference.category.System Package": { - "message": "系统模块" - }, - "sidebar.reference.category.Plugin System": { - "message": "插件系统" - }, - "sidebar.reference.category.Multi-Language": { - "message": "多语言集成" - }, - "sidebar.reference.category.Cheat Sheet": { - "message": "备忘表" - }, - "sidebar.reference.category.Package Management": { - "message": "包管理工具" - }, - "sidebar.reference.category.Command Reference": { - "message": "命令参考" - }, - "sidebar.reference.category.Advanced-Concepts": { - "message": "进阶概念" - }, - "sidebar.reference.category.Best-Practices": { - "message": "最佳实践" - }, - "sidebar.tools.category.Command Line Tools": { - "message": "命令行工具" - }, - "sidebar.tools.category.KCL Tools": { - "message": "语言工具" - }, - "sidebar.tools.category.OpenAPI Tools": { - "message": "OpenAPI 工具" - }, - "sidebar.community.category.Community": { - "message": "简介" - }, - "sidebar.community.category.Types": { - "message": "类型系统" - }, - "sidebar.community.category.Contribution Guide": { - "message": "贡献指南" - }, - "sidebar.community.category.Release Policy": { - "message": "发布策略" - }, - "sidebar.docs.category.GitOps": { - "message": "GitOps", - "description": "The label for category GitOps in sidebar docs" - }, - "sidebar.docs.category.CI Integration": { - "message": "CI 集成", - "description": "The label for category CI Integration in sidebar docs" - }, - "sidebar.user_docs.category.GitOps": { - "message": "GitOps", - "description": "The label for category GitOps in sidebar user_docs" - }, - "sidebar.user_docs.category.CI Integration": { - "message": "CI 集成", - "description": "The label for category CI Integration in sidebar user_docs" - }, - "sidebar.docs.category.Mutate or Validate Kubernetes Manifests": { - "message": "编辑或验证 Kubernetes 资源", - "description": "The label for category Mutate or Validate Kubernetes Manifests in sidebar docs" - }, - "sidebar.user_docs.category.Mutate or Validate Kubernetes Manifests": { - "message": "编辑或验证 Kubernetes 资源", - "description": "The label for category Mutate or Validate Kubernetes Manifests in sidebar user_docs" - }, - "sidebar.docs.category.Secret Management": { - "message": "敏感信息管理", - "description": "The label for category Secret Management in sidebar docs" - }, - "sidebar.user_docs.category.Secret Management": { - "message": "敏感信息管理", - "description": "The label for category Secret Management in sidebar user_docs" - } -} \ No newline at end of file diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/release-policy/roadmap.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/release-policy/roadmap.md deleted file mode 100644 index 2f0ee86a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/release-policy/roadmap.md +++ /dev/null @@ -1,3 +0,0 @@ -# 路线规划 - -![](/img/docs/community/release-policy/roadmap.jpg) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/error/exception.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/error/exception.md deleted file mode 100644 index cd18995f..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/error/exception.md +++ /dev/null @@ -1,1584 +0,0 @@ ---- -title: "KCL 错误与警告" -linkTitle: "KCL 错误与警告" -type: "docs" -weight: 2 -description: KCL 错误与警告 ---- - -# KCL 错误与警告 - -文档的此部分中的文章介绍了由 KCL 生成的诊断错误和警告消息。 - -**注意:** -**KCL 可以报告多种错误和警告。找到错误或警告后,KCL 可能会对代码意向作出假设并尝试继续,以便可以同时报告更多问题。 如果工具做出错误假设,则后续错误或警告可能不适应与当前 KCL 程序。 因此,纠正项目中的问题时,请先纠正第一个错误或警告,然后重新运行获取新的错误信息。 一个修补程序可能会导致后续错误消失。** - -此部分文档的主要内容包括: - -[KCL 语法错误 (E1xxx)](#11-kcl-%E8%AF%AD%E6%B3%95%E9%94%99%E8%AF%AF-e1xxx) : 如果 KCL 在当前 KCL 程序中发现了非法的 KCL 语法,KCL 就会停止运行并输出 KCL 程序语法错误的提示信息. - -[KCL 编译错误 (E2xxx)](#12-kcl-%E7%BC%96%E8%AF%91%E9%94%99%E8%AF%AF-e2xxx) : 如果 KCL 在一个不包含语法错误的 KCL 程序中发现了与 KCL 语义不符的代码,KCL 就会停止运行并输出编译错误的提示信息。 - -[KCL 运行时错误 (E3xxx)](#13-kcl-%E8%BF%90%E8%A1%8C%E6%97%B6%E9%94%99%E8%AF%AF-e3xxx) : KCL 程序通过编译后会生成 KCL 字节码,如果 KCL 在执行 KCL 字节码过程中出现错误,KCL 就会停止运行并输出运行时错误的提示信息. - -[KCL 编译警告 (W2xxx)](#14-kcl-%E7%BC%96%E8%AF%91%E8%AD%A6%E5%91%8A-w2xxx) : 当 KCL 发现可能导致运行失败的 KCL 代码,KCL 不会立即停止运行,但是会输出潜在错误的警告提示。 - -## 1.1 KCL 语法错误 (E1xxx) - -KCL 会出现的语法错误信息如下表所示: - -| ewcode | KCL exception | messages | -| ------ | ------------------------------------------------------------------- | ----------------------- | -| E1001 | [InvalidSyntaxError](#111-invalidsyntaxerror-e1001) | Invalid syntax | -| E1002 | [KCLTabError](#112-kcltaberror-e1002) | Tab Error | -| E1003 | [KCLIndentationError](#113-kclindentationerror-e1003) | Indentation Error | -| E1I37 | [IllegalArgumentSyntaxError](#114-illegalargumentsyntaxerror-e1i37) | Illegal argument syntax | - -### 1.1.1 InvalidSyntaxError [E1001] - -如果在运行 KCL 时遇到错误: - -- `InvalidSyntaxError`, 对应的 encode 为 `E1001` - -那么此时 KCL 程序中出现了 - -- 非法的 KCL 语法。 - -可能出现错误的 KCL 程序片段如下: - -```python -a, b = 1, 2 # 通过 “=” 赋值多个变量在KCL中是非法的。 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> /syntax_error/general/multiple_assign/case0/main.k:1:2 - | -1 | a, b = 1, 2 # Multiple assign is illegal in KCL syntax - | ^ expected statement - | -``` - -### 1.1.2 KCLTabError - -如果在运行 KCL 时遇到错误: `KCLTabError` - -那么此时 KCL 程序中出现了 - -- Tab 与空格混用的问题。KCL 中禁止在代码缩进中混用 Tab 和空格。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - name: str # 通过tab表示缩进 - age: int # 通过四个空格标识缩进, - # 在当前运行环境中的四个空格与tab不同 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> File /syntax_error/tab/tab_error_0/main.k:6:5 - | -3 | age: int = 1 - | ^ inconsistent use of tabs and spaces in indentation - | -``` - -可以尝试以下步骤来修复这个错误: - -- 在 KCL 程序中全部使用 Tab 或者全部使用四个空格,不要混用。 - -### 1.1.3 KCLIndentationError - -如果在运行 KCL 时遇到错误: `KCLIndentationError` - -那么此时 KCL 程序中出现了 - -- 程序缩进错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - name: str # 使用一个tab或者四个空格表示缩进 - age: int # KCL不支持使用三个空格表示缩进 - info: str # KCL不支持使用两个空格表示缩进 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> /syntax_error/indent/indent_error_0/main.k:3:4 - | -3 | age: int # three white spaces are illegal - | ^ unindent 3 does not match any outer indentation level - | -``` - -可以尝试以下步骤来修复这个错误: - -- 在 KCL 程序中全部使用 Tab 或者全部使用四个空格来表示缩进。 - -### 1.1.4 IllegalArgumentSyntaxError - -如果在运行 KCL 时遇到错误: `IllegalArgumentSyntaxError` - -那么此时 KCL 程序中出现了 - -- 参数语法错误 - -可能出现错误的 KCL 程序片段如下: - -```python -# KCL中带有keyword的参数必须出现在不带有keyword参数后面 -# 带有keyword的参数: type="list", default={"key": "value"} -# 不带有keyword的参数: "key1" -a = option(type="list", default={"key": "value"}, "key1") -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> /option/type_convert_fail_2/main.k:3:57 - | -3 | a = option(type="list", default={"key": "value"}, "key1") - | ^ positional argument follows keyword argument - | -``` - -可以尝试以下步骤来修复这个错误: - -- KCL 中带有 keyword 的参数必须出现在不带有 keyword 参数后面, 参数正常顺序: - -```python -func(input_1, ..., input_n, param_with_key_1 = input_with_key_1, ..., param_with_key_n = input_with_key_n) -``` - -## 1.2 KCL 编译错误 (E2xxx) - -KCL 会出现的编译错误信息如下表所示: - -| ewcode | KCL exception | messages | -| ------ | ----------------------------------------------------------------------- | --------------------------------------------------- | -| E2F04 | [CannotFindModule](#121-cannotfindmodule-e2f04) | Cannot find the module | -| E2F05 | [FailedLoadModule](#122-failedloadmodule-e2f05) | Failed to load module | -| E2H13 | [UnKnownDecoratorError](#123-unknowndecoratorerror-e2h13) | UnKnown decorator | -| E2H14 | [InvalidDecoratorTargetError](#124-invaliddecoratortargeterror-e2h14) | Invalid Decorator Target | -| E2C15 | [MixinNamingError](#125-mixinnamingerror-e2c15) | Illegal mixin naming | -| E2C16 | [MixinStructureIllegal](#126-mixinstructureillegal-e2c16) | Illegal mixin structure | -| E2B17 | [CannotAddMembersComplieError](#127-cannotaddmemberscomplieerror-e2b17) | Cannot add members to a schema | -| E2B20 | [IndexSignatureError](#128-indexsignatureerror-e2b20) | Invalid index signature | -| E2G22 | [TypeComplieError](#129-typecomplieerror-e2g22) | The type got is inconsistent with the type expected | -| E2L23 | [CompileError](#1210-compileerror-e2l23) | A complie error occurs during compiling | -| E2L25 | [KCLNameError](#1211-kclnameerror-e2l25) | Name Error | -| E2L26 | [KCLValueError](#1212-kclvalueerror-e2l26) | Value Error | -| E2L27 | [KCLKeyError](#1213-kclkeyerror-e2l27) | Key Error | -| E2L28 | [UniqueKeyError](#1214-uniquekeyerror-e2l28) | Unique key error | -| E2A29 | [KCLAttributeComplieError](#1215-kclattributecomplieerror-e2a29) | Attribute error occurs during compiling | -| E2D32 | [MultiInheritError](#1216-multiinheriterror-e2d32) | Multiple inheritance is illegal | -| E2D34 | [IllegalInheritError](#1217-illegalinheriterror-e2d34) | Illegal inheritance | -| E2I36 | [IllegalArgumentComplieError](#1218-illegalargumentcomplieerror-e2i36) | Illegal argument during compiling | -| E3L41 | [ImmutableCompileError](#1219-immutablecompileerror-e3l41) | Immutable variable is modified | - -### 1.2.1 CannotFindModule [E2F04] - -如果在运行 KCL 时遇到错误: - -- `CannotFindModule`, 对应的 encode 为 `E2F04` - -那么此时 KCL 程序中出现了 - -- 无法找到导入模块错误 - -可能出现错误的 KCL 程序片段如下: - -```python -import .some0.pkg1 as some00 # some0 not found in package - -Name1 = some00.Name # some0.pkg1.name -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2F04]: CannotFindModule - --> import_abs_fail_0/app-main/main.k:1:1 - | -1 | import .some0.pkg1 as some00 # some0 not found in package - | Cannot find the module .some0.pkg1 - | -``` - -可以尝试以下步骤来修复这个错误: - -- 在 import 路径下添加导入模块文件。 - -### 1.2.2 FailedLoadModule [E2F05] - -如果在运行 KCL 时遇到错误: - -- `FailedLoadModule`, 对应的 encode 为 `E2F05` - -那么此时 KCL 程序中出现了 - -- 导入模块加载错误 - -可以尝试以下步骤来修复这个错误: - -- 查看文件是否可读 -- 查看文件是否为 kcl 文件 - -### 1.2.3 UnKnownDecoratorError - -如果在运行 KCL 时遇到错误: - -- `UnKnownDecoratorError`, 对应的 encode 为 `E2H13` - -那么此时 KCL 程序中出现了 - -- 未知的装饰器错误 - -可能出现错误的 KCL 程序片段如下: - -```python -@err_deprecated # 这是一个非法的装饰器 -schema Person: - firstName: str = "John" - lastName: str - name: str - -JohnDoe = Person { - name: "deprecated" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> deprecated/unknown_fail_1/main.k:1:2 - | -1 | @err_deprecated # 这是一个非法的装饰器 - | ^ UnKnown decorator err_deprecated - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查装饰器是否存在。 - -### 1.2.4 InvalidDecoratorTargetError [E2H14] - -如果在运行 KCL 时遇到错误: - -- `InvalidDecoratorTargetError`, 对应的 encode 为 `E2H14` - -那么此时 KCL 程序中出现了 - -- 无效的装饰器目标错误。 - -可以尝试以下步骤来修复这个错误: - -- 检查使用装饰器的 KCL 代码是否出现异常。 - -### 1.2.5 MixinNamingError [E2C15] - -如果在运行 KCL 时遇到错误: - -- `MixinNamingError`, 对应的 encode 为 `E2C15` - -那么此时 KCL 程序中出现了 - -- Mixin 命名错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - firstName: str - lastName: str - fullName: str - -schema Fullname: # Mixin的名称应该以Mixin结尾 - fullName = "{} {}".format(firstName, lastName) - -schema Scholar(Person): - mixin [Fullname] - school: str - -JohnDoe = Scholar { - "firstName": "John", - "lastName": "Doe", - "fullName": "Doe Jon" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2D34]: IllegalInheritError - --> mixin/invalid_name_failure/main.k:10:12 - | -10 | mixin [Fullname] - | ^ illegal schema mixin object type 'Fullname' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 如果 schema 是一个 mixin,那么这个 schema 的名称应该以 Mixin 结尾。 - -### 1.2.6 MixinStructureIllegal [E2C16] - -如果在运行 KCL 时遇到错误: - -- `MixinStructureIllegal`, 对应的 encode 为 `E2C16` - -那么此时 KCL 程序中出现了 - -- Mixin 结构错误。 - -可以尝试以下步骤来修复这个错误: - -- 检查作为 Mixin 的 Schema 的结构。 - -### 1.2.7 CannotAddMembersComplieError [E2B17] - -如果在运行 KCL 时遇到错误: - -- `CannotAddMembersComplieError`, 对应的 encode 为 `E2B17` - -那么此时 KCL 程序中出现了 - -- 使用 Schema 中不存在的成员。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Girl: - gender: str = "female" - -alice = Girl { - "first": "alice", # Schema中没有成员“first” - "last": " Green", # Schema中没有成员“last” - "age": 10 # Schema中没有成员“age” -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:5:5 - | -5 | "first": "alice", - | ^ Cannot add member 'first' to schema 'Girl' - | - -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:6:5 - | -6 | "last": " Green", - | ^ Cannot add member 'last' to schema 'Girl' - | - -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:7:5 - | -7 | "age": 10 - | ^ Cannot add member 'age' to schema 'Girl' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 为 Schema 添加缺少的成员。 -- 不要使用 Schema 中不存在的成员。 - -### 1.2.8 IndexSignatureError [E2B20] - -如果在运行 KCL 时遇到错误: - -- `IndexSignatureError`, 对应的 encode 为 `E2B20` - -那么此时 KCL 程序中出现了 - -1. 在一个 schema 中使用多个索引签名。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Data: - [str]: str - [str]: int # 在同一个schema中使用了多个索引签名 - -data = Data { - name: "test" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError ----> index_signature/fail_1/main.k:3:5 - | -3 | [str]: int - | 5 ^ only one index signature is allowed in the schema - | -``` - -可以尝试以下步骤来修复这个错误: - -- 删除多余的索引签名。 - -2. schema 中索引签名的名称与 schema 中其他属性的名称存在同名冲突。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Data: - name: str # name - [name: str]: str # 已有名称为name的schema属性 - -data = Data { - name: "test" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: IndexSignatureError - --> index_signature/fail_2/main.k:3:5 - | -3 | [name: str]: str # the same name with the above attribute - | ^ index signature attribute name 'name' cannot have the same name as schema attributes - | -``` - -可以尝试以下步骤来修复这个错误: - -- 删除 schema 中出现同名冲突的属性或者索引签名,或者为它们更换不同的名称。 - -3. schema 索引签名的类型与 schema 实例化的属性类型冲突。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Data: - [str]: int - -data = Data { - name: "test" # 索引签名为 [str]:int, "test"的类型不是int. -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> index_signature/fail_3/main.k:5:5 - | -5 | name: "test" # Conflict with [str]:int, "test" is a string. - | ^ expected int, got str(test) - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 schema 索引签名的类型与 schema 实例中的属性类型是否一致。 - -4. Schema 中的属性与索引签名冲突 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Data: - count: int # int 和 str 冲突 - [str]: str - -data = Data { - count: 1 -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: IndexSignatureError - --> index_signature/fail_4/main.k:2:5 - | -2 | count: int - | ^ the type 'int' of schema attribute 'count' does not meet the index signature definition [str]: str - | -``` - -可以尝试以下步骤来修复这个错误: - -- 调整 Schema 属性或者调整索引签名。 - -### 1.2.9 TypeComplieError [E2G22] - -如果在运行 KCL 时遇到错误: - -- `TypeComplieError`, 对应的 encode 为 `E2G22` - -那么此时 KCL 程序中出现了 - -- 静态类型检查错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - firstName: str - lastName: int - -JohnDoe = Person { - "firstName": "John", - "lastName": "Doe" # Schema中定义lastName: int -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> type/type_fail_0/main.k:7:5 - | -7 | "lastName": "Doe" # Type Error,lastName: int,“Doe” is a string. - | ^ expected int, got str(Doe) - | - - --> type/type_fail_0/main.k:3:5 - | -3 | lastName: int - | ^ variable is defined here, its type is int, but got str(Doe) - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查赋给某个变量的值的类型与这个变量的类型是否一致。 - -### 1.2.10 CompileError [E2L23] - -如果在运行 KCL 时遇到错误: - -- `CompileError`, 对应的 encode 为 `E2L23` - -那么此时 KCL 程序中出现了 - -1. 不支持的类型合并 - -可能出现错误的 KCL 程序片段如下: - -```python -_data = [1, 2, 3] -_data |= "value" -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> union/fail/fail_1/main.k:2:1 - | -2 | _data |= "value" - | ^ unsupported operand type(s) for |: '[int]' and 'str(value)' - | -``` - -1. 不支持的操作符类型 - -可能出现错误的 KCL 程序片段如下: - -```python -a = None -b = 1 + None # KCL中不支持None和int之间进行+操作 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> operator/operator_fail_0/main.k:2:5 - | -2 | b = 1 + None # Unsupport operand type + for int and None - | ^ unsupported operand type(s) for +: 'int(1)' and 'NoneType' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 调整操作符号,使其同时支持两个操作数的类型。 -- 调整操作数,使其同时符合操作符号的约束。 - -1. 没有定义的变量 - -可能出现错误的 KCL 程序片段如下: - -```python -a = 1 -b = "${c + 1}" # 'c' 没有定义 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> var_not_define_fail_0/main.k:2:8 - | -2 | b = "${c + 1}" # 'c' is not defined - | ^ name 'c' is not defined - | -``` - -可以尝试以下步骤来修复这个错误: - -- 对未定义的变量进行定义。 -- 在表达式中去掉对未定义变量的操作。 - -4. 无效的赋值表达式 - -可能出现错误的 KCL 程序片段如下: - -```python -# pkg.k -a = 1 - -# main.k -import pkg -pkg.a |= 2 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> pkg_inplace_modify_1/main.k:3:1 - | -6 | pkg |= 2 - | ^ unsupported operand type(s) for |: 'module 'pkg'' and 'int(2)' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查赋值表达式的内容。 - -1. 无效的字符串表达式 - -可能出现错误的 KCL 程序片段如下: - -```python -a = 1 -b = "${b = a + 1}" # Invalid string interpolation expression -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> invalid_format_value_fail_0/main.k:2:5 - | -2 | b = "${b = a + 1}" - | 5 ^ invalid string interpolation expression 'b = a + 1' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查字符串表达式的内容。 - -1. 无效的循环变量 - -可能出现错误的 KCL 程序片段如下: - -```python -data = {"key1": "value1", "key2": "value2"} -dataLoop = [i for i, j, k in data] # the number of loop variables can only be 1 or 2 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> dict/invalid_loop_var_fail_0/main.k:2:25 - | -2 | dataLoop = [i for i, j, k in data] # the number of loop variables can only be 1 or 2 - | ^ the number of loop variables is 3, which can only be 1 or 2 - | -``` - -### 1.2.11 KCLNameError [E2L25] - -如果在运行 KCL 时遇到错误: - -- `KCLNameError`, 对应的 encode 为 `E2L25` - -那么此时 KCL 程序中出现了 - -- 试图访问的变量名不存在 - -可以尝试以下步骤来修复这个错误: - -- 检查报错信息中出现的变量是否存在。 - -### 1.2.12 KCLValueError [E2L26] - -如果在运行 KCL 时遇到错误: - -- `KCLValueError`, 对应的 encode 为 `E2L26` - -那么此时 KCL 程序中出现了 - -- 值错误,传给参数的类型不正确 - -可以尝试以下步骤来修复这个错误: - -- 检查参数的具体类型。 - -### 1.2.13 KCLKeyError [E2L27] - -如果在运行 KCL 时遇到错误: - -- `KCLKeyError`, 对应的 encode 为 `E2L27` - -那么此时 KCL 程序中出现了 - -- 使用了 dict 中不存在的 key 时引发的 key 错误 - -可以尝试以下步骤来修复这个错误: - -- 检查字典中是否存在 key。 - -### 1.2.14 UniqueKeyError [E2L28] - -如果在运行 KCL 时遇到错误: - -- `UniqueKeyError`, 对应的 encode 为 `E2L28` - -那么此时 KCL 程序中出现了 - -- 变量同名或重复定义。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - name: str = "kcl" - age: int = 1 - -schema Person: - aa: int - -x0 = Person{} -x1 = Person{age:101} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L28]: UniqueKeyError - --> /schema/same_name/main.k:5:8 - | -5 | schema Person: - | ^ Unique key error name 'Person' - | - - --> /schema/same_name/main.k:1:8 - | -1 | schema Person: - | ^ The variable 'Person' is declared here - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查出现错误的名称是否已经被使用。 - -### 1.2.15 KCLAttributeComplieError [E2A29] - -如果在运行 KCL 时遇到错误: - -- `KCLAttributeComplieError`, 对应的 encode 为 `E2A29` - -那么此时 KCL 程序中出现了 - -- Schema 的属性错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -# pkg -schema A: - field_A: str - -# main -import pkg as p - -a = p.D + 1 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> /import/module/no_module_attr_fail_0/main.k:4:5 - | -4 | a = p.D + 1 - | ^ module 'pkg' has no attribute D - | -``` - -可以尝试以下步骤来修复这个错误: - -- 在使用 Schema 属性时检查这个属性是否存在。 - -### 1.2.16 MultiInheritError [E2D32] - -如果在运行 KCL 时遇到错误: - -- `MultiInheritError`, 对应的 encode 为 `E2D32` - -那么此时 KCL 程序中出现了 - -- 多继承错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - firstName: str - lastName: str - -schema KnowledgeMixin: - firstName: int - subject: str - -schema Scholar(KnowledgeMixin, Person): # KCL中不支持多继承 - school: str -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> /schema/inherit/multi_inherit_fail_1/main.k:9:30 - | -9 | schema Scholar(KnowledgeMixin, Person): - | ^ expected one of [")"] got , - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查程序的继承结构,KCL 中不支持多继承。 - -### 1.2.17 IllegalInheritError [E2D34] - -如果在运行 KCL 时遇到错误: - -- `IllegalInheritError`, 对应的 encode 为 `E2D34` - -那么此时 KCL 程序中出现了 - -- 不合法的继承结构 - -可能出现错误的 KCL 程序片段如下: - -```python -schema FullnameMixin: - fullName = "{} {}".format(firstName, lastName) - -schema Scholar(FullnameMixin): # KCL中不支持Schema继承Mixin - school: str -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError -Invalid value for top level arguments -``` - -可以尝试以下步骤来修复这个错误: - -- KCL 中 Schema 支持单继承 Schema。 - -### 1.2.18 IllegalArgumentComplieError [E2I36] - -如果在运行 KCL 时遇到错误: - -- `IllegalArgumentComplieError`, 对应的 encode 为 `E2I36` - -那么此时 KCL 程序中出现了 - -- 参数错误 - -可能出现错误的 KCL 程序片段如下: - -```python -a = option("key") - -# kcl main.k -D key=value= -# key=value= is an illegal expression -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError -Invalid value for top level arguments -``` - -可以尝试以下步骤来修复这个错误: - -- 检查通过命令设置的 KCL option 参数是否为合法参数。 - -### 1.2.19 ImmutableCompileError [E3L41] - -如果在运行 KCL 时遇到错误: - -- `ImmutableCompileError`, 对应的 encode 为 `E3L41` - -那么此时 KCL 程序中出现了 - -- 不可变量的值发生改变 - -可能出现错误的 KCL 程序片段如下: - -```python -a = 2147483646 -a += 1 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: ImmutableError - --> augment_assign/main.k:2:1 - | -2 | a += 1 - | ^ Immutable variable 'a' is modified during compiling - | - - --> augment_assign/main.k:1:1 - | -1 | a = 2147483646 - | ^ The variable 'a' is declared here firstly - | -note: change the variable name to '_a' to make it mutable -``` - -可以尝试以下步骤来修复这个错误: - -- 将被改变的不可变量设置为私有或者去掉对不可变量值的改动。 - -## 1.3 KCL 运行时错误 (E3xxx) - -KCL 会出现的运行时错误信息如下表所示: - -| ewcode | KCL exception | messages | -| ------ | ----------------------------------------------------------------------- | --------------------------------------------------- | -| E3F06 | [RecursiveLoad](#131-recursiveload-e3f06) | Recursively loading module | -| E3K04 | [FloatOverflow](#132-floatoverflow-e3k04) | Float overflow | -| E3K09 | [IntOverflow](#133-intoverflow-e3k09) | Integer overflow | -| E3N11 | [DeprecatedError](#134-deprecatederror-e3n11) | Deprecated error | -| E3A30 | [KCLAttributeRuntimeError](#135-kclattributeruntimeerror-e3a30) | Attribute error occurs at runtime | -| E3G21 | [TypeRuntimeError](#136-typeruntimeerror-e3g21) | The type got is inconsistent with the type expected | -| E3B17 | [SchemaCheckFailure](#137-schemacheckfailure-e3b17) | Schema check is failed to check condition | -| E3B19 | [CannotAddMembersRuntimeError](#138-cannotaddmembersruntimeerror-e3b19) | Cannot add members to a schema | -| E3M38 | [EvaluationError](#139-evaluationerror-e3m38) | Evaluation failure | -| E3M39 | [InvalidFormatSpec](#1310-invalidformatspec-e3m39) | Invalid format specification | -| E3M40 | [KCLAssertionError](#1311-kclassertionerror-e3m40) | Assertion failure | -| E3M44 | [ImmutableRuntimeError](#1312-immutableruntimeerror-e3m44) | Immutable variable is modified | -| E2D33 | [CycleInheritError](#1313-cycleinheriterror-e2d33) | Cycle Inheritance is illegal | -| E3M42 | [KCLRecursionError](#1314-kclrecursionerror-e3m42) | Recursively reference | - -### 1.3.1 RecursiveLoad [E3F06] - -如果在运行 KCL 时遇到错误: - -- `RecursiveLoad`, 对应的 encode 为 `E3F06` - -那么此时 KCL 程序中出现了 - -- 循环导入错误 - -可能出现错误的 KCL 程序片段如下: - -``` -# module.k -import main # module.k 导入了 main.k - -print('module') - -# main.k -import module # main.k 导入了 module.k - -print('main') -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /import/recursive_import_fail/main.k:4 - | -2 | import module # main.k imports module.k - | ^ There is a circular import reference between module main and module - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查包的导入部分是否存在循环导入的问题。 - -### 1.3.2 FloatOverflow [E3K04] - -如果在运行 KCL 时遇到错误: - -- `FloatOverflow`, 对应的 encode 为 `E3K04` - -那么此时 KCL 程序中出现了 - -- 浮点数溢出 - -可能出现错误的 KCL 程序片段如下: - -```python -uplimit = 3.402823466e+39 -epsilon = 2.220446049250313e-16 -a = uplimit * (1 + epsilon) - -# kcl main.k -r -d -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /range_check_float/overflow/number_0/main.k:3:1 - | -3 | a = uplimit * (1 + epsilon) - | 3.4028234660000003e+39: A 32-bit floating point number overflow - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查浮点数的值是否在 KCL 支持的数字范围内。 - -### 1.3.3 IntOverflow [E3K09] - -如果在运行 KCL 时遇到错误: - -- `IntOverflow`, 对应的 encode 为 `E3K09` - -那么此时 KCL 程序中出现了 - -- 整数溢出 - -可能出现错误的 KCL 程序片段如下: - -```python -_a = 9223372036854775807 -_a += 1 - -# kcl test.k -d -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /range_check_int/augment_assign_fail_1/main.k:2:1 - | -2 | _a += 1 - | 9223372036854775808: A 64 bit integer overflow - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查整数的值是否在 KCL 支持的数字范围内。 - -### 1.3.4 DeprecatedError [E3N11] - -如果在运行 KCL 时遇到错误: - -- `DeprecatedError`, 对应的 encode 为 `E3N11` - -那么此时 KCL 程序中出现了 - -- 使用废弃代码 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - firstName: str = "John" - lastName: str - @deprecated(version="1.16", reason="use firstName and lastName instead", strict=True) - name: str - -JohnDoe = Person { - name: "deprecated" # name已经被过时,并且strict设置为True -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /range_check_float/overflow/number_0/main.k:7:1 - | -7 | JohnDoe = Person { - | name was deprecated since version 1.16, use firstName and lastName instead - | -``` - -可以尝试以下步骤来修复这个错误: - -- strict 设置为 True 时无法使用过时的代码,可以将 strict 设置为 False,将不会出现错误,而是输出一个警告。 -- 调整代码,不使用已经过时的代码。 - -### 1.3.5 KCLAttributeRuntimeError [E3A30] - -如果在运行 KCL 时遇到错误: - -- `KCLAttributeRuntimeError`, 对应的 encode 为 `E3A30` - -那么此时 KCL 程序中出现了 - -- 属性错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -import math - -a = math.err_func(1) # err_func is not found in math -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /import/module/no_module_attr_fail_2/main.k:3:5 - | -3 | a = math.err_func(1) # err_func is not found in math - | ^ module 'math' has no attribute err_func - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查属性调用是否正确。 - -### 1.3.6 TypeRuntimeError [E3G21] - -如果在运行 KCL 时遇到错误: - -- `TypeRuntimeError`, 对应的 encode 为 `E3G21` - -那么此时 KCL 程序中出现了 - -- 类型检查错误 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - name: str = "Alice" - -_personA = Person {} -_personA |= {"name" = 123.0} # name: str = "Alice" -personA = _personA -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /fail/fail_4/main.k:2:1 - | -2 | name: str = "Alice" - | expect str, got float - | -``` - -可以尝试以下步骤来修复这个错误: - -- 停止错误的类型合并或者将类型调整为 KCL 支持的类型合并。 - -### 1.3.7 SchemaCheckFailure [E3B17] - -如果在运行 KCL 时遇到错误: - -- `SchemaCheckFailure`, 对应的 encode 为 `E3B17` - -那么此时 KCL 程序中出现了 - -- Schema 中的 check 条件冲突 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - lastName: str - age: int - check: - age < 140, "age is too large" - -JohnDoe = Person { - "lastName": "Doe", - "age": 1000 # Schema中的check条件为: age < 140 -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /check_block/check_block_fail_1/main.k:7:11 - | -7 | JohnDoe = Person { - | ^ Instance check failed - | - - --> /check_block/check_block_fail_1/main.k:5:1 - | -5 | age < 140, "age is too large" - | Check failed on the condition - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 Schema 的属性与 check 中的条件是否符合 - -### 1.3.8 CannotAddMembersRuntimeError [E3B19] - -如果在运行 KCL 时遇到错误: - -- `CannotAddMembersRuntimeError`, 对应的 encode 为 `E3B19` - -那么此时 KCL 程序中出现了 - -- 访问 Schema 中不存在的成员 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Name: - name: str - -schema Person: - name: Name - -person = Person { - name.err_name: "Alice" # err_name is not found in schema Name -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /nest_var/nest_var_fail_1/main.k:8:5 - | -8 | name.err_name: "Alice" # err_name is not found in schema Name - | ^ Cannot add member 'err_name' to schema 'Name' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 为 Schema 添加不存在的成员。 -- 访问 Schema 中存在的成员。 - -### 1.3.9 EvaluationError [E3M38] - -如果在运行 KCL 时遇到错误: - -- `EvaluationError`, 对应的 encode 为 `E3M38` - -那么此时 KCL 程序中出现了 - -- 当 KCL 中数值计算过程出现了错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -_list1 = [1, 2, 3] # _list1 is a variable, and its type can only be known at runtime -_list2 = None # _list1 is a variable, and its type can only be known at runtime - -result2 = _list1 + _list2 # list + NoneType is illegal -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /datatype/list/add_None_fail/main.k:1 - | -4 | result2 = _list1 + _list2 # list + NoneType is illegal - | can only concatenate list (not "NoneType") to list - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查表达式中是否存在变量为 None,或者非法的计算过程。 - -### 1.3.10 InvalidFormatSpec [E3M39] - -如果在运行 KCL 时遇到错误: - -- `InvalidFormatSpec`, 对应的 encode 为 `E3M39` - -那么此时 KCL 程序中出现了 - -- 非法的字符串格式 - -可能出现错误的 KCL 程序片段如下: - -```python -a = 1 -b = 1 -data = "${a: #js}" + " $$ " # KCL插值字符串中,#js是非法的 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /datatype/str_interpolation/invalid_format_spec_fail_0/main.k:3 - | -3 | data = "${a: #js}" + " $$ " # #js is illegal string - | ^ #js is a invalid format spec - | -``` - -可以尝试以下步骤来修复这个错误: - -- 将非法 String 调整为 KCL 标准支持的 String。 - -### 1.3.11 KCLAssertionError [E3M40] - -如果在运行 KCL 时遇到错误: - -- `KCLAssertionError`, 对应的 encode 为 `E3M40` - -那么此时 KCL 程序中出现了 - -- Assert False - -可能出现错误的 KCL 程序片段如下: - -```python -assert False -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /assert/invalid/fail_0/main.k:1 - | -1 | assert False - | - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 Assert 的条件,Assert 条件为 False 时,就会出现此类错误,去掉 Assert 语句或改变条件为 True。 - -### 1.3.12 ImmutableRuntimeError [E3M44] - -如果在运行 KCL 时遇到错误: - -- `ImmutableRuntimeError`, 对应的 encode 为 `E3M44` - -那么此时 KCL 程序中出现了 - -- 不可变量的值发生改变 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - final firstName : str - lastName : str - - -schema Scholar(Person): - firstName = "CBA" - - -scholar = Scholar { - "firstName": "ABC" # firstName in schema Person is final. -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /final/fail_lazy_init_0/main.k:8:1 - | -8 | scholar = Scholar { - | attribute 'lastName' of Scholar is required and can't be None or Undefined - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 final 修饰的不可变量是否出现了赋值等改变值的操作。 - -### 1.3.13 CycleInheritError [E2D33] - -如果在运行 KCL 时遇到错误: - -- `CycleInheritError`, 对应的 encode 为 `E2D33` - -那么此时 KCL 程序中出现了 - -- 循环继承 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Parent(Son): - parent_field: str - -schema Son(GrandSon): - son_field: str - -schema GrandSon(Parent): - grandson_field: str - -parent = Parent { - parent_field: "" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /inherit/cycle_inherit_fail_1/main.k:7:8 - | -7 | schema GrandSon(Parent): - | ^ There is a circular reference between schema GrandSon and Parent - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 Schema 的继承关系,避免出现 A 继承 B,B 继承 A 的情况。 - -### 1.3.14 KCLRecursionError [E3M42] - -如果在运行 KCL 时遇到错误: - -- `KCLRecursionError`, 对应的 encode 为 `E3M42` - -那么此时 KCL 程序中出现了 - -- 循环引用 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Parent(Son): - parent_field: str - son: Son = Son { # Parent has attribute Son - parent: Parent { - parent_field: "123" - } - } - -schema Son: - son_field: str - parent: Parent = Parent { # Son has attribute Parent - son: Son { - son_field: "123" - } - } - -parent = Parent { - parent_field: "", -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -thread 'main' has overflowed its stack -fatal runtime error: stack overflow -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 Schema 中的属性成员,避免出现循环引用的问题。 - -## 1.4 KCL 编译警告 (W2xxx) - -KCL 中的编译警告如下表所示: - -| ewcode | KCL exception | messages | -| ------ | ------------------------------------------------- | ------------------ | -| W2K04 | [FloatUnderflow](#141-floatunderflow-w2k08) | Float underflow | -| W2P10 | [InvalidDocstring](#142-invaliddocstring-w2p10) | Invalid docstring | -| W2N12 | [DeprecatedWarning](#143-deprecatedwarning-w2n12) | Deprecated warning | - -### 1.4.1 FloatUnderflow [W2K08] - -如果在运行 KCL 时遇到错误: - -- `FloatUnderflow`, 对应的 encode 为 `W2K08` - -可以尝试以下步骤来修复这个错误: - -- 检查浮点数的值是否在 KCL 支持的数字范围内。 - -### 1.4.2 InvalidDocstring [W2P10] - -如果在运行 KCL 时遇到错误: - -- `InvalidDocstring`, 对应的 encode 为 `W2P10` - -那么此时 KCL 程序中出现了 - -- 无效的 doc 内容 - -可以尝试以下步骤来修复这个错误: - -- 请按照 KCL 标准编写 doc。 - -### 1.4.3 DeprecatedWarning [W2N12] - -如果在运行 KCL 时遇到错误: - -- `DeprecatedWarning`, 对应的 encode 为 `W2N12` - -那么此时 KCL 程序中出现了 - -- 过时的代码警告 - -可以尝试以下步骤来修复这个错误: - -- 尽量不要使用已经过时的代码。如果将 strict 设置为 True,KCL 将会输出错误,并停止运行。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/tour.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/tour.md deleted file mode 100644 index 93a080e5..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/tour.md +++ /dev/null @@ -1,3208 +0,0 @@ ---- -title: "KCL 之旅" -sidebar_position: 1 ---- - -本文展示了如何使用 KCL 的核心特性,包含变量、运算符、schema 和库,前提是您有使用其他语言编程的经验。KCL 主要受 Python 启发,了解 Python 对学习 KCL 非常有帮助。 - -### 重要概念 - -在学习 KCL 语言时,请牢记以下事实和概念: - -- KCL 是一种配置策略语言。它为编写配置和策略提供了简单且自洽的语言设计和库支持。它不能用于应用程序开发或其他通用编程语言(GPL)支持的场景。 -- KCL 吸收了经典 **OOP** 的元素,并且提供了**类型**、**复用**和**合并**等简单、开发人员友好、可靠且利于传播的配置编写实践。 -- KCL 更倾向于**不可变性**,建议使用**合并**来添加增量的变更。不可变性降低了副作用,例如不可预测的问题。 -- KCL 的 **schema** 结构体定义了严格的属性和静态类型,并且支持表达式验证。**schema** 结构体主要由带类型的属性、schema 上下文和检查块构成。 -- KCL 的 **config** 是一个类 **JSON** 表达式,通过它我们可以复用 schema 的完整定义。KCL 通过分离 schema 和 config 来提供定义和配置的能力。 -- KCL 的 **rule** 是一个书写规则约束表达式的结构,可用于数据校验和策略编写。 -- KCL 的代码文件以包(目录)和模块(文件)的形式进行管理。同一包中的 schema 彼此可见;跨包的数据需要通过 **import 语句**导入。包级变量虽然可以导出,但是它们不能被其他包修改。 -- KCL 语法定义主要使用声明式表达式,并且只提供少量必要的声明式语句,例如 import、 if...else、assert、assignment 以及 schema。 -- 没有主函数,每个 `.k` 文件可以作为单独的配置文件执行。 -- 支持**内置函数**和**插件**以简化编写。 - -### 关键字 - -下表列出了 KCL 语言的关键字。 - -```txt -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -### 标识符 - -在 KCL 中, 标识符是标识一个值的名称,可以带有选择器。 - -- 标识符由字母、数字、下划线或前缀 `$` 组成。 -- 标识符不能与关键字重复,除非它们有 `$` 前缀。 -- 标识符不得包含任何嵌入的空格或符号。 -- 可以在标识符中的任何位置使用字母和下划线。 -- 数字不能放在标识符的第一位。 -- `$` 字符只能放在标识符的第一个位置。 - -示例: - -```python -x -a -b1 -b_2 -_c -$if -``` - -为了简化限定标识符(例如 `pkg.type`)的定义,我们还定义了 `qualified identifier`: - -示例: - -```python -pkg.a -``` - -在 `qualified identifier` 中的包名必须通过 `import` 关键字导入。 - -#### 标识符前缀 - -使用 `$` 前缀符号定义关键字标识符。 - -```python -$if = 1 -$else = "s" -``` - -请注意,非关键字标识符是否有 `$` 符号都是同样的效果。 - -```python -_a = 1 -$_a = 2 # equal to `_a = 2` -``` - -### 变量 - -以下是如何创建并实例化变量的例子: - -```python -name = "Foo" # Declare a variable named `name` and its value is a string literal "Foo" -``` - -它对应了如下 YAML 输出: - -```yaml -name: Foo -``` - -在 KCL 中,我们可以通过定义包级变量将变量导出为配置数据。使其直接、清晰、可维护。导出的变量是不可变的。因此一旦声明它,就无法对其进行修改,例如,假设我们有一个名为 `example.k` 的配置文件,变量 `name` 在声明后就禁止修改,就像标准的命令式语言一样。 - -```python -name = "Foo" # exported - -... - -name = "Bar" # error: a exported declaration variable can only be set once. -``` - -作为补充,我们可以在模块级别定义一个非导出变量,这个变量是可变的,不会显示在 YAML 输出当中。 - -```python -_name = "Foo" # _ variables are not output to YAML and are mutable -_name = "Bar" -``` - -请注意,变量的名称不能为 `True`、`False`、`None` 或者 `Undefined`,因为它们与 KCL 内置的名称常量之间存在二义性。 - -```python -False = 1 # Error -True = False # Error -None = Undefined # Error -Undefined = None # Error -``` - -### 内置类型 - -KCL 支持以下类型: - -- 数字 -- 字符串 -- 布尔 -- 列表 -- 字典 - -#### 数字 - -KCL 的数字类型有两种形式: - -- 64 位有符号整数。值的范围为 -9223372036854775808~9223372036854775807. -- 64 位浮点数,遵循 IEEE 754 标准。我们不建议在配置中使用 float 类型,我们可以使用字符串代替并在运行时进行解析。 - -整数和浮点数都支持基本运算符,例如 `+`,`-`,`/` 和 `*`,而复杂的运算,例如 `abs()`, `ceil()` 和 `floor()`,都是通过内置的数学库来支持。 - -整数是不带小数点的数字。以下是一些定义整数的例子: - -```python -a = 1 -b = -1 -c = 0x10 # hexadecimal literal -d = 0o10 # octal literal -e = 010 # octal literal -f = 0b10 # binary literal -g = int("10") # int constructor -``` - -如果一个数字包含小数点,则它是浮点数。以下是一些浮点数的示例: - -```python -a = 1.10 -b = 1.0 -c = -35.59 -d = 32.3e+18 -f = -90. -h = 70.2E-12 -i = float("112") # float constructor -``` - -内置数学库可用于数字类型: - -```python -import math - -assert abs(-40) == 40 -assert round(70.23456) == 70 -assert min(80, 100, 1000) == 80 -assert max(80, 100, 1000) == 1000 -assert sum([0,1,2]) == 3 -assert math.ceil(100.12) == 101.0 -assert math.floor(100.12) == 100.0 -assert math.pow(100, 2) == 10000.0 -``` - -KCL 默认使用 64 位数字类型。我们可以在 KCL 命令行使用 `-r` 参数执行严格的 32 位范围检查。 - -```bash -kcl main.k -r -d -``` - -请注意,为了性能考虑该功能只能在 `debug` 模式中使用。 - -##### 单位字面值 - -在 KCL 中,我们可以给一个整数添加如下的单位后缀,这不影响它的真实值。 - -- 通用整形和定点数: `P`, `T`, `G`, `M`, `K`, `k`, `m`, `u`, `n` -- 2 的幂: `Pi`, `Ti`, `Gi`, `Mi`, `Ki` - -```python -# SI -n = 1n # 1e-09 -u = 1u # 1e-06 -m = 1m # 1e-03 -k = 1k # 1000 -K = 1K # 1000 -M = 1M # 1000000 -G = 1G # 1000000000 -T = 1T # 100000000000 -P = 1P # 1000000000000000 -# IEC -Ki = 1Ki # 1024 -Mi = 1Mi # 1024 ** 2 -Gi = 1Gi # 1024 ** 3 -Ti = 1Ti # 1024 ** 4 -Pi = 1Pi # 1024 ** 5 -``` - -此外,我们还可以使用定义在 `units` 模块中的单位常量: - -```python -import units - -n = 1 * units.n # 1e-09 -u = 1 * units.u # 1e-06 -m = 1 * units.m # 1e-03 -k = 1 * units.k # 1000 -K = 1 * units.K # 1000 -M = 1 * units.M # 1000000 -G = 1 * units.G # 1000000000 -T = 1 * units.T # 1000000000000 -P = 1 * units.P # 1000000000000000 -# IEC -Ki = 1 * units.Ki # 1024 -Mi = 1 * units.Mi # 1024 ** 2 -Gi = 1 * units.Gi # 1024 ** 3 -Ti = 1 * units.Ti # 1024 ** 4 -Pi = 1 * units.Pi # 1024 ** 5 -``` - -我们还可以使用定义在 `units` 模块内的整数和单位字符串之间的转换函数 - -```python -import units -# SI -K = units.to_K(1000) # "1K" -M = units.to_M(1000000) # "1M" -G = units.to_G(1000000000) # "1G" -T = units.to_T(1000000000000) # "1T" -P = units.to_P(1000000000000000) # "1P" -# IEC -Ki = units.to_Ki(1024) # "1Ki" -Mi = units.to_Mi(1024 ** 2) # "1Mi" -Gi = units.to_Gi(1024 ** 3) # "1Gi" -Ti = units.to_Ti(1024 ** 4) # "1Ti" -Pi = units.to_Pi(1024 ** 5) # "1Pi" -``` - -```python -import units -# SI -K = units.to_K(int("1M")) # "1000K" -M = units.to_M(int("1G")) # "1000M" -G = units.to_G(int("1T")) # "1000G" -T = units.to_T(int("1P")) # "1000T" -P = units.to_P(int("10P")) # "10P" -# IEC -Ki = units.to_Ki(int("1Mi")) # "1024Ki" -Mi = units.to_Mi(int("1Gi")) # "1024Mi" -Gi = units.to_Gi(int("1Ti")) # "1024Gi" -Ti = units.to_Ti(int("1Pi")) # "1024Ti" -Pi = units.to_Pi(int("10Pi")) # "10Pi" -``` - -单位类型定义在 `units` 模块中,单位类型的值不能进行任何四则运算。 - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -x0: NumberMultiplier = 1M # Ok -x1: NumberMultiplier = x0 # Ok -x2 = x0 + x1 # Error: unsupported operand type(s) for +: 'number_multiplier(1M)' and 'number_multiplier(1M)' -``` - -我们可以使用 `int()`、`float()` 和 `str()` 函数将数值单位类型转换为数字类型或字符串类型。 - -```python -a: int = int(1Ki) # 1024 -b: float = float(1Ki) # 1024.0 -c: str = str(1Mi) # "1Mi" -``` - -#### 字符串 - -字符串是一个不可变的 Unicode 字符序列。我们可以使用单引号或双引号创建字符串: - -```python -'allows embedded "double" quotes' # Single quotes -"allows embedded 'single' quotes" # Double quotes -'''Three single quotes''', """Three double quotes""" # Triple quoted -``` - -三引号用于定义多行字符串。 - -```python -"""This is a long triple quoted string -may span multiple lines. -""" -``` - -请注意,KCL 的单引号和双引号字符串的使用几乎没有区别。唯一可以简化的是,我们不需要在单引号字符串中转义双引号,也不需要在双引号中转义单引号。 - -```python -'This is my book named "foo"' # Don’t need to escape double quotes in single quoted strings. -"This is my book named 'foo'" # Don’t need to escape single quotes in double quoted strings. -``` - -我们可以使用 `+` 操作符连接字符串: - -```python -x = 'The + operator ' + 'works, as well.' -``` - -我们可以使用 `str` 内置函数将 int 或 float 转为字符串: - -```python -x = str(3.5) # "3.5" -``` - -可以使用很多内置的字符串函数: - -```python -x = "length" -assert len(x) == 6 # True -assert x.capitalize() == "Length" -assert x.count("gt") == 1 -assert x.endswith("th") == True -assert x.find("gth") == 3 -assert "{} {}".format("hello", "world") == 'hello world' -assert x.index("gth") == 3 -assert x.isalnum() == True -assert x.isalpha() == True -assert "123456".isdigit() == True -assert x.islower() == True -assert " ".isspace() == True -assert "This Is Title Example".istitle() == True -assert x.isupper() == False -assert "|".join(["a", "b", "c"]) == "a|b|c" -assert "LENGTH".lower() == "length" -assert ' spacious '.lstrip() == 'spacious ' -assert x.replace("th", "ht") == "lenght" -assert "lengthlength".rfind("le") == 6 -assert "lengthlength".rindex("le") == 6 -assert "length length".rsplit() == ["length", "length"] -assert "length ".rstrip() == "length" -assert "length length".split() == ["length", "length"] -assert 'ab c\n\nde fg\rkl\r\n'.splitlines() == ['ab c', '', 'de fg', 'kl'] -assert "length".startswith('len') == True -assert "***length***".strip('*') == "length" -assert "length length".title() == "Length Length" -assert x.upper() == "LENGTH" -``` - -格式化字符串有两种使用方法: 使用 `"{}".format()` 内置函数, 或者使用花括号指定变量并使用 `$` 标记取变量值。在 KCL 中叫做**插值字符串**。在下面的例子中,`a` 和 `b` 的值都是 `"hello world"`。 - -此外,要序列化的变量可以以特殊的数据格式提取,例如 YAML 或 JSON。在这种情况中,`#yaml` 或 `#json` 可以包含在花括号中。 - -具体来说,当 `$` 符号本身需要出现在**插值字符串**中,需要使用 `$$` 转义。或者使用 `+` 符号连接 `$` 符号和插值字符串来避免转义。在以下示例中,`c` 和 `c2` 的值都是 `$hello world$`。 - -```python -world = "world" -a = "hello {}".format(world) # "hello world" -b = "hello ${world}" # "hello world" -c = "$$hello ${world}$$" # "$hello world$" -c2 = "$" + "hello ${world}" + "$" # "$hello world$" - -myDict = { - "key1" = "value1" - "key2" = "value2" -} - -d = "here is myDict in json: ${myDict: #json}" -# d: 'here is myDict in json: {"key1": "value1", "key2": "value2"}' - -e = "here is myDict in yaml:\n${myDict: #yaml}" -# e: | -# here is myDict in yaml: -# key1: value1 -# key2: value2 -``` - -此外,我们可以在上面的示例代码输出 **YAML 字符串** 中看到一些符号,例如 `|`、`>`、`+`、`-`。 - -- `|` 表示 **块文字样式**,指示块内换行符的行为方式。 -- `>` 表示块标量中的**块折叠样式**,换行符将被空格替换。 -- `+` 和 `-` 是 **block chomping 指示符**,用于控制字符串末尾的换行符。 默认值 **clip** 在字符串的末尾放置一个换行符。 要删除所有换行符,请通过在样式指示符 `|` 或 `>` 后面添加 `-` 来**删除**它们。 clip 和 strip 都忽略块末尾实际有多少换行符; 在样式指示符后面添加一个 `+` 来**保留**它们。 - -例如,**strip 块文字样式** yaml 字符串是 - -```yaml -example: |- - Several lines of text, - with some "quotes" of various 'types', - and also a blank line: - - plus another line at the end. -``` - -结果为: - -```plain -Several lines of text, -with some "quotes" of various 'types', -and also a blank line: - -plus another line at the end. -``` - -更多信息可见 [Yaml Multiline String](https://yaml-multiline.info/) 和 [YAML Specification v1.2](https://yaml.org/spec/1.2.1/) 。 - -##### 原始字符串 - -KCL 原始字符串是通过在字符串字面值前加上 `'r'` 或 `'R'` 来创建的。 KCL 原始字符串将反斜杠 (`\`) 和字符串插值 (`${}`) 视为普通的非字符。当我们想要一个包含反斜杠、字符串插值的字符串并且不希望它们被视为转义字符时,原始字符串是很有用的。 - -- 对于包含反斜杠(`\`)的原始字符串,KCL 代码和输出 YAML 如下: - -```python -s = "Hi\nHello" -raw_s = r"Hi\nHello" # This is a KCL raw string with the `r` prefix. -``` - -```yaml -s: |- - Hi - Hello -raw_s: Hi\nHello -``` - -- 对于包含字符串插值(`${}`)的原始字符串,KCL 代码和输出 YAML 如下: - -```python -worldString = "world" -s = "Hello ${worldString}" -raw_s = r"Hello ${worldString}" # This is a KCL raw string with the `r` prefix. -``` - -```yaml -worldString: world -s: Hello world -raw_s: Hello ${worldString} -``` - -此外,原始字符串最常用的场景是在正则表达式中使用: - -```python -import regex - -key = "key" -result = regex.match(key, r"[A-Za-z0-9_.-]*") # True -``` - -#### 布尔值 - -布尔值有两个常量对象:`False` 和 `True`. - -```python -a = True -b = False -``` - -#### List - -List 是一个序列,通常用于存储同质项的集合。下面是一个简单的 KCL 列表的例子: - -```python -list = [1, 2, 3] -assert len(list) == 3 # True -assert list[0] == 1 # True -``` - -我们可以使用列表推导式构建列表: - -```python -list = [ _x for _x in range(20) if _x % 2 == 0] -assert list == [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] # True -``` - -并且还可以使用嵌套的列表推导式: - -```python -matrix = [[1, 2], [3,4], [5,6], [7,8]] -transpose = [[row[_i] for row in matrix] for _i in range(2)] -assert transpose == [[1, 3, 5, 7], [2, 4, 6, 8]] # True -``` - -此外,我们可以在列表推导式中使用两个变量。第一个变量表示列表中的索引,第二个变量表示列表中的项。 - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use `_` to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -我们可以通过 `+` 连接列表: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -joined_list = _list0 + _list1 # [1, 2, 3, 4, 5, 6] -``` - -我们可以使用解包操作符 `*` 合并多个列表: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -union_list = [*_list0, *_list1] # [1, 2, 3, 4, 5, 6] -``` - -我们可以使用 `if` 表达式动态的将元素添加到列表,符合条件的元素会被添加到列表,不符合条件的元素会被忽略。 - -```python -a = 1 # 1 -data = [ - 1 - if a == 1: 2 - if a > 0: 3 - if a < 0: 4 -] # [1, 2, 3] -``` - -```python -a = 1 # 1 -data1 = [ - 1 - if a == 1: - 2 - elif a == 2: - 3 - else: - 3 -] # [1, 2] -data2 = [ - 1 - if a == 1: 2 - elif a == 2: 2 - else: 3 -] # [1, 2] -``` - -我们可以合并(union)列表: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -union_list = _list0 | _list1 # [4, 5, 6] -``` - -我们可以使用 `for k in list_var` 表达式遍历列表: - -```python -data = [1, 2, 3] -dataAnother = [val * 2 for val in data] # [2, 4, 6] -``` - -#### Dict - -Dict 是将可哈希的值映射到任意对象的映射对象。字典是有序的。键的顺序遵循其声明的顺序: - -这里有几个简单的 KCL 字典: - -```python -a = {"one" = 1, "two" = 2, "three" = 3} -b = {'one' = 1, 'two' = 2, 'three' = 3} -assert a == b # True -assert len(a) == 3 # True -``` - -在写多行的键-值时,可以省略每个键-值对行尾的逗号 `,`: - -```python -data = { - "key1" = "value1" # Ignore the comma ',' at the end of line - "key2" = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -在 Dict 键上使用简单的字面值时可以省略引号: - -```python -data = { - key1 = "value1" # Ignore key quotation '"' - key2 = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -此外,**选择表达式**可以用于定义包含嵌套键 dict 实例。 - -```python -person = { - base.count = 2 - base.value = "value" - labels.key = "value" -} # {"base": {"count": 2, "value": "value"}, "labels": {"key": "value"}} -``` - -输出 YAML 为: - -```yaml -person: - base: - count: 2 - value: value - labels: - key: value -``` - -在 KCL 中,dict 中的不同的字段可以直接引用,比如如下的例子 - -```python -config = { - name = "me" - metadata.name = name # Reference `name` with the value `"me"` in `config` directly. -} -``` - -输出 YAML 为: - -```yaml -config: - name: me - metadata: - name: me -``` - -我们可以使用字典推导式构建字典: - -```python -x = {str(i): 2 * i for i in range(3)} -assert x == {"0" = 0, "1" = 2, "2" = 4} -``` - -此外,我们可以在字典推导式中使用两个变量。第一个变量表示字典的键,第二个变量表示字典中键对应的值。 - -```python -data = {key1 = "value1", key2 = "value2"} -# Single variable loop -dataKeys1 = {k: k for k in data} # {"key1": "key1", "key2": "key2"} -dataValues1 = {k: data[k] for k in data} # {"key1": "value1", "key2": "value2"} -# Double variable loop -dataKeys2 = {k: k for k, v in data} # {"key1": "key1", "key2": "key2"} -dataValues2 = {v: v for k, v in data} # {"value1": "value1", "value2": "value2"} -dataFilter = {k: v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use `_` to ignore loop variables -dataKeys3 = {k: k for k, _ in data} # {"key1": "key1", "key2": "key2"} -dataValues3 = {v: v for _, v in data} # {"value1": "value1", "value2": "value2"} -``` - -我们可以使用解包操作符 `**` 来合并字典: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = {**_part1, **_part2} # {"a: "b", "c": "d"} -``` - -此外,union 操作符 `|` 也能达到同样的效果: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = _part1 | _part2 # {"a: "b", "c": "d"} -``` - -我们可以使用 `if` 表达式动态的将元素添加到字典,符合条件的元素会被添加到字典,不符合条件的元素会被忽略。 - -```python -a = 1 # 1 -data = { - key1 = "value1" - if a == 1: key2 = "value2" - if a > 0: key3 = "value3" - if a < 0: key4 = "value4" -} # {"key1": "value1", "key2": "value2", "key3": "value3"} -``` - -```python -a = 1 # 1 -data1 = { - key1 = "value1" - if a == 1: - key2 = "value2" - elif a > 0: - key3 = "value3" - else: - key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -data2 = { - key1 = "value1" - if a == 1: key2 = "value2" - elif a > 0: key3 = "value3" - else: key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -``` - -我们可以使用 `for k in dict_var` 表达式来遍历字典, 并且可以使用 `in` 操作符来判断 dict 是否包含某个键。 - -```python -data = {key1 = "value1", key2 = "value2"} -dataAnother = {k: data[k] + "suffix" for k in data} # {"key1": "value1suffix", "key2": "value2suffix"} -containsKey1 = "key1" in data # True -containsKey2 = "key" in data # False -``` - -#### None - -在 KCL 中, `None` 表示对象的值为空, 这与 Go 中的 `nil` 和 Java 中的 `null` 一样,并且对应于 YAML 中的 `null`。 - -```python -a = None -b = [1, 2, None] -c = {key1 = "value1", key2 = None} -``` - -输出如下: - -```yaml -a: null -b: - - 1 - - 2 - - null -c: - key1: value1 - key2: null -``` - -请注意,`None` 不能参与四则运算,但它可以参与逻辑运算和比较运算。 - -```python -a = 1 + None # error -b = int(None) # error -c = not None # True -d = None == None # True -e = None or 1 # 1 -f = str(None) # None -``` - -#### Undefined - -`Undefined` 与 `None` 类似,但其语义是变量没有分配任何值,也不会输出到 YAML。 - -```python -a = Undefined -b = [1, 2, Undefined] -c = {key1 = "value1", key2 = Undefined} -``` - -输出如下: - -```yaml -b: - - 1 - - 2 -c: - key1: value1 -``` - -请注意,`Undefined` 不能参与四则运算,但它可以参与逻辑运算和比较运算。 - -```python -a = 1 + Undefined # error -b = int(Undefined) # error -c = not Undefined # True -d = Undefined == Undefined # True -e = Undefined or 1 # 1 -f = str(Undefined) # Undefined -``` - -### 运算符 - -以下字符表示运算符: - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != @ \ -``` - -#### 算数运算符 - -KCL 支持常见的算数运算符: - -```python -assert 2 + 3 == 5 -assert 2 - 3 == -1 -assert 2 * 3 == 6 -assert 5 / 2 == 2.5 -assert 5 // 2 == 2 -assert 5 % 2 == 1 -``` - -#### 相等和关系运算符 - -KCL 支持相等和关系运算符: - -```python -assert 2 == 2 -assert 2 != 3 -assert 3 > 2 -assert 2 < 3 -assert 3 >= 3 -assert 2 <= 3 -``` - -#### 逻辑运算符 - -我们可以使用逻辑运算符反转或组合布尔表达式,例如:`and` 和 `or`: - -```python -if not done and (col == 0 or col == 3): - # ...Do something... - -``` - -#### 位运算符和移位运算符 - -以下是位运算符和移位运算符的例子: - -```python -value = 0x22 -bitmask = 0x0f - -assert (value & bitmask) == 0x02 -assert (value & ~bitmask) == 0x20 -assert (value | bitmask) == 0x2f -assert (value ^ bitmask) == 0x2d -assert (value << 4) == 0x220 -assert (value >> 4) == 0x02 -``` - -`|` 运算符可用于位运算,合并基本类型和集合及结构化数据,例如**列表**、**字典**和 **schema**。 - -位运算示例: - -```python -0x12345678 | 0xFF # 0x123456FF -``` - -联合基本类型示例: - -```python -schema x: - a: int | str # attribute a could be a int or string -``` - -#### 赋值运算符 - -以下 token 作为语法中的分隔符: - -```txt - ( ) [ ] { } - , : . ; = -> - += -= *= /= //= %= - &= ^= >>= <<= **= -``` - -以下是使用赋值和参数赋值赋值运算符的例子: - -```python -_a = 2 -_a *= 3 -_a += 1 -assert _a == 7 -``` - -#### Identity 运算符 - -以下关键字作为语法中的 identity 运算符: - -```python -is, is not -``` - -Identity 运算符检查右侧和左侧是否时同一对象。它们通常用于检查某个变量是否是 `None/Undefined/True/False`。以下是一些例子: - -```python -empty_String = "" -empty_String is not None # True -``` - -#### 成员运算符 - -以下关键字作为语法中的成员运算符: - -```python -in, not in -``` - -- `in` 运算符计算了第一个操作数是否是第二个操作数的成员,第二个运算符必须是 list、dict、schema 或 string。 -- `not in` 运算符与 `in` 相反。它们都返回一个布尔值。 - -成员的含义因第二个操作数的类型而异:列表的成员是其元素;字典的成员是其键;字符串的成员是其所有子字符串。 - -```python -1 in [1, 2, 3] # True - -d = {one = 1, two = 2} -"one" in d # True -"three" in d # False -1 in d # False -[] in d # False - -"nasty" in "dynasty" # True -"a" in "banana" # True -"f" not in "way" # True - -d = Data {one = 1, two = 2} # Data is a schema with attributes one and two -"one" in d # True -"three" in d # False -``` - -#### 推导式 - -一个推导表达式通过遍历一个或多个迭代项并计算表达式生成的结果来生成连续的元素,并以此构造新的列表或字典。 - -我们可以如下使用列表和字典的推导表达式: - -```python -listVar = [_x for _x in range(20) if _x % 2 == 0] # list comprehension -dictVar = {str(_i): 2*_i for _i in range(3)} # dict comprehension -``` - -#### 其他运算符 - -- 使用 **()** 表示函数调用, 例如 `"{} {}".format("hello", world)`。 -- 使用 **[]** 引用列表中指定索引处的值。 -- 使用 **:** 定义类型注解。 -- 使用 **.** 引用成员字段。 -- 使用 **\\** 续行符编写长表达式。 - -```python -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " -``` - -### 表达式 - -#### 条件表达式 - -条件表达式的形式为 `a if cond else b`。它首先计算条件 `cond`。如果为真,则会计算 `a` 并生成它的值;否则,它会生成 `b` 的值。 - -示例: - -```python -x = True if enabled else False # If enabled is True, x is True, otherwise x is False -``` - -#### 索引表达式 - -索引表达式 `a[i]` 生成可索引类型的第 `i` 个元素,例如字符串或数组。索引 `i` 必须是 `-n` ≤ `i` < `n` 范围内的 `int` 值,其中 `n` 等于 `len(a)`。其他任何索引都会导致错误。 - -有效的负索引的行为类似于 `n+i`,允许方便的对序列末尾进行索引。 - -```python -val = "abc" -list = ["zero", "one", "two"] -str_0 = val[0] # "a" -str_1 = val[1] # "b" -str_n1 = val[-1] # "c" - -list_0 = list[0] # "zero" -list_1 = list[1] # "one" -list_n1 = list[-1] # "two" -``` - -索引表达式 `d[key]` 也可以用于字典 `d`,以获取指定键对应的值。如果字典中不包含这个键则会返回 `Undefined` - -出现在赋值符左侧的索引表达式会更新指定的列表或字典元素。 - -```python -d = {key1 = "value1", key2 = "value2"} -key1value = d["key1"] # value1 -key2value = d["key2"] # value2 -``` - -尝试更新不可变类型的元素值(如列表或字符串)或可变类型的不可变变量会产生错误。 - -#### 切片表达式 - -切片表达式 `a[start:stop:step]` 会生成 `a` 包含的一个子序列,其中 `a` 必须是字符串或者数组。 - -`start`、`stop` 和 `step` 三个操作数都是可选的。如果有的话,每个值都必须为整数。`step` 的默认值为 1。如果 `step` 未指定,它前面的冒号也可以省略。指定 `step` 为 0 会产生错误。 - -从概念上来说,这些操作数指定了一系列值,索引 `i` 从 `start` 开始,每次增加 `step` 直到 `i` 到达或超过 `stop`。结果由有效的 `i` 的 `a[i]` 组成。 - -如下所示,从三个操作数计算有效的开始和结束的索引。`n` 是序列的长度。 - -```python -val = "abc" -len = len(val) -a = val[1:len] # "bc" (remove first element) -b = val[0:-1] # "ab" (remove last element) -c = val[1:-1] # "b" (remove first and last element) -``` - -```python -"abc"[1:] # "bc" (remove first element) -"abc"[:-1] # "ab" (remove last element) -"abc"[1:-1] # "b" (remove first and last element) -"banana"[1::2] # "aaa" (select alternate elements starting at index 1) -"banana"[4::-2] # "nnb" (select alternate elements in reverse, starting at index 4) -``` - -KCL 禁止将切片表达式定义为左值。原因是列表和字符串是不可变的,重新切片可以直接操作操作数,以确保更好的性能。 - -#### 函数调用 - -KCL 允许调用内置函数,或者调用内置和系统模块中的函数。 - -调用函数的基本方法如下所示: - -```python -import math - -a = math.pow(2, 3) # 2 powers 3 is 8. -b = len([1, 2, 3]) # the length of [1, 2, 3] is 3 -``` - -参数以 `,` 分隔,并且 KCL 还支持位置参数和键-值对形式的参数。 - -```python -print("hello world", end="") -``` - -请注意: - -- 有些函数参数具有默认值。 -- 一些函数接受可变参数。 - -如果没有为没有默认值的参数提供参数,则会抛出错误。 - -#### 选择表达式 - -选择表达式选择值的属性或方法。KCL 提供了许多识别或过滤属性的方法: - -`x.y` - -- dict: 表示字典 `x` 中键 `y` 对应的值。 -- schema: 表示 schema `x` 中 `y` 属性的值。 -- package: 表示 package `x` 中 `y` 标示的标识符。 - -示例: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -name = person.name # "Alice" -age = person.age # 18 - -myDict = { - key = "value" -} -result = myDict.key # "value" -``` - -`x?.y` - -`x` 可以是 schema 实例或 dict。当 `x` 可能为 `None` 或者键 `y` 不在 `x` 中时这非常有用。 - -```python -# Example of dict: -data = {"key" = "value"} -a = data?.key # "value" -b = data?.name # Undefined - -# example of schema instance: -schema Company: - name: str - address: str - -schema Person: - name: str - job?: Company - -alice = Person { - name = "alice" -} - -if alice?.job?.name == "Group": - print("work in Group") -``` - -#### Quantifier 表达式 - -Quantifier 表达式用于集合:列表或字典。通常用于在处理集合后获得某个结果,主要有以下四种形式: - -- **all** - - 用于检测集合中所有元素都满足给定的逻辑表达式,并且返回一个布尔值作为结果。 - - 只有集合中所有元素都满足表达式为 true 时,`all` 表达式为 true,否则为 false。 - - 如果集合为空,返回 true。 - - 支持表达式执行期间逻辑表达式的短路。 -- **any** - - 用于检测集合中至少一个元素都满足给定的逻辑表达式,并且返回一个布尔值作为结果。 - - 当集合中至少一个元素都满足表达式为 true 时,`any` 表达式为 true,否则 false。 - - 如果集合为空,返回 false。 - - 支持表达式执行期间逻辑表达式的短路。 -- **map** - - 映射集合中的元素生成新的列表。 - - 新列表的长度严格等于原列表的长度。 -- **filter** - - 通过逻辑判断筛选原集合中的元素,返回一个经过筛选的子集合。 - - 当表达式为 true 时才将元素添加到子集合。 - - 产生的新集合的类型(list, dict 和 schema)与原集合的类型完全一致,并且长度为 `[0, len(original-collection)]`。 - -**all** 和 **any** 表达式的示例代码: - -```python -schema Config: - volumes: [{str:}] - services: [{str:}] - - check: - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - }, "invalid cluster ip" - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } -``` - -**map** 和 **filter** 表达式的示例代码: - -```python -a = map e in [{name = "1", value = 1}, {name = "2", value = 2}] { - {name = e.name, value = int(e.value) ** 2} -} # [{"name": "1", value: 1}, {"name": "2", "value": 4}] - -b = map k, v in {a = "foo", b = "bar"} { v } # ["foo", "bar"] - -c = filter e in [{name = "1", value = 1}, {name = "2", value = 2}] { - int(e.value) > 1 -} # [{"name": "2", "value": 2}] - -d = filter _, v in {a = "foo", b = "bar"} { - v == "foo" -} # {"a": "foo"} -``` - -请注意,区分 any 表达式和 any 类型的区别。当 `any` 在类型注解中使用,意味着变量的值是任意的,而 any 表达式意味着集合中的至少一个元素满足条件。 - -### 流程控制表达式 - -#### If 和 Else - -KCL 支持 `if` 表达式和可选的 `elif` 和 `else` 表达式, 示例如下: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - print("maybe a is negative") -else: - print("a >= 100") -``` - -`elif` 的例子: - -```python -_result = 0 -if condition == "one": - _result = 1 -elif condition == "two": - _result = 2 -elif condition == "three": - _result = 3 -else: - _result = 4 -``` - -`if-elif-else` 表达式可以嵌套,示例如下: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - if a < 0: - print("a is negative") - print("No matter a is negative or positive, this message is printed") -else: - print("a >= 100") -``` - -此外,对于简单的 `if` 表达式如下: - -```python -if success: - _result = "success" -else: - _result = "failed" -``` - -我们可以使用 ` if else ` 的形式将它们写在一行: - -```python -_result = "success" if success else "failed" -``` - -`if` 或 `elif` 语句计算一个给定的表达式。当表达式的计算结果为 `True`, `:` 之后的语句将被计算,而当表达式为 `False` ,后面的语句不会被计算。 - -请注意,常量 `False`, `None`, 数字 `0`, 空列表 `[]`, 空字典 `{}` 和空字符串 `""` 都被视为 `False` 。 - -```python -_emptyStr = "" -_emptyList = [] -_emptyDict = {} -isEmptyStr = False if _emptyStr else True -isEmptyList = False if _emptyList else True -isEmptyDict = False if _emptyDict else True -``` - -结果为: - -```yaml -isEmptyStr: true -isEmptyList: true -isEmptyDict: true -``` - -### 断言语句 - -当发生错误时,开发人员应该能够检测到错误并终止执行。因此,KCL 引入了 `assert` 语法,示例如下: - -```python -a = 1 -b = 3 -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -``` - -此外,我们可以为 assert 语声明一个条件,当条件满足时,才进行 assert 断言 - -- 使用 if 语句书写条件断言 - -```python -a = None -if a: - assert a > 2: -``` - -- 使用 if 表达式书写条件断言 - -```python -a = None -assert a > 2 if a -``` - -### 函数 - -KCL 支持使用 lambda 关键字定义一个函数 - -```python -func = lambda x: int, y: int -> int { - x + y -} -a = func(1, 1) # 2 -``` - -lambda 函数具有如下特性: - -- lambda 函数将最后一个表达式的值作为函数的返回值,空函数体返回 None -- 返回值类型注解可以省略,返回值类型为最后一个表达式值的类型 -- 函数体中没有与顺序无关的特性,所有的表达式都是按顺序执行的 - -```python -_func = lambda x: int, y: int -> int { - x + y -} # Define a function using the lambda expression -_func = lambda x: int, y: int -> int { - x - y -} # Ok -_func = lambda x: int, y: int -> str { - str(x + y) -} # Error (int, int) -> str can't be assigned to (int, int) -> int -``` - -lambda 函数对象不能参与任何计算,只能在赋值语句和调用语句中使用。 - -```python -func = lambda x: int, y: int -> int { - x + y -} -x = func + 1 # Error: unsupported operand type(s) for +: 'function' and 'int(1)' -``` - -lambda 函数支持捕获其外部作用域的变量,并且可以作为其他函数的参数进行传递 - -```python -a = 1 -func = lambda x: int { - x + a -} -funcOther = lambda f, para: int { - f(para) -} -r0 = funcOther(func, 1) # 2 -r1 = funcOther(lambda x: int { - x + a -}, 1) # 2 -``` - -输出为: - -```yaml -a: 1 -r: 2 -``` - -此外,可以定义一个匿名函数并直接调用。 - -```python -result = (lambda x, y { - z = 2 * x - z + y -})(1, 1) # 3 -``` - -并且还可以在 for 循环使用使用匿名函数 - -```python -result = [(lambda x, y { - x + y -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 3, 3, 4] -``` - -请注意,KCL 中定义的函数的均为纯函数: - -- 函数的返回结果只依赖于它的参数。 -- 函数执行过程里面没有副作用。 - -因此,KCL 函数不能修改外部的变量,只能引用外部的变量,比如如下代码会发生错误: - -```python -globalVar = 1 -func = lambda { - x = globalVar # Ok - globalVar = 1 # Error -} -``` - -### 类型系统 - -#### 类型注解 - -类型注解可用于包级变量,schema 属性和参数。 - -- 属性可以是基本类型,例如字符串(`string`),浮点数(`float`),定点数(`int`) 或布尔值(`bool`)。 -- 属性可以是字面值类型,例如字符串文本(`"TCP"` 和 `"UDP"`),数字文本 (`"1"` 和 `"1.2"`),布尔值文本(`True` 和 `False`)。 -- 属性也可以是列表或字典: - - 未指定元素类型的列表为 `[]`。 - - 元素类型为 `t` 的列表为 `[t]`。这里 `t` 是另一种类型。 - - 键的类型为 `kt` 且值的类型为 `vt` 的字典为 `{kt:vt}`。 - - `kt`, `vt` 或两者都可以为空, 就像列表未指定元素类型一样。 -- 属性可以是由 `|` 定义的 **联合类型** ,例如 `a | b`, 意为类型可以是 a 或 b。 - - 联合类型可以包含 `int`, `str`, `float`, `bool`, `list`, `dict`, 字面值类型和 schema 类型,并且支持类型的嵌套,例如: `{str:str|int}`、`[[int|str]|str|float]` 和 `2 | 4 | 6` 等。 -- 属性可以是 schema 类型。在这种情况下,使用包名 + schema 名称作为类型名。 -- 属性可以声明为任意类型,例如 `any`。 - -示例 - -- 基本类型 - -```python -"""Top level variable type annotation""" -a: int = 1 # Declare a variable `a` that has the type `int` and the value `1` -b: str = "s" # Declare a variable `b` that has the type `str` and the value `"s"` -c: float = 1.0 # Declare a variable `c` that has the type `float` and the value `1.0` -d: bool = True # Declare a variable `d` that has the type `bool` and the value `True` -``` - -- List/Dict/Schema 类型 - -```python -schema Person: - name: str = "Alice" - age: int = 10 - -a: [int] = [1, 2, 3] # Declare a variable `a` that has the list type `[int]` and the value `[1, 2, 3]` -b: {str:str} = {k1 = "v1", k2 = "v2"} # Declare a variable `b` that has the dict type `{str:str}` and the value `{k1 = "v1", k2 = "v2"}` -c: Person = Person {} # Declare a variable `c` that has the schema type `Person` and the value `Person {}` -``` - -- 联合类型 - -```python -# Basic union types -schema x[argc: int]: # Schema argument type annotation - p: int | str # Schema attribute type annotation -``` - -```python -# Literal union types -schema LiteralType: - # String literal union types, x_01 can be one of "TCP" and "UDP" - x_01: "TCP" | "UDP" - # Number literal union types, x_02 can be one of 2, 4, and 6 - x_02: 2 | 4 | 6 - # Unit union types, x_03 can be one of 1Gi, 2Gi and 4Gi - x_03: 1Gi | 2Gi | 4Gi - -x = LiteralType { - x_01 = "TCP" - x_02 = 2 - x_03 = 1Gi -} -``` - -当属性的值不符合联合类型定义时,编译器会抛出错误: - -```python -# Literal union types -schema LiteralType: - # String literal union types, x_01 can be one of "TCP" and "UDP" - x_01: "TCP" | "UDP" - -x = LiteralType { - x_01 = "HTTP" # Error: the type got is inconsistent with the type expected, expect str(TCP)|str(UDP), got str(HTTP) -} -``` - -- Any 类型 - -```python -# Any type -schema Config: - literalConf: any = 1 - dictConf: {str:any} = {key = "value"} - listConf: [any] = [1, "2", True] - -config = Config {} -``` - -请注意,一般在配置编写中不提倡使用 `float` 和 `any` 类型,因为它们都存在一定的不稳定因素,比如精度丢失,无法进行静态类型检查等。 - -此外在 KCL 中,不允许修改一个变量的类型。如果在重新分配值时不满足类型,将引发类型错误。 - -```python -_a = 1 # The type of `_a` is `int` -_a = "s" # Error: expect int, got str(s) -``` - -变量可以赋值给其上界类型,但不能赋值给它的特化类型。 - -`None` 和 `Undefined` 可以赋值给任何类型: - -- 任何类型都可以赋值给 `any` 类型, `None` 和 `Undefined` 可以赋值给 `any` 类型。 - -```python -a: int = None -b: str = Undefined -c: any = 1 -d: any = "s" -e: any = None -``` - -- `int` 类型可以赋值给 `float` 类型, `float` 类型不能赋值给 `int` 类型. - -```python -a: float = 1 -b: int = 1.0 # Error: expect int, got float(1.0) -``` - -- `int` 类型可以赋值给 `int|str` 类型, `int|str` 不能赋值给 `int` 类型. - -```python -a: int | str = 1 -b: int = 1 if a else "s" # Error: expect int, got int(1)|str(s) -``` - -请注意,在 KCL 中虽然提供了 any 类型,但是它仍然是静态类型,所有变量的类型在编译期间不可变。 - -#### 类型推导 - -如果顶层或 schema 中的变量或常量声明没有使用显式的类型注解,则会从初始值推断类型。 - -- 整形数值被推断为 `int`。 - -```python -a = 1 # The variable `a` has the type `int` -``` - -- 浮点数被推断为 `float`。 - -```python -a = 1.0 # The variable `a` has the type `float` -``` - -- 字符串被推断为 `str`。 - -```python -a = "s" # The variable `a` has the type `str` -``` - -- 布尔值被推断为 `bool`。 - -```python -a = True # The variable `a` has the type `bool` -b = False # The variable `b` has the type `bool` -``` - -- `None` 和 `Undefined` 被推断为 `any`。 - -```python -a = None # The variable `a` has the type `any` -b = Undefined # The variable `b` has the type `any` -``` - -- 列表的类型根据元素类型推断,并且是可变大小的。 - -```python -a = [1, 2, 3] # The variable `a` has the type `[int]` -b = [1, 2, True] # The variable `b` has the list union type `[int|bool]` -c = ["s", 1] # The variable `c` has the list union type `[int|str]` -``` - -请注意,空列表将被推导为 `[any]` 类型。 - -```python -a = [] # The variable `a` has the type `[any]` -``` - -- 字典的类型是根据元素的键和值推断的,并且是可变大小的。 - -```python -a = {key = "value"} # The variable `a` has the type `{str:str}` -b = {key = 1} # The variable `b` has the type `{str:int}` -c = {key1 = 1, key2 = "s"} # The variable `c` has the type `{str:int|str}` -``` - -请注意,空字典将被推导为 `{any:any}` 类型。 - -```python -a = {} # The variable `a` has the type `{any:any}` -``` - -- 携带运行时值的 if 条件表达式的类型将被静态推断为所有可能结果的联合类型。 - -```python -a: bool = True # The variable `a` has the type `bool` -b = 1 if a else "s" # The variable `b` has the type `int|str` -``` - -当变量被推导为某个类型时,它的类型不能再改变。 - -```python -_a = 1 -_a = "s" # Error: expect int, got str(1) -``` - -#### 类型别名 - -在 KCL 中,我们可以使用 `type` 关键字为所有类型声明一个类型别名简化复杂类型的书写。 - -```python -type Int = int -type String = str -type StringOrInt = String | Int -type IntList = [int] -type StringAnyDict = {str:} -``` - -我们可以从一个包中导入一个类型并为它定义一个别名。 - -```py -import pkg - -type Data = pkg.Data -``` - -此外,我们还可以使用类型别名和字面值联合类型充当近似枚举的效果。 - -```python -# A type alias of string literal union types -type Color = "Red" | "Yellow" | "Blue" - -schema Config: - color: Color = "Red" # The type of color is `"Red" | "Yellow" | "Blue"`, and it has an alias `Color`, whose default value is `"Red"` - -config = Config { - color = "Blue" -} -``` - -上述代码执行的输出结果为: - -```yaml -config: - color: Blue -``` - -请注意,类型别名不能与已有的内置类型 `any`、`int`、`float`、`bool` 和 `str` 等相同 - -```python -type any = int | str # Error -type int = str # Error -type float = int # Error -type bool = True # Error -type str = "A" | "B" | "C" # Error -``` - -#### 类型守卫 - -KCL 支持在程序中使用 `typeof` 函数对任意值求得其运行时的类型。 - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person {} -t3 = typeof(_x1) - -_x2 = pkg.Person {} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# Output -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -除此之外,我们可以使用 `as` 关键字在运行时作类型转换。`as` 关键字的一般用法如下: - -- 具有偏序关系的基础类型,比如 `float -> int` -- 具有偏序关系的联合类型,比如 `int | str -> str` -- 对类型上界 `any` 的转换,比如 `any -> int` -- 具有偏序关系的结构类型,比如 `base-schema -> sub-schema` - -```python -schema Data1: - id?: int - -schema Data2: - name?: str - -data: Data1 | Data2 = Data1 {} - -if typeof(a) == "Data1": - data1 = data as Data1 # The type of `data1` is `Data1` -elif typeof(a) == "Data2": - data2 = data as Data2 # The type of `data2` is `Data2` -``` - -当类型转换失败时,一个运行时错误将被抛出。 - -```python -a: any = "s" -b: int = a as int # Error: The `str` type cannot be converted to the `int` type -``` - -如果不想要运行时类型转换失败,我们可以添加 `if` 防御式代码进行检查。 - -```python -a: any = "s" -b = a as int if typeof(a) == "int" else None # The type of b is `int` -``` - -请注意,`as` 转换的目标类型不能是字面值类型或者联合类型,因为它们在运行时不具有一个完全确定的类型。 - -### Schema - -#### 概述 - -Schema 是定义复杂配置的语言元素。我们可以定义带类型的属性,初始值和验证规则。此外,KCL 支持 schema 单继承、mixin 和 protocol 实现复杂配置的复用。 - -#### 基础部分 - -##### 属性 - -以下是 schema 基础定义的示例: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 -``` - -在 KCL 中, 我们可以使用类型注解在 schema 中定义一些属性,每个属性都可以设置一个可选的默认值(比如上述代码中的 `age` 属性,它的默认值是 `0`),没有设置默认值的属性的初始值为 `Undefined`, 它们不会在 YAML 当中进行输出。 - -###### 不可变性 - -schema 中属性的不可变性遵循和全局变量不可变性一样的规则,只有 schema 中的可变属性可以在 schema 中修改。此外,schema 的属性默认值可被 schema 配置值修改: - -```python -schema Person: - age: int = 1 # Immutable attribute - _name: str = "Alice" # Mutable attribute - - age = 10 # Error, can't change the default value of the attribute `age` in the schema context. - _name = "Bob" # Ok - -person = Person { - age = 3 # Ok, can change the default value of the attribute `age` in the schema config. -} -``` - -###### 可选属性 - -schema 实例中每个属性 **必须** 赋值一个非 `None`/`Undefined` 的值,否则编译器会抛出错误,除非它被 `?` 符号标记为可选属性。 - -示例: - -```python -schema Employee: - bankCard: int # bankCard is a required attribute, and it can NOT be None or Undefined - nationality?: str # nationality is an optional attribute, and it can be None or Undefined - -employee = Employee { - bankCard = None # Error, attribute 'bankCard' of Employee is required and can't be None or Undefined - nationality = None # Ok -} -``` - -##### 顺序无关计算 - -schema 中顺序无关计算表示 schema 内部属性之间的引用关系。例如,当我们声明一个形式为 `a = b + 1` 的表达式时,`a` 值的计算依赖于 `b` 值的计算。当编译器计算 `a` 的值并且 `a` 的值取决于 `b` 的值时,编译器会选择先计算 `b` 的值,然后根据 `b` 的值计算 a 的值表达式 `a = b + 1`,这与传统过程语言的计算方法略有不同。 - -由于 schema 中值的计算是基于依赖关系的,就像有向无环图按照拓扑排序的顺序遍历图中的每个节点一样, schema 中属性的声明顺序并不那么重要,因此特征称为顺序无关计算。 - -请注意,不同 schema 属性值之间不能有循环引用。 - -我们可以通过下面的例子看到这个特性。 - -```python -schema Fib: - n1: int = n - 1 # Refers to the attribute `n` declared after `n1` - n2: int = n1 - 1 - n: int - value: int = 1 if n <= 2 else Fib {n = n1}.value + Fib {n = n2}.value - -fib8 = Fib {n = 8}.value -``` - -结果为: - -```yaml -fib8: 21 -``` - -在 schema 中,我们只需要简单的指定属性之间的依赖关系,编译器就会根据依赖关系自动计算出值,这样可以帮助我们节省大量的样板代码,减少配置编写难度。 - -##### Schema 上下文 - -我们可以定义 schema 的上下文来管理 schema 的属性,可以直接在 schema 中编写 schema 参数、临时变量和表达式等: - -```python -schema Person[_name: str]: # define a schema argument - name: str = _name # define a schema attribute - age: int = 10 # define a schema attribute with default value - hands: [int] = [i for i in [1, 2, 3]] # define a for statement -``` - -然后,我们可以通过如下代码实例化一个 `Person` 并将其赋值给 `alice` 变量: - -```python -alice = Person("alice") -``` - -可以得到如下 YAML 输出: - -```yaml -alice: - name: alice - age: 10 - hands: - - 1 - - 2 - - 3 -``` - -##### 校验 - -KCL 中为了确保代码稳定性,除了使用 **静态类型** (类型注解) 和 **不可变性**,还支持在 **check** 块中定义验证规则 (KCL 几乎原生支持所有 [OpenAPI](https://www.openapis.org/) 的验证能力): - -```python -import regex - -schema Sample: - foo: str - bar: int - fooList: [str] - - check: - bar > 0 # Minimum, also support the exclusive case - bar < 100 # Maximum, also support the exclusive case - len(fooList) > 0 # Min length, also support exclusive case - len(fooList) < 100 # Max length, also support exclusive case - regex.match(foo, "^The.*Foo$") # Regex match - isunique(fooList) # Unique - bar in range(100) # Range - bar in [2, 4, 6, 8] # Enum - multiplyof(bar, 2) # MultipleOf -``` - -使用 schema, 所有的实例将在编译时验证: - -```python -# Ok -goodSample = Sample { - foo = "The Foo" - bar = 2 - fooList = ["foo0", "foo1"] -} - -# Error: validation failure: Check failed on check conditions: bar < 100. -badSample = Sample { - foo = "The Foo" - bar = 123 - fooList = ["foo0", "foo1"] -} -``` - -此外,我们可以使用 **and**, **or**, **if** 来构建更复杂的检查逻辑: - -```python -schema Sample: - bar: int - foo: str - doCheck: bool - - check: - regex.match(foo, "^The.*Foo$") and bar in [2, 4, 6, 8] if doCheck -``` - -为了确保所有检查规则都能很好地发挥其相应的作用,我们可以通过编写 KCL 测试用例来测试不同数据组合的合理性和正确性,并通过 kcl test tool 运行所有测试用例。 - -##### 文档 - -通常在我们写好 schema 模型之后,我们会为 schema 写文档注释,可以用一个三引号字符串来完成,如下所示: - -```python -schema Server: - """Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - - Attributes - ---------- - workloadType : str, default is Deployment - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - name : str, default is None - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - labels : {str:str}, optional, default is None - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - - Examples - ---------------------- - myCustomApp = AppConfiguration { - name = "componentName" - } - """ - workloadType: str = "Deployment" - name: str - labels?: {str:str} -``` - -更多详细内容可见 Doc tools。 - -##### 配置 - -假设我们有如下 schema 定义: - -```python -schema Person: - firstName: str - lastName: str - labels?: {str:str} -``` - -可以用类 JSON 的表达式定义配置: - -```python -person = Person { - firstName = "firstName" - lastName = "lastName" -} -``` - -schema 遵循严格的属性定义,配置未定义的属性将触发编译错误: - -```python -person = Person { - firstName = "firstName" - lastName = "lastName" - fullName = "fullName" # Error: Cannot add member 'fullName' to schema 'Person', 'fullName' is not defined in schema 'Person' -} -``` - -此外,我们可以使用 `if` 表达式将元素动态的添加到 schema 实例中,将满足条件的元素添加到 schema 实例并忽略不满足条件的元素。并且除了使用一个 schema 类型实例化一个 schema,我们也可以通过 schema 实例得到一个新的实例。 - -```python -env = "prod" -person = Person { - firstName = "firstName" - lastName = "lastName" - if env == "prod": - labels.env = env - else: - labels.env = "other" -} -# We can use the person instance to get a new instance named `personx` directly. -personx = person { - firstName = "NewFirstName" -} -``` - -输出为: - -```yaml -env: prod -person: - firstName: firstName - lastName: lastName - labels: - env: prod -personx: - firstName: NewFirstName - lastName: lastName - labels: - env: prod -``` - -#### 高级功能 - -##### Protocol & Mixin - -除了 schema, 在 KCL 中还提供了一种额外的类型定义方式 `protocol`,它的性质如下: - -- 在 protocol 中,只能定义属性及其类型,不能书写复杂的逻辑与 check 表达式,也不能使用 mixin。 -- protocol 只能对非 `_` 开头的属性进行约束。 -- protocol 只能继承自或者引用 protocol, 不能继承自或者引用 schema。 - -此外,我们可以使用可选的 **mixin** 组装复杂的 schema,并使用 **protocol** 为 **mixin** 添加可选的宿主类型, 使用 `for` 关键字为 **mixin** 定义宿主类型,并且在 mixin 内部它将从宿主类型中查询到属性的类型。 - -```python -schema Person: - mixin [FullNameMixin] - - firstName: str # Required - lastName: str # Required - fullName?: str # Optional -``` - -FullNameMixin 是一个产生 fullName 字段的简单例子: - -```python -protocol PersonProtocol: - firstName: str - lastName: str - fullName?: str - -mixin FullNameMixin for PersonProtocol: - fullName = "{} {}".format(firstName, lastName) -``` - -然后我们可以通过一下方式获取 schema 实例: - -```python -person = Person { - firstName = "John" - lastName = "Doe" -} -``` - -输出结果为: - -```yaml -person: - firstName: John - lastName: Doe - fullName: John Doe -``` - -请注意,宿主类型 **protocol** 只能用于 **mixin** 的定义 (后缀名为 `Mixin`), 否则将会报错。 - -```python -protocol DataProtocol: - data: str - -schema Data for DataProtocol: # Error: only schema mixin can inherit from protocol - x: str = data -``` - -##### 索引签名 - -在 KCL schema 中可以定义索引签名,这意味着索引签名的键-值约束可用于构造具有 schema 类型的字典。或者可以将其他检查添加到额外的 schema 属性中,以增强 KCL 类型和语义检查。 - -###### 基本用法 - -使用 `[{attr_alias}: {key_type}]: {value_type}` 的形式去定义 schema 的类型注解, 其中 `{attr_alias}` 可以省略。 - -```python -schema Map: - """ - Map is a schema with a key of str type and a value of str type - """ - [str]: str # `{attr_alias}` can be omitted. - -data = Map { - key1 = "value1" - key2 = "value2" -} -``` - -###### 同时定义属性和索引签名 - -可以在 schema 中同时定义 schema 属性和索引签名,通常用于表示 schema 中额外属性的类型约束,比如如下代码 - -```python -schema Person: - name: str - age: int - [...str]: str # Except for the `name` and `age` attributes, the key type of all other attributes of the schema must be `str`, and the value type must also be `str`. -``` - -###### 定义索引签名别名 - -可以为索引签名定义类型注解的属性别名,并将其与检查块一起使用。 - -```python -schema Data: - [dataName: str]: str - check: - dataName in ["Alice", "Bob", "John"] # We can use the index signature key name in the check block. - -data = Data { - Alice = "10" - Bob = "12" - Jonn = "8" # Error: Jonn not in ["Alice", "Bob", "John"] -} -``` - -##### 继承 - -类似于其他面向对象语言,KCL 提供了基础且有限的面向对象支持,例如 **属性复用**,**私有和公有变量**和**单继承**。KCL 不支持多继承。 - -以下是单继承的例子: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 - -# An employee **is** a person, and has some additional information. -schema Employee(Person): - bankCard: int - nationality?: str - -employee = Employee { - firstName = "Bob" - lastName = "Green" - age = 18 - bankCard = 123456 -} -``` - -结果为: - -```yaml -employee: - firstName: Bob - lastName: Green - age: 18 - bankCard: 123456 - nationality: null -``` - -请注意,KCL 只支持 schema 的 **单继承**。 - -此外,当 schema 存在继承关系时,可选属性的性质如下: - -- 如果该属性在基类 schema 中是可选的,则它在子类 schema 中是可选的,也可以是子类 schema 中必选的。 -- 如果该属性在基类 schema 中是必选的,则它在子类 schema 中也是必选的。 - -```python -schema Person: - bankCard?: int - nationality: str - -schema Employee(Person): - bankCard: int # Valid, both `bankCard: int` and `bankCard?: int` are allowed - nationality?: str # Error, only `nationality: str` is allowed -``` - -##### Schema 函数 - -schema 映射到函数上非常好用;它可以有任意数量的输入和输出参数。 例如,Fibonacci 函数可以使用递归 schema 如下编写: - -```python -schema Fib[n: int]: - n1 = n - 1 - n2 = n - 2 - if n == 0: - value = 0 - elif n == 1: - value = 1 - else: - value = Fib(n1).value + Fib(n2).value - -fib8 = Fib(8).value # 21 -``` - -##### 装饰器 - -像 Python 一样, KCL 支持在 schema 上使用装饰器。KCL 装饰器动态地改变 schema 的功能,而不必直接使用子 schema 或更改被装饰的 schema 的源代码。 和函数调用一样,装饰器支持传入额外的参数。 - -内置的 schema 装饰器: - -- `@deprecated` - 标识 schema 或 schema 属性被废弃. `@deprecated` 装饰器支持三种参数: - - **version** - 字符串类型,表示版本信息。 默认值为空。 - - **reason** - 字符串类型,表示不推荐使用的原因。 默认值为空。 - - **strict** - bool 类型,表示是报错还是警告。 默认值是 true。 如果 `strict` 为 `True` 并且抛出错误,程序将被中断。 如果 `strict` 为 `False`,则会输出警告并且不会中断程序。 - -示例: - -```python -@deprecated -schema ObsoleteSchema: - attr: str - -schema Person: - firstName: str = "John" - lastName: str - @deprecated(version="1.16", reason="use firstName and lastName instead", strict=True) - name: str - attrs: ObsoleteSchema = { # Error: ObsoleteSchema was deprecated - attr = "value" - } - -JohnDoe = Person { # Error: name was deprecated since version 1.16, use firstName and lastName instead - name = "deprecated" -} -``` - -- `@info` - 给 schema 或 schema 属性标识额外的信息,支持任意参数,用于语言静态分析 schema 或 schema 属性的扩展标记信息 - -示例: - -```python -@info(version="v1") -schema Person: - @info(message="name") - name: str - age: int -``` - -请注意,当前版本的 KCL 尚不支持用户自己定义装饰器。 - -##### 成员函数 - -内置函数和 schema 成员 - -- instances() - 返回 schema 的现有实例列表。 - -```python -schema Person: - name: str - age: int - -alice = Person { - name = "Alice" - age = 18 -} - -bob = Person { - name = "Bob" - age = 10 -} - -aliceAndBob = Person.instances() # Person is a schema type, instances() is its member method -``` - -输出为: - -```yaml -alice: - name: Alice - age: 18 -bob: - name: Bob - age: 10 -aliceAndBob: - - name: Alice - age: 18 - - name: Bob - age: 10 -``` - -### 配置操作 - -#### 配置合并 - -##### | 运算符 - -在 KCL 中,我们可以使用合并运算符 `|` 来合并配置。union 运算符支持的类型包括如下: - -```txt -SchemaInstance | SchemaInstance -SchemaInstance | Dict -Dict | Dict -List | List -``` - -合并集合和结构化数据: - -- 合并 List。使用 `|` 运算符右边的列表表达式按照**索引**逐一覆盖左边列表表达式中的元素。 - -```python -_a = [1, 2, 3] -_b = [4, 5, 6, 7] -x = _a | _b # [4, 5, 6, 7] 1 -> 4; 2 -> 5; 3 -> 6; Undefined -> 7 -``` - -合并特定索引或所有元素仍在讨论中。 - -- 合并 Dict. 使用 `|` 运算符右边的列表表达式按照**键**逐一覆盖左边列表表达式中的元素。 - -```python -_a = {key1 = "value1"} -_b = {key1 = "overwrite", key2 = "value2"} -x = _a | _b # {"key1": "overwrite", "key2": "value2"} -``` - -集合和 schema 的合并是一个新的集合,其属性是将 b 合并到 a,保留从左到右的操作数顺序。 - -- 合并 schema。Schema 的合并与 dict 相似。 - -Schema 的合并操作如下: - -```python -schema Person: - firstName?: str - lastName?: str - -_a = Person { - firstName = "John" -} -_b = {lastName = "Doe"} -_c = _a | _b # {"firstName": "John", "lastName": "Doe"} -_d = _a | None # {"firstName": "John"} -_e = _a | Undefined # {"firstName": "John"} -_f = None | _a # {"firstName": "John"} -_g = Undefined | _a # {"firstName": "John"} -``` - -请注意,当 union 运算符的左右操作数之一为 None 时,将立即返回另一个操作数。 - -```python -data1 = {key = "value"} | None # {"key": "value"} -data2 = None | [1, 2, 3] # [1, 2, 3] -data3 = None | None # None -``` - -输出如下: - -```yaml -data1: - key: value -data2: - - 1 - - 2 - - 3 -data3: null -``` - -##### : 运算符 - -模式: `identifier : E` - -表达式 `E` 的值将被合并到元素值。 - -示例: - -```python -schema Data: - labels: {str:} = {key1 = "value1"} - -data = Data { - # union {key2: "value2"} into the attribute labels of the schema Data. - labels: {key2 = "value2"} -} -``` - -输出: - -```yaml -data: - labels: - key1: value1 - key2: value2 -``` - -除了在 schema 属性上使用属性运算符之外,还可以使用属性运算符对配置块执行不同的操作。 - -- schema 外部使用合并运算符 `:` - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - data: Data - -# This is one configuration that will be merged. -config: Config { - data.d1 = 1 -} -# This is another configuration that will be merged. -config: Config { - data.d2 = 2 -} -``` - -与它等效的配置代码可以表示为: - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - data: Data - -config: Config { - data.d1 = 1 - data.d2 = 1 -} -``` - -输出结果为: - -```yaml -config: - data: - d1: 1 - d2: 1 -``` - -- schema 内部使用合并运算符 `:` - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - # This is one configuration that will be merged. - data: Data { - d1 = 1 - } - # This is another configuration that will be merged. - data: Data { - d2 = 1 - } - -config: Config {} -``` - -#### 配置覆盖 - -##### = 运算符 - -模式: `identifier = E` - -表达式 `E` 的值将覆盖元素值。 - -示例: - -```python -schema Data: - labels: {str:} = {key1 = "value1"} - -data = Data { - # override {key2: "value2"} into the attribute labels of the schema Data. - labels = {key2 = "value2"} -} -``` - -输出: - -```yaml -data: - labels: - key2: value2 -``` - -请注意,可以使用 `Undefined` 来覆盖,来“删除”内容。例如 `{ a = Undefined }`。 - -#### 配置添加 - -##### += 运算符 - -模式: `identifier += E` - -插入只能用于列表类型的 `identifier`. - -`E` 将插入到列表 `identifier` 指定索引后,并且索引以后的属性将自动后移。 - -示例: - -```python -schema Data: - labels: {str:} = {key1 = [0]} - -data = Data { - # insert [1] into the attribute labels.key1 of the schema Data. - labels: {key1 += [1]} -} -``` - -输出: - -```yaml -data: - labels: - key1: - - 0 - - 1 -``` - -如果没有定义索引,将使用最后一个索引。 - -#### 注意事项 - -合并运算符 `:` 是一个可交换的幂等运算符,当合并的值发生值的冲突时会发生值冲突错误,因此我们需要 `=` 和 `+=` 运算符表示配置的覆盖,添加和删除操作。 - -```python -data0 = {id: 1} | {id: 2} # Error:conflicting values between {'id': 2} and {'id': 1} -data1 = {id: 1} | {id = 2} # Ok, the value of `data` is {"id": 2} -``` - -`:` 运算符冲突检查的规则如下: - -- `None` 和 `Undefined` 不与任何值冲突 - -```python -data0 = None | {id: 1} # Ok -``` - -- 对于 `int`、`float`、`str` 和 `bool` 类型的变量,当它们的值不相同时发生冲突错误。 - -```python -data0 = 1 | 1 # Ok -data1 = 1 | "s" # Error -``` - -- 对于列表类型 - - 当它们的长度不相同时,它们被认为是冲突的 - - 当它们的长度相同时,当且仅当它们的任意一个子元素值冲突时,它们自身是冲突的 - -```python -data0 = [1] | [1] # Ok -data1 = [1, 2] | [1] # Error -``` - -- 对于 dict/schema 类型 - - 对于相同的 key,key 的值冲突时,它们自身是冲突的,否则是不冲突的 - -```python -data0 = {id: 1} | {id: 1} # Ok -data1 = {id: 1} | {id: 2} # Error -data1 = {id: 1} | {idAnother: 1} # Ok -``` - -### Rule - -KCL 支持使用 rule 关键字定义校验块,可用于数据校验,用法类似于 schema 中的 check 表达式。 - -```python -rule SomeRule: - age > 0, "rule check failure message" -``` - -可以像 schema 实例化那样调用一个 rule 进行校验 - -```python -age = 0 -name = "Bob" -rule SomeRule: - age > 0, "rule check failure message" - name == "Alice" - -rule1 = SomeRule() # Rule call -rule2 = SomeRule {} -``` - -可以使用 protocol 和 for 绑定语句为 rule 增加类型约束: - -```python -# Schema definition -protocol Service: - clusterIp: str - $type: str - -# Schema definition -protocol Volume: - mountPath: [str] - -# Protocol -protocol SomeProtocol: - id: int - env: {str: any} - services: [Service] - volumes: [Volume] - -rule SomeChecker for SomeProtocol: - id > 0, "id must >0" - - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - } - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } - -# Call rule to check with config parameter -SomeChecker { - id = 1 - env = { - MY_ENV = "MY_ENV_VALUE" - } - services = [ - { - type = "ClusterIP" - clusterIP = "NONE" - } - ] - volumes = [ - { - mountPath = "/home/admin" - } - { - mountPath = "/home/myapp" - } - ] -} -``` - -请注意,`protocol` 和 `rule` 的组合方式可以使属性和其约束定义进行分离,我们可以在不同的包中定义不同的 `rule` 和 `protocol` 按需进行组合,这与 schema 中的 check 表达式只能与 schema 属性定义在一起是不同的。 - -此外,有两种复用不同 rule 的方式 - -- 直接调用 - -```python -weather = "sunny" -day = "wednesday" - -rule IsSunny: - weather == "sunny" - -rule IsWednesday: - day == "wednesday" - -rule Main: - IsSunny() # Rule inline call - IsWednesday() # Rule inline call - -Main() # Rule call -``` - -使用 rule 的继承 (rule 不同于 schema, 可以多继承混用) - -```python -weather = "sunny" -day = "wednesday" - -rule IsSunny: - weather == "sunny" - -rule IsWednesday: - day == "wednesday" - -rule Main(IsSunny, IsWednesday): - id == 1 - -Main() -``` - -可以使用 option 函数与命令行 `-D` 参数获得外部数据进行校验 - -- 一个简单例子 - -```python -schema Day: - day: str - homework: str - -days: [Day] = option("days") - -rule Main: - filter d in days { - d.day not in ["saturday", "sunday"] and d.homework - } - -Main() -``` - -- 一个复杂例子 - -```python -data = option("data") -input = option("input") - -rule Allow: - UserIsAdmin() - any grant in UserIsGranted() { - input.action == grant.action and input.type == grant.type - } - -rule UserIsAdmin: - any user in data.user_roles[input.user] { - user == "admin" - } - -rule UserIsGranted: - [ - grant - for role in data.user_roles[input.user] - for grant in data.role_grants[role] - ] - -allow = Allow() or False -``` - -### 模块 - -KCL 配置文件以 **模块** 形式组织。 单个 KCL 文件被认为是一个 module,一个目录被认为是一个包。 - -同一个包内的模块是可见的,跨包引用需要通过导入可见。 - -```bash -. -└── root - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -model1.k: - -```python -# schema CatalogItem in model1.k - -schema CatalogItem: - id: int - image: CatalogItemImage # CatalogItemImage is defined in the module of the same package e.g., model2.k in package model - title: str -``` - -service1.k: - -```python -import ..model as model # cross-package references - -schema ImageService: - image: model.CatalogItemImage # CatalogItemImage is imported from another package e.g., model2.k in package model - name: str -``` - -#### 相对路径引用 - -我们可以使用 `.` 运算符来实现 KCL 入口文件的相对路径导入。 - -main.k: - -```python -import .model1 # Current directory module -import ..service # Parent directory -import ...root # Parent of parent directory - -s = service.ImageService {} -m = root.Schema {} -``` - -#### 绝对路径引用 - -`import a.b.c.d` 的语义为: - -1. 如果 `kcl.mod` 文件不存在,将当前目录作为包的根路径,并从当前目前查找 `a/b/c/d` 路径 -2. 如果 `kcl.mod` 文件存在,从 `ROOT_PATH/a/b/c/d` 查找,否则抛出一个导入错误 - -根路径 `ROOT_PATH` 的定义为: - -从当前目录或者父级目录中查找 `kcl.mod` 文件对应的目录。 - -```bash -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -main.k: - -```python -import service # `root package` and `kcl.mod` are in the same directory -import mixin # `root package` and `kcl.mod` are in the same directory - -myModel = model.CatalogItem {} -``` - -请注意,对于 KCL 入口文件 `main.k`,不能导入所在文件夹,否则会出现递归导入错误: - -```python -import model # Error: recursively loading -``` - -### 动态参数 - -假设某些字段需要像用户输入一样动态传入,我们可以在模块中定义一个动态参数: - -```python -bankCard = option("bankCard") # Get bankCard through the option function. -``` - -我们可以如下使用 module: - -```bash -kcl employee.k -D bankCard=123 -``` - -目前,支持顶级参数的类型有数字、字符串、布尔、列表和字典。 - -```bash -kcl main.k -D list_key='[1,2,3]' -D dict_key='{"key":"value"}' -``` - -请注意,命令行中引号 `"` 等符号需要使用 `\` 进行转义 - -#### Setting 文件形式的参数 - -此外,它还支持输入一个 YAML 文件作为顶级参数。 - -```yaml -kcl_options: - - key: key_number - value: 1 - - key: key_dict - value: - innerDictKey: innerDictValue - - key: key_list - value: - - 1 - - 2 - - 3 - - key: bankCard - value: 123 -``` - -```bash -kcl -Y setting.yaml employee.k -``` - -此外,setting 文件还支持配置命令行编译参数如下: - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - disable_none: true - strict_range_check: true - debug: 1 - verbose: 1 - sort_keys: true - output: ./stdout.golden - overrides: - - app.image=new_image - path_selector: - - config - package_maps: - k8s: /Users/.kcl/kpm/k8s_1.24 -kcl_options: - - key: image - value: docker.io/kcllang/kcl:latest -``` - -KCL CLI -Y 参数还支持多文件配置,并支持编译参数和顶级参数的单独写入与合并。 - -```bash -kcl -Y compile_setting.yaml option_setting.yaml -``` - -- `compile_setting.yaml` - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - disable_none: true - strict_range_check: true - debug: 1 - verbose: 1 - output: ./stdout.golden -``` - -- `option_setting.yaml` - -```yaml -kcl_options: - - key: image - value: docker.io/kcllang/kcl:latest -``` - -我们可以使用以下指令获取每个参数的含义 - -```bash -kcl --help -``` - -#### Option Functions - -我们可以在 KCL 代码中使用 `option` 获取顶级参数。 - -```python -value = option(key="key", type='str', default="default_value", required=True, help="Set key value") -``` - -参数 - -- **key**: 参数的键。 -- **type**: 要转换的参数类型。 -- **default**: 参数默认值。 -- **required**: 当未提供参数且参数的 required 为 True 是报告错误。 -- **help**: 帮助信息。 - -### 多文件编译 - -除了上面的 KCL 单文件执行之外,我们还可以使用以下命令同时编译多个 KCL 入口文件: - -```bash -kcl main_1.k main_2.k ... main_n.k -``` - -main_1.k - -```python -a = 1 -b = 2 -``` - -main_2.k - -```python -c = 3 -d = 4 -``` - -输出结果为: - -```yaml -a: 1 -b: 2 -c: 3 -d: 4 -``` - -利用**多文件编译**,我们可以组合多个 KCL 文件,而无需使用 import 管理文件。 我们来看一个结合**多文件编译**和 **schema 实例**的例子。 - -model.k - -```python -schema Model: - name: str - labels?: {str:} - annotations?: {str:} - replicas: int - -_model1 = Model { - name = "model1" - labels.key1 = "value1" - labels.key2 = "value2" - annotations.key = "value" - replicas = 2 -} - -_model2 = Model { - name = "model2" - replicas = 3 -} -``` - -backend.k - -```python -import yaml - -schema Backend: - apiVersion: str = "v1" - kind: str = "Deployment" - metadata: {str:} - spec: {str:} = { - minReadySeconds = 0 - paused = False - progressDeadlineSeconds = 600 - replicas = 1 - revisionHistoryLimit = 10 - selector = {} - } - -_backends = [Backend { - metadata.name = model.name - metadata.labels = model.labels - metadata.annotations = model.annotations - spec.selector.matchLabels: model.labels - spec.replicas = model.replicas -} for model in Model.instances()] # Schema Model is defined in model.k -print("---\n".join([yaml.encode(_b, ignore_private=True) for _b in _backends])) -``` - -命令为: - -```bash -kcl model.k backend.k -``` - -输出为: - -```yaml -apiVersion: v1 -kind: Deployment -metadata: - name: model1 - labels: - key1: value1 - key2: value2 - annotations: - key: value -spec: - minReadySeconds: 0 - paused: false - progressDeadlineSeconds: 600 - replicas: 2 - revisionHistoryLimit: 10 - selector: - matchLabels: - key1: value1 - key2: value2 ---- -apiVersion: v1 -kind: Deployment -metadata: - name: model2 -spec: - minReadySeconds: 0 - paused: false - progressDeadlineSeconds: 600 - replicas: 3 - revisionHistoryLimit: 10 - selector: {} -``` - -### KCL 变量查询 - -我们可以在 KCL CLI 使用 `-S|--path-selector` 参数从 KCL 模型中查询一个或多个值。 - -变量查询形式如下: - -`var.name` - -#### 示例 - -Code structure: - -```bash -. -├── kcl.mod -└── main.k - └── pkg - └── model.k -``` - -pkg/model.k: - -```python -schema Person: - name: str - age: int - -var = Person { - name = "Alice" - age = 18 -} -``` - -main.k - -```python -import pkg - -var = pkg.Person { - name = "Bob" - age = 10 -} -``` - -命令为: - -```bash -kcl main.k -S var -``` - -输出结果为: - -```yaml -var: - name: Bob ---- -var: - name: Alice - age: 18 -``` - -### KCL 变量修改 - -除了变量查询,KCL 还允许我们通过 KCL CLI 的 `-O|--overrides` 参数直接修改配置模型中的值。 - -变量修改参数的使用与变量查询类似,参数包含三部分,如 `pkg`、`identifier`、`attribute` 和 `override_value` . - -```bash -kcl main.k -O override_spec -``` - -- `override_spec`: 表示需要修改的配置模型字段和值的统一表示 - -```txt -override_spec: [[pkgpath] ":"] identifier ("=" value | "-") -``` - -- `pkgpath`: 表示需要修改标识符的包路径,通常为 `a.b.c` 的形式,对于 main 包,`pkgpath` 表示为 `__main__`, 可省略,省略不写时表示 main 包 -- `identifier`: 表示需要修改配置的标识符,通常为 `a.b.c` 的形式 -- `value`: 表示需要修改配置的值,可以是任意合法的 KCL 表达式,比如数字/字符串字面值,list/dict/schema 表达式等 -- `=`: 表示修改identifier的值 - - 当 identifier 存在时,修改已有 identifier的值为 value - - 当 identifier 不存在时,添加 identifier属性,并将其值设置为 value -- `-`: 表示删除 identifier属性 - - 当 identifier 存在时,直接进行删除 - - 当 identifier 不存在时,对配置不作任何修改 - -请注意,当 `identifier` 出现多次时,修改/删除全部 `identifier` 的值 - -此外,在 KCL 中还提供了 API 用于变量查询和修改,详见 [API 文档](../xlang-api/go-api.md) - -#### 示例 - -##### 修改示例 - -KCL 代码: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -``` - -命令为: - -```bash -kcl main.k -O :person.name=Bob -O :person.age=10 -``` - -输出结果为: - -```yaml -person: - name: Bob - age: 10 -``` - -此外,当我们使用 KCL CLI `-d` 参数时,KCL 文件将同时修改为以下内容 - -```bash -kcl main.k -O :person.name=Bob -O :person.age=10 -d -``` - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Bob" - age = 10 -} -``` - -##### 删除示例 - -KCL 代码: - -```python -schema Config: - x?: int = 1 - y?: str = "s" - -config = Config { - x = 2 -} -``` - -命令为: - -```bash -kcl main.k -O config.x- -``` - -输出结果为: - -```yaml -config: - x: 1 - y: s -``` - -### 总结 - -本页总结了 KCL 语言中的常用功能。 KCL 作为一种新的语言,会根据配置场景的需求,逐步增加功能特性。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/datetime.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/datetime.md deleted file mode 100644 index 66cb4bca..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/datetime.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: "datetime" -linkTitle: "datetime" -type: "docs" -description: datetime 包 - 时间处理 -weight: 100 ---- - -## time - -`ticks() -> float` - -返回从 1970 年 1 月 1 日 0 时 0 分 0 秒(Epoch)开始到当前时间经过的秒数。如果系统时钟能提供更精确的时间,则秒数后可能会有小数部分。 - -## date - -`date() -> str` - -返回以 `%Y-%m-%d %H:%M:%S` 格式表示的时间。 - -## now - -`now() -> str` - -返回当地时间,例如 `'Sat Jun 06 16:26:11 1998'`。 - -## today - -`today() -> str` - -返回以 `%Y-%m-%d %H:%M:%S.%{ticks}` 格式表示的时间。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/index.md deleted file mode 100644 index c1f4b4a0..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# 系统模块 - -KCL 通过系统模块、用户模块和插件模块提供工程化的扩展能力。本节介绍系统模块的基本概念,插件模块可以参考插件系统。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/json.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/json.md deleted file mode 100644 index b19bdc88..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/json.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: "json" -linkTitle: "json" -type: "docs" -description: JSON 编码解码 -weight: 100 ---- - -## encode - -``` -encode( - data: any, - sort_keys: bool = False, - indent: int = None, - ignore_private: bool = False, - ignore_none: bool = False -) -> str -``` - -将 KCL 对象 `data` 序列化为 JSON 格式的字符串。 - -## decode - -`decode(value: str) -> any` - -反序列化 `value`(一个包含 JSON 格式文档的字符串实例)为一个 KCL 对象。 - -## dump_to_file - -``` -dump_to_file( - data: any, - filename: str, - ignore_private: bool = False, - ignore_none: bool = False -) -> None -``` - -将 KCL 对象 `data` 序列化为 JSON 格式的字符串,并将其写入文件 `filename` 中。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/overview.md deleted file mode 100644 index aa3eaeb3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/overview.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -sidebar_position: 0 ---- - -# 概览 - -KCL 是面向配置的编程语言,通过内置模块、KCL 模块和插件模块提供工程化的扩展能力。 - -![](/img/docs/reference/lang/model/kcl-module.png) - -用户代码中不用导入直接使用 builtin 的函数(比如用 `len` 计算列表的长度、通过 `typeof` 获取值的类型等),而对于字符串等基础类型也提供了一些内置方法(比如转化字符串的大小写等方法)。对于相对复杂的通用工作则通过标准库提供,比如通过 import 导入 `math` 库就可以使用相关的数学函数,可以通过导入 `regex` 库使用正则表达式库。而针对 KCL 代码也可以组织为模块,比如 Konfig 大库中将基础设施和各种标准的应用抽象为模块供上层用户使用。此外还可以通过 Plugin 机制,采用 Python 为 KCL 开发插件,比如目前有 meta 插件可以通过网络查询中心配置信息,`app-context` 插件则可以用于获取当前应用的上下文信息从而简化代码的编写。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/yaml.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/yaml.md deleted file mode 100644 index e0faf129..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/yaml.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: "yaml" -linkTitle: "yaml" -type: "docs" -description: yaml 编码解码 -weight: 300 ---- - -## encode - -``` -encode( - data: any, - sort_keys: bool = False, - ignore_private: bool = False, - ignore_none: bool = False -) -> str -``` - -将 KCL 对象 `data` 序列化为 YAML 格式的字符串。 - -## decode - -`decode(value: str) -> any` - -反序列化 `value`(一个包含 YAML 格式文档的字符串实例)为一个 KCL 对象。 - -## dump_to_file - -``` -dump_to_file( - data: any, - filename: str, - ignore_private: bool = False, - ignore_none: bool = False -) -> None -``` - -将 KCL 对象 `data` 序列化为 YAML 格式的字符串,并将其写入文件 `filename` 中。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/_category_.json deleted file mode 100644 index edfe989e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "包管理", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/1.init.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/1.init.md deleted file mode 100644 index 0bfc0303..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/1.init.md +++ /dev/null @@ -1,45 +0,0 @@ -# kpm init - -初始化一个 kcl 包。 - -## 使用 - -```shell -kpm init [options][package_name] -``` - -## 介绍 - -`kpm init` 会在当前目录初始化一个 kcl 包。如果没有提供包名,会使用当前目录的名字作为包名。 - -如果提供了包名,会在当前目录下创建一个以包名命名的子目录,并在该目录下初始化 kcl 包。 - -`kpm init` 会在包目录下创建 `kcl.mod`、`kcl.mod.lock` 和 `main.k`。 - -## 选线 - -### --help, -h - -显示帮助信息。 - -## 示例 - -### 初始化当前目录为 kcl 包 - -```shell -# 创建一个目录 -$ mkdir my_package - -# 进入目录 -$ cd my_package - -# 初始化当前目录为 kcl 包 -$ kpm init -``` - -### 初始化一个名为 my_package 的 kcl 包 - -```shell -# 初始化一个名为 my_package 的 kcl 包 -kpm init my_package -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/10.help.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/10.help.md deleted file mode 100644 index 0fd9fa3a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/10.help.md +++ /dev/null @@ -1,21 +0,0 @@ -# kpm help - -输出 kpm 命令的帮助信息。 - -## 使用 - -```shell -kpm help -``` - -## 介绍 - -`kpm help` 会输出 kpm 命令的帮助信息。 - -## 示例 - -使用 `kpm help` 输出 kpm 命令的帮助信息。 - -```shell -kpm help -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/2.add.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/2.add.md deleted file mode 100644 index 09fd5d46..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/2.add.md +++ /dev/null @@ -1,53 +0,0 @@ -# kpm add - -添加一个依赖到 kcl 包。 - -## 使用 - -```shell -kpm add [options][package_reference] -``` - -## 介绍 - -`kpm add` 会添加一个依赖到 kcl 包。依赖可以来自 git 仓库,或者 kcl registry。 - -`package_reference` 是一个 kcl 包引用,格式为 `package_name:version`。 - -## 选项 - -### --git - -指定依赖来自 git 仓库的 git url。 - -### --tag - -指定依赖来自 git 仓库的 tag。 - -### --help, -h - -显示帮助信息。 - -## 示例 - -### 添加一个来自 kcl registry 的依赖 - -添加一个名为 `k8s` 的依赖,版本为最新版本。 - -```shell -kpm add k8s -``` - -添加一个名为 `k8s` 的依赖,版本为 `v1.27.2`。 - -```shell -kpm add k8s:v1.27.2 -``` - -### 添加一个来自 git 仓库的依赖 - -添加一个来自 git 仓库的 kcl 包依赖,tag 为 v0.1.0 - -```shell -kpm add --git https://github.com/awesome-kusion/konfig.git --tag v0.1.0 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/3.pkg.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/3.pkg.md deleted file mode 100644 index fd708d03..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/3.pkg.md +++ /dev/null @@ -1,33 +0,0 @@ -# kpm pkg - -打包一个 kcl 包。 - -## 使用 - -```shell -kpm pkg [options] -``` - -## 介绍 - -`kpm pkg` 会打包一个 kcl 包为 `*.tar`。 - -选项 `--target` 用于指定打包后的 `*.tar` 文件路径。 - -## 选项 - -### --target - -指定打包后的 `*.tar` 文件路径。 - -### --help, -h - -显示帮助信息。 - -## 示例 - -### 打包当前 kcl 包为 `*.tar` - -```shell -kpm pkg --target /Users/my_package_tar -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/4.metadata.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/4.metadata.md deleted file mode 100644 index 199ebd2e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/4.metadata.md +++ /dev/null @@ -1,41 +0,0 @@ -# kpm metadata - -打印 kcl 包的元数据。 - -## 使用 - -```shell -kpm metadata [options] -``` - -## 介绍 - -`kpm metadata` 会打印 kcl 包的元数据。元数据包括包的依赖信息。 - -`--update` 选项用于自动下载缺失的依赖包。 - -## 选项 - -### --update - -自动下载缺失的依赖包。 - -### --help, -h - -展示 `kpm metadata` 命令的帮助信息。 - -## 示例 - -### 打印 kcl 包的元数据 - -打印 kcl 包的元数据。 - -```shell -kpm metadata -``` - -打印 kcl 包的元数据,并自动下载缺失的依赖包。 - -```shell -kpm metadata --update -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/5.run.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/5.run.md deleted file mode 100644 index eee83e08..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/5.run.md +++ /dev/null @@ -1,69 +0,0 @@ -# kpm run - -编译一个 kcl 包。 - -## 使用 - -```shell -kpm run [options][package_source] -``` - -## 介绍 - -`kpm run` 会编译一个 kcl 包。 - -## 选项 - -### --input - -指定包的入口文件路径。 - -### --tag - -指定 oci url 的包的 tag。 - -### --vendor - -`--vendor` 选项会将依赖包移动到当前包,并自动下载缺失的依赖包。 - -### --kcl_args - -`--kcl_args` 描述了传递给 kcl 编译器的参数。 - -### --help, -h - -展示 `kpm run` 命令的帮助信息。 - -## 示例 - -### 编译当前 kcl 包 - -在 kcl 包目录下,`kpm run` 可以用于编译当前 kcl 包。 - -```shell -kpm run -``` - -### 编译一个 kcl 包 tar 文件 - -`kpm run` 可以用于编译一个 kcl 包 tar 文件。 - -```shell -kpm run /Users/demo/my_package.tar -``` - -### 编译一个 kcl 包来自 oci url - -`kpm run` 可以用于编译一个 kcl 包从 oci url。 - -```shell -kpm run --tag 0.0.1 oci://localhost:5001/test/my_package -``` - -### 编译一个 kcl 包来自 oci ref - -`kpm run` 可以用于编译一个 kcl 包从 oci ref。 - -```shell -kpm run test/my_package:0.0.1 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/6.login.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/6.login.md deleted file mode 100644 index 9055d8fb..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/6.login.md +++ /dev/null @@ -1,68 +0,0 @@ -# kpm login - -登陆 kpm registry. - -## 使用 - -```shell -kpm login [options][kpm_registry] -``` - -## 介绍 - -`kpm login` 将会登陆 kpm registry。 - -## 选项 - -### --username, -u - -指定 kpm registry 的用户名。 - -### --password, -p - -指定 kpm registry 的密码。 - -### --help, -h - -展示 `kpm login` 命令的帮助信息。 - -## 示例 - -### 登陆到 kpm registry, 通过参数输入用户名和密码 - -```shell -kpm login -u -p -``` - -期望输出为 - -```shell -Login succeeded -``` - -### 登陆到 kpm registry, 通过参数输入用户名,密码通过交互式输入 - -```shell -kpm login -u -``` - -期望输出为 - -```shell -Password: -Login succeeded -``` - -### 登陆到 kpm registry, 用户名和密码通过交互式输入 - -```shell -kpm login -``` - -期望输出为 - -```shell -Username: -Password: -Login succeeded -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/7.logout.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/7.logout.md deleted file mode 100644 index 65dd317e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/7.logout.md +++ /dev/null @@ -1,27 +0,0 @@ -# kpm logout - -从 kpm registry 登出。 - -## 使用 - -```shell -kpm logout [options][kpm_registry] -``` - -## 介绍 - -`kpm logout` 会从 kpm registry 登出。 - -## 选项 - -### --help, -h - -展示 `kpm logout` 命令的帮助信息。 - -## 示例 - -### 从 kpm registry 登出 - -```shell -kpm logout -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/8.push.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/8.push.md deleted file mode 100644 index 53c2e520..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/8.push.md +++ /dev/null @@ -1,46 +0,0 @@ -# kpm push - -上传一个 kcl 包到 kpm registry。 - -## 使用 - -```shell -kpm push [options][kpm_registry] -``` - -## 介绍 - -`kpm push` 将会上传一个 kcl 包到 kpm registry。 - -## 选项 - -### --tar_path - -指定上传的 `*.tar` 文件路径。 - -### --help, -h - -展示 `kpm push` 命令的帮助信息。 - -## 示例 - -### 上传当前 kcl 包到 kpm registry - -你可以在 kcl 包的根目录下使用 `kpm push` 命令上传一个 kcl 包到 kpm registry。 - -```shell -# 创建一个 kcl 包 -$ kpm init -# 进入 kcl 包目录 -$ cd -# 上传 kcl 包到 kpm registry -$ kpm push -``` - -### 上传一个 `*.tar` 文件到 kpm registry - -你也可以使用 `kpm push` 命令上传一个 `*.tar` 文件到 kpm registry。 - -```shell -kpm push --tar_path -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/9.pull.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/9.pull.md deleted file mode 100644 index cec49291..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/9.pull.md +++ /dev/null @@ -1,41 +0,0 @@ -# kpm pull - -下载 kcl 包从 kpm registry。 - -## 使用 - -```shell -kpm pull [options][package_source] -``` - -## 介绍 - -`kpm pull` 会从 kpm registry 下载 kcl 包。 - -## 选项 - -### --tag - -使用 oci url 下载包时, 指定要下载的 kcl 包的 tag。 - -### --help, -h - -展示 `kpm pull` 命令的帮助信息。 - -## 示例 - -### 从 kpm registry 下载 kcl 包 - -你可以使用 `kpm pull` 命令从 默认的 kpm registry 下载 kcl 包。 - -```shell -kpm pull : -``` - -### 下载 kcl 包通过 oci url - -你可以使用 `kpm pull` 命令从一个 oci url 下载 kcl 包。 - -```shell -kpm pull --tag -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/index.md deleted file mode 100644 index e3025db9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/index.md +++ /dev/null @@ -1,36 +0,0 @@ -# kpm - -kpm 命令。 - -## 使用 - -```shell -kpm [arguments]... -``` - -## 介绍 - -`kpm` 是 kcl 包管理工具。它用于分发和管理 kcl 包。 - -## 选项 - -### --help, -h - -展示 `kpm` 命令的帮助信息。 - -### --version, -v - -展示 `kpm` 命令的版本信息。 - -## 子命令 - -- [kpm init](./1.init.md) - 初始化一个 kcl 包 -- [kpm add](./2.add.md) - 添加一个依赖到 kcl 包 -- [kpm pkg](./3.pkg.md) - 打包一个 kcl 包为 `*.tar` -- [kpm metadata](./4.metadata.md) - 打印一个 kcl 包的元数据 -- [kpm run](./5.run.md) - 编译一个 kcl 包为 yaml 并运行 -- [kpm login](./6.login.md) - 登录到一个 kcl registry -- [kpm logout](./7.logout.md) - 登出一个 kcl registry -- [kpm push](./8.push.md) - 上传一个 kcl 包到一个 registry -- [kpm pull](./9.pull.md) - 下载一个 kcl 包从一个 registry -- [kpm help](./10.help.md) - 打印 kpm 命令的帮助信息 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/plugin/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/plugin/overview.md deleted file mode 100644 index b3cc9469..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/plugin/overview.md +++ /dev/null @@ -1,183 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 简介 - -KCL 是声明式配置策略语言,对于不方便通过配置直接描述的复杂的业务逻辑可以通过通用的编程语言开发 KCL 插件对语言进行扩展。KCL 支持通过通用语言开发插件,KCL 程序导入插件中的函数。KCL 通过插件运行时和辅助的命令行工具提供插件支持。KCL 插件框架支持多种不同的通用语言开发插件,这里我们以 Python 为例简单说明插件的使用。 - -插件的 Git 仓库: [https://github.com/kcl-lang/kcl-plugin](https://github.com/kcl-lang/kcl-plugin) - -## 0. 前置依赖 - -使用 KCL Python 插件需要您的 `PATH` 中存在 `Python3.7+`。 - -## 1. 你好插件 - -KCL 插件在 KCL 的 `plugins` 子目录(通常安装在 `$HOME/.kcl/plugins` 目录),或者通过 `$KCL_PLUGINS_ROOT` 环境变量设置(环境变量优先级更高)。此外,`plugins` 插件目录还可以放在执行 KCL 命令的 `pwd` 路径或者父路径中。对于插件开发人员,插件都在 Git 仓库管理: [https://github.com/kcl-lang/kcl-plugin](https://github.com/kcl-lang/kcl-plugin) ,可以将插件仓库克隆到该目录进行开发。 - -输入 `kcl-plugin info` 命令查看查看插件目录(将其中的 `/Users/kcl_user` 替换成本地的 `$HOME` 路径): - -```shell -$ kcl-plugin info -# plugin_root: /Users/kcl_user/.kcl/plugins -``` - -通过 `kcl-plugin list` 子命令查看插件列表: - -```shell -$ kcl-plugin list -hello: hello doc - 0.0.1 -``` - -其中 `hello` 是 KCL 内置的示例插件(不要修改改插件)。 - -在 KCL 代码中,可以通过 `kcl_plugin.hello` 导入 `hello` 插件。`main.k` 代码如下: - -```python -import kcl_plugin.hello - -name = "kcl" -three = hello.add(1,2) -``` - -输出结果如下: - -```shell -$ python3 -m kclvm main.k -name: kcl -three: 3 -``` - -## 2. `kcl-plugin` 辅助命令 - -`kcl-plugin` 是提供的插件辅助工具,命令行帮助如下: - -```shell -$ kcl-plugin -usage: kcl-plugin [-h] {list,info,init,gendoc,test} ... -positional arguments: - {list,info,init,gendoc,test} - kcl plugin sub commands - list list all plugins - info show plugin document - init init a new plugin - gendoc gen all plugins document - test test plugin -optional arguments: - -h, --help show this help message and exit -``` - -其中 `list` 子命令用于查看插件列表;`info` 用户查看插件目录和每个插件的信息;`init` 可以用户初始化新插件;`gendoc` 更新全部插件的 API 文档;`test` 测试指定的插件。 - -## 3. 插件信息和文档 - -输入 `kcl-plugin info hello` 查看 `hello` 插件信息: - -```shell -$ kcl-plugin info hello -{ - "name": "hello", - "describe": "hello doc", - "long_describe": "long describe", - "version": "0.0.1", - "method": { - "add": "add two numbers, and return result", - "foo": "no doc", - "list_append": "no doc", - "say_hello": "no doc", - "tolower": "no doc", - "update_dict": "no doc" - } -} -``` - -插件的信息主要包含插件的名字和版本信息,插件提供的函数信息。该信息和插件目录中自动生成的 `api.md` 文件是一致的(插件 API 变化时通过 `kcl-plugin gendoc` 为全部的插件重新生成 `api.md` 文件)。 - -## 4. 插件的目录结构 - -插件的目录结构如下(将其中的 `/Users/kcl_user` 替换成本地的 `$HOME` 路径): - -```shell -$ tree /Users/kcl_user/.kcl/plugins/ -/Users/kcl_user/.kcl/plugins/ -├── _examples -├── _test -└── hello - ├── api.md - ├── plugin.py - └── plugin_test.py -$ -``` - -其中 `_examples` 目录下是插件的示例代码,`_test` 目录下是插件的 KCL 测试代码,其他以字母开头的目录是普通的插件(目录中同时包含 `plugin.py` 和 `plugin_test.py` 文件)。 - -KCL 的插件是有一个独立的纯 Python 代码文件实现,并且插件相互之间不能直接调用。插件的内容如下: - -```shell -$ cat ./hello/plugin.py -# Copyright 2020 The KCL Authors. All rights reserved. -INFO = { - 'name': 'hello', - 'describe': 'hello doc', - 'long_describe': 'long describe', - 'version': '0.0.1', -} -def add(a: int, b: int) -> int: - """add two numbers, and return result""" - return a + b -... -``` - -其中 `INFO` 指明了插件的名字、概要说明、详细说明和版本信息。而所有名字以字母开头的函数是插件给 KCL 提供的函数,因此 KCL 中可以直接调用 `add` 函数。 - -## 5. 创建一个插件 - -通过 `kcl-plugin init` 命令可以创建一个插件示例: - -``` -$ kcl-plugin init hi -$ kcl-plugin list -hello: hello doc - 0.0.1 -hi: hi doc - 0.0.1 -``` - -`kcl-plugin init` 命令会以内置的模板构造一个新的插件,然后通过 `kcl-plugin list` 命令可以查看到新创建的插件。 - -## 6. 插件的删除 - -KCL 插件在 KCL 的 `plugins` 子目录(通常安装在 `$HOME/.kcl/plugins` 目录)。 -可以通过命令 `kcl-plugin info` 查询插件安装目录。 - -```shell -$ kcl-plugin info -/Users/kcl_user/.kcl/plugins/ -$ tree /Users/kcl_user/.kcl/plugins/ -/Users/kcl_user/.kcl/plugins/ -├── _examples -├── _test -└── hello -- 删除这个目录就可以删除 hello plugin - ├── api.md - ├── plugin.py - └── plugin_test.py -$ -``` - -## 7. 插件的测试 - -插件是独立的纯 Python 文件实现,插件目录下有个 `plugin_test.py` 文件是插件的单元测试文件(基于 pytest 测试框架)。此外在 `_test` 目录下放置的是 KCL 文件的插件集成测试。`plugin_test.py` 单元测试是必须的,`_test` 目录下的 KCL 集成测试可以根据情况添加。 - -可以通过 `kcl-plugin test` 执行插件的单元测试: - -```shell -$ kcl-plugin test hello -============================= test session starts ============================== -platform darwin -- Python 3.7.6+, pytest-5.3.5, py-1.9.0, pluggy-0.13.1 -rootdir: /Users/kcl_user -collected 5 items -.kcl/plugins/hello/plugin_test.py ..... [100%] -============================== 5 passed in 0.03s =============================== -$ -``` - -集成测试可以通过在 `_test` 目录下执行 `python3 -m pytest` 命令进行测试。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/xlang-api/rest-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/xlang-api/rest-api.md deleted file mode 100644 index 74a9bf4c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/xlang-api/rest-api.md +++ /dev/null @@ -1,455 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Rest API - -## 1. 启动 REST 服务 - -通过以下方式可以启动 RestAPI 服务: - -```shell -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -或者 - -```shell -go install kcl-lang.io/kcl-go/cmds/kcl-go@main -kcl-go rest-server -``` - -然后可以通过 POST 协议请求服务: - -```shell -curl -X POST http://127.0.0.1:2021/api:protorpc/BuiltinService.Ping --data '{}' -``` - -期望输出为 - -```shell -{ - "error": "", - "result": {} -} -``` - -其中 POST 请求和返回的 JSON 数据和 Protobuf 定义的结构保持一致。 - -## 2. `BuiltinService` 服务 - -其中 `/api:protorpc/BuiltinService.Ping` 路径表示 `BuiltinService` 服务的 `Ping` 方法。 - -完整的 `BuiltinService` 由 Protobuf 定义: - -```protobuf -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} -``` - -其中 `Ping` 方法可以验证服务是否正常,`ListMethod` 方法可以查询提供的全部服务和函数列表。 - -## 3. `KclvmService` 服务 - -`KclvmService` 服务是和 KCL 功能相关的服务。用法和 `BuiltinService` 服务一样。 - -比如有以下的 `Person` 结构定义: - -```python -schema Person: - key: str - - check: - "value" in key # 'key' is required and 'key' must contain "value" -``` - -然后希望通过 `Person` 来校验以下的 JSON 数据: - -```json -{ "key": "value" } -``` - -可以通过 `KclvmService` 服务的 `ValidateCode` 方法完成。参考 `ValidateCode` 方法的 `ValidateCode_Args` 参数结构: - -```protobuf -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} -``` - -根据 `ValidateCode_Args` 参数结构构造 POST 请求需要的 JSON 数据,其中包含 `Person` 定义和要校验的 JSON 数据: - -```json -{ - "code": "\nschema Person:\n key: str\n\n check:\n \"value\" in key # 'key' is required and 'key' must contain \"value\"\n", - "data": "{\"key\": \"value\"}" -} -``` - -将该 JSON 数据保存到 `vet-hello.json` 文件,然后通过以下命令进行校验: - -```shell -curl -X POST \ - http://127.0.0.1:2021/api:protorpc/KclvmService.ValidateCode \ - -H "accept: application/json" \ - --data @./vet-hello.json -``` - -如果看到输出 - -```json -{ - "error": "", - "result": { - "success": true - } -} -``` - -说明校验成功。 - -## 4. 完整的 Protobuf 服务定义 - -跨语言的 API 通过 Protobuf 定义([https://github.com/kcl-lang/kcl-go/blob/main/pkg/spec/gpyrpc/gpyrpc.proto](https://github.com/kcl-lang/kcl-go/blob/main/pkg/spec/gpyrpc/gpyrpc.proto)): - -```protobuf -// Copyright 2023 The KCL Authors. All rights reserved. -// -// This file defines the request parameters and return structure of the KCL RPC server. -// We can use the following command to start a KCL RPC server. - -syntax = "proto3"; - -package gpyrpc; - -import "google/protobuf/any.proto"; -import "google/protobuf/descriptor.proto"; - -// ---------------------------------------------------------------------------- - -// kcl main.k -D name=value -message CmdArgSpec { - string name = 1; - string value = 2; -} - -// kcl main.k -O pkgpath:path.to.field=field_value -message CmdOverrideSpec { - string pkgpath = 1; - string field_path = 2; - string field_value = 3; - string action = 4; -} - -// ---------------------------------------------------------------------------- -// gpyrpc request/response/error types -// ---------------------------------------------------------------------------- - -message RestResponse { - google.protobuf.Any result = 1; - string error = 2; - KclError kcl_err = 3; -} - -message KclError { - string ewcode = 1; // See kclvm/kcl/error/kcl_err_msg.py - string name = 2; - string msg = 3; - repeated KclErrorInfo error_infos = 4; -} - -message KclErrorInfo { - string err_level = 1; - string arg_msg = 2; - string filename = 3; - string src_code = 4; - string line_no = 5; - string col_no = 6; -} - -// ---------------------------------------------------------------------------- -// service requset/response -// ---------------------------------------------------------------------------- - -// gpyrpc.BuiltinService -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -// gpyrpc.KclvmService -service KclvmService { - rpc Ping(Ping_Args) returns(Ping_Result); - - rpc ExecProgram(ExecProgram_Args) returns(ExecProgram_Result); - - rpc FormatCode(FormatCode_Args) returns(FormatCode_Result); - rpc FormatPath(FormatPath_Args) returns(FormatPath_Result); - rpc LintPath(LintPath_Args) returns(LintPath_Result); - rpc OverrideFile(OverrideFile_Args) returns (OverrideFile_Result); - - rpc GetSchemaType(GetSchemaType_Args) returns(GetSchemaType_Result); - rpc GetSchemaTypeMapping(GetSchemaTypeMapping_Args) returns(GetSchemaTypeMapping_Result); - rpc ValidateCode(ValidateCode_Args) returns(ValidateCode_Result); - - rpc ListDepFiles(ListDepFiles_Args) returns(ListDepFiles_Result); - rpc LoadSettingsFiles(LoadSettingsFiles_Args) returns(LoadSettingsFiles_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} - -message ParseFile_AST_Args { - string filename = 1; - string source_code = 2; -} -message ParseFile_AST_Result { - string ast_json = 1; // json value - KclError kcl_err = 2; -} - -message ParseProgram_AST_Args { - repeated string k_filename_list = 1; -} -message ParseProgram_AST_Result { - string ast_json = 1; // json value - KclError kcl_err = 2; -} - -message ExecProgram_Args { - string work_dir = 1; - - repeated string k_filename_list = 2; - repeated string k_code_list = 3; - - repeated CmdArgSpec args = 4; - repeated CmdOverrideSpec overrides = 5; - - bool disable_yaml_result = 6; - - bool print_override_ast = 7; - - // -r --strict-range-check - bool strict_range_check = 8; - - // -n --disable-none - bool disable_none = 9; - // -v --verbose - int32 verbose = 10; - - // -d --debug - int32 debug = 11; - - // yaml/json: sort keys - bool sort_keys = 12; - // include schema type path in JSON/YAML result - bool include_schema_type_path = 13; -} -message ExecProgram_Result { - string json_result = 1; - string yaml_result = 2; - - string escaped_time = 101; -} - -message ResetPlugin_Args { - string plugin_root = 1; -} -message ResetPlugin_Result { - // empty -} - -message FormatCode_Args { - string source = 1; -} - -message FormatCode_Result { - bytes formatted = 1; -} - -message FormatPath_Args { - string path = 1; -} - -message FormatPath_Result { - repeated string changed_paths = 1; -} - -message LintPath_Args { - repeated string paths = 1; -} - -message LintPath_Result { - repeated string results = 1; -} - -message OverrideFile_Args { - string file = 1; - repeated string specs = 2; - repeated string import_paths = 3; -} - -message OverrideFile_Result { - bool result = 1; -} - -message EvalCode_Args { - string code = 1; -} -message EvalCode_Result { - string json_result = 2; -} - -message ResolveCode_Args { - string code = 1; -} - -message ResolveCode_Result { - bool success = 1; -} - -message GetSchemaType_Args { - string file = 1; - string code = 2; - string schema_name = 3; -} -message GetSchemaType_Result { - repeated KclType schema_type_list = 1; -} - -message GetSchemaTypeMapping_Args { - string file = 1; - string code = 2; - string schema_name = 3; -} -message GetSchemaTypeMapping_Result { - map schema_type_mapping = 1; -} - -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} - -message ValidateCode_Result { - bool success = 1; - string err_message = 2; -} - -message Position { - int64 line = 1; - int64 column = 2; - string filename = 3; -} - -message ListDepFiles_Args { - string work_dir = 1; - bool use_abs_path = 2; - bool include_all = 3; - bool use_fast_parser = 4; -} - -message ListDepFiles_Result { - string pkgroot = 1; - string pkgpath = 2; - repeated string files = 3; -} - -// --------------------------------------------------------------------------------- -// LoadSettingsFiles API -// Input work dir and setting files and return the merged kcl singleton config. -// --------------------------------------------------------------------------------- - -message LoadSettingsFiles_Args { - string work_dir = 1; - repeated string files = 2; -} - -message LoadSettingsFiles_Result { - CliConfig kcl_cli_configs = 1; - repeated KeyValuePair kcl_options = 2; -} - -message CliConfig { - repeated string files = 1; - string output = 2; - repeated string overrides = 3; - repeated string path_selector = 4; - bool strict_range_check = 5; - bool disable_none = 6; - int64 verbose = 7; - bool debug = 8; -} - -message KeyValuePair { - string key = 1; - string value = 2; -} - -// ---------------------------------------------------------------------------- -// JSON Schema Lit -// ---------------------------------------------------------------------------- - -message KclType { - string type = 1; // schema, dict, list, str, int, float, bool, any, union, number_multiplier - repeated KclType union_types = 2 ; // union types - string default = 3; // default value - - string schema_name = 4; // schema name - string schema_doc = 5; // schema doc - map properties = 6; // schema properties - repeated string required = 7; // required schema properties, [property_name1, property_name2] - - KclType key = 8; // dict key type - KclType item = 9; // dict/list item type - - int32 line = 10; - - repeated Decorator decorators = 11; // schema decorators -} - -message Decorator { - string name = 1; - repeated string arguments = 2; - map keywords = 3; -} - -// ---------------------------------------------------------------------------- -// END -// ---------------------------------------------------------------------------- -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/Ide/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/Ide/index.md deleted file mode 100644 index 2ba6e5b4..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/Ide/index.md +++ /dev/null @@ -1,6 +0,0 @@ -# IDE - -我们为 KCL 提供了两种简单的 IDE 插件。您可以通过以下链接获得更多帮助信息: - -- IntelliJ 插件: https://github.com/kcl-lang/intellij-kcl -- VSCode 插件: https://github.com/kcl-lang/vscode-kcl diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/Ide/intellij.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/Ide/intellij.md deleted file mode 100644 index be637514..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/Ide/intellij.md +++ /dev/null @@ -1,3 +0,0 @@ -# IntelliJ IDEA - -- IntelliJ Plugin: https://github.com/kcl-lang/intellij-kcl diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/Ide/vs-code.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/Ide/vs-code.md deleted file mode 100644 index d3db7e01..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/Ide/vs-code.md +++ /dev/null @@ -1,54 +0,0 @@ -# Visual Studio Code KCL 插件 - -## 快速开始 - -- 1. [安装 KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) 并检查 `kcl` 和 `kcl-language-server` 命令在您的 PATH 中: - - ```bash - which kcl - which kcl-language-server - ``` - -- 2. 安装 [VS Code KCL 插件](https://marketplace.visualstudio.com/items?itemName=kcl.kcl-vscode-extension). 需要您的 VS Code 版本大于 1.50+ -- 3. 重新打开 VS Code 并创建一个 KCL 文件验证 IDE 插件功能 - -## 特性 - -此扩展提供了一些 KCL 编码帮助,包括以下功能: - -- **语法高亮** - ![Highlight](/img/docs/tools/Ide/vs-code/Highlight.png) -- **跳转** - ![Goto Definition](/img/docs/tools/Ide/vs-code/GotoDef.gif) -- **补全** - ![Completion](/img/docs/tools/Ide/vs-code/Completion.gif) -- **大纲** - ![Outline](/img/docs/tools/Ide/vs-code/Outline.gif) -- **悬停** - ![Hover](/img/docs/tools/Ide/vs-code/Hover.gif) -- **诊断** - ![Diagnostics](/img/docs/tools/Ide/vs-code/Diagnostics.gif) - -> 提示:您可以通过安装 [Error Lens 插件](https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens) 来增强诊断效果 - -其他一些有用的功能,如代码重构和智能感知等正在开发中。 - -## 最小依赖 - -我们建议您使用最新版本的 KCL,但此扩展所需的 KCL 最低版本为 v0.4.6。如果您使用的是更早期版本,则此扩展可能无法正常工作。 - -## 已知问题 - -[详见](https://github.com/kcl-lang/kcl/issues/524) - -## 寻求帮助 - -如果扩展没有如您所期望的那样工作,请通过[社区](https://kcl-lang.io/docs/community/intro/support)与我们联系和寻求帮助。 - -## 参与贡献 - -目前 VS Code KCL 插件处于早期版本,我们正在积极改进 VS Code KCL 插件体验,欢迎参考[贡献指南](https://kcl-lang.io/docs/community/contribute) 一起共建! - -## 许可 - -Apache License 2.0 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/docgen.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/docgen.md deleted file mode 100644 index 37b660ed..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/docgen.md +++ /dev/null @@ -1,313 +0,0 @@ ---- -sidebar_position: 5 ---- - -# 文档生成工具 - -KCL 命令行工具支持从 KCL 源码中一键提取模型文档,并支持丰富的输出格式:JSON,YAML 和 Markdown 等。本文介绍 KCL 语言的文档规范,举例说明如何使用 KCL 文档生成工具提取文档,并展示新增本地化语言文档的流程。 - -## 1. KCL 语言的文档规范 - -KCL文件的文档主要包含如下两个部分: - -- 当前 KCL Moudle 的文档:对当前 KCL 文件的说明 -- KCL 文件内包含的所有 Schema 的文档:对当前 Schema 的说明,其中包含 Schema 描述、Schema 各属性的描述、Examples 三部分,具体格式如下: - -1. Schema 描述 - -```python -"""这是Schema一个简短的描述信息 -""" -``` - -2. Schema 各属性的描述:包含属性描述、属性类型、默认值、是否可选 - -```python -""" -Attributes ----------- -x : type, default is a, optional. - Description of parameter `x`. -y : type, default is b, required. - Description of parameter `y`. -""" -``` - -其中,使用 `----------` 表示 `Attributes` 为一个标题(`-` 符号长度与标题长度保持一致),属性名称与属性类型用冒号 `:` 分隔,属性的说明另起一行并增加缩进进行书写。属性的默认值说明跟在属性类型之后使用逗号 `,` 分隔,书写为 `default is {默认值}` 形式,此外需要说明属性是否为可选/必选,对于可选属性在默认值之后书写 `optional`,对于必选属性在默认值之后书写 `required`。 - -3. Examples - -```python -""" -Examples --------- -val = Schema { - name = "Alice" - age = 18 -} -""" -``` - -此外,KCL 文档字符串语法应采用 [re-structured text (reST)](https://docutils.sourceforge.io/rst.html) 语法子集,并使用 [Sphinx](https://www.sphinx-doc.org/en/master/) 渲染呈现。 - -## 2. 从 KCL 源码生成文档 - -使用 kcl-doc generate 命令,从用户指定的文件或目录中提取文档,并输出到指定目录。 - -1. 参数说明 - -``` -usage: kcl-doc generate [-h] [--format YAML] [-o OUTPUT] [--r] - [--i18n-locale LOCALE] [--repo-url REPO_URL] - [files [files ...]] - -positional arguments: - files KCL file paths. If there's more than one files to - generate, separate them by space - -optional arguments: - -h, --help show this help message and exit - --format YAML Doc file format, support YAML, JSON and MARKDOWN. - Defaults to MARKDOWN - -o OUTPUT, --output-path OUTPUT - Specify the output directory. Defaults to ./kcl_doc - --r, -R, --recursive Search directory recursively - --i18n-locale LOCALE I18n locale, e.g.: zh, zh_cn, en, en_AS. Defaults to - en - --repo-url REPO_URL The source code repository url. It will be displayed in - the generated doc to link to the source code. -``` - -2. 从指定的一个或多个文件中提取文档,并输出到指定目录 - -```text -kcl-doc generate your_config.k your_another_config.k -o your_docs_output_dir -``` - -3. 从指定目录内,递归地查找 KCL 源码文件,并提取文档 - -```text -kcl-doc generate your_config_dir -r -o your_docs_output_dir -``` - -4. 在生成文档时,指定源码仓库地址。一经指定,生成的文档中将包含指向源码文件的链接 - -```text -kcl-doc generate your_config.k -o your_docs_output_dir --repo-url https://url/to/source_code -``` - -## 3. 新增本地化语言的文档 - -如前所示,默认情况下,文档生成工具提取的文档以源码 docstring 的内容为准,因而文档的语言随 docstring 编写语言而定。如果需要为源文件新增本地化语言的文档,则可以遵循按如下步骤: - -1. 初始化 i18n 配置文件。该步骤基于指定的 KCL 源码文件,生成相应的 i18n 配置文件,文件格式可选 JSON/YAML,默认为 YAML. 输出的配置文件名称将以指定的目标本地化方言结尾 - -```text -kcl-doc init-i18n your_config.k --format JSON --i18n-locale your_target_locale -``` - -2. 手动修改上述生成的 i18n 配置文件,使用目标语言修改配置中的 doc 字段 - -3. 基于修改后的 i18n 配置,生成本地化语言的文档。工具将查找指定目标语言的 i18n 配置文件,并转化为最终的文档 - -```text -kcl-doc generate your_config_dir --i18n-locale your_target_locale --format Markdown -``` - -接下来,通过一个小例子演示新增本地化语言文档的过程。 - -3.1 准备 KCL 源码文件,例如 server.k: - - ```python - schema Server: - """Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - - Attributes - ---------- - workloadType : str, default is "Deployment", required - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - name : str, required - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - labels : {str:str}, optional - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - - Examples - ---------------------- - myCustomApp = AppConfiguration { - name = "componentName" - } - """ - - workloadType: str = "Deployment" - name: str - labels?: {str: str} - ``` - -3.2 从 server.k 得到初始化的 i18n 配置文件,例如希望为其增加中文文档,指定生成的配置文件格式为 YAML - - ```text - kcl-doc init-i18n server.k --format YAML --i18n-locale zh_cn - ``` - - 该命令将在当前目录下创建 kcl_doc 目录,并生成 i18n 配置文件 kcl_doc/i18n_server_zh_cn.yaml,其内容如下: - - ```yaml - name: server - relative_path: ./server.k - schemas: - - name: Server - doc: | - Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - attributes: - - name: workloadType - doc: | - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - default_value: '"Deployment"' - is_optional: false - - name: name - doc: | - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: false - default_value: '' - - name: labels - doc: | - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - type: - type_str: '{str: str}' - type_category: DICT - dict_type: - key_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - value_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: true - default_value: '' - examples: | - myCustomApp = AppConfiguration { - name = "componentName" - } - doc: '' - source_code_url: '' - ``` - -3.3 修改初始化得到的 i18n 配置,将其中的 doc 字段修改为中文的描述,修改后的配置如下: - - ```yaml - name: server - relative_path: ./server.k - schemas: - - name: Server - doc: | - Server 模型定义了采用 Kubernetes 最佳实践的持续运行的服务的通用配置接口 - attributes: - - name: workloadType - doc: | - workloadType 属性定义了服务的类型,是服务级别的属性。合法的取值有:Deployment, CafeDeployment. - 另请查看:k8s/core/v1/workload_metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - default_value: '"Deployment"' - is_optional: false - - name: name - doc: | - name 为服务的名称,是服务级别的属性。 - 另请查看:k8s/core/v1/metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: false - default_value: '' - - name: labels - doc: | - labels 为服务的标签,是服务级别的属性。 - 另请查看:k8s/core/v1/metadata.k. - type: - type_str: '{str: str}' - type_category: DICT - dict_type: - key_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - value_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: true - default_value: '' - examples: | - myCustomApp = AppConfiguration { - name = "componentName" - } - doc: '' - source_code_url: '' - ``` - -3.4 基于修改后的 i18n 配置,生成本地化语言的文档,执行如下命令,将输出中文的文档 kcl_doc/doc_server_zh_cn.md,命令及生成的文档内容如下: - - ```text - kcl-doc generate server.k --i18n-locale zh_cn --format Markdown - ``` - - ~~~markdown - # server - ## Schema Server - Server 模型定义了采用 Kubernetes 最佳实践的持续运行的服务的通用配置接口 - - ### Attributes - |Name and Description|Type|Default Value|Required| - |--------------------|----|-------------|--------| - |**workloadType**
workloadType 属性定义了服务的类型,是服务级别的属性。合法的取值有:Deployment, CafeDeployment.
另请查看:k8s/core/v1/workload_metadata.k.|str|"Deployment"|**required**| - |**name**
name 为服务的名称,是服务级别的属性。
另请查看:k8s/core/v1/metadata.k.|str|Undefined|**required**| - |**labels**
labels 为服务的标签,是服务级别的属性。
另请查看:k8s/core/v1/metadata.k.|{str: str}|Undefined|optional| - ### Examples - ``` - myCustomApp = AppConfiguration { - name = "componentName" - } - ``` - - - - ~~~ - -## 4. 附录 - -### 1. 常见的 reST 概念 - -对于 reST 格式的文档,段落和缩进很重要,新段落用空白行标记,缩进即为表示输出中的缩进。可以使用如下方式表示字体样式: - -- \*斜体\* -- \*\*粗体\*\* -- \`\`等宽字体\`\` - -参考 [reST 文档](https://docutils.sourceforge.io/rst.html)获得更多帮助。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/fmt.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/fmt.md deleted file mode 100644 index 11199215..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/fmt.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -sidebar_position: 2 ---- - -# 格式化代码 - -KCL 支持通过内置的命令行工具一键格式化多个 KCL 文件文档。本文展示 KCL 编码风格和 KCL 格式化工具的使用方式。 - -## KCL 编码风格 - -KCL 格式化对文件的修改样式具体见 KCL 编码风格:[Style Guide for KCL Code](/docs/reference/lang/spec/codestyle) - -## 使用方式 - -- 单文件格式化 - -```text -kcl-fmt your_config.k -``` - -- 文件夹内多文件格式化 - -```text -kcl-fmt your_config_path -R -``` - -- 命令行参数 - - `-R|--recursive` 设置是否递归遍历子文件夹 - - `-w|--fmt-output` 设置是否输出到标准输出流,不加 `-w` 表示原地格式化 KCL 文件 - -## 格式化文件效果展示 - -- 格式化前 - -```py -import math -mixin DeploymentMixin: - service:str ="my-service" -schema DeploymentBase: - name: str - image : str -schema Deployment[replicas] ( DeploymentBase ) : - mixin[DeploymentMixin] - replicas : int = replicas - command: [str ] - labels: {str: str} -deploy = Deployment(replicas = 3){} -``` - -- 格式化后 - -```py -import math - -mixin DeploymentMixin: - service: str = "my-service" - -schema DeploymentBase: - name: str - image: str - -schema Deployment[replicas](DeploymentBase): - mixin [DeploymentMixin] - replicas: int = replicas - command: [str] - labels: {str:str} - -deploy = Deployment(replicas=3) {} - -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/index.md deleted file mode 100644 index 51f69ee6..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# KCL 语言工具 - -KCL 不仅提供了 kcl 命令编译和执行配置程序,还提供了 fmt、lint、test、vet、docgen 等配套的辅助工具。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/lint.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/lint.md deleted file mode 100644 index 7a66d3b3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/lint.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Lint 检查代码风格 - -KCL 支持通过内置的命令行工具对 KCL 代码进行检查,并支持多种输出格式。本文档展示 KCL Lint 工具的使用方式。 - -## 示例 - -### 工程结构 - -```text -. -└── Test - └── kcl.mod - └── a.k - └── b.k - └── dir - └── c.k - └── test.k -``` - -`a.k`,`b.k`,`c.k`,`test.k` 为测试的 kcl 文件。 - -命令: - -```shell -kcl-lint your_config.k -``` - -或 - -```shell -kcl-lint your_config_path -``` - -### CLI 参数 - -```shell -USAGE: - kcl-lint [OPTIONS] [--] [input]... - -ARGS: - ... Sets the input file to use - -OPTIONS: - --emit_warning Emit warning message - -h, --help Print help information - -v, --verbose Print test information verbosely - -Y, --setting ... Sets the input file to use -``` - -- input: 需要检查的单个 `.k` 文件路径或路径目录下的所有 `.k` 文件,支持绝对路径或当前目录的相对路径 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/test.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/test.md deleted file mode 100644 index f8707ff9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/test.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 5 ---- - -# 测试工具 - -即将到来! diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/vet.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/vet.md deleted file mode 100644 index 2c70ce91..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/vet.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Validation 校验代码 - -## 简介 - -KCL 支持通过内置的 `kcl-vet` 命令行工具提供了基本的配置数据校验能力,可以编写 KCL schema 对输入的 JSON/YAML 格式文件进行类型以及数值的校验。 - -## 使用方式 - -假设有 data.json 文件,代码如下: - -```json -{ - "name": "Alice", - "age": 18, - "message": "This is Alice", - "data": { - "id": 1, - "value": "value1" - }, - "labels": { - "key": "value" - }, - "hc": [1, 2, 3] -} -``` - -构造 schema.k 校验文件,内容如下: - -```py -schema User: - name: str - age: int - message?: str - data: Data - labels: {str:} - hc: [int] - - check: - age > 10 - -schema Data: - id: int - value: str -``` - -在目录下执行如下命令 - -```shell -$ kcl-vet data.json schema.k -``` - -## 指定校验的 schema - -当校验的 KCL 文件中存在多个 schema 定义时,kcl-vet 工具会默认取第一个 schema 定义进行校验,如果需要指定校验的 schema,可以使用 `-d|--schema` 参数 - -```shell -$ kcl-vet data.json schema.k -d User -``` - -## 命令行参数 - -```shell -$ kcl-vet -h -USAGE: - kcl-vet [OPTIONS] [ARGS] - -ARGS: - Validation data file - KCL file - -OPTIONS: - -d, --schema - Iterate through subdirectories recursively - - --format - Validation data file format, support YAML and JSON, default is JSON - - -h, --help - Print help information - - -n, --attribute_name - The attribute name for the data loading -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/openapi/crd-to-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/openapi/crd-to-kcl.md deleted file mode 100644 index 5b6f070c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/openapi/crd-to-kcl.md +++ /dev/null @@ -1,118 +0,0 @@ -# CRD to KCL - -命令 - -```shell -kcl-openapi generate model --crd -f ${your_CRD.yaml} -t ${the_kcl_files_output_dir} --skip-validation -``` - -# 示例 - -- 输入文件:test_crontab_CRD.yaml: - -```yaml -# Deprecated in v1.16 in favor of apiextensions.k8s.io/v1 -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - # name must match the spec fields below, and be in the form: . - name: crontabs.stable.example.com -spec: - # group name to use for REST API: /apis// - group: stable.example.com - # list of versions supported by this CustomResourceDefinition - versions: - - name: v1 - # Each version can be enabled/disabled by Served flag. - served: true - # One and only one version must be marked as the storage version. - storage: true - # either Namespaced or Cluster - scope: Namespaced - names: - # plural name to be used in the URL: /apis/// - plural: crontabs - # singular name to be used as an alias on the CLI and for display - singular: crontab - # kind is normally the CamelCased singular type. Your resource manifests use this. - kind: CronTab - # shortNames allow shorter string to match your resource on the CLI - shortNames: - - ct - preserveUnknownFields: false - validation: - openAPIV3Schema: - type: object - properties: - spec: - type: object - properties: - cronSpec: - type: string - image: - type: string - replicas: - type: integer -``` - -- 命令 - -```shell -kcl-openapi generate model -f test_crontab_CRD.yaml -t ~/ --skip-validation --crd -``` - -- 输出文件: ~/models/stable_example_com_v1_cron_tab.k - -```python -""" -This file was generated by the KCL auto-gen tool. DO NOT EDIT. -Editing this file might prove futile when you re-run the KCL auto-gen generate command. -""" -import kusion_kubernetes.apimachinery.apis - - -schema CronTab: - """stable example com v1 cron tab - - Attributes - ---------- - apiVersion : str, default is "stable.example.com/v1", required - APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - kind : str, default is "CronTab", required - Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - metadata : apis.ObjectMeta, default is Undefined, optional - metadata - spec : StableExampleComV1CronTabSpec, default is Undefined, optional - spec - """ - - - apiVersion: "stable.example.com/v1" = "stable.example.com/v1" - - kind: "CronTab" = "CronTab" - - metadata?: apis.ObjectMeta - - spec?: StableExampleComV1CronTabSpec - - -schema StableExampleComV1CronTabSpec: - """stable example com v1 cron tab spec - - Attributes - ---------- - cronSpec : str, default is Undefined, optional - cron spec - image : str, default is Undefined, optional - image - replicas : int, default is Undefined, optional - replicas - """ - - - cronSpec?: str - - image?: str - - replicas?: int -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/openapi/openapi-to-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/openapi/openapi-to-kcl.md deleted file mode 100644 index 6d9f8e54..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/openapi/openapi-to-kcl.md +++ /dev/null @@ -1,64 +0,0 @@ -# OpenAPI to KCL - -命令 - -```shell -kcl-openapi generate model -f ${your_open_api_spec.yaml} -t ${the_kcl_files_output_dir} -``` - -示例: - -- 输入文件:test_open_api_spec.yaml: - -```yaml -definitions: - v1.TestInt: - type: object - properties: - name: - type: string - format: int-or-string - required: - - name - x-kcl-type: - import: - package: v1.test_int - alias: test_int - type: TestInt -swagger: "2.0" -info: - title: KCL - version: v0.0.2 -paths: {} -``` - -- 命令: - -```shell -kcl-openapi generate model -f test_open_api_spec.yaml -t ~/ -``` - -- 输出:~/models/v1/test_int.k - -```python -""" -This is the test_int module in v1 package. -This file was generated by the KCL auto-gen tool. DO NOT EDIT. -Editing this file might prove futile when you re-run the KCL auto-gen generate command. -""" - - -schema TestInt: - """v1 test int - - Attributes - ---------- - name : int | str, default is Undefined, required - name - """ - - - name: int | str - - -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/openapi/quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/openapi/quick-start.md deleted file mode 100644 index 3d6a125d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/openapi/quick-start.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 快速开始 - -## 1. 安装 KCLOpenAPI 工具 - -目前有多种安装方式可选: - -- [通过 go install 安装](#11-通过-go-install-安装) -- [通过 curl|sh 安装(仅限 MacOS & Linux)](#12-通过-curlsh-安装(仅限-MacOS--Linux)) -- [下载发布包](#13-下载发布包) - -## 1.1 通过 go install 安装 - -```shell -go install kcl-lang.io/kcl-openapi@latest -``` - -## 1.2 通过 curl|sh 安装(仅限 MacOS & Linux) - -```shell -curl -fsSL https://kcl-lang.io/script/install-kcl-openapi.sh | /bin/bash -``` - -## 1.3 下载发布包 - -```shell -# 1. 下载二进制程序 -# https://github.com/kcl-lang/kcl-openapi/releases - -# 2. 解压发布包,并将命令添加至 PATH -export PATH=":$PATH" -``` - -## 1.4 验证安装结果 - -```shell -➜ kcl-openapi -v -kcl-openapi 0.5.0 -``` - -## 2. 生成 KCL 文件 - -- [将 OpenAPI 描述文件转换为 KCL](../openapi/openapi-to-kcl.md) -- [将 Kubernetes CRD 转换为 KCL](../openapi/crd-to-kcl.md) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/concepts/concepts.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/concepts/concepts.md deleted file mode 100644 index e2034db2..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/concepts/concepts.md +++ /dev/null @@ -1,3 +0,0 @@ -# 核心概念 - -学习更多关于 KCL 核心概念。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/getting-started/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/getting-started/index.md deleted file mode 100644 index 5d58acf6..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/getting-started/index.md +++ /dev/null @@ -1 +0,0 @@ -# 快速开始 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/getting-started/install.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/getting-started/install.md deleted file mode 100644 index 74510232..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/getting-started/install.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -sidebar_position: 2 ---- - -# 安装 - -## 1. 安装 KCL - -### 二进制下载 - -KCL 的每个版本都包含各种操作系统和体系结构。这些二进制版本可以从 [Github](https://github.com/kcl-lang/kcl/releases/) 或者 [Gitee](https://gitee.com/kusionstack/kcl/releases) 手动下载并安装,下载完成后将 `{install-location}/kclvm/bin` 添加到环境变量 PATH 中。 - -> ⚠️ 如果您不能成功访问 Github, 也可以访问 Gitee 获得二进制进行安装 - -#### MacOS & Linux - -```bash -export PATH=$PATH:{install-location}/kclvm/bin -``` - -#### Windows - -```powershell -$env:PATH += ";{install-location}\kclvm\bin;" -``` - -### 使用脚本安装最新版本 - -#### MacOS - -将 KCL darwin 最新版本安装到 /usr/local/kclvm/bin - -```bash -curl -fsSL https://kcl-lang.io/script/install.sh | /bin/bash -``` - -#### Linux - -将 KCL linux 最新版本安装到 /usr/local/kclvm/bin - -```bash -wget -q https://kcl-lang.io/script/install.sh -O - | /bin/bash -``` - -#### Windows - -将 KCL windows 最新版本安装到 $Env:SystemDrive\kclvm\bin,并将该目录添加到用户 PATH 环境变量中。 - -```bash -powershell -Command "iwr -useb https://kcl-lang.io/script/install.ps1 | iex" -``` - -### Homebrew (MacOS) - -- 安装 - -```bash -brew install kcl-lang/tap/kcl -``` - -- 升级 - -```bash -brew upgrade kcl-lang/tap/kcl -``` - -- 卸载 - -```bash -brew uninstall kcl-lang/tap/kcl -``` - -### Scoop (Windows) - -首先安装 [Scoop](https://scoop.sh/), 然后通过如下命令安装 `kcl`: - -```bash -scoop bucket add kcl-lang https://github.com/kcl-lang/scoop-bucket.git -scoop install kcl-lang/kcl -``` - -### 使用 Go 安装 - -通过 `Go` 命令安装 (Go 要求 1.18+) - -```bash -go install kcl-lang.io/kcl-go/cmds/kcl-go@main -``` - -添加一个 kcl 命令的别名 (可选) - -```bash -alias kcl='kcl-go run' -``` - -> 注意:`kcl-go` 并不依赖是否安装了 `kcl`,但如果 PATH 中存在 `kcl`,`kcl-go` 将优先使用 `PATH` 中的 `kcl`。 - -### 使用 Docker 镜像安装 - -- 基本命令 - -```bash -docker run --rm -it kcllang/kcl -``` - -- 更新镜像 - -```bash -docker pull kcllang/kcl -``` - -### 注意 - -可以执行运行如下命令确保 KCL 已经正确安装 - -```bash -kcl -V -``` - -如果安装成功,输出可能为如下形式 (不同版本结果可能稍微不同): - -```bash -Version: {kcl version} -Platform: {your platform} -GitCommit: {git commit} -``` - -对于上述所有安装方式, 如果您想使用 [KCL Python 插件](/docs/reference/plugin/overview), 需要确保您已经安装了 Python 3.7+ 并将 python3 命令添加到您的 PATH 中。 - -## 2. 安装 KCL IDE 插件 - -### VS Code - -KCL 为 VS Code 本地版本提供了插件支持,并提供了高亮、自动补全、跳转、悬停、大纲等功能。您可以[点击这里](/docs/tools/Ide/vs-code)进行安装。 - -![Completion](/img/docs/tools/Ide/vs-code/Completion.gif) - -### IntelliJ IDEA - -从[这里](https://github.com/kcl-lang/intellij-kcl/releases)下载发行版,在 IntelliJ IDEA 中,点击 Preference -> plugins -> install Plugin from Disk... -> 选择 kcl-idea-plugin zip -> 重启 IDE。此插件需要 IntelliJ IDEA 2020.2+ diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/getting-started/intro.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/getting-started/intro.md deleted file mode 100644 index aaa364e3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/getting-started/intro.md +++ /dev/null @@ -1,199 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 简介 - -## KCL 是什么? - -[KCL](https://github.com/kcl-lang/kcl) 是一个开源的基于约束的记录及函数语言。KCL 通过成熟的编程语言技术和实践来改进对大量繁杂配置比如云原生 Kubernetes 配置场景的编写,致力于构建围绕配置的更好的模块化、扩展性和稳定性,更简单的逻辑编写,以及更简单的自动化和生态工具集成。 - -## 为什么使用 KCL? - -KCL 期望通过更现代化的声明式配置语言在 Kubernetes 资源管理解决如下问题: - -- 通过**代码抽象**等手段屏蔽基础设施和平台的细节,降低研发者负担 -- **编辑**和**校验**已有的存量配置或模版 -- 通过配置语言无副作用地管理跨团队的大规模配置数据,提升团队协作效率 - - 用**生产级高性能编程语言**以**编写代码**的方式提升配置的灵活度,比如条件语句、循环、函数、包管理等特性提升配置重用的能力 - - 在代码层面提升**配置语义验证**的能力,比如字段可选/必选、类型、范围等配置检查能力 - - 提供**配置分块编写、组合和抽象的能力**,比如结构定义、结构继承、约束定义等能力 - - 通过**多语言 SDK**,**KCL 语言插件**等手段提升其**自动化**集成能力 - -您可以将 KCL 用于 - -- 生成静态配置数据如 JSON, YAML 等 -- 使用 schema 对配置数据进行建模并减少配置数据中的样板文件 -- 为配置数据定义带有规则约束的 schema 并对数据进行自动验证 -- 无副作用地组织、简化、统一和管理庞大的配置 -- 通过分块编写配置数据可扩展地管理庞大的配置 -- 与 [KusionStack](https://kusionstack.io) 一起,用作平台工程语言来交付现代应用程序 - -除了语言自身,KCL 还提供了许多额外的工具如格式化,测试、文档、包管理等工具帮助您使用、理解和检查编写的配置或策略;通过 VS Code 等 IDE 插件和 Playground 降低配置编写、分享的成本;通过 Rust, Go, 和 Python 多语言 SDK 自动化地管理和执行配置。 - -![](/img/docs/user_docs/intro/kcl-overview.png) - -此外,KCL 是一种现代高级领域编程语言,并且它是一种编译静态的强类型语言。KCL 为开发人员提供了通过记录和函数语言设计将**配置(config)**、**建模抽象(schema)**、**逻辑(lambda)**和**策略(rule)**作为核心能力。 - -![](/img/docs/user_docs/intro/kcl-concepts.png) - -KCL 试图提供独立于运行时的可编程性,不在本地提供线程和IO等系统功能,但支持云本地操作场景的功能,并试图为解决领域问题并提供稳定、安全、低噪声、低副作用、易于自动化和易于管理的编程支持。 - -总之,KCL 具备如下特点: - -- **简单易用**:源于 Python、Golang 等高级语言,采纳函数式编程语言特性,低副作用 -- **设计良好**:独立的 Spec 驱动的语法、语义、运行时和系统库设计 -- **快速建模**:以 [Schema](https://kcl-lang.io/docs/reference/lang/tour#schema) 为中心的配置类型及模块化抽象 -- **功能完备**:基于 [Config](https://kcl-lang.io/docs/reference/lang/tour#config-operations)、[Schema](https://kcl-lang.io/docs/reference/lang/tour#schema)、[Lambda](https://kcl-lang.io/docs/reference/lang/tour#function)、[Rule](https://kcl-lang.io/docs/reference/lang/tour#rule) 的配置及其模型、逻辑和策略编写 -- **可靠稳定**:依赖[静态类型系统](https://kcl-lang.io/docs/reference/lang/tour/#type-system)、[约束](https://kcl-lang.io/docs/reference/lang/tour/#validation)和[自定义规则](https://kcl-lang.io/docs/reference/lang/tour#rule)的配置稳定性 -- **强可扩展**:通过独立配置块[自动合并机制](https://kcl-lang.io/docs/reference/lang/tour/#-operators-1)保证配置编写的高可扩展性 -- **易自动化**:[CRUD APIs](https://kcl-lang.io/docs/reference/lang/tour/#kcl-cli-variable-override),[多语言 SDK](https://kcl-lang.io/docs/reference/xlang-api/overview),[语言插件](https://github.com/kcl-lang/kcl-plugin) 构成的梯度自动化方案 -- **极致性能**:使用 Rust & C,[LLVM](https://llvm.org/) 实现,支持编译到本地代码和 [WASM](https://webassembly.org/) 的高性能编译时和运行时 -- **API 亲和**:原生支持 [OpenAPI](https://github.com/kcl-lang/kcl-openapi)、 Kubernetes CRD, Kubernetes YAML 等 API 生态规范 -- **开发友好**:[语言工具](https://kcl-lang.io/docs/tools/cli/kcl/) (Format,Lint,Test,Vet,Doc 等)、 [IDE 插件](https://github.com/kcl-lang/vscode-kcl) 构建良好的研发体验 -- **安全可控**:面向领域,不原生提供线程、IO 等系统级功能,低噪音,低安全风险,易维护,易治理 -- **多语言 SDK**:[Go](https://kcl-lang.io/docs/reference/xlang-api/go-api),[Python](https://kcl-lang.io/docs/reference/xlang-api/python-api),[Java](https://kcl-lang.io/docs/reference/xlang-api/java-api) 和 [REST API](https://kcl-lang.io/docs/reference/xlang-api/rest-api) 满足不同场景和应用使用需求 -- **生态集成**:通过 [Kustomize KCL 插件](https://github.com/kcl-lang/kustomize-kcl), [Helm KCL 插件](https://github.com/kcl-lang/helm-kcl) 或者 [KPT KCL SDK](https://github.com/kcl-lang/kpt-kcl-sdk) 直接编辑或校验资源 -- **生产可用**:广泛应用在蚂蚁集团平台工程及自动化的生产环境实践中 - -虽然 KCL 不是通用语言,但它有相应的应用场景。开发人员可以通过 KCL 编写**config**、**schema**、**function**和**rule**,其中 config 用于定义数据,schema 用于描述数据的模型定义,rule 用于验证数据,schema 和 rule 还可以组合使用模型和约束来充分描述数据。此外,还可以使用 KCL 中的 lambda 纯函数来组织数据代码,封装通用代码,并在需要时直接调用它。 - -KCL 配置通常遵循如下模式: - -$$ -k = (T) v -$$ - -其中,$k$ 是属性名称,$v$ 是属性值,$T$ 是类型注解。由于 KCL 具有类型推导的能力,因此 $T$ 通常可以省略。 - -下面是一个用 KCL 生成 kubernetes 资源的例子 - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = name -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -我们可以使用上述 KCL 代码生成一个 Kubernetes YAML 配置 - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## 如何选择 - -目前社区已经进行了大量的尝试来改进其配置技术,主要可分为三类: - -- 用于模板、修补和验证的基于低级数据格式的工具,使用外部工具来增强重用和验证。 -- 领域特定语言(DSL)和配置语言(CL),以增强语言能力。 -- 基于通用语言(GPL)的解决方案,使用 GPL 的云开发工具包(CDK)或框架来定义配置。 - -简单的选择答案: - -- 如果您需要编写结构化的静态的 K-V,或使用 Kubernetes 原生的技术工具,建议选择 YAML。 -- 如果您希望引入编程语言便利性以消除文本(如 YAML、JSON) 模板,有良好的可读性,或者你已是 Terraform 的用户,建议选择 HCL。 -- 如果您希望引入类型功能提升稳定性,维护可扩展的配置文件,建议选择 CUE。 -- 如果您希望以现代语言方式编写复杂类型和建模,维护可扩展的配置文件,原生的纯函数和策略,和生产级的性能和自动化,建议直接选择 KCL 或将 KCL 用于对已有配置手段或工具进行增强。 - -### vs. YAML/JSON - -YAML/JSON 适用于小型配置场景。对于需要频繁修改的大型云原生配置场景,它们更适合 KCL。所涉及的主要区别是配置数据抽象和部署之间的区别: - -使用 KCL 进行配置的优点是:对于静态数据,抽象一层的优点意味着整个系统具有部署灵活性。不同的配置环境、租户和运行时可能对静态数据有不同的要求,甚至不同的组织可能有不同的规范和产品要求。KCL 可用于公开最需要的和经常修改的配置。 - -### vs. Jsonnet/GCL - -GCL 是一种用 Python 实现的声明式配置语言,它提供了支持模板抽象的必要语言功能。然而 GCL 编译器本身是用Python编写的,且语言本身是解释执行的。对于大型模板实例(如 kubernetes 模型),性能较差。 - -Jsonnet 是一种用 C++ 实现的数据模板语言,适用于应用程序和工具开发人员,可以生成配置数据并通过代码组织、简化和管理大型配置,而不会产生副作用。 - -Jsonnet 和 GCL 非常擅长减少样板。它们都可以使用代码生成配置,就像工程师只需要编写高级 GPL 代码,而不是手动编写容易出错且难以理解的服务器二进制代码一样。Jsonnet 减少了 GCL 的一些复杂性,但在很大程度上属于同一类别。两者都有许多运行时错误,类型检查和约束能力不足。 - -### vs. HCL - -HCL 是一种 Go 实现的结构化配置语言。HCL 的原生语法受到 libucl 和 nginx 配置的启发。它用于创建一种对人类和机器友好的结构化配置语言,作为 [Terraform 语言](https://www.terraform.io/language)主要用于 DevOps工具、服务器配置和资源配置等。 - -HCL 的用户界面不能通过 Terraform 提供者 Schema 定义直接感知。此外,在编写复杂对象和必需/可选字段定义时,用户界面很麻烦。动态参数受变量的条件字段约束。资源本身的约束需要由提供程序模式定义,或者与 Sentinel/Rego 和其他策略语言相结合。语言本身的完整性不能自我封闭,其实现方法也不统一。 - -### vs. CUE - -CUE 可以通过结构、无继承和其他特性用作建模,当模型定义之间没有冲突时可以实现高度抽象。因为 CUE 在运行时执行所有约束检查,所以它在大规模配置建模场景中可能存在性能瓶颈。CUE 将类型和值组合为一个概念,并通过各种语法简化了约束的编写。例如,不需要泛型类型和枚举,求和类型和空值合并是一回事。CUE 支持配置合并,但它是完全幂等的。它可能无法满足复杂的多租户和多环境配置场景的要求。对于复杂的循环和约束场景,编写起来很复杂,编写需要精确配置修改或者 Patch 的场景也很麻烦。 - -对于 KCL,建模是通过 KCL Schema 进行的,通过语言级工程和一些面向对象的特性(如单一继承、Mixin 复用)可以实现高模型抽象。KCL 是一种静态编译语言,用于大规模建模场景是运行时开销较低 (性能更高,更低的内存消耗)。KCL 提供了更丰富的检查声明性约束语法,这使得配置和策略编写更加容易。对于一些配置字段组合约束,它更容易编写(与 CUE 相比,KCL 提供了更多的 if-guard 组合约束、all/any/map/filter 表达式和其他集合约束编写方法,这使得编写更容易)。 - -### vs. Dhall - -Dhall 是一种可编程配置语言,它组合了 JSON、函数、类型和 imports 导入等功能, 本身风格偏向函数式,如果您学过 Haskell 等函数式风格语言,可能会对它感到熟悉的。相比于 Dhall, KCL 也提供了类似功能的组合,提供给用户配置可编程和抽象的能力,不过 KCL 在建模、约束检查、自动化等方面做了更多的改进,同时能够通过包管理手段进行模型共享。此外,KCL 的语法语义更贴近于面向对象语言,在一定程度上会比纯函数式风格接受程度更高。 - -### vs. Nickel - -Nickel 是一种简单的配置语言。它的目的是自动生成静态配置文件,本质上是带有函数和类型的 JSON。 - -KCL 和 Nickel 都有类似的渐进式类型系统(静态+动态)、合并策略、函数和约束定义。不同之处在于 KCL 是一种类似 Python 的语言,而 Nickel 是一种类似 JSON 的语言。此外,KCL 提供了 schema 关键字来区分配置定义和配置数据,以避免混合使用。 - -### vs. Starlark - -Starlark 主要用作 Bazel 的配置语言并且是 Python 的一种方言。它没有类型,并且禁止递归。 - -KCL 一定程度上也可以看作 Python 的变种,但是它极大地增强了静态类型和配置扩展性相关的设计,并且是一个编译型语言,这与 Starlark 有着本质的不同。 - -### vs. Kustomize - -Kustomize 的核心功能是其文件级覆盖功能。但是它存在多个覆盖链的问题,因为找到特定属性值的语句不能保证它是最终值,因为其他地方出现的另一个特定值可以覆盖它。对于复杂的场景,Kustomsize 文件的继承链的检索通常不如 KCL 代码的继承链检索方便,需要仔细考虑指定的配置文件覆盖顺序。此外,Kustomize 无法解决 YAML 配置编写、约束验证、模型抽象和开发等问题,更适合于简单的配置场景。 - -在 KCL 中,配置合并操作可以对代码中的每个配置属性进行细粒度处理,合并策略可以灵活设置,而不限于整体资源,配置之间的依赖关系可以通过KCL的import语句进行静态分析。 - -### vs. Helm - -Helm 的概念源于操作系统的包管理机制。它是一个基于模板化 YAML 文件的包管理工具,支持包中资源的执行和管理。 - -KCL 自然提供了 Helm 功能的超集,因此您可以直接使用 KCL 作为替代。对于采用 Helm 的用户,KCL 中的堆栈编译结果可以打包并以 Helm 格式使用,通过 kpm 包管理工具进行分发复用。此外,我们还可以直接使用 Helm-KCL 插件直接对已有的 Helm Charts 进行无侵入的可编程扩展。 - -### vs. CDK - -用CDK的高级语言编写可以很好地集成到应用程序项目中,这实际上是客户端运行时的一部分。对于KCL,由KCL编写的外部配置和策略与客户端运行时分离。 - -通用语言通常远远超出了需要解决的问题,例如安全问腿、能力边界问题(启动本地线程、访问IO、网络、代码无限循环和其他安全风险)。例如,在音乐领域,有专门的音符来表达音乐,这便于学习和交流,它不能用一般语言表达清楚。 - -此外,由于通用语言风格多样,需要统一维护、管理和自动化。通用语言通常用于编写客户端运行时,它是服务器运行时的延续,不适合编写独立于运行时的配置,被编译成二进制文件,并最终从进程开始运行。此外,GPL 稳定性和可扩展性不易控制。然而,KCL 配置语言通常用于编写数据,将数据与简单逻辑相结合,它描述了预期的最终结果,然后由编译器或引擎使用,既具备丰富的编程抽象能力,又具备方便的数据处理方式。 - -### vs. OPA/Rego - -Rego 起源于逻辑编程,它基于 Datalog,是一种受限制的 Prolog 形式,而 KCL 基于静态类型结构,具备部分 OOP 特性。Rego 类型化特征结构的设计是为了解决 Prolog 在人类语言编码应用中的缺点,将 Datalog 变量用于编程本质上是约束验证任务,Datalog 是一种优秀的查询语言。但对于约束强制执行,它有点麻烦,因为实际上首先需要查询要应用约束的值才能进行校验。 - -此外,KCL 的方法更易于找到规范化、简化、面向人类易读,面向运行时性能优良的约束和校验表示,具备静态类型,并且它更适合于从 OpenAPI 生成或者创建 OpenAPI。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/index.md deleted file mode 100644 index c0613d42..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/index.md +++ /dev/null @@ -1 +0,0 @@ -# 用户手册 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/package-management/1-overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/package-management/1-overview.md deleted file mode 100644 index ce7b13cb..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/package-management/1-overview.md +++ /dev/null @@ -1,3 +0,0 @@ -# 简介 - -KCL 通过包管理工具 [kpm](https://github.com/kcl-lang/kpm) 对 KCL 包进行管理。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/package-management/2-installation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/package-management/2-installation.md deleted file mode 100644 index 7b0892a5..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/package-management/2-installation.md +++ /dev/null @@ -1,53 +0,0 @@ -# 安装 - -## 安装 `kpm` - -kpm 将调用 `KCL`编译器来编译 KCL 程序。在使用 `kpm` 之前,您需要确保 `KCL` 编译器已经成功安装,您可以参照[如何安装 KCL 编译器](https://kcl-lang.io/docs/user_docs/getting-started/install)。 - -### 使用 `go install` 安装 `kpm` - -您可以使用 go install 命令安装 kpm。 - -```shell -go install kcl-lang.io/kpm@latest -``` - -### 从 Github release 页面手动安装 `kpm` - -您可以从 [kpm Github Release](https://github.com/kcl-lang/kpm/releases) 中获取 `kpm` ,并将 `kpm` 的二进制文件路径设置到环境变量 PATH 中。 - -```shell -# KPM_INSTALLATION_PATH 是 `kpm` 二进制文件的所在目录. -export PATH=$KPM_INSTALLATION_PATH:$PATH -``` - -请使用以下命令以确保您成功安装了`kpm`。 - -```shell -kpm --help -``` - -如果你看到以下输出信息,那么你已经成功安装了`kpm`,可以继续执行下一步操作。 - -```shell -NAME: - kpm - kpm is a kcl package manager - -USAGE: - kpm [arguments]... - -COMMANDS: - init initialize new module in current directory - add add new dependency - pkg package a kcl package into tar - metadata output the resolved dependencies of a package - run compile kcl package. - login login to a registry - logout logout from a registry - push push kcl package to OCI registry. - pull pull kcl package from OCI registry. - help, h Shows a list of commands or help for one command - -GLOBAL OPTIONS: - --help, -h show help -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/package-management/3-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/package-management/3-quick-start.md deleted file mode 100644 index 455987c8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/package-management/3-quick-start.md +++ /dev/null @@ -1,108 +0,0 @@ -# 快速开始 - -## 1. 初始化一个空的 KCL 包 - -使用 `kpm init` 命令创建一个名为 `my_package` 的 kcl 程序包, 并且在我们创建完成一个名为 `my_package` 的包后,我们需要通过命令 `cd my_package` 进入这个包来进行后续的操作。 - -```shell -kpm init my_package && cd my_package -``` - -![kpm_init](/img/docs/user_docs/guides/package-management/gifs/kpm_init.gif) - -`kpm` 将会在执行`kpm init my_package`命令的目录下创建两个默认的配置文件 `kcl.mod` 和 `kcl.mod.lock`。 - -```shell -- my_package - |- kcl.mod - |- kcl.mod.lock - |- # 你可以直接在这个目录下写你的kcl程序。 -``` - -`kcl.mod.lock` 是 `kpm` 用来固定依赖版本的文件,是自动生成的,请不要人工修改这个文件。 - -`kpm` 将会为这个新包创建一个默认的 `kcl.mod`。如下所示: - -```shell -[package] -name = "my_package" -edition = "0.0.1" -version = "0.0.1" -``` - -## 2. 为 KCL 包添加依赖 - -然后,您可以通过 `kpm add` 命令来为您当前的库添加一个外部依赖。 - -如下面的命令所示,为当前包添加一个版本号为 `1.27.2` 并且名为 `k8s` 的依赖包。 - -```shell -kpm add k8s:1.27.2 -``` - -![kpm_add_k8s](/img/docs/user_docs/guides/package-management/gifs/kpm_add_k8s.gif) - -`kpm` 会为您将依赖添加到 kcl.mod 文件中. - -```shell -[package] -name = "my_package" -edition = "0.0.1" -version = "0.0.1" - -[dependencies] -k8s = "1.27.2" # The dependency 'k8s' with version '1.27.2' -``` - -## 编写一个程序使用包 `konfig` 中的内容 - -在当前包中创建 `main.k`。 - -```shell -- my_package - |- kcl.mod - |- kcl.mod.lock - |- main.k # Your KCL program. -``` - -并且将下面的内容写入 `main.k` 文件中。 - -```kcl -# 导入并使用外部依赖 `k8s` 包中的内容。 -import k8s.api.core.v1 as k8core - -k8core.Pod { - metadata.name = "web-app" - spec.containers = [{ - name = "main-container" - image = "nginx" - ports = [{containerPort = 80}] - }] -} - -``` - -## 3. 运行 KCL 代码 - -你可以使用 kpm 编译刚才编写的 `main.k` 文件, 得到编译后的结果。 - -```shell -kpm run -``` - -输出为 - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: web-app -spec: - containers: - - image: nginx - name: main-container - ports: - - containerPort: 80 -``` - -![kpm_run](/img/docs/user_docs/guides/package-management/gifs/kpm_run.gif) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/package-management/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/package-management/_category_.json deleted file mode 100644 index d1600bfd..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/package-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "包管理", - "position": 7 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md deleted file mode 100644 index 5ebfe83c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: "从 Kubernetes 迁移" -sidebar_position: 1 ---- - -## 简介 - -KCL 对 Kubernetes 配置提供了许多开箱即用的支持,通过 KCL 工具,我们可以将 Kubernetes Schema 和 配置集成到 KCL 中,本节内容将介绍如何使用 KCL 对 Kubernetes 进行集成 - -### 1. Kubernetes OpenAPI Spec - -从 Kubernetes 1.4 开始,引入了对 OpenAPI 规范(在捐赠给 Open API Initiative 之前称为 swagger 2.0)的 alpha 支持,API 描述遵循 [OpenAPI 规范 2.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md),从 Kubernetes 1.5 开始,Kubernetes 能够直接从[源码自动地提取模型并生成 OpenAPI 规范](https://github.com/kubernetes/kube-openapi),自动化地保证了规范和文档与操作/模型的更新完全同步。 - -此外,Kubernetes CRD 使用 [OpenAPI v3.0 validation](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation) 来描述(除内置属性 apiVersion、kind、metadata 之外的)自定义 schema,在 CR 的创建和更新阶段,APIServer 会使用这个 schema 对 CR 的内容进行校验。 - -### 2. KCL OpenAPI 支持 - -KCLOpenAPI 工具支持从 OpenAPI/CRD 定义提取并生成 KCL schema. 在 KCLOpenAPI Spec 中明确定义了 OpenAPI 规范与 KCL 语言之间的映射关系。 - -### 3. 从 Kubernetes 模型迁移到 KCL - -#### 3.1 基于 kusion_models 编写配置 - -我们为你提供了一个开箱即用的 `kusion_models` 包,让你可以快速开始。其中包含一个精心设计的前端模型,称为[服务器模型](https://github.com/KusionStack/konfig/blob/main/base/pkg/kusion_models/kube/frontend/server.k)(Server schema)。你可以通过初始化 `Server schema` 来声明其配置。有关模式及其属性的说明和用法,请参阅 [Server schema 文档](https://kusionstack.io/docs/reference/model/kusion_models/kube/frontend/doc_server)。 - -#### 3.2 创建自定义的 models 前端模型 - -现有的 `kusion_models` 模型可能无法满足你的特定业务需求,那么你也可以设计自定义前端模型包。 您可基于预先生成的 Kubernetes KCL 包自定义您的前端模型。您还可以仿照`kube2kcl` 工具的模式,开发自定义脚本,完成配置数据的迁移。 - -##### 3.2.1 获取 Kubernetes KCL 模型 - -我们提供了预生成的各版本[Kubernetes KCL模型](https://github.com/orgs/KusionStack/packages/container/package/k8s),您可以在项目下执行 `kpm add k8s:` 来获得它。有关 kpm 使用的详细信息,请参考 [kpm快速入门指南](https://github.com/kcl-lang/kpm#quick-start)。 - -或者,如果您需要自己生成这些包,请参考[从 Kubernetes OpenAPI 文件生成 KCL 包](https://github.com/kcl-lang/kcl-openapi/blob/main/docs/generate_from_k8s_spec.md)。 - -##### 3.2.2 编写自定义前端模型 - -由于 Kubernetes 内置模型较为原子化和复杂,我们推荐以 Kubernetes 原生模型作为后端输出的模型,对其进一步抽象,而向用户暴露一份更为友好和简单的前端模型界面,具体您可参照 Konfig 仓库中 [kusion_models Server](https://github.com/KusionStack/konfig/blob/main/base/pkg/kusion_models/kube/frontend/server.k) 模型的设计方式进行。 - -##### 3.2.3 迁移配置数据 - -对于存量的 Kubernetes 配置数据,您可以仿照 kube2Kcl 工具的做法,编写自定义的转换脚本,进行一键迁移。Kusion 后续将提供该脚本的编写脚手架和编写指南。 - -### 4. 从 Kubernetes CRD 迁移 - -如果您的项目中使用了 CRD,也可以采用类似的模式,生成 CRD 对应的 KCL schema,并基于该 schema 声明 CR。 - -- 从 CRD 生成 KCL Schema - - ``` - kcl-openapi generate model --crd --skip-validation -f your_crd.yaml - ``` - -- 使用 KCL 声明 CR - - 使用 KCL 声明 CR 的模式与声明 Kubernetes 内置模型配置的模式相同,在此不做赘述。 - -## 小结 - -本节介绍了如何使用 kcl-openapi 工具将 OpenAPI 规范映射到 KCL 语言特性,此外提供了将 KCL 与 OpenAPI 和 Kubernetes CRD 一起使用的快速入门指南帮助从 Kubernetes 进行迁移或集成。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md deleted file mode 100644 index e674c946..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md +++ /dev/null @@ -1,249 +0,0 @@ ---- -title: "使用 KCL 生成并管理 Kubernetes 资源配置" -sidebar_position: 2 ---- - -## 简介 - -当我们管理 Kubernetes 资源清单时,我们常常会手写维护,或者使用 Helm 和 Kustomize 等工具来维护我们 YAML 配置或者配置模版,然后通过 kubectl 和 helm 命令行等工具将资源下发到集群。但是作为一个 "YAML 工程师" 每天维护 YAML 配置无疑是琐碎且无聊的,并且容易出错。 - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: ... # Omit -spec: - selector: - matchlabels: - cell: RZ00A - replicas: 2 - template: - metadata: ... # Omit - spec: - tolerations: - - effect: NoSchedules - key: is-over-quota - operator: Equal - value: 'true' - containers: - - name: test-app - image: images.example/app:v1 # Wrong ident - resources: - limits: - cpu: 2 # Wrong type. The type of cpu should be str - memory: 4Gi - # Field missing: ephemeral-storage - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: is-over-quota - operator: In - values: - - 'true' -``` - -- YAML 中的结构化数据是无类型的,缺乏验证方法,无法立即检查所有数据的有效性 -- YAML 编程能力欠佳,容易写出不正确的缩进,也没有逻辑判断等常见代码组织方式,容易写出大量重复配置,难以维护 -- Kubernetes 设计是复杂的,用户很难理解所有细节,比如上面配置中的 `toleration` 和 `affinity` 字段,如果用户不理解调度逻辑,它可能被错误地省略掉或者多余的添加 - -因此,KCL 期望在 Kubernetes YAML 资源管理解决如下问题: - -- 用**生产级高性能编程语言**以**编写代码**的方式提升配置的灵活度,比如条件语句、循环、函数、包管理等特性提升配置重用的能力 -- 在代码层面提升**配置语义验证**的能力,比如字段可选/必选、类型、范围等配置检查能力 -- 提供**配置分块编写、组合和抽象的能力**,比如结构定义、结构继承、约束定义等能力 - -## 先决条件 - -首先可以在 [KCL 快速开始](/docs/user_docs/getting-started/kcl-quick-start) 根据指导下载并安装 KCL,然后准备一个 [Kubernetes](https://kubernetes.io/) 环境 - -## 快速开始 - -### 1. 生成 Kubernetes 资源 - -我们可以编写如下 KCL 代码并命名为 main.k ,KCL 受 Python 启发,基础语法十分接近 Python, 比较容易学习和上手, 配置模式写法很简单,`k [: T] = v`, 其中 `k` 表示配置的属性名称; `v` 表示配置的属性值; `: T` 表示一个可选的类型注解。 - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -上述 KCL 代码中我们分别声明了一个 Kubernetes Deployment 资源的 `apiVersion`、`kind`、`metadata` 和 `spec` 等变量,并分别赋值了相应的内容,特别地,我们将 `metadata.labels` 字段分别重用在 `spec.selector.matchLabels` 和 `spec.template.metadata.labels` 字段。可以看出,相比于 YAML,KCL 定义的数据结构更加紧凑,而且可以通过定义局部变量实现配置重用。 - -我们可以执行如下命令行得到一个 Kubernetes YAML 文件 - -```bash -kcl main.k -``` - -输出为: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -当然我们可以将 KCL 工具与 kubectl 等工具结合使用,让我们执行如下命令并看看效果 - -```shell -kcl main.k | kubectl apply -f - -``` - -输出为 - -```shell -deployment.apps/nginx-deployment configured -``` - -可以从命令行的结果看出与我们使用直接使用 YAML 配置和 kubectl apply 的一个 Deployment 体验完全一致 - -通过 kubectl 检查部署状态 - -```shell -kubectl get deploy -``` - -输出为 - -```shell -NAME READY UP-TO-DATE AVAILABLE AGE -nginx-deployment 3/3 3 3 15s -``` - -### 2. 编写代码管理 Kubernetes 资源 - -对于 Kubernetes 资源发布时,我们常常会遇到配置参数需要动态指定的场景,比如不同的环境需要设置不同的 `image` 字段值生成不同环境的资源。对于这种场景,我们可以通过 KCL 的条件语句和 `option` 函数动态地接收外部参数。我们可以在上述例子的基础上根据不同的环境调整配置参数,比如对于如下代码,我们编写了一个条件语句并输入一个名为 `env` 的动态参数 - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" if option("env") == "prod" else "${metadata.name}:latest" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -使用 KCL 命令行 `-D` 标记接收一个外部设置的动态参数: - -```bash -kcl main.k -D env=prod -``` - -输出为: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -上述代码片段中的 `image = metadata.name + ":1.14.2" if option("env") == "prod" else metadata.name + ":latest"` 意思为:当动态参数 `env` 的值被设置为 `prod` 时,image 字段值为 `nginx:1.14.2`, 否则为 `nginx:latest`,因此我们可以根据需要为 env 设置为不同的值获得不同内容的 Kubernetes 资源。 - -并且 KCL 支持将 option 函数动态参数维护在配置文件中,比如编写下面展示的 `kcl.yaml` 文件 - -```yaml -kcl_options: - - key: env - value: prod -``` - -使用如下命令行也可以得到同样的 YAML 输出,以简化 KCL 动态参数的输入过程 - -```bash -kcl main.k -Y kcl.yaml -``` - -输出为: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## 小结 - -KCL 可以用于生成和管理 Kubernetes 资源,解决管理 YAML 配置的局限性,例如缺乏验证方法和较弱的编程能力等,并可以通过条件语句和 option 函数动态接收外部参数,从而能够根据不同的环境调整配置参数。此外,KCL 可以与 kubectl 等其他工具一起使用将配置一键生效到集群。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md deleted file mode 100644 index 5fe97d05..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: "Kubectl KCL 插件" -sidebar_position: 1 ---- - -## 简介 - -[Kubectl](https://kubernetes.io/docs/reference/kubectl/) is a command line tool for communicating with a Kubernetes cluster's control plane, using the Kubernetes API. You can use the `Kubectl-KCL-Plugin` to - -- Edit the YAML configuration in a hook way to separate data and logic for the Kubernetes manifests management. -- For multi-environment and multi-tenant scenarios, you can maintain these configurations gracefully rather than simply copy and paste. -- Validate all KRM resources using the KCL schema. - -## 前置条件 - -- Install [Kubectl](https://github.com/kubernetes/kubectl) -- Install [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) - -## 快速开始 - -Let’s write a KCL function which add annotation `managed-by=krm-kcl` only to `Deployment` resources in the helm chart. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/kubectl-kcl.git/ -cd ./kubectl-kcl/examples/ -``` - -### 2. Test and Run - -Run the KCL code via the `Kubectl KCL Plugin`. - -```bash -kubectl kcl run -f ./kcl-run.yaml -``` - -The output yaml is - -```yaml -apiVersion: config.kubernetes.io/v1 -kind: ResourceList -items: - - apiVersion: apps/v1 - kind: Deployment - metadata: - annotations: - managed-by: krm-kcl - labels: - app: nginx - name: nginx-deployment - spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - image: "nginx:1.14.2" - name: nginx - ports: - - containerPort: 80 - - apiVersion: v1 - kind: Service - metadata: - name: test - spec: - ports: - - port: 80 - protocol: TCP - targetPort: 9376 - selector: - app: MyApp -functionConfig: - # kcl-fn-config.yaml - apiVersion: krm.kcl.dev/v1alpha1 - kind: KCLRun - metadata: - # EDIT THE SOURCE! - # This should be your KCL code which preloads the `ResourceList` to `option("resource_list") - spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "krm-kcl"}} for resource in option("resource_list").items] -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md deleted file mode 100644 index 271f08e8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: "Helm KCL 插件" -sidebar_position: 2 ---- - -## 简介 - -[Helm](https://github.com/helm/helm) 是一个管理 Charts 的工具。Charts 是预配置的 Kubernetes 资源的包。您可以使用 `Helm-KCL-Plugin` 来完成以下操作: - -- 以 hook 的方式编辑 Helm charts,将数据和逻辑分离以便更好地管理 Kubernetes manifests -- 对于多环境和多租户方案,可以优雅地维护这些配置,而不仅仅是简单地复制和粘贴 -- 使用 KCL 模式验证所有 KRM 资源 - -## 先决条件 - -- 安装 [Helm](https://github.com/helm/helm) -- 安装 [Helm KCL 插件](https://github.com/kcl-lang/helm-kcl) - -## 快速开始 - -让我们编写一个仅向 `Deployment` 资源添加 annotation `managed-by=helm-kcl-plugin` 的 KCL 函数 - -### 1. 获取示例 - -```bash -git clone https://github.com/kcl-lang/helm-kcl.git/ -cd ./helm-kcl/examples/workload-charts-with-kcl -``` - -### 2. 测试和运行 - -通过 `Helm KCL Plugin` 运行KCL代码。 - -```bash -helm kcl template --file ./kcl-run.yaml -``` - -输出的YAML为 - -```yaml -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: workload - app.kubernetes.io/version: 0.1.0 - helm.sh/chart: workload-0.1.0 - name: workload -spec: - ports: - - name: www - port: 80 - protocol: TCP - targetPort: 80 - selector: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - type: ClusterIP ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: workload - app.kubernetes.io/version: 0.1.0 - helm.sh/chart: workload-0.1.0 - name: workload - annotations: - managed-by: helm-kcl-plugin -spec: - selector: - matchLabels: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - template: - metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - spec: - containers: - - image: nginx:alpine - name: frontend -``` - -## KCL 开发指南 - -以下是您可以在 KCL 代码中执行的操作: - -- 从 `option("resource_list")` 读取资源。`option("resource_list")` 符合 [KRM 函数规范](https://kpt.dev/book/05-developing-functions/01-functions-specification)。 你可以从 `option("resource_list")["items"]` 读取输入资源,并从 `option("resource_list")["functionConfig"]` 读取 `functionConfig`。 -- 返回输出资源的 KPM 列表。 -- 使用 `assert {condition},{error_message}` 返回错误消息。 - -## 更多文档和示例 - -- [Helm KCL 插件](https://github.com/kcl-lang/helm-kcl) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md deleted file mode 100644 index 4f1c8c56..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -title: "Kustomize KCL 插件" -sidebar_position: 3 ---- - -## 简介 - -[Kustomize](https://github.com/kubernetes-sigs/kustomize) 允许自定义用于多种目的原始的、无模板的 YAML 文件,同时保留原始 YAML 不变和可用。 - -KCL 可用于创建函数,以改变和/或验证 Kubernetes 资源模型(KRM)的 YAML 输入/输出格式,并且我们提供 Kustomize KCL 函数来简化函数编写过程。 - -## 先决条件 - -- 安装 [kustomize](https://github.com/kubernetes-sigs/kustomize) - -## 快速开始 - -让我们编写一个仅向 Deployment 资源添加 annotation `managed-by=kustomize-kcl` 的 KCL 函数 - -### 1. 获取示例 - -```bash -git clone https://github.com/kcl-lang/kustomize-kcl.git -cd ./kustomize-kcl/examples/set-annotation/ -``` - -### 2. 测试和运行 - -```bash -kustomize fn run ./local-resource/ --dry-run -``` - -输出的YAML为 - -```yaml -apiVersion: krm.kcl.dev/v1alpha1 -kind: KCLRun -metadata: - name: set-annotation - annotations: - config.kubernetes.io/function: | - container: - image: docker.io/kcllang/kustomize-kcl:v0.2.0 - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml -# EDIT THE SOURCE! -# This should be your KCL code which preloads the `ResourceList` to `option("resource_list") -spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "kustomize-kcl"}} for resource in option("resource_list").items] ---- -apiVersion: v1 -kind: Service -metadata: - name: test - annotations: - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml -spec: - selector: - app: MyApp - ports: - - protocol: TCP - port: 80 - targetPort: 9376 ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx - annotations: - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml - managed-by: kustomize-kcl -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## KCL 开发指南 - -以下是可以使用 KCL 执行的操作: - -- 从 `option("resource_list")` 读取资源。`option("resource_list")` 符合 [KRM 函数规范](https://kpt.dev/book/05-developing-functions/01-functions-specification)。 你可以从 `option("resource_list")["items"]` 读取输入资源,并从 `option("resource_list")["functionConfig"]` 读取 `functionConfig`。 -- 返回输出资源的 KPM 列表。 -- 使用 `assert {condition},{error_message}` 返回错误消息。 - -## 更多文档和示例 - -- [Kustomize KCL 插件](https://github.com/kcl-lang/kustomize-kcl) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-konfig/1-overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-konfig/1-overview.md deleted file mode 100644 index b112e946..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-konfig/1-overview.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -id: overview -sidebar_label: 概述 ---- - -# Konfig 概述 - -在 KCL 中推荐通过**配置库**的方式统一管理所有的配置清单和模型库,即不仅存放抽象模型本身的 KCL 定义,还存放各种类型的配置清单,比如应用的运维配置、策略配置等。配置大库推荐托管在各类 VCS 系统中,以方便做配置的回滚和漂移检查。配置大库的最佳实践代号为 Konfig,仓库托管在 [Github](https://github.com/KusionStack/konfig)。 - -⚡️ 配置大库主要包括: - -- KCL 模块声明文件(kcl.mod) -- KCL 领域模型库 (Kubernetes, Prometheus 等) -- 各类配置清单目录 (应用运维配置等) -- 配置构建和测试脚本 (Makefile,Github CI 文件等) - -之所以用一个统一的仓库管理全部的 KCL 配置代码,是由于不同代码包的研发主体不同,会引发出包管理和版本管理的问题。将业务配置代码、基础配置代码在一个统一仓库中,代码间的版本依赖管理会比较简单,通过定位唯一代码库的目录及文件即可,可以将配置代码统一管理,便于查找、修改、维护。 - -下面是配置大库(Konfig)的架构图: - -![](/img/docs/user_docs/guides/konfig/konfig-arch.png) - -Konfig 提供给用户开箱即用、高度抽象的配置界面,模型库最初朴素的出发点就是改善 YAML 用户的效率和体验,我们希望通过将代码更繁杂的模型抽象封装到统一的模型中,从而简化用户侧配置代码的编写。Konfig 由以下部分组成: - -- **核心模型**: - - **前端模型**:前端模型即「用户界面」,包含平台侧暴露给用户的所有可配置属性,其中省略了一些重复的、可推导的配置,抽象出必要属性暴露给用户,具有用户友好的特性,比如 server.k。 - - **后端模型**:后端模型是「模型实现」,是让前端模型属性生效的模型,主要包含前端模型实例的渲染逻辑,后端模型中可借助 KCL 编写校验和逻辑判断等以提高配置代码复用性和健壮性,对用户不感知,比如 server_backend.k -- **领域模型**:是不包含任何实现逻辑和抽象的模型,往往由工具转换生成,无需修改,和真正生效的 YAML 属性一一对应,底层模型需要经过进一步抽象,一般不直接被用户使用。比如,kusion_kubernetes 是 Kubernetes 场景的底层模型库。 - -此外,核心模型内部通过前端模型和后端模型两层抽象简化前端用户的配置代码,底层模型则是通过 KCL OpenAPI 工具自动生成。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-konfig/2-structure.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-konfig/2-structure.md deleted file mode 100644 index cc54087e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-konfig/2-structure.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -id: structure -sidebar_label: 工程结构 ---- - -# Konfig 工程结构 - -本文主要解释 Konfig 配置大库的目录和代码结构 - -## 整体结构 - -```bash -. -├── .github # CI 脚本 -├── Makefile # 通过 Makefile 封装常用命令 -├── README.md # 配置大库说明 -├── appops # 应用运维目录,用来放置所有应用的 KCL 运维配置 -│ ├── clickhouse-operator -│ ├── code-city -│ ├── guestbook -│ ├── http-echo -│ └── nginx-example -├── base # 模型库 -│ ├── examples # 样例代码 -│ │ ├── monitoring # 监控配置样例 -│ │ ├── native # Kubernetes 资源配置样例 -│ │ ├── provider # 基础资源配置样例 -│ │ └── server # 云原生应用运维配置模型样例 -│ └── pkg -│ ├── kusion_kubernetes # Kubernetes 底层模型库 -│ ├── kusion_models # 核心模型库 -│ ├── kusion_prometheus # Prometheus 底层模型库 -│ └── kusion_provider # 基础资源 底层模型库 -└── kcl.mod # 大库配置文件,通常用来标识大库根目录位置以及大库所需依赖 -``` - -## 核心模型库结构 - -核心模型库一般命名为 kusion_models,主要包含前端模型、后端模型、Mixin、渲染器等,目录结构为: - -```bash -├── commons # 基础资源核心模型库 -├── kube # 云原生资源核心模型库 -│ ├── backend # 后端模型 -│ ├── frontend # 前端模型 -│ │ ├── common # 通用前端模型 -│ │ ├── configmap # ConfigMap 前端模型 -│ │ ├── container # 容器前端模型 -│ │ ├── ingress # Ingress 前端模型 -│ │ ├── resource # 资源规格前端模型 -│ │ ├── secret # Secret 前端模型 -│ │ ├── service # Service 前端模型 -│ │ ├── sidecar # Sidecar 容器前端模型 -│ │ ├── strategy # 策略前端模型 -│ │ ├── volume # Volume 前端模型 -│ │ └── server.k # 云原生应用运维前端模型 -│ ├── metadata # 应用运维的元数据模型 -│ ├── mixins # 统一放置可复用的 Mixin -│ ├── render # 渲染器,把前后端模型联系在一起的桥梁 -│ ├── templates # 静态配置 -│ └── utils # 工具方法 -└── metadata # 通用元数据模型 -``` - -## Project 和 Stack 结构 - -![](/img/docs/user_docs/concepts/project-stack.png) - -Project 和 Stack 是用于组织 Konfig 的逻辑隔离概念。 - -### Project - -任何包含文件 "project.yaml" 的文件夹都将被视为一个 Project,"project.yaml" 用于描述此 Project 的元数据,如 "name" 和 "tenant" 等。项目必须具有明确的业务语义,用户可以将应用程序或运维场景映射到项目。 - -### Stack - -与Project一样,包含文件 "stack.yaml" 的任何文件夹都将被视为一个 Stack,"stack.yaml" 用于描述此 Stack 的元数据。Stack 是一组 KCL 文件,表示可以单独配置和部署的最小操作单元,它通常代表 CI/CD 过程中的不同阶段。 - -### Project 与 Stack 之间的关系 - -一个 Project 包含一个或多个 Stack,Stack 必须属于且只能属于一个 Project。用户可以根据自己的需要解释 Project 和 Stack 的含义,并灵活组织 Konfig 结构。根据我们的经验,我们提供以下示例作为最佳实践: - -```bash -├── README.md # Project 介绍文件 -├── base # 各环境通用配置 -│ └── base.k # 通用 KCL 配置 -├── dev # 环境特有配置 -│ ├── ci-test # 测试目录 -│ │ ├── settings.yaml # 测试数据 -│ │ └── stdout.golden.yaml # 测试期望结果 -│ ├── kcl.yaml # 多文件编译配置,是 KCL 编译的入口 -│ ├── main.k # 当前环境 KCL 配置 -│ └── stack.yaml # Stack 配置文件 -└── project.yaml # Project 配置文件 -``` - -Project 通常表示一个应用程序,Stack 表示该应用程序的不同环境的配置,例如 dev、pre 和 prod 等。通用配置可以存储在该 Project 下的 "base" 目录中。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-konfig/3-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-konfig/3-quick-start.md deleted file mode 100644 index 92c9849d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-konfig/3-quick-start.md +++ /dev/null @@ -1,198 +0,0 @@ ---- -id: guide -sidebar_label: 快速开始 ---- - -# 简介 - -本篇指南向你展示,如何使用 KCL 语言与其相对应的 CLI 工具,完成一个运行在 Kubernetes 中的 Long-Running 应用的部署,我们将组织配置的单位叫做应用(Application),描述应用部署和运维细节的配置集合叫做应用服务(Server),它本质上是通过 KCL 定义的运维模型。 - -要将一个运行在 Kubernetes 中的应用完全部署起来,一般需要下发多个 Kubernetes 资源,本次演示的样例涉及以下 Kubernetes 资源: - -- 命名空间(Namespace) -- 无状态工作负载(Deployment) -- 服务(Service) - -> 不清楚相关概念的,可以前往 Kubernetes 官方网站,查看相关说明: - -- [Learn Kubernetes Basics](https://kubernetes.io/docs/tutorials/kubernetes-basics/) -- [Namespace](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/) -- [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) -- [Service](https://kubernetes.io/docs/concepts/services-networking/service/) - -## 准备工作 - -在开始之前,我们需要做以下准备工作: - -1. 安装 KCL, 详情信息请参阅[下载和安装](/docs/user_docs/getting-started/install)。 - -2. 下载开源 Konfig 大库,仓库地址: [https://github.com/KusionStack/konfig.git](https://github.com/KusionStack/konfig.git) - -```shell -git clone https://github.com/KusionStack/konfig.git && cd konfig -``` - -## 快速开始 - -### 1. 配置编译 - -Konfig 的编程语言是 KCL,不是 Kubernetes 认识的 JSON/YAML,因此还需要编译得到最终输出。 - -进入到项目的 Stack 目录(`appops/nginx-example/dev`)并执行编译: - -```bash -cd appops/nginx-example/dev && kcl -Y kcl.yaml -D __konfig_output_format__=raw -``` - -可以获得如下 YAML 输出: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-exampledev - namespace: nginx-example -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - template: - metadata: - labels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - spec: - containers: - - image: nginx:1.7.8 - name: main - ports: - - containerPort: 80 - protocol: TCP - resources: - limits: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi - requests: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi ---- -apiVersion: v1 -kind: Namespace -metadata: - name: nginx-example ---- -apiVersion: v1 -kind: Service -metadata: - name: nginx-example - namespace: nginx-example -spec: - ports: - - nodePort: 30201 - port: 80 - targetPort: 80 - selector: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - type: NodePort -``` - -完成编译,可以看到 3 个资源: - -- 一个 name 为 nginx-exampledev 的 Deployment -- 一个 name 为 nginx-example 的 Namespace -- 一个 name 为 nginx-example 的 Service - -以上就完成了配置生效,后续可以使用 `kubectl apply` 等命令下发并检查资源的实际状态,本文不在赘述。 - -### 2. 配置修改 - -Server 模型中的 image 属性用于声明应用的业务容器镜像,我们可以修改 base/main.k 中的 image 的值进行镜像修改或升级: - -```diff -14c14 -< image = "nginx:1.7.8" ---- -> image = "nginx:latest" -``` - -重新编译配置代码可以获得修改后的 YAML 输出: - -```shell -kcl -Y kcl.yaml -D __konfig_output_format__=raw -``` - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-exampledev - namespace: nginx-example -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - template: - metadata: - labels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - spec: - containers: - - image: nginx:latest - name: main - ports: - - containerPort: 80 - protocol: TCP - resources: - limits: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi - requests: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi ---- -apiVersion: v1 -kind: Namespace -metadata: - name: nginx-example ---- -apiVersion: v1 -kind: Service -metadata: - name: nginx-example - namespace: nginx-example -spec: - ports: - - nodePort: 30201 - port: 80 - targetPort: 80 - selector: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - type: NodePort -``` - -## 小结 - -本文主要介绍了如何使用 KCL 语言与其相对应的 Konfig 库,完成一个运行在 Kubernetes 中的 Long-Running 应用的部署。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/support/faq-install.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/support/faq-install.md deleted file mode 100644 index 1c98f224..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/support/faq-install.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -sidebar_position: 5 ---- - -# 安装问题 - -## MacOS 提示无法打开 "kcl",因为 Apple 无法检查其是否包含恶意软件 - -MacOS 提示无法打开 "kcl",因为 Apple 无法检查其是否包含恶意软件。这个错误是因为 macOS 操作系统中的 Gatekeeper 安全功能阻止了应用程序的运行。要解决此问题,请按照以下步骤操作: - -打开"系统偏好设置"并点击"安全性与隐私"。 在"通用"选项卡中,您将看到一个消息:"kcl" 已被阻止。单击"仍要打开"。 或者,你可以单击"打开任何方式"以打开你的应用程序。(可能需要使用管理员权限来打开应用程序。) - -如果不想在每次打开应用程序时都执行这些步骤,则可以的应用程序添加到白名单中,以便在不受阻止的情况下运行。要将您的应用程序添加到白名单中,请执行以下操作: - -打开终端并输入以下命令: - -```shell -xattr -rd com.apple.quarantine /path/to/kcl -``` - -其中,/path/to/kcl 是 kcl 应用程序的完整路径。运行命令后,应用程序将被添加到白名单中,Gatekeeper 将不再阻止其运行。 - -## 在 Windows/Linux/MacOS 平台上抱 program not found 或者 run linker failed 错误 - -请确保如下依赖在您的 PATH 中 - -- MacOS: `clang` -- Linux: `gcc` -- Windows: `cl.exe` (可以通过安装 MSVC 获得) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/support/faq-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/support/faq-kcl.md deleted file mode 100644 index 8330dfd6..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/support/faq-kcl.md +++ /dev/null @@ -1,2355 +0,0 @@ ---- -sidebar_position: 2 ---- - -# KCL 语法 - -## 1. 如何用 KCL 写一个简单的 key-value 对配置 - -创建一个名为 `config.k` 的文件 - -```python -cpu = 256 -memory = 512 -image = "nginx:1.14.2" -service = "my-service" -``` - -上述 KCL 代码中,定义了 4 个变量 `cpu` 和 `memory` 被声明为整数类型,并且它们的值分别为 `256` 和 `512`,而 `image` 和 `service` 是字符串类型,它们的值分别为 `image` 和 `service` - -使用如下命令可以将上述 KCL 文件编译为 YAML 进行输出 - -``` -kcl config.k -``` - -得到的 YAML 输出为: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -如果想要输出到文件,可以使用 `-o|--output` 参数: - -``` -kcl config.k -o config.yaml -``` - -## 2. KCL 中有哪些基本的数据类型? - -KCL 目前的基本数值类型和值包含: - -- 整数类型 `int` - - 举例: 十进制正整数 `1`, 十进制负整数 `-1`, 十六进制整数 `0x10`, 八进制整数 `0o10`, 二进制整数 `0b10` -- 浮点数类型 `float` - - 举例: 正浮点数 `1.10`, `1.0`, 负浮点数 `-35.59`, `-90.`, 科学记数法浮点数 `32.3e+18`, `70.2E-12` -- 布尔类型 `bool` - - 举例: 真值 `True`, 假值 `False` -- 字符串类型 `str` - 使用引号 `'`, `"` 标记 - - 举例: 双引号字符串 `"string"`, `"""string"""`, 单引号字符串 `'string'`, `'''string'''` -- 列表类型 `list` - 使用 `[`, `]` 标记 - - 举例: 空列表 `[]`, 字符串列表 `["string1", "string2", "string3"]` -- 字典类型 `dict` - 使用 `{`, `}` 标记 - - 举例: 空字典 `{}`, 键值均为字符串类型的字典 `{"key1": "value1", "key2": "value2"}` -- 结构类型 `schema` - 使用关键字 `schema` 定义,并使用相应的 schema 名称进行实例化 -- 空值类型 `None` - 用于表示一个变量的值为空,与输出 YAML 的 `null` 值对应 -- 未定义值类型 `Undefined` - 用于表示一个变量未被赋值,值为 `Undefined` 的变量不会被输出到 YAML 中 - -```python -schema Person: - name: str - age: int - -alice = Person { - name = "Alice" - age = 18 -} -bob = Person { - name = "Bob" - age = 10 -} -``` - -注意: 所有 KCL 类型的变量均可赋值为空值 `None` 和未定义的值 `Undefined` - -## 3. 有些 KCL 变量名带 `_` 下划线前缀表示什么?和不带 `_` 下划线前缀的区别是什么?分别适合什么场景下使用? - -KCL 中带下划线前缀的变量表示一个**隐藏**的,**可变**的变量,**隐藏**表示带下划线前缀的变量不会被输出到 YAML 当中,包括包级别的下划线前缀变量和 schema 当中的下划线前缀变量。**可变**表示带下划线前缀的变量可被多次重复赋值,不带下划线前缀的变量被赋值后不可变。 - -带 `_` 下划线前缀的变量与不带 `_` 下划线前缀变量的区别是: 不带 `_` 下划线前缀变量默认是导出到 YAML 当中的,并且具有强不可变性;带 `_` 下划线前缀变量是不导出的,可变的。 - -```python -name = 'Foo' # 导出变量,不可变变量 -name = 'Bar' # 错误:导出变量只能设置一次 -``` - -```python -_name = 'Foo' # 隐藏变量,可变变量 -_name = 'Bar' - -schema Person: - _name: str # hidden and mutable -``` - -## 4. 如何向 dict 中添加元素? - -可以使用 union 运算符 `|`, 或者 dict 解包运算符 `**` 来向 dict 中添加一个元素,并且可以使用 `in`,`not in` 等关键字判断 dict 变量当中是否包含某一个键值 - -```python -_left = {key: {key1 = "value1"}, intKey = 1} # 注意使用 = 表示覆盖 -_right = {key: {key2 = "value2"}, intKey = 2} -dataUnion = _left | _right # {"key": {"key1": "value1", "key2": "value2"}, "intKey": 2} -dataUnpack = {**_left, **_right} # {"key": {"key1": "value1", "key2": "value2"}, "intKey": 2} -``` - -输出 YAML 为: - -```yaml -dataUnion: - key: - key1: value1 - key2: value2 - intKey: 2 -dataUnpack: - key: - key1: value1 - key2: value2 - intKey: 2 -``` - -此外还可以使用 `字符串插值` 或者字符串 `format` 成员函数特性向 kcl dict 添加变量键值对 - -```python -dictKey1 = "key1" -dictKey2 = "key2" -data = { - "${dictKey1}" = "value1" - "{}".format(dictKey2) = "value2" -} -``` - -输出 YAML 为: - -```yaml -dictKey1: key1 -dictKey2: key2 -data: - key1: value1 - key2: value2 -``` - -## 5. 如何修改 dict 中的元素? - -我们可以使用 union 运算符 `|`, 或者解包运算符 `**` 修改 dict 当中的元素 - -```python -_data = {key = "value"} # {"key": "value"} -_data = _data | {key = "override_value1"} # {"key": "override_value1"} -_data = {**_data, **{key = "override_value2"}} # {"key": "override_value2"} -``` - -如果想要删除 dict 中某个键为 `key` 的值,可以使用解包运算符 `**{key = Undefined}` 或者合并运算符 `| {key = Undefined}` 进行覆盖,覆盖后 key 的值为 Undefined,不会进行 YAML 输出。 - -## 6. 如何向 list 中添加元素? - -在 list 中添加元素有两种方式: - -- 使用 `+`, `+=` 和 slice 切片连接组装 list 变量达到向 list 中添加元素的目的 - -```python -_args = ["a", "b", "c"] -_args += ["end"] # 在list尾部添加元素"end", ["a", "b", "c", "end"] -_args = _args[:2] + ["x"] + _args[2:] # 在list索引为2的地方插入元素"x", ["a", "b", "x", "c", "end"] -_args = ["start"] + _args # 在list头部添加元素"start", ["start", "a", "b", "x", "c", "end"] -``` - -- 使用 `*` 解包运算符连接合并 list - -```python -_args = ["a", "b", "c"] -_args = [*_args, "end"] # 在list尾部添加元素"end", ["a", "b", "c", "end"] -_args = ["start", *_args] # 在list头部添加元素"start", ["start", "a", "b", "c", "end"] -``` - -注意:当接连的变量为 `None/Undefined` 时,使用 `+` 可能会发生错误,这时使用 list 解包运算符 `*` 或者使用 `or` 运算符取 list 的默认值可以避免空值判断 - -```python -data1 = [1, 2, 3] -data2 = None -data3 = [*data1, *data2] # Right [1, 2, 3] -data4 = data1 + data2 or [] # Right [1, 2, 3], 使用 or 取 data2 的默认值为 [], 当 data2 为 None/Undefined 时,取空列表 [] 进行计算 -data5 = data1 + data2 # Error: can only concatenate list (not "NoneType") to list -``` - -## 7. 如何修改/删除 list 中的元素? - -修改 list 中的元素分为两种方式: - -- 直接修改 list 某个索引处的值,使用 slice 切片 - -```python -_index = 1 -_args = ["a", "b", "c"] -_args = _args[:index] + ["x"] + _args[index+1:] # 修改list索引为1的元素为"x", ["a", "x", "c"] -``` - -- 根据某个条件修改 list 当中的元素,使用 list comprehension 列表推导式 - -```python -_args = ["a", "b", "c"] -_args = ["x" if a == "b" else a for a in _args] # 将list当中值为"b"的值都修改为"x", ["a", "x", "c"] -``` - -删除 list 中的元素分为两种方式: - -- 使用 list for 推导表达式中 if 过滤条件 -- 使用 filter 表达式对 list 进行元素过滤 - -比如想要删除一个列表 `[1, 2, 3, 4, 5]` 中大于 2 的数字,则在 KCL 中可以写为: - -```python -originList = [1, 2, 3, 4, 5] -oneWayDeleteListItem = [item for item in originList if item <= 2] -anotherWayDeleteListItem = filter item in originList { - item <= 2 -} -``` - -输出如下结果 - -```yaml -originList: - - 1 - - 2 - - 3 - - 4 - - 5 -oneWayDeleteListItem: - - 1 - - 2 -anotherWayDeleteListItem: - - 1 - - 2 -``` - -## 8. 怎样写 for 循环?怎样理解和使用 list comprehension 列表推导式 和 dict comprehension 字典推导式 ? - -KCL 目前仅支持函数式/声明式的推导式 for 循环方式,可以按照如下方式遍历 dict 和 list 变量: - -list 推导式具体形式为(其中推导式两边使用方括号 `[]`): - -```txt -[expression for expr in sequence1 - if condition1 - for expr2 in sequence2 - if condition2 - for expr3 in sequence3 ... - if condition3 - for exprN in sequenceN - if conditionN] -``` - -dict 推导式具体形式为(其中推导式两边使用花括号 `{}`): - -```txt -{expression for expr in sequence1 - if condition1 - for expr2 in sequence2 - if condition2 - for expr3 in sequence3 ... - if condition3 - for exprN in sequenceN - if conditionN} -``` - -上述推导式中的 `if` 表示过滤条件,满足条件的表达式 `expr` 才会生成到新的 list 或 dict 中 - -list 推导式举例: - -```python -_listData = [1, 2, 3, 4, 5, 6] -_listData = [l * 2 for l in _listData] # _listData中所有元素都乘以2,[2, 4, 6, 8, 10, 12] -_listData = [l for l in _listData if l % 4 == 0] # 筛选出_listData中可以被4整除的所有元素,[4, 8, 12] -_listData = [l + 100 if l % 8 == 0 else l for l in _listData] # 遍历_listData, 当其中的元素可以被8整除时,将该元素加100,否则保持不变, [4, 108, 12] -``` - -注意上述代码中第 3 行和第 4 行两个 `if` 的区别: - -- 第一个 `if` 表示 list 变量 `_listData` 本身的推导式过滤条件,后不能跟 `else`,满足该过滤条件的元素会继续放在该列表中,不满足条件的元素被剔除,有可能会使列表长度发生变化 -- 第二个 `if` 表示 list 迭代变量 `l` 的选择条件,表示 `if-else` 三元表达式,后必须跟 `else`,不论是否满足该条件,产生的元素仍然在该列表中,列表长度不变 - -dict 推导式举例: - -```python -_dictData = {key1 = "value1", key2 = "value2"} -_dictData = {k = _dictData[k] for k in _dictData if k == "key1" and _dictData[k] == "value1"} # 将_dictData中key为"key1", value为"value1"的元素筛选出来, {"key1": "value1"} -``` - -使用推导式获得 dict 所有 key: - -```python -dictData = {key1 = "value1", key2 = "value2"} -dictDataKeys = [k for k in _dictData] # ["key1", "key2"] -``` - -使用推导式对 dict 按照 key 的字典序升序进行排序: - -```python -dictData = {key3 = "value3", key2 = "value2", key1 = "value1"} # {'key3': 'value3', 'key2': 'value2', 'key1': 'value1'} -dictSortedData = {k = dictData[k] for k in sorted(dictData)} # {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'} -``` - -多级推导式举例: - -```python -array1 = [1, 2, 3] -array2 = [4, 5, 6] -data = [a1 + a2 for a1 in array1 for a2 in array2] # [5, 6, 7, 6, 7, 8, 7, 8, 9] len(data) == len(array1) * len(array2) -``` - -双变量循环(for 推导表达式支持 list 的索引迭代以及 dict 的 value 迭代,可以简化 list/dict 迭代过程代码书写): - -- list - -```python -data = [1000, 2000, 3000] -# 单变量循环 -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# 双变量循环 -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# 使用_忽略循环变量 -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -- dict - -```python -data = {key1 = "value1", key2 = "value2"} -# 单变量循环 -dataKeys1 = [k for k in data] # ["key1", "key2"] -dataValues1 = [data[k] for k in data] # ["value1", "value2"] -# 双变量循环 -dataKeys2 = [k for k, v in data] # ["key1", "key2"] -dataValues2 = [v for k, v in data] # ["value1", "value2"] -dataFilter = {k = v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# 使用_忽略循环变量 -dataKeys3 = [k for k, _ in data] # ["key1", "key2"] -dataValues3 = [v for _, v in data] # ["value1", "value2"] -``` - -## 9. 怎样写 if 条件语句? - -KCL 支持两种方式书写 if 条件语句: - -- if-elif-else 块语句,其中 elif 和 else 块均可省略,并且 elif 块可以使用多次 - -```python -success = True -_result = "failed" -if success: - _result = "success" -``` - -```python -success = True -if success: - _result = "success" -else: - _result = "failed" -``` - -```python -_result = 0 -if condition == "one": - _result = 1 -elif condition == "two": - _result = 2 -elif condition == "three": - _result = 3 -else: - _result = 4 -``` - -- 条件表达式 ` if else `, 类似于 C 语言当中的 ` ? : ` 三元表达式 - -```python -success = True -_result = "success" if success else "failed" -``` - -注意:在书写 if-elif-else 块语句时注意书写 if 条件后的冒号 `:` 以及保持缩进的统一 - -除此之外,还可以在 list 或者 dict 结构中直接书写条件表达式(不同的是,在结构中书写的 if 表达式中需要书写的值而不是语句): - -- list - -```python -env = "prod" -data = [ - "env_value" - ":" - if env == "prod": - "prod" # 书写需要添加到 data 中的值,而不是语句 - else: - "other_prod" -] # ["env_value", ":", "prod"] -``` - -- dict - -```python -env = "prod" -config = { - if env == "prod": - MY_PROD_ENV = "prod_value" # 书写需要添加到 config 中的键-值对,而不是语句 - else: - OTHER_ENV = "other_value" -} # {"MY_PROD_ENV": "prod_value"} -``` - -## 10. 怎样表达 "与" "或" "非" 等逻辑运算? - -在 KCL 中,使用 `and` 表示"逻辑与", 使用 `or` 表示"逻辑或", 使用 `not` 表示"非", 与 C 语言当中的 `&&`, `||` 和 `~` 语义一致; - -```python -done = True -col == 0 -if done and (col == 0 or col == 3): - ok = 1 -``` - -对于整数的"按位与", "按位或"和"按位异或",在 KCL 中使用 `&`, `|` 和 `^` 运算符表示, 与 C 语言当中的 `&`, `|` 和 `^` 语义一致; - -```python -value = 0x22 -bitmask = 0x0f - -assert (value & bitmask) == 0x02 -assert (value & ~bitmask) == 0x20 -assert (value | bitmask) == 0x2f -assert (value ^ bitmask) == 0x2d -``` - -"逻辑或" `or` 的妙用:当需要书写诸如 `A if A else B` 类似的模式时,可以使用 `A or B` 进行简化,比如如下代码: - -```python -value = [0] -default = [1] -x0 = value if value else default -x1 = value or default # 使用 value or default 代替 value if value else default -``` - -## 11. 如何判断变量是否为 None/Undefined、字符串/dict/list 是否为空? - -请注意,在 if 表达式的条件判断中,`False`、`None`、`Undefined`、数字 `0`、空列表 `[]`、空字典 `{}` 和空字符串 `""`, `''`, `""""""`, `''''''` 都被视为值为 `假` 的表达式。 - -比如判断一个字符串变量 `strData` 既不为 `None/Undefined` 也不为空字符串时(字符串长度大于 0),就可以简单的使用如下表达式: - -```python -strData = "value" -if strData: - isEmptyStr = False -``` - -空字典和空列表判断举例: - -```python -_emptyList = [] -_emptyDict = {} -isEmptyList = False if _emptyList else True -isEmptyDict = False if _emptyDict else True -``` - -YAML 输出为: - -```yaml -isEmptyList: true -isEmptyDict: true -``` - -或者使用布尔函数 `bool` 进行判断 - -```python -_emptyList = [] -_emptyDict = {} -isEmptyList = bool(_emptyList) -isEmptyDict = bool(_emptyDict) -``` - -## 12. 字符串怎样拼接、怎样格式化字符串、怎样检查字符串前缀、后缀?怎样替换字符串内容? - -- KCL 中可以使用 `+` 运算符连接两个字符串 - -```python -data1 = "string1" + "string2" # "string1string2" -data2 = "string1" + " " + "string2" # "string1 string2" -``` - -- KCL 中目前存在两种格式化字符串的方式: - - 字符串变量的 format 方法 `"{}".format()` - - 字符串插值 `${}` - -```python -hello = "hello" -a = "{} world".format(hello) -b = "${hello} world" -``` - -注意,如果想在 `"{}".format()` 中单独使用 `{` 字符或者 `}`, 则需要使用 `{{` 和 `}}` 分别对 `{` 和 `}` 进行转义,比如转义一个 JSON 字符串如下代码: - -```python -data = "value" -jsonData = '{{"key": "{}"}}'.format(data) -``` - -输出 YAML 为: - -```yaml -data: value -jsonData: '{"key": "value"}' -``` - -注意,如果想在 `${}` 插值字符串中单独使用 `$` 字符,则需要使用 `$$` 对 `$` 进行转义 - -```python -world = "world" -a = "hello {}".format(world) # "hello world" -b = "hello ${world}" # "hello world" -c = "$$hello ${world}$$" # "$hello world$" -c2 = "$" + "hello ${world}" + "$" # "$hello world$" -``` - -输出 YAML 为: - -```yaml -world: world -a: hello world -b: hello world -c: $hello world$ -c2: $hello world$ -``` - -- KCL 中使用字符串的 `startswith` 和 `endswith` 方法检查字符串的前缀和后缀 - -```python -data = "length" -isEndsWith = data.endswith("th") # True -isStartsWith = "length".startswith('len') # True -``` - -- KCL 中使用字符串的 replace 方法或者 regex.replace 函数替换字符串的内容 - -```python -import regex -data1 = "length".replace("len", "xxx") # 使用"xxx"替换"len", "xxxgth" -data2 = regex.replace("abc123", r"\D", "0") # 替换"abc123"中的所有非数字为"0", "000123" -``` - -其中,`r"\D"` 表示不需要使用 `\\` 转义 `\D` 中的反斜杠 `\`,多用于正则表达式字符串中 - -此外,我们可以在字符串格式化表达式中插入索引占位符或者关键字占位符用于格式化多个字符串 - -- 索引占位符 - -```python -x = '{2} {1} {0}'.format('directions', 'the', 'Read') -y = '{0} {0} {0}'.format('string') -``` - -输出为: - -```yaml -x: Read the directions -y: string string string -``` - -- 关键字占位符 - -```python -x = 'a: {a}, b: {b}, c: {c}'.format(a = 1, b = 'Two', c = 12.3) -``` - -输出为: - -```yaml -x: "a: 1, b: Two, c: 12.3" -``` - -## 13. 字符串中使用单引号和双引号的区别是什么? - -KCL 单引号和双引号字符串几乎没有区别。唯一的区别是,不需要在单引号字符串中使用 `\"` 转义双引号 `"`,不需要在双引号字符串中使用 `\'` 转义单引号引号 `'`。 - -```python -singleQuotedString = 'This is my book named "foo"' # Don’t need to escape double quotes in single quoted strings. -doubleQuotedString = "This is my book named 'foo'" # Don’t need to escape single quotes in double quoted strings. -``` - -此外在 KCL 中,使用三个单引号或者三个双引号组成的长字符串,无需在其中对单引号或者三引号进行转义 (除字符串首尾),比如如下例子: - -```python -longStrWithQuote0 = """Double quotes in long strings "(not at the beginning and end)""" -longStrWithQuote1 = '''Double quotes in long strings "(not at the beginning and end)''' -longStrWithQuote2 = """Single quotes in long strings '(not at the beginning and end)""" -longStrWithQuote3 = '''Single quotes in long strings '(not at the beginning and end)''' -``` - -输出 YAML: - -```yaml -longStrWithQuote0: Double quotes in long strings "(not at the beginning and end) -longStrWithQuote1: Double quotes in long strings "(not at the beginning and end) -longStrWithQuote2: Single quotes in long strings '(not at the beginning and end) -longStrWithQuote3: Single quotes in long strings '(not at the beginning and end) -``` - -## 14. 如何编写跨行的长字符串? - -KCL 中可以使用单引号字符串 + 换行符 `\n` 或者三引号字符串书写一个多行字符串,并且可以借助续行符 `\` 优化 KCL 字符串的形式,比如对于如下代码中的三个多行字符串变量,它们的制是相同的: - -```python -string1 = "The first line\nThe second line\nThe third line\n" -string2 = """The first line -The second line -The third line -""" -string3 = """\ -The first line -The second line -The third line -""" # 推荐使用 string3 长字符串的书写形式 -``` - -输出 YAML 为: - -```yaml -string1: | - The first line - The second line - The third line -string2: | - The first line - The second line - The third line -string3: | - The first line - The second line - The third line -``` - -## 15. 如何使用正则表达式? - -通过在 KCL 中导入正则表达式库 `import regex` 即可使用正则表达式,其中包含了如下函数: - -- **match**: 正则表达式匹配函数,根据正则表达式对输入字符串进行匹配,返回 bool 类型表示是否匹配成功 -- **split**: 正则表达式分割函数,根据正则表达式分割字符串,返回分割字串的列表 -- **replace**: 正则表达式替换函数,替换字符串中所有满足正则表达式的子串,返回被替换的字符串 -- **compile**: 正则表达式编译函数,返回 bool 类型表示是否是一个合法的正则表达式 -- **search**: 正则表达式搜索函数,搜索所有满足正则表达式的子串,返回子串的列表 - -使用举例: - -```python -import regex - -regex_source = "Apple,Google,Baidu,Xiaomi" -regex_split = regex.split(regex_source, ",") -regex_replace = regex.replace(regex_source, ",", "|") -regex_compile = regex.compile("$^") -regex_search = regex.search("aaaa", "a") -regex_find_all = regex.findall("aaaa", "a") -regex_result = regex.match("192.168.0.1", "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$") # 判断是否是一个IP字符串 -regex_result_false = regex.match("192.168.0,1", "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$") # 判断是否是一个IP字符串 -``` - -输出 YAML: - -```yaml -regex_source: Apple,Google,Baidu,Xiaomi -regex_split: - - Apple - - Google - - Baidu - - Xiaomi -regex_replace: Apple|Google|Baidu|Xiaomi -regex_compile: true -regex_search: true -regex_find_all: - - a - - a - - a - - a -regex_result: true -regex_result_false: false -``` - -对于比较长的正则表达式,还可以使用 r-string 忽略 `\` 符号的转义简化正则表达式字符串的书写: - -```python -import regex - -isIp = regex.match("192.168.0.1", r"^(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)$") # 判断是否是一个IP字符串 -``` - -更多举例: - -```python -import regex - -schema Resource: - cpu: str = "1" - memory: str = "1024Mi" - disk: str = "10Gi" - check: - regex.match(cpu, r"^([+-]?[0-9.]+)([m]*[-+]?[0-9]*)$"), "cpu must match specific regular expression" - regex.match(memory, r"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"), "memory must match specific regular expression" - regex.match(disk, r"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"), "disk must match specific regular expression" -``` - -```python -import regex - -schema Env: - name: str - value?: str - check: - len(name) <= 63, "a valid env name must be no more than 63 characters" - regex.match(name, r"[A-Za-z_][A-Za-z0-9_]*"), "a valid env name must start with alphabetic character or '_', followed by a string of alphanumeric characters or '_'" -``` - -## 16. KCL 当中的 schema 是什么含义? - -schema 是 KCL 中一种语言元素,用于定义配置数据的类型,像 C 语言中的 struct 或者 Java 中的 class 一样,在其中可以定义属性,每种属性具有相应的类型。 - -## 17. 如何声明 schema? - -KCL 中使用 schema 关键字可以定义一个结构,在其中可以申明 schema 的各个属性 - -```python -# 一个Person结构,其中具有属性字符串类型的firstName, 字符串类型的lastName, 整数类型的age -schema Person: - firstName: str - lastName: str - # age属性的默认值为0 - age: int = 0 -``` - -一个复杂例子: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels: {str:str} -``` - -在上面的代码中,`cpu` 和 `memory` 被定义为整数 int 类型;`name`,`image` 和 `service` 是字符串 str 类型; `command` 是字符串类型的列表; labels 是字典类型,其键类型和值类型均为字符串。 - -## 18. 如何为 schema 属性添加 "不可变"、"必选" 约束? - -KCL 中使用 `?` 运算符定义一个 schema 的"可选"约束,schema 属性默认都是"必选"的 - -```python -# 一个Person结构,其中具有属性字符串类型的firstName, 字符串类型的lastName, 整数类型的age -schema Person: - firstName?: str # firstName是一个可选属性,可以赋值为None/Undefined - lastName?: str # age是一个可选属性,可以赋值为None/Undefined - # age属性的默认值为0 - age: int = 18 # age是一个必选属性,不能赋值为None/Undefined,并且是一个不可变属性 - age = 10 # Error, age是一个不可变的属性 -``` - -## 19. 如何为 schema 中的属性编写校验规则? - -在 schema 定义当中可以使用 check 关键字编写 schema 属性的校验规则, 如下所示,check 代码块中的每一行都对应一个条件表达式,当满足条件时校验成功,当不满足条件时校验失败。条件表达式后可跟 `, "check error message"` 表示当校验失败时需要显示的信息 - -```python -import regex - -schema Sample: - foo: str # Required, 不能为None/Undefined, 且类型必须为str - bar: int # Required, 不能为None/Undefined, 且类型必须为int - fooList: [int] # Required, 不能为None/Undefined, 且类型必须为int列表 - color: "Red" | "Yellow" | "Blue" # Required, 字面值联合类型,且必须为"Red", "Yellow", "Blue"中的一个,枚举作用 - id?: int # Optional,可以留空,类型必须为int - - check: - bar >= 0 # bar必须大于等于0 - bar < 100 # bar必须小于100 - len(fooList) > 0 # fooList不能为None/Undefined,并且长度必须大于0 - len(fooList) < 100 # fooList不能为None/Undefined,并且长度必须小于100 - regex.match(foo, "^The.*Foo$") # regex 正则表达式匹配 - bar in range(100) # range, bar范围只能为1到99 - bar in [2, 4, 6, 8] # enum, bar只能取2, 4, 6, 8 - bar % 2 == 0 # bar必须为2的倍数 - all foo in fooList { - foo > 1 - } # fooList中的所有元素必须大于1 - any foo in fooList { - foo > 10 - } # fooList中至少有一个元素必须大于10 - abs(id) > 10 if id # check if 表达式,当 id 不为空时,id的绝对值必须大于10 -``` - -此外,上述 check 当中比较表达式还可以简写为: - -```python -0 <= bar < 100 -0 < len(fooList) < 100 -``` - -综上所述,KCL Schema 中支持的校验类型为: - -| 校验类型 | 使用方法 | -| -------- | ---------------------------------------------------------- | -| 范围校验 | 使用 `<`, `>` 等比较运算符 | -| 正则校验 | 使用 `regex` 系统库中的 `match` 等方法 | -| 长度校验 | 使用 `len` 内置函数,可以求 `list/dict/str` 类型的变量长度 | -| 枚举校验 | 使用字面值联合类型 | -| 非空校验 | 使用 schema 的可选/必选属性 | -| 条件校验 | 使用 check if 条件表达式 | - -## 20. 如何为 schema 及其属性添加文档注释? - -一个完整的 schema 属性注释使用三引号字符串表示,其中的结构如下所示: - -```python -schema Person: - """The schema person definition - - Attributes - ---------- - name : str - The name of the person - age : int - The age of the person - - See Also - -------- - Son: - Sub-schema Son of the schema Person. - - Examples - -------- - person = Person { - name = "Alice" - age = 18 - } - """ - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -``` - -## 21. 如何基于 schema 编写配置?多个配置之间如何复用公共的配置? - -在 schema 实例化的过程中可以使用解包运算符 `**` 对公共的配置进行展开 - -```python -schema Boy: - name: str - age: int - hc: int - -schema Girl: - name: str - age: int - hc: int - -config = { - age = 18 - hc = 10 -} - -boy = Boy { - **config - name = "Bob" -} -girl = Girl { - **config - name = "Alice" -} -``` - -输出 YAML 为: - -```yaml -config: - age: 18 - hc: 10 -boy: - name: Bob - age: 18 - hc: 10 -girl: - name: Alice - age: 18 - hc: 10 -``` - -## 22. 基于 schema 编写配置时如何覆盖 schema 属性的默认值? - -在定义 schema 后,可以使用 schema 名称实例化相应的配置,使用 `:` 运算符对 schema 默认值进行 union, 使用 `=` 对 schema 默认值进行覆盖。对于 int/float/bool/str 类型的 schema 属性,union 和覆盖的效果相同; 对于 list/dict/schema 类型的 schema 属性,union 和覆盖的效果不同; - -```python -schema Meta: - labels: {str:str} = {"key1" = "value1"} - annotations: {str:str} = {"key1" = "value1"} - -meta = Meta { - labels: {"key2": "value2"} - annotations = {"key2" = "value2"} -} -``` - -输出 YAML 为: - -```yaml -meta: - labels: - key1: value1 - key2: value2 - annotations: - key2: value2 -``` - -## 23. 如何通过继承来复用 schema 定义? - -可以在 schema 定义处声明 schema 需要继承的 schema 名称: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 - -# An employee **is** a person, and has some additional information. -schema Employee(Person): - bankCard: int - nationality: str - -employee = Employee { - firstName = "Bob" - lastName = "Green" - age = 18 - bankCard = 123456 - nationality = "China" -} -``` - -输出 YAML 为: - -```yaml -employee: - firstName: Bob - lastName: Green - age: 18 - bankCard: 123456 - nationality: China -``` - -注意: KCL 只允许 schema 单继承 - -## 24. 如何通过组合复用 schema 逻辑? - -可以使用 KCL schema mixin 复用 schema 逻辑,mixin 一般被用于 schema 内部属性的分离数据,和数据映射等功能,可以使 KCL 代码更具模块化和声明性。注意不同的 mixin 之间的混入属性不建议定义依赖关系,会使得 mixin 使用方式复杂,一般一个 mixin 中作不超过三个属性混入即可。 - -```python -schema Person: - mixin [FullNameMixin, UpperMixin] - - firstName: str - lastName: str - fullName: str - upper: str - -schema FullNameMixin: - fullName = "{} {}".format(firstName, lastName) - -schema UpperMixin: - upper = fullName.upper() - -person = Person { - firstName = "John" - lastName = "Doe" -} -``` - -输出 YAML 为: - -```yaml -person: - firstName: John - lastName: Doe - fullName: John Doe - upper: JOHN DOE -``` - -## 25. 如何导入其他 KCL 文件? - -通过 import 关键字可以导入其他 KCL 文件,KCL 配置文件被组织为模块。单个 KCL 文件被视为一个模块,目录被视为一个包,作为一个特殊的模块。import 关键字支持相对路径导入和绝对路径导入两种方式 - -比如对于如下目录结构: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ │── service1.k - │ └── service2.k - └── mixin - └── mixin1.k -``` - -对于 `main.k`, 相对路径导入和绝对路径导入分别可以表示为: - -```python -import service # 绝对路径导入, 根目录为kcl.mod所在的路径 -import mixin # 绝对路径导入, 根目录为kcl.mod所在的路径 - -import .model1 # 相对路径导入, 当前目录模块 -import ..service # 相对路径导入, 父目录 -import ...root # 相对路径导入, 父目录的父目录 -``` - -注意,对于 KCL 的入口文件 `main.k`, 其不能导入自身所在的文件夹,否则会发生循环导入错误: - -```python -import model # Error: recursively loading -``` - -## 26. 什么情况下可以省略 import ? - -除了 main 包当中的同一文件夹下的 KCL 可以相互引用而不需通过 import 相互引用,比如对于如下目录结构: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ │── service1.k - │ └── service2.k - └── mixin - └── mixin1.k -``` - -当 main.k 作为 KCL 命令行入口文件时, model 文件夹中的 main.k, model1.k 和 model2.k 中的变量不能相互引用,需要通过 import 导入,但是 service 文件夹中的 service1.k 和 service2.k 当中的变量可以互相引用,忽略 import - -service1.k - -```python -schema BaseService: - name: str - namespace: str -``` - -service2.k - -```python -schema Service(BaseService): - id: str -``` - -## 27. 有一行代码太长了,如何在语法正确的情况下优雅地换行? - -在 KCL 中可以使用续行符 `\` 进行换行, 并且在字符串中也可以使用 `\` 表示续行 - -长字符串连接续行举例: - -```python -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " -``` - -推导表达式续行举例: - -```python -data = [1, 2, 3, 4] -dataNew = [ - d + 2 \ - for d in data \ - if d % 2 == 0 -] -``` - -if 表达式续行举例: - -```python -condition = 1 -data1 = 1 \ - if condition \ - else 2 -data2 = 2 \ -if condition \ -else 1 -``` - -三引号字符串内部续行举例: - -```python -longString = """\ -The first line\ -The continue second line\ -""" -``` - -注意: 使用续行符 `\` 的同时缩进的保持, 如下所示: - -错误用例: - -```python -data1 = [ - 1, 2, - 3, 4 \ -] # Error, 需要保持右方括号]的缩进 - -data2 = [ - 1, 2, - 3, 4 -] # Error, 需要数字1和3的缩进统一 -``` - -正确用例: - -```python -data1 = [ - 1, 2, - 3, 4 -] # Right, 带缩进的列表定义 - -data2 = [ \ - 1, 2, \ - 3, 4 \ -] # Right, 使用续行符的列表定义, 实际效果是单行列表 - -data3 = [ \ - 1, 2, \ - 3, 4 \ -] # Right, 使用续行符的列表定义, 无需保持缩进, 实际效果是单行列表 -``` - -## 28. \*_, _ 这些符号是什么意思? - -- `**`, `*` 出现在 dict/list 外部时分别表示乘方运算符和乘法运算符 - -```python -data1 = 2 ** 4 # 2的4次方等于16 -data2 = 2 * 3 # 2乘以3等于6 -``` - -- `**`, `*` 出现在 dict/list 内部时表示解包运算符,经常用于 list/dict 的解包和合并, 与 Python 当中的解包运算符用法相同 - -dict 的解包: - -```python -data = {"key1" = "value1"} -dataUnpack = {**data, "key2" = "value2"} # 将data解包合并入dataUnpack中, {"key1": "value1", "key2": "value2"} -``` - -list 的解包: - -```python -data = [1, 2, 3] -dataUnpack = [*data, 4, 5, 6] # 将data解包合并入dataUnpack中, [1, 2, 3, 4, 5, 6] -``` - -## 29. 如何取 list/dict/schema 的子元素 - -在 KCL 中可以使用 select 表达式或者 subscript 表达式取 list/dict/schema 的子元素 - -- 对于 list 类型,可以使用 `[]` 取列表中的某一个元素或者某一些元素 - -```python -data = [1, 2, 3] # 定义一个整数类型的数组 -theFirstItem = data[0] # 取数组中索引为0的元素,即第一个元素 1 -theSecondItem = data[1] # 取数组中索引为1的元素,即第一个元素 2 -``` - -注意:索引的取值不能超出列表的长度,否则会发生错误,可以使用 `len` 函数获得数组的长度 - -```python -data = [1, 2, 3] -dataLength = len(data) # 数组长度为3 -item = data[3] # 发生数组索引越界错误 -``` - -此外,还可以使用负数索引倒序获得列表中的元素 - -```python -data = [1, 2, 3] -item1 = data[-1] # 取数组中索引为-1的元素,即最后一个元素 3 -item2 = data[-2] # 取数组中索引为-2的元素,即倒数第二个元素 2 -``` - -综上,列表索引的取值范围为 `[-len, len - 1]` - -当想要取得列表的一部分时,可以在 `[]` 中使用切片表达式,其具体语法为 `[<列表开始索引>:<列表终止索引>:<列表遍历步长>]`,注意索引开始终止的取值区间为 `左闭右开[<列表开始索引>, <列表终止索引>)`,注意三个参数均可省略不写 - -```python -data = [1, 2, 3, 4, 5] -dataSlice0 = data[1:2] # 取列表中索引开始为 1, 终止索引为 2 的元素集合 [2] -dataSlice1 = data[1:3] # 取列表中索引开始为 1, 终止索引为 3 的元素集合 [2, 3] -dataSlice2 = data[1:] # 取列表中索引开始为 1, 终止索引为 最后一个索引 的元素集合 [2, 3, 4, 5] -dataSlice3 = data[:3] # 取列表中索引开始为 第一个索引, 终止索引为 3 的元素集合 [1, 2, 3] -dataSlice4 = data[::2] # 取列表中索引开始为 第一个索引, 终止索引为 最后一个索引 的元素集合(步长为2) [1, 3, 5] -dataSlice5 = data[::-1] # 反转一个列表,[5, 4, 3, 2, 1] -dataSlice6 = data[2:1] # 当开始,终止,步长三个参数组合不满足条件时返回空列表 [] - -``` - -- 对于 dict/schema 类型,可以使用 `[]` 和 `.` 两种方式取 dict/schema 中的子元素 - -```python -data = {key1: "value1", key2: "value2"} -data1 = data["key1"] # "value1" -data2 = data.key1 # "value1" -data3 = data["key2"] # "value2" -data4 = data.key2 # "value2" -``` - -```python -schema Person: - name: str = "Alice" - age: int = 18 - -person = Person {} -name1 = person.name # "Alice" -name2 = person["name"] # "Alice" -age1 = person.age # 18 -age2 = person.age # 18 -``` - -当键值在 dict 中不存在时,返回未定义值 `Undefined` - -```python -data = {key1 = "value1", key2 = "value2"} -data1 = data["not_exist_key"] # Undefined -data2 = data.not_exist_key # Undefined -``` - -可以使用 `in` 关键字判断某个键值是否在 dict/schema 中存在 - -```python -data = {key1 = "value1", key2 = "value2"} -exist1 = "key1" in data # True -exist2 = "not_exist_key" in data # False -``` - -当键值中存在 `.` 时或者需要运行时取一个键值变量对应的值时,只能使用 `[]` 方式,如无特殊情况,使用 `.` 即可: - -```python -name = "key1" -data = {key1 = "value1", key2 = "value2", "contains.dot" = "value3"} -data1 = data[name] # "value1" -data2 = data["contains.dot"] # "value3" -# 注意这样子是不对的 data3 = data.contains.dot -``` - -注意:上述取子元素的运算符不能对非 list/dict/schema 集合类型的值进行操作,比如整数,空值等。 - -```python -data = 1 -data1 = 1[0] # error -``` - -```python -data = None -data1 = None[0] # error -``` - -在取集合类型的子元素时往往要进行非空或者长度判断: - -```python -data = [] -item = data[0] if data else None -``` - -可以使用非空判断符 `?` 添加在 `[]`, `.` 的前面表示进行 if 非空判断,当不满足条件时返回 None,比如上述代码可以简化为: - -```python -data = [] -item1 = data?[0] # 当data为空时,返回空值 None -item2 = data?[0] or 1 # 当data为空时,返回空值 None, 如果不想返回 None, 还可与 or 运算符连用返回其他默认值 -``` - -使用 `?` 可以进行递归调用, 避免复杂繁琐的非空判断 - -```python -data = {key1.key2.key3 = []} -item = data?.key1?.key2?.key3?[0] -``` - -## 30. 如何在 KCL 代码中判断变量的类型 - -KCL typeof built-in 函数可以在该函数执行时立即返回一个变量的类型(字符串表示)用于类型断言 - -用法举例: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person{} -t3 = typeof(_x1) - -_x2 = pkg.Person{} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# 输出 -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -## 31. 关键字和 KCL 变量名冲突了可以怎么解决? - -对于与关键字冲突的标识符,可以在标识符前添加 `$` 前缀用于定义一个关键字标识符,比如如下代码中使用了 `if`, `else` 等关键字作为标识符并且可以得到相应的 YAML 输出 - -```python -$if = 1 -$else = "s" - -schema Data: - $filter: str = "filter" - -data = Data {} -``` - -输出 YAML: - -```yaml -data: - filter: filter -if: 1 -else: s -``` - -注意:在非关键字标识符前添加 `$` 前缀的效果与不添加相同 - -```python -_a = 1 -$_a = 2 # 等效于 `_a = 2` -``` - -## 32. KCL 的内置类型是 KCL 的关键字吗?是否可用于变量的定义 - -KCL 的内置类型包括 `int`, `float`, `bool` 和 `str` 四种类型,它们不是 KCL 的关键字,可用于变量的定义,比如如下代码: - -```py -int = 1 -str = 2 -``` - -输出 YAML 为: - -```yaml -int: 1 -str: 2 -``` - -注意:如无特殊需求,不建议变量的名称取这些内置类型,因为在有些语言当中,它们作为关键字存在 - -## 33. 如何在 KCL 中实现类似 Enum 枚举的功能 - -有两种方式可以在 KCL 中实现 Enum 枚举的方式 - -- (推荐)使用**字面值类型**的**联合类型** - -```python -schema Person: - name: str - gender: "Male" | "Female" - -person = Person { - name = "Alice" - gender = "Male" # gender 只能为 "Male" 或者 "Female" -} -``` - -一个复杂例子 - -```python -schema Config: - colors: ["Red" | "Yellow" | "Blue"] # colors 是一个枚举数组 - -config = Config { - colors = [ - "Red" - "Blue" - ] -} -``` - -- 使用 schema 的 check 表达式 - -```python -schema Person: - name: str - gender: "Male" | "Female" - - check: - gender in ["Male", "Female"] - -person = Person { - name = "Alice" - gender = "Male" # gender 只能为 "Male" 或者 "Female" -} -``` - -## 34. 如何求字典 dict 的长度 - -在 KCL 中可以使用 `len` 内置函数直接求 dict 的长度 - -```python -len1 = len({k1: "v1"}) # 1 -len2 = len({k1: "v1", k2: "v2"}) # 2 -varDict = {k1 = 1, k2 = 2, k3 = 3} -len3 = len(varDict) # 3 -``` - -此外,使用 `len` 函数还可以求 `str` 和 `list` 类型长度 - -```python -len1 = len("hello") # 5 -len2 = len([1, 2, 3]) # 3 -``` - -## 35. 如何在 KCL 中编写带条件的配置 - -在 KCL 中,除了支持在顶级的语句中书写 `if-elif-else` 条件表达式以外,还支持在 KCL 复杂结构(list/dict/schema)中书写条件表达式,支持带条件的配置书写。 - -```python -x = 1 -# List 结构中的 if 条件语句 -dataList = [ - if x == 1: 1 -] -# Dict 结构中的 if 条件语句 -dataDict = { - if x == 1: key1 = "value1" # 可以同一行书写 - elif x == 2: - key2 = "value2" # 可以跨行书写 -} -# Schema 结构中的 if 条件语句 -schema Config: - id?: int -env = "prod" -dataSchema = Config { - if env == "prod": - id = 1 - elif env == "pre": - id = 2 - elif env == "test": - id = 3 -} -``` - -## 36. KCL 中的 == 运算符会作深度比较嘛? - -KCL 中的 `==` 运算符 - -- 对于基本类型 `int`, `float`, `bool`, `str` 的变量是直接比较它们的值是否相等 -- 对于复合类型 `list`, `dict`, `schema` 的变量会深度递归地比较其中的子元素是否相等 - - `list` 类型深度递归递归比较每个索引的值以及长度 - - `dict`/`schema` 类型深度递归比较每个属性的值(与属性出现的顺序无关) - -```python -print([1, 2] == [1, 2]) # True -print([[0, 1], 1] == [[0, 1], 1]) # True -print({k1 = 1, k2 = 2} == {k2 = 2, k1 = 1}) # True - -print([1, 2] == [1, 2, 3]) # False -print({k1 = 1, k2 = 2, k3 = 3} == {k2 = 2, k1 = 1}) # False -``` - -## 37. 如何对 KCL 中已有的配置块进行修改 - -在 KCL 中,存在三种**属性运算符** `=`、`+=`、`:`,可以用来对已有配置块进行修改,并且可以使用**解包运算符** `**` 等"继承"一个配置块的所有属性字段和值。 - -- `=` 属性运算符表示覆盖,使用 `=` 运算符可以对属性进行有优先级的覆盖/删除,(如果是用 `Undefined` 覆盖则表示删除) -- `+=` 属性运算符表示添加,一般用于对 list 类型的属性添加子元素,`+=` 属性运算符后跟的操作数类型也只能为 list 类型 -- `:` 属性运算符表示幂等合并,当值发生冲突时进行报错,不冲突时进行合并 - -### 覆盖属性运算符= - -最常使用的属性运算符是 `=`,表示一个属性的赋值,多次对同一个属性进行使用时表示覆盖,对于 `{}` 外的全局变量或者 `{}` 内的属性均表示使用值覆盖这个全局变量或者属性 - -```python -data = { # 定义一个字典类型的变量 data - a = 1 # 使用 = 在 data 中声明一个值为 1 的属性 a - b = 2 # 使用 = 在 data 中声明一个值为 1 的属性 b -} # 最终 data 的值为 {"a": 1, "b": 1} -``` - -在 schema 实例化处也可以使用覆盖属性运算符实现对 schema 默认值的覆盖效果,一般在创建新的 schema 实例时如无特殊的需求,一般使用 `=` 即可 - -```python -schema Person: - name: str = "Alice" # schema Person 的 name 属性具有默认值 "Alice" - age: int = 18 # schema Person 的 age 属性具有默认值 18 - -bob = Person { - name = "Bob" # "Bob" -> "Alice", 属性 name 的值 "Bob" 的值会覆盖 schema Person name 属性的默认值 "Alice" - age = 10 # 10 -> 18, 属性 age 的值 10 的值会覆盖 schema Person age 属性的默认值 18 -} # 最终 bob 的值为 {"name": "Bob", age: 10} -``` - -### 插入属性运算符 += - -插入属性运算符表示对一个属性的值进行原地添加,比如向一个 list 类型的属性添加新的元素 - -```python -data = { - args = ["kcl"] # 使用 = 在 data 中声明一个值为 ["kcl"] 的属性 args - args += ["-Y", "settings.yaml"] # 使用 += 运算符向属性 args 中添加两个元素"-Y", "settings.yaml" -} # 最终 data 的值为 {"args": ["kcl", "-Y", "settings.yaml"]} -``` - -### 合并属性运算符: - -合并属性运算符表示对一个属性的不同配置块值进行幂等的合并,当需要合并的值发生冲突时进行报错,多用于复杂配置合并场景 - -```python -data = { - labels: {key1: "value1"} # 定义一个 labels, 它的类型为 dict, 值为 {"key1": "value1"} - labels: {key2: "value2"} # 使用 : 将 labels 不同的配置值进行合并 -} # 最终 data 的值为 {"labels": {"key1": "value1", "key2": "value2"}} -``` - -合并属性运算符属于幂等运算符,需要合并的配置块的书写顺序不影响其最终结果,比如上述例子中的两个 `labels` 属性也可以调换顺序书写 - -```python -data = { # 同一个属性 labels 的合并书写顺序不影响最终结果 - labels: {key2: "value2"} # 定义一个 labels, 它的类型为 dict, 值为 {"key2": "value2"} - labels: {key1: "value1"} # 使用 : 将 labels 不同的配置值进行合并 -} # 最终 data 的值为 {"labels": {"key1": "value1", "key2": "value2"}} -``` - -注意:合并属性运算符会对合并的值进行冲突检查,当需要合并的配置值发生冲突时进行报错 - -```python -data = { - a: 1 # a 的值为 1 - a: 2 # Error: a 的值 2 不能与 a 的值 1 进行合并,因为其结果存在冲突,且合并是不可交换的 -} -``` - -```python -data = { - labels: {key: "value"} - labels: {key: "override_value"} # Error: 两个 labels 的 key 属性的值 "value" 和 "override_value" 是冲突的,不可合并 -} -``` - -合并运算符对不同类型的使用方式不同 - -- 不同类型的属性不能进行合并 -- 当属性为 int/float/str/bool 等基本类型时,运算符会判断需要合并的值是否相等,不相等时发生合并冲突错误 - -```python -data = { - a: 1 - a: 1 # Ok - a: 2 # Error -} -``` - -- 当属性为 list 类型时 - - 当需要合并的两个 list 长度不相等时,发生合并冲突错误 - - 当需要合并的两个 list 长度相等时,按照索引递归地合并 list 当中的每一个元素 - -```python -data = { - args: ["kcl"] - args: ["-Y", "settings.yaml"] # Error: 两个 args 属性的长度不相同,不能进行合并 - env: [{key1: "value1"}] - env: [{key2: "value2"}] # Ok: 最终 env 属性的值为 [{"key1": "value1"}, {"key2": "value2"}] -} -``` - -- 当属性为 dict/schema 类型时,按照 key 递归地合并 dict/schema 当中的每一个元素 - -```python -data = { - labels: {key1: "value1"} - labels: {key2: "value2"} - labels: {key3: "value3"} -} # 最终 data 的值为 {"labels": {"key1": "value1", "key2": "value2", "key3": "value3"}} -``` - -- 任意类型的属性与 None/Undefined 合并的结果都是其自身 - -```python -data = { - args: ["kcl"] - args: None # Ok - args: Undefined #Ok -} # 最终 data 的值为 {"args": ["kcl"]} -``` - -支持顶级变量使用 `:` 属性声明与合并(仍然可使用 `config = Config {}` 的方式声明一个配置块) - -```python -schema Config: - id: int - value: str - -config: Config { - id: 1 -} -config: Config { - value: "1" -} -""" -此处定义了两个 Config 配置块,使用 : 运算符将可以两个配置块合并在一起,其合并的等效代码如下: -config: Config { - id: 1 - value: "1" -} -""" -``` - -综上所述,合并属性运算符 `:` 的使用场景主要为复杂数据结构 list/dict/schema 的合并操作,一般情况如无特殊需求使用 `=` 和 `+=` 两种属性运算符即可,因此属性运算符的最佳实践如下 - -- 对于基本类型,采用 `=` 运算符 -- 对于 list 类型,一般采用 `=` 和 `+=` 运算符,使用 `=` 表示完全覆盖 list 属性,使用 `+=` 表示向 list 中添加元素 -- 对于 dict/schema 类型,一般采用 `:` 运算符 - -此外,当已经存在一个配置时,可以使用解包运算符 `**` 获得此配置的所有字段值并对其中的字段使用不同属性运算符进行修改,并获得一个新的配置 - -```python -configBase = { - intKey = 1 # 一个 int 类型的属性 - floatKey = 1.0 # 一个 float 类型的属性 - listKey = [0] # 一个 list 类型的属性 - dictKey = {key1: "value1"} # 一个 dict 类型的属性 -} -configNew = { - **configBase # 将 configBase 解包内联到 configNew 中 - intKey = 0 # 使用 覆盖属性运算符 = 将 intKey 属性覆盖为 1 - floatKey = Undefined # 使用 覆盖属性运算符 = 删除 floatKey 属性 - listKey += [1] # 使用 添加属性运算符 += 为 listKey 属性尾部添加一个属性 1 - dictKey: {key2: "value2"} # 使用 合并属性运算符 : 为 dictKey 属性扩展一个键-值对 -} -``` - -输出的 YAML 结果为: - -```yaml -configBase: - intKey: 1 - floatKey: 1.0 - listKey: - - 0 - dictKey: - key1: value1 -configNew: - intKey: 0 - listKey: - - 0 - - 1 - dictKey: - key1: value1 - key2: value2 -``` - -或者可以使用 `|` 运算符对两个配置块合并: - -```python -configBase = { - intKey = 1 # 一个 int 类型的属性 - floatKey = 1.0 # 一个 float 类型的属性 - listKey = [0] # 一个 list 类型的属性 - dictKey = {key1: "value1"} # 一个 dict 类型的属性 -} -configNew = configBase | { # 使用 | 进行合并 - intKey = 0 # 使用 覆盖属性运算符 = 将 intKey 属性覆盖为 1 - floatKey = Undefined # 使用 覆盖属性运算符 = 删除 floatKey 属性 - listKey += [1] # 使用 添加属性运算符 += 为 listKey 属性尾部添加一个属性 1 - dictKey: {key2: "value2"} # 使用 合并属性运算符 : 为 dictKey 属性扩展一个键-值对 -} -``` - -输出的 YAML 结果为: - -```yaml -configBase: - intKey: 1 - floatKey: 1.0 - listKey: - - 0 - dictKey: - key1: value1 -configNew: - intKey: 0 - listKey: - - 0 - - 1 - dictKey: - key1: value1 - key2: value2 -``` - -### KCL 发生 conflicting values on the attribute 'attr' between {value1} and {value2} 错误的解决方式 - -当 KCL 发生类似 conflicting values on the attribute 'attr' between {value1} and {value2} 错误时,一般是合并属性运算符 `:` 的使用问题,表明 `value1` 和 `value2` 配置进行合并时在属性 `attr` 处发生了冲突错误。一般情况将 value2 的 attr 属性修改为其他属性运算符即可,使用 `=` 表示覆盖,使用 `+=` 表示添加 - -比如对于如下代码: - -```python -data = {k: 1} | {k: 2} # Error: conflicting values on the attribute 'k' between {'k': 1} and {'k': 2} -``` - -则可以使用 `=` 属性运算符修改为如下形式 - -```python -data = {k: 1} | {k = 2} # Ok: the value 2 will override the value 1 through the `=` operator -``` - -## 38. KCL 中如何同时遍历多个元素 - -KCL 中可以使用 for 推导表达式遍历多个元素 - -- 举例 1: 使用 for 进行 2 维元素遍历 - -```python -dimension1 = [1, 2, 3] # dimension1 列表的长度是 3 -dimension2 = [1, 2, 3] # dimension2 列表的长度是 3 -matrix = [x + y for x in dimension1 for y in dimension2] # matrix 列表的长度是 9 = 3 * 3 -``` - -输出结果如下: - -```yaml -dimension1: - - 1 - - 2 - - 3 -dimension2: - - 1 - - 2 - - 3 -matrix: - - 2 - - 3 - - 4 - - 3 - - 4 - - 5 - - 4 - - 5 - - 6 -``` - -- 举例 2: 使用 for 循环配合 zip 内置函数按照索引一一对应对多个列表进行遍历 - -```python -dimension1 = [1, 2, 3] # dimension1 列表的长度是 3 -dimension2 = [1, 2, 3] # dimension2 列表的长度是 3 -dimension3 = [d[0] + d[1] for d in zip(dimension1, dimension2)] # dimension3 列表的长度是 3 -``` - -输出结果如下: - -```yaml -dimension1: - - 1 - - 2 - - 3 -dimension2: - - 1 - - 2 - - 3 -dimension3: - - 2 - - 4 - - 6 -``` - -## 39. KCL 中如何为 option 函数设定默认值 - -在 KCL 中,当 option 属性的值为 None/Undefined 空时,可以使用逻辑或 `or` 直接指定一个默认值 - -```python -value = option("key") or "default_value" # 当 key 的值存在时,取 option("key") 的值,否则取 "default_value" -``` - -或者使用 option 函数的 default 参数 - -```python -value = option("key", default="default_value") # 当 key 的值存在时,取 option("key") 的值,否则取 "default_value" -``` - -## 40. KCL 中 schema 怎么检查多个属性不能同时为空或同时设置 - -在 KCL 中,对于 schema 的单个属性不能为空可以使用属性非空标记 - -```python -schema Person: - name: str # required. name 不能为空 - age: int # required. age 不能为空 - id?: int # optional. id 可以留空 -``` - -而对于需要检查 schema 属性不能同时为空或者只能有一者为空的情况时,需要借助 schema check 表达式进行书写,下面以同一个 schema Config 的两个属性 a, b 为例进行说明 - -- Config 的 a, b 属性不能同时为空 - -```python -schema Config: - a?: str - b?: str - - check: - a or b, "a属性和b属性不能同时为空" -``` - -- Config 的 a, b 属性只能有一个为空或者都为空(不能同时存在或不为空) - -```python -schema Config: - a?: str - b?: str - - check: - not a or not b, "a属性和b属性不能同时填写" -``` - -## 41. KCL 中 import 了某个文件但是找不到其同目录下其他 KCL 文件定义的 schema 可能是什么原因 - -可能是与使用 import 仅导入了这个文件夹的这一个文件导致,在 KCL 中,import 支持导入整个文件夹,也支持导入某一个文件夹下的的某一个 KCL 文件,比如对于如下目录结构 - -``` -. -├── kcl.mod -├── main.k -└── pkg - ├── pkg1.k - ├── pkg2.k - └── pkg3.k -``` - -在根目录下存在入口文件 main.k,可以在 main.k 中书写如下代码导入整个 pkg 文件夹,此时 pkg 文件夹下的所有 schema 定义互相可见 - -```python -import pkg -``` - -还可以书写如下代码导入单个文件 pkg/pkg1.k,此时 pkg1.k 不能找到其他文件即 pkg2.k/pkg3.k 下的 schema 定义 - -```python -import pkg.pkg1 -``` - -## 42. KCL 中的缩进是如何处理的? - -在 KCL 中,在出现冒号 `:`、中括号对 `[]` 以及大括号对 `{}` 时,一般需要使用换行 + 缩进,同一缩进级的缩进空格数需要保持一致,一个缩进级一般采用 4 个空格表示 - -- 冒号 `:` 后跟换行 + 缩进 - -```python -"""if 语句中的缩进""" -_a = 1 -_b = 1 -if _a >= 1: # 冒号后跟换行+缩进 - if _a > 8: - _b = 2 - elif a > 6: - _b = 3 - -"""schema 定义中的缩进""" -schema Person: # 冒号后跟换行+缩进 - name: str - age: int -``` - -- 中括号对 `[]` 后跟换行 + 缩进 - -```python -data = [ # 左中括号 [ 后跟换行+缩进 - 1 - 2 - 3 -] # 右中括号 ] 前取消缩进 -``` - -```python -data = [ # 左中括号 [ 后跟换行+缩进 - i * 2 for i in range(5) -] # 右中括号 ] 前取消缩进 -``` - -- 大括号对 `{}` 后跟换行 + 缩进 - -```python -data = { # 左大括号 { 后跟换行+缩进 - k1 = "v1" - k2 = "v2" -} # 右大括号 } 前取消缩进 -``` - -```python -data = { # 左大括号 { 后跟换行+缩进 - str(i): i * 2 for i in range(5) -} # 右大括号 } 前取消缩进 -``` - -## 43. 如何为 KCL 代码编写简单的测试? - -KCL 目前的版本还不支持内部程序调试,可以使用 assert 语句以及 print 函数实现数据的断言和打印查看 - -```python -a = 1 -print("The value of a is", a) -assert a == 1 -``` - -此外,还可以借助 kcl-test 测试工具编写 KCL 内部编写测试用例 - -假设有 hello.k 文件,代码如下: - -```python -schema Person: - name: str = "kcl" - age: int = 1 - -hello = Person { - name = "hello kcl" - age = 102 -} -``` - -构造 hello_test.k 测试文件,内容如下: - -```python -schema TestPerson: - a = Person{} - assert a.name == 'kcl' - -schema TestPerson_age: - a = Person{} - assert a.age == 1 - -schema TestPerson_ok: - a = Person{} - assert a.name == "kcl" - assert a.age == 1 -``` - -然后在目录下执行 kcl-test 命令: - -``` -$ kcl-test -ok /pkg/to/app [365.154142ms] -$ -``` - -## 44. KCL 中如何定义函数或定义方法? - -schema 结构在一定程度上充当了函数的功能,并且这个函数具有多个输入参数和多个输出参数的能力,比如如下代码可以实现一个斐波那契数列的功能: - -```python -schema Fib: - n: int - value: int = 1 if n <= 2 else (Fib {n: n - 1}).value + (Fib {n: n - 2}).value - -fib8 = (Fib {n: 8}).value -``` - -输出结果为: - -```yaml -fib8: 21 -``` - -一个合并列表为字典的 schema 函数 - -```python -schema UnionAll[data, n]: - _?: [] = data - value?: {:} = ((UnionAll(data=data, n=n - 1) {}).value | data[n] if n > 0 else data[0]) if data else {} - -schema MergeList[data]: - """Union一个列表中的所有元素返回合并字典 - - [{"key1": "value1"}, {"key2": "value2"}, {"key3": "value3"}] -> {"key1": "value1", "key2": "value2", "key3": "value3"} - """ - _?: [] = data - value?: {:} = (UnionAll(data=data, n=len(data) - 1) {}).value if data else {} -``` - -此外,KCL 支持使用 `lambda` 关键字定义一个函数: - -```python -func = lambda x: int, y: int -> int { - x + y -} -a = func(1, 1) # 2 -``` - -lambda 函数具有如下特性: - -- lambda 函数将最后一个表达式的值作为函数的返回值,空函数体返回 None。 -- 返回值类型注解可以省略,返回值类型为最后一个表达式值的类型 -- 函数体中没有与顺序无关的特性,所有的表达式都是按顺序执行的 - -```python -_func = lambda x: int, y: int -> int { - x + y -} # 使用 lambda 表达式定义一个函数 -_func = lambda x: int, y: int -> int { - x - y -} # Ok -_func = lambda x: int, y: int -> str { - str(x + y) -} # Error (int, int) -> str can't be assigned to (int, int) -> int -``` - -lambda 函数对象不能参与任何计算,只能在赋值语句和调用语句中使用。 - -```python -func = lambda x: int, y: int -> int { - x + y -} -x = func + 1 # Error: unsupported operand type(s) for +: 'function' and 'int(1)' -``` - -```python -a = 1 -func = lambda x: int { - x + a -} -funcOther = lambda f, para: int { - f(para) -} -r = funcOther(func, 1) # 2 -``` - -输出为: - -```python -a: 1 -r: 2 -``` - -可以定义一个匿名函数并直接调用 - -```python -result = (lambda x, y { - z = 2 * x - z + y -})(1, 1) # 3 -``` - -可以在 for 循环使用使用匿名函数 - -```python -result = [(lambda x, y { - x + y -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 3, 3, 4] -``` - -可以在 KCL schema 中定义并使用函数 - -```python -_funcOutOfSchema = lambda x: int, y: int { - x + y -} -schema Data: - _funcInSchema = lambda x: int, y: int { - x + y - } - id0: int = _funcOutOfSchema(1, 1) - id1: int = _funcInSchema(1, 1) - id2: int = (lambda x: int, y: int { - x + y - })(1, 1) -``` - -输出 YAML 为: - -```yaml -data: - id0: 2 - id1: 2 - id2: 2 -``` - -## 45. 为什么变量赋值为枚举类型(字面值联合类型)时会报错 - -在 KCL 中,被定义为字面值联合类型的属性,在赋值时仅允许接收一个字面值或者同为字面值联合类型的变量,比如如下代码是正确的: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -data = Data { - color = "Red" # Ok, 赋值为 "Red"、"Yellow" 和 "Blue" 均可 -} -``` - -然而以下代码是错误的: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -_color = "Red" - -data = Data { - color = _color # Error: expect str(Red)|str(Yellow)|str(Blue), got str -} -``` - -这是因为没有为变量 `_color` 申明一个类型,它会被 KCL 编译器推导为 `str` 字符串类型,因此当一个 “较大” 的类型 `str` 赋值为一个 “较小” 的类型时 `"Red" | "Yellow" | "Blue"` 会报错,一个解决方式是为 `_color` 变量声明一个类型,以下代码是正确的: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -_color: "Red" | "Yellow" | "Blue" = "Red" - -data = Data { - color = _color # Ok -} -``` - -进一步地,我们可以使用类型别名来简化枚举(字面值联合类型的书写),比如如下代码: - -```python -type Color = "Red" | "Yellow" | "Blue" # 定义一个类型别名,可以在不同的地方重复使用,降低代码书写量 - -schema Data: - color: Color - -_color: Color = "Red" - -data = Data { - color = _color # Ok -} -``` - -## 46. 过程式的 for 循环 - -KCL 中为何不支持过程式的 for 循环! - -KCL 提供了推导表达式以及 all/any/map/filter 表达式等用于对一个集合元素进行处理,满足大部分需求,提供过程式的 for 循环体从目前场景看需求暂时不强烈,因此暂未提供过程式的 for 循环支持 - -此外,KCL 中虽然没有支持过程式的 for 循环,但是可以通过 for 循环和 lambda 函数“构造”相应的过程式 for 循环 - -```python -result = [(lambda x: int, y: int -> int { - # 在其中书写过程式的 for 循环逻辑 - z = x + y - x * 2 -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 2, 4, 4] -``` - -## 47. 默认变量不可变 - -KCL 变量不可变性是指 KCL 顶层结构中的非下划线 `_` 开头的导出变量初始化后不能被改变。 - -```python -schema Person: - name: str - age: int - -a = 1 # a会输出到YAML中,一旦赋值不可修改 -_b = 1 # _b变量以下划线开头命名,不会输出到YAML中, 可多次赋值修改 -_b = 2 -alice = Person { - name = "Alice" - age = 18 -} -``` - -规定变量不可变的方式分为两类: - -- schema 外的非下划线顶层变量 - -```python -a = 1 # 不可变导出变量 -_b = 2 # 可变非导出变量 -``` - -## 48. 在 KCL 中存在类似 Go `interface{}`/`any` 或者 Java `Object` 的类型嘛? - -在 KCL 中,我们可以使用 `any` 类型注解来定义一个变量存储任意类型比如整数、字符串、schema 结构等数据。比如如下例子: - -```python -schema Data: - id: int = 1 - -var_list: [any] = [1, "12", Data {}] -``` - -输出 YAML 为: - -```yaml -var_list: - - 1 - - "12" - - id: 1 -``` - -此外,我们可以使用 `typeof` 函数来判断 KCL 变量的类型: - -```python -schema Data1: - id: int = 1 - -schema Data2: - name: str = "name" - -data_list: [any] = [Data1 {}, Data2 {}] -data_type_list: [str] = [typeof(data) for data in data_list] -``` - -输出 YAML 为: - -```yaml -data_list: - - id: 1 - - name: name -data_type_list: - - Data1 - - Data2 -``` - -## 49. 如何通过编写 KCL 插件进行扩展? - -KCL 插件在 KCL 的 plugins 子目录(通常安装在 `$HOME/.kcl/plugins` 目录),或者通过 `$KCL_PLUGINS_ROOT` 环境变量设置(环境变量优先级更高)。对于插件开发人员,插件都在 [Git 仓库](https://github.com/kcl-lang/kcl-plugin)管理,可以将插件仓库克隆到该目录进行开发。 - -KCL 内置了 kcl-plugin 脚手架命令用于辅助用户使用 Python 语言编写 KCL 插件,以便在 KCL 文件当中调用相应的插件对 KCL 语言本身进行增强,比如访问网络,读写 IO,CMDB 查询和加密解密等功能。 - -``` -usage: kcl-plugin [-h] {list,init,info,gendoc,test} ... - -positional arguments: - {list,init,info,gendoc,test} - kcl plugin sub commands - list list all plugins - init init a new plugin - info show plugin document - gendoc gen all plugins document - test test plugin - -optional arguments: - -h, --help show this help message and exit -``` - -比如想要开发一个名为 io 插件,就可以使用如下命令成功新建一个 io 插件 - -``` -kcl-plugin init io -``` - -然后可以使用如下命令获得 plugin 的根路径并 cd 到相应的 io 插件目录进行开发 - -``` -kcl-plugin info -``` - -比如想要开发一个读文件的函数 read_file,就可以在 `$plugin_root/io` 的 `plugin.py` 中进行 python 代码编写: - -```python -# Copyright 2020 The KCL Authors. All rights reserved. - -import pathlib - -INFO = { - 'name': 'io', - 'describe': 'my io plugin description test', - 'long_describe': 'my io plugin long description test', - 'version': '0.0.1', -} - - -def read_file(file: str) -> str: - """Read string from file""" - return pathlib.Path(file).read_text() - -``` - -另外可以在 `plugin_test.py` 中编写相应的测试函数,也可以直接编写如下所示 KCL 文件进行测试: - -```python -import kcl_plugin.io - -text = io.read_file('test.txt') -``` - -还可以使用 info 命令查看 io 插件的信息 - -``` -kcl-plugin info io -``` - -``` -{ - "name": "io", - "describe": "my io plugin description test", - "long_describe": "my io plugin long description test", - "version": "0.0.1", - "method": { - "read_file": "Read string from file" - } -} -``` - -最后将编写测试完成的插件在 `kcl_plugins` 仓库提 MR 合并即可 - -## 50. 如何在 KCL 中进行基本类型转换 - -可以使用`int()`, `float()`和`str()` 这些内置的方法来进行 `int`, `float` 和 `str` 之间的基本类型转换. - -``` -_t = 1 - -t_str: str = str(_t) # 输出的 t_str 为一个字符串 "t_str: '1'" -t_int: int = int(t_str) # 输出的 t_int 为一个整型 "t_int: 1" -t_float: float = float(t_str) # 输出的 t_float 为一个浮点型 "t_float: 1.0" -``` - -如果您想查看更多详细的关于KCL类型系统和类型转换的内容,您可以查阅 [KCL 内置类型](https://kcl-lang.io/docs/reference/lang/tour#built-in-types) 和 [KCL 类型系统](https://kcl-lang.io/docs/reference/lang/tour#type-system)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/support/support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/support/support.md deleted file mode 100644 index 648ee5a3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/support/support.md +++ /dev/null @@ -1,3 +0,0 @@ -# 常见问答 - -KCL 安装、使用过程中遇到的常见问题,包括基本概念解释、KCL 语法、KCL 语言设计、命令行工具和 YAML 等常见问题。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3.json deleted file mode 100644 index a9e8bfe5..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "sidebar.user_docs.category.Get Started": { - "message": "快速开始" - }, - "sidebar.user_docs.category.Introduction": { - "message": "简介" - }, - "sidebar.user_docs.category.User Guide": { - "message": "用户手册" - }, - "sidebar.user_docs.guides.category.Automation": { - "message": "自动化" - }, - "sidebar.user_docs.category.Configuration": { - "message": "配置" - }, - "sidebar.user_docs.category.Data Integration": { - "message": "数据集成" - }, - "sidebar.user_docs.category.Package Management": { - "message": "包管理工具" - }, - "sidebar.user_docs.category.How to": { - "message": "如何使用" - }, - "sidebar.user_docs.category.Schema Definition": { - "message": "模型定义" - }, - "sidebar.user_docs.category.Validation": { - "message": "验证" - }, - "sidebar.user_docs.category.Concepts": { - "message": "核心概念" - }, - "sidebar.user_docs.category.FAQ": { - "message": "常见问答" - }, - "sidebar.reference.category.Tutorial": { - "message": "教程" - }, - "sidebar.reference.category.Code Lab": { - "message": "代码实验室" - }, - "sidebar.reference.category.Spec": { - "message": "语言规范" - }, - "sidebar.reference.category.Errors and Warnings": { - "message": "错误与警告" - }, - "sidebar.reference.category.Types": { - "message": "类型系统" - }, - "sidebar.reference.category.System Package": { - "message": "系统模块" - }, - "sidebar.reference.category.Plugin System": { - "message": "插件系统" - }, - "sidebar.reference.category.Multi-Language": { - "message": "多语言集成" - }, - "sidebar.reference.category.Cheat Sheet": { - "message": "备忘表" - }, - "sidebar.reference.category.Package Management": { - "message": "包管理工具" - }, - "sidebar.reference.category.Command Reference": { - "message": "命令参考" - }, - "sidebar.reference.category.Advanced-Concepts": { - "message": "进阶概念" - }, - "sidebar.reference.category.Best-Practices": { - "message": "最佳实践" - }, - "sidebar.tools.category.Command Line Tools": { - "message": "命令行工具" - }, - "sidebar.tools.category.KCL Tools": { - "message": "语言工具" - }, - "sidebar.tools.category.OpenAPI Tools": { - "message": "OpenAPI 工具" - }, - "sidebar.community.category.Community": { - "message": "简介" - }, - "sidebar.community.category.Types": { - "message": "类型系统" - }, - "sidebar.community.category.Contribution Guide": { - "message": "贡献指南" - }, - "sidebar.community.category.Release Policy": { - "message": "发布策略" - }, - "sidebar.docs.category.GitOps": { - "message": "GitOps", - "description": "The label for category GitOps in sidebar docs" - }, - "sidebar.docs.category.CI Integration": { - "message": "CI 集成", - "description": "The label for category CI Integration in sidebar docs" - }, - "sidebar.user_docs.category.GitOps": { - "message": "GitOps", - "description": "The label for category GitOps in sidebar user_docs" - }, - "sidebar.user_docs.category.CI Integration": { - "message": "CI 集成", - "description": "The label for category CI Integration in sidebar user_docs" - }, - "sidebar.docs.category.Mutate or Validate Kubernetes Manifests": { - "message": "编辑或验证 Kubernetes 资源", - "description": "The label for category Mutate or Validate Kubernetes Manifests in sidebar docs" - }, - "sidebar.user_docs.category.Mutate or Validate Kubernetes Manifests": { - "message": "编辑或验证 Kubernetes 资源", - "description": "The label for category Mutate or Validate Kubernetes Manifests in sidebar user_docs" - }, - "sidebar.docs.category.Secret Management": { - "message": "敏感信息管理", - "description": "The label for category Secret Management in sidebar docs" - }, - "sidebar.user_docs.category.Secret Management": { - "message": "敏感信息管理", - "description": "The label for category Secret Management in sidebar user_docs" - } -} \ No newline at end of file diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/release-policy/roadmap.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/release-policy/roadmap.md deleted file mode 100644 index 2f0ee86a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/release-policy/roadmap.md +++ /dev/null @@ -1,3 +0,0 @@ -# 路线规划 - -![](/img/docs/community/release-policy/roadmap.jpg) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/error/_error.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/error/_error.md deleted file mode 100644 index a2f192b8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/error/_error.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: "错误检查" -linkTitle: "错误检查" -type: "docs" -weight: 1 -description: KCL 语言规范 ---- - -When errors happen, developers should be able to detect the error and abort -execution. Thus, KCL introduce the `assert` syntax. - -In the previous topic of `schema` syntax. Errors can also be raised when a -schema is violated. - -## Syntax - -The syntax of the `assert` statement is the following. - -``` -assert_stmt: 'assert' test [',' test] -``` - -In the basic form, an `assert` statement evaluates an expression. If the -expression is evaluated to `False`, the assertion is failed, and an error -should be reported. - -In the extended form, an error message can be provided. The error message is -another expression. It is only evaluated when the expression to be evaluated -is evaluated to `False`. The evaluation result of the error message is printed -when reporting the error. - -The following is an example: - -```py -a = 1 -b = 3 -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -``` - -## The Implementation - -When an error happens, no matter it is caused by the `assert` or the `schema` syntax, -the virtual machine should exit with an exit code greater than `0`. - -The virtual machine may choose to dump the back trace information, and it is strongly -recommended to implement it. - -In practice, KCL can dump back trace by default, and an argument can be introduced -to disable it. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/error/exception.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/error/exception.md deleted file mode 100644 index cd18995f..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/error/exception.md +++ /dev/null @@ -1,1584 +0,0 @@ ---- -title: "KCL 错误与警告" -linkTitle: "KCL 错误与警告" -type: "docs" -weight: 2 -description: KCL 错误与警告 ---- - -# KCL 错误与警告 - -文档的此部分中的文章介绍了由 KCL 生成的诊断错误和警告消息。 - -**注意:** -**KCL 可以报告多种错误和警告。找到错误或警告后,KCL 可能会对代码意向作出假设并尝试继续,以便可以同时报告更多问题。 如果工具做出错误假设,则后续错误或警告可能不适应与当前 KCL 程序。 因此,纠正项目中的问题时,请先纠正第一个错误或警告,然后重新运行获取新的错误信息。 一个修补程序可能会导致后续错误消失。** - -此部分文档的主要内容包括: - -[KCL 语法错误 (E1xxx)](#11-kcl-%E8%AF%AD%E6%B3%95%E9%94%99%E8%AF%AF-e1xxx) : 如果 KCL 在当前 KCL 程序中发现了非法的 KCL 语法,KCL 就会停止运行并输出 KCL 程序语法错误的提示信息. - -[KCL 编译错误 (E2xxx)](#12-kcl-%E7%BC%96%E8%AF%91%E9%94%99%E8%AF%AF-e2xxx) : 如果 KCL 在一个不包含语法错误的 KCL 程序中发现了与 KCL 语义不符的代码,KCL 就会停止运行并输出编译错误的提示信息。 - -[KCL 运行时错误 (E3xxx)](#13-kcl-%E8%BF%90%E8%A1%8C%E6%97%B6%E9%94%99%E8%AF%AF-e3xxx) : KCL 程序通过编译后会生成 KCL 字节码,如果 KCL 在执行 KCL 字节码过程中出现错误,KCL 就会停止运行并输出运行时错误的提示信息. - -[KCL 编译警告 (W2xxx)](#14-kcl-%E7%BC%96%E8%AF%91%E8%AD%A6%E5%91%8A-w2xxx) : 当 KCL 发现可能导致运行失败的 KCL 代码,KCL 不会立即停止运行,但是会输出潜在错误的警告提示。 - -## 1.1 KCL 语法错误 (E1xxx) - -KCL 会出现的语法错误信息如下表所示: - -| ewcode | KCL exception | messages | -| ------ | ------------------------------------------------------------------- | ----------------------- | -| E1001 | [InvalidSyntaxError](#111-invalidsyntaxerror-e1001) | Invalid syntax | -| E1002 | [KCLTabError](#112-kcltaberror-e1002) | Tab Error | -| E1003 | [KCLIndentationError](#113-kclindentationerror-e1003) | Indentation Error | -| E1I37 | [IllegalArgumentSyntaxError](#114-illegalargumentsyntaxerror-e1i37) | Illegal argument syntax | - -### 1.1.1 InvalidSyntaxError [E1001] - -如果在运行 KCL 时遇到错误: - -- `InvalidSyntaxError`, 对应的 encode 为 `E1001` - -那么此时 KCL 程序中出现了 - -- 非法的 KCL 语法。 - -可能出现错误的 KCL 程序片段如下: - -```python -a, b = 1, 2 # 通过 “=” 赋值多个变量在KCL中是非法的。 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> /syntax_error/general/multiple_assign/case0/main.k:1:2 - | -1 | a, b = 1, 2 # Multiple assign is illegal in KCL syntax - | ^ expected statement - | -``` - -### 1.1.2 KCLTabError - -如果在运行 KCL 时遇到错误: `KCLTabError` - -那么此时 KCL 程序中出现了 - -- Tab 与空格混用的问题。KCL 中禁止在代码缩进中混用 Tab 和空格。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - name: str # 通过tab表示缩进 - age: int # 通过四个空格标识缩进, - # 在当前运行环境中的四个空格与tab不同 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> File /syntax_error/tab/tab_error_0/main.k:6:5 - | -3 | age: int = 1 - | ^ inconsistent use of tabs and spaces in indentation - | -``` - -可以尝试以下步骤来修复这个错误: - -- 在 KCL 程序中全部使用 Tab 或者全部使用四个空格,不要混用。 - -### 1.1.3 KCLIndentationError - -如果在运行 KCL 时遇到错误: `KCLIndentationError` - -那么此时 KCL 程序中出现了 - -- 程序缩进错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - name: str # 使用一个tab或者四个空格表示缩进 - age: int # KCL不支持使用三个空格表示缩进 - info: str # KCL不支持使用两个空格表示缩进 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> /syntax_error/indent/indent_error_0/main.k:3:4 - | -3 | age: int # three white spaces are illegal - | ^ unindent 3 does not match any outer indentation level - | -``` - -可以尝试以下步骤来修复这个错误: - -- 在 KCL 程序中全部使用 Tab 或者全部使用四个空格来表示缩进。 - -### 1.1.4 IllegalArgumentSyntaxError - -如果在运行 KCL 时遇到错误: `IllegalArgumentSyntaxError` - -那么此时 KCL 程序中出现了 - -- 参数语法错误 - -可能出现错误的 KCL 程序片段如下: - -```python -# KCL中带有keyword的参数必须出现在不带有keyword参数后面 -# 带有keyword的参数: type="list", default={"key": "value"} -# 不带有keyword的参数: "key1" -a = option(type="list", default={"key": "value"}, "key1") -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> /option/type_convert_fail_2/main.k:3:57 - | -3 | a = option(type="list", default={"key": "value"}, "key1") - | ^ positional argument follows keyword argument - | -``` - -可以尝试以下步骤来修复这个错误: - -- KCL 中带有 keyword 的参数必须出现在不带有 keyword 参数后面, 参数正常顺序: - -```python -func(input_1, ..., input_n, param_with_key_1 = input_with_key_1, ..., param_with_key_n = input_with_key_n) -``` - -## 1.2 KCL 编译错误 (E2xxx) - -KCL 会出现的编译错误信息如下表所示: - -| ewcode | KCL exception | messages | -| ------ | ----------------------------------------------------------------------- | --------------------------------------------------- | -| E2F04 | [CannotFindModule](#121-cannotfindmodule-e2f04) | Cannot find the module | -| E2F05 | [FailedLoadModule](#122-failedloadmodule-e2f05) | Failed to load module | -| E2H13 | [UnKnownDecoratorError](#123-unknowndecoratorerror-e2h13) | UnKnown decorator | -| E2H14 | [InvalidDecoratorTargetError](#124-invaliddecoratortargeterror-e2h14) | Invalid Decorator Target | -| E2C15 | [MixinNamingError](#125-mixinnamingerror-e2c15) | Illegal mixin naming | -| E2C16 | [MixinStructureIllegal](#126-mixinstructureillegal-e2c16) | Illegal mixin structure | -| E2B17 | [CannotAddMembersComplieError](#127-cannotaddmemberscomplieerror-e2b17) | Cannot add members to a schema | -| E2B20 | [IndexSignatureError](#128-indexsignatureerror-e2b20) | Invalid index signature | -| E2G22 | [TypeComplieError](#129-typecomplieerror-e2g22) | The type got is inconsistent with the type expected | -| E2L23 | [CompileError](#1210-compileerror-e2l23) | A complie error occurs during compiling | -| E2L25 | [KCLNameError](#1211-kclnameerror-e2l25) | Name Error | -| E2L26 | [KCLValueError](#1212-kclvalueerror-e2l26) | Value Error | -| E2L27 | [KCLKeyError](#1213-kclkeyerror-e2l27) | Key Error | -| E2L28 | [UniqueKeyError](#1214-uniquekeyerror-e2l28) | Unique key error | -| E2A29 | [KCLAttributeComplieError](#1215-kclattributecomplieerror-e2a29) | Attribute error occurs during compiling | -| E2D32 | [MultiInheritError](#1216-multiinheriterror-e2d32) | Multiple inheritance is illegal | -| E2D34 | [IllegalInheritError](#1217-illegalinheriterror-e2d34) | Illegal inheritance | -| E2I36 | [IllegalArgumentComplieError](#1218-illegalargumentcomplieerror-e2i36) | Illegal argument during compiling | -| E3L41 | [ImmutableCompileError](#1219-immutablecompileerror-e3l41) | Immutable variable is modified | - -### 1.2.1 CannotFindModule [E2F04] - -如果在运行 KCL 时遇到错误: - -- `CannotFindModule`, 对应的 encode 为 `E2F04` - -那么此时 KCL 程序中出现了 - -- 无法找到导入模块错误 - -可能出现错误的 KCL 程序片段如下: - -```python -import .some0.pkg1 as some00 # some0 not found in package - -Name1 = some00.Name # some0.pkg1.name -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2F04]: CannotFindModule - --> import_abs_fail_0/app-main/main.k:1:1 - | -1 | import .some0.pkg1 as some00 # some0 not found in package - | Cannot find the module .some0.pkg1 - | -``` - -可以尝试以下步骤来修复这个错误: - -- 在 import 路径下添加导入模块文件。 - -### 1.2.2 FailedLoadModule [E2F05] - -如果在运行 KCL 时遇到错误: - -- `FailedLoadModule`, 对应的 encode 为 `E2F05` - -那么此时 KCL 程序中出现了 - -- 导入模块加载错误 - -可以尝试以下步骤来修复这个错误: - -- 查看文件是否可读 -- 查看文件是否为 kcl 文件 - -### 1.2.3 UnKnownDecoratorError - -如果在运行 KCL 时遇到错误: - -- `UnKnownDecoratorError`, 对应的 encode 为 `E2H13` - -那么此时 KCL 程序中出现了 - -- 未知的装饰器错误 - -可能出现错误的 KCL 程序片段如下: - -```python -@err_deprecated # 这是一个非法的装饰器 -schema Person: - firstName: str = "John" - lastName: str - name: str - -JohnDoe = Person { - name: "deprecated" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> deprecated/unknown_fail_1/main.k:1:2 - | -1 | @err_deprecated # 这是一个非法的装饰器 - | ^ UnKnown decorator err_deprecated - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查装饰器是否存在。 - -### 1.2.4 InvalidDecoratorTargetError [E2H14] - -如果在运行 KCL 时遇到错误: - -- `InvalidDecoratorTargetError`, 对应的 encode 为 `E2H14` - -那么此时 KCL 程序中出现了 - -- 无效的装饰器目标错误。 - -可以尝试以下步骤来修复这个错误: - -- 检查使用装饰器的 KCL 代码是否出现异常。 - -### 1.2.5 MixinNamingError [E2C15] - -如果在运行 KCL 时遇到错误: - -- `MixinNamingError`, 对应的 encode 为 `E2C15` - -那么此时 KCL 程序中出现了 - -- Mixin 命名错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - firstName: str - lastName: str - fullName: str - -schema Fullname: # Mixin的名称应该以Mixin结尾 - fullName = "{} {}".format(firstName, lastName) - -schema Scholar(Person): - mixin [Fullname] - school: str - -JohnDoe = Scholar { - "firstName": "John", - "lastName": "Doe", - "fullName": "Doe Jon" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2D34]: IllegalInheritError - --> mixin/invalid_name_failure/main.k:10:12 - | -10 | mixin [Fullname] - | ^ illegal schema mixin object type 'Fullname' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 如果 schema 是一个 mixin,那么这个 schema 的名称应该以 Mixin 结尾。 - -### 1.2.6 MixinStructureIllegal [E2C16] - -如果在运行 KCL 时遇到错误: - -- `MixinStructureIllegal`, 对应的 encode 为 `E2C16` - -那么此时 KCL 程序中出现了 - -- Mixin 结构错误。 - -可以尝试以下步骤来修复这个错误: - -- 检查作为 Mixin 的 Schema 的结构。 - -### 1.2.7 CannotAddMembersComplieError [E2B17] - -如果在运行 KCL 时遇到错误: - -- `CannotAddMembersComplieError`, 对应的 encode 为 `E2B17` - -那么此时 KCL 程序中出现了 - -- 使用 Schema 中不存在的成员。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Girl: - gender: str = "female" - -alice = Girl { - "first": "alice", # Schema中没有成员“first” - "last": " Green", # Schema中没有成员“last” - "age": 10 # Schema中没有成员“age” -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:5:5 - | -5 | "first": "alice", - | ^ Cannot add member 'first' to schema 'Girl' - | - -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:6:5 - | -6 | "last": " Green", - | ^ Cannot add member 'last' to schema 'Girl' - | - -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:7:5 - | -7 | "age": 10 - | ^ Cannot add member 'age' to schema 'Girl' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 为 Schema 添加缺少的成员。 -- 不要使用 Schema 中不存在的成员。 - -### 1.2.8 IndexSignatureError [E2B20] - -如果在运行 KCL 时遇到错误: - -- `IndexSignatureError`, 对应的 encode 为 `E2B20` - -那么此时 KCL 程序中出现了 - -1. 在一个 schema 中使用多个索引签名。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Data: - [str]: str - [str]: int # 在同一个schema中使用了多个索引签名 - -data = Data { - name: "test" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError ----> index_signature/fail_1/main.k:3:5 - | -3 | [str]: int - | 5 ^ only one index signature is allowed in the schema - | -``` - -可以尝试以下步骤来修复这个错误: - -- 删除多余的索引签名。 - -2. schema 中索引签名的名称与 schema 中其他属性的名称存在同名冲突。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Data: - name: str # name - [name: str]: str # 已有名称为name的schema属性 - -data = Data { - name: "test" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: IndexSignatureError - --> index_signature/fail_2/main.k:3:5 - | -3 | [name: str]: str # the same name with the above attribute - | ^ index signature attribute name 'name' cannot have the same name as schema attributes - | -``` - -可以尝试以下步骤来修复这个错误: - -- 删除 schema 中出现同名冲突的属性或者索引签名,或者为它们更换不同的名称。 - -3. schema 索引签名的类型与 schema 实例化的属性类型冲突。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Data: - [str]: int - -data = Data { - name: "test" # 索引签名为 [str]:int, "test"的类型不是int. -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> index_signature/fail_3/main.k:5:5 - | -5 | name: "test" # Conflict with [str]:int, "test" is a string. - | ^ expected int, got str(test) - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 schema 索引签名的类型与 schema 实例中的属性类型是否一致。 - -4. Schema 中的属性与索引签名冲突 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Data: - count: int # int 和 str 冲突 - [str]: str - -data = Data { - count: 1 -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: IndexSignatureError - --> index_signature/fail_4/main.k:2:5 - | -2 | count: int - | ^ the type 'int' of schema attribute 'count' does not meet the index signature definition [str]: str - | -``` - -可以尝试以下步骤来修复这个错误: - -- 调整 Schema 属性或者调整索引签名。 - -### 1.2.9 TypeComplieError [E2G22] - -如果在运行 KCL 时遇到错误: - -- `TypeComplieError`, 对应的 encode 为 `E2G22` - -那么此时 KCL 程序中出现了 - -- 静态类型检查错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - firstName: str - lastName: int - -JohnDoe = Person { - "firstName": "John", - "lastName": "Doe" # Schema中定义lastName: int -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> type/type_fail_0/main.k:7:5 - | -7 | "lastName": "Doe" # Type Error,lastName: int,“Doe” is a string. - | ^ expected int, got str(Doe) - | - - --> type/type_fail_0/main.k:3:5 - | -3 | lastName: int - | ^ variable is defined here, its type is int, but got str(Doe) - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查赋给某个变量的值的类型与这个变量的类型是否一致。 - -### 1.2.10 CompileError [E2L23] - -如果在运行 KCL 时遇到错误: - -- `CompileError`, 对应的 encode 为 `E2L23` - -那么此时 KCL 程序中出现了 - -1. 不支持的类型合并 - -可能出现错误的 KCL 程序片段如下: - -```python -_data = [1, 2, 3] -_data |= "value" -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> union/fail/fail_1/main.k:2:1 - | -2 | _data |= "value" - | ^ unsupported operand type(s) for |: '[int]' and 'str(value)' - | -``` - -1. 不支持的操作符类型 - -可能出现错误的 KCL 程序片段如下: - -```python -a = None -b = 1 + None # KCL中不支持None和int之间进行+操作 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> operator/operator_fail_0/main.k:2:5 - | -2 | b = 1 + None # Unsupport operand type + for int and None - | ^ unsupported operand type(s) for +: 'int(1)' and 'NoneType' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 调整操作符号,使其同时支持两个操作数的类型。 -- 调整操作数,使其同时符合操作符号的约束。 - -1. 没有定义的变量 - -可能出现错误的 KCL 程序片段如下: - -```python -a = 1 -b = "${c + 1}" # 'c' 没有定义 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> var_not_define_fail_0/main.k:2:8 - | -2 | b = "${c + 1}" # 'c' is not defined - | ^ name 'c' is not defined - | -``` - -可以尝试以下步骤来修复这个错误: - -- 对未定义的变量进行定义。 -- 在表达式中去掉对未定义变量的操作。 - -4. 无效的赋值表达式 - -可能出现错误的 KCL 程序片段如下: - -```python -# pkg.k -a = 1 - -# main.k -import pkg -pkg.a |= 2 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> pkg_inplace_modify_1/main.k:3:1 - | -6 | pkg |= 2 - | ^ unsupported operand type(s) for |: 'module 'pkg'' and 'int(2)' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查赋值表达式的内容。 - -1. 无效的字符串表达式 - -可能出现错误的 KCL 程序片段如下: - -```python -a = 1 -b = "${b = a + 1}" # Invalid string interpolation expression -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> invalid_format_value_fail_0/main.k:2:5 - | -2 | b = "${b = a + 1}" - | 5 ^ invalid string interpolation expression 'b = a + 1' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查字符串表达式的内容。 - -1. 无效的循环变量 - -可能出现错误的 KCL 程序片段如下: - -```python -data = {"key1": "value1", "key2": "value2"} -dataLoop = [i for i, j, k in data] # the number of loop variables can only be 1 or 2 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> dict/invalid_loop_var_fail_0/main.k:2:25 - | -2 | dataLoop = [i for i, j, k in data] # the number of loop variables can only be 1 or 2 - | ^ the number of loop variables is 3, which can only be 1 or 2 - | -``` - -### 1.2.11 KCLNameError [E2L25] - -如果在运行 KCL 时遇到错误: - -- `KCLNameError`, 对应的 encode 为 `E2L25` - -那么此时 KCL 程序中出现了 - -- 试图访问的变量名不存在 - -可以尝试以下步骤来修复这个错误: - -- 检查报错信息中出现的变量是否存在。 - -### 1.2.12 KCLValueError [E2L26] - -如果在运行 KCL 时遇到错误: - -- `KCLValueError`, 对应的 encode 为 `E2L26` - -那么此时 KCL 程序中出现了 - -- 值错误,传给参数的类型不正确 - -可以尝试以下步骤来修复这个错误: - -- 检查参数的具体类型。 - -### 1.2.13 KCLKeyError [E2L27] - -如果在运行 KCL 时遇到错误: - -- `KCLKeyError`, 对应的 encode 为 `E2L27` - -那么此时 KCL 程序中出现了 - -- 使用了 dict 中不存在的 key 时引发的 key 错误 - -可以尝试以下步骤来修复这个错误: - -- 检查字典中是否存在 key。 - -### 1.2.14 UniqueKeyError [E2L28] - -如果在运行 KCL 时遇到错误: - -- `UniqueKeyError`, 对应的 encode 为 `E2L28` - -那么此时 KCL 程序中出现了 - -- 变量同名或重复定义。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - name: str = "kcl" - age: int = 1 - -schema Person: - aa: int - -x0 = Person{} -x1 = Person{age:101} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L28]: UniqueKeyError - --> /schema/same_name/main.k:5:8 - | -5 | schema Person: - | ^ Unique key error name 'Person' - | - - --> /schema/same_name/main.k:1:8 - | -1 | schema Person: - | ^ The variable 'Person' is declared here - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查出现错误的名称是否已经被使用。 - -### 1.2.15 KCLAttributeComplieError [E2A29] - -如果在运行 KCL 时遇到错误: - -- `KCLAttributeComplieError`, 对应的 encode 为 `E2A29` - -那么此时 KCL 程序中出现了 - -- Schema 的属性错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -# pkg -schema A: - field_A: str - -# main -import pkg as p - -a = p.D + 1 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> /import/module/no_module_attr_fail_0/main.k:4:5 - | -4 | a = p.D + 1 - | ^ module 'pkg' has no attribute D - | -``` - -可以尝试以下步骤来修复这个错误: - -- 在使用 Schema 属性时检查这个属性是否存在。 - -### 1.2.16 MultiInheritError [E2D32] - -如果在运行 KCL 时遇到错误: - -- `MultiInheritError`, 对应的 encode 为 `E2D32` - -那么此时 KCL 程序中出现了 - -- 多继承错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - firstName: str - lastName: str - -schema KnowledgeMixin: - firstName: int - subject: str - -schema Scholar(KnowledgeMixin, Person): # KCL中不支持多继承 - school: str -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> /schema/inherit/multi_inherit_fail_1/main.k:9:30 - | -9 | schema Scholar(KnowledgeMixin, Person): - | ^ expected one of [")"] got , - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查程序的继承结构,KCL 中不支持多继承。 - -### 1.2.17 IllegalInheritError [E2D34] - -如果在运行 KCL 时遇到错误: - -- `IllegalInheritError`, 对应的 encode 为 `E2D34` - -那么此时 KCL 程序中出现了 - -- 不合法的继承结构 - -可能出现错误的 KCL 程序片段如下: - -```python -schema FullnameMixin: - fullName = "{} {}".format(firstName, lastName) - -schema Scholar(FullnameMixin): # KCL中不支持Schema继承Mixin - school: str -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError -Invalid value for top level arguments -``` - -可以尝试以下步骤来修复这个错误: - -- KCL 中 Schema 支持单继承 Schema。 - -### 1.2.18 IllegalArgumentComplieError [E2I36] - -如果在运行 KCL 时遇到错误: - -- `IllegalArgumentComplieError`, 对应的 encode 为 `E2I36` - -那么此时 KCL 程序中出现了 - -- 参数错误 - -可能出现错误的 KCL 程序片段如下: - -```python -a = option("key") - -# kcl main.k -D key=value= -# key=value= is an illegal expression -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError -Invalid value for top level arguments -``` - -可以尝试以下步骤来修复这个错误: - -- 检查通过命令设置的 KCL option 参数是否为合法参数。 - -### 1.2.19 ImmutableCompileError [E3L41] - -如果在运行 KCL 时遇到错误: - -- `ImmutableCompileError`, 对应的 encode 为 `E3L41` - -那么此时 KCL 程序中出现了 - -- 不可变量的值发生改变 - -可能出现错误的 KCL 程序片段如下: - -```python -a = 2147483646 -a += 1 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: ImmutableError - --> augment_assign/main.k:2:1 - | -2 | a += 1 - | ^ Immutable variable 'a' is modified during compiling - | - - --> augment_assign/main.k:1:1 - | -1 | a = 2147483646 - | ^ The variable 'a' is declared here firstly - | -note: change the variable name to '_a' to make it mutable -``` - -可以尝试以下步骤来修复这个错误: - -- 将被改变的不可变量设置为私有或者去掉对不可变量值的改动。 - -## 1.3 KCL 运行时错误 (E3xxx) - -KCL 会出现的运行时错误信息如下表所示: - -| ewcode | KCL exception | messages | -| ------ | ----------------------------------------------------------------------- | --------------------------------------------------- | -| E3F06 | [RecursiveLoad](#131-recursiveload-e3f06) | Recursively loading module | -| E3K04 | [FloatOverflow](#132-floatoverflow-e3k04) | Float overflow | -| E3K09 | [IntOverflow](#133-intoverflow-e3k09) | Integer overflow | -| E3N11 | [DeprecatedError](#134-deprecatederror-e3n11) | Deprecated error | -| E3A30 | [KCLAttributeRuntimeError](#135-kclattributeruntimeerror-e3a30) | Attribute error occurs at runtime | -| E3G21 | [TypeRuntimeError](#136-typeruntimeerror-e3g21) | The type got is inconsistent with the type expected | -| E3B17 | [SchemaCheckFailure](#137-schemacheckfailure-e3b17) | Schema check is failed to check condition | -| E3B19 | [CannotAddMembersRuntimeError](#138-cannotaddmembersruntimeerror-e3b19) | Cannot add members to a schema | -| E3M38 | [EvaluationError](#139-evaluationerror-e3m38) | Evaluation failure | -| E3M39 | [InvalidFormatSpec](#1310-invalidformatspec-e3m39) | Invalid format specification | -| E3M40 | [KCLAssertionError](#1311-kclassertionerror-e3m40) | Assertion failure | -| E3M44 | [ImmutableRuntimeError](#1312-immutableruntimeerror-e3m44) | Immutable variable is modified | -| E2D33 | [CycleInheritError](#1313-cycleinheriterror-e2d33) | Cycle Inheritance is illegal | -| E3M42 | [KCLRecursionError](#1314-kclrecursionerror-e3m42) | Recursively reference | - -### 1.3.1 RecursiveLoad [E3F06] - -如果在运行 KCL 时遇到错误: - -- `RecursiveLoad`, 对应的 encode 为 `E3F06` - -那么此时 KCL 程序中出现了 - -- 循环导入错误 - -可能出现错误的 KCL 程序片段如下: - -``` -# module.k -import main # module.k 导入了 main.k - -print('module') - -# main.k -import module # main.k 导入了 module.k - -print('main') -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /import/recursive_import_fail/main.k:4 - | -2 | import module # main.k imports module.k - | ^ There is a circular import reference between module main and module - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查包的导入部分是否存在循环导入的问题。 - -### 1.3.2 FloatOverflow [E3K04] - -如果在运行 KCL 时遇到错误: - -- `FloatOverflow`, 对应的 encode 为 `E3K04` - -那么此时 KCL 程序中出现了 - -- 浮点数溢出 - -可能出现错误的 KCL 程序片段如下: - -```python -uplimit = 3.402823466e+39 -epsilon = 2.220446049250313e-16 -a = uplimit * (1 + epsilon) - -# kcl main.k -r -d -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /range_check_float/overflow/number_0/main.k:3:1 - | -3 | a = uplimit * (1 + epsilon) - | 3.4028234660000003e+39: A 32-bit floating point number overflow - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查浮点数的值是否在 KCL 支持的数字范围内。 - -### 1.3.3 IntOverflow [E3K09] - -如果在运行 KCL 时遇到错误: - -- `IntOverflow`, 对应的 encode 为 `E3K09` - -那么此时 KCL 程序中出现了 - -- 整数溢出 - -可能出现错误的 KCL 程序片段如下: - -```python -_a = 9223372036854775807 -_a += 1 - -# kcl test.k -d -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /range_check_int/augment_assign_fail_1/main.k:2:1 - | -2 | _a += 1 - | 9223372036854775808: A 64 bit integer overflow - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查整数的值是否在 KCL 支持的数字范围内。 - -### 1.3.4 DeprecatedError [E3N11] - -如果在运行 KCL 时遇到错误: - -- `DeprecatedError`, 对应的 encode 为 `E3N11` - -那么此时 KCL 程序中出现了 - -- 使用废弃代码 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - firstName: str = "John" - lastName: str - @deprecated(version="1.16", reason="use firstName and lastName instead", strict=True) - name: str - -JohnDoe = Person { - name: "deprecated" # name已经被过时,并且strict设置为True -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /range_check_float/overflow/number_0/main.k:7:1 - | -7 | JohnDoe = Person { - | name was deprecated since version 1.16, use firstName and lastName instead - | -``` - -可以尝试以下步骤来修复这个错误: - -- strict 设置为 True 时无法使用过时的代码,可以将 strict 设置为 False,将不会出现错误,而是输出一个警告。 -- 调整代码,不使用已经过时的代码。 - -### 1.3.5 KCLAttributeRuntimeError [E3A30] - -如果在运行 KCL 时遇到错误: - -- `KCLAttributeRuntimeError`, 对应的 encode 为 `E3A30` - -那么此时 KCL 程序中出现了 - -- 属性错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -import math - -a = math.err_func(1) # err_func is not found in math -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /import/module/no_module_attr_fail_2/main.k:3:5 - | -3 | a = math.err_func(1) # err_func is not found in math - | ^ module 'math' has no attribute err_func - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查属性调用是否正确。 - -### 1.3.6 TypeRuntimeError [E3G21] - -如果在运行 KCL 时遇到错误: - -- `TypeRuntimeError`, 对应的 encode 为 `E3G21` - -那么此时 KCL 程序中出现了 - -- 类型检查错误 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - name: str = "Alice" - -_personA = Person {} -_personA |= {"name" = 123.0} # name: str = "Alice" -personA = _personA -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /fail/fail_4/main.k:2:1 - | -2 | name: str = "Alice" - | expect str, got float - | -``` - -可以尝试以下步骤来修复这个错误: - -- 停止错误的类型合并或者将类型调整为 KCL 支持的类型合并。 - -### 1.3.7 SchemaCheckFailure [E3B17] - -如果在运行 KCL 时遇到错误: - -- `SchemaCheckFailure`, 对应的 encode 为 `E3B17` - -那么此时 KCL 程序中出现了 - -- Schema 中的 check 条件冲突 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - lastName: str - age: int - check: - age < 140, "age is too large" - -JohnDoe = Person { - "lastName": "Doe", - "age": 1000 # Schema中的check条件为: age < 140 -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /check_block/check_block_fail_1/main.k:7:11 - | -7 | JohnDoe = Person { - | ^ Instance check failed - | - - --> /check_block/check_block_fail_1/main.k:5:1 - | -5 | age < 140, "age is too large" - | Check failed on the condition - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 Schema 的属性与 check 中的条件是否符合 - -### 1.3.8 CannotAddMembersRuntimeError [E3B19] - -如果在运行 KCL 时遇到错误: - -- `CannotAddMembersRuntimeError`, 对应的 encode 为 `E3B19` - -那么此时 KCL 程序中出现了 - -- 访问 Schema 中不存在的成员 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Name: - name: str - -schema Person: - name: Name - -person = Person { - name.err_name: "Alice" # err_name is not found in schema Name -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /nest_var/nest_var_fail_1/main.k:8:5 - | -8 | name.err_name: "Alice" # err_name is not found in schema Name - | ^ Cannot add member 'err_name' to schema 'Name' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 为 Schema 添加不存在的成员。 -- 访问 Schema 中存在的成员。 - -### 1.3.9 EvaluationError [E3M38] - -如果在运行 KCL 时遇到错误: - -- `EvaluationError`, 对应的 encode 为 `E3M38` - -那么此时 KCL 程序中出现了 - -- 当 KCL 中数值计算过程出现了错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -_list1 = [1, 2, 3] # _list1 is a variable, and its type can only be known at runtime -_list2 = None # _list1 is a variable, and its type can only be known at runtime - -result2 = _list1 + _list2 # list + NoneType is illegal -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /datatype/list/add_None_fail/main.k:1 - | -4 | result2 = _list1 + _list2 # list + NoneType is illegal - | can only concatenate list (not "NoneType") to list - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查表达式中是否存在变量为 None,或者非法的计算过程。 - -### 1.3.10 InvalidFormatSpec [E3M39] - -如果在运行 KCL 时遇到错误: - -- `InvalidFormatSpec`, 对应的 encode 为 `E3M39` - -那么此时 KCL 程序中出现了 - -- 非法的字符串格式 - -可能出现错误的 KCL 程序片段如下: - -```python -a = 1 -b = 1 -data = "${a: #js}" + " $$ " # KCL插值字符串中,#js是非法的 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /datatype/str_interpolation/invalid_format_spec_fail_0/main.k:3 - | -3 | data = "${a: #js}" + " $$ " # #js is illegal string - | ^ #js is a invalid format spec - | -``` - -可以尝试以下步骤来修复这个错误: - -- 将非法 String 调整为 KCL 标准支持的 String。 - -### 1.3.11 KCLAssertionError [E3M40] - -如果在运行 KCL 时遇到错误: - -- `KCLAssertionError`, 对应的 encode 为 `E3M40` - -那么此时 KCL 程序中出现了 - -- Assert False - -可能出现错误的 KCL 程序片段如下: - -```python -assert False -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /assert/invalid/fail_0/main.k:1 - | -1 | assert False - | - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 Assert 的条件,Assert 条件为 False 时,就会出现此类错误,去掉 Assert 语句或改变条件为 True。 - -### 1.3.12 ImmutableRuntimeError [E3M44] - -如果在运行 KCL 时遇到错误: - -- `ImmutableRuntimeError`, 对应的 encode 为 `E3M44` - -那么此时 KCL 程序中出现了 - -- 不可变量的值发生改变 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - final firstName : str - lastName : str - - -schema Scholar(Person): - firstName = "CBA" - - -scholar = Scholar { - "firstName": "ABC" # firstName in schema Person is final. -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /final/fail_lazy_init_0/main.k:8:1 - | -8 | scholar = Scholar { - | attribute 'lastName' of Scholar is required and can't be None or Undefined - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 final 修饰的不可变量是否出现了赋值等改变值的操作。 - -### 1.3.13 CycleInheritError [E2D33] - -如果在运行 KCL 时遇到错误: - -- `CycleInheritError`, 对应的 encode 为 `E2D33` - -那么此时 KCL 程序中出现了 - -- 循环继承 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Parent(Son): - parent_field: str - -schema Son(GrandSon): - son_field: str - -schema GrandSon(Parent): - grandson_field: str - -parent = Parent { - parent_field: "" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /inherit/cycle_inherit_fail_1/main.k:7:8 - | -7 | schema GrandSon(Parent): - | ^ There is a circular reference between schema GrandSon and Parent - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 Schema 的继承关系,避免出现 A 继承 B,B 继承 A 的情况。 - -### 1.3.14 KCLRecursionError [E3M42] - -如果在运行 KCL 时遇到错误: - -- `KCLRecursionError`, 对应的 encode 为 `E3M42` - -那么此时 KCL 程序中出现了 - -- 循环引用 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Parent(Son): - parent_field: str - son: Son = Son { # Parent has attribute Son - parent: Parent { - parent_field: "123" - } - } - -schema Son: - son_field: str - parent: Parent = Parent { # Son has attribute Parent - son: Son { - son_field: "123" - } - } - -parent = Parent { - parent_field: "", -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -thread 'main' has overflowed its stack -fatal runtime error: stack overflow -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 Schema 中的属性成员,避免出现循环引用的问题。 - -## 1.4 KCL 编译警告 (W2xxx) - -KCL 中的编译警告如下表所示: - -| ewcode | KCL exception | messages | -| ------ | ------------------------------------------------- | ------------------ | -| W2K04 | [FloatUnderflow](#141-floatunderflow-w2k08) | Float underflow | -| W2P10 | [InvalidDocstring](#142-invaliddocstring-w2p10) | Invalid docstring | -| W2N12 | [DeprecatedWarning](#143-deprecatedwarning-w2n12) | Deprecated warning | - -### 1.4.1 FloatUnderflow [W2K08] - -如果在运行 KCL 时遇到错误: - -- `FloatUnderflow`, 对应的 encode 为 `W2K08` - -可以尝试以下步骤来修复这个错误: - -- 检查浮点数的值是否在 KCL 支持的数字范围内。 - -### 1.4.2 InvalidDocstring [W2P10] - -如果在运行 KCL 时遇到错误: - -- `InvalidDocstring`, 对应的 encode 为 `W2P10` - -那么此时 KCL 程序中出现了 - -- 无效的 doc 内容 - -可以尝试以下步骤来修复这个错误: - -- 请按照 KCL 标准编写 doc。 - -### 1.4.3 DeprecatedWarning [W2N12] - -如果在运行 KCL 时遇到错误: - -- `DeprecatedWarning`, 对应的 encode 为 `W2N12` - -那么此时 KCL 程序中出现了 - -- 过时的代码警告 - -可以尝试以下步骤来修复这个错误: - -- 尽量不要使用已经过时的代码。如果将 strict 设置为 True,KCL 将会输出错误,并停止运行。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/tour.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/tour.md deleted file mode 100644 index 93a080e5..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/tour.md +++ /dev/null @@ -1,3208 +0,0 @@ ---- -title: "KCL 之旅" -sidebar_position: 1 ---- - -本文展示了如何使用 KCL 的核心特性,包含变量、运算符、schema 和库,前提是您有使用其他语言编程的经验。KCL 主要受 Python 启发,了解 Python 对学习 KCL 非常有帮助。 - -### 重要概念 - -在学习 KCL 语言时,请牢记以下事实和概念: - -- KCL 是一种配置策略语言。它为编写配置和策略提供了简单且自洽的语言设计和库支持。它不能用于应用程序开发或其他通用编程语言(GPL)支持的场景。 -- KCL 吸收了经典 **OOP** 的元素,并且提供了**类型**、**复用**和**合并**等简单、开发人员友好、可靠且利于传播的配置编写实践。 -- KCL 更倾向于**不可变性**,建议使用**合并**来添加增量的变更。不可变性降低了副作用,例如不可预测的问题。 -- KCL 的 **schema** 结构体定义了严格的属性和静态类型,并且支持表达式验证。**schema** 结构体主要由带类型的属性、schema 上下文和检查块构成。 -- KCL 的 **config** 是一个类 **JSON** 表达式,通过它我们可以复用 schema 的完整定义。KCL 通过分离 schema 和 config 来提供定义和配置的能力。 -- KCL 的 **rule** 是一个书写规则约束表达式的结构,可用于数据校验和策略编写。 -- KCL 的代码文件以包(目录)和模块(文件)的形式进行管理。同一包中的 schema 彼此可见;跨包的数据需要通过 **import 语句**导入。包级变量虽然可以导出,但是它们不能被其他包修改。 -- KCL 语法定义主要使用声明式表达式,并且只提供少量必要的声明式语句,例如 import、 if...else、assert、assignment 以及 schema。 -- 没有主函数,每个 `.k` 文件可以作为单独的配置文件执行。 -- 支持**内置函数**和**插件**以简化编写。 - -### 关键字 - -下表列出了 KCL 语言的关键字。 - -```txt -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -### 标识符 - -在 KCL 中, 标识符是标识一个值的名称,可以带有选择器。 - -- 标识符由字母、数字、下划线或前缀 `$` 组成。 -- 标识符不能与关键字重复,除非它们有 `$` 前缀。 -- 标识符不得包含任何嵌入的空格或符号。 -- 可以在标识符中的任何位置使用字母和下划线。 -- 数字不能放在标识符的第一位。 -- `$` 字符只能放在标识符的第一个位置。 - -示例: - -```python -x -a -b1 -b_2 -_c -$if -``` - -为了简化限定标识符(例如 `pkg.type`)的定义,我们还定义了 `qualified identifier`: - -示例: - -```python -pkg.a -``` - -在 `qualified identifier` 中的包名必须通过 `import` 关键字导入。 - -#### 标识符前缀 - -使用 `$` 前缀符号定义关键字标识符。 - -```python -$if = 1 -$else = "s" -``` - -请注意,非关键字标识符是否有 `$` 符号都是同样的效果。 - -```python -_a = 1 -$_a = 2 # equal to `_a = 2` -``` - -### 变量 - -以下是如何创建并实例化变量的例子: - -```python -name = "Foo" # Declare a variable named `name` and its value is a string literal "Foo" -``` - -它对应了如下 YAML 输出: - -```yaml -name: Foo -``` - -在 KCL 中,我们可以通过定义包级变量将变量导出为配置数据。使其直接、清晰、可维护。导出的变量是不可变的。因此一旦声明它,就无法对其进行修改,例如,假设我们有一个名为 `example.k` 的配置文件,变量 `name` 在声明后就禁止修改,就像标准的命令式语言一样。 - -```python -name = "Foo" # exported - -... - -name = "Bar" # error: a exported declaration variable can only be set once. -``` - -作为补充,我们可以在模块级别定义一个非导出变量,这个变量是可变的,不会显示在 YAML 输出当中。 - -```python -_name = "Foo" # _ variables are not output to YAML and are mutable -_name = "Bar" -``` - -请注意,变量的名称不能为 `True`、`False`、`None` 或者 `Undefined`,因为它们与 KCL 内置的名称常量之间存在二义性。 - -```python -False = 1 # Error -True = False # Error -None = Undefined # Error -Undefined = None # Error -``` - -### 内置类型 - -KCL 支持以下类型: - -- 数字 -- 字符串 -- 布尔 -- 列表 -- 字典 - -#### 数字 - -KCL 的数字类型有两种形式: - -- 64 位有符号整数。值的范围为 -9223372036854775808~9223372036854775807. -- 64 位浮点数,遵循 IEEE 754 标准。我们不建议在配置中使用 float 类型,我们可以使用字符串代替并在运行时进行解析。 - -整数和浮点数都支持基本运算符,例如 `+`,`-`,`/` 和 `*`,而复杂的运算,例如 `abs()`, `ceil()` 和 `floor()`,都是通过内置的数学库来支持。 - -整数是不带小数点的数字。以下是一些定义整数的例子: - -```python -a = 1 -b = -1 -c = 0x10 # hexadecimal literal -d = 0o10 # octal literal -e = 010 # octal literal -f = 0b10 # binary literal -g = int("10") # int constructor -``` - -如果一个数字包含小数点,则它是浮点数。以下是一些浮点数的示例: - -```python -a = 1.10 -b = 1.0 -c = -35.59 -d = 32.3e+18 -f = -90. -h = 70.2E-12 -i = float("112") # float constructor -``` - -内置数学库可用于数字类型: - -```python -import math - -assert abs(-40) == 40 -assert round(70.23456) == 70 -assert min(80, 100, 1000) == 80 -assert max(80, 100, 1000) == 1000 -assert sum([0,1,2]) == 3 -assert math.ceil(100.12) == 101.0 -assert math.floor(100.12) == 100.0 -assert math.pow(100, 2) == 10000.0 -``` - -KCL 默认使用 64 位数字类型。我们可以在 KCL 命令行使用 `-r` 参数执行严格的 32 位范围检查。 - -```bash -kcl main.k -r -d -``` - -请注意,为了性能考虑该功能只能在 `debug` 模式中使用。 - -##### 单位字面值 - -在 KCL 中,我们可以给一个整数添加如下的单位后缀,这不影响它的真实值。 - -- 通用整形和定点数: `P`, `T`, `G`, `M`, `K`, `k`, `m`, `u`, `n` -- 2 的幂: `Pi`, `Ti`, `Gi`, `Mi`, `Ki` - -```python -# SI -n = 1n # 1e-09 -u = 1u # 1e-06 -m = 1m # 1e-03 -k = 1k # 1000 -K = 1K # 1000 -M = 1M # 1000000 -G = 1G # 1000000000 -T = 1T # 100000000000 -P = 1P # 1000000000000000 -# IEC -Ki = 1Ki # 1024 -Mi = 1Mi # 1024 ** 2 -Gi = 1Gi # 1024 ** 3 -Ti = 1Ti # 1024 ** 4 -Pi = 1Pi # 1024 ** 5 -``` - -此外,我们还可以使用定义在 `units` 模块中的单位常量: - -```python -import units - -n = 1 * units.n # 1e-09 -u = 1 * units.u # 1e-06 -m = 1 * units.m # 1e-03 -k = 1 * units.k # 1000 -K = 1 * units.K # 1000 -M = 1 * units.M # 1000000 -G = 1 * units.G # 1000000000 -T = 1 * units.T # 1000000000000 -P = 1 * units.P # 1000000000000000 -# IEC -Ki = 1 * units.Ki # 1024 -Mi = 1 * units.Mi # 1024 ** 2 -Gi = 1 * units.Gi # 1024 ** 3 -Ti = 1 * units.Ti # 1024 ** 4 -Pi = 1 * units.Pi # 1024 ** 5 -``` - -我们还可以使用定义在 `units` 模块内的整数和单位字符串之间的转换函数 - -```python -import units -# SI -K = units.to_K(1000) # "1K" -M = units.to_M(1000000) # "1M" -G = units.to_G(1000000000) # "1G" -T = units.to_T(1000000000000) # "1T" -P = units.to_P(1000000000000000) # "1P" -# IEC -Ki = units.to_Ki(1024) # "1Ki" -Mi = units.to_Mi(1024 ** 2) # "1Mi" -Gi = units.to_Gi(1024 ** 3) # "1Gi" -Ti = units.to_Ti(1024 ** 4) # "1Ti" -Pi = units.to_Pi(1024 ** 5) # "1Pi" -``` - -```python -import units -# SI -K = units.to_K(int("1M")) # "1000K" -M = units.to_M(int("1G")) # "1000M" -G = units.to_G(int("1T")) # "1000G" -T = units.to_T(int("1P")) # "1000T" -P = units.to_P(int("10P")) # "10P" -# IEC -Ki = units.to_Ki(int("1Mi")) # "1024Ki" -Mi = units.to_Mi(int("1Gi")) # "1024Mi" -Gi = units.to_Gi(int("1Ti")) # "1024Gi" -Ti = units.to_Ti(int("1Pi")) # "1024Ti" -Pi = units.to_Pi(int("10Pi")) # "10Pi" -``` - -单位类型定义在 `units` 模块中,单位类型的值不能进行任何四则运算。 - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -x0: NumberMultiplier = 1M # Ok -x1: NumberMultiplier = x0 # Ok -x2 = x0 + x1 # Error: unsupported operand type(s) for +: 'number_multiplier(1M)' and 'number_multiplier(1M)' -``` - -我们可以使用 `int()`、`float()` 和 `str()` 函数将数值单位类型转换为数字类型或字符串类型。 - -```python -a: int = int(1Ki) # 1024 -b: float = float(1Ki) # 1024.0 -c: str = str(1Mi) # "1Mi" -``` - -#### 字符串 - -字符串是一个不可变的 Unicode 字符序列。我们可以使用单引号或双引号创建字符串: - -```python -'allows embedded "double" quotes' # Single quotes -"allows embedded 'single' quotes" # Double quotes -'''Three single quotes''', """Three double quotes""" # Triple quoted -``` - -三引号用于定义多行字符串。 - -```python -"""This is a long triple quoted string -may span multiple lines. -""" -``` - -请注意,KCL 的单引号和双引号字符串的使用几乎没有区别。唯一可以简化的是,我们不需要在单引号字符串中转义双引号,也不需要在双引号中转义单引号。 - -```python -'This is my book named "foo"' # Don’t need to escape double quotes in single quoted strings. -"This is my book named 'foo'" # Don’t need to escape single quotes in double quoted strings. -``` - -我们可以使用 `+` 操作符连接字符串: - -```python -x = 'The + operator ' + 'works, as well.' -``` - -我们可以使用 `str` 内置函数将 int 或 float 转为字符串: - -```python -x = str(3.5) # "3.5" -``` - -可以使用很多内置的字符串函数: - -```python -x = "length" -assert len(x) == 6 # True -assert x.capitalize() == "Length" -assert x.count("gt") == 1 -assert x.endswith("th") == True -assert x.find("gth") == 3 -assert "{} {}".format("hello", "world") == 'hello world' -assert x.index("gth") == 3 -assert x.isalnum() == True -assert x.isalpha() == True -assert "123456".isdigit() == True -assert x.islower() == True -assert " ".isspace() == True -assert "This Is Title Example".istitle() == True -assert x.isupper() == False -assert "|".join(["a", "b", "c"]) == "a|b|c" -assert "LENGTH".lower() == "length" -assert ' spacious '.lstrip() == 'spacious ' -assert x.replace("th", "ht") == "lenght" -assert "lengthlength".rfind("le") == 6 -assert "lengthlength".rindex("le") == 6 -assert "length length".rsplit() == ["length", "length"] -assert "length ".rstrip() == "length" -assert "length length".split() == ["length", "length"] -assert 'ab c\n\nde fg\rkl\r\n'.splitlines() == ['ab c', '', 'de fg', 'kl'] -assert "length".startswith('len') == True -assert "***length***".strip('*') == "length" -assert "length length".title() == "Length Length" -assert x.upper() == "LENGTH" -``` - -格式化字符串有两种使用方法: 使用 `"{}".format()` 内置函数, 或者使用花括号指定变量并使用 `$` 标记取变量值。在 KCL 中叫做**插值字符串**。在下面的例子中,`a` 和 `b` 的值都是 `"hello world"`。 - -此外,要序列化的变量可以以特殊的数据格式提取,例如 YAML 或 JSON。在这种情况中,`#yaml` 或 `#json` 可以包含在花括号中。 - -具体来说,当 `$` 符号本身需要出现在**插值字符串**中,需要使用 `$$` 转义。或者使用 `+` 符号连接 `$` 符号和插值字符串来避免转义。在以下示例中,`c` 和 `c2` 的值都是 `$hello world$`。 - -```python -world = "world" -a = "hello {}".format(world) # "hello world" -b = "hello ${world}" # "hello world" -c = "$$hello ${world}$$" # "$hello world$" -c2 = "$" + "hello ${world}" + "$" # "$hello world$" - -myDict = { - "key1" = "value1" - "key2" = "value2" -} - -d = "here is myDict in json: ${myDict: #json}" -# d: 'here is myDict in json: {"key1": "value1", "key2": "value2"}' - -e = "here is myDict in yaml:\n${myDict: #yaml}" -# e: | -# here is myDict in yaml: -# key1: value1 -# key2: value2 -``` - -此外,我们可以在上面的示例代码输出 **YAML 字符串** 中看到一些符号,例如 `|`、`>`、`+`、`-`。 - -- `|` 表示 **块文字样式**,指示块内换行符的行为方式。 -- `>` 表示块标量中的**块折叠样式**,换行符将被空格替换。 -- `+` 和 `-` 是 **block chomping 指示符**,用于控制字符串末尾的换行符。 默认值 **clip** 在字符串的末尾放置一个换行符。 要删除所有换行符,请通过在样式指示符 `|` 或 `>` 后面添加 `-` 来**删除**它们。 clip 和 strip 都忽略块末尾实际有多少换行符; 在样式指示符后面添加一个 `+` 来**保留**它们。 - -例如,**strip 块文字样式** yaml 字符串是 - -```yaml -example: |- - Several lines of text, - with some "quotes" of various 'types', - and also a blank line: - - plus another line at the end. -``` - -结果为: - -```plain -Several lines of text, -with some "quotes" of various 'types', -and also a blank line: - -plus another line at the end. -``` - -更多信息可见 [Yaml Multiline String](https://yaml-multiline.info/) 和 [YAML Specification v1.2](https://yaml.org/spec/1.2.1/) 。 - -##### 原始字符串 - -KCL 原始字符串是通过在字符串字面值前加上 `'r'` 或 `'R'` 来创建的。 KCL 原始字符串将反斜杠 (`\`) 和字符串插值 (`${}`) 视为普通的非字符。当我们想要一个包含反斜杠、字符串插值的字符串并且不希望它们被视为转义字符时,原始字符串是很有用的。 - -- 对于包含反斜杠(`\`)的原始字符串,KCL 代码和输出 YAML 如下: - -```python -s = "Hi\nHello" -raw_s = r"Hi\nHello" # This is a KCL raw string with the `r` prefix. -``` - -```yaml -s: |- - Hi - Hello -raw_s: Hi\nHello -``` - -- 对于包含字符串插值(`${}`)的原始字符串,KCL 代码和输出 YAML 如下: - -```python -worldString = "world" -s = "Hello ${worldString}" -raw_s = r"Hello ${worldString}" # This is a KCL raw string with the `r` prefix. -``` - -```yaml -worldString: world -s: Hello world -raw_s: Hello ${worldString} -``` - -此外,原始字符串最常用的场景是在正则表达式中使用: - -```python -import regex - -key = "key" -result = regex.match(key, r"[A-Za-z0-9_.-]*") # True -``` - -#### 布尔值 - -布尔值有两个常量对象:`False` 和 `True`. - -```python -a = True -b = False -``` - -#### List - -List 是一个序列,通常用于存储同质项的集合。下面是一个简单的 KCL 列表的例子: - -```python -list = [1, 2, 3] -assert len(list) == 3 # True -assert list[0] == 1 # True -``` - -我们可以使用列表推导式构建列表: - -```python -list = [ _x for _x in range(20) if _x % 2 == 0] -assert list == [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] # True -``` - -并且还可以使用嵌套的列表推导式: - -```python -matrix = [[1, 2], [3,4], [5,6], [7,8]] -transpose = [[row[_i] for row in matrix] for _i in range(2)] -assert transpose == [[1, 3, 5, 7], [2, 4, 6, 8]] # True -``` - -此外,我们可以在列表推导式中使用两个变量。第一个变量表示列表中的索引,第二个变量表示列表中的项。 - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use `_` to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -我们可以通过 `+` 连接列表: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -joined_list = _list0 + _list1 # [1, 2, 3, 4, 5, 6] -``` - -我们可以使用解包操作符 `*` 合并多个列表: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -union_list = [*_list0, *_list1] # [1, 2, 3, 4, 5, 6] -``` - -我们可以使用 `if` 表达式动态的将元素添加到列表,符合条件的元素会被添加到列表,不符合条件的元素会被忽略。 - -```python -a = 1 # 1 -data = [ - 1 - if a == 1: 2 - if a > 0: 3 - if a < 0: 4 -] # [1, 2, 3] -``` - -```python -a = 1 # 1 -data1 = [ - 1 - if a == 1: - 2 - elif a == 2: - 3 - else: - 3 -] # [1, 2] -data2 = [ - 1 - if a == 1: 2 - elif a == 2: 2 - else: 3 -] # [1, 2] -``` - -我们可以合并(union)列表: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -union_list = _list0 | _list1 # [4, 5, 6] -``` - -我们可以使用 `for k in list_var` 表达式遍历列表: - -```python -data = [1, 2, 3] -dataAnother = [val * 2 for val in data] # [2, 4, 6] -``` - -#### Dict - -Dict 是将可哈希的值映射到任意对象的映射对象。字典是有序的。键的顺序遵循其声明的顺序: - -这里有几个简单的 KCL 字典: - -```python -a = {"one" = 1, "two" = 2, "three" = 3} -b = {'one' = 1, 'two' = 2, 'three' = 3} -assert a == b # True -assert len(a) == 3 # True -``` - -在写多行的键-值时,可以省略每个键-值对行尾的逗号 `,`: - -```python -data = { - "key1" = "value1" # Ignore the comma ',' at the end of line - "key2" = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -在 Dict 键上使用简单的字面值时可以省略引号: - -```python -data = { - key1 = "value1" # Ignore key quotation '"' - key2 = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -此外,**选择表达式**可以用于定义包含嵌套键 dict 实例。 - -```python -person = { - base.count = 2 - base.value = "value" - labels.key = "value" -} # {"base": {"count": 2, "value": "value"}, "labels": {"key": "value"}} -``` - -输出 YAML 为: - -```yaml -person: - base: - count: 2 - value: value - labels: - key: value -``` - -在 KCL 中,dict 中的不同的字段可以直接引用,比如如下的例子 - -```python -config = { - name = "me" - metadata.name = name # Reference `name` with the value `"me"` in `config` directly. -} -``` - -输出 YAML 为: - -```yaml -config: - name: me - metadata: - name: me -``` - -我们可以使用字典推导式构建字典: - -```python -x = {str(i): 2 * i for i in range(3)} -assert x == {"0" = 0, "1" = 2, "2" = 4} -``` - -此外,我们可以在字典推导式中使用两个变量。第一个变量表示字典的键,第二个变量表示字典中键对应的值。 - -```python -data = {key1 = "value1", key2 = "value2"} -# Single variable loop -dataKeys1 = {k: k for k in data} # {"key1": "key1", "key2": "key2"} -dataValues1 = {k: data[k] for k in data} # {"key1": "value1", "key2": "value2"} -# Double variable loop -dataKeys2 = {k: k for k, v in data} # {"key1": "key1", "key2": "key2"} -dataValues2 = {v: v for k, v in data} # {"value1": "value1", "value2": "value2"} -dataFilter = {k: v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use `_` to ignore loop variables -dataKeys3 = {k: k for k, _ in data} # {"key1": "key1", "key2": "key2"} -dataValues3 = {v: v for _, v in data} # {"value1": "value1", "value2": "value2"} -``` - -我们可以使用解包操作符 `**` 来合并字典: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = {**_part1, **_part2} # {"a: "b", "c": "d"} -``` - -此外,union 操作符 `|` 也能达到同样的效果: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = _part1 | _part2 # {"a: "b", "c": "d"} -``` - -我们可以使用 `if` 表达式动态的将元素添加到字典,符合条件的元素会被添加到字典,不符合条件的元素会被忽略。 - -```python -a = 1 # 1 -data = { - key1 = "value1" - if a == 1: key2 = "value2" - if a > 0: key3 = "value3" - if a < 0: key4 = "value4" -} # {"key1": "value1", "key2": "value2", "key3": "value3"} -``` - -```python -a = 1 # 1 -data1 = { - key1 = "value1" - if a == 1: - key2 = "value2" - elif a > 0: - key3 = "value3" - else: - key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -data2 = { - key1 = "value1" - if a == 1: key2 = "value2" - elif a > 0: key3 = "value3" - else: key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -``` - -我们可以使用 `for k in dict_var` 表达式来遍历字典, 并且可以使用 `in` 操作符来判断 dict 是否包含某个键。 - -```python -data = {key1 = "value1", key2 = "value2"} -dataAnother = {k: data[k] + "suffix" for k in data} # {"key1": "value1suffix", "key2": "value2suffix"} -containsKey1 = "key1" in data # True -containsKey2 = "key" in data # False -``` - -#### None - -在 KCL 中, `None` 表示对象的值为空, 这与 Go 中的 `nil` 和 Java 中的 `null` 一样,并且对应于 YAML 中的 `null`。 - -```python -a = None -b = [1, 2, None] -c = {key1 = "value1", key2 = None} -``` - -输出如下: - -```yaml -a: null -b: - - 1 - - 2 - - null -c: - key1: value1 - key2: null -``` - -请注意,`None` 不能参与四则运算,但它可以参与逻辑运算和比较运算。 - -```python -a = 1 + None # error -b = int(None) # error -c = not None # True -d = None == None # True -e = None or 1 # 1 -f = str(None) # None -``` - -#### Undefined - -`Undefined` 与 `None` 类似,但其语义是变量没有分配任何值,也不会输出到 YAML。 - -```python -a = Undefined -b = [1, 2, Undefined] -c = {key1 = "value1", key2 = Undefined} -``` - -输出如下: - -```yaml -b: - - 1 - - 2 -c: - key1: value1 -``` - -请注意,`Undefined` 不能参与四则运算,但它可以参与逻辑运算和比较运算。 - -```python -a = 1 + Undefined # error -b = int(Undefined) # error -c = not Undefined # True -d = Undefined == Undefined # True -e = Undefined or 1 # 1 -f = str(Undefined) # Undefined -``` - -### 运算符 - -以下字符表示运算符: - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != @ \ -``` - -#### 算数运算符 - -KCL 支持常见的算数运算符: - -```python -assert 2 + 3 == 5 -assert 2 - 3 == -1 -assert 2 * 3 == 6 -assert 5 / 2 == 2.5 -assert 5 // 2 == 2 -assert 5 % 2 == 1 -``` - -#### 相等和关系运算符 - -KCL 支持相等和关系运算符: - -```python -assert 2 == 2 -assert 2 != 3 -assert 3 > 2 -assert 2 < 3 -assert 3 >= 3 -assert 2 <= 3 -``` - -#### 逻辑运算符 - -我们可以使用逻辑运算符反转或组合布尔表达式,例如:`and` 和 `or`: - -```python -if not done and (col == 0 or col == 3): - # ...Do something... - -``` - -#### 位运算符和移位运算符 - -以下是位运算符和移位运算符的例子: - -```python -value = 0x22 -bitmask = 0x0f - -assert (value & bitmask) == 0x02 -assert (value & ~bitmask) == 0x20 -assert (value | bitmask) == 0x2f -assert (value ^ bitmask) == 0x2d -assert (value << 4) == 0x220 -assert (value >> 4) == 0x02 -``` - -`|` 运算符可用于位运算,合并基本类型和集合及结构化数据,例如**列表**、**字典**和 **schema**。 - -位运算示例: - -```python -0x12345678 | 0xFF # 0x123456FF -``` - -联合基本类型示例: - -```python -schema x: - a: int | str # attribute a could be a int or string -``` - -#### 赋值运算符 - -以下 token 作为语法中的分隔符: - -```txt - ( ) [ ] { } - , : . ; = -> - += -= *= /= //= %= - &= ^= >>= <<= **= -``` - -以下是使用赋值和参数赋值赋值运算符的例子: - -```python -_a = 2 -_a *= 3 -_a += 1 -assert _a == 7 -``` - -#### Identity 运算符 - -以下关键字作为语法中的 identity 运算符: - -```python -is, is not -``` - -Identity 运算符检查右侧和左侧是否时同一对象。它们通常用于检查某个变量是否是 `None/Undefined/True/False`。以下是一些例子: - -```python -empty_String = "" -empty_String is not None # True -``` - -#### 成员运算符 - -以下关键字作为语法中的成员运算符: - -```python -in, not in -``` - -- `in` 运算符计算了第一个操作数是否是第二个操作数的成员,第二个运算符必须是 list、dict、schema 或 string。 -- `not in` 运算符与 `in` 相反。它们都返回一个布尔值。 - -成员的含义因第二个操作数的类型而异:列表的成员是其元素;字典的成员是其键;字符串的成员是其所有子字符串。 - -```python -1 in [1, 2, 3] # True - -d = {one = 1, two = 2} -"one" in d # True -"three" in d # False -1 in d # False -[] in d # False - -"nasty" in "dynasty" # True -"a" in "banana" # True -"f" not in "way" # True - -d = Data {one = 1, two = 2} # Data is a schema with attributes one and two -"one" in d # True -"three" in d # False -``` - -#### 推导式 - -一个推导表达式通过遍历一个或多个迭代项并计算表达式生成的结果来生成连续的元素,并以此构造新的列表或字典。 - -我们可以如下使用列表和字典的推导表达式: - -```python -listVar = [_x for _x in range(20) if _x % 2 == 0] # list comprehension -dictVar = {str(_i): 2*_i for _i in range(3)} # dict comprehension -``` - -#### 其他运算符 - -- 使用 **()** 表示函数调用, 例如 `"{} {}".format("hello", world)`。 -- 使用 **[]** 引用列表中指定索引处的值。 -- 使用 **:** 定义类型注解。 -- 使用 **.** 引用成员字段。 -- 使用 **\\** 续行符编写长表达式。 - -```python -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " -``` - -### 表达式 - -#### 条件表达式 - -条件表达式的形式为 `a if cond else b`。它首先计算条件 `cond`。如果为真,则会计算 `a` 并生成它的值;否则,它会生成 `b` 的值。 - -示例: - -```python -x = True if enabled else False # If enabled is True, x is True, otherwise x is False -``` - -#### 索引表达式 - -索引表达式 `a[i]` 生成可索引类型的第 `i` 个元素,例如字符串或数组。索引 `i` 必须是 `-n` ≤ `i` < `n` 范围内的 `int` 值,其中 `n` 等于 `len(a)`。其他任何索引都会导致错误。 - -有效的负索引的行为类似于 `n+i`,允许方便的对序列末尾进行索引。 - -```python -val = "abc" -list = ["zero", "one", "two"] -str_0 = val[0] # "a" -str_1 = val[1] # "b" -str_n1 = val[-1] # "c" - -list_0 = list[0] # "zero" -list_1 = list[1] # "one" -list_n1 = list[-1] # "two" -``` - -索引表达式 `d[key]` 也可以用于字典 `d`,以获取指定键对应的值。如果字典中不包含这个键则会返回 `Undefined` - -出现在赋值符左侧的索引表达式会更新指定的列表或字典元素。 - -```python -d = {key1 = "value1", key2 = "value2"} -key1value = d["key1"] # value1 -key2value = d["key2"] # value2 -``` - -尝试更新不可变类型的元素值(如列表或字符串)或可变类型的不可变变量会产生错误。 - -#### 切片表达式 - -切片表达式 `a[start:stop:step]` 会生成 `a` 包含的一个子序列,其中 `a` 必须是字符串或者数组。 - -`start`、`stop` 和 `step` 三个操作数都是可选的。如果有的话,每个值都必须为整数。`step` 的默认值为 1。如果 `step` 未指定,它前面的冒号也可以省略。指定 `step` 为 0 会产生错误。 - -从概念上来说,这些操作数指定了一系列值,索引 `i` 从 `start` 开始,每次增加 `step` 直到 `i` 到达或超过 `stop`。结果由有效的 `i` 的 `a[i]` 组成。 - -如下所示,从三个操作数计算有效的开始和结束的索引。`n` 是序列的长度。 - -```python -val = "abc" -len = len(val) -a = val[1:len] # "bc" (remove first element) -b = val[0:-1] # "ab" (remove last element) -c = val[1:-1] # "b" (remove first and last element) -``` - -```python -"abc"[1:] # "bc" (remove first element) -"abc"[:-1] # "ab" (remove last element) -"abc"[1:-1] # "b" (remove first and last element) -"banana"[1::2] # "aaa" (select alternate elements starting at index 1) -"banana"[4::-2] # "nnb" (select alternate elements in reverse, starting at index 4) -``` - -KCL 禁止将切片表达式定义为左值。原因是列表和字符串是不可变的,重新切片可以直接操作操作数,以确保更好的性能。 - -#### 函数调用 - -KCL 允许调用内置函数,或者调用内置和系统模块中的函数。 - -调用函数的基本方法如下所示: - -```python -import math - -a = math.pow(2, 3) # 2 powers 3 is 8. -b = len([1, 2, 3]) # the length of [1, 2, 3] is 3 -``` - -参数以 `,` 分隔,并且 KCL 还支持位置参数和键-值对形式的参数。 - -```python -print("hello world", end="") -``` - -请注意: - -- 有些函数参数具有默认值。 -- 一些函数接受可变参数。 - -如果没有为没有默认值的参数提供参数,则会抛出错误。 - -#### 选择表达式 - -选择表达式选择值的属性或方法。KCL 提供了许多识别或过滤属性的方法: - -`x.y` - -- dict: 表示字典 `x` 中键 `y` 对应的值。 -- schema: 表示 schema `x` 中 `y` 属性的值。 -- package: 表示 package `x` 中 `y` 标示的标识符。 - -示例: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -name = person.name # "Alice" -age = person.age # 18 - -myDict = { - key = "value" -} -result = myDict.key # "value" -``` - -`x?.y` - -`x` 可以是 schema 实例或 dict。当 `x` 可能为 `None` 或者键 `y` 不在 `x` 中时这非常有用。 - -```python -# Example of dict: -data = {"key" = "value"} -a = data?.key # "value" -b = data?.name # Undefined - -# example of schema instance: -schema Company: - name: str - address: str - -schema Person: - name: str - job?: Company - -alice = Person { - name = "alice" -} - -if alice?.job?.name == "Group": - print("work in Group") -``` - -#### Quantifier 表达式 - -Quantifier 表达式用于集合:列表或字典。通常用于在处理集合后获得某个结果,主要有以下四种形式: - -- **all** - - 用于检测集合中所有元素都满足给定的逻辑表达式,并且返回一个布尔值作为结果。 - - 只有集合中所有元素都满足表达式为 true 时,`all` 表达式为 true,否则为 false。 - - 如果集合为空,返回 true。 - - 支持表达式执行期间逻辑表达式的短路。 -- **any** - - 用于检测集合中至少一个元素都满足给定的逻辑表达式,并且返回一个布尔值作为结果。 - - 当集合中至少一个元素都满足表达式为 true 时,`any` 表达式为 true,否则 false。 - - 如果集合为空,返回 false。 - - 支持表达式执行期间逻辑表达式的短路。 -- **map** - - 映射集合中的元素生成新的列表。 - - 新列表的长度严格等于原列表的长度。 -- **filter** - - 通过逻辑判断筛选原集合中的元素,返回一个经过筛选的子集合。 - - 当表达式为 true 时才将元素添加到子集合。 - - 产生的新集合的类型(list, dict 和 schema)与原集合的类型完全一致,并且长度为 `[0, len(original-collection)]`。 - -**all** 和 **any** 表达式的示例代码: - -```python -schema Config: - volumes: [{str:}] - services: [{str:}] - - check: - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - }, "invalid cluster ip" - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } -``` - -**map** 和 **filter** 表达式的示例代码: - -```python -a = map e in [{name = "1", value = 1}, {name = "2", value = 2}] { - {name = e.name, value = int(e.value) ** 2} -} # [{"name": "1", value: 1}, {"name": "2", "value": 4}] - -b = map k, v in {a = "foo", b = "bar"} { v } # ["foo", "bar"] - -c = filter e in [{name = "1", value = 1}, {name = "2", value = 2}] { - int(e.value) > 1 -} # [{"name": "2", "value": 2}] - -d = filter _, v in {a = "foo", b = "bar"} { - v == "foo" -} # {"a": "foo"} -``` - -请注意,区分 any 表达式和 any 类型的区别。当 `any` 在类型注解中使用,意味着变量的值是任意的,而 any 表达式意味着集合中的至少一个元素满足条件。 - -### 流程控制表达式 - -#### If 和 Else - -KCL 支持 `if` 表达式和可选的 `elif` 和 `else` 表达式, 示例如下: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - print("maybe a is negative") -else: - print("a >= 100") -``` - -`elif` 的例子: - -```python -_result = 0 -if condition == "one": - _result = 1 -elif condition == "two": - _result = 2 -elif condition == "three": - _result = 3 -else: - _result = 4 -``` - -`if-elif-else` 表达式可以嵌套,示例如下: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - if a < 0: - print("a is negative") - print("No matter a is negative or positive, this message is printed") -else: - print("a >= 100") -``` - -此外,对于简单的 `if` 表达式如下: - -```python -if success: - _result = "success" -else: - _result = "failed" -``` - -我们可以使用 ` if else ` 的形式将它们写在一行: - -```python -_result = "success" if success else "failed" -``` - -`if` 或 `elif` 语句计算一个给定的表达式。当表达式的计算结果为 `True`, `:` 之后的语句将被计算,而当表达式为 `False` ,后面的语句不会被计算。 - -请注意,常量 `False`, `None`, 数字 `0`, 空列表 `[]`, 空字典 `{}` 和空字符串 `""` 都被视为 `False` 。 - -```python -_emptyStr = "" -_emptyList = [] -_emptyDict = {} -isEmptyStr = False if _emptyStr else True -isEmptyList = False if _emptyList else True -isEmptyDict = False if _emptyDict else True -``` - -结果为: - -```yaml -isEmptyStr: true -isEmptyList: true -isEmptyDict: true -``` - -### 断言语句 - -当发生错误时,开发人员应该能够检测到错误并终止执行。因此,KCL 引入了 `assert` 语法,示例如下: - -```python -a = 1 -b = 3 -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -``` - -此外,我们可以为 assert 语声明一个条件,当条件满足时,才进行 assert 断言 - -- 使用 if 语句书写条件断言 - -```python -a = None -if a: - assert a > 2: -``` - -- 使用 if 表达式书写条件断言 - -```python -a = None -assert a > 2 if a -``` - -### 函数 - -KCL 支持使用 lambda 关键字定义一个函数 - -```python -func = lambda x: int, y: int -> int { - x + y -} -a = func(1, 1) # 2 -``` - -lambda 函数具有如下特性: - -- lambda 函数将最后一个表达式的值作为函数的返回值,空函数体返回 None -- 返回值类型注解可以省略,返回值类型为最后一个表达式值的类型 -- 函数体中没有与顺序无关的特性,所有的表达式都是按顺序执行的 - -```python -_func = lambda x: int, y: int -> int { - x + y -} # Define a function using the lambda expression -_func = lambda x: int, y: int -> int { - x - y -} # Ok -_func = lambda x: int, y: int -> str { - str(x + y) -} # Error (int, int) -> str can't be assigned to (int, int) -> int -``` - -lambda 函数对象不能参与任何计算,只能在赋值语句和调用语句中使用。 - -```python -func = lambda x: int, y: int -> int { - x + y -} -x = func + 1 # Error: unsupported operand type(s) for +: 'function' and 'int(1)' -``` - -lambda 函数支持捕获其外部作用域的变量,并且可以作为其他函数的参数进行传递 - -```python -a = 1 -func = lambda x: int { - x + a -} -funcOther = lambda f, para: int { - f(para) -} -r0 = funcOther(func, 1) # 2 -r1 = funcOther(lambda x: int { - x + a -}, 1) # 2 -``` - -输出为: - -```yaml -a: 1 -r: 2 -``` - -此外,可以定义一个匿名函数并直接调用。 - -```python -result = (lambda x, y { - z = 2 * x - z + y -})(1, 1) # 3 -``` - -并且还可以在 for 循环使用使用匿名函数 - -```python -result = [(lambda x, y { - x + y -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 3, 3, 4] -``` - -请注意,KCL 中定义的函数的均为纯函数: - -- 函数的返回结果只依赖于它的参数。 -- 函数执行过程里面没有副作用。 - -因此,KCL 函数不能修改外部的变量,只能引用外部的变量,比如如下代码会发生错误: - -```python -globalVar = 1 -func = lambda { - x = globalVar # Ok - globalVar = 1 # Error -} -``` - -### 类型系统 - -#### 类型注解 - -类型注解可用于包级变量,schema 属性和参数。 - -- 属性可以是基本类型,例如字符串(`string`),浮点数(`float`),定点数(`int`) 或布尔值(`bool`)。 -- 属性可以是字面值类型,例如字符串文本(`"TCP"` 和 `"UDP"`),数字文本 (`"1"` 和 `"1.2"`),布尔值文本(`True` 和 `False`)。 -- 属性也可以是列表或字典: - - 未指定元素类型的列表为 `[]`。 - - 元素类型为 `t` 的列表为 `[t]`。这里 `t` 是另一种类型。 - - 键的类型为 `kt` 且值的类型为 `vt` 的字典为 `{kt:vt}`。 - - `kt`, `vt` 或两者都可以为空, 就像列表未指定元素类型一样。 -- 属性可以是由 `|` 定义的 **联合类型** ,例如 `a | b`, 意为类型可以是 a 或 b。 - - 联合类型可以包含 `int`, `str`, `float`, `bool`, `list`, `dict`, 字面值类型和 schema 类型,并且支持类型的嵌套,例如: `{str:str|int}`、`[[int|str]|str|float]` 和 `2 | 4 | 6` 等。 -- 属性可以是 schema 类型。在这种情况下,使用包名 + schema 名称作为类型名。 -- 属性可以声明为任意类型,例如 `any`。 - -示例 - -- 基本类型 - -```python -"""Top level variable type annotation""" -a: int = 1 # Declare a variable `a` that has the type `int` and the value `1` -b: str = "s" # Declare a variable `b` that has the type `str` and the value `"s"` -c: float = 1.0 # Declare a variable `c` that has the type `float` and the value `1.0` -d: bool = True # Declare a variable `d` that has the type `bool` and the value `True` -``` - -- List/Dict/Schema 类型 - -```python -schema Person: - name: str = "Alice" - age: int = 10 - -a: [int] = [1, 2, 3] # Declare a variable `a` that has the list type `[int]` and the value `[1, 2, 3]` -b: {str:str} = {k1 = "v1", k2 = "v2"} # Declare a variable `b` that has the dict type `{str:str}` and the value `{k1 = "v1", k2 = "v2"}` -c: Person = Person {} # Declare a variable `c` that has the schema type `Person` and the value `Person {}` -``` - -- 联合类型 - -```python -# Basic union types -schema x[argc: int]: # Schema argument type annotation - p: int | str # Schema attribute type annotation -``` - -```python -# Literal union types -schema LiteralType: - # String literal union types, x_01 can be one of "TCP" and "UDP" - x_01: "TCP" | "UDP" - # Number literal union types, x_02 can be one of 2, 4, and 6 - x_02: 2 | 4 | 6 - # Unit union types, x_03 can be one of 1Gi, 2Gi and 4Gi - x_03: 1Gi | 2Gi | 4Gi - -x = LiteralType { - x_01 = "TCP" - x_02 = 2 - x_03 = 1Gi -} -``` - -当属性的值不符合联合类型定义时,编译器会抛出错误: - -```python -# Literal union types -schema LiteralType: - # String literal union types, x_01 can be one of "TCP" and "UDP" - x_01: "TCP" | "UDP" - -x = LiteralType { - x_01 = "HTTP" # Error: the type got is inconsistent with the type expected, expect str(TCP)|str(UDP), got str(HTTP) -} -``` - -- Any 类型 - -```python -# Any type -schema Config: - literalConf: any = 1 - dictConf: {str:any} = {key = "value"} - listConf: [any] = [1, "2", True] - -config = Config {} -``` - -请注意,一般在配置编写中不提倡使用 `float` 和 `any` 类型,因为它们都存在一定的不稳定因素,比如精度丢失,无法进行静态类型检查等。 - -此外在 KCL 中,不允许修改一个变量的类型。如果在重新分配值时不满足类型,将引发类型错误。 - -```python -_a = 1 # The type of `_a` is `int` -_a = "s" # Error: expect int, got str(s) -``` - -变量可以赋值给其上界类型,但不能赋值给它的特化类型。 - -`None` 和 `Undefined` 可以赋值给任何类型: - -- 任何类型都可以赋值给 `any` 类型, `None` 和 `Undefined` 可以赋值给 `any` 类型。 - -```python -a: int = None -b: str = Undefined -c: any = 1 -d: any = "s" -e: any = None -``` - -- `int` 类型可以赋值给 `float` 类型, `float` 类型不能赋值给 `int` 类型. - -```python -a: float = 1 -b: int = 1.0 # Error: expect int, got float(1.0) -``` - -- `int` 类型可以赋值给 `int|str` 类型, `int|str` 不能赋值给 `int` 类型. - -```python -a: int | str = 1 -b: int = 1 if a else "s" # Error: expect int, got int(1)|str(s) -``` - -请注意,在 KCL 中虽然提供了 any 类型,但是它仍然是静态类型,所有变量的类型在编译期间不可变。 - -#### 类型推导 - -如果顶层或 schema 中的变量或常量声明没有使用显式的类型注解,则会从初始值推断类型。 - -- 整形数值被推断为 `int`。 - -```python -a = 1 # The variable `a` has the type `int` -``` - -- 浮点数被推断为 `float`。 - -```python -a = 1.0 # The variable `a` has the type `float` -``` - -- 字符串被推断为 `str`。 - -```python -a = "s" # The variable `a` has the type `str` -``` - -- 布尔值被推断为 `bool`。 - -```python -a = True # The variable `a` has the type `bool` -b = False # The variable `b` has the type `bool` -``` - -- `None` 和 `Undefined` 被推断为 `any`。 - -```python -a = None # The variable `a` has the type `any` -b = Undefined # The variable `b` has the type `any` -``` - -- 列表的类型根据元素类型推断,并且是可变大小的。 - -```python -a = [1, 2, 3] # The variable `a` has the type `[int]` -b = [1, 2, True] # The variable `b` has the list union type `[int|bool]` -c = ["s", 1] # The variable `c` has the list union type `[int|str]` -``` - -请注意,空列表将被推导为 `[any]` 类型。 - -```python -a = [] # The variable `a` has the type `[any]` -``` - -- 字典的类型是根据元素的键和值推断的,并且是可变大小的。 - -```python -a = {key = "value"} # The variable `a` has the type `{str:str}` -b = {key = 1} # The variable `b` has the type `{str:int}` -c = {key1 = 1, key2 = "s"} # The variable `c` has the type `{str:int|str}` -``` - -请注意,空字典将被推导为 `{any:any}` 类型。 - -```python -a = {} # The variable `a` has the type `{any:any}` -``` - -- 携带运行时值的 if 条件表达式的类型将被静态推断为所有可能结果的联合类型。 - -```python -a: bool = True # The variable `a` has the type `bool` -b = 1 if a else "s" # The variable `b` has the type `int|str` -``` - -当变量被推导为某个类型时,它的类型不能再改变。 - -```python -_a = 1 -_a = "s" # Error: expect int, got str(1) -``` - -#### 类型别名 - -在 KCL 中,我们可以使用 `type` 关键字为所有类型声明一个类型别名简化复杂类型的书写。 - -```python -type Int = int -type String = str -type StringOrInt = String | Int -type IntList = [int] -type StringAnyDict = {str:} -``` - -我们可以从一个包中导入一个类型并为它定义一个别名。 - -```py -import pkg - -type Data = pkg.Data -``` - -此外,我们还可以使用类型别名和字面值联合类型充当近似枚举的效果。 - -```python -# A type alias of string literal union types -type Color = "Red" | "Yellow" | "Blue" - -schema Config: - color: Color = "Red" # The type of color is `"Red" | "Yellow" | "Blue"`, and it has an alias `Color`, whose default value is `"Red"` - -config = Config { - color = "Blue" -} -``` - -上述代码执行的输出结果为: - -```yaml -config: - color: Blue -``` - -请注意,类型别名不能与已有的内置类型 `any`、`int`、`float`、`bool` 和 `str` 等相同 - -```python -type any = int | str # Error -type int = str # Error -type float = int # Error -type bool = True # Error -type str = "A" | "B" | "C" # Error -``` - -#### 类型守卫 - -KCL 支持在程序中使用 `typeof` 函数对任意值求得其运行时的类型。 - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person {} -t3 = typeof(_x1) - -_x2 = pkg.Person {} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# Output -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -除此之外,我们可以使用 `as` 关键字在运行时作类型转换。`as` 关键字的一般用法如下: - -- 具有偏序关系的基础类型,比如 `float -> int` -- 具有偏序关系的联合类型,比如 `int | str -> str` -- 对类型上界 `any` 的转换,比如 `any -> int` -- 具有偏序关系的结构类型,比如 `base-schema -> sub-schema` - -```python -schema Data1: - id?: int - -schema Data2: - name?: str - -data: Data1 | Data2 = Data1 {} - -if typeof(a) == "Data1": - data1 = data as Data1 # The type of `data1` is `Data1` -elif typeof(a) == "Data2": - data2 = data as Data2 # The type of `data2` is `Data2` -``` - -当类型转换失败时,一个运行时错误将被抛出。 - -```python -a: any = "s" -b: int = a as int # Error: The `str` type cannot be converted to the `int` type -``` - -如果不想要运行时类型转换失败,我们可以添加 `if` 防御式代码进行检查。 - -```python -a: any = "s" -b = a as int if typeof(a) == "int" else None # The type of b is `int` -``` - -请注意,`as` 转换的目标类型不能是字面值类型或者联合类型,因为它们在运行时不具有一个完全确定的类型。 - -### Schema - -#### 概述 - -Schema 是定义复杂配置的语言元素。我们可以定义带类型的属性,初始值和验证规则。此外,KCL 支持 schema 单继承、mixin 和 protocol 实现复杂配置的复用。 - -#### 基础部分 - -##### 属性 - -以下是 schema 基础定义的示例: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 -``` - -在 KCL 中, 我们可以使用类型注解在 schema 中定义一些属性,每个属性都可以设置一个可选的默认值(比如上述代码中的 `age` 属性,它的默认值是 `0`),没有设置默认值的属性的初始值为 `Undefined`, 它们不会在 YAML 当中进行输出。 - -###### 不可变性 - -schema 中属性的不可变性遵循和全局变量不可变性一样的规则,只有 schema 中的可变属性可以在 schema 中修改。此外,schema 的属性默认值可被 schema 配置值修改: - -```python -schema Person: - age: int = 1 # Immutable attribute - _name: str = "Alice" # Mutable attribute - - age = 10 # Error, can't change the default value of the attribute `age` in the schema context. - _name = "Bob" # Ok - -person = Person { - age = 3 # Ok, can change the default value of the attribute `age` in the schema config. -} -``` - -###### 可选属性 - -schema 实例中每个属性 **必须** 赋值一个非 `None`/`Undefined` 的值,否则编译器会抛出错误,除非它被 `?` 符号标记为可选属性。 - -示例: - -```python -schema Employee: - bankCard: int # bankCard is a required attribute, and it can NOT be None or Undefined - nationality?: str # nationality is an optional attribute, and it can be None or Undefined - -employee = Employee { - bankCard = None # Error, attribute 'bankCard' of Employee is required and can't be None or Undefined - nationality = None # Ok -} -``` - -##### 顺序无关计算 - -schema 中顺序无关计算表示 schema 内部属性之间的引用关系。例如,当我们声明一个形式为 `a = b + 1` 的表达式时,`a` 值的计算依赖于 `b` 值的计算。当编译器计算 `a` 的值并且 `a` 的值取决于 `b` 的值时,编译器会选择先计算 `b` 的值,然后根据 `b` 的值计算 a 的值表达式 `a = b + 1`,这与传统过程语言的计算方法略有不同。 - -由于 schema 中值的计算是基于依赖关系的,就像有向无环图按照拓扑排序的顺序遍历图中的每个节点一样, schema 中属性的声明顺序并不那么重要,因此特征称为顺序无关计算。 - -请注意,不同 schema 属性值之间不能有循环引用。 - -我们可以通过下面的例子看到这个特性。 - -```python -schema Fib: - n1: int = n - 1 # Refers to the attribute `n` declared after `n1` - n2: int = n1 - 1 - n: int - value: int = 1 if n <= 2 else Fib {n = n1}.value + Fib {n = n2}.value - -fib8 = Fib {n = 8}.value -``` - -结果为: - -```yaml -fib8: 21 -``` - -在 schema 中,我们只需要简单的指定属性之间的依赖关系,编译器就会根据依赖关系自动计算出值,这样可以帮助我们节省大量的样板代码,减少配置编写难度。 - -##### Schema 上下文 - -我们可以定义 schema 的上下文来管理 schema 的属性,可以直接在 schema 中编写 schema 参数、临时变量和表达式等: - -```python -schema Person[_name: str]: # define a schema argument - name: str = _name # define a schema attribute - age: int = 10 # define a schema attribute with default value - hands: [int] = [i for i in [1, 2, 3]] # define a for statement -``` - -然后,我们可以通过如下代码实例化一个 `Person` 并将其赋值给 `alice` 变量: - -```python -alice = Person("alice") -``` - -可以得到如下 YAML 输出: - -```yaml -alice: - name: alice - age: 10 - hands: - - 1 - - 2 - - 3 -``` - -##### 校验 - -KCL 中为了确保代码稳定性,除了使用 **静态类型** (类型注解) 和 **不可变性**,还支持在 **check** 块中定义验证规则 (KCL 几乎原生支持所有 [OpenAPI](https://www.openapis.org/) 的验证能力): - -```python -import regex - -schema Sample: - foo: str - bar: int - fooList: [str] - - check: - bar > 0 # Minimum, also support the exclusive case - bar < 100 # Maximum, also support the exclusive case - len(fooList) > 0 # Min length, also support exclusive case - len(fooList) < 100 # Max length, also support exclusive case - regex.match(foo, "^The.*Foo$") # Regex match - isunique(fooList) # Unique - bar in range(100) # Range - bar in [2, 4, 6, 8] # Enum - multiplyof(bar, 2) # MultipleOf -``` - -使用 schema, 所有的实例将在编译时验证: - -```python -# Ok -goodSample = Sample { - foo = "The Foo" - bar = 2 - fooList = ["foo0", "foo1"] -} - -# Error: validation failure: Check failed on check conditions: bar < 100. -badSample = Sample { - foo = "The Foo" - bar = 123 - fooList = ["foo0", "foo1"] -} -``` - -此外,我们可以使用 **and**, **or**, **if** 来构建更复杂的检查逻辑: - -```python -schema Sample: - bar: int - foo: str - doCheck: bool - - check: - regex.match(foo, "^The.*Foo$") and bar in [2, 4, 6, 8] if doCheck -``` - -为了确保所有检查规则都能很好地发挥其相应的作用,我们可以通过编写 KCL 测试用例来测试不同数据组合的合理性和正确性,并通过 kcl test tool 运行所有测试用例。 - -##### 文档 - -通常在我们写好 schema 模型之后,我们会为 schema 写文档注释,可以用一个三引号字符串来完成,如下所示: - -```python -schema Server: - """Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - - Attributes - ---------- - workloadType : str, default is Deployment - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - name : str, default is None - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - labels : {str:str}, optional, default is None - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - - Examples - ---------------------- - myCustomApp = AppConfiguration { - name = "componentName" - } - """ - workloadType: str = "Deployment" - name: str - labels?: {str:str} -``` - -更多详细内容可见 Doc tools。 - -##### 配置 - -假设我们有如下 schema 定义: - -```python -schema Person: - firstName: str - lastName: str - labels?: {str:str} -``` - -可以用类 JSON 的表达式定义配置: - -```python -person = Person { - firstName = "firstName" - lastName = "lastName" -} -``` - -schema 遵循严格的属性定义,配置未定义的属性将触发编译错误: - -```python -person = Person { - firstName = "firstName" - lastName = "lastName" - fullName = "fullName" # Error: Cannot add member 'fullName' to schema 'Person', 'fullName' is not defined in schema 'Person' -} -``` - -此外,我们可以使用 `if` 表达式将元素动态的添加到 schema 实例中,将满足条件的元素添加到 schema 实例并忽略不满足条件的元素。并且除了使用一个 schema 类型实例化一个 schema,我们也可以通过 schema 实例得到一个新的实例。 - -```python -env = "prod" -person = Person { - firstName = "firstName" - lastName = "lastName" - if env == "prod": - labels.env = env - else: - labels.env = "other" -} -# We can use the person instance to get a new instance named `personx` directly. -personx = person { - firstName = "NewFirstName" -} -``` - -输出为: - -```yaml -env: prod -person: - firstName: firstName - lastName: lastName - labels: - env: prod -personx: - firstName: NewFirstName - lastName: lastName - labels: - env: prod -``` - -#### 高级功能 - -##### Protocol & Mixin - -除了 schema, 在 KCL 中还提供了一种额外的类型定义方式 `protocol`,它的性质如下: - -- 在 protocol 中,只能定义属性及其类型,不能书写复杂的逻辑与 check 表达式,也不能使用 mixin。 -- protocol 只能对非 `_` 开头的属性进行约束。 -- protocol 只能继承自或者引用 protocol, 不能继承自或者引用 schema。 - -此外,我们可以使用可选的 **mixin** 组装复杂的 schema,并使用 **protocol** 为 **mixin** 添加可选的宿主类型, 使用 `for` 关键字为 **mixin** 定义宿主类型,并且在 mixin 内部它将从宿主类型中查询到属性的类型。 - -```python -schema Person: - mixin [FullNameMixin] - - firstName: str # Required - lastName: str # Required - fullName?: str # Optional -``` - -FullNameMixin 是一个产生 fullName 字段的简单例子: - -```python -protocol PersonProtocol: - firstName: str - lastName: str - fullName?: str - -mixin FullNameMixin for PersonProtocol: - fullName = "{} {}".format(firstName, lastName) -``` - -然后我们可以通过一下方式获取 schema 实例: - -```python -person = Person { - firstName = "John" - lastName = "Doe" -} -``` - -输出结果为: - -```yaml -person: - firstName: John - lastName: Doe - fullName: John Doe -``` - -请注意,宿主类型 **protocol** 只能用于 **mixin** 的定义 (后缀名为 `Mixin`), 否则将会报错。 - -```python -protocol DataProtocol: - data: str - -schema Data for DataProtocol: # Error: only schema mixin can inherit from protocol - x: str = data -``` - -##### 索引签名 - -在 KCL schema 中可以定义索引签名,这意味着索引签名的键-值约束可用于构造具有 schema 类型的字典。或者可以将其他检查添加到额外的 schema 属性中,以增强 KCL 类型和语义检查。 - -###### 基本用法 - -使用 `[{attr_alias}: {key_type}]: {value_type}` 的形式去定义 schema 的类型注解, 其中 `{attr_alias}` 可以省略。 - -```python -schema Map: - """ - Map is a schema with a key of str type and a value of str type - """ - [str]: str # `{attr_alias}` can be omitted. - -data = Map { - key1 = "value1" - key2 = "value2" -} -``` - -###### 同时定义属性和索引签名 - -可以在 schema 中同时定义 schema 属性和索引签名,通常用于表示 schema 中额外属性的类型约束,比如如下代码 - -```python -schema Person: - name: str - age: int - [...str]: str # Except for the `name` and `age` attributes, the key type of all other attributes of the schema must be `str`, and the value type must also be `str`. -``` - -###### 定义索引签名别名 - -可以为索引签名定义类型注解的属性别名,并将其与检查块一起使用。 - -```python -schema Data: - [dataName: str]: str - check: - dataName in ["Alice", "Bob", "John"] # We can use the index signature key name in the check block. - -data = Data { - Alice = "10" - Bob = "12" - Jonn = "8" # Error: Jonn not in ["Alice", "Bob", "John"] -} -``` - -##### 继承 - -类似于其他面向对象语言,KCL 提供了基础且有限的面向对象支持,例如 **属性复用**,**私有和公有变量**和**单继承**。KCL 不支持多继承。 - -以下是单继承的例子: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 - -# An employee **is** a person, and has some additional information. -schema Employee(Person): - bankCard: int - nationality?: str - -employee = Employee { - firstName = "Bob" - lastName = "Green" - age = 18 - bankCard = 123456 -} -``` - -结果为: - -```yaml -employee: - firstName: Bob - lastName: Green - age: 18 - bankCard: 123456 - nationality: null -``` - -请注意,KCL 只支持 schema 的 **单继承**。 - -此外,当 schema 存在继承关系时,可选属性的性质如下: - -- 如果该属性在基类 schema 中是可选的,则它在子类 schema 中是可选的,也可以是子类 schema 中必选的。 -- 如果该属性在基类 schema 中是必选的,则它在子类 schema 中也是必选的。 - -```python -schema Person: - bankCard?: int - nationality: str - -schema Employee(Person): - bankCard: int # Valid, both `bankCard: int` and `bankCard?: int` are allowed - nationality?: str # Error, only `nationality: str` is allowed -``` - -##### Schema 函数 - -schema 映射到函数上非常好用;它可以有任意数量的输入和输出参数。 例如,Fibonacci 函数可以使用递归 schema 如下编写: - -```python -schema Fib[n: int]: - n1 = n - 1 - n2 = n - 2 - if n == 0: - value = 0 - elif n == 1: - value = 1 - else: - value = Fib(n1).value + Fib(n2).value - -fib8 = Fib(8).value # 21 -``` - -##### 装饰器 - -像 Python 一样, KCL 支持在 schema 上使用装饰器。KCL 装饰器动态地改变 schema 的功能,而不必直接使用子 schema 或更改被装饰的 schema 的源代码。 和函数调用一样,装饰器支持传入额外的参数。 - -内置的 schema 装饰器: - -- `@deprecated` - 标识 schema 或 schema 属性被废弃. `@deprecated` 装饰器支持三种参数: - - **version** - 字符串类型,表示版本信息。 默认值为空。 - - **reason** - 字符串类型,表示不推荐使用的原因。 默认值为空。 - - **strict** - bool 类型,表示是报错还是警告。 默认值是 true。 如果 `strict` 为 `True` 并且抛出错误,程序将被中断。 如果 `strict` 为 `False`,则会输出警告并且不会中断程序。 - -示例: - -```python -@deprecated -schema ObsoleteSchema: - attr: str - -schema Person: - firstName: str = "John" - lastName: str - @deprecated(version="1.16", reason="use firstName and lastName instead", strict=True) - name: str - attrs: ObsoleteSchema = { # Error: ObsoleteSchema was deprecated - attr = "value" - } - -JohnDoe = Person { # Error: name was deprecated since version 1.16, use firstName and lastName instead - name = "deprecated" -} -``` - -- `@info` - 给 schema 或 schema 属性标识额外的信息,支持任意参数,用于语言静态分析 schema 或 schema 属性的扩展标记信息 - -示例: - -```python -@info(version="v1") -schema Person: - @info(message="name") - name: str - age: int -``` - -请注意,当前版本的 KCL 尚不支持用户自己定义装饰器。 - -##### 成员函数 - -内置函数和 schema 成员 - -- instances() - 返回 schema 的现有实例列表。 - -```python -schema Person: - name: str - age: int - -alice = Person { - name = "Alice" - age = 18 -} - -bob = Person { - name = "Bob" - age = 10 -} - -aliceAndBob = Person.instances() # Person is a schema type, instances() is its member method -``` - -输出为: - -```yaml -alice: - name: Alice - age: 18 -bob: - name: Bob - age: 10 -aliceAndBob: - - name: Alice - age: 18 - - name: Bob - age: 10 -``` - -### 配置操作 - -#### 配置合并 - -##### | 运算符 - -在 KCL 中,我们可以使用合并运算符 `|` 来合并配置。union 运算符支持的类型包括如下: - -```txt -SchemaInstance | SchemaInstance -SchemaInstance | Dict -Dict | Dict -List | List -``` - -合并集合和结构化数据: - -- 合并 List。使用 `|` 运算符右边的列表表达式按照**索引**逐一覆盖左边列表表达式中的元素。 - -```python -_a = [1, 2, 3] -_b = [4, 5, 6, 7] -x = _a | _b # [4, 5, 6, 7] 1 -> 4; 2 -> 5; 3 -> 6; Undefined -> 7 -``` - -合并特定索引或所有元素仍在讨论中。 - -- 合并 Dict. 使用 `|` 运算符右边的列表表达式按照**键**逐一覆盖左边列表表达式中的元素。 - -```python -_a = {key1 = "value1"} -_b = {key1 = "overwrite", key2 = "value2"} -x = _a | _b # {"key1": "overwrite", "key2": "value2"} -``` - -集合和 schema 的合并是一个新的集合,其属性是将 b 合并到 a,保留从左到右的操作数顺序。 - -- 合并 schema。Schema 的合并与 dict 相似。 - -Schema 的合并操作如下: - -```python -schema Person: - firstName?: str - lastName?: str - -_a = Person { - firstName = "John" -} -_b = {lastName = "Doe"} -_c = _a | _b # {"firstName": "John", "lastName": "Doe"} -_d = _a | None # {"firstName": "John"} -_e = _a | Undefined # {"firstName": "John"} -_f = None | _a # {"firstName": "John"} -_g = Undefined | _a # {"firstName": "John"} -``` - -请注意,当 union 运算符的左右操作数之一为 None 时,将立即返回另一个操作数。 - -```python -data1 = {key = "value"} | None # {"key": "value"} -data2 = None | [1, 2, 3] # [1, 2, 3] -data3 = None | None # None -``` - -输出如下: - -```yaml -data1: - key: value -data2: - - 1 - - 2 - - 3 -data3: null -``` - -##### : 运算符 - -模式: `identifier : E` - -表达式 `E` 的值将被合并到元素值。 - -示例: - -```python -schema Data: - labels: {str:} = {key1 = "value1"} - -data = Data { - # union {key2: "value2"} into the attribute labels of the schema Data. - labels: {key2 = "value2"} -} -``` - -输出: - -```yaml -data: - labels: - key1: value1 - key2: value2 -``` - -除了在 schema 属性上使用属性运算符之外,还可以使用属性运算符对配置块执行不同的操作。 - -- schema 外部使用合并运算符 `:` - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - data: Data - -# This is one configuration that will be merged. -config: Config { - data.d1 = 1 -} -# This is another configuration that will be merged. -config: Config { - data.d2 = 2 -} -``` - -与它等效的配置代码可以表示为: - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - data: Data - -config: Config { - data.d1 = 1 - data.d2 = 1 -} -``` - -输出结果为: - -```yaml -config: - data: - d1: 1 - d2: 1 -``` - -- schema 内部使用合并运算符 `:` - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - # This is one configuration that will be merged. - data: Data { - d1 = 1 - } - # This is another configuration that will be merged. - data: Data { - d2 = 1 - } - -config: Config {} -``` - -#### 配置覆盖 - -##### = 运算符 - -模式: `identifier = E` - -表达式 `E` 的值将覆盖元素值。 - -示例: - -```python -schema Data: - labels: {str:} = {key1 = "value1"} - -data = Data { - # override {key2: "value2"} into the attribute labels of the schema Data. - labels = {key2 = "value2"} -} -``` - -输出: - -```yaml -data: - labels: - key2: value2 -``` - -请注意,可以使用 `Undefined` 来覆盖,来“删除”内容。例如 `{ a = Undefined }`。 - -#### 配置添加 - -##### += 运算符 - -模式: `identifier += E` - -插入只能用于列表类型的 `identifier`. - -`E` 将插入到列表 `identifier` 指定索引后,并且索引以后的属性将自动后移。 - -示例: - -```python -schema Data: - labels: {str:} = {key1 = [0]} - -data = Data { - # insert [1] into the attribute labels.key1 of the schema Data. - labels: {key1 += [1]} -} -``` - -输出: - -```yaml -data: - labels: - key1: - - 0 - - 1 -``` - -如果没有定义索引,将使用最后一个索引。 - -#### 注意事项 - -合并运算符 `:` 是一个可交换的幂等运算符,当合并的值发生值的冲突时会发生值冲突错误,因此我们需要 `=` 和 `+=` 运算符表示配置的覆盖,添加和删除操作。 - -```python -data0 = {id: 1} | {id: 2} # Error:conflicting values between {'id': 2} and {'id': 1} -data1 = {id: 1} | {id = 2} # Ok, the value of `data` is {"id": 2} -``` - -`:` 运算符冲突检查的规则如下: - -- `None` 和 `Undefined` 不与任何值冲突 - -```python -data0 = None | {id: 1} # Ok -``` - -- 对于 `int`、`float`、`str` 和 `bool` 类型的变量,当它们的值不相同时发生冲突错误。 - -```python -data0 = 1 | 1 # Ok -data1 = 1 | "s" # Error -``` - -- 对于列表类型 - - 当它们的长度不相同时,它们被认为是冲突的 - - 当它们的长度相同时,当且仅当它们的任意一个子元素值冲突时,它们自身是冲突的 - -```python -data0 = [1] | [1] # Ok -data1 = [1, 2] | [1] # Error -``` - -- 对于 dict/schema 类型 - - 对于相同的 key,key 的值冲突时,它们自身是冲突的,否则是不冲突的 - -```python -data0 = {id: 1} | {id: 1} # Ok -data1 = {id: 1} | {id: 2} # Error -data1 = {id: 1} | {idAnother: 1} # Ok -``` - -### Rule - -KCL 支持使用 rule 关键字定义校验块,可用于数据校验,用法类似于 schema 中的 check 表达式。 - -```python -rule SomeRule: - age > 0, "rule check failure message" -``` - -可以像 schema 实例化那样调用一个 rule 进行校验 - -```python -age = 0 -name = "Bob" -rule SomeRule: - age > 0, "rule check failure message" - name == "Alice" - -rule1 = SomeRule() # Rule call -rule2 = SomeRule {} -``` - -可以使用 protocol 和 for 绑定语句为 rule 增加类型约束: - -```python -# Schema definition -protocol Service: - clusterIp: str - $type: str - -# Schema definition -protocol Volume: - mountPath: [str] - -# Protocol -protocol SomeProtocol: - id: int - env: {str: any} - services: [Service] - volumes: [Volume] - -rule SomeChecker for SomeProtocol: - id > 0, "id must >0" - - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - } - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } - -# Call rule to check with config parameter -SomeChecker { - id = 1 - env = { - MY_ENV = "MY_ENV_VALUE" - } - services = [ - { - type = "ClusterIP" - clusterIP = "NONE" - } - ] - volumes = [ - { - mountPath = "/home/admin" - } - { - mountPath = "/home/myapp" - } - ] -} -``` - -请注意,`protocol` 和 `rule` 的组合方式可以使属性和其约束定义进行分离,我们可以在不同的包中定义不同的 `rule` 和 `protocol` 按需进行组合,这与 schema 中的 check 表达式只能与 schema 属性定义在一起是不同的。 - -此外,有两种复用不同 rule 的方式 - -- 直接调用 - -```python -weather = "sunny" -day = "wednesday" - -rule IsSunny: - weather == "sunny" - -rule IsWednesday: - day == "wednesday" - -rule Main: - IsSunny() # Rule inline call - IsWednesday() # Rule inline call - -Main() # Rule call -``` - -使用 rule 的继承 (rule 不同于 schema, 可以多继承混用) - -```python -weather = "sunny" -day = "wednesday" - -rule IsSunny: - weather == "sunny" - -rule IsWednesday: - day == "wednesday" - -rule Main(IsSunny, IsWednesday): - id == 1 - -Main() -``` - -可以使用 option 函数与命令行 `-D` 参数获得外部数据进行校验 - -- 一个简单例子 - -```python -schema Day: - day: str - homework: str - -days: [Day] = option("days") - -rule Main: - filter d in days { - d.day not in ["saturday", "sunday"] and d.homework - } - -Main() -``` - -- 一个复杂例子 - -```python -data = option("data") -input = option("input") - -rule Allow: - UserIsAdmin() - any grant in UserIsGranted() { - input.action == grant.action and input.type == grant.type - } - -rule UserIsAdmin: - any user in data.user_roles[input.user] { - user == "admin" - } - -rule UserIsGranted: - [ - grant - for role in data.user_roles[input.user] - for grant in data.role_grants[role] - ] - -allow = Allow() or False -``` - -### 模块 - -KCL 配置文件以 **模块** 形式组织。 单个 KCL 文件被认为是一个 module,一个目录被认为是一个包。 - -同一个包内的模块是可见的,跨包引用需要通过导入可见。 - -```bash -. -└── root - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -model1.k: - -```python -# schema CatalogItem in model1.k - -schema CatalogItem: - id: int - image: CatalogItemImage # CatalogItemImage is defined in the module of the same package e.g., model2.k in package model - title: str -``` - -service1.k: - -```python -import ..model as model # cross-package references - -schema ImageService: - image: model.CatalogItemImage # CatalogItemImage is imported from another package e.g., model2.k in package model - name: str -``` - -#### 相对路径引用 - -我们可以使用 `.` 运算符来实现 KCL 入口文件的相对路径导入。 - -main.k: - -```python -import .model1 # Current directory module -import ..service # Parent directory -import ...root # Parent of parent directory - -s = service.ImageService {} -m = root.Schema {} -``` - -#### 绝对路径引用 - -`import a.b.c.d` 的语义为: - -1. 如果 `kcl.mod` 文件不存在,将当前目录作为包的根路径,并从当前目前查找 `a/b/c/d` 路径 -2. 如果 `kcl.mod` 文件存在,从 `ROOT_PATH/a/b/c/d` 查找,否则抛出一个导入错误 - -根路径 `ROOT_PATH` 的定义为: - -从当前目录或者父级目录中查找 `kcl.mod` 文件对应的目录。 - -```bash -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -main.k: - -```python -import service # `root package` and `kcl.mod` are in the same directory -import mixin # `root package` and `kcl.mod` are in the same directory - -myModel = model.CatalogItem {} -``` - -请注意,对于 KCL 入口文件 `main.k`,不能导入所在文件夹,否则会出现递归导入错误: - -```python -import model # Error: recursively loading -``` - -### 动态参数 - -假设某些字段需要像用户输入一样动态传入,我们可以在模块中定义一个动态参数: - -```python -bankCard = option("bankCard") # Get bankCard through the option function. -``` - -我们可以如下使用 module: - -```bash -kcl employee.k -D bankCard=123 -``` - -目前,支持顶级参数的类型有数字、字符串、布尔、列表和字典。 - -```bash -kcl main.k -D list_key='[1,2,3]' -D dict_key='{"key":"value"}' -``` - -请注意,命令行中引号 `"` 等符号需要使用 `\` 进行转义 - -#### Setting 文件形式的参数 - -此外,它还支持输入一个 YAML 文件作为顶级参数。 - -```yaml -kcl_options: - - key: key_number - value: 1 - - key: key_dict - value: - innerDictKey: innerDictValue - - key: key_list - value: - - 1 - - 2 - - 3 - - key: bankCard - value: 123 -``` - -```bash -kcl -Y setting.yaml employee.k -``` - -此外,setting 文件还支持配置命令行编译参数如下: - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - disable_none: true - strict_range_check: true - debug: 1 - verbose: 1 - sort_keys: true - output: ./stdout.golden - overrides: - - app.image=new_image - path_selector: - - config - package_maps: - k8s: /Users/.kcl/kpm/k8s_1.24 -kcl_options: - - key: image - value: docker.io/kcllang/kcl:latest -``` - -KCL CLI -Y 参数还支持多文件配置,并支持编译参数和顶级参数的单独写入与合并。 - -```bash -kcl -Y compile_setting.yaml option_setting.yaml -``` - -- `compile_setting.yaml` - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - disable_none: true - strict_range_check: true - debug: 1 - verbose: 1 - output: ./stdout.golden -``` - -- `option_setting.yaml` - -```yaml -kcl_options: - - key: image - value: docker.io/kcllang/kcl:latest -``` - -我们可以使用以下指令获取每个参数的含义 - -```bash -kcl --help -``` - -#### Option Functions - -我们可以在 KCL 代码中使用 `option` 获取顶级参数。 - -```python -value = option(key="key", type='str', default="default_value", required=True, help="Set key value") -``` - -参数 - -- **key**: 参数的键。 -- **type**: 要转换的参数类型。 -- **default**: 参数默认值。 -- **required**: 当未提供参数且参数的 required 为 True 是报告错误。 -- **help**: 帮助信息。 - -### 多文件编译 - -除了上面的 KCL 单文件执行之外,我们还可以使用以下命令同时编译多个 KCL 入口文件: - -```bash -kcl main_1.k main_2.k ... main_n.k -``` - -main_1.k - -```python -a = 1 -b = 2 -``` - -main_2.k - -```python -c = 3 -d = 4 -``` - -输出结果为: - -```yaml -a: 1 -b: 2 -c: 3 -d: 4 -``` - -利用**多文件编译**,我们可以组合多个 KCL 文件,而无需使用 import 管理文件。 我们来看一个结合**多文件编译**和 **schema 实例**的例子。 - -model.k - -```python -schema Model: - name: str - labels?: {str:} - annotations?: {str:} - replicas: int - -_model1 = Model { - name = "model1" - labels.key1 = "value1" - labels.key2 = "value2" - annotations.key = "value" - replicas = 2 -} - -_model2 = Model { - name = "model2" - replicas = 3 -} -``` - -backend.k - -```python -import yaml - -schema Backend: - apiVersion: str = "v1" - kind: str = "Deployment" - metadata: {str:} - spec: {str:} = { - minReadySeconds = 0 - paused = False - progressDeadlineSeconds = 600 - replicas = 1 - revisionHistoryLimit = 10 - selector = {} - } - -_backends = [Backend { - metadata.name = model.name - metadata.labels = model.labels - metadata.annotations = model.annotations - spec.selector.matchLabels: model.labels - spec.replicas = model.replicas -} for model in Model.instances()] # Schema Model is defined in model.k -print("---\n".join([yaml.encode(_b, ignore_private=True) for _b in _backends])) -``` - -命令为: - -```bash -kcl model.k backend.k -``` - -输出为: - -```yaml -apiVersion: v1 -kind: Deployment -metadata: - name: model1 - labels: - key1: value1 - key2: value2 - annotations: - key: value -spec: - minReadySeconds: 0 - paused: false - progressDeadlineSeconds: 600 - replicas: 2 - revisionHistoryLimit: 10 - selector: - matchLabels: - key1: value1 - key2: value2 ---- -apiVersion: v1 -kind: Deployment -metadata: - name: model2 -spec: - minReadySeconds: 0 - paused: false - progressDeadlineSeconds: 600 - replicas: 3 - revisionHistoryLimit: 10 - selector: {} -``` - -### KCL 变量查询 - -我们可以在 KCL CLI 使用 `-S|--path-selector` 参数从 KCL 模型中查询一个或多个值。 - -变量查询形式如下: - -`var.name` - -#### 示例 - -Code structure: - -```bash -. -├── kcl.mod -└── main.k - └── pkg - └── model.k -``` - -pkg/model.k: - -```python -schema Person: - name: str - age: int - -var = Person { - name = "Alice" - age = 18 -} -``` - -main.k - -```python -import pkg - -var = pkg.Person { - name = "Bob" - age = 10 -} -``` - -命令为: - -```bash -kcl main.k -S var -``` - -输出结果为: - -```yaml -var: - name: Bob ---- -var: - name: Alice - age: 18 -``` - -### KCL 变量修改 - -除了变量查询,KCL 还允许我们通过 KCL CLI 的 `-O|--overrides` 参数直接修改配置模型中的值。 - -变量修改参数的使用与变量查询类似,参数包含三部分,如 `pkg`、`identifier`、`attribute` 和 `override_value` . - -```bash -kcl main.k -O override_spec -``` - -- `override_spec`: 表示需要修改的配置模型字段和值的统一表示 - -```txt -override_spec: [[pkgpath] ":"] identifier ("=" value | "-") -``` - -- `pkgpath`: 表示需要修改标识符的包路径,通常为 `a.b.c` 的形式,对于 main 包,`pkgpath` 表示为 `__main__`, 可省略,省略不写时表示 main 包 -- `identifier`: 表示需要修改配置的标识符,通常为 `a.b.c` 的形式 -- `value`: 表示需要修改配置的值,可以是任意合法的 KCL 表达式,比如数字/字符串字面值,list/dict/schema 表达式等 -- `=`: 表示修改identifier的值 - - 当 identifier 存在时,修改已有 identifier的值为 value - - 当 identifier 不存在时,添加 identifier属性,并将其值设置为 value -- `-`: 表示删除 identifier属性 - - 当 identifier 存在时,直接进行删除 - - 当 identifier 不存在时,对配置不作任何修改 - -请注意,当 `identifier` 出现多次时,修改/删除全部 `identifier` 的值 - -此外,在 KCL 中还提供了 API 用于变量查询和修改,详见 [API 文档](../xlang-api/go-api.md) - -#### 示例 - -##### 修改示例 - -KCL 代码: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -``` - -命令为: - -```bash -kcl main.k -O :person.name=Bob -O :person.age=10 -``` - -输出结果为: - -```yaml -person: - name: Bob - age: 10 -``` - -此外,当我们使用 KCL CLI `-d` 参数时,KCL 文件将同时修改为以下内容 - -```bash -kcl main.k -O :person.name=Bob -O :person.age=10 -d -``` - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Bob" - age = 10 -} -``` - -##### 删除示例 - -KCL 代码: - -```python -schema Config: - x?: int = 1 - y?: str = "s" - -config = Config { - x = 2 -} -``` - -命令为: - -```bash -kcl main.k -O config.x- -``` - -输出结果为: - -```yaml -config: - x: 1 - y: s -``` - -### 总结 - -本页总结了 KCL 语言中的常用功能。 KCL 作为一种新的语言,会根据配置场景的需求,逐步增加功能特性。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/crypto.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/crypto.md deleted file mode 100644 index cef03352..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/crypto.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "crypto" -linkTitle: "crypto" -type: "docs" -description: crypto 包 - 提供 SHA 相关的哈希函数 -weight: 100 ---- - -## md5 - -`md5(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `MD5` 算法对字符串 `value` 进行加密。 - -## sha1 - -`sha1(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA1` 算法对字符串 `value` 进行加密。 - -## sha224 - -`sha224(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA224` 算法对字符串 `value` 进行加密。 - -## sha256 - -`sha256(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA256` 算法对字符串 `value` 进行加密。 - -## sha384 - -`sha384(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA384` 算法对字符串 `value` 进行加密。 - -## sha512 - -`sha512(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA512` 算法对字符串 `value` 进行加密。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/datetime.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/datetime.md deleted file mode 100644 index 66cb4bca..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/datetime.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: "datetime" -linkTitle: "datetime" -type: "docs" -description: datetime 包 - 时间处理 -weight: 100 ---- - -## time - -`ticks() -> float` - -返回从 1970 年 1 月 1 日 0 时 0 分 0 秒(Epoch)开始到当前时间经过的秒数。如果系统时钟能提供更精确的时间,则秒数后可能会有小数部分。 - -## date - -`date() -> str` - -返回以 `%Y-%m-%d %H:%M:%S` 格式表示的时间。 - -## now - -`now() -> str` - -返回当地时间,例如 `'Sat Jun 06 16:26:11 1998'`。 - -## today - -`today() -> str` - -返回以 `%Y-%m-%d %H:%M:%S.%{ticks}` 格式表示的时间。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/index.md deleted file mode 100644 index c1f4b4a0..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# 系统模块 - -KCL 通过系统模块、用户模块和插件模块提供工程化的扩展能力。本节介绍系统模块的基本概念,插件模块可以参考插件系统。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/json.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/json.md deleted file mode 100644 index b19bdc88..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/json.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: "json" -linkTitle: "json" -type: "docs" -description: JSON 编码解码 -weight: 100 ---- - -## encode - -``` -encode( - data: any, - sort_keys: bool = False, - indent: int = None, - ignore_private: bool = False, - ignore_none: bool = False -) -> str -``` - -将 KCL 对象 `data` 序列化为 JSON 格式的字符串。 - -## decode - -`decode(value: str) -> any` - -反序列化 `value`(一个包含 JSON 格式文档的字符串实例)为一个 KCL 对象。 - -## dump_to_file - -``` -dump_to_file( - data: any, - filename: str, - ignore_private: bool = False, - ignore_none: bool = False -) -> None -``` - -将 KCL 对象 `data` 序列化为 JSON 格式的字符串,并将其写入文件 `filename` 中。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/overview.md deleted file mode 100644 index aa3eaeb3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/overview.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -sidebar_position: 0 ---- - -# 概览 - -KCL 是面向配置的编程语言,通过内置模块、KCL 模块和插件模块提供工程化的扩展能力。 - -![](/img/docs/reference/lang/model/kcl-module.png) - -用户代码中不用导入直接使用 builtin 的函数(比如用 `len` 计算列表的长度、通过 `typeof` 获取值的类型等),而对于字符串等基础类型也提供了一些内置方法(比如转化字符串的大小写等方法)。对于相对复杂的通用工作则通过标准库提供,比如通过 import 导入 `math` 库就可以使用相关的数学函数,可以通过导入 `regex` 库使用正则表达式库。而针对 KCL 代码也可以组织为模块,比如 Konfig 大库中将基础设施和各种标准的应用抽象为模块供上层用户使用。此外还可以通过 Plugin 机制,采用 Python 为 KCL 开发插件,比如目前有 meta 插件可以通过网络查询中心配置信息,`app-context` 插件则可以用于获取当前应用的上下文信息从而简化代码的编写。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/yaml.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/yaml.md deleted file mode 100644 index e0faf129..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/yaml.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: "yaml" -linkTitle: "yaml" -type: "docs" -description: yaml 编码解码 -weight: 300 ---- - -## encode - -``` -encode( - data: any, - sort_keys: bool = False, - ignore_private: bool = False, - ignore_none: bool = False -) -> str -``` - -将 KCL 对象 `data` 序列化为 YAML 格式的字符串。 - -## decode - -`decode(value: str) -> any` - -反序列化 `value`(一个包含 YAML 格式文档的字符串实例)为一个 KCL 对象。 - -## dump_to_file - -``` -dump_to_file( - data: any, - filename: str, - ignore_private: bool = False, - ignore_none: bool = False -) -> None -``` - -将 KCL 对象 `data` 序列化为 YAML 格式的字符串,并将其写入文件 `filename` 中。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/_category_.json deleted file mode 100644 index edfe989e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "包管理", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/1.init.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/1.init.md deleted file mode 100644 index 0bfc0303..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/1.init.md +++ /dev/null @@ -1,45 +0,0 @@ -# kpm init - -初始化一个 kcl 包。 - -## 使用 - -```shell -kpm init [options][package_name] -``` - -## 介绍 - -`kpm init` 会在当前目录初始化一个 kcl 包。如果没有提供包名,会使用当前目录的名字作为包名。 - -如果提供了包名,会在当前目录下创建一个以包名命名的子目录,并在该目录下初始化 kcl 包。 - -`kpm init` 会在包目录下创建 `kcl.mod`、`kcl.mod.lock` 和 `main.k`。 - -## 选线 - -### --help, -h - -显示帮助信息。 - -## 示例 - -### 初始化当前目录为 kcl 包 - -```shell -# 创建一个目录 -$ mkdir my_package - -# 进入目录 -$ cd my_package - -# 初始化当前目录为 kcl 包 -$ kpm init -``` - -### 初始化一个名为 my_package 的 kcl 包 - -```shell -# 初始化一个名为 my_package 的 kcl 包 -kpm init my_package -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/10.help.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/10.help.md deleted file mode 100644 index 0fd9fa3a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/10.help.md +++ /dev/null @@ -1,21 +0,0 @@ -# kpm help - -输出 kpm 命令的帮助信息。 - -## 使用 - -```shell -kpm help -``` - -## 介绍 - -`kpm help` 会输出 kpm 命令的帮助信息。 - -## 示例 - -使用 `kpm help` 输出 kpm 命令的帮助信息。 - -```shell -kpm help -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/2.add.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/2.add.md deleted file mode 100644 index 09fd5d46..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/2.add.md +++ /dev/null @@ -1,53 +0,0 @@ -# kpm add - -添加一个依赖到 kcl 包。 - -## 使用 - -```shell -kpm add [options][package_reference] -``` - -## 介绍 - -`kpm add` 会添加一个依赖到 kcl 包。依赖可以来自 git 仓库,或者 kcl registry。 - -`package_reference` 是一个 kcl 包引用,格式为 `package_name:version`。 - -## 选项 - -### --git - -指定依赖来自 git 仓库的 git url。 - -### --tag - -指定依赖来自 git 仓库的 tag。 - -### --help, -h - -显示帮助信息。 - -## 示例 - -### 添加一个来自 kcl registry 的依赖 - -添加一个名为 `k8s` 的依赖,版本为最新版本。 - -```shell -kpm add k8s -``` - -添加一个名为 `k8s` 的依赖,版本为 `v1.27.2`。 - -```shell -kpm add k8s:v1.27.2 -``` - -### 添加一个来自 git 仓库的依赖 - -添加一个来自 git 仓库的 kcl 包依赖,tag 为 v0.1.0 - -```shell -kpm add --git https://github.com/awesome-kusion/konfig.git --tag v0.1.0 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/3.pkg.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/3.pkg.md deleted file mode 100644 index fd708d03..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/3.pkg.md +++ /dev/null @@ -1,33 +0,0 @@ -# kpm pkg - -打包一个 kcl 包。 - -## 使用 - -```shell -kpm pkg [options] -``` - -## 介绍 - -`kpm pkg` 会打包一个 kcl 包为 `*.tar`。 - -选项 `--target` 用于指定打包后的 `*.tar` 文件路径。 - -## 选项 - -### --target - -指定打包后的 `*.tar` 文件路径。 - -### --help, -h - -显示帮助信息。 - -## 示例 - -### 打包当前 kcl 包为 `*.tar` - -```shell -kpm pkg --target /Users/my_package_tar -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/4.metadata.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/4.metadata.md deleted file mode 100644 index 199ebd2e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/4.metadata.md +++ /dev/null @@ -1,41 +0,0 @@ -# kpm metadata - -打印 kcl 包的元数据。 - -## 使用 - -```shell -kpm metadata [options] -``` - -## 介绍 - -`kpm metadata` 会打印 kcl 包的元数据。元数据包括包的依赖信息。 - -`--update` 选项用于自动下载缺失的依赖包。 - -## 选项 - -### --update - -自动下载缺失的依赖包。 - -### --help, -h - -展示 `kpm metadata` 命令的帮助信息。 - -## 示例 - -### 打印 kcl 包的元数据 - -打印 kcl 包的元数据。 - -```shell -kpm metadata -``` - -打印 kcl 包的元数据,并自动下载缺失的依赖包。 - -```shell -kpm metadata --update -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/5.run.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/5.run.md deleted file mode 100644 index eee83e08..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/5.run.md +++ /dev/null @@ -1,69 +0,0 @@ -# kpm run - -编译一个 kcl 包。 - -## 使用 - -```shell -kpm run [options][package_source] -``` - -## 介绍 - -`kpm run` 会编译一个 kcl 包。 - -## 选项 - -### --input - -指定包的入口文件路径。 - -### --tag - -指定 oci url 的包的 tag。 - -### --vendor - -`--vendor` 选项会将依赖包移动到当前包,并自动下载缺失的依赖包。 - -### --kcl_args - -`--kcl_args` 描述了传递给 kcl 编译器的参数。 - -### --help, -h - -展示 `kpm run` 命令的帮助信息。 - -## 示例 - -### 编译当前 kcl 包 - -在 kcl 包目录下,`kpm run` 可以用于编译当前 kcl 包。 - -```shell -kpm run -``` - -### 编译一个 kcl 包 tar 文件 - -`kpm run` 可以用于编译一个 kcl 包 tar 文件。 - -```shell -kpm run /Users/demo/my_package.tar -``` - -### 编译一个 kcl 包来自 oci url - -`kpm run` 可以用于编译一个 kcl 包从 oci url。 - -```shell -kpm run --tag 0.0.1 oci://localhost:5001/test/my_package -``` - -### 编译一个 kcl 包来自 oci ref - -`kpm run` 可以用于编译一个 kcl 包从 oci ref。 - -```shell -kpm run test/my_package:0.0.1 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/6.login.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/6.login.md deleted file mode 100644 index 9055d8fb..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/6.login.md +++ /dev/null @@ -1,68 +0,0 @@ -# kpm login - -登陆 kpm registry. - -## 使用 - -```shell -kpm login [options][kpm_registry] -``` - -## 介绍 - -`kpm login` 将会登陆 kpm registry。 - -## 选项 - -### --username, -u - -指定 kpm registry 的用户名。 - -### --password, -p - -指定 kpm registry 的密码。 - -### --help, -h - -展示 `kpm login` 命令的帮助信息。 - -## 示例 - -### 登陆到 kpm registry, 通过参数输入用户名和密码 - -```shell -kpm login -u -p -``` - -期望输出为 - -```shell -Login succeeded -``` - -### 登陆到 kpm registry, 通过参数输入用户名,密码通过交互式输入 - -```shell -kpm login -u -``` - -期望输出为 - -```shell -Password: -Login succeeded -``` - -### 登陆到 kpm registry, 用户名和密码通过交互式输入 - -```shell -kpm login -``` - -期望输出为 - -```shell -Username: -Password: -Login succeeded -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/7.logout.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/7.logout.md deleted file mode 100644 index 65dd317e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/7.logout.md +++ /dev/null @@ -1,27 +0,0 @@ -# kpm logout - -从 kpm registry 登出。 - -## 使用 - -```shell -kpm logout [options][kpm_registry] -``` - -## 介绍 - -`kpm logout` 会从 kpm registry 登出。 - -## 选项 - -### --help, -h - -展示 `kpm logout` 命令的帮助信息。 - -## 示例 - -### 从 kpm registry 登出 - -```shell -kpm logout -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/8.push.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/8.push.md deleted file mode 100644 index 53c2e520..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/8.push.md +++ /dev/null @@ -1,46 +0,0 @@ -# kpm push - -上传一个 kcl 包到 kpm registry。 - -## 使用 - -```shell -kpm push [options][kpm_registry] -``` - -## 介绍 - -`kpm push` 将会上传一个 kcl 包到 kpm registry。 - -## 选项 - -### --tar_path - -指定上传的 `*.tar` 文件路径。 - -### --help, -h - -展示 `kpm push` 命令的帮助信息。 - -## 示例 - -### 上传当前 kcl 包到 kpm registry - -你可以在 kcl 包的根目录下使用 `kpm push` 命令上传一个 kcl 包到 kpm registry。 - -```shell -# 创建一个 kcl 包 -$ kpm init -# 进入 kcl 包目录 -$ cd -# 上传 kcl 包到 kpm registry -$ kpm push -``` - -### 上传一个 `*.tar` 文件到 kpm registry - -你也可以使用 `kpm push` 命令上传一个 `*.tar` 文件到 kpm registry。 - -```shell -kpm push --tar_path -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/9.pull.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/9.pull.md deleted file mode 100644 index cec49291..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/9.pull.md +++ /dev/null @@ -1,41 +0,0 @@ -# kpm pull - -下载 kcl 包从 kpm registry。 - -## 使用 - -```shell -kpm pull [options][package_source] -``` - -## 介绍 - -`kpm pull` 会从 kpm registry 下载 kcl 包。 - -## 选项 - -### --tag - -使用 oci url 下载包时, 指定要下载的 kcl 包的 tag。 - -### --help, -h - -展示 `kpm pull` 命令的帮助信息。 - -## 示例 - -### 从 kpm registry 下载 kcl 包 - -你可以使用 `kpm pull` 命令从 默认的 kpm registry 下载 kcl 包。 - -```shell -kpm pull : -``` - -### 下载 kcl 包通过 oci url - -你可以使用 `kpm pull` 命令从一个 oci url 下载 kcl 包。 - -```shell -kpm pull --tag -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/index.md deleted file mode 100644 index e3025db9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/index.md +++ /dev/null @@ -1,36 +0,0 @@ -# kpm - -kpm 命令。 - -## 使用 - -```shell -kpm [arguments]... -``` - -## 介绍 - -`kpm` 是 kcl 包管理工具。它用于分发和管理 kcl 包。 - -## 选项 - -### --help, -h - -展示 `kpm` 命令的帮助信息。 - -### --version, -v - -展示 `kpm` 命令的版本信息。 - -## 子命令 - -- [kpm init](./1.init.md) - 初始化一个 kcl 包 -- [kpm add](./2.add.md) - 添加一个依赖到 kcl 包 -- [kpm pkg](./3.pkg.md) - 打包一个 kcl 包为 `*.tar` -- [kpm metadata](./4.metadata.md) - 打印一个 kcl 包的元数据 -- [kpm run](./5.run.md) - 编译一个 kcl 包为 yaml 并运行 -- [kpm login](./6.login.md) - 登录到一个 kcl registry -- [kpm logout](./7.logout.md) - 登出一个 kcl registry -- [kpm push](./8.push.md) - 上传一个 kcl 包到一个 registry -- [kpm pull](./9.pull.md) - 下载一个 kcl 包从一个 registry -- [kpm help](./10.help.md) - 打印 kpm 命令的帮助信息 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/plugin/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/plugin/index.md deleted file mode 100644 index e2fe86d6..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/plugin/index.md +++ /dev/null @@ -1 +0,0 @@ -# 插件系统 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/plugin/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/plugin/overview.md deleted file mode 100644 index b3cc9469..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/plugin/overview.md +++ /dev/null @@ -1,183 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 简介 - -KCL 是声明式配置策略语言,对于不方便通过配置直接描述的复杂的业务逻辑可以通过通用的编程语言开发 KCL 插件对语言进行扩展。KCL 支持通过通用语言开发插件,KCL 程序导入插件中的函数。KCL 通过插件运行时和辅助的命令行工具提供插件支持。KCL 插件框架支持多种不同的通用语言开发插件,这里我们以 Python 为例简单说明插件的使用。 - -插件的 Git 仓库: [https://github.com/kcl-lang/kcl-plugin](https://github.com/kcl-lang/kcl-plugin) - -## 0. 前置依赖 - -使用 KCL Python 插件需要您的 `PATH` 中存在 `Python3.7+`。 - -## 1. 你好插件 - -KCL 插件在 KCL 的 `plugins` 子目录(通常安装在 `$HOME/.kcl/plugins` 目录),或者通过 `$KCL_PLUGINS_ROOT` 环境变量设置(环境变量优先级更高)。此外,`plugins` 插件目录还可以放在执行 KCL 命令的 `pwd` 路径或者父路径中。对于插件开发人员,插件都在 Git 仓库管理: [https://github.com/kcl-lang/kcl-plugin](https://github.com/kcl-lang/kcl-plugin) ,可以将插件仓库克隆到该目录进行开发。 - -输入 `kcl-plugin info` 命令查看查看插件目录(将其中的 `/Users/kcl_user` 替换成本地的 `$HOME` 路径): - -```shell -$ kcl-plugin info -# plugin_root: /Users/kcl_user/.kcl/plugins -``` - -通过 `kcl-plugin list` 子命令查看插件列表: - -```shell -$ kcl-plugin list -hello: hello doc - 0.0.1 -``` - -其中 `hello` 是 KCL 内置的示例插件(不要修改改插件)。 - -在 KCL 代码中,可以通过 `kcl_plugin.hello` 导入 `hello` 插件。`main.k` 代码如下: - -```python -import kcl_plugin.hello - -name = "kcl" -three = hello.add(1,2) -``` - -输出结果如下: - -```shell -$ python3 -m kclvm main.k -name: kcl -three: 3 -``` - -## 2. `kcl-plugin` 辅助命令 - -`kcl-plugin` 是提供的插件辅助工具,命令行帮助如下: - -```shell -$ kcl-plugin -usage: kcl-plugin [-h] {list,info,init,gendoc,test} ... -positional arguments: - {list,info,init,gendoc,test} - kcl plugin sub commands - list list all plugins - info show plugin document - init init a new plugin - gendoc gen all plugins document - test test plugin -optional arguments: - -h, --help show this help message and exit -``` - -其中 `list` 子命令用于查看插件列表;`info` 用户查看插件目录和每个插件的信息;`init` 可以用户初始化新插件;`gendoc` 更新全部插件的 API 文档;`test` 测试指定的插件。 - -## 3. 插件信息和文档 - -输入 `kcl-plugin info hello` 查看 `hello` 插件信息: - -```shell -$ kcl-plugin info hello -{ - "name": "hello", - "describe": "hello doc", - "long_describe": "long describe", - "version": "0.0.1", - "method": { - "add": "add two numbers, and return result", - "foo": "no doc", - "list_append": "no doc", - "say_hello": "no doc", - "tolower": "no doc", - "update_dict": "no doc" - } -} -``` - -插件的信息主要包含插件的名字和版本信息,插件提供的函数信息。该信息和插件目录中自动生成的 `api.md` 文件是一致的(插件 API 变化时通过 `kcl-plugin gendoc` 为全部的插件重新生成 `api.md` 文件)。 - -## 4. 插件的目录结构 - -插件的目录结构如下(将其中的 `/Users/kcl_user` 替换成本地的 `$HOME` 路径): - -```shell -$ tree /Users/kcl_user/.kcl/plugins/ -/Users/kcl_user/.kcl/plugins/ -├── _examples -├── _test -└── hello - ├── api.md - ├── plugin.py - └── plugin_test.py -$ -``` - -其中 `_examples` 目录下是插件的示例代码,`_test` 目录下是插件的 KCL 测试代码,其他以字母开头的目录是普通的插件(目录中同时包含 `plugin.py` 和 `plugin_test.py` 文件)。 - -KCL 的插件是有一个独立的纯 Python 代码文件实现,并且插件相互之间不能直接调用。插件的内容如下: - -```shell -$ cat ./hello/plugin.py -# Copyright 2020 The KCL Authors. All rights reserved. -INFO = { - 'name': 'hello', - 'describe': 'hello doc', - 'long_describe': 'long describe', - 'version': '0.0.1', -} -def add(a: int, b: int) -> int: - """add two numbers, and return result""" - return a + b -... -``` - -其中 `INFO` 指明了插件的名字、概要说明、详细说明和版本信息。而所有名字以字母开头的函数是插件给 KCL 提供的函数,因此 KCL 中可以直接调用 `add` 函数。 - -## 5. 创建一个插件 - -通过 `kcl-plugin init` 命令可以创建一个插件示例: - -``` -$ kcl-plugin init hi -$ kcl-plugin list -hello: hello doc - 0.0.1 -hi: hi doc - 0.0.1 -``` - -`kcl-plugin init` 命令会以内置的模板构造一个新的插件,然后通过 `kcl-plugin list` 命令可以查看到新创建的插件。 - -## 6. 插件的删除 - -KCL 插件在 KCL 的 `plugins` 子目录(通常安装在 `$HOME/.kcl/plugins` 目录)。 -可以通过命令 `kcl-plugin info` 查询插件安装目录。 - -```shell -$ kcl-plugin info -/Users/kcl_user/.kcl/plugins/ -$ tree /Users/kcl_user/.kcl/plugins/ -/Users/kcl_user/.kcl/plugins/ -├── _examples -├── _test -└── hello -- 删除这个目录就可以删除 hello plugin - ├── api.md - ├── plugin.py - └── plugin_test.py -$ -``` - -## 7. 插件的测试 - -插件是独立的纯 Python 文件实现,插件目录下有个 `plugin_test.py` 文件是插件的单元测试文件(基于 pytest 测试框架)。此外在 `_test` 目录下放置的是 KCL 文件的插件集成测试。`plugin_test.py` 单元测试是必须的,`_test` 目录下的 KCL 集成测试可以根据情况添加。 - -可以通过 `kcl-plugin test` 执行插件的单元测试: - -```shell -$ kcl-plugin test hello -============================= test session starts ============================== -platform darwin -- Python 3.7.6+, pytest-5.3.5, py-1.9.0, pluggy-0.13.1 -rootdir: /Users/kcl_user -collected 5 items -.kcl/plugins/hello/plugin_test.py ..... [100%] -============================== 5 passed in 0.03s =============================== -$ -``` - -集成测试可以通过在 `_test` 目录下执行 `python3 -m pytest` 命令进行测试。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/xlang-api/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/xlang-api/index.md deleted file mode 100644 index ea02d458..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/xlang-api/index.md +++ /dev/null @@ -1 +0,0 @@ -# 多语言 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/xlang-api/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/xlang-api/overview.md deleted file mode 100644 index 29c8680d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/xlang-api/overview.md +++ /dev/null @@ -1,295 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 简介 - -KCL 语言提供 C/Rust/Go/Python/Java 等通用编程语言接口,相关语言正在开发完整中。 - -## C/Rust 语言 - -KCL 核心采用 Rust 语言开发,对外导出 C 语言 API 供 Go/Python/Java 等高级语言包装和集成。 - -## Go 语言 - -Go 语言是通过 CGO 包装 KCL 提供的 C-API,同时提供更深度的定制特性以满足上层工具的需求。 - -### API 抽象模型 - -Go 语言 API 的抽象模型如下图: - -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ kcl files │ │ KCL-Go-API │ │ KCLResultList │ -│ ┌───────────┐ │ │ │ │ │ -│ │ 1.k │ │ │ │ │ │ -│ └───────────┘ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ ┌───────────┐ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.Get("a.b.c") │ -│ │ 2.k │ │ │ │ Run(path) │ │ │ └───────────┘ │ └───────────────┘ -│ └───────────┘ │────┐ │ └───────────┘ │ │ │ -│ ┌───────────┐ │ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ │ 3.k │ │ │ │ │ │ │ KCLResult │──┼────────▶│x.Get("k", &v) │ -│ └───────────┘ │ │ │ │ │ └───────────┘ │ └───────────────┘ -│ ┌───────────┐ │ ├───▶│ ┌───────────┐ │──────────▶│ │ -│ │setting.yml│ │ │ │ │RunFiles() │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ └───────────┘ │ │ │ └───────────┘ │ │ │ KCLResult │──┼────────▶│x.JSONString() │ -└─────────────────┘ │ │ │ │ └───────────┘ │ └───────────────┘ - │ │ │ │ │ -┌─────────────────┐ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ Options │ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.YAMLString() │ -│WithOptions │ │ │ │MustRun() │ │ │ └───────────┘ │ └───────────────┘ -│WithOverrides │────┘ │ └───────────┘ │ │ │ -│WithWorkDir │ │ │ │ │ -│WithDisableNone │ │ │ │ │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ -``` - -其中输入的文件包含 KCL 文件和 `setting.yml` 配置文件,`Options` 可以用于指定额外的参数和工作目录等信息。“KCL-Go-API”部分是提供的 KCL 执行函数,执行函数根据输入文件和额外的参数执行 KCL 程序,最终输出 `KCLResultList` 结果。`KCLResultList` 是一个 `KCLResult` 构成的列表,每个 `KCLResult` 对应一个生成的配置文件或 `map[string]interface{}`。 - -### 例子 - -```go -package main - -import ( - "fmt" - - kcl "kcl-lang.io/kcl-go" -) - - -func main() { - const k_code = ` -name = "kcl" -age = 1 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person{} -x1 = Person{age:101} -` - - result := kcl.MustRun("hello.k", kcl.WithCode(k_code)).First() - fmt.Println(result.YAMLString()) - - fmt.Println("----") - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - - fmt.Println("----") - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x1", &person)) -} -``` - -输出结果: - -```yaml -age: 1 -name: kcl -x0: - age: 1 - name: kcl -x1: - age: 101 - name: kcl - ----- -x0.name: kcl -x1.age: 101 ----- -person: &{Name:kcl Age:101} -``` - -## REST-API - -KCL 提供的 C-API 并没有 REST-API,REST-API 是通过 Protobuf 定义,最终由上层的 Go-SDK 提供实现。 - -### 启动 REST 服务 - -通过以下方式可以启动 RestAPI 服务: - -```shell -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -然后可以通过 POST 协议请求服务: - -```shell -$ curl -X POST http://127.0.0.1:2021/api:protorpc/BuiltinService.Ping --data '{}' -{ - "error": "", - "result": {} -} -``` - -其中 POST 请求和返回的 JSON 数据和 Protobuf 定义的结构保持一致。 - -### `BuiltinService` 服务 - -其中 `/api:protorpc/BuiltinService.Ping` 路径表示 `BuiltinService` 服务的 `Ping` 方法。 - -完整的 `BuiltinService` 由 Protobuf 定义: - -```protobuf -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} -``` - -其中 `Ping` 方法可以验证服务是否正常,`ListMethod` 方法可以查询提供的全部服务和函数列表。 - -### `KclvmService` 服务 - -`KclvmService` 服务是和 KCL 功能相关的服务。用法和 `BuiltinService` 服务一样。 - -比如有以下的 `Person` 结构定义: - -```python -schema Person: - key: str - - check: - "value" in key # 'key' is required and 'key' must contain "value" -``` - -然后希望通过 `Person` 来校验以下的 JSON 数据: - -```json -{ "key": "value" } -``` - -可以通过 `KclvmService` 服务的 `ValidateCode` 方法完成。参考 `ValidateCode` 方法的 `ValidateCode_Args` 参数结构: - -```protobuf -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} -``` - -根据 `ValidateCode_Args` 参数结构构造 POST 请求需要的 JSON 数据,其中包含 `Person` 定义和要校验的 JSON 数据: - -```json -{ - "code": "\nschema Person:\n key: str\n\n check:\n \"value\" in key # 'key' is required and 'key' must contain \"value\"\n", - "data": "{\"key\": \"value\"}" -} -``` - -将该 JSON 数据保存到 `vet-hello.json` 文件,然后通过以下命令进行校验: - -```shell -$ curl -X POST \ - http://127.0.0.1:2021/api:protorpc/KclvmService.ValidateCode \ - -H "accept: application/json" \ - --data @./vet-hello.json -{ - "error": "", - "result": { - "success": true - } -} -``` - -说明校验成功。 - -## Python 语言 - -使用 Python SDK 要求您本地具备高于 3.7.3 的 Python 版本和 pip 包管理工具,可以通过如下命令进行安装并获得帮助信息 - -```bash -python3 -m pip install kclvm --user && python3 -m kclvm --help -``` - -### 命令行工具 - -编写名为 `main.k` 的 KCL 文件: - -```python -name = "kcl" -age = 1 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {} -x1 = Person { - age = 101 -} -``` - -执行如下命令并获得输出: - -```shell -$ python3 -m kclvm hello.k -name: kcl -age: 1 -x0: - name: kcl - age: 1 -x1: - name: kcl - age: 101 -``` - -### API - -此外,我们还可以通过 Python 代码实现对 KCL 文件的执行 - -编写名为 `main.py` 的 python 文件: - -```python -import kclvm.program.exec as kclvm_exec -import kclvm.vm.planner as planner - -print(planner.plan(kclvm_exec.Run(["hello.k"]).filter_by_path_selector())) -``` - -执行如下命令并获得输出: - -```shell -$ python3 main.py -name: kcl -age: 1 -x0: - name: kcl - age: 1 -x1: - name: kcl - age: 101 -``` - -可以看出通过命令行工具和 API 可以获得同样的输出。 - -目前 KCL Python SDK 还处于早期预览版本,后续 KCL 团队会持续更新并提供更丰富的功能,更多信息请参阅:[https://github.com/kcl-lang/kcl-py](https://github.com/kcl-lang/kcl-py) - -## 其它语言 - -用户也可以基于 C-API 和 RestAPI 包装其它语言的 SDK。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/xlang-api/rest-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/xlang-api/rest-api.md deleted file mode 100644 index 74a9bf4c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/xlang-api/rest-api.md +++ /dev/null @@ -1,455 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Rest API - -## 1. 启动 REST 服务 - -通过以下方式可以启动 RestAPI 服务: - -```shell -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -或者 - -```shell -go install kcl-lang.io/kcl-go/cmds/kcl-go@main -kcl-go rest-server -``` - -然后可以通过 POST 协议请求服务: - -```shell -curl -X POST http://127.0.0.1:2021/api:protorpc/BuiltinService.Ping --data '{}' -``` - -期望输出为 - -```shell -{ - "error": "", - "result": {} -} -``` - -其中 POST 请求和返回的 JSON 数据和 Protobuf 定义的结构保持一致。 - -## 2. `BuiltinService` 服务 - -其中 `/api:protorpc/BuiltinService.Ping` 路径表示 `BuiltinService` 服务的 `Ping` 方法。 - -完整的 `BuiltinService` 由 Protobuf 定义: - -```protobuf -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} -``` - -其中 `Ping` 方法可以验证服务是否正常,`ListMethod` 方法可以查询提供的全部服务和函数列表。 - -## 3. `KclvmService` 服务 - -`KclvmService` 服务是和 KCL 功能相关的服务。用法和 `BuiltinService` 服务一样。 - -比如有以下的 `Person` 结构定义: - -```python -schema Person: - key: str - - check: - "value" in key # 'key' is required and 'key' must contain "value" -``` - -然后希望通过 `Person` 来校验以下的 JSON 数据: - -```json -{ "key": "value" } -``` - -可以通过 `KclvmService` 服务的 `ValidateCode` 方法完成。参考 `ValidateCode` 方法的 `ValidateCode_Args` 参数结构: - -```protobuf -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} -``` - -根据 `ValidateCode_Args` 参数结构构造 POST 请求需要的 JSON 数据,其中包含 `Person` 定义和要校验的 JSON 数据: - -```json -{ - "code": "\nschema Person:\n key: str\n\n check:\n \"value\" in key # 'key' is required and 'key' must contain \"value\"\n", - "data": "{\"key\": \"value\"}" -} -``` - -将该 JSON 数据保存到 `vet-hello.json` 文件,然后通过以下命令进行校验: - -```shell -curl -X POST \ - http://127.0.0.1:2021/api:protorpc/KclvmService.ValidateCode \ - -H "accept: application/json" \ - --data @./vet-hello.json -``` - -如果看到输出 - -```json -{ - "error": "", - "result": { - "success": true - } -} -``` - -说明校验成功。 - -## 4. 完整的 Protobuf 服务定义 - -跨语言的 API 通过 Protobuf 定义([https://github.com/kcl-lang/kcl-go/blob/main/pkg/spec/gpyrpc/gpyrpc.proto](https://github.com/kcl-lang/kcl-go/blob/main/pkg/spec/gpyrpc/gpyrpc.proto)): - -```protobuf -// Copyright 2023 The KCL Authors. All rights reserved. -// -// This file defines the request parameters and return structure of the KCL RPC server. -// We can use the following command to start a KCL RPC server. - -syntax = "proto3"; - -package gpyrpc; - -import "google/protobuf/any.proto"; -import "google/protobuf/descriptor.proto"; - -// ---------------------------------------------------------------------------- - -// kcl main.k -D name=value -message CmdArgSpec { - string name = 1; - string value = 2; -} - -// kcl main.k -O pkgpath:path.to.field=field_value -message CmdOverrideSpec { - string pkgpath = 1; - string field_path = 2; - string field_value = 3; - string action = 4; -} - -// ---------------------------------------------------------------------------- -// gpyrpc request/response/error types -// ---------------------------------------------------------------------------- - -message RestResponse { - google.protobuf.Any result = 1; - string error = 2; - KclError kcl_err = 3; -} - -message KclError { - string ewcode = 1; // See kclvm/kcl/error/kcl_err_msg.py - string name = 2; - string msg = 3; - repeated KclErrorInfo error_infos = 4; -} - -message KclErrorInfo { - string err_level = 1; - string arg_msg = 2; - string filename = 3; - string src_code = 4; - string line_no = 5; - string col_no = 6; -} - -// ---------------------------------------------------------------------------- -// service requset/response -// ---------------------------------------------------------------------------- - -// gpyrpc.BuiltinService -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -// gpyrpc.KclvmService -service KclvmService { - rpc Ping(Ping_Args) returns(Ping_Result); - - rpc ExecProgram(ExecProgram_Args) returns(ExecProgram_Result); - - rpc FormatCode(FormatCode_Args) returns(FormatCode_Result); - rpc FormatPath(FormatPath_Args) returns(FormatPath_Result); - rpc LintPath(LintPath_Args) returns(LintPath_Result); - rpc OverrideFile(OverrideFile_Args) returns (OverrideFile_Result); - - rpc GetSchemaType(GetSchemaType_Args) returns(GetSchemaType_Result); - rpc GetSchemaTypeMapping(GetSchemaTypeMapping_Args) returns(GetSchemaTypeMapping_Result); - rpc ValidateCode(ValidateCode_Args) returns(ValidateCode_Result); - - rpc ListDepFiles(ListDepFiles_Args) returns(ListDepFiles_Result); - rpc LoadSettingsFiles(LoadSettingsFiles_Args) returns(LoadSettingsFiles_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} - -message ParseFile_AST_Args { - string filename = 1; - string source_code = 2; -} -message ParseFile_AST_Result { - string ast_json = 1; // json value - KclError kcl_err = 2; -} - -message ParseProgram_AST_Args { - repeated string k_filename_list = 1; -} -message ParseProgram_AST_Result { - string ast_json = 1; // json value - KclError kcl_err = 2; -} - -message ExecProgram_Args { - string work_dir = 1; - - repeated string k_filename_list = 2; - repeated string k_code_list = 3; - - repeated CmdArgSpec args = 4; - repeated CmdOverrideSpec overrides = 5; - - bool disable_yaml_result = 6; - - bool print_override_ast = 7; - - // -r --strict-range-check - bool strict_range_check = 8; - - // -n --disable-none - bool disable_none = 9; - // -v --verbose - int32 verbose = 10; - - // -d --debug - int32 debug = 11; - - // yaml/json: sort keys - bool sort_keys = 12; - // include schema type path in JSON/YAML result - bool include_schema_type_path = 13; -} -message ExecProgram_Result { - string json_result = 1; - string yaml_result = 2; - - string escaped_time = 101; -} - -message ResetPlugin_Args { - string plugin_root = 1; -} -message ResetPlugin_Result { - // empty -} - -message FormatCode_Args { - string source = 1; -} - -message FormatCode_Result { - bytes formatted = 1; -} - -message FormatPath_Args { - string path = 1; -} - -message FormatPath_Result { - repeated string changed_paths = 1; -} - -message LintPath_Args { - repeated string paths = 1; -} - -message LintPath_Result { - repeated string results = 1; -} - -message OverrideFile_Args { - string file = 1; - repeated string specs = 2; - repeated string import_paths = 3; -} - -message OverrideFile_Result { - bool result = 1; -} - -message EvalCode_Args { - string code = 1; -} -message EvalCode_Result { - string json_result = 2; -} - -message ResolveCode_Args { - string code = 1; -} - -message ResolveCode_Result { - bool success = 1; -} - -message GetSchemaType_Args { - string file = 1; - string code = 2; - string schema_name = 3; -} -message GetSchemaType_Result { - repeated KclType schema_type_list = 1; -} - -message GetSchemaTypeMapping_Args { - string file = 1; - string code = 2; - string schema_name = 3; -} -message GetSchemaTypeMapping_Result { - map schema_type_mapping = 1; -} - -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} - -message ValidateCode_Result { - bool success = 1; - string err_message = 2; -} - -message Position { - int64 line = 1; - int64 column = 2; - string filename = 3; -} - -message ListDepFiles_Args { - string work_dir = 1; - bool use_abs_path = 2; - bool include_all = 3; - bool use_fast_parser = 4; -} - -message ListDepFiles_Result { - string pkgroot = 1; - string pkgpath = 2; - repeated string files = 3; -} - -// --------------------------------------------------------------------------------- -// LoadSettingsFiles API -// Input work dir and setting files and return the merged kcl singleton config. -// --------------------------------------------------------------------------------- - -message LoadSettingsFiles_Args { - string work_dir = 1; - repeated string files = 2; -} - -message LoadSettingsFiles_Result { - CliConfig kcl_cli_configs = 1; - repeated KeyValuePair kcl_options = 2; -} - -message CliConfig { - repeated string files = 1; - string output = 2; - repeated string overrides = 3; - repeated string path_selector = 4; - bool strict_range_check = 5; - bool disable_none = 6; - int64 verbose = 7; - bool debug = 8; -} - -message KeyValuePair { - string key = 1; - string value = 2; -} - -// ---------------------------------------------------------------------------- -// JSON Schema Lit -// ---------------------------------------------------------------------------- - -message KclType { - string type = 1; // schema, dict, list, str, int, float, bool, any, union, number_multiplier - repeated KclType union_types = 2 ; // union types - string default = 3; // default value - - string schema_name = 4; // schema name - string schema_doc = 5; // schema doc - map properties = 6; // schema properties - repeated string required = 7; // required schema properties, [property_name1, property_name2] - - KclType key = 8; // dict key type - KclType item = 9; // dict/list item type - - int32 line = 10; - - repeated Decorator decorators = 11; // schema decorators -} - -message Decorator { - string name = 1; - repeated string arguments = 2; - map keywords = 3; -} - -// ---------------------------------------------------------------------------- -// END -// ---------------------------------------------------------------------------- -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/Ide/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/Ide/index.md deleted file mode 100644 index 2ba6e5b4..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/Ide/index.md +++ /dev/null @@ -1,6 +0,0 @@ -# IDE - -我们为 KCL 提供了两种简单的 IDE 插件。您可以通过以下链接获得更多帮助信息: - -- IntelliJ 插件: https://github.com/kcl-lang/intellij-kcl -- VSCode 插件: https://github.com/kcl-lang/vscode-kcl diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/Ide/intellij.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/Ide/intellij.md deleted file mode 100644 index be637514..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/Ide/intellij.md +++ /dev/null @@ -1,3 +0,0 @@ -# IntelliJ IDEA - -- IntelliJ Plugin: https://github.com/kcl-lang/intellij-kcl diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/Ide/vs-code.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/Ide/vs-code.md deleted file mode 100644 index d3db7e01..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/Ide/vs-code.md +++ /dev/null @@ -1,54 +0,0 @@ -# Visual Studio Code KCL 插件 - -## 快速开始 - -- 1. [安装 KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) 并检查 `kcl` 和 `kcl-language-server` 命令在您的 PATH 中: - - ```bash - which kcl - which kcl-language-server - ``` - -- 2. 安装 [VS Code KCL 插件](https://marketplace.visualstudio.com/items?itemName=kcl.kcl-vscode-extension). 需要您的 VS Code 版本大于 1.50+ -- 3. 重新打开 VS Code 并创建一个 KCL 文件验证 IDE 插件功能 - -## 特性 - -此扩展提供了一些 KCL 编码帮助,包括以下功能: - -- **语法高亮** - ![Highlight](/img/docs/tools/Ide/vs-code/Highlight.png) -- **跳转** - ![Goto Definition](/img/docs/tools/Ide/vs-code/GotoDef.gif) -- **补全** - ![Completion](/img/docs/tools/Ide/vs-code/Completion.gif) -- **大纲** - ![Outline](/img/docs/tools/Ide/vs-code/Outline.gif) -- **悬停** - ![Hover](/img/docs/tools/Ide/vs-code/Hover.gif) -- **诊断** - ![Diagnostics](/img/docs/tools/Ide/vs-code/Diagnostics.gif) - -> 提示:您可以通过安装 [Error Lens 插件](https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens) 来增强诊断效果 - -其他一些有用的功能,如代码重构和智能感知等正在开发中。 - -## 最小依赖 - -我们建议您使用最新版本的 KCL,但此扩展所需的 KCL 最低版本为 v0.4.6。如果您使用的是更早期版本,则此扩展可能无法正常工作。 - -## 已知问题 - -[详见](https://github.com/kcl-lang/kcl/issues/524) - -## 寻求帮助 - -如果扩展没有如您所期望的那样工作,请通过[社区](https://kcl-lang.io/docs/community/intro/support)与我们联系和寻求帮助。 - -## 参与贡献 - -目前 VS Code KCL 插件处于早期版本,我们正在积极改进 VS Code KCL 插件体验,欢迎参考[贡献指南](https://kcl-lang.io/docs/community/contribute) 一起共建! - -## 许可 - -Apache License 2.0 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/docgen.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/docgen.md deleted file mode 100644 index 37b660ed..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/docgen.md +++ /dev/null @@ -1,313 +0,0 @@ ---- -sidebar_position: 5 ---- - -# 文档生成工具 - -KCL 命令行工具支持从 KCL 源码中一键提取模型文档,并支持丰富的输出格式:JSON,YAML 和 Markdown 等。本文介绍 KCL 语言的文档规范,举例说明如何使用 KCL 文档生成工具提取文档,并展示新增本地化语言文档的流程。 - -## 1. KCL 语言的文档规范 - -KCL文件的文档主要包含如下两个部分: - -- 当前 KCL Moudle 的文档:对当前 KCL 文件的说明 -- KCL 文件内包含的所有 Schema 的文档:对当前 Schema 的说明,其中包含 Schema 描述、Schema 各属性的描述、Examples 三部分,具体格式如下: - -1. Schema 描述 - -```python -"""这是Schema一个简短的描述信息 -""" -``` - -2. Schema 各属性的描述:包含属性描述、属性类型、默认值、是否可选 - -```python -""" -Attributes ----------- -x : type, default is a, optional. - Description of parameter `x`. -y : type, default is b, required. - Description of parameter `y`. -""" -``` - -其中,使用 `----------` 表示 `Attributes` 为一个标题(`-` 符号长度与标题长度保持一致),属性名称与属性类型用冒号 `:` 分隔,属性的说明另起一行并增加缩进进行书写。属性的默认值说明跟在属性类型之后使用逗号 `,` 分隔,书写为 `default is {默认值}` 形式,此外需要说明属性是否为可选/必选,对于可选属性在默认值之后书写 `optional`,对于必选属性在默认值之后书写 `required`。 - -3. Examples - -```python -""" -Examples --------- -val = Schema { - name = "Alice" - age = 18 -} -""" -``` - -此外,KCL 文档字符串语法应采用 [re-structured text (reST)](https://docutils.sourceforge.io/rst.html) 语法子集,并使用 [Sphinx](https://www.sphinx-doc.org/en/master/) 渲染呈现。 - -## 2. 从 KCL 源码生成文档 - -使用 kcl-doc generate 命令,从用户指定的文件或目录中提取文档,并输出到指定目录。 - -1. 参数说明 - -``` -usage: kcl-doc generate [-h] [--format YAML] [-o OUTPUT] [--r] - [--i18n-locale LOCALE] [--repo-url REPO_URL] - [files [files ...]] - -positional arguments: - files KCL file paths. If there's more than one files to - generate, separate them by space - -optional arguments: - -h, --help show this help message and exit - --format YAML Doc file format, support YAML, JSON and MARKDOWN. - Defaults to MARKDOWN - -o OUTPUT, --output-path OUTPUT - Specify the output directory. Defaults to ./kcl_doc - --r, -R, --recursive Search directory recursively - --i18n-locale LOCALE I18n locale, e.g.: zh, zh_cn, en, en_AS. Defaults to - en - --repo-url REPO_URL The source code repository url. It will be displayed in - the generated doc to link to the source code. -``` - -2. 从指定的一个或多个文件中提取文档,并输出到指定目录 - -```text -kcl-doc generate your_config.k your_another_config.k -o your_docs_output_dir -``` - -3. 从指定目录内,递归地查找 KCL 源码文件,并提取文档 - -```text -kcl-doc generate your_config_dir -r -o your_docs_output_dir -``` - -4. 在生成文档时,指定源码仓库地址。一经指定,生成的文档中将包含指向源码文件的链接 - -```text -kcl-doc generate your_config.k -o your_docs_output_dir --repo-url https://url/to/source_code -``` - -## 3. 新增本地化语言的文档 - -如前所示,默认情况下,文档生成工具提取的文档以源码 docstring 的内容为准,因而文档的语言随 docstring 编写语言而定。如果需要为源文件新增本地化语言的文档,则可以遵循按如下步骤: - -1. 初始化 i18n 配置文件。该步骤基于指定的 KCL 源码文件,生成相应的 i18n 配置文件,文件格式可选 JSON/YAML,默认为 YAML. 输出的配置文件名称将以指定的目标本地化方言结尾 - -```text -kcl-doc init-i18n your_config.k --format JSON --i18n-locale your_target_locale -``` - -2. 手动修改上述生成的 i18n 配置文件,使用目标语言修改配置中的 doc 字段 - -3. 基于修改后的 i18n 配置,生成本地化语言的文档。工具将查找指定目标语言的 i18n 配置文件,并转化为最终的文档 - -```text -kcl-doc generate your_config_dir --i18n-locale your_target_locale --format Markdown -``` - -接下来,通过一个小例子演示新增本地化语言文档的过程。 - -3.1 准备 KCL 源码文件,例如 server.k: - - ```python - schema Server: - """Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - - Attributes - ---------- - workloadType : str, default is "Deployment", required - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - name : str, required - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - labels : {str:str}, optional - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - - Examples - ---------------------- - myCustomApp = AppConfiguration { - name = "componentName" - } - """ - - workloadType: str = "Deployment" - name: str - labels?: {str: str} - ``` - -3.2 从 server.k 得到初始化的 i18n 配置文件,例如希望为其增加中文文档,指定生成的配置文件格式为 YAML - - ```text - kcl-doc init-i18n server.k --format YAML --i18n-locale zh_cn - ``` - - 该命令将在当前目录下创建 kcl_doc 目录,并生成 i18n 配置文件 kcl_doc/i18n_server_zh_cn.yaml,其内容如下: - - ```yaml - name: server - relative_path: ./server.k - schemas: - - name: Server - doc: | - Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - attributes: - - name: workloadType - doc: | - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - default_value: '"Deployment"' - is_optional: false - - name: name - doc: | - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: false - default_value: '' - - name: labels - doc: | - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - type: - type_str: '{str: str}' - type_category: DICT - dict_type: - key_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - value_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: true - default_value: '' - examples: | - myCustomApp = AppConfiguration { - name = "componentName" - } - doc: '' - source_code_url: '' - ``` - -3.3 修改初始化得到的 i18n 配置,将其中的 doc 字段修改为中文的描述,修改后的配置如下: - - ```yaml - name: server - relative_path: ./server.k - schemas: - - name: Server - doc: | - Server 模型定义了采用 Kubernetes 最佳实践的持续运行的服务的通用配置接口 - attributes: - - name: workloadType - doc: | - workloadType 属性定义了服务的类型,是服务级别的属性。合法的取值有:Deployment, CafeDeployment. - 另请查看:k8s/core/v1/workload_metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - default_value: '"Deployment"' - is_optional: false - - name: name - doc: | - name 为服务的名称,是服务级别的属性。 - 另请查看:k8s/core/v1/metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: false - default_value: '' - - name: labels - doc: | - labels 为服务的标签,是服务级别的属性。 - 另请查看:k8s/core/v1/metadata.k. - type: - type_str: '{str: str}' - type_category: DICT - dict_type: - key_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - value_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: true - default_value: '' - examples: | - myCustomApp = AppConfiguration { - name = "componentName" - } - doc: '' - source_code_url: '' - ``` - -3.4 基于修改后的 i18n 配置,生成本地化语言的文档,执行如下命令,将输出中文的文档 kcl_doc/doc_server_zh_cn.md,命令及生成的文档内容如下: - - ```text - kcl-doc generate server.k --i18n-locale zh_cn --format Markdown - ``` - - ~~~markdown - # server - ## Schema Server - Server 模型定义了采用 Kubernetes 最佳实践的持续运行的服务的通用配置接口 - - ### Attributes - |Name and Description|Type|Default Value|Required| - |--------------------|----|-------------|--------| - |**workloadType**
workloadType 属性定义了服务的类型,是服务级别的属性。合法的取值有:Deployment, CafeDeployment.
另请查看:k8s/core/v1/workload_metadata.k.|str|"Deployment"|**required**| - |**name**
name 为服务的名称,是服务级别的属性。
另请查看:k8s/core/v1/metadata.k.|str|Undefined|**required**| - |**labels**
labels 为服务的标签,是服务级别的属性。
另请查看:k8s/core/v1/metadata.k.|{str: str}|Undefined|optional| - ### Examples - ``` - myCustomApp = AppConfiguration { - name = "componentName" - } - ``` - - - - ~~~ - -## 4. 附录 - -### 1. 常见的 reST 概念 - -对于 reST 格式的文档,段落和缩进很重要,新段落用空白行标记,缩进即为表示输出中的缩进。可以使用如下方式表示字体样式: - -- \*斜体\* -- \*\*粗体\*\* -- \`\`等宽字体\`\` - -参考 [reST 文档](https://docutils.sourceforge.io/rst.html)获得更多帮助。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/fmt.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/fmt.md deleted file mode 100644 index 11199215..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/fmt.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -sidebar_position: 2 ---- - -# 格式化代码 - -KCL 支持通过内置的命令行工具一键格式化多个 KCL 文件文档。本文展示 KCL 编码风格和 KCL 格式化工具的使用方式。 - -## KCL 编码风格 - -KCL 格式化对文件的修改样式具体见 KCL 编码风格:[Style Guide for KCL Code](/docs/reference/lang/spec/codestyle) - -## 使用方式 - -- 单文件格式化 - -```text -kcl-fmt your_config.k -``` - -- 文件夹内多文件格式化 - -```text -kcl-fmt your_config_path -R -``` - -- 命令行参数 - - `-R|--recursive` 设置是否递归遍历子文件夹 - - `-w|--fmt-output` 设置是否输出到标准输出流,不加 `-w` 表示原地格式化 KCL 文件 - -## 格式化文件效果展示 - -- 格式化前 - -```py -import math -mixin DeploymentMixin: - service:str ="my-service" -schema DeploymentBase: - name: str - image : str -schema Deployment[replicas] ( DeploymentBase ) : - mixin[DeploymentMixin] - replicas : int = replicas - command: [str ] - labels: {str: str} -deploy = Deployment(replicas = 3){} -``` - -- 格式化后 - -```py -import math - -mixin DeploymentMixin: - service: str = "my-service" - -schema DeploymentBase: - name: str - image: str - -schema Deployment[replicas](DeploymentBase): - mixin [DeploymentMixin] - replicas: int = replicas - command: [str] - labels: {str:str} - -deploy = Deployment(replicas=3) {} - -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/index.md deleted file mode 100644 index 51f69ee6..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# KCL 语言工具 - -KCL 不仅提供了 kcl 命令编译和执行配置程序,还提供了 fmt、lint、test、vet、docgen 等配套的辅助工具。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/lint.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/lint.md deleted file mode 100644 index 7a66d3b3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/lint.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Lint 检查代码风格 - -KCL 支持通过内置的命令行工具对 KCL 代码进行检查,并支持多种输出格式。本文档展示 KCL Lint 工具的使用方式。 - -## 示例 - -### 工程结构 - -```text -. -└── Test - └── kcl.mod - └── a.k - └── b.k - └── dir - └── c.k - └── test.k -``` - -`a.k`,`b.k`,`c.k`,`test.k` 为测试的 kcl 文件。 - -命令: - -```shell -kcl-lint your_config.k -``` - -或 - -```shell -kcl-lint your_config_path -``` - -### CLI 参数 - -```shell -USAGE: - kcl-lint [OPTIONS] [--] [input]... - -ARGS: - ... Sets the input file to use - -OPTIONS: - --emit_warning Emit warning message - -h, --help Print help information - -v, --verbose Print test information verbosely - -Y, --setting ... Sets the input file to use -``` - -- input: 需要检查的单个 `.k` 文件路径或路径目录下的所有 `.k` 文件,支持绝对路径或当前目录的相对路径 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/overview.md deleted file mode 100644 index 4fa606dc..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/overview.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 概览 - -KCL 工具链是 KCL 语言的工具集合,旨在提升 KCL 的批量迁移、编写、编译和测试的效率。 - -| 类别 | 工具名称 | 说明 | -| ---------- | ---------------------- | --------------------------------------------------------- | -| 主工具集 | **kcl** | kcl 命令行工具提供对基于 KCL 语言的配置编写、编译和运行。 | -| | kcl-test | 即将提供 | -| | kcl-fmt | kcl-fmt 工具提供对 KCL 代码的格式化 | -| | kcl-lint | kcl-lint 工具提供对 KCL 代码的 lint 检查和自动修复 | -| | kcl-doc | kcl-doc 工具提供对 KCL 代码的文档解析和生成 | -| | kcl-vet | 使用 KCL 代码校验诸如 JSON 和 YAML 的数据格式 | -| ide 插件集 | IntelliJ IDEA KCL 插件 | 提供 IntelliJ IDEA 平台的 KCL 编写、编译辅助 | -| | VS Code KCL 插件 | 提供 VS Code 平台的 KCL 编写、编译辅助 | - -## KCL 工具 - -### 命令行参数 - -```shell -USAGE: - kcl [OPTIONS] [--] [input]... - -Arguments: - [input]... Specify the input files to run - -Options: - -o, --output - Specify the YAML output file path - -Y, --setting ... - Specify the input setting file - -v, --verbose... - Print test information verbosely - -n, --disable_none - Disable dumping None values - -r, --strict_range_check - Do perform strict numeric range checks - -d, --debug - Run in debug mode (for developers only) - -k, --sort_keys - Sort result keys - -D, --argument ... - Specify the top-level argument - -S, --path_selector ... - Specify the path selector - -O, --overrides ... - Specify the configuration override path and value - --target - Specify the target type - -E, --external ... - Mapping of package name and path where the package is located - -h, --help - Print help -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/test.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/test.md deleted file mode 100644 index f8707ff9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/test.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 5 ---- - -# 测试工具 - -即将到来! diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/vet.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/vet.md deleted file mode 100644 index 2c70ce91..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/vet.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Validation 校验代码 - -## 简介 - -KCL 支持通过内置的 `kcl-vet` 命令行工具提供了基本的配置数据校验能力,可以编写 KCL schema 对输入的 JSON/YAML 格式文件进行类型以及数值的校验。 - -## 使用方式 - -假设有 data.json 文件,代码如下: - -```json -{ - "name": "Alice", - "age": 18, - "message": "This is Alice", - "data": { - "id": 1, - "value": "value1" - }, - "labels": { - "key": "value" - }, - "hc": [1, 2, 3] -} -``` - -构造 schema.k 校验文件,内容如下: - -```py -schema User: - name: str - age: int - message?: str - data: Data - labels: {str:} - hc: [int] - - check: - age > 10 - -schema Data: - id: int - value: str -``` - -在目录下执行如下命令 - -```shell -$ kcl-vet data.json schema.k -``` - -## 指定校验的 schema - -当校验的 KCL 文件中存在多个 schema 定义时,kcl-vet 工具会默认取第一个 schema 定义进行校验,如果需要指定校验的 schema,可以使用 `-d|--schema` 参数 - -```shell -$ kcl-vet data.json schema.k -d User -``` - -## 命令行参数 - -```shell -$ kcl-vet -h -USAGE: - kcl-vet [OPTIONS] [ARGS] - -ARGS: - Validation data file - KCL file - -OPTIONS: - -d, --schema - Iterate through subdirectories recursively - - --format - Validation data file format, support YAML and JSON, default is JSON - - -h, --help - Print help information - - -n, --attribute_name - The attribute name for the data loading -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/openapi/crd-to-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/openapi/crd-to-kcl.md deleted file mode 100644 index 5b6f070c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/openapi/crd-to-kcl.md +++ /dev/null @@ -1,118 +0,0 @@ -# CRD to KCL - -命令 - -```shell -kcl-openapi generate model --crd -f ${your_CRD.yaml} -t ${the_kcl_files_output_dir} --skip-validation -``` - -# 示例 - -- 输入文件:test_crontab_CRD.yaml: - -```yaml -# Deprecated in v1.16 in favor of apiextensions.k8s.io/v1 -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - # name must match the spec fields below, and be in the form: . - name: crontabs.stable.example.com -spec: - # group name to use for REST API: /apis// - group: stable.example.com - # list of versions supported by this CustomResourceDefinition - versions: - - name: v1 - # Each version can be enabled/disabled by Served flag. - served: true - # One and only one version must be marked as the storage version. - storage: true - # either Namespaced or Cluster - scope: Namespaced - names: - # plural name to be used in the URL: /apis/// - plural: crontabs - # singular name to be used as an alias on the CLI and for display - singular: crontab - # kind is normally the CamelCased singular type. Your resource manifests use this. - kind: CronTab - # shortNames allow shorter string to match your resource on the CLI - shortNames: - - ct - preserveUnknownFields: false - validation: - openAPIV3Schema: - type: object - properties: - spec: - type: object - properties: - cronSpec: - type: string - image: - type: string - replicas: - type: integer -``` - -- 命令 - -```shell -kcl-openapi generate model -f test_crontab_CRD.yaml -t ~/ --skip-validation --crd -``` - -- 输出文件: ~/models/stable_example_com_v1_cron_tab.k - -```python -""" -This file was generated by the KCL auto-gen tool. DO NOT EDIT. -Editing this file might prove futile when you re-run the KCL auto-gen generate command. -""" -import kusion_kubernetes.apimachinery.apis - - -schema CronTab: - """stable example com v1 cron tab - - Attributes - ---------- - apiVersion : str, default is "stable.example.com/v1", required - APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - kind : str, default is "CronTab", required - Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - metadata : apis.ObjectMeta, default is Undefined, optional - metadata - spec : StableExampleComV1CronTabSpec, default is Undefined, optional - spec - """ - - - apiVersion: "stable.example.com/v1" = "stable.example.com/v1" - - kind: "CronTab" = "CronTab" - - metadata?: apis.ObjectMeta - - spec?: StableExampleComV1CronTabSpec - - -schema StableExampleComV1CronTabSpec: - """stable example com v1 cron tab spec - - Attributes - ---------- - cronSpec : str, default is Undefined, optional - cron spec - image : str, default is Undefined, optional - image - replicas : int, default is Undefined, optional - replicas - """ - - - cronSpec?: str - - image?: str - - replicas?: int -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/openapi/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/openapi/index.md deleted file mode 100644 index 0654db2a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/openapi/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# OpenAPI Tools - -kcl-openapi 工具支持将通过 OpenAPI 规范描述的模型转换为 KCL 配置策略语言,除了能直接转换 OpenAPI 描述文件之外,还可以从 Kubernetes CRD 中提取并转换为 KCL schema. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/openapi/openapi-to-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/openapi/openapi-to-kcl.md deleted file mode 100644 index 6d9f8e54..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/openapi/openapi-to-kcl.md +++ /dev/null @@ -1,64 +0,0 @@ -# OpenAPI to KCL - -命令 - -```shell -kcl-openapi generate model -f ${your_open_api_spec.yaml} -t ${the_kcl_files_output_dir} -``` - -示例: - -- 输入文件:test_open_api_spec.yaml: - -```yaml -definitions: - v1.TestInt: - type: object - properties: - name: - type: string - format: int-or-string - required: - - name - x-kcl-type: - import: - package: v1.test_int - alias: test_int - type: TestInt -swagger: "2.0" -info: - title: KCL - version: v0.0.2 -paths: {} -``` - -- 命令: - -```shell -kcl-openapi generate model -f test_open_api_spec.yaml -t ~/ -``` - -- 输出:~/models/v1/test_int.k - -```python -""" -This is the test_int module in v1 package. -This file was generated by the KCL auto-gen tool. DO NOT EDIT. -Editing this file might prove futile when you re-run the KCL auto-gen generate command. -""" - - -schema TestInt: - """v1 test int - - Attributes - ---------- - name : int | str, default is Undefined, required - name - """ - - - name: int | str - - -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/openapi/quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/openapi/quick-start.md deleted file mode 100644 index 3d6a125d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/openapi/quick-start.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 快速开始 - -## 1. 安装 KCLOpenAPI 工具 - -目前有多种安装方式可选: - -- [通过 go install 安装](#11-通过-go-install-安装) -- [通过 curl|sh 安装(仅限 MacOS & Linux)](#12-通过-curlsh-安装(仅限-MacOS--Linux)) -- [下载发布包](#13-下载发布包) - -## 1.1 通过 go install 安装 - -```shell -go install kcl-lang.io/kcl-openapi@latest -``` - -## 1.2 通过 curl|sh 安装(仅限 MacOS & Linux) - -```shell -curl -fsSL https://kcl-lang.io/script/install-kcl-openapi.sh | /bin/bash -``` - -## 1.3 下载发布包 - -```shell -# 1. 下载二进制程序 -# https://github.com/kcl-lang/kcl-openapi/releases - -# 2. 解压发布包,并将命令添加至 PATH -export PATH=":$PATH" -``` - -## 1.4 验证安装结果 - -```shell -➜ kcl-openapi -v -kcl-openapi 0.5.0 -``` - -## 2. 生成 KCL 文件 - -- [将 OpenAPI 描述文件转换为 KCL](../openapi/openapi-to-kcl.md) -- [将 Kubernetes CRD 转换为 KCL](../openapi/crd-to-kcl.md) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/concepts/concepts.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/concepts/concepts.md deleted file mode 100644 index e2034db2..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/concepts/concepts.md +++ /dev/null @@ -1,3 +0,0 @@ -# 核心概念 - -学习更多关于 KCL 核心概念。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/getting-started/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/getting-started/index.md deleted file mode 100644 index 5d58acf6..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/getting-started/index.md +++ /dev/null @@ -1 +0,0 @@ -# 快速开始 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/getting-started/install.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/getting-started/install.md deleted file mode 100644 index 74510232..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/getting-started/install.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -sidebar_position: 2 ---- - -# 安装 - -## 1. 安装 KCL - -### 二进制下载 - -KCL 的每个版本都包含各种操作系统和体系结构。这些二进制版本可以从 [Github](https://github.com/kcl-lang/kcl/releases/) 或者 [Gitee](https://gitee.com/kusionstack/kcl/releases) 手动下载并安装,下载完成后将 `{install-location}/kclvm/bin` 添加到环境变量 PATH 中。 - -> ⚠️ 如果您不能成功访问 Github, 也可以访问 Gitee 获得二进制进行安装 - -#### MacOS & Linux - -```bash -export PATH=$PATH:{install-location}/kclvm/bin -``` - -#### Windows - -```powershell -$env:PATH += ";{install-location}\kclvm\bin;" -``` - -### 使用脚本安装最新版本 - -#### MacOS - -将 KCL darwin 最新版本安装到 /usr/local/kclvm/bin - -```bash -curl -fsSL https://kcl-lang.io/script/install.sh | /bin/bash -``` - -#### Linux - -将 KCL linux 最新版本安装到 /usr/local/kclvm/bin - -```bash -wget -q https://kcl-lang.io/script/install.sh -O - | /bin/bash -``` - -#### Windows - -将 KCL windows 最新版本安装到 $Env:SystemDrive\kclvm\bin,并将该目录添加到用户 PATH 环境变量中。 - -```bash -powershell -Command "iwr -useb https://kcl-lang.io/script/install.ps1 | iex" -``` - -### Homebrew (MacOS) - -- 安装 - -```bash -brew install kcl-lang/tap/kcl -``` - -- 升级 - -```bash -brew upgrade kcl-lang/tap/kcl -``` - -- 卸载 - -```bash -brew uninstall kcl-lang/tap/kcl -``` - -### Scoop (Windows) - -首先安装 [Scoop](https://scoop.sh/), 然后通过如下命令安装 `kcl`: - -```bash -scoop bucket add kcl-lang https://github.com/kcl-lang/scoop-bucket.git -scoop install kcl-lang/kcl -``` - -### 使用 Go 安装 - -通过 `Go` 命令安装 (Go 要求 1.18+) - -```bash -go install kcl-lang.io/kcl-go/cmds/kcl-go@main -``` - -添加一个 kcl 命令的别名 (可选) - -```bash -alias kcl='kcl-go run' -``` - -> 注意:`kcl-go` 并不依赖是否安装了 `kcl`,但如果 PATH 中存在 `kcl`,`kcl-go` 将优先使用 `PATH` 中的 `kcl`。 - -### 使用 Docker 镜像安装 - -- 基本命令 - -```bash -docker run --rm -it kcllang/kcl -``` - -- 更新镜像 - -```bash -docker pull kcllang/kcl -``` - -### 注意 - -可以执行运行如下命令确保 KCL 已经正确安装 - -```bash -kcl -V -``` - -如果安装成功,输出可能为如下形式 (不同版本结果可能稍微不同): - -```bash -Version: {kcl version} -Platform: {your platform} -GitCommit: {git commit} -``` - -对于上述所有安装方式, 如果您想使用 [KCL Python 插件](/docs/reference/plugin/overview), 需要确保您已经安装了 Python 3.7+ 并将 python3 命令添加到您的 PATH 中。 - -## 2. 安装 KCL IDE 插件 - -### VS Code - -KCL 为 VS Code 本地版本提供了插件支持,并提供了高亮、自动补全、跳转、悬停、大纲等功能。您可以[点击这里](/docs/tools/Ide/vs-code)进行安装。 - -![Completion](/img/docs/tools/Ide/vs-code/Completion.gif) - -### IntelliJ IDEA - -从[这里](https://github.com/kcl-lang/intellij-kcl/releases)下载发行版,在 IntelliJ IDEA 中,点击 Preference -> plugins -> install Plugin from Disk... -> 选择 kcl-idea-plugin zip -> 重启 IDE。此插件需要 IntelliJ IDEA 2020.2+ diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/getting-started/intro.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/getting-started/intro.md deleted file mode 100644 index aaa364e3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/getting-started/intro.md +++ /dev/null @@ -1,199 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 简介 - -## KCL 是什么? - -[KCL](https://github.com/kcl-lang/kcl) 是一个开源的基于约束的记录及函数语言。KCL 通过成熟的编程语言技术和实践来改进对大量繁杂配置比如云原生 Kubernetes 配置场景的编写,致力于构建围绕配置的更好的模块化、扩展性和稳定性,更简单的逻辑编写,以及更简单的自动化和生态工具集成。 - -## 为什么使用 KCL? - -KCL 期望通过更现代化的声明式配置语言在 Kubernetes 资源管理解决如下问题: - -- 通过**代码抽象**等手段屏蔽基础设施和平台的细节,降低研发者负担 -- **编辑**和**校验**已有的存量配置或模版 -- 通过配置语言无副作用地管理跨团队的大规模配置数据,提升团队协作效率 - - 用**生产级高性能编程语言**以**编写代码**的方式提升配置的灵活度,比如条件语句、循环、函数、包管理等特性提升配置重用的能力 - - 在代码层面提升**配置语义验证**的能力,比如字段可选/必选、类型、范围等配置检查能力 - - 提供**配置分块编写、组合和抽象的能力**,比如结构定义、结构继承、约束定义等能力 - - 通过**多语言 SDK**,**KCL 语言插件**等手段提升其**自动化**集成能力 - -您可以将 KCL 用于 - -- 生成静态配置数据如 JSON, YAML 等 -- 使用 schema 对配置数据进行建模并减少配置数据中的样板文件 -- 为配置数据定义带有规则约束的 schema 并对数据进行自动验证 -- 无副作用地组织、简化、统一和管理庞大的配置 -- 通过分块编写配置数据可扩展地管理庞大的配置 -- 与 [KusionStack](https://kusionstack.io) 一起,用作平台工程语言来交付现代应用程序 - -除了语言自身,KCL 还提供了许多额外的工具如格式化,测试、文档、包管理等工具帮助您使用、理解和检查编写的配置或策略;通过 VS Code 等 IDE 插件和 Playground 降低配置编写、分享的成本;通过 Rust, Go, 和 Python 多语言 SDK 自动化地管理和执行配置。 - -![](/img/docs/user_docs/intro/kcl-overview.png) - -此外,KCL 是一种现代高级领域编程语言,并且它是一种编译静态的强类型语言。KCL 为开发人员提供了通过记录和函数语言设计将**配置(config)**、**建模抽象(schema)**、**逻辑(lambda)**和**策略(rule)**作为核心能力。 - -![](/img/docs/user_docs/intro/kcl-concepts.png) - -KCL 试图提供独立于运行时的可编程性,不在本地提供线程和IO等系统功能,但支持云本地操作场景的功能,并试图为解决领域问题并提供稳定、安全、低噪声、低副作用、易于自动化和易于管理的编程支持。 - -总之,KCL 具备如下特点: - -- **简单易用**:源于 Python、Golang 等高级语言,采纳函数式编程语言特性,低副作用 -- **设计良好**:独立的 Spec 驱动的语法、语义、运行时和系统库设计 -- **快速建模**:以 [Schema](https://kcl-lang.io/docs/reference/lang/tour#schema) 为中心的配置类型及模块化抽象 -- **功能完备**:基于 [Config](https://kcl-lang.io/docs/reference/lang/tour#config-operations)、[Schema](https://kcl-lang.io/docs/reference/lang/tour#schema)、[Lambda](https://kcl-lang.io/docs/reference/lang/tour#function)、[Rule](https://kcl-lang.io/docs/reference/lang/tour#rule) 的配置及其模型、逻辑和策略编写 -- **可靠稳定**:依赖[静态类型系统](https://kcl-lang.io/docs/reference/lang/tour/#type-system)、[约束](https://kcl-lang.io/docs/reference/lang/tour/#validation)和[自定义规则](https://kcl-lang.io/docs/reference/lang/tour#rule)的配置稳定性 -- **强可扩展**:通过独立配置块[自动合并机制](https://kcl-lang.io/docs/reference/lang/tour/#-operators-1)保证配置编写的高可扩展性 -- **易自动化**:[CRUD APIs](https://kcl-lang.io/docs/reference/lang/tour/#kcl-cli-variable-override),[多语言 SDK](https://kcl-lang.io/docs/reference/xlang-api/overview),[语言插件](https://github.com/kcl-lang/kcl-plugin) 构成的梯度自动化方案 -- **极致性能**:使用 Rust & C,[LLVM](https://llvm.org/) 实现,支持编译到本地代码和 [WASM](https://webassembly.org/) 的高性能编译时和运行时 -- **API 亲和**:原生支持 [OpenAPI](https://github.com/kcl-lang/kcl-openapi)、 Kubernetes CRD, Kubernetes YAML 等 API 生态规范 -- **开发友好**:[语言工具](https://kcl-lang.io/docs/tools/cli/kcl/) (Format,Lint,Test,Vet,Doc 等)、 [IDE 插件](https://github.com/kcl-lang/vscode-kcl) 构建良好的研发体验 -- **安全可控**:面向领域,不原生提供线程、IO 等系统级功能,低噪音,低安全风险,易维护,易治理 -- **多语言 SDK**:[Go](https://kcl-lang.io/docs/reference/xlang-api/go-api),[Python](https://kcl-lang.io/docs/reference/xlang-api/python-api),[Java](https://kcl-lang.io/docs/reference/xlang-api/java-api) 和 [REST API](https://kcl-lang.io/docs/reference/xlang-api/rest-api) 满足不同场景和应用使用需求 -- **生态集成**:通过 [Kustomize KCL 插件](https://github.com/kcl-lang/kustomize-kcl), [Helm KCL 插件](https://github.com/kcl-lang/helm-kcl) 或者 [KPT KCL SDK](https://github.com/kcl-lang/kpt-kcl-sdk) 直接编辑或校验资源 -- **生产可用**:广泛应用在蚂蚁集团平台工程及自动化的生产环境实践中 - -虽然 KCL 不是通用语言,但它有相应的应用场景。开发人员可以通过 KCL 编写**config**、**schema**、**function**和**rule**,其中 config 用于定义数据,schema 用于描述数据的模型定义,rule 用于验证数据,schema 和 rule 还可以组合使用模型和约束来充分描述数据。此外,还可以使用 KCL 中的 lambda 纯函数来组织数据代码,封装通用代码,并在需要时直接调用它。 - -KCL 配置通常遵循如下模式: - -$$ -k = (T) v -$$ - -其中,$k$ 是属性名称,$v$ 是属性值,$T$ 是类型注解。由于 KCL 具有类型推导的能力,因此 $T$ 通常可以省略。 - -下面是一个用 KCL 生成 kubernetes 资源的例子 - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = name -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -我们可以使用上述 KCL 代码生成一个 Kubernetes YAML 配置 - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## 如何选择 - -目前社区已经进行了大量的尝试来改进其配置技术,主要可分为三类: - -- 用于模板、修补和验证的基于低级数据格式的工具,使用外部工具来增强重用和验证。 -- 领域特定语言(DSL)和配置语言(CL),以增强语言能力。 -- 基于通用语言(GPL)的解决方案,使用 GPL 的云开发工具包(CDK)或框架来定义配置。 - -简单的选择答案: - -- 如果您需要编写结构化的静态的 K-V,或使用 Kubernetes 原生的技术工具,建议选择 YAML。 -- 如果您希望引入编程语言便利性以消除文本(如 YAML、JSON) 模板,有良好的可读性,或者你已是 Terraform 的用户,建议选择 HCL。 -- 如果您希望引入类型功能提升稳定性,维护可扩展的配置文件,建议选择 CUE。 -- 如果您希望以现代语言方式编写复杂类型和建模,维护可扩展的配置文件,原生的纯函数和策略,和生产级的性能和自动化,建议直接选择 KCL 或将 KCL 用于对已有配置手段或工具进行增强。 - -### vs. YAML/JSON - -YAML/JSON 适用于小型配置场景。对于需要频繁修改的大型云原生配置场景,它们更适合 KCL。所涉及的主要区别是配置数据抽象和部署之间的区别: - -使用 KCL 进行配置的优点是:对于静态数据,抽象一层的优点意味着整个系统具有部署灵活性。不同的配置环境、租户和运行时可能对静态数据有不同的要求,甚至不同的组织可能有不同的规范和产品要求。KCL 可用于公开最需要的和经常修改的配置。 - -### vs. Jsonnet/GCL - -GCL 是一种用 Python 实现的声明式配置语言,它提供了支持模板抽象的必要语言功能。然而 GCL 编译器本身是用Python编写的,且语言本身是解释执行的。对于大型模板实例(如 kubernetes 模型),性能较差。 - -Jsonnet 是一种用 C++ 实现的数据模板语言,适用于应用程序和工具开发人员,可以生成配置数据并通过代码组织、简化和管理大型配置,而不会产生副作用。 - -Jsonnet 和 GCL 非常擅长减少样板。它们都可以使用代码生成配置,就像工程师只需要编写高级 GPL 代码,而不是手动编写容易出错且难以理解的服务器二进制代码一样。Jsonnet 减少了 GCL 的一些复杂性,但在很大程度上属于同一类别。两者都有许多运行时错误,类型检查和约束能力不足。 - -### vs. HCL - -HCL 是一种 Go 实现的结构化配置语言。HCL 的原生语法受到 libucl 和 nginx 配置的启发。它用于创建一种对人类和机器友好的结构化配置语言,作为 [Terraform 语言](https://www.terraform.io/language)主要用于 DevOps工具、服务器配置和资源配置等。 - -HCL 的用户界面不能通过 Terraform 提供者 Schema 定义直接感知。此外,在编写复杂对象和必需/可选字段定义时,用户界面很麻烦。动态参数受变量的条件字段约束。资源本身的约束需要由提供程序模式定义,或者与 Sentinel/Rego 和其他策略语言相结合。语言本身的完整性不能自我封闭,其实现方法也不统一。 - -### vs. CUE - -CUE 可以通过结构、无继承和其他特性用作建模,当模型定义之间没有冲突时可以实现高度抽象。因为 CUE 在运行时执行所有约束检查,所以它在大规模配置建模场景中可能存在性能瓶颈。CUE 将类型和值组合为一个概念,并通过各种语法简化了约束的编写。例如,不需要泛型类型和枚举,求和类型和空值合并是一回事。CUE 支持配置合并,但它是完全幂等的。它可能无法满足复杂的多租户和多环境配置场景的要求。对于复杂的循环和约束场景,编写起来很复杂,编写需要精确配置修改或者 Patch 的场景也很麻烦。 - -对于 KCL,建模是通过 KCL Schema 进行的,通过语言级工程和一些面向对象的特性(如单一继承、Mixin 复用)可以实现高模型抽象。KCL 是一种静态编译语言,用于大规模建模场景是运行时开销较低 (性能更高,更低的内存消耗)。KCL 提供了更丰富的检查声明性约束语法,这使得配置和策略编写更加容易。对于一些配置字段组合约束,它更容易编写(与 CUE 相比,KCL 提供了更多的 if-guard 组合约束、all/any/map/filter 表达式和其他集合约束编写方法,这使得编写更容易)。 - -### vs. Dhall - -Dhall 是一种可编程配置语言,它组合了 JSON、函数、类型和 imports 导入等功能, 本身风格偏向函数式,如果您学过 Haskell 等函数式风格语言,可能会对它感到熟悉的。相比于 Dhall, KCL 也提供了类似功能的组合,提供给用户配置可编程和抽象的能力,不过 KCL 在建模、约束检查、自动化等方面做了更多的改进,同时能够通过包管理手段进行模型共享。此外,KCL 的语法语义更贴近于面向对象语言,在一定程度上会比纯函数式风格接受程度更高。 - -### vs. Nickel - -Nickel 是一种简单的配置语言。它的目的是自动生成静态配置文件,本质上是带有函数和类型的 JSON。 - -KCL 和 Nickel 都有类似的渐进式类型系统(静态+动态)、合并策略、函数和约束定义。不同之处在于 KCL 是一种类似 Python 的语言,而 Nickel 是一种类似 JSON 的语言。此外,KCL 提供了 schema 关键字来区分配置定义和配置数据,以避免混合使用。 - -### vs. Starlark - -Starlark 主要用作 Bazel 的配置语言并且是 Python 的一种方言。它没有类型,并且禁止递归。 - -KCL 一定程度上也可以看作 Python 的变种,但是它极大地增强了静态类型和配置扩展性相关的设计,并且是一个编译型语言,这与 Starlark 有着本质的不同。 - -### vs. Kustomize - -Kustomize 的核心功能是其文件级覆盖功能。但是它存在多个覆盖链的问题,因为找到特定属性值的语句不能保证它是最终值,因为其他地方出现的另一个特定值可以覆盖它。对于复杂的场景,Kustomsize 文件的继承链的检索通常不如 KCL 代码的继承链检索方便,需要仔细考虑指定的配置文件覆盖顺序。此外,Kustomize 无法解决 YAML 配置编写、约束验证、模型抽象和开发等问题,更适合于简单的配置场景。 - -在 KCL 中,配置合并操作可以对代码中的每个配置属性进行细粒度处理,合并策略可以灵活设置,而不限于整体资源,配置之间的依赖关系可以通过KCL的import语句进行静态分析。 - -### vs. Helm - -Helm 的概念源于操作系统的包管理机制。它是一个基于模板化 YAML 文件的包管理工具,支持包中资源的执行和管理。 - -KCL 自然提供了 Helm 功能的超集,因此您可以直接使用 KCL 作为替代。对于采用 Helm 的用户,KCL 中的堆栈编译结果可以打包并以 Helm 格式使用,通过 kpm 包管理工具进行分发复用。此外,我们还可以直接使用 Helm-KCL 插件直接对已有的 Helm Charts 进行无侵入的可编程扩展。 - -### vs. CDK - -用CDK的高级语言编写可以很好地集成到应用程序项目中,这实际上是客户端运行时的一部分。对于KCL,由KCL编写的外部配置和策略与客户端运行时分离。 - -通用语言通常远远超出了需要解决的问题,例如安全问腿、能力边界问题(启动本地线程、访问IO、网络、代码无限循环和其他安全风险)。例如,在音乐领域,有专门的音符来表达音乐,这便于学习和交流,它不能用一般语言表达清楚。 - -此外,由于通用语言风格多样,需要统一维护、管理和自动化。通用语言通常用于编写客户端运行时,它是服务器运行时的延续,不适合编写独立于运行时的配置,被编译成二进制文件,并最终从进程开始运行。此外,GPL 稳定性和可扩展性不易控制。然而,KCL 配置语言通常用于编写数据,将数据与简单逻辑相结合,它描述了预期的最终结果,然后由编译器或引擎使用,既具备丰富的编程抽象能力,又具备方便的数据处理方式。 - -### vs. OPA/Rego - -Rego 起源于逻辑编程,它基于 Datalog,是一种受限制的 Prolog 形式,而 KCL 基于静态类型结构,具备部分 OOP 特性。Rego 类型化特征结构的设计是为了解决 Prolog 在人类语言编码应用中的缺点,将 Datalog 变量用于编程本质上是约束验证任务,Datalog 是一种优秀的查询语言。但对于约束强制执行,它有点麻烦,因为实际上首先需要查询要应用约束的值才能进行校验。 - -此外,KCL 的方法更易于找到规范化、简化、面向人类易读,面向运行时性能优良的约束和校验表示,具备静态类型,并且它更适合于从 OpenAPI 生成或者创建 OpenAPI。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/automation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/automation.md deleted file mode 100644 index 83eb6446..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/automation.md +++ /dev/null @@ -1,205 +0,0 @@ ---- -title: "自动化" -sidebar_position: 6 ---- - -## 简介 - -在 KCL 中提供了很多自动化相关的能力,主要包括工具和多语言 API。 通过 `package_identifier : key_identifier`的模式支持对任意配置键值的索引,从而完成对任意键值的增删改查。比如下图所示修改某个应用配置的镜像内容,可以直接执行如下指令修改镜像,修改前后的 diff 如下图所示。 - -![](/img/blog/2022-09-15-declarative-config-overview/14-kcl-image-update.png) - -此外,KCL 的自动化能力也可以被集成到 CI/CD 中。 - -![](/img/blog/2022-09-15-declarative-config-overview/15-kcl-automation.png) - -## 使用 KCL 进行自动化 - -### 0. 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. 获得示例 - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/automation -``` - -我们可以执行如下命令显示配置 - -```bash -cat main.k -``` - -输出为 - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "app" - replicas = 1 - labels.key = "value" -} -``` - -我们可以执行如下命令输出配置 - -```bash -kcl main.k -``` - -输出为 - -```yaml -app: - name: app - replicas: 1 - labels: - app: app - key: value -``` - -### 2. 使用 KCL CLI 进行自动化 - -KCL 允许使用通过 CLI `-O|--overrides` 参数修改配置模型中的值,这个参数通常由三个部分组成: 包名 `pkg`, 配置标识符 `identifier`, 配置属性 `attribute` 和覆盖值 `override_value` - -```bash -kcl main.k -O override_spec -``` - -- `override_spec`: 表示需要修改的配置模型字段和值的统一表示 - -```bash -override_spec: [[pkgpath] ":"] identifier ("=" value | "-") -``` - -- `pkgpath`: 表示需要修改标识符的包路径,通常为 `a.b.c` 的形式,对于 main 包,`pkgpath` 表示为 `__main__`, 可省略,省略不写时表示 main 包 -- `identifier`: 表示需要修改配置的标识符,通常为 `a.b.c` 的形式 -- `value`: 表示需要修改配置的值,可以是任意合法的 KCL 表达式,比如数字/字符串字面值,`list`/`dict`/`schema` 表达式等 -- `=`: 表示修改identifier的值 -- `-`: 表示删除 identifier 属性 - -请注意,当 `identifier` 多次出现时,修改/删除全部 `identifier` 的值 - -#### 修改配置 - -执行如下命令可以更新应用名称: - -```bash -kcl main.k -O app.name='new_app' -``` - -输出为 - -```yaml -app: - name: new_app - replicas: 1 - labels: - app: new_app - key: value -``` - -可以看出 `app` 的 `name` 属性的值被修改为了 `new_app` - -此外,当我们使用 KCL CLI `-d` 参数时,KCL 文件将同时修改为以下内容 - -```bash -kcl main.k -O app.name='new_app' -d -``` - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "new_app" - replicas = 1 - labels: {key = "value"} -} -``` - -#### 删除配置 - -执行如下命令可以删除 `labels` 中的 `key` 字段 - -```bash -kcl main.k -O app.labels.key- -``` - -输出为: - -```yaml -app: - name: app - replicas: 1 - labels: - app: app -``` - -执行如下命令 - -```bash -kcl main.k -O config.x- -``` - -输出结果为: - -```yaml -config: - x: 1 - y: s -``` - -### 3. 使用 KCL API 进行自动化 - -此外,我们还可以通过[多语言 API](/docs/reference/xlang-api/overview) 自动修改配置属性 - -以 RestAPI 为例 - -执行如下命令启动 RestAPI 服务端 - -```bash -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -通过如下命令 POST 命令请求配置修改服务 - -```bash -curl -X POST http://127.0.0.1:2021/api:protorpc/KclvmService.OverrideFile -H 'content-type: accept/json' -d '{ - "file": "main.k", - "specs": ["app.name=\"nginx\""] -}' -``` - -服务调用完成后,`main.k` 会被修改为如下形式: - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "nginx" - replicas = 1 - labels: { - "key" = "value" - } -} -``` - -## 小结 - -该文档介绍了KCL的自动化功能,包括工具和多语言 API。它支持对任何配置的键值进行索引,允许添加、删除、修改和查询任何键值。它也可以集成到 CI/CD 中。本文档提供了一个使用 KCL 自动化配置管理的示例,包括使用 KCL CLI/API 覆盖和删除配置。更多信息请参阅[此处](/docs/reference/lang/tour#KCL-cli-variable-Override)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/index.md deleted file mode 100644 index c0613d42..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/index.md +++ /dev/null @@ -1 +0,0 @@ -# 用户手册 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/package-management/1-overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/package-management/1-overview.md deleted file mode 100644 index ce7b13cb..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/package-management/1-overview.md +++ /dev/null @@ -1,3 +0,0 @@ -# 简介 - -KCL 通过包管理工具 [kpm](https://github.com/kcl-lang/kpm) 对 KCL 包进行管理。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/package-management/2-installation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/package-management/2-installation.md deleted file mode 100644 index 7b0892a5..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/package-management/2-installation.md +++ /dev/null @@ -1,53 +0,0 @@ -# 安装 - -## 安装 `kpm` - -kpm 将调用 `KCL`编译器来编译 KCL 程序。在使用 `kpm` 之前,您需要确保 `KCL` 编译器已经成功安装,您可以参照[如何安装 KCL 编译器](https://kcl-lang.io/docs/user_docs/getting-started/install)。 - -### 使用 `go install` 安装 `kpm` - -您可以使用 go install 命令安装 kpm。 - -```shell -go install kcl-lang.io/kpm@latest -``` - -### 从 Github release 页面手动安装 `kpm` - -您可以从 [kpm Github Release](https://github.com/kcl-lang/kpm/releases) 中获取 `kpm` ,并将 `kpm` 的二进制文件路径设置到环境变量 PATH 中。 - -```shell -# KPM_INSTALLATION_PATH 是 `kpm` 二进制文件的所在目录. -export PATH=$KPM_INSTALLATION_PATH:$PATH -``` - -请使用以下命令以确保您成功安装了`kpm`。 - -```shell -kpm --help -``` - -如果你看到以下输出信息,那么你已经成功安装了`kpm`,可以继续执行下一步操作。 - -```shell -NAME: - kpm - kpm is a kcl package manager - -USAGE: - kpm [arguments]... - -COMMANDS: - init initialize new module in current directory - add add new dependency - pkg package a kcl package into tar - metadata output the resolved dependencies of a package - run compile kcl package. - login login to a registry - logout logout from a registry - push push kcl package to OCI registry. - pull pull kcl package from OCI registry. - help, h Shows a list of commands or help for one command - -GLOBAL OPTIONS: - --help, -h show help -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/package-management/3-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/package-management/3-quick-start.md deleted file mode 100644 index 455987c8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/package-management/3-quick-start.md +++ /dev/null @@ -1,108 +0,0 @@ -# 快速开始 - -## 1. 初始化一个空的 KCL 包 - -使用 `kpm init` 命令创建一个名为 `my_package` 的 kcl 程序包, 并且在我们创建完成一个名为 `my_package` 的包后,我们需要通过命令 `cd my_package` 进入这个包来进行后续的操作。 - -```shell -kpm init my_package && cd my_package -``` - -![kpm_init](/img/docs/user_docs/guides/package-management/gifs/kpm_init.gif) - -`kpm` 将会在执行`kpm init my_package`命令的目录下创建两个默认的配置文件 `kcl.mod` 和 `kcl.mod.lock`。 - -```shell -- my_package - |- kcl.mod - |- kcl.mod.lock - |- # 你可以直接在这个目录下写你的kcl程序。 -``` - -`kcl.mod.lock` 是 `kpm` 用来固定依赖版本的文件,是自动生成的,请不要人工修改这个文件。 - -`kpm` 将会为这个新包创建一个默认的 `kcl.mod`。如下所示: - -```shell -[package] -name = "my_package" -edition = "0.0.1" -version = "0.0.1" -``` - -## 2. 为 KCL 包添加依赖 - -然后,您可以通过 `kpm add` 命令来为您当前的库添加一个外部依赖。 - -如下面的命令所示,为当前包添加一个版本号为 `1.27.2` 并且名为 `k8s` 的依赖包。 - -```shell -kpm add k8s:1.27.2 -``` - -![kpm_add_k8s](/img/docs/user_docs/guides/package-management/gifs/kpm_add_k8s.gif) - -`kpm` 会为您将依赖添加到 kcl.mod 文件中. - -```shell -[package] -name = "my_package" -edition = "0.0.1" -version = "0.0.1" - -[dependencies] -k8s = "1.27.2" # The dependency 'k8s' with version '1.27.2' -``` - -## 编写一个程序使用包 `konfig` 中的内容 - -在当前包中创建 `main.k`。 - -```shell -- my_package - |- kcl.mod - |- kcl.mod.lock - |- main.k # Your KCL program. -``` - -并且将下面的内容写入 `main.k` 文件中。 - -```kcl -# 导入并使用外部依赖 `k8s` 包中的内容。 -import k8s.api.core.v1 as k8core - -k8core.Pod { - metadata.name = "web-app" - spec.containers = [{ - name = "main-container" - image = "nginx" - ports = [{containerPort = 80}] - }] -} - -``` - -## 3. 运行 KCL 代码 - -你可以使用 kpm 编译刚才编写的 `main.k` 文件, 得到编译后的结果。 - -```shell -kpm run -``` - -输出为 - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: web-app -spec: - containers: - - image: nginx - name: main-container - ports: - - containerPort: 80 -``` - -![kpm_run](/img/docs/user_docs/guides/package-management/gifs/kpm_run.gif) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/package-management/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/package-management/_category_.json deleted file mode 100644 index d1600bfd..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/package-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "包管理", - "position": 7 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md deleted file mode 100644 index 5ebfe83c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: "从 Kubernetes 迁移" -sidebar_position: 1 ---- - -## 简介 - -KCL 对 Kubernetes 配置提供了许多开箱即用的支持,通过 KCL 工具,我们可以将 Kubernetes Schema 和 配置集成到 KCL 中,本节内容将介绍如何使用 KCL 对 Kubernetes 进行集成 - -### 1. Kubernetes OpenAPI Spec - -从 Kubernetes 1.4 开始,引入了对 OpenAPI 规范(在捐赠给 Open API Initiative 之前称为 swagger 2.0)的 alpha 支持,API 描述遵循 [OpenAPI 规范 2.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md),从 Kubernetes 1.5 开始,Kubernetes 能够直接从[源码自动地提取模型并生成 OpenAPI 规范](https://github.com/kubernetes/kube-openapi),自动化地保证了规范和文档与操作/模型的更新完全同步。 - -此外,Kubernetes CRD 使用 [OpenAPI v3.0 validation](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation) 来描述(除内置属性 apiVersion、kind、metadata 之外的)自定义 schema,在 CR 的创建和更新阶段,APIServer 会使用这个 schema 对 CR 的内容进行校验。 - -### 2. KCL OpenAPI 支持 - -KCLOpenAPI 工具支持从 OpenAPI/CRD 定义提取并生成 KCL schema. 在 KCLOpenAPI Spec 中明确定义了 OpenAPI 规范与 KCL 语言之间的映射关系。 - -### 3. 从 Kubernetes 模型迁移到 KCL - -#### 3.1 基于 kusion_models 编写配置 - -我们为你提供了一个开箱即用的 `kusion_models` 包,让你可以快速开始。其中包含一个精心设计的前端模型,称为[服务器模型](https://github.com/KusionStack/konfig/blob/main/base/pkg/kusion_models/kube/frontend/server.k)(Server schema)。你可以通过初始化 `Server schema` 来声明其配置。有关模式及其属性的说明和用法,请参阅 [Server schema 文档](https://kusionstack.io/docs/reference/model/kusion_models/kube/frontend/doc_server)。 - -#### 3.2 创建自定义的 models 前端模型 - -现有的 `kusion_models` 模型可能无法满足你的特定业务需求,那么你也可以设计自定义前端模型包。 您可基于预先生成的 Kubernetes KCL 包自定义您的前端模型。您还可以仿照`kube2kcl` 工具的模式,开发自定义脚本,完成配置数据的迁移。 - -##### 3.2.1 获取 Kubernetes KCL 模型 - -我们提供了预生成的各版本[Kubernetes KCL模型](https://github.com/orgs/KusionStack/packages/container/package/k8s),您可以在项目下执行 `kpm add k8s:` 来获得它。有关 kpm 使用的详细信息,请参考 [kpm快速入门指南](https://github.com/kcl-lang/kpm#quick-start)。 - -或者,如果您需要自己生成这些包,请参考[从 Kubernetes OpenAPI 文件生成 KCL 包](https://github.com/kcl-lang/kcl-openapi/blob/main/docs/generate_from_k8s_spec.md)。 - -##### 3.2.2 编写自定义前端模型 - -由于 Kubernetes 内置模型较为原子化和复杂,我们推荐以 Kubernetes 原生模型作为后端输出的模型,对其进一步抽象,而向用户暴露一份更为友好和简单的前端模型界面,具体您可参照 Konfig 仓库中 [kusion_models Server](https://github.com/KusionStack/konfig/blob/main/base/pkg/kusion_models/kube/frontend/server.k) 模型的设计方式进行。 - -##### 3.2.3 迁移配置数据 - -对于存量的 Kubernetes 配置数据,您可以仿照 kube2Kcl 工具的做法,编写自定义的转换脚本,进行一键迁移。Kusion 后续将提供该脚本的编写脚手架和编写指南。 - -### 4. 从 Kubernetes CRD 迁移 - -如果您的项目中使用了 CRD,也可以采用类似的模式,生成 CRD 对应的 KCL schema,并基于该 schema 声明 CR。 - -- 从 CRD 生成 KCL Schema - - ``` - kcl-openapi generate model --crd --skip-validation -f your_crd.yaml - ``` - -- 使用 KCL 声明 CR - - 使用 KCL 声明 CR 的模式与声明 Kubernetes 内置模型配置的模式相同,在此不做赘述。 - -## 小结 - -本节介绍了如何使用 kcl-openapi 工具将 OpenAPI 规范映射到 KCL 语言特性,此外提供了将 KCL 与 OpenAPI 和 Kubernetes CRD 一起使用的快速入门指南帮助从 Kubernetes 进行迁移或集成。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md deleted file mode 100644 index e674c946..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md +++ /dev/null @@ -1,249 +0,0 @@ ---- -title: "使用 KCL 生成并管理 Kubernetes 资源配置" -sidebar_position: 2 ---- - -## 简介 - -当我们管理 Kubernetes 资源清单时,我们常常会手写维护,或者使用 Helm 和 Kustomize 等工具来维护我们 YAML 配置或者配置模版,然后通过 kubectl 和 helm 命令行等工具将资源下发到集群。但是作为一个 "YAML 工程师" 每天维护 YAML 配置无疑是琐碎且无聊的,并且容易出错。 - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: ... # Omit -spec: - selector: - matchlabels: - cell: RZ00A - replicas: 2 - template: - metadata: ... # Omit - spec: - tolerations: - - effect: NoSchedules - key: is-over-quota - operator: Equal - value: 'true' - containers: - - name: test-app - image: images.example/app:v1 # Wrong ident - resources: - limits: - cpu: 2 # Wrong type. The type of cpu should be str - memory: 4Gi - # Field missing: ephemeral-storage - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: is-over-quota - operator: In - values: - - 'true' -``` - -- YAML 中的结构化数据是无类型的,缺乏验证方法,无法立即检查所有数据的有效性 -- YAML 编程能力欠佳,容易写出不正确的缩进,也没有逻辑判断等常见代码组织方式,容易写出大量重复配置,难以维护 -- Kubernetes 设计是复杂的,用户很难理解所有细节,比如上面配置中的 `toleration` 和 `affinity` 字段,如果用户不理解调度逻辑,它可能被错误地省略掉或者多余的添加 - -因此,KCL 期望在 Kubernetes YAML 资源管理解决如下问题: - -- 用**生产级高性能编程语言**以**编写代码**的方式提升配置的灵活度,比如条件语句、循环、函数、包管理等特性提升配置重用的能力 -- 在代码层面提升**配置语义验证**的能力,比如字段可选/必选、类型、范围等配置检查能力 -- 提供**配置分块编写、组合和抽象的能力**,比如结构定义、结构继承、约束定义等能力 - -## 先决条件 - -首先可以在 [KCL 快速开始](/docs/user_docs/getting-started/kcl-quick-start) 根据指导下载并安装 KCL,然后准备一个 [Kubernetes](https://kubernetes.io/) 环境 - -## 快速开始 - -### 1. 生成 Kubernetes 资源 - -我们可以编写如下 KCL 代码并命名为 main.k ,KCL 受 Python 启发,基础语法十分接近 Python, 比较容易学习和上手, 配置模式写法很简单,`k [: T] = v`, 其中 `k` 表示配置的属性名称; `v` 表示配置的属性值; `: T` 表示一个可选的类型注解。 - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -上述 KCL 代码中我们分别声明了一个 Kubernetes Deployment 资源的 `apiVersion`、`kind`、`metadata` 和 `spec` 等变量,并分别赋值了相应的内容,特别地,我们将 `metadata.labels` 字段分别重用在 `spec.selector.matchLabels` 和 `spec.template.metadata.labels` 字段。可以看出,相比于 YAML,KCL 定义的数据结构更加紧凑,而且可以通过定义局部变量实现配置重用。 - -我们可以执行如下命令行得到一个 Kubernetes YAML 文件 - -```bash -kcl main.k -``` - -输出为: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -当然我们可以将 KCL 工具与 kubectl 等工具结合使用,让我们执行如下命令并看看效果 - -```shell -kcl main.k | kubectl apply -f - -``` - -输出为 - -```shell -deployment.apps/nginx-deployment configured -``` - -可以从命令行的结果看出与我们使用直接使用 YAML 配置和 kubectl apply 的一个 Deployment 体验完全一致 - -通过 kubectl 检查部署状态 - -```shell -kubectl get deploy -``` - -输出为 - -```shell -NAME READY UP-TO-DATE AVAILABLE AGE -nginx-deployment 3/3 3 3 15s -``` - -### 2. 编写代码管理 Kubernetes 资源 - -对于 Kubernetes 资源发布时,我们常常会遇到配置参数需要动态指定的场景,比如不同的环境需要设置不同的 `image` 字段值生成不同环境的资源。对于这种场景,我们可以通过 KCL 的条件语句和 `option` 函数动态地接收外部参数。我们可以在上述例子的基础上根据不同的环境调整配置参数,比如对于如下代码,我们编写了一个条件语句并输入一个名为 `env` 的动态参数 - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" if option("env") == "prod" else "${metadata.name}:latest" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -使用 KCL 命令行 `-D` 标记接收一个外部设置的动态参数: - -```bash -kcl main.k -D env=prod -``` - -输出为: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -上述代码片段中的 `image = metadata.name + ":1.14.2" if option("env") == "prod" else metadata.name + ":latest"` 意思为:当动态参数 `env` 的值被设置为 `prod` 时,image 字段值为 `nginx:1.14.2`, 否则为 `nginx:latest`,因此我们可以根据需要为 env 设置为不同的值获得不同内容的 Kubernetes 资源。 - -并且 KCL 支持将 option 函数动态参数维护在配置文件中,比如编写下面展示的 `kcl.yaml` 文件 - -```yaml -kcl_options: - - key: env - value: prod -``` - -使用如下命令行也可以得到同样的 YAML 输出,以简化 KCL 动态参数的输入过程 - -```bash -kcl main.k -Y kcl.yaml -``` - -输出为: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## 小结 - -KCL 可以用于生成和管理 Kubernetes 资源,解决管理 YAML 配置的局限性,例如缺乏验证方法和较弱的编程能力等,并可以通过条件语句和 option 函数动态接收外部参数,从而能够根据不同的环境调整配置参数。此外,KCL 可以与 kubectl 等其他工具一起使用将配置一键生效到集群。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md deleted file mode 100644 index 5fe97d05..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: "Kubectl KCL 插件" -sidebar_position: 1 ---- - -## 简介 - -[Kubectl](https://kubernetes.io/docs/reference/kubectl/) is a command line tool for communicating with a Kubernetes cluster's control plane, using the Kubernetes API. You can use the `Kubectl-KCL-Plugin` to - -- Edit the YAML configuration in a hook way to separate data and logic for the Kubernetes manifests management. -- For multi-environment and multi-tenant scenarios, you can maintain these configurations gracefully rather than simply copy and paste. -- Validate all KRM resources using the KCL schema. - -## 前置条件 - -- Install [Kubectl](https://github.com/kubernetes/kubectl) -- Install [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) - -## 快速开始 - -Let’s write a KCL function which add annotation `managed-by=krm-kcl` only to `Deployment` resources in the helm chart. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/kubectl-kcl.git/ -cd ./kubectl-kcl/examples/ -``` - -### 2. Test and Run - -Run the KCL code via the `Kubectl KCL Plugin`. - -```bash -kubectl kcl run -f ./kcl-run.yaml -``` - -The output yaml is - -```yaml -apiVersion: config.kubernetes.io/v1 -kind: ResourceList -items: - - apiVersion: apps/v1 - kind: Deployment - metadata: - annotations: - managed-by: krm-kcl - labels: - app: nginx - name: nginx-deployment - spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - image: "nginx:1.14.2" - name: nginx - ports: - - containerPort: 80 - - apiVersion: v1 - kind: Service - metadata: - name: test - spec: - ports: - - port: 80 - protocol: TCP - targetPort: 9376 - selector: - app: MyApp -functionConfig: - # kcl-fn-config.yaml - apiVersion: krm.kcl.dev/v1alpha1 - kind: KCLRun - metadata: - # EDIT THE SOURCE! - # This should be your KCL code which preloads the `ResourceList` to `option("resource_list") - spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "krm-kcl"}} for resource in option("resource_list").items] -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md deleted file mode 100644 index 271f08e8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: "Helm KCL 插件" -sidebar_position: 2 ---- - -## 简介 - -[Helm](https://github.com/helm/helm) 是一个管理 Charts 的工具。Charts 是预配置的 Kubernetes 资源的包。您可以使用 `Helm-KCL-Plugin` 来完成以下操作: - -- 以 hook 的方式编辑 Helm charts,将数据和逻辑分离以便更好地管理 Kubernetes manifests -- 对于多环境和多租户方案,可以优雅地维护这些配置,而不仅仅是简单地复制和粘贴 -- 使用 KCL 模式验证所有 KRM 资源 - -## 先决条件 - -- 安装 [Helm](https://github.com/helm/helm) -- 安装 [Helm KCL 插件](https://github.com/kcl-lang/helm-kcl) - -## 快速开始 - -让我们编写一个仅向 `Deployment` 资源添加 annotation `managed-by=helm-kcl-plugin` 的 KCL 函数 - -### 1. 获取示例 - -```bash -git clone https://github.com/kcl-lang/helm-kcl.git/ -cd ./helm-kcl/examples/workload-charts-with-kcl -``` - -### 2. 测试和运行 - -通过 `Helm KCL Plugin` 运行KCL代码。 - -```bash -helm kcl template --file ./kcl-run.yaml -``` - -输出的YAML为 - -```yaml -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: workload - app.kubernetes.io/version: 0.1.0 - helm.sh/chart: workload-0.1.0 - name: workload -spec: - ports: - - name: www - port: 80 - protocol: TCP - targetPort: 80 - selector: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - type: ClusterIP ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: workload - app.kubernetes.io/version: 0.1.0 - helm.sh/chart: workload-0.1.0 - name: workload - annotations: - managed-by: helm-kcl-plugin -spec: - selector: - matchLabels: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - template: - metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - spec: - containers: - - image: nginx:alpine - name: frontend -``` - -## KCL 开发指南 - -以下是您可以在 KCL 代码中执行的操作: - -- 从 `option("resource_list")` 读取资源。`option("resource_list")` 符合 [KRM 函数规范](https://kpt.dev/book/05-developing-functions/01-functions-specification)。 你可以从 `option("resource_list")["items"]` 读取输入资源,并从 `option("resource_list")["functionConfig"]` 读取 `functionConfig`。 -- 返回输出资源的 KPM 列表。 -- 使用 `assert {condition},{error_message}` 返回错误消息。 - -## 更多文档和示例 - -- [Helm KCL 插件](https://github.com/kcl-lang/helm-kcl) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md deleted file mode 100644 index 4f1c8c56..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -title: "Kustomize KCL 插件" -sidebar_position: 3 ---- - -## 简介 - -[Kustomize](https://github.com/kubernetes-sigs/kustomize) 允许自定义用于多种目的原始的、无模板的 YAML 文件,同时保留原始 YAML 不变和可用。 - -KCL 可用于创建函数,以改变和/或验证 Kubernetes 资源模型(KRM)的 YAML 输入/输出格式,并且我们提供 Kustomize KCL 函数来简化函数编写过程。 - -## 先决条件 - -- 安装 [kustomize](https://github.com/kubernetes-sigs/kustomize) - -## 快速开始 - -让我们编写一个仅向 Deployment 资源添加 annotation `managed-by=kustomize-kcl` 的 KCL 函数 - -### 1. 获取示例 - -```bash -git clone https://github.com/kcl-lang/kustomize-kcl.git -cd ./kustomize-kcl/examples/set-annotation/ -``` - -### 2. 测试和运行 - -```bash -kustomize fn run ./local-resource/ --dry-run -``` - -输出的YAML为 - -```yaml -apiVersion: krm.kcl.dev/v1alpha1 -kind: KCLRun -metadata: - name: set-annotation - annotations: - config.kubernetes.io/function: | - container: - image: docker.io/kcllang/kustomize-kcl:v0.2.0 - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml -# EDIT THE SOURCE! -# This should be your KCL code which preloads the `ResourceList` to `option("resource_list") -spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "kustomize-kcl"}} for resource in option("resource_list").items] ---- -apiVersion: v1 -kind: Service -metadata: - name: test - annotations: - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml -spec: - selector: - app: MyApp - ports: - - protocol: TCP - port: 80 - targetPort: 9376 ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx - annotations: - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml - managed-by: kustomize-kcl -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## KCL 开发指南 - -以下是可以使用 KCL 执行的操作: - -- 从 `option("resource_list")` 读取资源。`option("resource_list")` 符合 [KRM 函数规范](https://kpt.dev/book/05-developing-functions/01-functions-specification)。 你可以从 `option("resource_list")["items"]` 读取输入资源,并从 `option("resource_list")["functionConfig"]` 读取 `functionConfig`。 -- 返回输出资源的 KPM 列表。 -- 使用 `assert {condition},{error_message}` 返回错误消息。 - -## 更多文档和示例 - -- [Kustomize KCL 插件](https://github.com/kcl-lang/kustomize-kcl) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-konfig/1-overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-konfig/1-overview.md deleted file mode 100644 index b112e946..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-konfig/1-overview.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -id: overview -sidebar_label: 概述 ---- - -# Konfig 概述 - -在 KCL 中推荐通过**配置库**的方式统一管理所有的配置清单和模型库,即不仅存放抽象模型本身的 KCL 定义,还存放各种类型的配置清单,比如应用的运维配置、策略配置等。配置大库推荐托管在各类 VCS 系统中,以方便做配置的回滚和漂移检查。配置大库的最佳实践代号为 Konfig,仓库托管在 [Github](https://github.com/KusionStack/konfig)。 - -⚡️ 配置大库主要包括: - -- KCL 模块声明文件(kcl.mod) -- KCL 领域模型库 (Kubernetes, Prometheus 等) -- 各类配置清单目录 (应用运维配置等) -- 配置构建和测试脚本 (Makefile,Github CI 文件等) - -之所以用一个统一的仓库管理全部的 KCL 配置代码,是由于不同代码包的研发主体不同,会引发出包管理和版本管理的问题。将业务配置代码、基础配置代码在一个统一仓库中,代码间的版本依赖管理会比较简单,通过定位唯一代码库的目录及文件即可,可以将配置代码统一管理,便于查找、修改、维护。 - -下面是配置大库(Konfig)的架构图: - -![](/img/docs/user_docs/guides/konfig/konfig-arch.png) - -Konfig 提供给用户开箱即用、高度抽象的配置界面,模型库最初朴素的出发点就是改善 YAML 用户的效率和体验,我们希望通过将代码更繁杂的模型抽象封装到统一的模型中,从而简化用户侧配置代码的编写。Konfig 由以下部分组成: - -- **核心模型**: - - **前端模型**:前端模型即「用户界面」,包含平台侧暴露给用户的所有可配置属性,其中省略了一些重复的、可推导的配置,抽象出必要属性暴露给用户,具有用户友好的特性,比如 server.k。 - - **后端模型**:后端模型是「模型实现」,是让前端模型属性生效的模型,主要包含前端模型实例的渲染逻辑,后端模型中可借助 KCL 编写校验和逻辑判断等以提高配置代码复用性和健壮性,对用户不感知,比如 server_backend.k -- **领域模型**:是不包含任何实现逻辑和抽象的模型,往往由工具转换生成,无需修改,和真正生效的 YAML 属性一一对应,底层模型需要经过进一步抽象,一般不直接被用户使用。比如,kusion_kubernetes 是 Kubernetes 场景的底层模型库。 - -此外,核心模型内部通过前端模型和后端模型两层抽象简化前端用户的配置代码,底层模型则是通过 KCL OpenAPI 工具自动生成。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-konfig/2-structure.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-konfig/2-structure.md deleted file mode 100644 index cc54087e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-konfig/2-structure.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -id: structure -sidebar_label: 工程结构 ---- - -# Konfig 工程结构 - -本文主要解释 Konfig 配置大库的目录和代码结构 - -## 整体结构 - -```bash -. -├── .github # CI 脚本 -├── Makefile # 通过 Makefile 封装常用命令 -├── README.md # 配置大库说明 -├── appops # 应用运维目录,用来放置所有应用的 KCL 运维配置 -│ ├── clickhouse-operator -│ ├── code-city -│ ├── guestbook -│ ├── http-echo -│ └── nginx-example -├── base # 模型库 -│ ├── examples # 样例代码 -│ │ ├── monitoring # 监控配置样例 -│ │ ├── native # Kubernetes 资源配置样例 -│ │ ├── provider # 基础资源配置样例 -│ │ └── server # 云原生应用运维配置模型样例 -│ └── pkg -│ ├── kusion_kubernetes # Kubernetes 底层模型库 -│ ├── kusion_models # 核心模型库 -│ ├── kusion_prometheus # Prometheus 底层模型库 -│ └── kusion_provider # 基础资源 底层模型库 -└── kcl.mod # 大库配置文件,通常用来标识大库根目录位置以及大库所需依赖 -``` - -## 核心模型库结构 - -核心模型库一般命名为 kusion_models,主要包含前端模型、后端模型、Mixin、渲染器等,目录结构为: - -```bash -├── commons # 基础资源核心模型库 -├── kube # 云原生资源核心模型库 -│ ├── backend # 后端模型 -│ ├── frontend # 前端模型 -│ │ ├── common # 通用前端模型 -│ │ ├── configmap # ConfigMap 前端模型 -│ │ ├── container # 容器前端模型 -│ │ ├── ingress # Ingress 前端模型 -│ │ ├── resource # 资源规格前端模型 -│ │ ├── secret # Secret 前端模型 -│ │ ├── service # Service 前端模型 -│ │ ├── sidecar # Sidecar 容器前端模型 -│ │ ├── strategy # 策略前端模型 -│ │ ├── volume # Volume 前端模型 -│ │ └── server.k # 云原生应用运维前端模型 -│ ├── metadata # 应用运维的元数据模型 -│ ├── mixins # 统一放置可复用的 Mixin -│ ├── render # 渲染器,把前后端模型联系在一起的桥梁 -│ ├── templates # 静态配置 -│ └── utils # 工具方法 -└── metadata # 通用元数据模型 -``` - -## Project 和 Stack 结构 - -![](/img/docs/user_docs/concepts/project-stack.png) - -Project 和 Stack 是用于组织 Konfig 的逻辑隔离概念。 - -### Project - -任何包含文件 "project.yaml" 的文件夹都将被视为一个 Project,"project.yaml" 用于描述此 Project 的元数据,如 "name" 和 "tenant" 等。项目必须具有明确的业务语义,用户可以将应用程序或运维场景映射到项目。 - -### Stack - -与Project一样,包含文件 "stack.yaml" 的任何文件夹都将被视为一个 Stack,"stack.yaml" 用于描述此 Stack 的元数据。Stack 是一组 KCL 文件,表示可以单独配置和部署的最小操作单元,它通常代表 CI/CD 过程中的不同阶段。 - -### Project 与 Stack 之间的关系 - -一个 Project 包含一个或多个 Stack,Stack 必须属于且只能属于一个 Project。用户可以根据自己的需要解释 Project 和 Stack 的含义,并灵活组织 Konfig 结构。根据我们的经验,我们提供以下示例作为最佳实践: - -```bash -├── README.md # Project 介绍文件 -├── base # 各环境通用配置 -│ └── base.k # 通用 KCL 配置 -├── dev # 环境特有配置 -│ ├── ci-test # 测试目录 -│ │ ├── settings.yaml # 测试数据 -│ │ └── stdout.golden.yaml # 测试期望结果 -│ ├── kcl.yaml # 多文件编译配置,是 KCL 编译的入口 -│ ├── main.k # 当前环境 KCL 配置 -│ └── stack.yaml # Stack 配置文件 -└── project.yaml # Project 配置文件 -``` - -Project 通常表示一个应用程序,Stack 表示该应用程序的不同环境的配置,例如 dev、pre 和 prod 等。通用配置可以存储在该 Project 下的 "base" 目录中。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-konfig/3-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-konfig/3-quick-start.md deleted file mode 100644 index 92c9849d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-konfig/3-quick-start.md +++ /dev/null @@ -1,198 +0,0 @@ ---- -id: guide -sidebar_label: 快速开始 ---- - -# 简介 - -本篇指南向你展示,如何使用 KCL 语言与其相对应的 CLI 工具,完成一个运行在 Kubernetes 中的 Long-Running 应用的部署,我们将组织配置的单位叫做应用(Application),描述应用部署和运维细节的配置集合叫做应用服务(Server),它本质上是通过 KCL 定义的运维模型。 - -要将一个运行在 Kubernetes 中的应用完全部署起来,一般需要下发多个 Kubernetes 资源,本次演示的样例涉及以下 Kubernetes 资源: - -- 命名空间(Namespace) -- 无状态工作负载(Deployment) -- 服务(Service) - -> 不清楚相关概念的,可以前往 Kubernetes 官方网站,查看相关说明: - -- [Learn Kubernetes Basics](https://kubernetes.io/docs/tutorials/kubernetes-basics/) -- [Namespace](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/) -- [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) -- [Service](https://kubernetes.io/docs/concepts/services-networking/service/) - -## 准备工作 - -在开始之前,我们需要做以下准备工作: - -1. 安装 KCL, 详情信息请参阅[下载和安装](/docs/user_docs/getting-started/install)。 - -2. 下载开源 Konfig 大库,仓库地址: [https://github.com/KusionStack/konfig.git](https://github.com/KusionStack/konfig.git) - -```shell -git clone https://github.com/KusionStack/konfig.git && cd konfig -``` - -## 快速开始 - -### 1. 配置编译 - -Konfig 的编程语言是 KCL,不是 Kubernetes 认识的 JSON/YAML,因此还需要编译得到最终输出。 - -进入到项目的 Stack 目录(`appops/nginx-example/dev`)并执行编译: - -```bash -cd appops/nginx-example/dev && kcl -Y kcl.yaml -D __konfig_output_format__=raw -``` - -可以获得如下 YAML 输出: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-exampledev - namespace: nginx-example -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - template: - metadata: - labels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - spec: - containers: - - image: nginx:1.7.8 - name: main - ports: - - containerPort: 80 - protocol: TCP - resources: - limits: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi - requests: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi ---- -apiVersion: v1 -kind: Namespace -metadata: - name: nginx-example ---- -apiVersion: v1 -kind: Service -metadata: - name: nginx-example - namespace: nginx-example -spec: - ports: - - nodePort: 30201 - port: 80 - targetPort: 80 - selector: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - type: NodePort -``` - -完成编译,可以看到 3 个资源: - -- 一个 name 为 nginx-exampledev 的 Deployment -- 一个 name 为 nginx-example 的 Namespace -- 一个 name 为 nginx-example 的 Service - -以上就完成了配置生效,后续可以使用 `kubectl apply` 等命令下发并检查资源的实际状态,本文不在赘述。 - -### 2. 配置修改 - -Server 模型中的 image 属性用于声明应用的业务容器镜像,我们可以修改 base/main.k 中的 image 的值进行镜像修改或升级: - -```diff -14c14 -< image = "nginx:1.7.8" ---- -> image = "nginx:latest" -``` - -重新编译配置代码可以获得修改后的 YAML 输出: - -```shell -kcl -Y kcl.yaml -D __konfig_output_format__=raw -``` - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-exampledev - namespace: nginx-example -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - template: - metadata: - labels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - spec: - containers: - - image: nginx:latest - name: main - ports: - - containerPort: 80 - protocol: TCP - resources: - limits: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi - requests: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi ---- -apiVersion: v1 -kind: Namespace -metadata: - name: nginx-example ---- -apiVersion: v1 -kind: Service -metadata: - name: nginx-example - namespace: nginx-example -spec: - ports: - - nodePort: 30201 - port: 80 - targetPort: 80 - selector: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - type: NodePort -``` - -## 小结 - -本文主要介绍了如何使用 KCL 语言与其相对应的 Konfig 库,完成一个运行在 Kubernetes 中的 Long-Running 应用的部署。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/support/faq-install.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/support/faq-install.md deleted file mode 100644 index 1c98f224..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/support/faq-install.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -sidebar_position: 5 ---- - -# 安装问题 - -## MacOS 提示无法打开 "kcl",因为 Apple 无法检查其是否包含恶意软件 - -MacOS 提示无法打开 "kcl",因为 Apple 无法检查其是否包含恶意软件。这个错误是因为 macOS 操作系统中的 Gatekeeper 安全功能阻止了应用程序的运行。要解决此问题,请按照以下步骤操作: - -打开"系统偏好设置"并点击"安全性与隐私"。 在"通用"选项卡中,您将看到一个消息:"kcl" 已被阻止。单击"仍要打开"。 或者,你可以单击"打开任何方式"以打开你的应用程序。(可能需要使用管理员权限来打开应用程序。) - -如果不想在每次打开应用程序时都执行这些步骤,则可以的应用程序添加到白名单中,以便在不受阻止的情况下运行。要将您的应用程序添加到白名单中,请执行以下操作: - -打开终端并输入以下命令: - -```shell -xattr -rd com.apple.quarantine /path/to/kcl -``` - -其中,/path/to/kcl 是 kcl 应用程序的完整路径。运行命令后,应用程序将被添加到白名单中,Gatekeeper 将不再阻止其运行。 - -## 在 Windows/Linux/MacOS 平台上抱 program not found 或者 run linker failed 错误 - -请确保如下依赖在您的 PATH 中 - -- MacOS: `clang` -- Linux: `gcc` -- Windows: `cl.exe` (可以通过安装 MSVC 获得) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/support/faq-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/support/faq-kcl.md deleted file mode 100644 index 8330dfd6..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/support/faq-kcl.md +++ /dev/null @@ -1,2355 +0,0 @@ ---- -sidebar_position: 2 ---- - -# KCL 语法 - -## 1. 如何用 KCL 写一个简单的 key-value 对配置 - -创建一个名为 `config.k` 的文件 - -```python -cpu = 256 -memory = 512 -image = "nginx:1.14.2" -service = "my-service" -``` - -上述 KCL 代码中,定义了 4 个变量 `cpu` 和 `memory` 被声明为整数类型,并且它们的值分别为 `256` 和 `512`,而 `image` 和 `service` 是字符串类型,它们的值分别为 `image` 和 `service` - -使用如下命令可以将上述 KCL 文件编译为 YAML 进行输出 - -``` -kcl config.k -``` - -得到的 YAML 输出为: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -如果想要输出到文件,可以使用 `-o|--output` 参数: - -``` -kcl config.k -o config.yaml -``` - -## 2. KCL 中有哪些基本的数据类型? - -KCL 目前的基本数值类型和值包含: - -- 整数类型 `int` - - 举例: 十进制正整数 `1`, 十进制负整数 `-1`, 十六进制整数 `0x10`, 八进制整数 `0o10`, 二进制整数 `0b10` -- 浮点数类型 `float` - - 举例: 正浮点数 `1.10`, `1.0`, 负浮点数 `-35.59`, `-90.`, 科学记数法浮点数 `32.3e+18`, `70.2E-12` -- 布尔类型 `bool` - - 举例: 真值 `True`, 假值 `False` -- 字符串类型 `str` - 使用引号 `'`, `"` 标记 - - 举例: 双引号字符串 `"string"`, `"""string"""`, 单引号字符串 `'string'`, `'''string'''` -- 列表类型 `list` - 使用 `[`, `]` 标记 - - 举例: 空列表 `[]`, 字符串列表 `["string1", "string2", "string3"]` -- 字典类型 `dict` - 使用 `{`, `}` 标记 - - 举例: 空字典 `{}`, 键值均为字符串类型的字典 `{"key1": "value1", "key2": "value2"}` -- 结构类型 `schema` - 使用关键字 `schema` 定义,并使用相应的 schema 名称进行实例化 -- 空值类型 `None` - 用于表示一个变量的值为空,与输出 YAML 的 `null` 值对应 -- 未定义值类型 `Undefined` - 用于表示一个变量未被赋值,值为 `Undefined` 的变量不会被输出到 YAML 中 - -```python -schema Person: - name: str - age: int - -alice = Person { - name = "Alice" - age = 18 -} -bob = Person { - name = "Bob" - age = 10 -} -``` - -注意: 所有 KCL 类型的变量均可赋值为空值 `None` 和未定义的值 `Undefined` - -## 3. 有些 KCL 变量名带 `_` 下划线前缀表示什么?和不带 `_` 下划线前缀的区别是什么?分别适合什么场景下使用? - -KCL 中带下划线前缀的变量表示一个**隐藏**的,**可变**的变量,**隐藏**表示带下划线前缀的变量不会被输出到 YAML 当中,包括包级别的下划线前缀变量和 schema 当中的下划线前缀变量。**可变**表示带下划线前缀的变量可被多次重复赋值,不带下划线前缀的变量被赋值后不可变。 - -带 `_` 下划线前缀的变量与不带 `_` 下划线前缀变量的区别是: 不带 `_` 下划线前缀变量默认是导出到 YAML 当中的,并且具有强不可变性;带 `_` 下划线前缀变量是不导出的,可变的。 - -```python -name = 'Foo' # 导出变量,不可变变量 -name = 'Bar' # 错误:导出变量只能设置一次 -``` - -```python -_name = 'Foo' # 隐藏变量,可变变量 -_name = 'Bar' - -schema Person: - _name: str # hidden and mutable -``` - -## 4. 如何向 dict 中添加元素? - -可以使用 union 运算符 `|`, 或者 dict 解包运算符 `**` 来向 dict 中添加一个元素,并且可以使用 `in`,`not in` 等关键字判断 dict 变量当中是否包含某一个键值 - -```python -_left = {key: {key1 = "value1"}, intKey = 1} # 注意使用 = 表示覆盖 -_right = {key: {key2 = "value2"}, intKey = 2} -dataUnion = _left | _right # {"key": {"key1": "value1", "key2": "value2"}, "intKey": 2} -dataUnpack = {**_left, **_right} # {"key": {"key1": "value1", "key2": "value2"}, "intKey": 2} -``` - -输出 YAML 为: - -```yaml -dataUnion: - key: - key1: value1 - key2: value2 - intKey: 2 -dataUnpack: - key: - key1: value1 - key2: value2 - intKey: 2 -``` - -此外还可以使用 `字符串插值` 或者字符串 `format` 成员函数特性向 kcl dict 添加变量键值对 - -```python -dictKey1 = "key1" -dictKey2 = "key2" -data = { - "${dictKey1}" = "value1" - "{}".format(dictKey2) = "value2" -} -``` - -输出 YAML 为: - -```yaml -dictKey1: key1 -dictKey2: key2 -data: - key1: value1 - key2: value2 -``` - -## 5. 如何修改 dict 中的元素? - -我们可以使用 union 运算符 `|`, 或者解包运算符 `**` 修改 dict 当中的元素 - -```python -_data = {key = "value"} # {"key": "value"} -_data = _data | {key = "override_value1"} # {"key": "override_value1"} -_data = {**_data, **{key = "override_value2"}} # {"key": "override_value2"} -``` - -如果想要删除 dict 中某个键为 `key` 的值,可以使用解包运算符 `**{key = Undefined}` 或者合并运算符 `| {key = Undefined}` 进行覆盖,覆盖后 key 的值为 Undefined,不会进行 YAML 输出。 - -## 6. 如何向 list 中添加元素? - -在 list 中添加元素有两种方式: - -- 使用 `+`, `+=` 和 slice 切片连接组装 list 变量达到向 list 中添加元素的目的 - -```python -_args = ["a", "b", "c"] -_args += ["end"] # 在list尾部添加元素"end", ["a", "b", "c", "end"] -_args = _args[:2] + ["x"] + _args[2:] # 在list索引为2的地方插入元素"x", ["a", "b", "x", "c", "end"] -_args = ["start"] + _args # 在list头部添加元素"start", ["start", "a", "b", "x", "c", "end"] -``` - -- 使用 `*` 解包运算符连接合并 list - -```python -_args = ["a", "b", "c"] -_args = [*_args, "end"] # 在list尾部添加元素"end", ["a", "b", "c", "end"] -_args = ["start", *_args] # 在list头部添加元素"start", ["start", "a", "b", "c", "end"] -``` - -注意:当接连的变量为 `None/Undefined` 时,使用 `+` 可能会发生错误,这时使用 list 解包运算符 `*` 或者使用 `or` 运算符取 list 的默认值可以避免空值判断 - -```python -data1 = [1, 2, 3] -data2 = None -data3 = [*data1, *data2] # Right [1, 2, 3] -data4 = data1 + data2 or [] # Right [1, 2, 3], 使用 or 取 data2 的默认值为 [], 当 data2 为 None/Undefined 时,取空列表 [] 进行计算 -data5 = data1 + data2 # Error: can only concatenate list (not "NoneType") to list -``` - -## 7. 如何修改/删除 list 中的元素? - -修改 list 中的元素分为两种方式: - -- 直接修改 list 某个索引处的值,使用 slice 切片 - -```python -_index = 1 -_args = ["a", "b", "c"] -_args = _args[:index] + ["x"] + _args[index+1:] # 修改list索引为1的元素为"x", ["a", "x", "c"] -``` - -- 根据某个条件修改 list 当中的元素,使用 list comprehension 列表推导式 - -```python -_args = ["a", "b", "c"] -_args = ["x" if a == "b" else a for a in _args] # 将list当中值为"b"的值都修改为"x", ["a", "x", "c"] -``` - -删除 list 中的元素分为两种方式: - -- 使用 list for 推导表达式中 if 过滤条件 -- 使用 filter 表达式对 list 进行元素过滤 - -比如想要删除一个列表 `[1, 2, 3, 4, 5]` 中大于 2 的数字,则在 KCL 中可以写为: - -```python -originList = [1, 2, 3, 4, 5] -oneWayDeleteListItem = [item for item in originList if item <= 2] -anotherWayDeleteListItem = filter item in originList { - item <= 2 -} -``` - -输出如下结果 - -```yaml -originList: - - 1 - - 2 - - 3 - - 4 - - 5 -oneWayDeleteListItem: - - 1 - - 2 -anotherWayDeleteListItem: - - 1 - - 2 -``` - -## 8. 怎样写 for 循环?怎样理解和使用 list comprehension 列表推导式 和 dict comprehension 字典推导式 ? - -KCL 目前仅支持函数式/声明式的推导式 for 循环方式,可以按照如下方式遍历 dict 和 list 变量: - -list 推导式具体形式为(其中推导式两边使用方括号 `[]`): - -```txt -[expression for expr in sequence1 - if condition1 - for expr2 in sequence2 - if condition2 - for expr3 in sequence3 ... - if condition3 - for exprN in sequenceN - if conditionN] -``` - -dict 推导式具体形式为(其中推导式两边使用花括号 `{}`): - -```txt -{expression for expr in sequence1 - if condition1 - for expr2 in sequence2 - if condition2 - for expr3 in sequence3 ... - if condition3 - for exprN in sequenceN - if conditionN} -``` - -上述推导式中的 `if` 表示过滤条件,满足条件的表达式 `expr` 才会生成到新的 list 或 dict 中 - -list 推导式举例: - -```python -_listData = [1, 2, 3, 4, 5, 6] -_listData = [l * 2 for l in _listData] # _listData中所有元素都乘以2,[2, 4, 6, 8, 10, 12] -_listData = [l for l in _listData if l % 4 == 0] # 筛选出_listData中可以被4整除的所有元素,[4, 8, 12] -_listData = [l + 100 if l % 8 == 0 else l for l in _listData] # 遍历_listData, 当其中的元素可以被8整除时,将该元素加100,否则保持不变, [4, 108, 12] -``` - -注意上述代码中第 3 行和第 4 行两个 `if` 的区别: - -- 第一个 `if` 表示 list 变量 `_listData` 本身的推导式过滤条件,后不能跟 `else`,满足该过滤条件的元素会继续放在该列表中,不满足条件的元素被剔除,有可能会使列表长度发生变化 -- 第二个 `if` 表示 list 迭代变量 `l` 的选择条件,表示 `if-else` 三元表达式,后必须跟 `else`,不论是否满足该条件,产生的元素仍然在该列表中,列表长度不变 - -dict 推导式举例: - -```python -_dictData = {key1 = "value1", key2 = "value2"} -_dictData = {k = _dictData[k] for k in _dictData if k == "key1" and _dictData[k] == "value1"} # 将_dictData中key为"key1", value为"value1"的元素筛选出来, {"key1": "value1"} -``` - -使用推导式获得 dict 所有 key: - -```python -dictData = {key1 = "value1", key2 = "value2"} -dictDataKeys = [k for k in _dictData] # ["key1", "key2"] -``` - -使用推导式对 dict 按照 key 的字典序升序进行排序: - -```python -dictData = {key3 = "value3", key2 = "value2", key1 = "value1"} # {'key3': 'value3', 'key2': 'value2', 'key1': 'value1'} -dictSortedData = {k = dictData[k] for k in sorted(dictData)} # {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'} -``` - -多级推导式举例: - -```python -array1 = [1, 2, 3] -array2 = [4, 5, 6] -data = [a1 + a2 for a1 in array1 for a2 in array2] # [5, 6, 7, 6, 7, 8, 7, 8, 9] len(data) == len(array1) * len(array2) -``` - -双变量循环(for 推导表达式支持 list 的索引迭代以及 dict 的 value 迭代,可以简化 list/dict 迭代过程代码书写): - -- list - -```python -data = [1000, 2000, 3000] -# 单变量循环 -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# 双变量循环 -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# 使用_忽略循环变量 -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -- dict - -```python -data = {key1 = "value1", key2 = "value2"} -# 单变量循环 -dataKeys1 = [k for k in data] # ["key1", "key2"] -dataValues1 = [data[k] for k in data] # ["value1", "value2"] -# 双变量循环 -dataKeys2 = [k for k, v in data] # ["key1", "key2"] -dataValues2 = [v for k, v in data] # ["value1", "value2"] -dataFilter = {k = v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# 使用_忽略循环变量 -dataKeys3 = [k for k, _ in data] # ["key1", "key2"] -dataValues3 = [v for _, v in data] # ["value1", "value2"] -``` - -## 9. 怎样写 if 条件语句? - -KCL 支持两种方式书写 if 条件语句: - -- if-elif-else 块语句,其中 elif 和 else 块均可省略,并且 elif 块可以使用多次 - -```python -success = True -_result = "failed" -if success: - _result = "success" -``` - -```python -success = True -if success: - _result = "success" -else: - _result = "failed" -``` - -```python -_result = 0 -if condition == "one": - _result = 1 -elif condition == "two": - _result = 2 -elif condition == "three": - _result = 3 -else: - _result = 4 -``` - -- 条件表达式 ` if else `, 类似于 C 语言当中的 ` ? : ` 三元表达式 - -```python -success = True -_result = "success" if success else "failed" -``` - -注意:在书写 if-elif-else 块语句时注意书写 if 条件后的冒号 `:` 以及保持缩进的统一 - -除此之外,还可以在 list 或者 dict 结构中直接书写条件表达式(不同的是,在结构中书写的 if 表达式中需要书写的值而不是语句): - -- list - -```python -env = "prod" -data = [ - "env_value" - ":" - if env == "prod": - "prod" # 书写需要添加到 data 中的值,而不是语句 - else: - "other_prod" -] # ["env_value", ":", "prod"] -``` - -- dict - -```python -env = "prod" -config = { - if env == "prod": - MY_PROD_ENV = "prod_value" # 书写需要添加到 config 中的键-值对,而不是语句 - else: - OTHER_ENV = "other_value" -} # {"MY_PROD_ENV": "prod_value"} -``` - -## 10. 怎样表达 "与" "或" "非" 等逻辑运算? - -在 KCL 中,使用 `and` 表示"逻辑与", 使用 `or` 表示"逻辑或", 使用 `not` 表示"非", 与 C 语言当中的 `&&`, `||` 和 `~` 语义一致; - -```python -done = True -col == 0 -if done and (col == 0 or col == 3): - ok = 1 -``` - -对于整数的"按位与", "按位或"和"按位异或",在 KCL 中使用 `&`, `|` 和 `^` 运算符表示, 与 C 语言当中的 `&`, `|` 和 `^` 语义一致; - -```python -value = 0x22 -bitmask = 0x0f - -assert (value & bitmask) == 0x02 -assert (value & ~bitmask) == 0x20 -assert (value | bitmask) == 0x2f -assert (value ^ bitmask) == 0x2d -``` - -"逻辑或" `or` 的妙用:当需要书写诸如 `A if A else B` 类似的模式时,可以使用 `A or B` 进行简化,比如如下代码: - -```python -value = [0] -default = [1] -x0 = value if value else default -x1 = value or default # 使用 value or default 代替 value if value else default -``` - -## 11. 如何判断变量是否为 None/Undefined、字符串/dict/list 是否为空? - -请注意,在 if 表达式的条件判断中,`False`、`None`、`Undefined`、数字 `0`、空列表 `[]`、空字典 `{}` 和空字符串 `""`, `''`, `""""""`, `''''''` 都被视为值为 `假` 的表达式。 - -比如判断一个字符串变量 `strData` 既不为 `None/Undefined` 也不为空字符串时(字符串长度大于 0),就可以简单的使用如下表达式: - -```python -strData = "value" -if strData: - isEmptyStr = False -``` - -空字典和空列表判断举例: - -```python -_emptyList = [] -_emptyDict = {} -isEmptyList = False if _emptyList else True -isEmptyDict = False if _emptyDict else True -``` - -YAML 输出为: - -```yaml -isEmptyList: true -isEmptyDict: true -``` - -或者使用布尔函数 `bool` 进行判断 - -```python -_emptyList = [] -_emptyDict = {} -isEmptyList = bool(_emptyList) -isEmptyDict = bool(_emptyDict) -``` - -## 12. 字符串怎样拼接、怎样格式化字符串、怎样检查字符串前缀、后缀?怎样替换字符串内容? - -- KCL 中可以使用 `+` 运算符连接两个字符串 - -```python -data1 = "string1" + "string2" # "string1string2" -data2 = "string1" + " " + "string2" # "string1 string2" -``` - -- KCL 中目前存在两种格式化字符串的方式: - - 字符串变量的 format 方法 `"{}".format()` - - 字符串插值 `${}` - -```python -hello = "hello" -a = "{} world".format(hello) -b = "${hello} world" -``` - -注意,如果想在 `"{}".format()` 中单独使用 `{` 字符或者 `}`, 则需要使用 `{{` 和 `}}` 分别对 `{` 和 `}` 进行转义,比如转义一个 JSON 字符串如下代码: - -```python -data = "value" -jsonData = '{{"key": "{}"}}'.format(data) -``` - -输出 YAML 为: - -```yaml -data: value -jsonData: '{"key": "value"}' -``` - -注意,如果想在 `${}` 插值字符串中单独使用 `$` 字符,则需要使用 `$$` 对 `$` 进行转义 - -```python -world = "world" -a = "hello {}".format(world) # "hello world" -b = "hello ${world}" # "hello world" -c = "$$hello ${world}$$" # "$hello world$" -c2 = "$" + "hello ${world}" + "$" # "$hello world$" -``` - -输出 YAML 为: - -```yaml -world: world -a: hello world -b: hello world -c: $hello world$ -c2: $hello world$ -``` - -- KCL 中使用字符串的 `startswith` 和 `endswith` 方法检查字符串的前缀和后缀 - -```python -data = "length" -isEndsWith = data.endswith("th") # True -isStartsWith = "length".startswith('len') # True -``` - -- KCL 中使用字符串的 replace 方法或者 regex.replace 函数替换字符串的内容 - -```python -import regex -data1 = "length".replace("len", "xxx") # 使用"xxx"替换"len", "xxxgth" -data2 = regex.replace("abc123", r"\D", "0") # 替换"abc123"中的所有非数字为"0", "000123" -``` - -其中,`r"\D"` 表示不需要使用 `\\` 转义 `\D` 中的反斜杠 `\`,多用于正则表达式字符串中 - -此外,我们可以在字符串格式化表达式中插入索引占位符或者关键字占位符用于格式化多个字符串 - -- 索引占位符 - -```python -x = '{2} {1} {0}'.format('directions', 'the', 'Read') -y = '{0} {0} {0}'.format('string') -``` - -输出为: - -```yaml -x: Read the directions -y: string string string -``` - -- 关键字占位符 - -```python -x = 'a: {a}, b: {b}, c: {c}'.format(a = 1, b = 'Two', c = 12.3) -``` - -输出为: - -```yaml -x: "a: 1, b: Two, c: 12.3" -``` - -## 13. 字符串中使用单引号和双引号的区别是什么? - -KCL 单引号和双引号字符串几乎没有区别。唯一的区别是,不需要在单引号字符串中使用 `\"` 转义双引号 `"`,不需要在双引号字符串中使用 `\'` 转义单引号引号 `'`。 - -```python -singleQuotedString = 'This is my book named "foo"' # Don’t need to escape double quotes in single quoted strings. -doubleQuotedString = "This is my book named 'foo'" # Don’t need to escape single quotes in double quoted strings. -``` - -此外在 KCL 中,使用三个单引号或者三个双引号组成的长字符串,无需在其中对单引号或者三引号进行转义 (除字符串首尾),比如如下例子: - -```python -longStrWithQuote0 = """Double quotes in long strings "(not at the beginning and end)""" -longStrWithQuote1 = '''Double quotes in long strings "(not at the beginning and end)''' -longStrWithQuote2 = """Single quotes in long strings '(not at the beginning and end)""" -longStrWithQuote3 = '''Single quotes in long strings '(not at the beginning and end)''' -``` - -输出 YAML: - -```yaml -longStrWithQuote0: Double quotes in long strings "(not at the beginning and end) -longStrWithQuote1: Double quotes in long strings "(not at the beginning and end) -longStrWithQuote2: Single quotes in long strings '(not at the beginning and end) -longStrWithQuote3: Single quotes in long strings '(not at the beginning and end) -``` - -## 14. 如何编写跨行的长字符串? - -KCL 中可以使用单引号字符串 + 换行符 `\n` 或者三引号字符串书写一个多行字符串,并且可以借助续行符 `\` 优化 KCL 字符串的形式,比如对于如下代码中的三个多行字符串变量,它们的制是相同的: - -```python -string1 = "The first line\nThe second line\nThe third line\n" -string2 = """The first line -The second line -The third line -""" -string3 = """\ -The first line -The second line -The third line -""" # 推荐使用 string3 长字符串的书写形式 -``` - -输出 YAML 为: - -```yaml -string1: | - The first line - The second line - The third line -string2: | - The first line - The second line - The third line -string3: | - The first line - The second line - The third line -``` - -## 15. 如何使用正则表达式? - -通过在 KCL 中导入正则表达式库 `import regex` 即可使用正则表达式,其中包含了如下函数: - -- **match**: 正则表达式匹配函数,根据正则表达式对输入字符串进行匹配,返回 bool 类型表示是否匹配成功 -- **split**: 正则表达式分割函数,根据正则表达式分割字符串,返回分割字串的列表 -- **replace**: 正则表达式替换函数,替换字符串中所有满足正则表达式的子串,返回被替换的字符串 -- **compile**: 正则表达式编译函数,返回 bool 类型表示是否是一个合法的正则表达式 -- **search**: 正则表达式搜索函数,搜索所有满足正则表达式的子串,返回子串的列表 - -使用举例: - -```python -import regex - -regex_source = "Apple,Google,Baidu,Xiaomi" -regex_split = regex.split(regex_source, ",") -regex_replace = regex.replace(regex_source, ",", "|") -regex_compile = regex.compile("$^") -regex_search = regex.search("aaaa", "a") -regex_find_all = regex.findall("aaaa", "a") -regex_result = regex.match("192.168.0.1", "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$") # 判断是否是一个IP字符串 -regex_result_false = regex.match("192.168.0,1", "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$") # 判断是否是一个IP字符串 -``` - -输出 YAML: - -```yaml -regex_source: Apple,Google,Baidu,Xiaomi -regex_split: - - Apple - - Google - - Baidu - - Xiaomi -regex_replace: Apple|Google|Baidu|Xiaomi -regex_compile: true -regex_search: true -regex_find_all: - - a - - a - - a - - a -regex_result: true -regex_result_false: false -``` - -对于比较长的正则表达式,还可以使用 r-string 忽略 `\` 符号的转义简化正则表达式字符串的书写: - -```python -import regex - -isIp = regex.match("192.168.0.1", r"^(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)$") # 判断是否是一个IP字符串 -``` - -更多举例: - -```python -import regex - -schema Resource: - cpu: str = "1" - memory: str = "1024Mi" - disk: str = "10Gi" - check: - regex.match(cpu, r"^([+-]?[0-9.]+)([m]*[-+]?[0-9]*)$"), "cpu must match specific regular expression" - regex.match(memory, r"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"), "memory must match specific regular expression" - regex.match(disk, r"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"), "disk must match specific regular expression" -``` - -```python -import regex - -schema Env: - name: str - value?: str - check: - len(name) <= 63, "a valid env name must be no more than 63 characters" - regex.match(name, r"[A-Za-z_][A-Za-z0-9_]*"), "a valid env name must start with alphabetic character or '_', followed by a string of alphanumeric characters or '_'" -``` - -## 16. KCL 当中的 schema 是什么含义? - -schema 是 KCL 中一种语言元素,用于定义配置数据的类型,像 C 语言中的 struct 或者 Java 中的 class 一样,在其中可以定义属性,每种属性具有相应的类型。 - -## 17. 如何声明 schema? - -KCL 中使用 schema 关键字可以定义一个结构,在其中可以申明 schema 的各个属性 - -```python -# 一个Person结构,其中具有属性字符串类型的firstName, 字符串类型的lastName, 整数类型的age -schema Person: - firstName: str - lastName: str - # age属性的默认值为0 - age: int = 0 -``` - -一个复杂例子: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels: {str:str} -``` - -在上面的代码中,`cpu` 和 `memory` 被定义为整数 int 类型;`name`,`image` 和 `service` 是字符串 str 类型; `command` 是字符串类型的列表; labels 是字典类型,其键类型和值类型均为字符串。 - -## 18. 如何为 schema 属性添加 "不可变"、"必选" 约束? - -KCL 中使用 `?` 运算符定义一个 schema 的"可选"约束,schema 属性默认都是"必选"的 - -```python -# 一个Person结构,其中具有属性字符串类型的firstName, 字符串类型的lastName, 整数类型的age -schema Person: - firstName?: str # firstName是一个可选属性,可以赋值为None/Undefined - lastName?: str # age是一个可选属性,可以赋值为None/Undefined - # age属性的默认值为0 - age: int = 18 # age是一个必选属性,不能赋值为None/Undefined,并且是一个不可变属性 - age = 10 # Error, age是一个不可变的属性 -``` - -## 19. 如何为 schema 中的属性编写校验规则? - -在 schema 定义当中可以使用 check 关键字编写 schema 属性的校验规则, 如下所示,check 代码块中的每一行都对应一个条件表达式,当满足条件时校验成功,当不满足条件时校验失败。条件表达式后可跟 `, "check error message"` 表示当校验失败时需要显示的信息 - -```python -import regex - -schema Sample: - foo: str # Required, 不能为None/Undefined, 且类型必须为str - bar: int # Required, 不能为None/Undefined, 且类型必须为int - fooList: [int] # Required, 不能为None/Undefined, 且类型必须为int列表 - color: "Red" | "Yellow" | "Blue" # Required, 字面值联合类型,且必须为"Red", "Yellow", "Blue"中的一个,枚举作用 - id?: int # Optional,可以留空,类型必须为int - - check: - bar >= 0 # bar必须大于等于0 - bar < 100 # bar必须小于100 - len(fooList) > 0 # fooList不能为None/Undefined,并且长度必须大于0 - len(fooList) < 100 # fooList不能为None/Undefined,并且长度必须小于100 - regex.match(foo, "^The.*Foo$") # regex 正则表达式匹配 - bar in range(100) # range, bar范围只能为1到99 - bar in [2, 4, 6, 8] # enum, bar只能取2, 4, 6, 8 - bar % 2 == 0 # bar必须为2的倍数 - all foo in fooList { - foo > 1 - } # fooList中的所有元素必须大于1 - any foo in fooList { - foo > 10 - } # fooList中至少有一个元素必须大于10 - abs(id) > 10 if id # check if 表达式,当 id 不为空时,id的绝对值必须大于10 -``` - -此外,上述 check 当中比较表达式还可以简写为: - -```python -0 <= bar < 100 -0 < len(fooList) < 100 -``` - -综上所述,KCL Schema 中支持的校验类型为: - -| 校验类型 | 使用方法 | -| -------- | ---------------------------------------------------------- | -| 范围校验 | 使用 `<`, `>` 等比较运算符 | -| 正则校验 | 使用 `regex` 系统库中的 `match` 等方法 | -| 长度校验 | 使用 `len` 内置函数,可以求 `list/dict/str` 类型的变量长度 | -| 枚举校验 | 使用字面值联合类型 | -| 非空校验 | 使用 schema 的可选/必选属性 | -| 条件校验 | 使用 check if 条件表达式 | - -## 20. 如何为 schema 及其属性添加文档注释? - -一个完整的 schema 属性注释使用三引号字符串表示,其中的结构如下所示: - -```python -schema Person: - """The schema person definition - - Attributes - ---------- - name : str - The name of the person - age : int - The age of the person - - See Also - -------- - Son: - Sub-schema Son of the schema Person. - - Examples - -------- - person = Person { - name = "Alice" - age = 18 - } - """ - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -``` - -## 21. 如何基于 schema 编写配置?多个配置之间如何复用公共的配置? - -在 schema 实例化的过程中可以使用解包运算符 `**` 对公共的配置进行展开 - -```python -schema Boy: - name: str - age: int - hc: int - -schema Girl: - name: str - age: int - hc: int - -config = { - age = 18 - hc = 10 -} - -boy = Boy { - **config - name = "Bob" -} -girl = Girl { - **config - name = "Alice" -} -``` - -输出 YAML 为: - -```yaml -config: - age: 18 - hc: 10 -boy: - name: Bob - age: 18 - hc: 10 -girl: - name: Alice - age: 18 - hc: 10 -``` - -## 22. 基于 schema 编写配置时如何覆盖 schema 属性的默认值? - -在定义 schema 后,可以使用 schema 名称实例化相应的配置,使用 `:` 运算符对 schema 默认值进行 union, 使用 `=` 对 schema 默认值进行覆盖。对于 int/float/bool/str 类型的 schema 属性,union 和覆盖的效果相同; 对于 list/dict/schema 类型的 schema 属性,union 和覆盖的效果不同; - -```python -schema Meta: - labels: {str:str} = {"key1" = "value1"} - annotations: {str:str} = {"key1" = "value1"} - -meta = Meta { - labels: {"key2": "value2"} - annotations = {"key2" = "value2"} -} -``` - -输出 YAML 为: - -```yaml -meta: - labels: - key1: value1 - key2: value2 - annotations: - key2: value2 -``` - -## 23. 如何通过继承来复用 schema 定义? - -可以在 schema 定义处声明 schema 需要继承的 schema 名称: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 - -# An employee **is** a person, and has some additional information. -schema Employee(Person): - bankCard: int - nationality: str - -employee = Employee { - firstName = "Bob" - lastName = "Green" - age = 18 - bankCard = 123456 - nationality = "China" -} -``` - -输出 YAML 为: - -```yaml -employee: - firstName: Bob - lastName: Green - age: 18 - bankCard: 123456 - nationality: China -``` - -注意: KCL 只允许 schema 单继承 - -## 24. 如何通过组合复用 schema 逻辑? - -可以使用 KCL schema mixin 复用 schema 逻辑,mixin 一般被用于 schema 内部属性的分离数据,和数据映射等功能,可以使 KCL 代码更具模块化和声明性。注意不同的 mixin 之间的混入属性不建议定义依赖关系,会使得 mixin 使用方式复杂,一般一个 mixin 中作不超过三个属性混入即可。 - -```python -schema Person: - mixin [FullNameMixin, UpperMixin] - - firstName: str - lastName: str - fullName: str - upper: str - -schema FullNameMixin: - fullName = "{} {}".format(firstName, lastName) - -schema UpperMixin: - upper = fullName.upper() - -person = Person { - firstName = "John" - lastName = "Doe" -} -``` - -输出 YAML 为: - -```yaml -person: - firstName: John - lastName: Doe - fullName: John Doe - upper: JOHN DOE -``` - -## 25. 如何导入其他 KCL 文件? - -通过 import 关键字可以导入其他 KCL 文件,KCL 配置文件被组织为模块。单个 KCL 文件被视为一个模块,目录被视为一个包,作为一个特殊的模块。import 关键字支持相对路径导入和绝对路径导入两种方式 - -比如对于如下目录结构: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ │── service1.k - │ └── service2.k - └── mixin - └── mixin1.k -``` - -对于 `main.k`, 相对路径导入和绝对路径导入分别可以表示为: - -```python -import service # 绝对路径导入, 根目录为kcl.mod所在的路径 -import mixin # 绝对路径导入, 根目录为kcl.mod所在的路径 - -import .model1 # 相对路径导入, 当前目录模块 -import ..service # 相对路径导入, 父目录 -import ...root # 相对路径导入, 父目录的父目录 -``` - -注意,对于 KCL 的入口文件 `main.k`, 其不能导入自身所在的文件夹,否则会发生循环导入错误: - -```python -import model # Error: recursively loading -``` - -## 26. 什么情况下可以省略 import ? - -除了 main 包当中的同一文件夹下的 KCL 可以相互引用而不需通过 import 相互引用,比如对于如下目录结构: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ │── service1.k - │ └── service2.k - └── mixin - └── mixin1.k -``` - -当 main.k 作为 KCL 命令行入口文件时, model 文件夹中的 main.k, model1.k 和 model2.k 中的变量不能相互引用,需要通过 import 导入,但是 service 文件夹中的 service1.k 和 service2.k 当中的变量可以互相引用,忽略 import - -service1.k - -```python -schema BaseService: - name: str - namespace: str -``` - -service2.k - -```python -schema Service(BaseService): - id: str -``` - -## 27. 有一行代码太长了,如何在语法正确的情况下优雅地换行? - -在 KCL 中可以使用续行符 `\` 进行换行, 并且在字符串中也可以使用 `\` 表示续行 - -长字符串连接续行举例: - -```python -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " -``` - -推导表达式续行举例: - -```python -data = [1, 2, 3, 4] -dataNew = [ - d + 2 \ - for d in data \ - if d % 2 == 0 -] -``` - -if 表达式续行举例: - -```python -condition = 1 -data1 = 1 \ - if condition \ - else 2 -data2 = 2 \ -if condition \ -else 1 -``` - -三引号字符串内部续行举例: - -```python -longString = """\ -The first line\ -The continue second line\ -""" -``` - -注意: 使用续行符 `\` 的同时缩进的保持, 如下所示: - -错误用例: - -```python -data1 = [ - 1, 2, - 3, 4 \ -] # Error, 需要保持右方括号]的缩进 - -data2 = [ - 1, 2, - 3, 4 -] # Error, 需要数字1和3的缩进统一 -``` - -正确用例: - -```python -data1 = [ - 1, 2, - 3, 4 -] # Right, 带缩进的列表定义 - -data2 = [ \ - 1, 2, \ - 3, 4 \ -] # Right, 使用续行符的列表定义, 实际效果是单行列表 - -data3 = [ \ - 1, 2, \ - 3, 4 \ -] # Right, 使用续行符的列表定义, 无需保持缩进, 实际效果是单行列表 -``` - -## 28. \*_, _ 这些符号是什么意思? - -- `**`, `*` 出现在 dict/list 外部时分别表示乘方运算符和乘法运算符 - -```python -data1 = 2 ** 4 # 2的4次方等于16 -data2 = 2 * 3 # 2乘以3等于6 -``` - -- `**`, `*` 出现在 dict/list 内部时表示解包运算符,经常用于 list/dict 的解包和合并, 与 Python 当中的解包运算符用法相同 - -dict 的解包: - -```python -data = {"key1" = "value1"} -dataUnpack = {**data, "key2" = "value2"} # 将data解包合并入dataUnpack中, {"key1": "value1", "key2": "value2"} -``` - -list 的解包: - -```python -data = [1, 2, 3] -dataUnpack = [*data, 4, 5, 6] # 将data解包合并入dataUnpack中, [1, 2, 3, 4, 5, 6] -``` - -## 29. 如何取 list/dict/schema 的子元素 - -在 KCL 中可以使用 select 表达式或者 subscript 表达式取 list/dict/schema 的子元素 - -- 对于 list 类型,可以使用 `[]` 取列表中的某一个元素或者某一些元素 - -```python -data = [1, 2, 3] # 定义一个整数类型的数组 -theFirstItem = data[0] # 取数组中索引为0的元素,即第一个元素 1 -theSecondItem = data[1] # 取数组中索引为1的元素,即第一个元素 2 -``` - -注意:索引的取值不能超出列表的长度,否则会发生错误,可以使用 `len` 函数获得数组的长度 - -```python -data = [1, 2, 3] -dataLength = len(data) # 数组长度为3 -item = data[3] # 发生数组索引越界错误 -``` - -此外,还可以使用负数索引倒序获得列表中的元素 - -```python -data = [1, 2, 3] -item1 = data[-1] # 取数组中索引为-1的元素,即最后一个元素 3 -item2 = data[-2] # 取数组中索引为-2的元素,即倒数第二个元素 2 -``` - -综上,列表索引的取值范围为 `[-len, len - 1]` - -当想要取得列表的一部分时,可以在 `[]` 中使用切片表达式,其具体语法为 `[<列表开始索引>:<列表终止索引>:<列表遍历步长>]`,注意索引开始终止的取值区间为 `左闭右开[<列表开始索引>, <列表终止索引>)`,注意三个参数均可省略不写 - -```python -data = [1, 2, 3, 4, 5] -dataSlice0 = data[1:2] # 取列表中索引开始为 1, 终止索引为 2 的元素集合 [2] -dataSlice1 = data[1:3] # 取列表中索引开始为 1, 终止索引为 3 的元素集合 [2, 3] -dataSlice2 = data[1:] # 取列表中索引开始为 1, 终止索引为 最后一个索引 的元素集合 [2, 3, 4, 5] -dataSlice3 = data[:3] # 取列表中索引开始为 第一个索引, 终止索引为 3 的元素集合 [1, 2, 3] -dataSlice4 = data[::2] # 取列表中索引开始为 第一个索引, 终止索引为 最后一个索引 的元素集合(步长为2) [1, 3, 5] -dataSlice5 = data[::-1] # 反转一个列表,[5, 4, 3, 2, 1] -dataSlice6 = data[2:1] # 当开始,终止,步长三个参数组合不满足条件时返回空列表 [] - -``` - -- 对于 dict/schema 类型,可以使用 `[]` 和 `.` 两种方式取 dict/schema 中的子元素 - -```python -data = {key1: "value1", key2: "value2"} -data1 = data["key1"] # "value1" -data2 = data.key1 # "value1" -data3 = data["key2"] # "value2" -data4 = data.key2 # "value2" -``` - -```python -schema Person: - name: str = "Alice" - age: int = 18 - -person = Person {} -name1 = person.name # "Alice" -name2 = person["name"] # "Alice" -age1 = person.age # 18 -age2 = person.age # 18 -``` - -当键值在 dict 中不存在时,返回未定义值 `Undefined` - -```python -data = {key1 = "value1", key2 = "value2"} -data1 = data["not_exist_key"] # Undefined -data2 = data.not_exist_key # Undefined -``` - -可以使用 `in` 关键字判断某个键值是否在 dict/schema 中存在 - -```python -data = {key1 = "value1", key2 = "value2"} -exist1 = "key1" in data # True -exist2 = "not_exist_key" in data # False -``` - -当键值中存在 `.` 时或者需要运行时取一个键值变量对应的值时,只能使用 `[]` 方式,如无特殊情况,使用 `.` 即可: - -```python -name = "key1" -data = {key1 = "value1", key2 = "value2", "contains.dot" = "value3"} -data1 = data[name] # "value1" -data2 = data["contains.dot"] # "value3" -# 注意这样子是不对的 data3 = data.contains.dot -``` - -注意:上述取子元素的运算符不能对非 list/dict/schema 集合类型的值进行操作,比如整数,空值等。 - -```python -data = 1 -data1 = 1[0] # error -``` - -```python -data = None -data1 = None[0] # error -``` - -在取集合类型的子元素时往往要进行非空或者长度判断: - -```python -data = [] -item = data[0] if data else None -``` - -可以使用非空判断符 `?` 添加在 `[]`, `.` 的前面表示进行 if 非空判断,当不满足条件时返回 None,比如上述代码可以简化为: - -```python -data = [] -item1 = data?[0] # 当data为空时,返回空值 None -item2 = data?[0] or 1 # 当data为空时,返回空值 None, 如果不想返回 None, 还可与 or 运算符连用返回其他默认值 -``` - -使用 `?` 可以进行递归调用, 避免复杂繁琐的非空判断 - -```python -data = {key1.key2.key3 = []} -item = data?.key1?.key2?.key3?[0] -``` - -## 30. 如何在 KCL 代码中判断变量的类型 - -KCL typeof built-in 函数可以在该函数执行时立即返回一个变量的类型(字符串表示)用于类型断言 - -用法举例: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person{} -t3 = typeof(_x1) - -_x2 = pkg.Person{} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# 输出 -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -## 31. 关键字和 KCL 变量名冲突了可以怎么解决? - -对于与关键字冲突的标识符,可以在标识符前添加 `$` 前缀用于定义一个关键字标识符,比如如下代码中使用了 `if`, `else` 等关键字作为标识符并且可以得到相应的 YAML 输出 - -```python -$if = 1 -$else = "s" - -schema Data: - $filter: str = "filter" - -data = Data {} -``` - -输出 YAML: - -```yaml -data: - filter: filter -if: 1 -else: s -``` - -注意:在非关键字标识符前添加 `$` 前缀的效果与不添加相同 - -```python -_a = 1 -$_a = 2 # 等效于 `_a = 2` -``` - -## 32. KCL 的内置类型是 KCL 的关键字吗?是否可用于变量的定义 - -KCL 的内置类型包括 `int`, `float`, `bool` 和 `str` 四种类型,它们不是 KCL 的关键字,可用于变量的定义,比如如下代码: - -```py -int = 1 -str = 2 -``` - -输出 YAML 为: - -```yaml -int: 1 -str: 2 -``` - -注意:如无特殊需求,不建议变量的名称取这些内置类型,因为在有些语言当中,它们作为关键字存在 - -## 33. 如何在 KCL 中实现类似 Enum 枚举的功能 - -有两种方式可以在 KCL 中实现 Enum 枚举的方式 - -- (推荐)使用**字面值类型**的**联合类型** - -```python -schema Person: - name: str - gender: "Male" | "Female" - -person = Person { - name = "Alice" - gender = "Male" # gender 只能为 "Male" 或者 "Female" -} -``` - -一个复杂例子 - -```python -schema Config: - colors: ["Red" | "Yellow" | "Blue"] # colors 是一个枚举数组 - -config = Config { - colors = [ - "Red" - "Blue" - ] -} -``` - -- 使用 schema 的 check 表达式 - -```python -schema Person: - name: str - gender: "Male" | "Female" - - check: - gender in ["Male", "Female"] - -person = Person { - name = "Alice" - gender = "Male" # gender 只能为 "Male" 或者 "Female" -} -``` - -## 34. 如何求字典 dict 的长度 - -在 KCL 中可以使用 `len` 内置函数直接求 dict 的长度 - -```python -len1 = len({k1: "v1"}) # 1 -len2 = len({k1: "v1", k2: "v2"}) # 2 -varDict = {k1 = 1, k2 = 2, k3 = 3} -len3 = len(varDict) # 3 -``` - -此外,使用 `len` 函数还可以求 `str` 和 `list` 类型长度 - -```python -len1 = len("hello") # 5 -len2 = len([1, 2, 3]) # 3 -``` - -## 35. 如何在 KCL 中编写带条件的配置 - -在 KCL 中,除了支持在顶级的语句中书写 `if-elif-else` 条件表达式以外,还支持在 KCL 复杂结构(list/dict/schema)中书写条件表达式,支持带条件的配置书写。 - -```python -x = 1 -# List 结构中的 if 条件语句 -dataList = [ - if x == 1: 1 -] -# Dict 结构中的 if 条件语句 -dataDict = { - if x == 1: key1 = "value1" # 可以同一行书写 - elif x == 2: - key2 = "value2" # 可以跨行书写 -} -# Schema 结构中的 if 条件语句 -schema Config: - id?: int -env = "prod" -dataSchema = Config { - if env == "prod": - id = 1 - elif env == "pre": - id = 2 - elif env == "test": - id = 3 -} -``` - -## 36. KCL 中的 == 运算符会作深度比较嘛? - -KCL 中的 `==` 运算符 - -- 对于基本类型 `int`, `float`, `bool`, `str` 的变量是直接比较它们的值是否相等 -- 对于复合类型 `list`, `dict`, `schema` 的变量会深度递归地比较其中的子元素是否相等 - - `list` 类型深度递归递归比较每个索引的值以及长度 - - `dict`/`schema` 类型深度递归比较每个属性的值(与属性出现的顺序无关) - -```python -print([1, 2] == [1, 2]) # True -print([[0, 1], 1] == [[0, 1], 1]) # True -print({k1 = 1, k2 = 2} == {k2 = 2, k1 = 1}) # True - -print([1, 2] == [1, 2, 3]) # False -print({k1 = 1, k2 = 2, k3 = 3} == {k2 = 2, k1 = 1}) # False -``` - -## 37. 如何对 KCL 中已有的配置块进行修改 - -在 KCL 中,存在三种**属性运算符** `=`、`+=`、`:`,可以用来对已有配置块进行修改,并且可以使用**解包运算符** `**` 等"继承"一个配置块的所有属性字段和值。 - -- `=` 属性运算符表示覆盖,使用 `=` 运算符可以对属性进行有优先级的覆盖/删除,(如果是用 `Undefined` 覆盖则表示删除) -- `+=` 属性运算符表示添加,一般用于对 list 类型的属性添加子元素,`+=` 属性运算符后跟的操作数类型也只能为 list 类型 -- `:` 属性运算符表示幂等合并,当值发生冲突时进行报错,不冲突时进行合并 - -### 覆盖属性运算符= - -最常使用的属性运算符是 `=`,表示一个属性的赋值,多次对同一个属性进行使用时表示覆盖,对于 `{}` 外的全局变量或者 `{}` 内的属性均表示使用值覆盖这个全局变量或者属性 - -```python -data = { # 定义一个字典类型的变量 data - a = 1 # 使用 = 在 data 中声明一个值为 1 的属性 a - b = 2 # 使用 = 在 data 中声明一个值为 1 的属性 b -} # 最终 data 的值为 {"a": 1, "b": 1} -``` - -在 schema 实例化处也可以使用覆盖属性运算符实现对 schema 默认值的覆盖效果,一般在创建新的 schema 实例时如无特殊的需求,一般使用 `=` 即可 - -```python -schema Person: - name: str = "Alice" # schema Person 的 name 属性具有默认值 "Alice" - age: int = 18 # schema Person 的 age 属性具有默认值 18 - -bob = Person { - name = "Bob" # "Bob" -> "Alice", 属性 name 的值 "Bob" 的值会覆盖 schema Person name 属性的默认值 "Alice" - age = 10 # 10 -> 18, 属性 age 的值 10 的值会覆盖 schema Person age 属性的默认值 18 -} # 最终 bob 的值为 {"name": "Bob", age: 10} -``` - -### 插入属性运算符 += - -插入属性运算符表示对一个属性的值进行原地添加,比如向一个 list 类型的属性添加新的元素 - -```python -data = { - args = ["kcl"] # 使用 = 在 data 中声明一个值为 ["kcl"] 的属性 args - args += ["-Y", "settings.yaml"] # 使用 += 运算符向属性 args 中添加两个元素"-Y", "settings.yaml" -} # 最终 data 的值为 {"args": ["kcl", "-Y", "settings.yaml"]} -``` - -### 合并属性运算符: - -合并属性运算符表示对一个属性的不同配置块值进行幂等的合并,当需要合并的值发生冲突时进行报错,多用于复杂配置合并场景 - -```python -data = { - labels: {key1: "value1"} # 定义一个 labels, 它的类型为 dict, 值为 {"key1": "value1"} - labels: {key2: "value2"} # 使用 : 将 labels 不同的配置值进行合并 -} # 最终 data 的值为 {"labels": {"key1": "value1", "key2": "value2"}} -``` - -合并属性运算符属于幂等运算符,需要合并的配置块的书写顺序不影响其最终结果,比如上述例子中的两个 `labels` 属性也可以调换顺序书写 - -```python -data = { # 同一个属性 labels 的合并书写顺序不影响最终结果 - labels: {key2: "value2"} # 定义一个 labels, 它的类型为 dict, 值为 {"key2": "value2"} - labels: {key1: "value1"} # 使用 : 将 labels 不同的配置值进行合并 -} # 最终 data 的值为 {"labels": {"key1": "value1", "key2": "value2"}} -``` - -注意:合并属性运算符会对合并的值进行冲突检查,当需要合并的配置值发生冲突时进行报错 - -```python -data = { - a: 1 # a 的值为 1 - a: 2 # Error: a 的值 2 不能与 a 的值 1 进行合并,因为其结果存在冲突,且合并是不可交换的 -} -``` - -```python -data = { - labels: {key: "value"} - labels: {key: "override_value"} # Error: 两个 labels 的 key 属性的值 "value" 和 "override_value" 是冲突的,不可合并 -} -``` - -合并运算符对不同类型的使用方式不同 - -- 不同类型的属性不能进行合并 -- 当属性为 int/float/str/bool 等基本类型时,运算符会判断需要合并的值是否相等,不相等时发生合并冲突错误 - -```python -data = { - a: 1 - a: 1 # Ok - a: 2 # Error -} -``` - -- 当属性为 list 类型时 - - 当需要合并的两个 list 长度不相等时,发生合并冲突错误 - - 当需要合并的两个 list 长度相等时,按照索引递归地合并 list 当中的每一个元素 - -```python -data = { - args: ["kcl"] - args: ["-Y", "settings.yaml"] # Error: 两个 args 属性的长度不相同,不能进行合并 - env: [{key1: "value1"}] - env: [{key2: "value2"}] # Ok: 最终 env 属性的值为 [{"key1": "value1"}, {"key2": "value2"}] -} -``` - -- 当属性为 dict/schema 类型时,按照 key 递归地合并 dict/schema 当中的每一个元素 - -```python -data = { - labels: {key1: "value1"} - labels: {key2: "value2"} - labels: {key3: "value3"} -} # 最终 data 的值为 {"labels": {"key1": "value1", "key2": "value2", "key3": "value3"}} -``` - -- 任意类型的属性与 None/Undefined 合并的结果都是其自身 - -```python -data = { - args: ["kcl"] - args: None # Ok - args: Undefined #Ok -} # 最终 data 的值为 {"args": ["kcl"]} -``` - -支持顶级变量使用 `:` 属性声明与合并(仍然可使用 `config = Config {}` 的方式声明一个配置块) - -```python -schema Config: - id: int - value: str - -config: Config { - id: 1 -} -config: Config { - value: "1" -} -""" -此处定义了两个 Config 配置块,使用 : 运算符将可以两个配置块合并在一起,其合并的等效代码如下: -config: Config { - id: 1 - value: "1" -} -""" -``` - -综上所述,合并属性运算符 `:` 的使用场景主要为复杂数据结构 list/dict/schema 的合并操作,一般情况如无特殊需求使用 `=` 和 `+=` 两种属性运算符即可,因此属性运算符的最佳实践如下 - -- 对于基本类型,采用 `=` 运算符 -- 对于 list 类型,一般采用 `=` 和 `+=` 运算符,使用 `=` 表示完全覆盖 list 属性,使用 `+=` 表示向 list 中添加元素 -- 对于 dict/schema 类型,一般采用 `:` 运算符 - -此外,当已经存在一个配置时,可以使用解包运算符 `**` 获得此配置的所有字段值并对其中的字段使用不同属性运算符进行修改,并获得一个新的配置 - -```python -configBase = { - intKey = 1 # 一个 int 类型的属性 - floatKey = 1.0 # 一个 float 类型的属性 - listKey = [0] # 一个 list 类型的属性 - dictKey = {key1: "value1"} # 一个 dict 类型的属性 -} -configNew = { - **configBase # 将 configBase 解包内联到 configNew 中 - intKey = 0 # 使用 覆盖属性运算符 = 将 intKey 属性覆盖为 1 - floatKey = Undefined # 使用 覆盖属性运算符 = 删除 floatKey 属性 - listKey += [1] # 使用 添加属性运算符 += 为 listKey 属性尾部添加一个属性 1 - dictKey: {key2: "value2"} # 使用 合并属性运算符 : 为 dictKey 属性扩展一个键-值对 -} -``` - -输出的 YAML 结果为: - -```yaml -configBase: - intKey: 1 - floatKey: 1.0 - listKey: - - 0 - dictKey: - key1: value1 -configNew: - intKey: 0 - listKey: - - 0 - - 1 - dictKey: - key1: value1 - key2: value2 -``` - -或者可以使用 `|` 运算符对两个配置块合并: - -```python -configBase = { - intKey = 1 # 一个 int 类型的属性 - floatKey = 1.0 # 一个 float 类型的属性 - listKey = [0] # 一个 list 类型的属性 - dictKey = {key1: "value1"} # 一个 dict 类型的属性 -} -configNew = configBase | { # 使用 | 进行合并 - intKey = 0 # 使用 覆盖属性运算符 = 将 intKey 属性覆盖为 1 - floatKey = Undefined # 使用 覆盖属性运算符 = 删除 floatKey 属性 - listKey += [1] # 使用 添加属性运算符 += 为 listKey 属性尾部添加一个属性 1 - dictKey: {key2: "value2"} # 使用 合并属性运算符 : 为 dictKey 属性扩展一个键-值对 -} -``` - -输出的 YAML 结果为: - -```yaml -configBase: - intKey: 1 - floatKey: 1.0 - listKey: - - 0 - dictKey: - key1: value1 -configNew: - intKey: 0 - listKey: - - 0 - - 1 - dictKey: - key1: value1 - key2: value2 -``` - -### KCL 发生 conflicting values on the attribute 'attr' between {value1} and {value2} 错误的解决方式 - -当 KCL 发生类似 conflicting values on the attribute 'attr' between {value1} and {value2} 错误时,一般是合并属性运算符 `:` 的使用问题,表明 `value1` 和 `value2` 配置进行合并时在属性 `attr` 处发生了冲突错误。一般情况将 value2 的 attr 属性修改为其他属性运算符即可,使用 `=` 表示覆盖,使用 `+=` 表示添加 - -比如对于如下代码: - -```python -data = {k: 1} | {k: 2} # Error: conflicting values on the attribute 'k' between {'k': 1} and {'k': 2} -``` - -则可以使用 `=` 属性运算符修改为如下形式 - -```python -data = {k: 1} | {k = 2} # Ok: the value 2 will override the value 1 through the `=` operator -``` - -## 38. KCL 中如何同时遍历多个元素 - -KCL 中可以使用 for 推导表达式遍历多个元素 - -- 举例 1: 使用 for 进行 2 维元素遍历 - -```python -dimension1 = [1, 2, 3] # dimension1 列表的长度是 3 -dimension2 = [1, 2, 3] # dimension2 列表的长度是 3 -matrix = [x + y for x in dimension1 for y in dimension2] # matrix 列表的长度是 9 = 3 * 3 -``` - -输出结果如下: - -```yaml -dimension1: - - 1 - - 2 - - 3 -dimension2: - - 1 - - 2 - - 3 -matrix: - - 2 - - 3 - - 4 - - 3 - - 4 - - 5 - - 4 - - 5 - - 6 -``` - -- 举例 2: 使用 for 循环配合 zip 内置函数按照索引一一对应对多个列表进行遍历 - -```python -dimension1 = [1, 2, 3] # dimension1 列表的长度是 3 -dimension2 = [1, 2, 3] # dimension2 列表的长度是 3 -dimension3 = [d[0] + d[1] for d in zip(dimension1, dimension2)] # dimension3 列表的长度是 3 -``` - -输出结果如下: - -```yaml -dimension1: - - 1 - - 2 - - 3 -dimension2: - - 1 - - 2 - - 3 -dimension3: - - 2 - - 4 - - 6 -``` - -## 39. KCL 中如何为 option 函数设定默认值 - -在 KCL 中,当 option 属性的值为 None/Undefined 空时,可以使用逻辑或 `or` 直接指定一个默认值 - -```python -value = option("key") or "default_value" # 当 key 的值存在时,取 option("key") 的值,否则取 "default_value" -``` - -或者使用 option 函数的 default 参数 - -```python -value = option("key", default="default_value") # 当 key 的值存在时,取 option("key") 的值,否则取 "default_value" -``` - -## 40. KCL 中 schema 怎么检查多个属性不能同时为空或同时设置 - -在 KCL 中,对于 schema 的单个属性不能为空可以使用属性非空标记 - -```python -schema Person: - name: str # required. name 不能为空 - age: int # required. age 不能为空 - id?: int # optional. id 可以留空 -``` - -而对于需要检查 schema 属性不能同时为空或者只能有一者为空的情况时,需要借助 schema check 表达式进行书写,下面以同一个 schema Config 的两个属性 a, b 为例进行说明 - -- Config 的 a, b 属性不能同时为空 - -```python -schema Config: - a?: str - b?: str - - check: - a or b, "a属性和b属性不能同时为空" -``` - -- Config 的 a, b 属性只能有一个为空或者都为空(不能同时存在或不为空) - -```python -schema Config: - a?: str - b?: str - - check: - not a or not b, "a属性和b属性不能同时填写" -``` - -## 41. KCL 中 import 了某个文件但是找不到其同目录下其他 KCL 文件定义的 schema 可能是什么原因 - -可能是与使用 import 仅导入了这个文件夹的这一个文件导致,在 KCL 中,import 支持导入整个文件夹,也支持导入某一个文件夹下的的某一个 KCL 文件,比如对于如下目录结构 - -``` -. -├── kcl.mod -├── main.k -└── pkg - ├── pkg1.k - ├── pkg2.k - └── pkg3.k -``` - -在根目录下存在入口文件 main.k,可以在 main.k 中书写如下代码导入整个 pkg 文件夹,此时 pkg 文件夹下的所有 schema 定义互相可见 - -```python -import pkg -``` - -还可以书写如下代码导入单个文件 pkg/pkg1.k,此时 pkg1.k 不能找到其他文件即 pkg2.k/pkg3.k 下的 schema 定义 - -```python -import pkg.pkg1 -``` - -## 42. KCL 中的缩进是如何处理的? - -在 KCL 中,在出现冒号 `:`、中括号对 `[]` 以及大括号对 `{}` 时,一般需要使用换行 + 缩进,同一缩进级的缩进空格数需要保持一致,一个缩进级一般采用 4 个空格表示 - -- 冒号 `:` 后跟换行 + 缩进 - -```python -"""if 语句中的缩进""" -_a = 1 -_b = 1 -if _a >= 1: # 冒号后跟换行+缩进 - if _a > 8: - _b = 2 - elif a > 6: - _b = 3 - -"""schema 定义中的缩进""" -schema Person: # 冒号后跟换行+缩进 - name: str - age: int -``` - -- 中括号对 `[]` 后跟换行 + 缩进 - -```python -data = [ # 左中括号 [ 后跟换行+缩进 - 1 - 2 - 3 -] # 右中括号 ] 前取消缩进 -``` - -```python -data = [ # 左中括号 [ 后跟换行+缩进 - i * 2 for i in range(5) -] # 右中括号 ] 前取消缩进 -``` - -- 大括号对 `{}` 后跟换行 + 缩进 - -```python -data = { # 左大括号 { 后跟换行+缩进 - k1 = "v1" - k2 = "v2" -} # 右大括号 } 前取消缩进 -``` - -```python -data = { # 左大括号 { 后跟换行+缩进 - str(i): i * 2 for i in range(5) -} # 右大括号 } 前取消缩进 -``` - -## 43. 如何为 KCL 代码编写简单的测试? - -KCL 目前的版本还不支持内部程序调试,可以使用 assert 语句以及 print 函数实现数据的断言和打印查看 - -```python -a = 1 -print("The value of a is", a) -assert a == 1 -``` - -此外,还可以借助 kcl-test 测试工具编写 KCL 内部编写测试用例 - -假设有 hello.k 文件,代码如下: - -```python -schema Person: - name: str = "kcl" - age: int = 1 - -hello = Person { - name = "hello kcl" - age = 102 -} -``` - -构造 hello_test.k 测试文件,内容如下: - -```python -schema TestPerson: - a = Person{} - assert a.name == 'kcl' - -schema TestPerson_age: - a = Person{} - assert a.age == 1 - -schema TestPerson_ok: - a = Person{} - assert a.name == "kcl" - assert a.age == 1 -``` - -然后在目录下执行 kcl-test 命令: - -``` -$ kcl-test -ok /pkg/to/app [365.154142ms] -$ -``` - -## 44. KCL 中如何定义函数或定义方法? - -schema 结构在一定程度上充当了函数的功能,并且这个函数具有多个输入参数和多个输出参数的能力,比如如下代码可以实现一个斐波那契数列的功能: - -```python -schema Fib: - n: int - value: int = 1 if n <= 2 else (Fib {n: n - 1}).value + (Fib {n: n - 2}).value - -fib8 = (Fib {n: 8}).value -``` - -输出结果为: - -```yaml -fib8: 21 -``` - -一个合并列表为字典的 schema 函数 - -```python -schema UnionAll[data, n]: - _?: [] = data - value?: {:} = ((UnionAll(data=data, n=n - 1) {}).value | data[n] if n > 0 else data[0]) if data else {} - -schema MergeList[data]: - """Union一个列表中的所有元素返回合并字典 - - [{"key1": "value1"}, {"key2": "value2"}, {"key3": "value3"}] -> {"key1": "value1", "key2": "value2", "key3": "value3"} - """ - _?: [] = data - value?: {:} = (UnionAll(data=data, n=len(data) - 1) {}).value if data else {} -``` - -此外,KCL 支持使用 `lambda` 关键字定义一个函数: - -```python -func = lambda x: int, y: int -> int { - x + y -} -a = func(1, 1) # 2 -``` - -lambda 函数具有如下特性: - -- lambda 函数将最后一个表达式的值作为函数的返回值,空函数体返回 None。 -- 返回值类型注解可以省略,返回值类型为最后一个表达式值的类型 -- 函数体中没有与顺序无关的特性,所有的表达式都是按顺序执行的 - -```python -_func = lambda x: int, y: int -> int { - x + y -} # 使用 lambda 表达式定义一个函数 -_func = lambda x: int, y: int -> int { - x - y -} # Ok -_func = lambda x: int, y: int -> str { - str(x + y) -} # Error (int, int) -> str can't be assigned to (int, int) -> int -``` - -lambda 函数对象不能参与任何计算,只能在赋值语句和调用语句中使用。 - -```python -func = lambda x: int, y: int -> int { - x + y -} -x = func + 1 # Error: unsupported operand type(s) for +: 'function' and 'int(1)' -``` - -```python -a = 1 -func = lambda x: int { - x + a -} -funcOther = lambda f, para: int { - f(para) -} -r = funcOther(func, 1) # 2 -``` - -输出为: - -```python -a: 1 -r: 2 -``` - -可以定义一个匿名函数并直接调用 - -```python -result = (lambda x, y { - z = 2 * x - z + y -})(1, 1) # 3 -``` - -可以在 for 循环使用使用匿名函数 - -```python -result = [(lambda x, y { - x + y -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 3, 3, 4] -``` - -可以在 KCL schema 中定义并使用函数 - -```python -_funcOutOfSchema = lambda x: int, y: int { - x + y -} -schema Data: - _funcInSchema = lambda x: int, y: int { - x + y - } - id0: int = _funcOutOfSchema(1, 1) - id1: int = _funcInSchema(1, 1) - id2: int = (lambda x: int, y: int { - x + y - })(1, 1) -``` - -输出 YAML 为: - -```yaml -data: - id0: 2 - id1: 2 - id2: 2 -``` - -## 45. 为什么变量赋值为枚举类型(字面值联合类型)时会报错 - -在 KCL 中,被定义为字面值联合类型的属性,在赋值时仅允许接收一个字面值或者同为字面值联合类型的变量,比如如下代码是正确的: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -data = Data { - color = "Red" # Ok, 赋值为 "Red"、"Yellow" 和 "Blue" 均可 -} -``` - -然而以下代码是错误的: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -_color = "Red" - -data = Data { - color = _color # Error: expect str(Red)|str(Yellow)|str(Blue), got str -} -``` - -这是因为没有为变量 `_color` 申明一个类型,它会被 KCL 编译器推导为 `str` 字符串类型,因此当一个 “较大” 的类型 `str` 赋值为一个 “较小” 的类型时 `"Red" | "Yellow" | "Blue"` 会报错,一个解决方式是为 `_color` 变量声明一个类型,以下代码是正确的: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -_color: "Red" | "Yellow" | "Blue" = "Red" - -data = Data { - color = _color # Ok -} -``` - -进一步地,我们可以使用类型别名来简化枚举(字面值联合类型的书写),比如如下代码: - -```python -type Color = "Red" | "Yellow" | "Blue" # 定义一个类型别名,可以在不同的地方重复使用,降低代码书写量 - -schema Data: - color: Color - -_color: Color = "Red" - -data = Data { - color = _color # Ok -} -``` - -## 46. 过程式的 for 循环 - -KCL 中为何不支持过程式的 for 循环! - -KCL 提供了推导表达式以及 all/any/map/filter 表达式等用于对一个集合元素进行处理,满足大部分需求,提供过程式的 for 循环体从目前场景看需求暂时不强烈,因此暂未提供过程式的 for 循环支持 - -此外,KCL 中虽然没有支持过程式的 for 循环,但是可以通过 for 循环和 lambda 函数“构造”相应的过程式 for 循环 - -```python -result = [(lambda x: int, y: int -> int { - # 在其中书写过程式的 for 循环逻辑 - z = x + y - x * 2 -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 2, 4, 4] -``` - -## 47. 默认变量不可变 - -KCL 变量不可变性是指 KCL 顶层结构中的非下划线 `_` 开头的导出变量初始化后不能被改变。 - -```python -schema Person: - name: str - age: int - -a = 1 # a会输出到YAML中,一旦赋值不可修改 -_b = 1 # _b变量以下划线开头命名,不会输出到YAML中, 可多次赋值修改 -_b = 2 -alice = Person { - name = "Alice" - age = 18 -} -``` - -规定变量不可变的方式分为两类: - -- schema 外的非下划线顶层变量 - -```python -a = 1 # 不可变导出变量 -_b = 2 # 可变非导出变量 -``` - -## 48. 在 KCL 中存在类似 Go `interface{}`/`any` 或者 Java `Object` 的类型嘛? - -在 KCL 中,我们可以使用 `any` 类型注解来定义一个变量存储任意类型比如整数、字符串、schema 结构等数据。比如如下例子: - -```python -schema Data: - id: int = 1 - -var_list: [any] = [1, "12", Data {}] -``` - -输出 YAML 为: - -```yaml -var_list: - - 1 - - "12" - - id: 1 -``` - -此外,我们可以使用 `typeof` 函数来判断 KCL 变量的类型: - -```python -schema Data1: - id: int = 1 - -schema Data2: - name: str = "name" - -data_list: [any] = [Data1 {}, Data2 {}] -data_type_list: [str] = [typeof(data) for data in data_list] -``` - -输出 YAML 为: - -```yaml -data_list: - - id: 1 - - name: name -data_type_list: - - Data1 - - Data2 -``` - -## 49. 如何通过编写 KCL 插件进行扩展? - -KCL 插件在 KCL 的 plugins 子目录(通常安装在 `$HOME/.kcl/plugins` 目录),或者通过 `$KCL_PLUGINS_ROOT` 环境变量设置(环境变量优先级更高)。对于插件开发人员,插件都在 [Git 仓库](https://github.com/kcl-lang/kcl-plugin)管理,可以将插件仓库克隆到该目录进行开发。 - -KCL 内置了 kcl-plugin 脚手架命令用于辅助用户使用 Python 语言编写 KCL 插件,以便在 KCL 文件当中调用相应的插件对 KCL 语言本身进行增强,比如访问网络,读写 IO,CMDB 查询和加密解密等功能。 - -``` -usage: kcl-plugin [-h] {list,init,info,gendoc,test} ... - -positional arguments: - {list,init,info,gendoc,test} - kcl plugin sub commands - list list all plugins - init init a new plugin - info show plugin document - gendoc gen all plugins document - test test plugin - -optional arguments: - -h, --help show this help message and exit -``` - -比如想要开发一个名为 io 插件,就可以使用如下命令成功新建一个 io 插件 - -``` -kcl-plugin init io -``` - -然后可以使用如下命令获得 plugin 的根路径并 cd 到相应的 io 插件目录进行开发 - -``` -kcl-plugin info -``` - -比如想要开发一个读文件的函数 read_file,就可以在 `$plugin_root/io` 的 `plugin.py` 中进行 python 代码编写: - -```python -# Copyright 2020 The KCL Authors. All rights reserved. - -import pathlib - -INFO = { - 'name': 'io', - 'describe': 'my io plugin description test', - 'long_describe': 'my io plugin long description test', - 'version': '0.0.1', -} - - -def read_file(file: str) -> str: - """Read string from file""" - return pathlib.Path(file).read_text() - -``` - -另外可以在 `plugin_test.py` 中编写相应的测试函数,也可以直接编写如下所示 KCL 文件进行测试: - -```python -import kcl_plugin.io - -text = io.read_file('test.txt') -``` - -还可以使用 info 命令查看 io 插件的信息 - -``` -kcl-plugin info io -``` - -``` -{ - "name": "io", - "describe": "my io plugin description test", - "long_describe": "my io plugin long description test", - "version": "0.0.1", - "method": { - "read_file": "Read string from file" - } -} -``` - -最后将编写测试完成的插件在 `kcl_plugins` 仓库提 MR 合并即可 - -## 50. 如何在 KCL 中进行基本类型转换 - -可以使用`int()`, `float()`和`str()` 这些内置的方法来进行 `int`, `float` 和 `str` 之间的基本类型转换. - -``` -_t = 1 - -t_str: str = str(_t) # 输出的 t_str 为一个字符串 "t_str: '1'" -t_int: int = int(t_str) # 输出的 t_int 为一个整型 "t_int: 1" -t_float: float = float(t_str) # 输出的 t_float 为一个浮点型 "t_float: 1.0" -``` - -如果您想查看更多详细的关于KCL类型系统和类型转换的内容,您可以查阅 [KCL 内置类型](https://kcl-lang.io/docs/reference/lang/tour#built-in-types) 和 [KCL 类型系统](https://kcl-lang.io/docs/reference/lang/tour#type-system)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/support/support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/support/support.md deleted file mode 100644 index 648ee5a3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/support/support.md +++ /dev/null @@ -1,3 +0,0 @@ -# 常见问答 - -KCL 安装、使用过程中遇到的常见问题,包括基本概念解释、KCL 语法、KCL 语言设计、命令行工具和 YAML 等常见问题。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4.json deleted file mode 100644 index a9e8bfe5..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "sidebar.user_docs.category.Get Started": { - "message": "快速开始" - }, - "sidebar.user_docs.category.Introduction": { - "message": "简介" - }, - "sidebar.user_docs.category.User Guide": { - "message": "用户手册" - }, - "sidebar.user_docs.guides.category.Automation": { - "message": "自动化" - }, - "sidebar.user_docs.category.Configuration": { - "message": "配置" - }, - "sidebar.user_docs.category.Data Integration": { - "message": "数据集成" - }, - "sidebar.user_docs.category.Package Management": { - "message": "包管理工具" - }, - "sidebar.user_docs.category.How to": { - "message": "如何使用" - }, - "sidebar.user_docs.category.Schema Definition": { - "message": "模型定义" - }, - "sidebar.user_docs.category.Validation": { - "message": "验证" - }, - "sidebar.user_docs.category.Concepts": { - "message": "核心概念" - }, - "sidebar.user_docs.category.FAQ": { - "message": "常见问答" - }, - "sidebar.reference.category.Tutorial": { - "message": "教程" - }, - "sidebar.reference.category.Code Lab": { - "message": "代码实验室" - }, - "sidebar.reference.category.Spec": { - "message": "语言规范" - }, - "sidebar.reference.category.Errors and Warnings": { - "message": "错误与警告" - }, - "sidebar.reference.category.Types": { - "message": "类型系统" - }, - "sidebar.reference.category.System Package": { - "message": "系统模块" - }, - "sidebar.reference.category.Plugin System": { - "message": "插件系统" - }, - "sidebar.reference.category.Multi-Language": { - "message": "多语言集成" - }, - "sidebar.reference.category.Cheat Sheet": { - "message": "备忘表" - }, - "sidebar.reference.category.Package Management": { - "message": "包管理工具" - }, - "sidebar.reference.category.Command Reference": { - "message": "命令参考" - }, - "sidebar.reference.category.Advanced-Concepts": { - "message": "进阶概念" - }, - "sidebar.reference.category.Best-Practices": { - "message": "最佳实践" - }, - "sidebar.tools.category.Command Line Tools": { - "message": "命令行工具" - }, - "sidebar.tools.category.KCL Tools": { - "message": "语言工具" - }, - "sidebar.tools.category.OpenAPI Tools": { - "message": "OpenAPI 工具" - }, - "sidebar.community.category.Community": { - "message": "简介" - }, - "sidebar.community.category.Types": { - "message": "类型系统" - }, - "sidebar.community.category.Contribution Guide": { - "message": "贡献指南" - }, - "sidebar.community.category.Release Policy": { - "message": "发布策略" - }, - "sidebar.docs.category.GitOps": { - "message": "GitOps", - "description": "The label for category GitOps in sidebar docs" - }, - "sidebar.docs.category.CI Integration": { - "message": "CI 集成", - "description": "The label for category CI Integration in sidebar docs" - }, - "sidebar.user_docs.category.GitOps": { - "message": "GitOps", - "description": "The label for category GitOps in sidebar user_docs" - }, - "sidebar.user_docs.category.CI Integration": { - "message": "CI 集成", - "description": "The label for category CI Integration in sidebar user_docs" - }, - "sidebar.docs.category.Mutate or Validate Kubernetes Manifests": { - "message": "编辑或验证 Kubernetes 资源", - "description": "The label for category Mutate or Validate Kubernetes Manifests in sidebar docs" - }, - "sidebar.user_docs.category.Mutate or Validate Kubernetes Manifests": { - "message": "编辑或验证 Kubernetes 资源", - "description": "The label for category Mutate or Validate Kubernetes Manifests in sidebar user_docs" - }, - "sidebar.docs.category.Secret Management": { - "message": "敏感信息管理", - "description": "The label for category Secret Management in sidebar docs" - }, - "sidebar.user_docs.category.Secret Management": { - "message": "敏感信息管理", - "description": "The label for category Secret Management in sidebar user_docs" - } -} \ No newline at end of file diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/_category_.json deleted file mode 100644 index f763b5c8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "社区", - "position": 5 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/contribute/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/contribute/_category_.json deleted file mode 100644 index 131bb8e3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/contribute/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "贡献指南", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/contribute/contribute-code.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/contribute/contribute-code.md deleted file mode 100644 index 8e8392fe..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/contribute/contribute-code.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -sidebar_position: 2 ---- - -# 如何贡献代码? - -欢迎参与 KCL 共建贡献完善代码、完善代码文档和测试,同时也欢迎通过 Issue 提供反馈。本文主要针对修改和完善已有的代码,如果是希望增加 KCL 语言特性请通过 KEP 流程提交。 - -## 1. 代码和注释中的错别字 - -如果只是修改代码和注释中的错别字,不涉及代码逻辑的调整,那么可以直接在 Github 克隆仓库后直接修改并提交 PR。需要注意的是尽量保持代码风格一致。 - -## 2. 如何贡献 KCL 代码 - -- 先确保本地测试环境正常 -- 修改代码并补充测试 -- 本地测试通过后提交 PR - -## 3. 如何贡献 VS Code 插件代码 - -请参考 VS Code 插件仓库的相关文档 - -## 4. 开发流程相关代码 - -欢迎通过 Issue 和讨论组讨论。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/contribute/contribute-docs.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/contribute/contribute-docs.md deleted file mode 100644 index 7b846680..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/contribute/contribute-docs.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 如何贡献文档? - -本文主要针对已有的文档做局部修改。如果是投稿博客文章、添加新的文档或者调整文档目录结构请先联系团队成员。 - -KCL 文档分为用户指南、开发文档、内部文档、参考手册和博客文章等,他们的区别如下: - -- 用户指南:对应使用文档,是让用户以最小的代价快速使用 KCL 工具完整工作,不要涉及太多的内部原理和实现 -- 开发文档:内部是怎么实现的,主要针对希望了解 KCL 原理和参与贡献和开发的同学 -- 内部文档:针对企业用户的一些内部场景定制的文档 -- 参考手册:KCL 语言、工具和 IDE 等全部特性的文档,内容覆盖最广但比较琐碎 -- 博客文章:没有特别的限制,可以是针对某些具体的场景、某些技术点或者是整体发展展望等分享文章 - -在贡献不同类型的文档时,最好能够结合上面的定位对不同的内容做一些适当的裁剪,给读者最佳体验。 - -## 1. 基本规范 - -- 除标题外,内部小标题尽量带编号,便于阅读 -- 工具自动输出的文档需要由到源代码的链接,小标题可以不带编号 -- 尽量不要贴大段的代码(30行以内),代码最好给出文字解释和对应的参考链接 -- 有图有真相,但是不推荐过度复杂的架构图 -- 内部链接:采用 `/docs/user_docs/getting-started/intro` 绝对路径形式 - -**标点和空格** - -- 在中文的文档中优先使用中文的标点 -- 中文和英文之间需要增加 1 个空格 -- 中文和数字之间需要增加 1 个空格 -- 中文使用全角标点,标点前后均不添加空格 -- 英文内容使用半角标点,标点后面加 1 个空格 -- 链接前后需要保留一个空格,但是段落开头和中文全角标点附近不用添加空格。 - -**图片和资源文件名** - -- 文件名和目录名只能用数字、英文字母、下划线 `_` 和减号 `-` 组成 -- 当前文档的图片放在当前目录的 images 目录下 -- 矢量图片可以通过 [drawio 离线版](https://github.com/jgraph/drawio-desktop/releases) 绘制(并同时提交源文件),以 200% 分辨率导出 png 格式图片 - -## 2. 使用文档内容的基本模式 - -每个使用文档可以看作是一个相对完整的分享或博客文章(参考手册不再此类)。使用文档遵循以下模式组织内容: - -1. 概览:本文希望解决什么问题,达到什么效果,可以先放最终效果截图 -1. 依赖的环境:需要安装什么工具,并给出相关链接 -1. 引入本文构建资源的关系图或架构图 - - 需要用到的 Konfig 模型,给出模型参考页面链接,以及对应的上游原始模型的文档链接 -1. 具体的操作步骤 - - 尽量确保最小化代码,甚至可以刻意隐藏一些干扰代码,同时给出完整代码对应的链接 - - 列出每个步骤命令的概要输出信息,并配以文字描述 -1. 给出测试方式 - - 尽量采用社区通用的方式(比如kube、curl命令、或浏览器)测试 - - 给出测试结果的截图(和开头呼应) -1. 总结和展望 - - 简单回顾当前操作的流程,以及一些可以展开的地方(可以给出一些链接) - -## 3. 测试和提交 PR - -先克隆文档仓库,本地通过 `npm run start` 和 `npm run build` 命令测试查看效果,确保可以正常浏览后提交 PR 即可。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/contribute/contribute.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/contribute/contribute.md deleted file mode 100644 index 692df6ab..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/contribute/contribute.md +++ /dev/null @@ -1 +0,0 @@ -# 贡献指南 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/contribute/git-guideline.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/contribute/git-guideline.md deleted file mode 100644 index c475057d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/contribute/git-guideline.md +++ /dev/null @@ -1,132 +0,0 @@ -# Git 提交指南 - -本文介绍了 Git 提交变更时需要注意的事项,如果拒绝接受本文的内容会导致提交的变更无法被接受。 - -## 1. 关于 issue - -在提交一个 issue 之前,请先查阅已经关闭的 issue ,也许在关闭的 issue 中已经存在合适的解决方案。 - -如果没有找到合适的方案,我们提供了4种模版在创建 issue 的时候使用。 - -- Bug Report : 发现了一个 Bug,可以通过 Bug Report 模版创建 issue 与我们联系。 -- Enhancement : 开发者对工具进行了增强,可以通过 Enhancement 模版创建 issue 来介绍增加的内容。 -- Feature Request : 在使用的过程中想要为工具增加某些新的特性或者功能,可以通过 Feature Request 模版创建 issue 来描述新特性。 -- Ask a Question : 如果有任何的疑问,可以通过 Ask a Question 模版来创建一个 issue 与我们联系。 - -在选择合适的模版后,只需要填写模版上的要求填写的内容即可。如果在创建 issue 的时候发现没有模版,或者模版内容为空,可以通过微信群,钉钉群或者邮件向我们反馈这个问题。 - -## 2. 关于 Git 分支 - -要向 kcl-lang 贡献代码,您必须拥有一个 GitHub 帐户,以便您可以将代码推送到您自己的分支并创建拉取请求。我们推荐参考 [Angular 规范](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines) 为您自己的分支命名。 -推荐的格式如下: - -``` -{type}-{a_short_description} -``` - -分支名称主要包括两个字段,并通过 “-” 分割。其中: - -- {type} : 当前分支内容的类型。 -- {a_short_description}: 一个简短的描述,介绍这个分支的主要内容。 - -e.g. 张三首先 Fork 仓库到自己账户下,然后创建对应名称 `zhangsan:fix-output-fmt-bug` 的分支(冒号之前是张三的账号),用于修复输出格式化 bug。 - -## 3. 关于 Git Commit - -我们参考 [Commitizen](https://github.com/commitizen/cz-cli) 书写 Commit Message。 - -``` -注: 如果直接使用 Commitizen 生成 Commit Message,需要注意因为 Commitizen -是开发人员管理 commit 的工具,与项目本身无关联,因此由 Commitizen 生成的中间产物 -(如: node_modules 文件目录)可能没有在项目 .gitignore 文件中。 - -您可以 git add {filename} 选择要提交的文件而忽视中间产物。 -或者您可以向 .gitignore 文件中添加如下内容而自动忽视中间产物: -# commitizen -package.json -package-lock.json -node_modules/* -``` - -如果手动编写 Commit Message,我们也建议采用 [Commitizen](https://github.com/commitizen/cz-cli) 的 commit message 格式。 - -``` -{type} ( {component_or_file} ) {a_short_description} - {a_longer_description} - BREAKING CHANGE: {breaking_change_description}. - {linked issue} -``` - -其中主要包括6个字段: - -- {type} : 当前 commit 对应的分支的类型。 -- {component_or_file}: 当前 commit 改动的模块或者文件的名称。 -- {a_short_description}: 简短的描述介绍 commit 中的内容。 -- {a_longer_description}: 详细的描述用来介绍 commit 中的内容。 -- {breaking_change_description}: 如果 commit 中包含破环兼容性的改动,需要对兼容性改动产生的影响进行介绍。 -- {linked issue}: 与当前这个 commit 关联的 issue。 - -其中 {breaking_change_description} 和 {linked issue} 如果 commit 中不包含破坏兼容性的改动和关联的 issue,可以省略。 - -e.g. 张三在分支 `zhangsan:fix-output-fmt-bug` 中创建的 commit。 - -``` - - fix(kcl-printer): fix an output format bug in kcl-printer - - There is an output format bug in kcl-printer because ..., - So, The calling of method "XXX" is replaced by "HHHH"..., - ... - - -- 如果没有破坏兼容性的改动和关联的 issue 可以省略下面内容。 - - BREAKING CHANGE: This change maybe cause ....... - - fix #123 - -``` - -## 4. 关于 pull request - -在提交一个 PR 之前,可能需要优先考虑以下几个问题: - -- 请先查阅已经关闭的 PR ,也许在已经关闭的 PR 中,可能存在已经完成的解决方案。 -- 我们建议在提交变更之前,提交一个对应的 issue 描述变更中将要解决的问题,并将变更对应的 PR 与 issue 关联。 -- 在向我们提交 PR 之后,请签署 [Contributor License Agreement (CLA)](#cla) ,如果拒绝签署,我们将无法接受 PR。 -- 请确保每次改动都创建了一个新的分支,并根据上文中提到的规范为分支命名。 -- 一次 PR 请不要超过两个 commit ,请将多余的 commit 通过 squash 压缩,并根据上文中提到的规范,编写 commit message 。 -- 我们提供了 [PR 模版](https://github.com/kcl-lang/.github/blob/main/.github/PULL_REQUEST_TEMPLATE.md),只需要添加模版中要求的内容即可,如果在创建PR时发现没有模版或者模版内容为空,可以通过微信群,钉钉群或者邮件向我们反馈这个问题。 - -我们建议PR的标题与分支名、commit message 风格保持一致: - -``` -{type} ( {component_name_or_file_name} ) :{a_short_description} -``` - -e.g. 张三为分支`fix/zhangsan/fix_output_fmt_bug`创建的PR名称。 - -``` -fix(kcl-printer): fix an output format bug in kcl-printer. -``` - -## 5. 目前 type 支持的类型 - -参考[Angular 规范](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines),type 支持类型的类型如下: - -``` -- feat: -- 添加了新的功能特性。 -- fix: -- 进行了 Bug 的修复。 -- docs: -- 进行了文档部分的修改。 -- style: -- 对代码格式的修改,并不影响代码的功能,如:删除多余空格,代码缩进等。 -- refactor: -- 在不改变代码功能的基础上对代码进行了的重构。 -- perf: -- 对代码进行了性能优化。 -- test: -- 添加或者调整已有的测试用例。 -- build: -- 对构建系统或者外部依赖库进行了调整。 -- ci: -- 调整了 CI 的配置文件或者脚本。 -- chore: -- 对源代码和测试文件之外其他部分的调整。 -- revert: -- 对 commit 进行回滚。 -``` - -## 6. Contributor License Agreement (CLA) - -在第一次向我们提交 PR 之后,在 PR 中的 CLA 检查将会失败并提示签署 CLA。您可以通过自己的账户之间在 PR 回复 "I have read the CLA Document and I hereby sign the CLA" 表示同意签署 CLA,然后手动重启失败的 CLA 检查 Action 即可。当 PR 被成功合并之后将会被锁定不能再修改。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/intro/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/intro/_category_.json deleted file mode 100644 index e4cb1869..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/intro/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "简介", - "position": 1 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/intro/intro.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/intro/intro.md deleted file mode 100644 index af94bc33..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/intro/intro.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 社区 - -欢迎来到 KCL 开源社区,每个人的参与都是所有开源项目健康成长的动力!有很多方法可以参与开源。每个人都可以通过提交PR(Pull Request)来创建问题或修复 bug、改进文档或修改代码, - -可以查看[社区](https://github.com/kcl-lang/community)并加入我们。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/intro/license.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/intro/license.md deleted file mode 100644 index fe1db435..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/intro/license.md +++ /dev/null @@ -1,211 +0,0 @@ ---- -sidebar_position: 99 ---- - -# 许可 - -KCL 使用 [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0): - -``` - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2023 The KCL Authors. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/intro/support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/intro/support.md deleted file mode 100644 index 70ecd7e8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/intro/support.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 寻求帮助 - -KCL拥有一个由众多爱好者组成的开发者和用户社区。在此页面上,我们列出了您可以参与的KCL相关社区;有关其他在线和离线学习材料,请参阅本节的其他页面。 - -在加入 KCL 社区之前,请阅读[贡献者条款](https://www.contributor-covenant.org/version/2/0/code_of_conduct/),所有社区成员都需要遵守这些条款。 - -## 讨论 - -- 在 Github 上提交问题 -- 在 Github 讨论组中交流 -- 通过官方网站、Github、Twitter、微信和其他帐户获取 KCL 最新状态。可以查看[社区](https://github.com/kcl-lang/community)并加入我们。 - -## 新功能 - -请尽量避免提交新功能的拉取请求,我们可能已经有人在处理这些功能,或者这个功能已经是我们未来计划的一部分。总之,请在提交新功能之前与我们联系! diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/release-policy/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/release-policy/_category_.json deleted file mode 100644 index bf01a053..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/release-policy/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "发布策略", - "position": 3 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/release-policy/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/release-policy/index.md deleted file mode 100644 index a4a0bc3d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/release-policy/index.md +++ /dev/null @@ -1 +0,0 @@ -# 发布策略 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/release-policy/kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/release-policy/kcl.md deleted file mode 100644 index 0f9115b8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/release-policy/kcl.md +++ /dev/null @@ -1,39 +0,0 @@ -# KCL 发布策略 - -KCL 开发团队采用 [语义化版本](https://semver.org/lang/zh-CN/) 来简化管理。版本格式:主版本号.次版本号.修订号。版本号递增规则如下:主版本号对应不兼容的 API 修改,次版本号对应向下兼容的功能性新增,修订号对应向下兼容的问题修正。总体目标是每一个半月发布一个特性增强的次要版本,根据需要不定期发布其他版本的修订。 - -KCL 项目版本发布策略如下: - -- 主版本号:当进行重大的架构调整或者加入重大的新功能时,需要提升主版本号。对于 KCL 项目来说,目前的主版本号为 0。 -- 次版本号:当添加的功能和特性有较大的变化时,提升次版本号。目前的次版本号为 5,2023 年度会相继发布 0.5, 0.6, 0.7 版本。 -- 修订号:通过修复漏洞或者改进性能来更新程序时,会提升修订号,修订号从 0 开始计数以此加 1。 -- 发布周期:在未达到 v1.0.0 版本之前,计划每隔 3 个月发布一个新的次要版本。在此期间,需要持续收集用户反馈,并进行必要的修复和改进。 -- 发布流程:在发布新版本之前,需要进行严格的测试和审核,确保新版本的质量。封板并测试完成后,会在 Github 上发布新版本的源代码,二进制和镜像,并提供详细的文档和使用指南。 -- 版本支持:我们将对最新的版本提供长期支持,包括漏洞修复和安全更新。对于旧版本,我们将提供有限的支持,仅在必要时进行修复。 - -## 发布流程与规则 - -- 特性开发:main 分支主干开发,分支发布,block 用户使用的问题和严重的 bug, 安全隐患,高优先级解决,尽可能保持在一周内收敛,高于一般的功能研发。 -- 迭代周期:我们的迭代周期通常为 3 个月,即每 3 个月发布一个新的次要版本。 -- 版本规划:发版前两周产出 alpha 版本,前一周产出 beta 版本,alpha 版本仍可进行特性合并,beta 版本只合并错误修复,最终产出正式版本并打 tag 作为长期保存的 release 分支。 -- 发版计划:在每个发布周期开始时制定详细的发版计划(Github Milestone),包括发布日期、版本号、功能列表和测试计划等。需要尽可能地遵守发版计划,确保按时发布新版本。 -- 发布前测试:在发布新版本之前,需要进行全面的测试,包括单元测试、集成测试,模糊测试,压测,用户验收测试等。只有经过测试并无问题后,我们才会发布新版本。 -- 版本回滚:如果在发布后发现了严重的问题,需要立即回滚版本,并尽快修复问题。并通过邮件、社交媒体等渠道及时通知用户,并提供解决方案。 -- 发布文档:需要在发布时提供详细的文档,包括发布说明、更新日志、API 文档和使用指南等,帮助用户了解和使用新版本。在 KCL 中,我们统一在 KCL 网站进行维护。 -- 版本兼容性:在发布新版本时,需要尽可能保持兼容性,以确保用户无需进行过多的修改和适应。KCL 还没有达到 v1,暂时没有兼容性保证。KCL 的目标是尽可能少地进行重大更改,不应轻率地考虑对语言的更改,为了语言自身更好地演进和发展,一般认为更改具有重大好处时才会进行(较好地解决了目标场景的问题或者提升了绝大用户的使用体验)。对于可能引入兼容性问题的功能或变更,提供相应的提示和解决方案,同时会提供逐步升级的指南或提供自动迁移的工具,以帮助用户平滑地迁移到新版本。 - -## 发布组件 - -![](/img/docs/community/release-policy/kcl-components.png) - -每次版本发布时,KCL 相关所有组件保持一个依赖同一个 KCL 核心主要版本,整体采用树形结构组织依赖顺序发布并进行回归测试,直到发布测试完成,尽力避免三角依赖,禁止循环依赖。 - -## 一个 Feature 的生命周期 - -- 设计方案/文档:通过 Issue 回答清楚这个 feature 的动机是什么,它解决什么问题以及目标是什么,用户需求和用户故事是怎样的;这个 feature 做什么,如何做,难度怎样,需要多长时间,依赖项,需要做什么测试等。(Tips: 大的设计尽量拆分成小的设计,通过权衡和广泛的调研找到一个简单且可持续的解决方案,并且具备一定得到可扩展以适应未来的业务或技术变化,通过持续讨论和方案评审确定最终设计)。 -- 编写代码:通过高频小改动进行迭代、持续沟通和协作,提前设计单元测试、集成测试和 benchmark 等测试用例,确保编写代码 100% 测试覆盖,注释完整和逻辑清晰,并通过 Demo 演示持续收集反馈。 -- 文档撰写:在 [KCL 网站](https://kcl-lang.io) 中更新用户文档。 -- 测试和反馈:在发布功能之前,让一些同行/用户通过**随循文档**而不是口述来尝试和测试这些新功能。接收反馈并改进。 -- 发布和公告:撰写 Release Note, PR 文章,场景和新特性解读等以及渠道宣发等。 - -> 注:以上所有信息全是公开的,需要透出给所有社区研发者进行参与、讨论和贡献。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/release-policy/roadmap.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/release-policy/roadmap.md deleted file mode 100644 index 2f0ee86a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/community/release-policy/roadmap.md +++ /dev/null @@ -1,3 +0,0 @@ -# 路线规划 - -![](/img/docs/community/release-policy/roadmap.jpg) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/_category_.json deleted file mode 100644 index 1910abe4..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "参考手册", - "position": 5 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/cheatsheets/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/cheatsheets/_category_.json deleted file mode 100644 index 7839b7a2..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/cheatsheets/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "备忘录", - "position": 10 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/cheatsheets/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/cheatsheets/index.md deleted file mode 100644 index 6bfb2e4c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/cheatsheets/index.md +++ /dev/null @@ -1,5 +0,0 @@ -# KCL 备忘录 - -![](/img/docs/reference/cheatsheets/cheatsheet.png) - -[Download PDF](https://github.com/kcl-lang/kcl-lang.io/blob/main/cheatsheet/cheatsheet.pdf) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/index.md deleted file mode 100644 index 9fd0c276..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/index.md +++ /dev/null @@ -1 +0,0 @@ -# 学习 KCL diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/_category_.json deleted file mode 100644 index 6066c82b..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KCL", - "position": 1 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/codelab/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/codelab/_category_.json deleted file mode 100644 index c0133443..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/codelab/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "代码实验室", - "position": 2 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/codelab/collaborative.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/codelab/collaborative.md deleted file mode 100644 index 883f4853..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/codelab/collaborative.md +++ /dev/null @@ -1,345 +0,0 @@ ---- -title: "使用配置操作分块编写配置" -linkTitle: "使用配置操作分块编写配置" -type: "docs" -weight: 2 -description: 使用配置操作分块编写配置 -sidebar_position: 3 ---- - -## 1. Introduction - -KCL 是一种简单易用的配置语言,用户可以简单地编写可重复使用的配置代码。 - -在这个教程中,我们将学习如何使用 KCL 配置操作(config operation)功能以协同的方式编写配置。 - -### 本节将会学习 - -1. 定义 schema 并组织项目目录。 -2. 通过KCL的配置操作功能创建多个环境配置。 -3. 配置编译参数和测试。 - -## 2. 定义 Schema 和 组织项目目录 - -### Schema 定义 - -假设我们想定义具有某些属性的服务器配置,我们可以通过创建一个 `server.k` 文件来创建一个简单的配置,我们可以填写以下代码来定义服务器配置的可重用模式: - -```python -import units - -type Unit = units.NumberMultiplier - -schema Server: - replicas: int = 1 - image: str - resource: Resource = {} - mainContainer: Main = {} - labels?: {str:str} - annotations?: {str:str} - -schema Main: - name: str = "main" - command?: [str] - args?: [str] - ports?: [Port] - -schema Resource: - cpu?: int = 1 - memory?: Unit = 1024Mi - disk?: Unit = 10Gi - -schema Port: - name?: str - protocol: "HTTP" | "TCP" - port: 80 | 443 - targetPort: int - - check: - targetPort > 1024, "targetPort must be larger than 1024" -``` - -在上面的代码中,我们定义了一个名为 Server 的 schema,该 schema 表示用户将要编写的配置类型,其中包含一些基本类型属性(例如`replicas`、`image` 等)和一些复合类型属性(例如 `resource`、`main` 等)。除了一些在 [schema codelab](./schema.md)中提到的基本类型之外,我们可以看到上面的代码中有两种类型 `Unit` 和 `units.NumberMultiplier`。其中,`units.NumberMultiplier` 表示 KCL 数字单位类型,意味着可以在 KCL 数字后添加自然单位或二进制单位,例如 `1K` 表示 `1000`,`1Ki` 表示 `1024`。 `Unit` 是 `units.NumberMultiplier` 的类型别名,用于简化类型注释的编写。 - -### 项目目录 - -为了完成协同的配置的开发,我们首先需要一个配置项目,其中包含测试应用程序的配置以及不同环境的差异化配置,因此我们正在创建以下项目目录: - -``` -. -├── appops -│ └── test_app -│ ├── base -│ │ └── base.k -│ ├── dev -│ │ ├── ci-test -│ │ │ └── stdout.golden.yaml -│ │ ├── kcl.yaml -│ │ └── main.k -│ └── prod -│ ├── ci-test -│ │ └── stdout.golden.yaml -│ ├── kcl.yaml -│ └── main.k -├── kcl.mod -└── pkg - └── sever.k -``` - -该项目目录主要包含三个部分: - -- `kcl.mod`:用于标识KCL项目的根目录的文件。 -- `pkg`:不同应用程序配置所共用的 `Server Schema` 结构。 -- `appops`:不同应用程序的 Server 配置,目前仅包含一个名为 `test_app` 的应用程序。 - - `base`:供所有环境使用的应用程序通用配置。 - - `dev`:供开发环境使用的应用程序配置。 - - `prod`:供生产环境使用的应用程序配置。 - -后续章节将会介绍`base.k`、`main.k`、`kcl.yaml` 和 `ci-test/stdout.golden.yaml` 的含义。 - -## 3. 通过 KCL 配置操作功能创建多个环境配置 - -### 创建基线配置 - -在组织好项目目录和基本的服务器配置模型之后,我们可以编写用户应用程序的配置。我们可以创建自己的测试应用程序文件夹 `test_app`,并将其放置在应用程序配置文件夹 `appops` 中。 - -对于应用程序的配置,我们通常将其分为基本配置和多个环境的差异化配置并进行合并。通过 KCL 的配置合并功能,我们可以轻松实现这一点。假设我们有开发环境和生产环境的两个配置,我们可以创建三个文件夹:`base`、`dev` 和 `prod` 分别存储基线、开发环境和生产环境的配置。首先,我们编写 `base/base.k` 的配置: - -```python -import pkg - -server: pkg.Server { - # 设置镜像的值为 "nginx:1.14.2" - image = "nginx:1.14.2" - # 添加 app label - labels.app = "test_app" - # 添加一个mainContainer配置,它的端口是 [{protocol = "HTTP", port = 80, targetPort = 1100}] - mainContainer.ports = [{ - protocol = "HTTP" - port = 80 - targetPort = 1100 - }] -} -``` - -正如上述代码中所示,我们使用 `import` 关键字在 `base.k` 中导入放置在 `pkg` 下的 `Server` schema,并使用它实例化一个名为`server` 的配置,在其中将 `image` 属性设置为 `"nginx:1.14.2"`,并添加一个带有值为 `test_app` 的标签 `app`。此外,我们还在 `ports` 属性中添加了主容器 `mainContainer` 的配置,其值为 `[{protocol = "HTTP", port = 80, targetPort = 1100}]`。 - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k -``` - -输出: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2 - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app -``` - -当前,我们已经有了一个基线配置。 - -### 创建多重环境配置 - -接下来我们将配置一个差异化的多环境配置。首先假设我们想在开发环境中使用自己的临时镜像 `nginx:1.14.2-dev`,然后使用它来覆盖基准中的服务器配置,我们可以在 `dev/main.k` 中编写以下配置: - -```python -import pkg - -server: pkg.Server { - # 覆盖 base 配置中的声明的镜像 - image = "nginx:1.14.2-dev" -} -``` - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -输出: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app -``` - -可以看出输出的 YAML 文件的 `image` 字段被覆盖为 `nginx:1.14.2-dev`。假设我们还想将一个具有键为 `env`,值为 `dev` 的标签添加到 `dev` 环境中,我们将以下代码添加到 `dev/main.k` 中: - -```python -import pkg - -server: pkg.Server { - # 覆盖 base 配置中的声明的镜像 - image = "nginx:1.14.2-dev" - # 将新标签 env 合并到 base 标签中 - labels.env = "dev" -} -``` - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app - env: dev -``` - -可以看到输出的 YAML 文件的 `labels` 字段中有两个标签。 - -此外,我们还可以使用 `+=` 运算符将新值添加到列表类型属性中,例如在基准环境中的 `mainContainer.ports` 配置,继续修改 `dev/main.k` 中的代码: - -```python -import pkg - -server: pkg.Server { - # 覆盖 base 配置中的声明的镜像 - image = "nginx:1.14.2-dev" - # 将新标签 env 合并到 base 标签中 - labels.env = "dev" - # 在 base ports配置中添加一个 port - mainContainer.ports += [{ - protocol = "TCP" - port = 443 - targetPort = 1100 - }] -} -``` - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -输出: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - - protocol: TCP - port: 443 - targetPort: 1100 - labels: - app: test_app - env: dev -``` - -使用相同的方法,我们可以构建生产配置,在 `dev/main.k` 文件中编写代码,并为其添加标签。 - -```python -import pkg - -server: pkg.Server { - # 将新标签 env 合并到 base 标签中 - labels.env = "prod" -} -``` - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k appops/test_app/prod/main.k -``` - -输出: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2 - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app - env: prod -``` - -## 4. 配置编译参数和测试 - -在前面的章节中,我们通过代码构建了一个多环境配置。可以看出不同环境的 KCL 命令行编译参数相似,因此我们可以将这些编译参数配置到一个文件中,并将其输入到 KCL 命令行中进行调用。请将以下代码配置在 `dev/kcl.yaml`中: - -```yaml -kcl_cli_configs: - files: - - ../base/base.k - - main.k - output: ./ci-test/stdout.golden.yaml -``` - -然后我们可以使用以下命令在开发环境中编译配置: - -```bash -cd appops/test_app/dev && kcl -Y ./kcl.yaml -``` - -此外,我们已经在 `dev/kcl.yaml` 中配置了 `output` 字段,以将 YAML 输出到文件,以便进行后续配置分发或测试。您可以通过遍历每个环境中的 `kcl.yaml` 构建,并将其与 `./ci-test/stdout.golden.yaml` 进行比较,可以验证应用程序的配置是否符合预期。 - -## 5. 最后 - -恭喜! - -我们已经完成了关于 KCL 的第三课。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/codelab/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/codelab/index.md deleted file mode 100644 index 123c0878..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/codelab/index.md +++ /dev/null @@ -1 +0,0 @@ -# 代码实验室 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/codelab/schema.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/codelab/schema.md deleted file mode 100644 index 434e1f5c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/codelab/schema.md +++ /dev/null @@ -1,814 +0,0 @@ ---- -title: "使用 KCL Schema 编写复杂配置" -linkTitle: "使用 KCL Schema 编写复杂配置" -type: "docs" -weight: 2 -description: 使用 KCL Schema 编写复杂配置 -sidebar_position: 2 ---- - -## 1. 介绍 - -KCL 是一种简单易用的配置语言,用户可以简单地编写可重用的配置代码。 - -在本节教程中,我们将学习如何使用 KCL 编写定制配置,这样我们就可以定义一个架构并以协作方式编写配置。 - -### 本节将会学习 - -1. 定义一个简单的 schema -2. 为 schema 字段设置默认的不可变值 -3. 基于简单的 schema 创建配置 -4. 在 schema 中编写复杂的逻辑 -5. 通过 schema 的组合创建新的 schema -6. 使用 dict/map 创建具有深度嵌套 schema 的配置 -7. 通过 schema 继承创建新的 schema -8. 通过多个 mixin schema 创建新的 schema -9. 声明 schema 验证规则 -10. 配置 schema 的输出布局 -11. 共享和重用 schema - -## 2. 编写简单的 Schema - -假设我们希望定义一个具有特定属性的工作负载,我们可以通过创建一个 `my_config.k` 文件来创建一个简单的配置。我们可以按以下方式填写下面的代码,定义一个可重复使用的部署配置的 schema: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels: {str:str} -``` - -在上述代码中,`cpu` 和 `memory` 被定义为 int 值;`name`、`image` 和 `service` 是字符串;`command` 是由字符串构成的列表;`labels` 是字典类型,其键和值的类型均为字符串。 - -另外,每个属性都**必须**被赋予非 None 值作为 schema 实例,除非它被标记问号 **?** 而作为可选参数。 - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels?: {str:str} # labels 是一个可选的参数 -``` - -当存在继承关系时: - -- 如果在基 schema 中该属性为可选(optional)参数,则在子 schema 中它应该是可选的(optional)或必需的(required)。 -- 如果在基 schema 中该属性为必需(required)属性,则在子 schema 中它需要是必需的(required)。 - -## 3. Enhance Schema as Needed - -Suppose we need to set default values to service and replica, we can make them as below: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str = "my-service" # defaulting - replica: int = 1 # defaulting - command: [str] - labels?: {str:str} # labels is an optional attribute -``` - -And then we can set the service type annotation as the string literal type to make it immutable: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: "my-service" = "my-service" - replica: int = 1 - command: [str] - labels?: {str:str} -``` - -In the schema, type hint is a `must`, for example we can define cpu as `cpu: int`. - -Specially, we can define a string-interface dict as `{str:}`, and in case we want to define an object or interface, just define as `{:}`. - -## 4. 基于简单 Schema 创建配置 - -现在我们有了一个简单的 schema 定义,我们可以用它来定义配置: - -```python -nginx = Deployment { - name = "my-nginx" - cpu = 256 - memory = 512 - image = "nginx:1.14.2" - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python - kcl my_config.k -``` - -标准输出: - -```yaml -nginx: - name: my-nginx - cpu: 256 - memory: 512 - image: nginx:1.14.2 - service: my-service - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -> 有关集合数据类型和块的更多详细信息,请查看手册和规范。 - -此外,**配置选择器表达式**(config selector expressions)可以用于初始化 schema 实例,我们可以忽略配置表达式中行末的逗号。 - -```python -nginx = Deployment { - name = "my-nginx" - cpu = 256 - memory = 512 - image = "nginx:1.14.2" - command = ["nginx"] # 忽略行尾的逗号 - labels.run = "my-nginx" # schema 中的字典变量可以使用选择器表达式 - labels.env = "pre-prod" # schema 中的字典变量可以使用选择器表达式 -} -``` - -## 5. 在 Schema 中编写更为复杂的逻辑 - -假设我们有一些schema逻辑,我们可以将它包装进 schema 中: - -```python -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - image: str - service: "my-service" = "my-service" - replica: int = 1 - command: [str] - labels?: {str:str} - - _cpu = 2048 - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 -``` - -现在,我们可以通过创建 schema 实例来定义配置,并将优先级作为参数传递给模式: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl my_config.k -``` - -标准输出: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - image: nginx:1.14.2 - service: my-service - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 6. 通过 Schema 组合创建新 Schema - -现在我们想要定义一个详细的 schema,包括服务(service)和卷(volumes),我们可以按以下方式进行操作: - -```python -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - volumes?: [Volume] - image: str - service?: Service - replica: int = 1 - command: [str] - labels?: {str:str} - - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 - -schema Port: - name: str - protocol: str - port: int - targetPort: int - -schema Service: - name: "my-service" = "my-service" - ports: [Port] - -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -在这种情况下,Deployment 由 Service 和一系列 Volume 组成,而 Service 又由一系列 Port 组成。 - -## 7. 使用 dict/map 创建具有深度嵌套 schema 的配置 - -现在我们有一个新的 Deployment schema,但我们可能会注意到,它包含多层嵌套的结构,在复杂的结构定义中,这是非常常见的,我们通常必须编写命令式组装代码来生成最终结构。 - -使用 KCL,我们可以使用简单的字典声明创建配置,并具有完整的 schema 初始化和验证功能。例如,我们可以按照以下方式使用新的 Deployment schema简单地配置 nginx: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl my_config.k -``` - -标准输出: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -请注意,我们用于定义 Deployment 配置的字典必须与 schema 定义对齐,否则我们将会得到一个错误。例如,假设我们将服务端口的类型定义错误如下: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = [80] # 错误的数据类型,试图将 List 分配给 int - targetPort = 9376 - }] -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl my_config.k -``` - -标准错误输出: - -``` -The type got is inconsistent with the type expected: expect int, got [int(80)] -``` - -## 8. 声明 Schema 验证规则 - -现在我们已经看到了一个复杂的 schema,在其中每个字段都有一个类型提示,以使其更加不容错(error-prone)。 - -但是这还不够好,我们希望为我们的 schema 支持更多的增强验证,以便尽快发现 schema 和配置中的代码错误。许多验证规则,如 None 类型检查、范围检查、值检查、长度检查、正则表达式匹配、枚举检查已经被添加或陆续添加进来。以下是一段代码示例: - -```python -import regex - -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - volumes?: [Volume] - image: str - service?: Service - replica: int = 1 - command: [str] - labels?: {str:str} - - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 - - check: - multiplyof(cpu, 256), "cpu must be a multiplier of 256" - regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$"), "image name should be like 'nginx:1.14.2'" - 1 <= replica < 100, "replica should be in range (1, 100)" - len(labels) >= 2 if labels, "the length of labels should be large or equal to 2" - "env" in labels, "'env' must be in labels" - len(command) > 0, "the command list should be non-empty" - -schema Port: - name: str - protocol: str - port: int - targetPort: int - - check: - port in [80, 443], "we can only expose 80 and 443 port" - protocol in ["HTTP", "TCP"], "protocol must be either HTTP or TCP" - 1024 < targetPort, "targetPort must be larger than 1024" - -schema Service: - name: "my-service" = "my-service" - ports: [Port] - - check: - len(ports) > 0, "ports list must be non-empty" - -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -由于schema定义的属性默认是**必需的**(required),因此可以省略判断变量不能为 None/Undefined 的验证。 - -```python -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -现在我们可以基于新的 schema 编写配置,并及时暴露配置错误。例如,使用以下无效的配置: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1142" # 镜像值不匹配正则表达式 - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -每个字段都是类型有效的,但镜像名无效。 - -运行 KCL,我们将看到如下错误信息: - -KCL 命令: - -```python -kcl my_config.k -``` - -标准错误输出: - -``` -Schema check is failed to check condition: regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$"), "image name should be like 'nginx:1.14.2'" -``` - -> KCL 的验证功能涵盖了 Openapi 定义的验证,因此我们可以通过 KCL 编写任何 API 验证。 - -## 9. 通过 Schema 继承创建新 Schema - -现在,我们拥有了一个稳定的部署 schema 定义,可以用它来声明配置。 - -通常,部署 schema 将被用于多个场景中。我们可以直接使用 schema 在不同的用例中声明配置(见上文的部分),或者我们可以通过继承生成一个更具体的 schema 定义。 - -例如,我们可以使用部署 schema 作为基础,来定义 nginx 的基本 schema,并在每个场景中扩展定义。在这种情况下,我们定义了一些常用的属性。请注意,我们使用“final”关键字将名称标记为不可变,以防止被覆盖。 - -```python -schema Nginx(Deployment): - """ A base nginx schema """ - name: "my-nginx" = "my-nginx" - image: str = "nginx:1.14.2" - replica: int = 3 - command: [str] = ["nginx"] - -schema NginxProd(Nginx): - """ A prod nginx schema with stable configurations """ - volumes: [Volume] = [{ - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - """ A volume mapped to host path """ - service: Service = { - ports = [{ - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] - } - """ An 80 port to target backend server """ -``` - -现在我们有了一些 nginx 的静态配置。建议将我们认为是静态的配置声明在那里,并将更多的动态配置放在下面: - -```python -nginx = Nginx { - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -```python -nginx = NginxProd { - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -现在,我们只需要通过运行时标签值 “prod” 来简单定义 不那么静态的 nginx 生产环境配置。 - -实际上,在某些复杂情况下,我们可以将所有配置分为基本配置、业务配置和环境配置定义,并基于此实现团队成员之间的协作。 - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl prod_config.k -``` - -标准输出: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 3 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 10. Create New Schema by Multiple Protocol and Mixin Schemas Inheritance - -现在,我们可以通过 Deployment schema 完成服务器配置的声明。 - -然而,通常实际情况更为复杂,部署可能有各种可选变量附件。 - -例如,我们想要在现有 schema 中支持声明持久卷,作为可重用的 Kubernetes schema。在这种情况下,我们可以通过以下 `mixin` 和 `protocal` 进行包装: - -```python -import k8spkg.api.core.v1 - -protocol PVCProtocol: - pvc?: {str:} - -mixin PersistentVolumeClaimMixin for PVCProtocol: - """ - PersistentVolumeClaim (PVC) sample: - Link: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims - """ - - # Mix in a new attribute `kubernetesPVC` - kubernetesPVC?: v1.PersistentVolumeClaim - - if pvc: - kubernetesPVC = v1.PersistentVolumeClaim { - metadata.name = pvc.name - metadata.labels = pvc.labels - spec = { - accessModes = pvc.accessModes - resources = pvc.resources - storageClassName = pvc.storageClassName - } - } -``` - -有了 PersistentVolumeClaimMixin,我们使用清晰的用户界面(user interface)定义了一个 PVC schema,并使用 Kubernetes PVC 作为实现。然后,我们可以使用 Deployment schema 和 PVC mixin schema 定义一个 server schema。 - -```python -schema Server(Deployment): - mixin [PersistentVolumeClaimMixin] - pvc?: {str:} - """ pvc user interface data defined by PersistentVolumeClaimMixin """ -``` - -在 Server schema 中,Deployment schema 是基础 schema,而 PersistentVolumeClaimMixin 是一个可选附加项,其用户界面数据为`pvc?:{str:}`。 - -请注意,mixin 通常用于向宿主 schema 添加新属性,或修改宿主 schema 的现有属性。因此,mixin 可以使用宿主 schema 中的属性。由于其被设计为可重用,因此我们需要一个额外的协议来限制 mixin 中宿主 schema 中属性的名称和类型。 - -现在,如果我们想要使用 PVC 进行部署,只需声明用户界面: - -```python -server = Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] - pvc = { - name = "my_pvc" - accessModes = ["ReadWriteOnce"] - resources.requests.storage = "8Gi" - storageClassName = "slow" - } -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl server.k -``` - -标准输出: - -```yaml -server: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod - pvc: - name: my_pvc - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 8Gi - storageClassName: slow ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: my_pvc -spec: - accessModes: - - ReadWriteOnce - storageClassName: slow - resources: - requests: - storage: 8Gi -``` - -如果我们不需要持久卷,只需删除 pvc 配置块。 - -## 11. 共享和重用 Schema - -可以通过导入来共享 Server schema,我们只需要将代码与 KCL 一起打包即可。 - -```python -import pkg - -server = pkg.Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -另一个关于共享代码的技巧是:在同一包下的模块不需要相互导入。 - -假设我们在 pkg 中有如下 models: - -``` -pkg/ - - deploy.k - - server.k - - pvc.k -``` - -在 `server.k` 中,我们可以只使用 `deploy.k` 中的 Deployment schema 和 `pvc.k` 中的 pvc schema 而无需导入: - -```python -# 无需 import -schema Server(Deployment): - mixin [PersistentVolumeClaimMixin] - pvc?: {str:} - """ pvc user interface data defined by PersistentVolumeClaimMixin """ -``` - -然后用户必须导入 pkg 才能作为一个整体使用它: - -```python -import pkg - -server = pkg.Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [pkg.Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } - service.ports = [pkg.Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -运行 KCL 命令: - -```python -kcl pkg_server.k -``` - -Output: - -```yaml -server: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 12. 最后 - -恭喜! - -我们已经完成了 KCL 的第二节课。我们使用 KCL 来替换我们的 key-value 文本文件,以便获得更好的可编程性。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/codelab/simple.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/codelab/simple.md deleted file mode 100644 index 32ad2612..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/codelab/simple.md +++ /dev/null @@ -1,495 +0,0 @@ ---- -title: "使用 KCL 编写简单配置" -linkTitle: "使用 KCL 编写简单配置" -type: "docs" -weight: 2 -description: 使用 KCL 编写简单配置 -sidebar_position: 1 ---- - -## 1. 介绍 - -KCL 是一种简单易用的配置语言,用户可以简单地编写可重用的配置代码。 - -在这个第一个教程中,我们将学习如何使用 KCL 编写一个简单的配置。 - -学习这个代码实验只需要基本的编程知识,如果你有 Python 经验,将会更容易上手。 - -### 本节将会学习 - -1. 用一种可编程的方式编写简单的 key-value 配置 -2. 使用 KCL 编写简单的逻辑 -3. 使用 KCL 编写集合(collections) -4. 使用 KCL 代码进行测试和调试 -5. 在 KCL 代码中使用内置(built-in)支持 -6. 共享和重用 KCL 代码 -7. 使用动态输入参数编写配置 - -## 2. 编写Key-Value键值对 - -通过创建 `my_config.k` 来生成一个简单的配置,我们可以填充下面的代码,并且不需要严格的格式描述部署的配置。 - -```python -cpu = 256 -memory = 512 -image = "nginx:1.14.2" -service = "my-service" -``` - -在上述代码中,cpu 和 memory 被声明为 int 类型的值,而 image 和 service 被声明为字符串字面值。 - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -KCL 命令: - -```bash -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -可导出变量(exported variable)默认情况下是不可变的,一旦声明,就不能在其他地方修改它。 - -## 3. 编写简单逻辑 - -有时候我们想在配置中编写一些逻辑,那么我们就可以使用: - -- 以 `_` 开头的非导出可变变量(mutable and non-exported variable) -- if-else 语句 - -非导出变量表示它不会出现在输出的 YAML 中,且它可以被多次赋值。 - -这是一个示例,显示如何根据条件调整资源。 - -KCL 命令: - -```python -kcl my_config.k -``` - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -image = "nginx:1.14.2" -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -```python -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -.. 注意:: -KCL 对运算符和字符串成员函数有丰富的支持,请阅读手册和规范以了解更多细节。 - -## 4. 编写集合 - -我们可以使用集合来表示复杂的数据类型。已支持的集合类型有: - -- list -- dict - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -command = ["nginx"] # 列表 -labels = {run = "my-nginx"} # a dict -image = "nginx:1.14.2" -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -KCL 命令: - -```bash -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx -image: nginx:1.14.2 -service: my-service -``` - -> 有关集合数据类型和成员函数的更多信息,请查阅手册和规范。 - -## 5. 在集合中添加元素 - -我们可以将逻辑表达式、推导式、切片、联合类型等特性组合起来,动态地将元素添加到集合中。 - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 -_env = "pre-prod" - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -_command = ["nginx"] # 列表 -_command = _command + ["-f", "file"] # 使用 + 运算符将元素附加到命令中以连接两个列表 -command = [c.lower() for c in _command] # # 将列表中的每个元素转为小写 -_labels = { - run = "my-nginx" - if _env: - env = _env # 当 _env 不是 None/Undefined 或为空时使用 if 表达式添加一个字典键值对 -} # 字典 -labels = _labels -image = "nginx:1.14.2" -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -```python -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 256 -memory: 512 -command: - - nginx - - -f - - file -labels: - run: my-nginx -image: nginx:1.14.2 -service: my-service -``` - -## 6. 编写断言 - -为了使代码可测试且健壮,我们可以使用断言(assertions)验证配置数据。 - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -command = ["nginx"] # 列表 -labels = {run = "my-nginx"} # 字典 -image = "nginx:1.14.2" -service = "my-service" -assert "env" in labels, "env label is a must" -assert cpu >= 256, "cpu cannot be less than 256" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -```bash -kcl my_config.k -``` - -标准错误输出: - -```bash -Assertion failure: env label is a must. -``` - -将 env:pre-prod 对添加到标签中后,我们将得到如下输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 7. 使用方便的内置支持 - -更重要的是,我们可以使用内置函数来帮助我们调试或简化编码。 - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -_name = "nginx" -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # 列表 -labels = { - run = "my-{}".format(_name) - env = "pre-prod" -} # a dict -image = "{}:1.14.2".format(_name) # 字符串格式 -service = "my-service" - -# debugging -print(labels) # 通过打印调式 - -# test -assert len(labels) > 0, "labels can't be empty" # 使用 len() 得到列表长度 -assert "env" in labels, "env label is a must" -assert cpu >= 256, "cpu cannot be less than 256" -``` - -此示例展示了我们如何使用 `format()`、`len()`、`print()` 函数来帮助自定义配置。 - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -KCL 命令: - -```bash -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -run: my-nginx -env: pre-prod -``` - -注意:更多的内置函数和模块可以在 spec/module 目录中查看。 - -## 8. 重用另一个模块的变量 - -为了使我们的代码得到良好的组织,我们可以将代码简单地分为 `my_config.k` 和 `my_config_test.k` 两个文件。 - -在 `my_config.k` 中定义配置数据: - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 -_name = "nginx" - -# 可导出变量 -cpu = _cpu -memory = _cpu * 2 -command = [_name] # 列表 -labels = { - run = "my-{}".format(_name) - env = "pre-prod" -} # a dict -image = "{}:1.14.2".format(_name) # 字符串格式 -service = "my-service" -``` - -而测试代码定义在 `my_config_test.k` 中,我们可以在其中导入 `my_config.k`: - -```python -import my_config - -# debugging -print(my_config.labels) # 通过打印调试 - -# test -assert len(my_config.labels) > 0, "labels can't be empty" # 使用 len() 得到列表长度 -assert "env" in my_config.labels, "env label is a must" -assert my_config.cpu >= 256, "cpu cannot be less than256" -``` - -## 9. 配置输入参数 - -有时我们需要获得通过从最终用户或平台动态获取的外部输入参数。 - -在这种情况下,我们可以按需传递 `priority` 和 `env` 参数: - -- 通过参数传递: `-D priority=1 -D env=pre-prod` -- 可以在 KCL 代码中使用 `option` 关键字获取这些值 - -```python -_priority = option("priority") # 非导出可变变量 -_env = option("env") # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -_name = "nginx" -# 可导出变量 -cpu = _cpu -memory = _cpu * 2 -command = [_name] # 列表 -labels = { - run = "my-{}".format(_name) - env = _env -} # a dict -image = "{}:1.14.2".format(_name) # 字符串格式 -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -```bash -kcl my_config.k -D priority=2 -D env=pre-prod -``` - -标准输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 10. 使用 Dict 简化逻辑表达式 - -当我们需要编写复杂的逻辑时,可以使用dict来简化逻辑的编写。 - -```python -_priority = option("priority") # 非导出可变变量 -_env = option("env") # 非导出可变变量 -_priorityCpuMap = { - "1" = 256 - "2" = 512 - "3" = 1024 -} -# 使用字典简化逻辑,默认值为2048 -_cpu = _priorityCpuMap[_priority] or 2048 -_name = "nginx" -# 可导出变量 -cpu = _cpu -memory = _cpu * 2 -command = [_name] # 列表 -labels = { - run = "my-{}".format(_name) - env = _env -} # a dict -image = "{}:1.14.2".format(_name) # 字符串格式 -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -KCL 命令: - -```bash -kcl my_config.k -D priority=2 -D env=pre-prod -``` - -标准输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 11. 最后 - -恭喜! - -我们已经完成了关于 KCL 的第一课程,我们使用 KCL 来替换我们的键值文本文件,以获得更好的编程支持。 - -建议立即查看架构代码实验,以了解如何使用 KCL `schema` 机制协作编写高级配置。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/error/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/error/_category_.json deleted file mode 100644 index 4f285ced..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/error/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "错误与警告", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/error/_error.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/error/_error.md deleted file mode 100644 index a2f192b8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/error/_error.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: "错误检查" -linkTitle: "错误检查" -type: "docs" -weight: 1 -description: KCL 语言规范 ---- - -When errors happen, developers should be able to detect the error and abort -execution. Thus, KCL introduce the `assert` syntax. - -In the previous topic of `schema` syntax. Errors can also be raised when a -schema is violated. - -## Syntax - -The syntax of the `assert` statement is the following. - -``` -assert_stmt: 'assert' test [',' test] -``` - -In the basic form, an `assert` statement evaluates an expression. If the -expression is evaluated to `False`, the assertion is failed, and an error -should be reported. - -In the extended form, an error message can be provided. The error message is -another expression. It is only evaluated when the expression to be evaluated -is evaluated to `False`. The evaluation result of the error message is printed -when reporting the error. - -The following is an example: - -```py -a = 1 -b = 3 -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -``` - -## The Implementation - -When an error happens, no matter it is caused by the `assert` or the `schema` syntax, -the virtual machine should exit with an exit code greater than `0`. - -The virtual machine may choose to dump the back trace information, and it is strongly -recommended to implement it. - -In practice, KCL can dump back trace by default, and an argument can be introduced -to disable it. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/error/exception.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/error/exception.md deleted file mode 100644 index cd18995f..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/error/exception.md +++ /dev/null @@ -1,1584 +0,0 @@ ---- -title: "KCL 错误与警告" -linkTitle: "KCL 错误与警告" -type: "docs" -weight: 2 -description: KCL 错误与警告 ---- - -# KCL 错误与警告 - -文档的此部分中的文章介绍了由 KCL 生成的诊断错误和警告消息。 - -**注意:** -**KCL 可以报告多种错误和警告。找到错误或警告后,KCL 可能会对代码意向作出假设并尝试继续,以便可以同时报告更多问题。 如果工具做出错误假设,则后续错误或警告可能不适应与当前 KCL 程序。 因此,纠正项目中的问题时,请先纠正第一个错误或警告,然后重新运行获取新的错误信息。 一个修补程序可能会导致后续错误消失。** - -此部分文档的主要内容包括: - -[KCL 语法错误 (E1xxx)](#11-kcl-%E8%AF%AD%E6%B3%95%E9%94%99%E8%AF%AF-e1xxx) : 如果 KCL 在当前 KCL 程序中发现了非法的 KCL 语法,KCL 就会停止运行并输出 KCL 程序语法错误的提示信息. - -[KCL 编译错误 (E2xxx)](#12-kcl-%E7%BC%96%E8%AF%91%E9%94%99%E8%AF%AF-e2xxx) : 如果 KCL 在一个不包含语法错误的 KCL 程序中发现了与 KCL 语义不符的代码,KCL 就会停止运行并输出编译错误的提示信息。 - -[KCL 运行时错误 (E3xxx)](#13-kcl-%E8%BF%90%E8%A1%8C%E6%97%B6%E9%94%99%E8%AF%AF-e3xxx) : KCL 程序通过编译后会生成 KCL 字节码,如果 KCL 在执行 KCL 字节码过程中出现错误,KCL 就会停止运行并输出运行时错误的提示信息. - -[KCL 编译警告 (W2xxx)](#14-kcl-%E7%BC%96%E8%AF%91%E8%AD%A6%E5%91%8A-w2xxx) : 当 KCL 发现可能导致运行失败的 KCL 代码,KCL 不会立即停止运行,但是会输出潜在错误的警告提示。 - -## 1.1 KCL 语法错误 (E1xxx) - -KCL 会出现的语法错误信息如下表所示: - -| ewcode | KCL exception | messages | -| ------ | ------------------------------------------------------------------- | ----------------------- | -| E1001 | [InvalidSyntaxError](#111-invalidsyntaxerror-e1001) | Invalid syntax | -| E1002 | [KCLTabError](#112-kcltaberror-e1002) | Tab Error | -| E1003 | [KCLIndentationError](#113-kclindentationerror-e1003) | Indentation Error | -| E1I37 | [IllegalArgumentSyntaxError](#114-illegalargumentsyntaxerror-e1i37) | Illegal argument syntax | - -### 1.1.1 InvalidSyntaxError [E1001] - -如果在运行 KCL 时遇到错误: - -- `InvalidSyntaxError`, 对应的 encode 为 `E1001` - -那么此时 KCL 程序中出现了 - -- 非法的 KCL 语法。 - -可能出现错误的 KCL 程序片段如下: - -```python -a, b = 1, 2 # 通过 “=” 赋值多个变量在KCL中是非法的。 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> /syntax_error/general/multiple_assign/case0/main.k:1:2 - | -1 | a, b = 1, 2 # Multiple assign is illegal in KCL syntax - | ^ expected statement - | -``` - -### 1.1.2 KCLTabError - -如果在运行 KCL 时遇到错误: `KCLTabError` - -那么此时 KCL 程序中出现了 - -- Tab 与空格混用的问题。KCL 中禁止在代码缩进中混用 Tab 和空格。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - name: str # 通过tab表示缩进 - age: int # 通过四个空格标识缩进, - # 在当前运行环境中的四个空格与tab不同 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> File /syntax_error/tab/tab_error_0/main.k:6:5 - | -3 | age: int = 1 - | ^ inconsistent use of tabs and spaces in indentation - | -``` - -可以尝试以下步骤来修复这个错误: - -- 在 KCL 程序中全部使用 Tab 或者全部使用四个空格,不要混用。 - -### 1.1.3 KCLIndentationError - -如果在运行 KCL 时遇到错误: `KCLIndentationError` - -那么此时 KCL 程序中出现了 - -- 程序缩进错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - name: str # 使用一个tab或者四个空格表示缩进 - age: int # KCL不支持使用三个空格表示缩进 - info: str # KCL不支持使用两个空格表示缩进 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> /syntax_error/indent/indent_error_0/main.k:3:4 - | -3 | age: int # three white spaces are illegal - | ^ unindent 3 does not match any outer indentation level - | -``` - -可以尝试以下步骤来修复这个错误: - -- 在 KCL 程序中全部使用 Tab 或者全部使用四个空格来表示缩进。 - -### 1.1.4 IllegalArgumentSyntaxError - -如果在运行 KCL 时遇到错误: `IllegalArgumentSyntaxError` - -那么此时 KCL 程序中出现了 - -- 参数语法错误 - -可能出现错误的 KCL 程序片段如下: - -```python -# KCL中带有keyword的参数必须出现在不带有keyword参数后面 -# 带有keyword的参数: type="list", default={"key": "value"} -# 不带有keyword的参数: "key1" -a = option(type="list", default={"key": "value"}, "key1") -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> /option/type_convert_fail_2/main.k:3:57 - | -3 | a = option(type="list", default={"key": "value"}, "key1") - | ^ positional argument follows keyword argument - | -``` - -可以尝试以下步骤来修复这个错误: - -- KCL 中带有 keyword 的参数必须出现在不带有 keyword 参数后面, 参数正常顺序: - -```python -func(input_1, ..., input_n, param_with_key_1 = input_with_key_1, ..., param_with_key_n = input_with_key_n) -``` - -## 1.2 KCL 编译错误 (E2xxx) - -KCL 会出现的编译错误信息如下表所示: - -| ewcode | KCL exception | messages | -| ------ | ----------------------------------------------------------------------- | --------------------------------------------------- | -| E2F04 | [CannotFindModule](#121-cannotfindmodule-e2f04) | Cannot find the module | -| E2F05 | [FailedLoadModule](#122-failedloadmodule-e2f05) | Failed to load module | -| E2H13 | [UnKnownDecoratorError](#123-unknowndecoratorerror-e2h13) | UnKnown decorator | -| E2H14 | [InvalidDecoratorTargetError](#124-invaliddecoratortargeterror-e2h14) | Invalid Decorator Target | -| E2C15 | [MixinNamingError](#125-mixinnamingerror-e2c15) | Illegal mixin naming | -| E2C16 | [MixinStructureIllegal](#126-mixinstructureillegal-e2c16) | Illegal mixin structure | -| E2B17 | [CannotAddMembersComplieError](#127-cannotaddmemberscomplieerror-e2b17) | Cannot add members to a schema | -| E2B20 | [IndexSignatureError](#128-indexsignatureerror-e2b20) | Invalid index signature | -| E2G22 | [TypeComplieError](#129-typecomplieerror-e2g22) | The type got is inconsistent with the type expected | -| E2L23 | [CompileError](#1210-compileerror-e2l23) | A complie error occurs during compiling | -| E2L25 | [KCLNameError](#1211-kclnameerror-e2l25) | Name Error | -| E2L26 | [KCLValueError](#1212-kclvalueerror-e2l26) | Value Error | -| E2L27 | [KCLKeyError](#1213-kclkeyerror-e2l27) | Key Error | -| E2L28 | [UniqueKeyError](#1214-uniquekeyerror-e2l28) | Unique key error | -| E2A29 | [KCLAttributeComplieError](#1215-kclattributecomplieerror-e2a29) | Attribute error occurs during compiling | -| E2D32 | [MultiInheritError](#1216-multiinheriterror-e2d32) | Multiple inheritance is illegal | -| E2D34 | [IllegalInheritError](#1217-illegalinheriterror-e2d34) | Illegal inheritance | -| E2I36 | [IllegalArgumentComplieError](#1218-illegalargumentcomplieerror-e2i36) | Illegal argument during compiling | -| E3L41 | [ImmutableCompileError](#1219-immutablecompileerror-e3l41) | Immutable variable is modified | - -### 1.2.1 CannotFindModule [E2F04] - -如果在运行 KCL 时遇到错误: - -- `CannotFindModule`, 对应的 encode 为 `E2F04` - -那么此时 KCL 程序中出现了 - -- 无法找到导入模块错误 - -可能出现错误的 KCL 程序片段如下: - -```python -import .some0.pkg1 as some00 # some0 not found in package - -Name1 = some00.Name # some0.pkg1.name -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2F04]: CannotFindModule - --> import_abs_fail_0/app-main/main.k:1:1 - | -1 | import .some0.pkg1 as some00 # some0 not found in package - | Cannot find the module .some0.pkg1 - | -``` - -可以尝试以下步骤来修复这个错误: - -- 在 import 路径下添加导入模块文件。 - -### 1.2.2 FailedLoadModule [E2F05] - -如果在运行 KCL 时遇到错误: - -- `FailedLoadModule`, 对应的 encode 为 `E2F05` - -那么此时 KCL 程序中出现了 - -- 导入模块加载错误 - -可以尝试以下步骤来修复这个错误: - -- 查看文件是否可读 -- 查看文件是否为 kcl 文件 - -### 1.2.3 UnKnownDecoratorError - -如果在运行 KCL 时遇到错误: - -- `UnKnownDecoratorError`, 对应的 encode 为 `E2H13` - -那么此时 KCL 程序中出现了 - -- 未知的装饰器错误 - -可能出现错误的 KCL 程序片段如下: - -```python -@err_deprecated # 这是一个非法的装饰器 -schema Person: - firstName: str = "John" - lastName: str - name: str - -JohnDoe = Person { - name: "deprecated" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> deprecated/unknown_fail_1/main.k:1:2 - | -1 | @err_deprecated # 这是一个非法的装饰器 - | ^ UnKnown decorator err_deprecated - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查装饰器是否存在。 - -### 1.2.4 InvalidDecoratorTargetError [E2H14] - -如果在运行 KCL 时遇到错误: - -- `InvalidDecoratorTargetError`, 对应的 encode 为 `E2H14` - -那么此时 KCL 程序中出现了 - -- 无效的装饰器目标错误。 - -可以尝试以下步骤来修复这个错误: - -- 检查使用装饰器的 KCL 代码是否出现异常。 - -### 1.2.5 MixinNamingError [E2C15] - -如果在运行 KCL 时遇到错误: - -- `MixinNamingError`, 对应的 encode 为 `E2C15` - -那么此时 KCL 程序中出现了 - -- Mixin 命名错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - firstName: str - lastName: str - fullName: str - -schema Fullname: # Mixin的名称应该以Mixin结尾 - fullName = "{} {}".format(firstName, lastName) - -schema Scholar(Person): - mixin [Fullname] - school: str - -JohnDoe = Scholar { - "firstName": "John", - "lastName": "Doe", - "fullName": "Doe Jon" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2D34]: IllegalInheritError - --> mixin/invalid_name_failure/main.k:10:12 - | -10 | mixin [Fullname] - | ^ illegal schema mixin object type 'Fullname' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 如果 schema 是一个 mixin,那么这个 schema 的名称应该以 Mixin 结尾。 - -### 1.2.6 MixinStructureIllegal [E2C16] - -如果在运行 KCL 时遇到错误: - -- `MixinStructureIllegal`, 对应的 encode 为 `E2C16` - -那么此时 KCL 程序中出现了 - -- Mixin 结构错误。 - -可以尝试以下步骤来修复这个错误: - -- 检查作为 Mixin 的 Schema 的结构。 - -### 1.2.7 CannotAddMembersComplieError [E2B17] - -如果在运行 KCL 时遇到错误: - -- `CannotAddMembersComplieError`, 对应的 encode 为 `E2B17` - -那么此时 KCL 程序中出现了 - -- 使用 Schema 中不存在的成员。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Girl: - gender: str = "female" - -alice = Girl { - "first": "alice", # Schema中没有成员“first” - "last": " Green", # Schema中没有成员“last” - "age": 10 # Schema中没有成员“age” -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:5:5 - | -5 | "first": "alice", - | ^ Cannot add member 'first' to schema 'Girl' - | - -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:6:5 - | -6 | "last": " Green", - | ^ Cannot add member 'last' to schema 'Girl' - | - -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:7:5 - | -7 | "age": 10 - | ^ Cannot add member 'age' to schema 'Girl' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 为 Schema 添加缺少的成员。 -- 不要使用 Schema 中不存在的成员。 - -### 1.2.8 IndexSignatureError [E2B20] - -如果在运行 KCL 时遇到错误: - -- `IndexSignatureError`, 对应的 encode 为 `E2B20` - -那么此时 KCL 程序中出现了 - -1. 在一个 schema 中使用多个索引签名。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Data: - [str]: str - [str]: int # 在同一个schema中使用了多个索引签名 - -data = Data { - name: "test" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError ----> index_signature/fail_1/main.k:3:5 - | -3 | [str]: int - | 5 ^ only one index signature is allowed in the schema - | -``` - -可以尝试以下步骤来修复这个错误: - -- 删除多余的索引签名。 - -2. schema 中索引签名的名称与 schema 中其他属性的名称存在同名冲突。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Data: - name: str # name - [name: str]: str # 已有名称为name的schema属性 - -data = Data { - name: "test" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: IndexSignatureError - --> index_signature/fail_2/main.k:3:5 - | -3 | [name: str]: str # the same name with the above attribute - | ^ index signature attribute name 'name' cannot have the same name as schema attributes - | -``` - -可以尝试以下步骤来修复这个错误: - -- 删除 schema 中出现同名冲突的属性或者索引签名,或者为它们更换不同的名称。 - -3. schema 索引签名的类型与 schema 实例化的属性类型冲突。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Data: - [str]: int - -data = Data { - name: "test" # 索引签名为 [str]:int, "test"的类型不是int. -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> index_signature/fail_3/main.k:5:5 - | -5 | name: "test" # Conflict with [str]:int, "test" is a string. - | ^ expected int, got str(test) - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 schema 索引签名的类型与 schema 实例中的属性类型是否一致。 - -4. Schema 中的属性与索引签名冲突 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Data: - count: int # int 和 str 冲突 - [str]: str - -data = Data { - count: 1 -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: IndexSignatureError - --> index_signature/fail_4/main.k:2:5 - | -2 | count: int - | ^ the type 'int' of schema attribute 'count' does not meet the index signature definition [str]: str - | -``` - -可以尝试以下步骤来修复这个错误: - -- 调整 Schema 属性或者调整索引签名。 - -### 1.2.9 TypeComplieError [E2G22] - -如果在运行 KCL 时遇到错误: - -- `TypeComplieError`, 对应的 encode 为 `E2G22` - -那么此时 KCL 程序中出现了 - -- 静态类型检查错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - firstName: str - lastName: int - -JohnDoe = Person { - "firstName": "John", - "lastName": "Doe" # Schema中定义lastName: int -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> type/type_fail_0/main.k:7:5 - | -7 | "lastName": "Doe" # Type Error,lastName: int,“Doe” is a string. - | ^ expected int, got str(Doe) - | - - --> type/type_fail_0/main.k:3:5 - | -3 | lastName: int - | ^ variable is defined here, its type is int, but got str(Doe) - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查赋给某个变量的值的类型与这个变量的类型是否一致。 - -### 1.2.10 CompileError [E2L23] - -如果在运行 KCL 时遇到错误: - -- `CompileError`, 对应的 encode 为 `E2L23` - -那么此时 KCL 程序中出现了 - -1. 不支持的类型合并 - -可能出现错误的 KCL 程序片段如下: - -```python -_data = [1, 2, 3] -_data |= "value" -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> union/fail/fail_1/main.k:2:1 - | -2 | _data |= "value" - | ^ unsupported operand type(s) for |: '[int]' and 'str(value)' - | -``` - -1. 不支持的操作符类型 - -可能出现错误的 KCL 程序片段如下: - -```python -a = None -b = 1 + None # KCL中不支持None和int之间进行+操作 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> operator/operator_fail_0/main.k:2:5 - | -2 | b = 1 + None # Unsupport operand type + for int and None - | ^ unsupported operand type(s) for +: 'int(1)' and 'NoneType' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 调整操作符号,使其同时支持两个操作数的类型。 -- 调整操作数,使其同时符合操作符号的约束。 - -1. 没有定义的变量 - -可能出现错误的 KCL 程序片段如下: - -```python -a = 1 -b = "${c + 1}" # 'c' 没有定义 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> var_not_define_fail_0/main.k:2:8 - | -2 | b = "${c + 1}" # 'c' is not defined - | ^ name 'c' is not defined - | -``` - -可以尝试以下步骤来修复这个错误: - -- 对未定义的变量进行定义。 -- 在表达式中去掉对未定义变量的操作。 - -4. 无效的赋值表达式 - -可能出现错误的 KCL 程序片段如下: - -```python -# pkg.k -a = 1 - -# main.k -import pkg -pkg.a |= 2 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> pkg_inplace_modify_1/main.k:3:1 - | -6 | pkg |= 2 - | ^ unsupported operand type(s) for |: 'module 'pkg'' and 'int(2)' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查赋值表达式的内容。 - -1. 无效的字符串表达式 - -可能出现错误的 KCL 程序片段如下: - -```python -a = 1 -b = "${b = a + 1}" # Invalid string interpolation expression -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> invalid_format_value_fail_0/main.k:2:5 - | -2 | b = "${b = a + 1}" - | 5 ^ invalid string interpolation expression 'b = a + 1' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查字符串表达式的内容。 - -1. 无效的循环变量 - -可能出现错误的 KCL 程序片段如下: - -```python -data = {"key1": "value1", "key2": "value2"} -dataLoop = [i for i, j, k in data] # the number of loop variables can only be 1 or 2 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> dict/invalid_loop_var_fail_0/main.k:2:25 - | -2 | dataLoop = [i for i, j, k in data] # the number of loop variables can only be 1 or 2 - | ^ the number of loop variables is 3, which can only be 1 or 2 - | -``` - -### 1.2.11 KCLNameError [E2L25] - -如果在运行 KCL 时遇到错误: - -- `KCLNameError`, 对应的 encode 为 `E2L25` - -那么此时 KCL 程序中出现了 - -- 试图访问的变量名不存在 - -可以尝试以下步骤来修复这个错误: - -- 检查报错信息中出现的变量是否存在。 - -### 1.2.12 KCLValueError [E2L26] - -如果在运行 KCL 时遇到错误: - -- `KCLValueError`, 对应的 encode 为 `E2L26` - -那么此时 KCL 程序中出现了 - -- 值错误,传给参数的类型不正确 - -可以尝试以下步骤来修复这个错误: - -- 检查参数的具体类型。 - -### 1.2.13 KCLKeyError [E2L27] - -如果在运行 KCL 时遇到错误: - -- `KCLKeyError`, 对应的 encode 为 `E2L27` - -那么此时 KCL 程序中出现了 - -- 使用了 dict 中不存在的 key 时引发的 key 错误 - -可以尝试以下步骤来修复这个错误: - -- 检查字典中是否存在 key。 - -### 1.2.14 UniqueKeyError [E2L28] - -如果在运行 KCL 时遇到错误: - -- `UniqueKeyError`, 对应的 encode 为 `E2L28` - -那么此时 KCL 程序中出现了 - -- 变量同名或重复定义。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - name: str = "kcl" - age: int = 1 - -schema Person: - aa: int - -x0 = Person{} -x1 = Person{age:101} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L28]: UniqueKeyError - --> /schema/same_name/main.k:5:8 - | -5 | schema Person: - | ^ Unique key error name 'Person' - | - - --> /schema/same_name/main.k:1:8 - | -1 | schema Person: - | ^ The variable 'Person' is declared here - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查出现错误的名称是否已经被使用。 - -### 1.2.15 KCLAttributeComplieError [E2A29] - -如果在运行 KCL 时遇到错误: - -- `KCLAttributeComplieError`, 对应的 encode 为 `E2A29` - -那么此时 KCL 程序中出现了 - -- Schema 的属性错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -# pkg -schema A: - field_A: str - -# main -import pkg as p - -a = p.D + 1 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> /import/module/no_module_attr_fail_0/main.k:4:5 - | -4 | a = p.D + 1 - | ^ module 'pkg' has no attribute D - | -``` - -可以尝试以下步骤来修复这个错误: - -- 在使用 Schema 属性时检查这个属性是否存在。 - -### 1.2.16 MultiInheritError [E2D32] - -如果在运行 KCL 时遇到错误: - -- `MultiInheritError`, 对应的 encode 为 `E2D32` - -那么此时 KCL 程序中出现了 - -- 多继承错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - firstName: str - lastName: str - -schema KnowledgeMixin: - firstName: int - subject: str - -schema Scholar(KnowledgeMixin, Person): # KCL中不支持多继承 - school: str -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> /schema/inherit/multi_inherit_fail_1/main.k:9:30 - | -9 | schema Scholar(KnowledgeMixin, Person): - | ^ expected one of [")"] got , - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查程序的继承结构,KCL 中不支持多继承。 - -### 1.2.17 IllegalInheritError [E2D34] - -如果在运行 KCL 时遇到错误: - -- `IllegalInheritError`, 对应的 encode 为 `E2D34` - -那么此时 KCL 程序中出现了 - -- 不合法的继承结构 - -可能出现错误的 KCL 程序片段如下: - -```python -schema FullnameMixin: - fullName = "{} {}".format(firstName, lastName) - -schema Scholar(FullnameMixin): # KCL中不支持Schema继承Mixin - school: str -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError -Invalid value for top level arguments -``` - -可以尝试以下步骤来修复这个错误: - -- KCL 中 Schema 支持单继承 Schema。 - -### 1.2.18 IllegalArgumentComplieError [E2I36] - -如果在运行 KCL 时遇到错误: - -- `IllegalArgumentComplieError`, 对应的 encode 为 `E2I36` - -那么此时 KCL 程序中出现了 - -- 参数错误 - -可能出现错误的 KCL 程序片段如下: - -```python -a = option("key") - -# kcl main.k -D key=value= -# key=value= is an illegal expression -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError -Invalid value for top level arguments -``` - -可以尝试以下步骤来修复这个错误: - -- 检查通过命令设置的 KCL option 参数是否为合法参数。 - -### 1.2.19 ImmutableCompileError [E3L41] - -如果在运行 KCL 时遇到错误: - -- `ImmutableCompileError`, 对应的 encode 为 `E3L41` - -那么此时 KCL 程序中出现了 - -- 不可变量的值发生改变 - -可能出现错误的 KCL 程序片段如下: - -```python -a = 2147483646 -a += 1 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: ImmutableError - --> augment_assign/main.k:2:1 - | -2 | a += 1 - | ^ Immutable variable 'a' is modified during compiling - | - - --> augment_assign/main.k:1:1 - | -1 | a = 2147483646 - | ^ The variable 'a' is declared here firstly - | -note: change the variable name to '_a' to make it mutable -``` - -可以尝试以下步骤来修复这个错误: - -- 将被改变的不可变量设置为私有或者去掉对不可变量值的改动。 - -## 1.3 KCL 运行时错误 (E3xxx) - -KCL 会出现的运行时错误信息如下表所示: - -| ewcode | KCL exception | messages | -| ------ | ----------------------------------------------------------------------- | --------------------------------------------------- | -| E3F06 | [RecursiveLoad](#131-recursiveload-e3f06) | Recursively loading module | -| E3K04 | [FloatOverflow](#132-floatoverflow-e3k04) | Float overflow | -| E3K09 | [IntOverflow](#133-intoverflow-e3k09) | Integer overflow | -| E3N11 | [DeprecatedError](#134-deprecatederror-e3n11) | Deprecated error | -| E3A30 | [KCLAttributeRuntimeError](#135-kclattributeruntimeerror-e3a30) | Attribute error occurs at runtime | -| E3G21 | [TypeRuntimeError](#136-typeruntimeerror-e3g21) | The type got is inconsistent with the type expected | -| E3B17 | [SchemaCheckFailure](#137-schemacheckfailure-e3b17) | Schema check is failed to check condition | -| E3B19 | [CannotAddMembersRuntimeError](#138-cannotaddmembersruntimeerror-e3b19) | Cannot add members to a schema | -| E3M38 | [EvaluationError](#139-evaluationerror-e3m38) | Evaluation failure | -| E3M39 | [InvalidFormatSpec](#1310-invalidformatspec-e3m39) | Invalid format specification | -| E3M40 | [KCLAssertionError](#1311-kclassertionerror-e3m40) | Assertion failure | -| E3M44 | [ImmutableRuntimeError](#1312-immutableruntimeerror-e3m44) | Immutable variable is modified | -| E2D33 | [CycleInheritError](#1313-cycleinheriterror-e2d33) | Cycle Inheritance is illegal | -| E3M42 | [KCLRecursionError](#1314-kclrecursionerror-e3m42) | Recursively reference | - -### 1.3.1 RecursiveLoad [E3F06] - -如果在运行 KCL 时遇到错误: - -- `RecursiveLoad`, 对应的 encode 为 `E3F06` - -那么此时 KCL 程序中出现了 - -- 循环导入错误 - -可能出现错误的 KCL 程序片段如下: - -``` -# module.k -import main # module.k 导入了 main.k - -print('module') - -# main.k -import module # main.k 导入了 module.k - -print('main') -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /import/recursive_import_fail/main.k:4 - | -2 | import module # main.k imports module.k - | ^ There is a circular import reference between module main and module - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查包的导入部分是否存在循环导入的问题。 - -### 1.3.2 FloatOverflow [E3K04] - -如果在运行 KCL 时遇到错误: - -- `FloatOverflow`, 对应的 encode 为 `E3K04` - -那么此时 KCL 程序中出现了 - -- 浮点数溢出 - -可能出现错误的 KCL 程序片段如下: - -```python -uplimit = 3.402823466e+39 -epsilon = 2.220446049250313e-16 -a = uplimit * (1 + epsilon) - -# kcl main.k -r -d -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /range_check_float/overflow/number_0/main.k:3:1 - | -3 | a = uplimit * (1 + epsilon) - | 3.4028234660000003e+39: A 32-bit floating point number overflow - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查浮点数的值是否在 KCL 支持的数字范围内。 - -### 1.3.3 IntOverflow [E3K09] - -如果在运行 KCL 时遇到错误: - -- `IntOverflow`, 对应的 encode 为 `E3K09` - -那么此时 KCL 程序中出现了 - -- 整数溢出 - -可能出现错误的 KCL 程序片段如下: - -```python -_a = 9223372036854775807 -_a += 1 - -# kcl test.k -d -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /range_check_int/augment_assign_fail_1/main.k:2:1 - | -2 | _a += 1 - | 9223372036854775808: A 64 bit integer overflow - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查整数的值是否在 KCL 支持的数字范围内。 - -### 1.3.4 DeprecatedError [E3N11] - -如果在运行 KCL 时遇到错误: - -- `DeprecatedError`, 对应的 encode 为 `E3N11` - -那么此时 KCL 程序中出现了 - -- 使用废弃代码 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - firstName: str = "John" - lastName: str - @deprecated(version="1.16", reason="use firstName and lastName instead", strict=True) - name: str - -JohnDoe = Person { - name: "deprecated" # name已经被过时,并且strict设置为True -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /range_check_float/overflow/number_0/main.k:7:1 - | -7 | JohnDoe = Person { - | name was deprecated since version 1.16, use firstName and lastName instead - | -``` - -可以尝试以下步骤来修复这个错误: - -- strict 设置为 True 时无法使用过时的代码,可以将 strict 设置为 False,将不会出现错误,而是输出一个警告。 -- 调整代码,不使用已经过时的代码。 - -### 1.3.5 KCLAttributeRuntimeError [E3A30] - -如果在运行 KCL 时遇到错误: - -- `KCLAttributeRuntimeError`, 对应的 encode 为 `E3A30` - -那么此时 KCL 程序中出现了 - -- 属性错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -import math - -a = math.err_func(1) # err_func is not found in math -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /import/module/no_module_attr_fail_2/main.k:3:5 - | -3 | a = math.err_func(1) # err_func is not found in math - | ^ module 'math' has no attribute err_func - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查属性调用是否正确。 - -### 1.3.6 TypeRuntimeError [E3G21] - -如果在运行 KCL 时遇到错误: - -- `TypeRuntimeError`, 对应的 encode 为 `E3G21` - -那么此时 KCL 程序中出现了 - -- 类型检查错误 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - name: str = "Alice" - -_personA = Person {} -_personA |= {"name" = 123.0} # name: str = "Alice" -personA = _personA -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /fail/fail_4/main.k:2:1 - | -2 | name: str = "Alice" - | expect str, got float - | -``` - -可以尝试以下步骤来修复这个错误: - -- 停止错误的类型合并或者将类型调整为 KCL 支持的类型合并。 - -### 1.3.7 SchemaCheckFailure [E3B17] - -如果在运行 KCL 时遇到错误: - -- `SchemaCheckFailure`, 对应的 encode 为 `E3B17` - -那么此时 KCL 程序中出现了 - -- Schema 中的 check 条件冲突 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - lastName: str - age: int - check: - age < 140, "age is too large" - -JohnDoe = Person { - "lastName": "Doe", - "age": 1000 # Schema中的check条件为: age < 140 -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /check_block/check_block_fail_1/main.k:7:11 - | -7 | JohnDoe = Person { - | ^ Instance check failed - | - - --> /check_block/check_block_fail_1/main.k:5:1 - | -5 | age < 140, "age is too large" - | Check failed on the condition - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 Schema 的属性与 check 中的条件是否符合 - -### 1.3.8 CannotAddMembersRuntimeError [E3B19] - -如果在运行 KCL 时遇到错误: - -- `CannotAddMembersRuntimeError`, 对应的 encode 为 `E3B19` - -那么此时 KCL 程序中出现了 - -- 访问 Schema 中不存在的成员 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Name: - name: str - -schema Person: - name: Name - -person = Person { - name.err_name: "Alice" # err_name is not found in schema Name -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /nest_var/nest_var_fail_1/main.k:8:5 - | -8 | name.err_name: "Alice" # err_name is not found in schema Name - | ^ Cannot add member 'err_name' to schema 'Name' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 为 Schema 添加不存在的成员。 -- 访问 Schema 中存在的成员。 - -### 1.3.9 EvaluationError [E3M38] - -如果在运行 KCL 时遇到错误: - -- `EvaluationError`, 对应的 encode 为 `E3M38` - -那么此时 KCL 程序中出现了 - -- 当 KCL 中数值计算过程出现了错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -_list1 = [1, 2, 3] # _list1 is a variable, and its type can only be known at runtime -_list2 = None # _list1 is a variable, and its type can only be known at runtime - -result2 = _list1 + _list2 # list + NoneType is illegal -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /datatype/list/add_None_fail/main.k:1 - | -4 | result2 = _list1 + _list2 # list + NoneType is illegal - | can only concatenate list (not "NoneType") to list - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查表达式中是否存在变量为 None,或者非法的计算过程。 - -### 1.3.10 InvalidFormatSpec [E3M39] - -如果在运行 KCL 时遇到错误: - -- `InvalidFormatSpec`, 对应的 encode 为 `E3M39` - -那么此时 KCL 程序中出现了 - -- 非法的字符串格式 - -可能出现错误的 KCL 程序片段如下: - -```python -a = 1 -b = 1 -data = "${a: #js}" + " $$ " # KCL插值字符串中,#js是非法的 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /datatype/str_interpolation/invalid_format_spec_fail_0/main.k:3 - | -3 | data = "${a: #js}" + " $$ " # #js is illegal string - | ^ #js is a invalid format spec - | -``` - -可以尝试以下步骤来修复这个错误: - -- 将非法 String 调整为 KCL 标准支持的 String。 - -### 1.3.11 KCLAssertionError [E3M40] - -如果在运行 KCL 时遇到错误: - -- `KCLAssertionError`, 对应的 encode 为 `E3M40` - -那么此时 KCL 程序中出现了 - -- Assert False - -可能出现错误的 KCL 程序片段如下: - -```python -assert False -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /assert/invalid/fail_0/main.k:1 - | -1 | assert False - | - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 Assert 的条件,Assert 条件为 False 时,就会出现此类错误,去掉 Assert 语句或改变条件为 True。 - -### 1.3.12 ImmutableRuntimeError [E3M44] - -如果在运行 KCL 时遇到错误: - -- `ImmutableRuntimeError`, 对应的 encode 为 `E3M44` - -那么此时 KCL 程序中出现了 - -- 不可变量的值发生改变 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - final firstName : str - lastName : str - - -schema Scholar(Person): - firstName = "CBA" - - -scholar = Scholar { - "firstName": "ABC" # firstName in schema Person is final. -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /final/fail_lazy_init_0/main.k:8:1 - | -8 | scholar = Scholar { - | attribute 'lastName' of Scholar is required and can't be None or Undefined - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 final 修饰的不可变量是否出现了赋值等改变值的操作。 - -### 1.3.13 CycleInheritError [E2D33] - -如果在运行 KCL 时遇到错误: - -- `CycleInheritError`, 对应的 encode 为 `E2D33` - -那么此时 KCL 程序中出现了 - -- 循环继承 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Parent(Son): - parent_field: str - -schema Son(GrandSon): - son_field: str - -schema GrandSon(Parent): - grandson_field: str - -parent = Parent { - parent_field: "" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /inherit/cycle_inherit_fail_1/main.k:7:8 - | -7 | schema GrandSon(Parent): - | ^ There is a circular reference between schema GrandSon and Parent - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 Schema 的继承关系,避免出现 A 继承 B,B 继承 A 的情况。 - -### 1.3.14 KCLRecursionError [E3M42] - -如果在运行 KCL 时遇到错误: - -- `KCLRecursionError`, 对应的 encode 为 `E3M42` - -那么此时 KCL 程序中出现了 - -- 循环引用 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Parent(Son): - parent_field: str - son: Son = Son { # Parent has attribute Son - parent: Parent { - parent_field: "123" - } - } - -schema Son: - son_field: str - parent: Parent = Parent { # Son has attribute Parent - son: Son { - son_field: "123" - } - } - -parent = Parent { - parent_field: "", -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -thread 'main' has overflowed its stack -fatal runtime error: stack overflow -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 Schema 中的属性成员,避免出现循环引用的问题。 - -## 1.4 KCL 编译警告 (W2xxx) - -KCL 中的编译警告如下表所示: - -| ewcode | KCL exception | messages | -| ------ | ------------------------------------------------- | ------------------ | -| W2K04 | [FloatUnderflow](#141-floatunderflow-w2k08) | Float underflow | -| W2P10 | [InvalidDocstring](#142-invaliddocstring-w2p10) | Invalid docstring | -| W2N12 | [DeprecatedWarning](#143-deprecatedwarning-w2n12) | Deprecated warning | - -### 1.4.1 FloatUnderflow [W2K08] - -如果在运行 KCL 时遇到错误: - -- `FloatUnderflow`, 对应的 encode 为 `W2K08` - -可以尝试以下步骤来修复这个错误: - -- 检查浮点数的值是否在 KCL 支持的数字范围内。 - -### 1.4.2 InvalidDocstring [W2P10] - -如果在运行 KCL 时遇到错误: - -- `InvalidDocstring`, 对应的 encode 为 `W2P10` - -那么此时 KCL 程序中出现了 - -- 无效的 doc 内容 - -可以尝试以下步骤来修复这个错误: - -- 请按照 KCL 标准编写 doc。 - -### 1.4.3 DeprecatedWarning [W2N12] - -如果在运行 KCL 时遇到错误: - -- `DeprecatedWarning`, 对应的 encode 为 `W2N12` - -那么此时 KCL 程序中出现了 - -- 过时的代码警告 - -可以尝试以下步骤来修复这个错误: - -- 尽量不要使用已经过时的代码。如果将 strict 设置为 True,KCL 将会输出错误,并停止运行。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/error/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/error/index.md deleted file mode 100644 index e4f702ec..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/error/index.md +++ /dev/null @@ -1 +0,0 @@ -# 错误与警告 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/index.md deleted file mode 100644 index 66fd3dde..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/index.md +++ /dev/null @@ -1 +0,0 @@ -# KCL diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/_category_.json deleted file mode 100644 index c088e386..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "规范", - "position": 3 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/error.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/error.md deleted file mode 100644 index 2a58b553..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/error.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: "Errors" -linkTitle: "Errors" -type: "docs" -weight: 2 -description: Errors ---- - -When errors happen, developers should be able to detect the error and abort -execution. Thus, KCL introduce the `assert` syntax. - -In the previous topic of `schema` syntax. Errors can also be raised when a -schema is violated. - -## Syntax - -The syntax of the `assert` statement is the following. - -```bnf -assert_stmt: 'assert' test ['if' test] [',' test] -``` - -In the basic form, an `assert` statement evaluates an expression. If the -expression is evaluated to `False`, the assertion is failed, and an error -should be reported. - -In the extended form, an error message can be provided. The error message is -another expression. It is only evaluated when the expression to be evaluated -is evaluated to `False`. The evaluation result of the error message is printed -when reporting the error. - -The following is an example: - -```python -a = 1 -b = 3 -condition = False -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -# if condition is True, then assert `a == b`, if failed, the message "error message" will be printed. -assert a == b if condition, "error message" -``` - -## The Implementation - -When an error happens, no matter it is caused by the `assert` or the `schema` syntax, -the virtual machine should exit with an exit code greater than `0`. - -The virtual machine may choose to dump the back trace information, and it is strongly recommended to implement it. - -In practice, KCL can dump back trace by default, and an argument can be introduced to disable it. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/expressions.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/expressions.md deleted file mode 100644 index b52c10f3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/expressions.md +++ /dev/null @@ -1,915 +0,0 @@ ---- -title: "Expressions" -linkTitle: "Expressions" -type: "docs" -weight: 2 -description: Expressions ---- - -## Syntax - -In KCL, an expression specifies the computation of a value. - -The syntax is the following: - -```bnf -expression: test ("," test)* -test: if_expr | primary_expr | unary_expr | binary_expr -``` - -KCL expressions consist of `if` expression, `primary` expression, `unary` expression, and `binary` expression. - -### Primary Expressions - -Primary expressions are the operands for unary and binary expressions. - -Operands are self-delimiting. An **operand** may be followed by any number of selector dot, a function call, or slice suffixes, to form a primary expression. The grammar uses `expression`, where a multiple-component expression is allowed, and `test` where it accepts an expression of only a single component. - -Syntax: - -```bnf -primary_expr: operand | primary_expr select_suffix | primary_expr call_suffix | primary_expr subscript_suffix -``` - -### Operands - -Operand denotes the elementary value in an expression. An operand may be an identifier, a literal, or a parenthesized expression. - -Syntax: - -```bnf -operand: operand_name | number | string | "True" | "False" | "None" | "Undefined" | list_expr | list_comp | dict_expr | dict_comp | "(" expression ")" -operand_name: identifier | qualified_identifier -``` - -### Identifiers - -In KCL, an identifier is a name, may with selectors, that identifies a value. - -Syntax: - -```bnf -identifier: NAME -``` - -Examples: - -```python -x -a -_b -``` - -Use the `$` character prefix to define keyword identifiers. - -```python -$if = 1 -$else = "s" -``` - -Please note: whether the non-keyword identifier is prefixed with `$` has the same effect. - -```python -_a = 1 -$_a = 2 # equal to `_a = 2` -``` - -To simplify the definition of the qualified identifier, such as 'pkg.type', we additionally define `qualified_identifier`: - -Syntax: - -```bnf -qualified_identifier: identifier "." identifier -``` - -Examples: - -```python -pkg.a -``` - -The package name in qualified_identifier must be imported. - -### Basic Literals - -Basic literals supported in KCL are `int`, `float`, `string` and `bool` including `True` and `False`. Evaluation of basic literal yields a value of the given type with the given value. - -Syntax: - -```bnf -operand: number | string | "True" | "False" | "None" | "Undefined" -``` - -Examples: - -```python -1 -2.3 -"abc" -True -False -None -Undefined -``` - -See more details about **data type** spec. - -### Parenthesized Expressions - -An expression enclosed in parentheses yields the result of that expression. - -Syntax: - -```bnf -operand: '(' expression ')' -``` - -Examples: - -```python -x = (1 + 2) * (3 + 4) # 21 -``` - -### Dictionary Expressions - -A dictionary expression is a comma-separated immutable list of colon-separated key/value expression pairs, enclosed in curly brackets, and it yields a new dictionary object. An optional comma may follow the final pair. - -```bnf -config_expr: '{' config_entries '}' -config_entries: config_entry [config_entry*] -config_comp: '{' (config_entry comp_clause+) '}' -config_entry: expr (':' | '=' | '+=') expr | double_star_expr | if_entry -double_star_expr: "**" expression -if_entry: - 'if' expr ';' if_entry_exec_block - ('elif' expr ':' if_entry_exec_block)* - ('else' ':' if_entry_exec_block)? -NEWLINE: '/r?/n' -``` - -Examples: - -```python -{} -{"one": 1} -{"one": 1, "two": 2} -``` - -The key and value expressions are evaluated in left-to-right order. Evaluation fails if the same key is used multiple times. - -Only hashable values may be used as the keys of a dictionary. This includes all built-in types except dictionaries, and lists. - -We can ignore the comma `,` at the end of the line for writing dict key-value pairs in multiple lines: - -```python -data = { - "key1" = "value1" # Ignore the comma ',' at the end of line - "key2" = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -We can ignore the key quotation marks when we writing simple literals on the key. - -```python -data = { - key1 = "value1" # Ignore the comma ',' at the end of line - key2 = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -In addition, the **config selector expressions** can be used to init a schema instance. - -```python -person = { - base.count = 2 - base.value = "value" - labels.key = "value" -} # {"base": {"count": 2, "value": "value"}, "labels": {"key": "value"}} -``` - -We can **merge** dict using the dict unpacking operator `**` like this: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = {**_part1, **_part2} # {"a: "b", "c": "d"} -``` - -We can use `if expressions` to dynamically add elements to the dict element, elements that meet the conditions are added to the dict, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = { - key1 = "value1" - if a == 1: key2 = "value2" - if a > 0: key3 = "value3" - if a < 0: key4 = "value4" -} # {"key1": "value1", "key2": "value2", "key3": "value3"} -``` - -```python -a = 1 # 1 -data1 = { - key1 = "value1" - if a == 1: - key2 = "value2" - elif a > 0: - key3 = "value3" - else: - key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -data2 = { - key1 = "value1" - if a == 1: key2 = "value2" - elif a > 0: key3 = "value3" - else: key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -``` - -### List Expressions - -A list expression is a comma-separated immutable list of element expressions, enclosed in square brackets, and it yields a new list. An optional comma may follow the last element expression. - -```bnf -list_expr: '[' [list_item [',']] ']' -list_item: test | "*" primary_expr | if_expr -``` - -Element expressions are evaluated in left-to-right order. - -Examples: - -```python -[] # [], empty list -[1] # [1], a 1-element list -[1, 2, 3] # [1, 2, 3], a 3-element list -``` - -We can use `if expressions` to dynamically add elements to the list element, elements that meet the conditions are added to the list, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = [ - 1 - if a == 1: 2 - if a > 0: 3 - if a < 0: 4 -] # [1, 2, 3] -``` - -```python -a = 1 # 1 -data1 = [ - 1 - if a == 1: - 2 - elif a == 2: - 3 - else: - 3 -] # [1, 2] -data2 = [ - 1 - if a == 1: 2 - elif a == 2: 2 - else: 3 -] # [1, 2] -``` - -### Comprehensions - -A comprehension constructs a new list or dictionary value by looping over one or more iterables and evaluating a body expression that produces successive elements of the result. - -Syntax: - -```bnf -list_comp: '[' list_item comp_clause+ ']' . -dict_comp: '{' entry comp_clause+ '}' . - -comp_clause: 'for' loop_variables [","] 'in' test ['if' test] -loop_variables: primary_expr (',' primary_expr)* -``` - -A list comprehension consists of a single expression followed by one or more clauses, the first of which must be a `for` clause. Each `for` clause resembles a `for` statement, and specifies an iterable operand and a set of variables to be assigned by successive values of the iterable. An `if` cause resembles an `if` statement, and specifies a condition that must be met for the body expression to be evaluated. A sequence of `for` and `if` clauses acts like a nested sequence of `for` and `if` statements. - -Examples: - -```python -[x * x for x in range(5)] # [0, 1, 4, 9, 16] -[x * x for x in range(5) if x % 2 == 0] # [0, 4, 16] -[[x, y] for x in range(5) \ - if x % 2 == 0 \ - for y in range(5) \ - if y > x] # [[0, 1], [0, 2], [0, 3], [0, 4], [2, 3], [2, 4]] -``` - -Besides, we can use two variables in the list comprehension, the first variable denotes the list index and the second variable denotes the list item. - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use `_` to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -A dict comprehension resembles a list comprehension, but its body is a pair of expressions, key: value, separated by a colon, and its result is a dictionary containing the key/value pairs for which the body expression was evaluated. Evaluation fails if the value of any key is un-hashable. - -Besides, we can use two variables in the dict comprehension, the first variable denotes the dict key and the second variable denotes the dict value of the key. - -```python -data = {"key1" = "value1", "key2" = "value2"} -# Single variable loop -dataKeys1 = {k: k for k in data} # {"key1": "key1", "key2": "key2"} -dataValues1 = {k: data[k] for k in data} # {"key1": "value1", "key2": "value2"} -# Double variable loop -dataKeys2 = {k: k for k, v in data} # {"key1": "key1", "key2": "key2"} -dataValues2 = {v: v for k, v in data} # {"value1": "value1", "value2": "value2"} -dataFilter = {k: v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use `_` to ignore loop variables -dataKeys3 = {k: k for k, _ in data} # {"key1": "key1", "key2": "key2"} -dataValues3 = {v: v for _, v in data} # {"value1": "value1", "value2": "value2"} -``` - -As with a `for` loop, the loop variables may exploit compound assignment: - -```python -[x * y + z for [x, y], z in [[[2, 3], 5], [["o", 2], "!"]]] # [11, 'oo!'] -``` - -KCL does not accept an un-parenthesized list as the operand of a for clause: - -```python -[x * x for x in 1, 2, 3] # parse error: unexpected comma -``` - -Comprehensions defines a new lexical block, so assignments to loop variables have no effect on variables of the same name in an enclosing block: - -```python -x = 1 -_ = [x for x in [2]] # new variable x is local to the comprehension -print(x) # 1 -``` - -The operand of a comprehension's first clause (always a for) is resolved in the lexical block enclosing the comprehension. In the examples below, identifiers referring to the outer variable named x have been distinguished by subscript. - -```python -x0 = [1, 2, 3] -[x * x for x in x0] # [1, 4, 9] -[x * x for x in x0 if x % 2 == 0] # [4] -``` - -All subsequent for and if expressions are resolved within the comprehension's lexical block, as in this rather obscure example: - -```python -x0 = [[1, 2], [3, 4], [5, 6]] -[x * x for x in x0 for x in x if x % 2 == 0] # [4, 16, 36] -``` - -which would be more clearly rewritten as: - -```python -x = [[1, 2], [3, 4], [5, 6]] -[z * z for y in x for z in y if z % 2 == 0] # [4, 16, 36] -``` - -### Conditional Expressions - -A conditional expression has the form `a if cond else b`. It first evaluates the condition `cond`. If it's true, it evaluates `a` and yields its value; otherwise it yields the value of `b`. - -Syntax: - -```bnf -if_expr: test "if" test "else" test -``` - -Examples: - -```python -x = True if enabled else False # if enabled is -``` - -### Unary Expressions - -In KCL, supported unary operators are `+`, `-`, `~`, and `not`. - -Syntax: - -```bnf -unary_expr: ("+" | "-" | "~") primary_expr - | "not" test -``` - -Usage: - -```bnf -+ number unary positive (int, float) -- number unary negation (int, float) -~ number unary bitwise inversion (int) -not x logical negation (any type) -``` - -The `+` and `-` operators may be applied to any number (int or float) and return the number. -The `not` operator returns the negation of the truth value of its operand. - -Examples: - -```python -~1 # -2 -~-1 # 0 -~0 # -1 -not True # False -not 0 # True -``` - -### Binary Expressions - -In KCL, binary expressions consist of `comparisons`, `logical operations`, `arithmetic operations` and `membership tests`. - -Syntax: - -```bnf -binary_expr: test bin_op test -bin_op: 'or' - | 'and' - | '==' | '!=' | '<' | '>' | '<=' | '>=' - | 'in' | 'not' 'in' - | '|' - | '^' - | '&' - | '-' | '+' - | '*' | '%' | '/' | '//' - | '<<' | '>>' -``` - -#### Logical Operations - -The `or` and `and` operators yield the logical disjunction and conjunction of their arguments, which need not be Booleans. - -The expression `x or y` yields the value of `x` if its truth value is `True`, or the value of `y` otherwise. - -```python -False or False # False -False or True # True -True or True # True -1 or "hello" # 1 -``` - -Similarly, `x` and `y` yields the value of `x` if its truth value is `False`, or the value of `y` otherwise. - -```python -False and False # False -False and True # False -True and True # True -1 and "hello" # "hello" -``` - -These operators use "short circuit" evaluation, so the second expression is not evaluated if the value of the first expression has already determined the result, allowing constructions like these: - -```python -x and x[0] == 1 # x[0] is not evaluated if x is empty -len(x) == 0 or x[0] == "" -not x or not x[0] -``` - -#### Comparisons - -The `==` operator reports whether its operands are equal; the `!=` operator is its negation. - -The operators `<`, `>`, `<=`, and `>=` perform an ordered comparison of their operands. It is an error to apply these operators to operands of unequal type, unless one of the operands is an `int` and the other is a `float`. Of the built-in types, only the following support ordered comparison, using the ordering relation shown: - -```bnf -NoneType # None <= None -bool # False < True -int # mathematical -float # as defined by IEEE 754 -string # lexicographical -list # lexicographical -``` - -Comparison of floating-point values follows the IEEE 754 standard, which breaks several mathematical identities. For example, if `x` is a `NaN` value, the comparisons `x < y`, `x == y`, and `x > y` all yield false for all values of `y`. - -The remaining built-in types support only equality comparisons. Values of type `dict` and `schema` compare equal if their elements compare equal, and values of type function or `builtin_function_or_method` are equal only to themselves. - -```bnf -dict # equal contents -schema # equal exported-attributes -function # identity -builtin_function_or_method # identity -``` - -#### Arithmetic Operations - -The following table summarizes the binary arithmetic operations available for built-in types: - -```bnf -Arithmetic (int or float; result has type float unless both operands have type int) - number + number # addition - number - number # subtraction - number * number # multiplication - number / number # real division (result is always a float) - number // number # floored division - number % number # remainder of floored division - number ^ number # bitwise XOR - number << number # bitwise left shift - number >> number # bitwise right shift - -Concatenation - string + string - list + list - -Repetition (string/list) - int * sequence - sequence * int - -Union - int | int - list | list - dict | dict - schema | schema - schema | dict -basictype | basictype -``` - -The operands of the arithmetic operators `+`, `-`, `*`, `//`, and `%` must both be numbers (`int` or `float`) but need not have the same type. The type of the result has type `int` only if both operands have that type. The result of real division / always has type `float`. - -The `+` operator may be applied to non-numeric operands of the same type, such as two lists, or two strings, in which case it computes the concatenation of the two operands and yields a new value of the same type. - -```python -"Hello, " + "world" # "Hello, world" -[1, 2] + [3, 4] # [1, 2, 3, 4] -``` - -The `*` operator may be applied to an integer n and a value of type `string`, `list`, in which case it yields a new value of the same sequence type consisting of n repetitions of the original sequence. The order of the operands is immaterial. Negative values of n behave like zero. - -```python -'mur' * 2 # 'murmur' -3 * range(3) # [0, 1, 2, 0, 1, 2, 0, 1, 2] -``` - -The `&` operator requires two operands of the same type, such as `int`. For integers, it yields the bitwise intersection (AND) of its operands. - -The `|` operator likewise computes bitwise, unions basic types and unions collection and schema data, such as **list**, **dict** and **schema**. - -Computing bitwise examples: - -```python -0x12345678 | 0xFF # 0x123456FF -``` - -Unioning basic types examples: - -```python -schema x: - a: int | str # attribute a could be a int or string -``` - -A union type is used to define a schema attribute type. See more details in **schema** spec. -Supported types in a union type are `int`, `str`, `float`, `bool`, `list` and `dict`. - -Unioning collection and schema data: - -- Unioning List. Overwrite the list expression on the right side of the operator `|` to the list variable on the left side of the operator one by one according to the **index**. - -```python -_a = [1, 2, 3] -_b = [4, 5, 6, 7] -x = _a | _b # [4, 5, 6, 7] 4 -> 1; 5 -> 2; 6 -> 3; 7 -> None -``` - -Unioning to the specific index or all elements is still under discussion. - -- Unioning Dict. Union the dict expression on the right side of the operator `|` one by one to the dict variable on the left side of the operator according to the **key** - -```python -_a = {key1 = "value1"} -_b = {key1 = "overwrite", key2 = "value2"} -_c = _a | _b # {"key1": "overwrite", "key2": "value2"} -``` - -The union of collection and schema is a new one whose attributes are unioning b to a, preserving the order of the attributes of the operands, left before right. - -Unioning to the specific key or all keys is still under discussion. - -- Unioning Schema. - -The union operation for schema is similar to dict. - -Schema union could be done as: - -```bnf -schema Person: - firstName: str - lastName: str - -_a = Person { - firstName = "John" -} -_b = {lastName = "Doe"} -_a = _a | _b # {"firstName": "John", "lastName": "Doe"} -``` - -Unioning to a specific attribute is still under discussion. Unioning to all attributes is not applicable to schema instances. - -See **selector expression** in **expression** spec for more details. - -The `^` operator accepts operands of `int`. For integers, it yields the bitwise XOR (exclusive OR) of its operands. - -The `<<` and `>>` operators require operands of `int` type both. They shift the first operand to the left or right by the number of bits given by the second operand. It is a dynamic error if the second operand is negative. Implementations may impose a limit on the second operand of a left shift. - -```python -0x12345678 & 0xFF # 0x00000078 -0b01011101 ^ 0b110101101 # 0b111110000 -0b01011101 >> 2 # 0b010111 -0b01011101 << 2 # 0b0101110100 -``` - -#### Membership Tests - -Usage: - -```bnf - any in sequence (list, dict, schema, string) - any not in sequence -``` - -The `in` operator reports whether its first operand is a member of its second operand, which must be a list, dict, schema, or string. The `not in` operator is its negation. Both return a Boolean. - -The meaning of membership varies by the type of the second operand: the members of a list are its elements; the members of a dict are its keys; the members of a string are all its substrings. - -```python -1 in [1, 2, 3] # True - -d = {"one" = 1, "two" = 2} -"one" in d # True -"three" in d # False -1 in d # False -[] in d # False - -"nasty" in "dynasty" # True -"a" in "banana" # True -"f" not in "way" # True - -d = data {one = 1, two = 2} # data is a schema with attributes one and two -"one" in d # True -"three" in d # False -``` - -### Function Invocations - -KCL allows calling built-in functions and functions from built-in and system modules. Whether KCL allows defining new functions is under discussion. - -Syntax: - -```bnf -call_suffix: "(" [arguments [","]] ")" -arguments: argument ("," argument)* -argument: test | identifier "=" test | "*" test | "**" test -``` - -To call a function, the basic way is shown as the following code excerpt: - -```python -print("An argument") - -import math -# 2 powers 3 is 8. -a = math.pow(2, 3) -``` - -As you can see, arguments are separated with `,`. Arguments can only be passed in this way. KCL supports positional arguments and key-value arguments. - -Note that: - -- Some functions have parameters with default values. -- Some functions accept variadic arguments. - -When an argument is not supplied for a parameter without a default value, -an error will be reported. - -### Selector Expressions - -A selector expression selects the attribute or method of the value. - -#### Select Attributes - -Syntax: - -```bnf -select_suffix: ["?"] "." identifier -``` - -KCL provides a wealth of ways to identify or filter attributes. - -x.y - -- schema: it denotes the attribute value of a schema `x` identified by `y` -- package: it denotes the identifier of a package `x` identified by `y` - -Examples: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -name = person.name # "Alice" -age = person.age # 18 -``` - -x?.y - -If the x if None/Undefined or empty(empty list or dict), just return None, otherwise behave as x.y. - -Examples - -```python -noneData = None -data?.name # None - -emptyDict = {} -emptyDict?.name # None - -emptyList = [] -emptyList?[0] # None -``` - -As a supplementary of the `selector` expression in KCL code, the KCL compiler needs to provide corresponding identifying and filtering features through the command line and api form. - -#### Select Methods - -Syntax: - -```bnf -select_suffix: "." identifier -``` - -A `identifier` identifies method belongs to the built-in types `string`, `list`, `dict`, and `schema`. - -- A selector expression fails if the value does not have an attribute of the specified name. -- A selector expression that selects a method typically appears within a call expression, as in these examples: - -Examples: - -```python -["able", "baker", "charlie"].index("baker") # 1 -"banana".count("a") # 3 -"banana".reverse() # error: string has no .reverse field or method -Person.instances() # all instances of schema Person -``` - -But when not called immediately, the selector expression evaluates to a bound method, that is, a method coupled to a specific receiver value. A bound method can be called like an ordinary function, without a receiver argument: - -```bnf -f = "banana".count -f # -f("a") # 3 -f("n") # 2 -``` - -### Index Expressions - -An index expression `a[i]` yields the `i` th element of an indexable type such as a string or list. The index `i` must be an `int` value in the range `-n` ≤ `i` < `n`, where `n` is `len(a)`; any other index results in an error. - -Syntax: - -```bnf -subscript_suffix: "[" [test] "]" -``` - -A valid negative index `i` behaves like the non-negative index `n+i`, allowing for convenient indexing relative to the end of the sequence. - -```python -"abc"[0] # "a" -"abc"[1] # "b" -"abc"[-1] # "c" - -["zero", "one", "two"][0] # "zero" -["zero", "one", "two"][1] # "one" -["zero", "one", "two"][-1] # "two" -``` - -An index expression `d[key]` may also be applied to a dictionary `d`, to obtain the value associated with the specified key. It returns `Undefined` if the dictionary contains no such key. - -An index expression appearing on the left side of an assignment causes the specified list or dictionary element to be updated: - -```python -a = range(3) # a == [0, 1, 2] -b = a[2] # 2 - - -``` - -It is a dynamic error to attempt to update an element of an immutable type, such as a list or string, or a frozen value of a mutable type. - -### Slice Expressions - -A slice expression `a[start:stop:stride]` yields a new value containing a sub-sequence of `a`, which must be a string, or list. - -```bnf -subscript_suffix: "[" [test] [":" [test] [":" [test]]] "]" -``` - -Each of the `start`, `stop`, and `stride` operands is optional; if present, and not `None`, each must be an integer. -The `stride` value defaults to 1. If the stride is not specified, the colon preceding it may be omitted too. It is an error to specify a stride of zero. - -Conceptually, these operands specify a sequence of values `i` starting at start and successively adding `stride` until `i` reaches or passes `stop`. The result consists of the concatenation of values of `a[i]` for which `i` is valid.` - -The effective start and stop indices are computed from the three operands as follows. Let `n` be the length of the sequence. - -**If the stride is positive**: If the `start` operand was omitted, it defaults to -infinity. If the `end` operand was omitted, it defaults to +infinity. For either operand, if a negative value was supplied, `n` is added to it. The `start` and `end` values are then "clamped" to the nearest value in the range 0 to `n`, inclusive. - -**If the stride is negative**: If the `start` operand was omitted, it defaults to +infinity. If the `end` operand was omitted, it defaults to -infinity. For either operand, if a negative value was supplied, `n` is added to it. The `start` and `end` values are then "clamped" to the nearest value in the range -1 to `n`-1, inclusive. - -```python -"abc"[1:] # "bc" (remove first element) -"abc"[:-1] # "ab" (remove last element) -"abc"[1:-1] # "b" (remove first and last element) -"banana"[1::2] # "aaa" (select alternate elements starting at index 1) -"banana"[4::-2] # "nnb" (select alternate elements in reverse, starting at index 4) -``` - -It's not allowed to define a slice expression as a left value in KCL. -Cause list and string are immutable, re-slicing can directly operate to operand to ensure better performance. - -#### Quantifier Expressions - -Quantifier expressions act on collection: list or dict, generally used to obtain a certain result after processing the collection, mainly in the following four forms: - -```bnf -quant_expr: quant_op [ identifier ',' ] identifier 'in' quant_target '{' expr ['if' expr] '}' -quant_target: string | identifier | list_expr |list_comp | dict_expr | dict_comp -quant_op: 'all' | 'any' | 'filter' | 'map' -``` - -- **all** - - Used to detect that all elements in the collection satisfy the given logical expression, and return a boolean value as the result. - - Only when all elements in the collection satisfy the expression true, the `all` expression is true, otherwise it is false. - - If the original collection is empty, return true. - - Supports short-circuiting of logical expressions during expression execution. -- **any** - - Used to detect that at least one element in the collection satisfies the given logical expression, and returns a boolean value as the result. - - When at least one element in the collection satisfies the expression true, the `any` expression is true, otherwise it is false. - - If the original collection is empty, return false. - - Supports short-circuiting of logical expressions during expression execution. -- **map** - - Generate a new **list** by mapping the elements in the original collection. - - The length of the new list is exactly the same as the original collection. -- **filter** - - By logically judging and filtering the elements in the original collection, and returning the filtered sub-collection. - - Only when the element judges the expression to be true, it is added to the sub-collection. - - The type (list, dict and schema) of the new collection is exactly the same as the original collection, and the length range is `[0, len(original-collection)]`. - -**all** and **any** expression sample codes: - -```python -schema Config: - volumes: [{str:}] - services: [{str:}] - - check: - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - }, "invalid cluster ip" - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } -``` - -**map** and **filter** expression sample codes: - -```python -a = map e in [{name = "1", value = 1}, {name = "2", value = 2}] { - {name = e.name, value = int(e.value) ** 2} -} # [{"name": "1", value: 1}, {"name": "2", "value": 4}] - -b = map k, v in {a = "foo", b = "bar"} { v } # ["foo", "bar"] - -c = filter e in [{name = "1", value = 1}, {name = "2", value = 2}] { - int(e.value) > 1 -} # [{"name": "2", "value": 2}] - -d = filter _, v in {a = "foo", b = "bar"} { - v == "foo" -} # {"a": "foo"} -``` - -Please pay attention to distinguish the difference between any expression and any type. When `any` is used in type annotations, it means that the value of the variable is arbitrary, while the any expression means that one of the elements in a set satisfies the condition. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/index.md deleted file mode 100644 index c3ecc162..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/index.md +++ /dev/null @@ -1 +0,0 @@ -# KCL 语言规范 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/kcl-spec.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/kcl-spec.md deleted file mode 100644 index 63a9d6e7..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/kcl-spec.md +++ /dev/null @@ -1,343 +0,0 @@ ---- -title: "KCL Spec" -linkTitle: "KCL Spec" -type: "docs" -weight: 2 -description: KCL Spec ---- - -## Lexical rules - -### Keywords and reserved words - -The following are the keywords of the KCL: - -```python -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -The following are reserved words for the KCL: - -```python -pass return validate rule flow -def del raise except try -finally while from with yield -global nonlocal struct class final -``` - -### Line comment - -```python -# a comment -``` - -### Operators - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != = -+= -= *= **= /= //= %= -<<= >>= &= ^= -``` - -### Delimiters - -```python -( ) [ ] { } -, : . ; @ -``` - -### Operator precedence - -The following list of operators is ordered from **highest to lowest**: - -| Operator | Description | -| -------------------------------------------------------------------------------- | -------------------------------------------------------- | -| `**` | Exponentiation (highest priority) | -| `+x` `-x` `~x` | Positive, negative, bitwise NOT | -| `*` `/` `%` `//` | Multiplication, division, floor division and remainder | -| `+` `-` | Addition and subtraction | -| `<<` `>>` | Left and right shifts | -| `&` | Bitwise AND | -| `^` | Bitwise XOR | -| \| | Bitwise OR | -| `in`, `not in`, `is`, `is not`, `<`, `<=`, `>`, `>=`, `!=`, `==` | Comparisons, including membership and identity operators | -| `not` | Boolean NOT | -| `and` | Boolean AND | -| `or` | Boolean OR | -| `if – else` | Conditional expression = | -| `=`, `+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `=`, `^=`, `\*\*=`, `//=`, `<<=`, `>>=` | Assign | - -## Grammar - -KCL uses Python's [LarkParser](https://lark-parser.readthedocs.io/en/latest/) tool to describe the grammar, and the specification rules are as follows: - -```bnf -//////////// KCL grammar //////////// -start: (NEWLINE | statement)* - -statement: simple_stmt | compound_stmt -simple_stmt: (assign_stmt | unification_stmt | expr_stmt | assert_stmt | import_stmt | type_alias_stmt) NEWLINE -compound_stmt: if_stmt | schema_stmt | rule_stmt - -//////////// import_stmt //////////// -import_stmt: IMPORT dot_name (AS NAME)? -dot_name: (leading_dots identifier) | identifier -leading_dots: DOT+ - -/////////// assert_stmt //////////// -assert_stmt: ASSERT simple_expr (IF simple_expr)? (COMMA test)? - -//////////// if_stmt //////////// -if_stmt: IF test COLON execution_block (ELIF test COLON execution_block)* (ELSE COLON execution_block)? -execution_block: if_simple_stmt | NEWLINE _INDENT schema_init_stmt+ _DEDENT -if_simple_stmt: (simple_assign_stmt | unification_stmt | expr_stmt | assert_stmt) NEWLINE - -//////////// assign_stmt //////////// -assign_stmt: identifier [COLON type] (ASSIGN identifier)* ASSIGN test - | identifier (COMP_PLUS | COMP_MINUS | COMP_MULTIPLY | COMP_DOUBLE_STAR | COMP_DIVIDE - | COMP_DOUBLE_DIVIDE | COMP_MOD | COMP_AND | COMP_OR | COMP_XOR | COMP_SHIFT_LEFT - | COMP_SHIFT_RIGHT) test - -simple_assign_stmt: identifier ASSIGN test - | identifier (COMP_PLUS | COMP_MINUS | COMP_MULTIPLY | COMP_DOUBLE_STAR | COMP_DIVIDE - | COMP_DOUBLE_DIVIDE | COMP_MOD | COMP_AND | COMP_OR | COMP_XOR | COMP_SHIFT_LEFT - | COMP_SHIFT_RIGHT) test - -//////////// unification_stmt //////////// -unification_stmt: identifier COLON schema_expr - -//////////// schema_stmt //////////// -schema_stmt: [decorators] (SCHEMA|MIXIN|PROTOCOL) NAME [LEFT_BRACKETS [schema_arguments] RIGHT_BRACKETS] [LEFT_PARENTHESES identifier (COMMA identifier)* RIGHT_PARENTHESES] [for_host] COLON NEWLINE [schema_body] -schema_arguments: schema_argument (COMMA schema_argument)* -schema_argument: NAME [COLON type] [ASSIGN test] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt|schema_init_stmt|schema_index_signature)* [check_block] _DEDENT -schema_attribute_stmt: attribute_stmt NEWLINE -attribute_stmt: [decorators] identifier [QUESTION] COLON type [(ASSIGN|COMP_OR) test] -schema_init_stmt: if_simple_stmt | if_stmt -schema_index_signature: LEFT_BRACKETS [NAME COLON] [ELLIPSIS] basic_type RIGHT_BRACKETS COLON type [ASSIGN test] NEWLINE - -//////////// rule_stmt //////////// -rule_stmt: [decorators] RULE NAME [LEFT_BRACKETS [schema_arguments] RIGHT_BRACKETS] [LEFT_PARENTHESES identifier (COMMA identifier)* RIGHT_PARENTHESES] [for_host] COLON NEWLINE [rule_body] -rule_body: _INDENT (string NEWLINE)* check_expr+ _DEDENT - -for_host: FOR identifier - -/////////// decorators //////////// -decorators: (AT decorator_expr NEWLINE)+ -decorator_expr: identifier [call_suffix] - -//////////// type //////////// -type: type_element (OR type_element)* -type_element: schema_type | basic_type | compound_type | literal_type -schema_type: identifier -basic_type: STRING_TYPE | INT_TYPE | FLOAT_TYPE | BOOL_TYPE | ANY_TYPE -compound_type: list_type | dict_type -list_type: LEFT_BRACKETS (type)? RIGHT_BRACKETS -dict_type: LEFT_BRACE (type)? COLON (type)? RIGHT_BRACE -literal_type: string | number | TRUE | FALSE | NONE - -//////////// type alias //////////// -type_alias_stmt: TYPE NAME ASSIGN type - -//////////// check_stmt //////////// -check_block: CHECK COLON NEWLINE _INDENT check_expr+ _DEDENT -check_expr: simple_expr [IF simple_expr] [COMMA primary_expr] NEWLINE - -//////////// mixin_stmt //////////// -mixin_stmt: MIXIN LEFT_BRACKETS [mixins | multiline_mixins] RIGHT_BRACKETS NEWLINE -multiline_mixins: NEWLINE _INDENT mixins NEWLINE _DEDENT -mixins: identifier (COMMA (NEWLINE mixins | identifier))* - - -//////////// expression_stmt //////////// -expr_stmt: testlist_expr -testlist_expr: test (COMMA test)* -test: if_expr | simple_expr -if_expr: simple_expr IF simple_expr ELSE test - -simple_expr: unary_expr | binary_expr | primary_expr - -unary_expr: un_op simple_expr -binary_expr: simple_expr bin_op simple_expr - -bin_op: L_OR | L_AND - | OR | XOR | AND - | SHIFT_LEFT | SHIFT_RIGHT - | PLUS | MINUS | MULTIPLY | DIVIDE | MOD | DOUBLE_DIVIDE - | DOUBLE_STAR - | EQUAL_TO | NOT_EQUAL_TO - | LESS_THAN | GREATER_THAN | LESS_THAN_OR_EQUAL_TO | GREATER_THAN_OR_EQUAL_TO - | IN | L_NOT IN | IS | IS L_NOT | L_NOT | AS -un_op: L_NOT | PLUS | MINUS | NOT - -primary_expr: identifier call_suffix | operand | primary_expr select_suffix | primary_expr call_suffix | primary_expr slice_suffix -operand: identifier | number | string | constant | quant_expr | list_expr | list_comp | config_expr | dict_comp | schema_expr | lambda_expr | LEFT_PARENTHESES test RIGHT_PARENTHESES -select_suffix: [QUESTION] DOT NAME -call_suffix: LEFT_PARENTHESES [arguments [COMMA]] RIGHT_PARENTHESES -slice_suffix: [QUESTION] LEFT_BRACKETS (test | [test] COLON [test] [COLON [test]]) RIGHT_BRACKETS -arguments: argument (COMMA argument)* -argument: test | NAME ASSIGN test | MULTIPLY test | DOUBLE_STAR test - - -//////////// operand //////////// -identifier: NAME (DOT NAME)* -quant_expr: quant_op [ identifier COMMA ] identifier IN quant_target LEFT_BRACE (simple_expr [IF simple_expr] | NEWLINE _INDENT simple_expr [IF simple_expr] NEWLINE _DEDENT)? RIGHT_BRACE -quant_target: string | identifier | list_expr | list_comp | config_expr | dict_comp -quant_op: ALL | ANY | FILTER | MAP -list_expr: LEFT_BRACKETS [list_items | NEWLINE [_INDENT list_items _DEDENT]] RIGHT_BRACKETS -list_items: list_item ((COMMA [NEWLINE] | [NEWLINE]) list_item)* [COMMA] [NEWLINE] -list_item: test | star_expr | if_item -list_comp: LEFT_BRACKETS (list_item comp_clause+ | NEWLINE _INDENT list_item comp_clause+ _DEDENT) RIGHT_BRACKETS -dict_comp: LEFT_BRACE (entry comp_clause+ | NEWLINE _INDENT entry comp_clause+ _DEDENT) RIGHT_BRACE -entry: test (COLON | ASSIGN | COMP_PLUS) test -comp_clause: FOR loop_variables [COMMA] IN simple_expr [NEWLINE] [IF test [NEWLINE]] -if_entry: IF test COLON if_entry_exec_block (ELIF test COLON if_entry_exec_block)* (ELSE COLON if_entry_exec_block)? -if_entry_exec_block: (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry) [NEWLINE] | NEWLINE _INDENT (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry) ((COMMA [NEWLINE] | [NEWLINE]) (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry))* [COMMA] [NEWLINE] _DEDENT -if_item: IF test COLON if_item_exec_block (ELIF test COLON if_item_exec_block)* (ELSE COLON if_item_exec_block)? -if_item_exec_block: list_item [NEWLINE] | NEWLINE _INDENT list_item ((COMMA [NEWLINE] | NEWLINE) list_item)* [COMMA] [NEWLINE] _DEDENT - -star_expr: MULTIPLY test -double_star_expr: DOUBLE_STAR test -loop_variables: primary_expr (COMMA primary_expr)* -schema_expr: identifier (LEFT_PARENTHESES [arguments] RIGHT_PARENTHESES)? config_expr -config_expr: LEFT_BRACE [config_entries | NEWLINE [_INDENT config_entries _DEDENT]] RIGHT_BRACE -config_entries: config_entry ((COMMA [NEWLINE] | [NEWLINE]) config_entry)* [COMMA] [NEWLINE] -config_entry: test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry - -//////////// lambda_expr //////////// -lambda_expr: LAMBDA [schema_arguments] [RIGHT_ARROW type] LEFT_BRACE [expr_stmt | NEWLINE _INDENT schema_init_stmt+ _DEDENT] RIGHT_BRACE - -//////////// misc //////////// -number: DEC_NUMBER [multiplier] | HEX_NUMBER | BIN_NUMBER | OCT_NUMBER | FLOAT_NUMBER -multiplier: SI_N_L | SI_U_L | SI_M_L | SI_K_L | SI_K | SI_M | SI_G | SI_T | SI_P - | SI_K_IEC | SI_M_IEC | SI_G_IEC | SI_T_IEC | SI_P_IEC -string: STRING | LONG_STRING -constant : TRUE | FALSE | NONE | UNDEFINED -// Tokens - -ASSIGN: "=" -COLON: ":" -SEMI_COLON: ";" -COMMA: "," -QUESTION: "?" -ELLIPSIS: "..." -RIGHT_ARROW: "->" -LEFT_PARENTHESES: "(" -RIGHT_PARENTHESES: ")" -LEFT_BRACKETS: "[" -RIGHT_BRACKETS: "]" -LEFT_BRACE: "{" -RIGHT_BRACE: "}" -PLUS: "+" -MINUS: "-" -MULTIPLY: "*" -DIVIDE: "/" -MOD: "%" -DOT: "." -AND: "&" -OR: "|" -XOR: "^" -NOT: "~" -LESS_THAN: "<" -GREATER_THAN: ">" -EQUAL_TO: "==" -NOT_EQUAL_TO: "!=" -GREATER_THAN_OR_EQUAL_TO: ">=" -LESS_THAN_OR_EQUAL_TO: "<=" -DOUBLE_STAR: "**" -DOUBLE_DIVIDE: "//" -SHIFT_LEFT: "<<" -SHIFT_RIGHT: ">>" -AT: "@" - -COMP_PLUS: "+=" -COMP_MINUS: "-=" -COMP_MULTIPLY: "*=" -COMP_DIVIDE: "/=" -COMP_MOD: "%=" -COMP_AND: "&=" -COMP_OR: "|=" -COMP_XOR: "^=" -COMP_DOUBLE_STAR: "**=" -COMP_DOUBLE_DIVIDE: "//=" -COMP_SHIFT_LEFT: "<<=" -COMP_SHIFT_RIGHT: ">>=" - -// Special tokens -IMPORT: "import" -AS: "as" -RULE: "rule" -SCHEMA: "schema" -MIXIN: "mixin" -PROTOCOL: "protocol" -CHECK: "check" -FOR: "for" -ASSERT: "assert" -IF: "if" -ELIF: "elif" -ELSE: "else" -L_OR: "or" -L_AND: "and" -L_NOT: "not" -IN: "in" -IS: "is" -LAMBDA: "lambda" -ALL: "all" -ANY: "any" -FILTER: "filter" -MAP: "map" -TYPE: "type" - -ANY_TYPE: "any" -STRING_TYPE: "str" -INT_TYPE: "int" -FLOAT_TYPE: "float" -BOOL_TYPE: "bool" - -// Constant tokens -TRUE: "True" -FALSE: "False" -NONE: "None" -UNDEFINED: "Undefined" - -// Binary prefix -SI_N_L: "n" -SI_U_L: "u" -SI_M_L: "m" -SI_K_L: "k" -SI_K: "K" -SI_M: "M" -SI_G: "G" -SI_T: "T" -SI_P: "P" -SI_K_IEC: "Ki" -SI_M_IEC: "Mi" -SI_G_IEC: "Gi" -SI_T_IEC: "Ti" -SI_P_IEC: "Pi" -IEC: "i" - -NAME: /\$?[a-zA-Z_]\w*/ -COMMENT: /#[^\n]*/ -NEWLINE: ( /\r?\n[\t ]*/ | COMMENT )+ - -STRING: /r?("(?!"").*?(? **note** -> -> Any character except the ASCII space, tab (`\t`) and formfeed (`\f`) is considered a none-space character. - -- A line ending in a backslash cannot carry a comment (, which will be introduced shortly afterwards). -- A backslash does not continue a comment. -- A backslash does not continue a token except for string literals (i.e., tokens other than string literals cannot be split across physical lines using a backslash). -- A backslash is illegal elsewhere on a line outside a string literal. - -### Implicit Line Joining - -Expressions in parentheses, square brackets or curly braces can be split over more than one physical line without using backslashes. - -- Implicitly continued lines can carry comments. -- The indentation of the continuation lines is not important. -- Blank continuation lines are allowed. -- There is no `NEWLINE` token between implicit continuation lines. -- Implicitly continued lines can also occur within triple-quoted strings (see below); in that case they cannot carry comments. - -### Blank Lines - -### Indentation - -### Comments - -Starting with a `#` character that is not part of a string literal is a comment. A comment ends at the end of the physical line. - -A comment signifies the end of the logical line unless the implicit line joining rules are invoked. - -Comments are ignored by the syntax. - -### Identifiers and Keywords - -Identifiers (also referred to as names) are described by the following lexical definitions. - -Within the ASCII range (from `U+0001` to `U+007F`), the valid characters for identifiers are the uppercase and lowercase letters `A` through `Z`, the underscore `_` and, except for the first character, the digits `0` through `9`. - -Identifiers are unlimited in length. The case is significant. - -### Keywords - -The following identifiers are used as reserved words, or keywords of the language, and cannot be used as ordinary identifiers. They must be spelled exactly as written here: - -```python -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -The following tokens are not used, but they are reserved as possible future keywords: - -```python -pass return validate rule flow -def del raise except try -finally while from with yield -global nonlocal struct class final -``` - -### Literals - -Literals are notations for constant values of some built-in types. - -### String Literals - -String literals are described by the following lexical definitions: - -``` -stringliteral ::= [stringprefix](shortstring | longstring) -stringprefix ::= "r" | "R" -shortstring ::= "'" shortstringitem* "'" | '"' shortstringitem* '"' -longstring ::= "'''" longstringitem* "'''" | '"""' longstringitem* '"""' -shortstringitem ::= shortstringchar | stringescapeseq -longstringitem ::= longstringchar | stringescapeseq -shortstringchar ::= -longstringchar ::= -stringescapeseq ::= "\" -``` - -Multiple adjacent string or bytes literals (delimited by whitespace),possibly using different quoting conventions, are allowed, and their meaning is the same as their concatenation. - -### Numeric Literals - -There are two types of numeric literals: integers and floating-point numbers. - -Integer literals are described by the following lexical definitions: - -``` -integer ::= decinteger | bininteger | octinteger | hexinteger -decinteger ::= nonzerodigit (["_"] digit)* | "0"+ (["_"] "0")* -bininteger ::= "0" ("b" | "B") (["_"] bindigit)+ -octinteger ::= "0" ("o" | "O") (["_"] octdigit)+ -hexinteger ::= "0" ("x" | "X") (["_"] hexdigit)+ -nonzerodigit ::= "1"..."9" -digit ::= "0"..."9" -bindigit ::= "0" | "1" -octdigit ::= "0"..."7" -hexdigit ::= digit | "a"..."f" | "A"..."F" -``` - -Floating-point literals are described by the following lexical definitions: - -``` -floatnumber ::= pointfloat | exponentfloat -pointfloat ::= [digitpart] fraction | digitpart "." -exponentfloat ::= (digitpart | pointfloat) exponent -digitpart ::= digit (["_"] digit)* -fraction ::= "." digitpart -exponent ::= ("e" | "E") ["+" | "-"] digitpart -``` - -## Operators and Delimiters - -### Operators - -The following tokens are operators: - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != @ -``` - -### Delimiters - -The following tokens serve as delimiters in the grammar: - -```python -( ) [ ] { } -, : . ; = += --= *= **= /= //= %= -<<= >>= &= |= ^= -``` - -The period can also occur in floating-point literals. - -The following printing ASCII characters have special meaning as part of other tokens or are otherwise significant to the lexical analyzer: - -``` -' " # \ -``` - -The following printing ASCII characters are not used in KCL. Their occurrence outside string literals and comments is an unconditional error: - -``` -? ` -``` - -## Reference - -Since the lexical conventions of KCL is very similar to that of Python, we use the following document as the reference when writing this chapter. - -- [https://docs.python.org/3/reference/lexical_analysis.html](https://docs.python.org/3/reference/lexical_analysis.html) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/modules.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/modules.md deleted file mode 100644 index f8608619..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/modules.md +++ /dev/null @@ -1,621 +0,0 @@ ---- -title: "Modules" -linkTitle: "Modules" -type: "docs" -weight: 2 -description: Modules ---- - -## Modules and the Import System - -KCL code is organized in **modules**. For code in one module to access the code defined in another module, a process called **importing** must be used. - -Importing is undertaken at compile-time in KCL. The advantage is to have static checking enabled. - -A regular KCL module is a file on the file system. It is required to have a `.k` suffix. - -## Packages - -To help manage modules and provide a naming hierarchy, KCL has the concept of packages. In KCL, a package maps to exactly a file system directory, and a regular module maps to a file. - -Files directly under a package are considered parts of the package, instead of individual regular modules. - -Packages can have sub-packages. - -Packages are special modules: - -- All packages in KCL are modules. -- A single-file module can never be a package. - -All modules have a name. - -Sub package names are separated from their parent package name by dots. - -To summary, a regular KCL module is a `.k` file, and a package is a directory on the file system. All `.k` files directly under the directory are included in the package, other files are ignored. If the directory has subdirectories, they become sub-packages as long as there are `.k` files underneath. - -### Intra-Package Name Space Sharing - -Inside a package, all `.k` files are considered parts of the package, instead of regular modules. Code in these files share a single name space and can access names defined in other files, without explicitly granted. - -### Package Initialization - -A package can have the initialization code. The code must exist in only one of the `.k` files under this package. The interpreter guarantees that the initialization code is executed after all definitions. - -## Searching - -The searching begins when an `import` statement is used to import a module. - -### Module Cache - -In KCL, only standard system modules are cached. When a cached module is imported, the cached version is used. In other words, KCL runtime would not create another copy of the standard system module in memory. - -However, other modules are uncached. Importing a module multiple time would create multiple instances of the module. - -### Module Names - -An `import` statement specifies the name of the module to import. The syntax is: - -``` -import [as ] -``` - -The rule to search with the module name is very simple: - -- **Step 1**: Searches the module name from the **standard system modules**, then **plugins modules**. - - See **standard system modules** and **plugins modules** for more details. If matched, the module is imported. Otherwise, continue to **Step 2**. -- **Step 2**. Whether a module name starts with a `.` is checked. If yes, the name is a so-called relative pathname, and we go to **Step 5**. Otherwise, continue to **Step 3**. -- **Step 3**: If the module name does not start with any `.`, then the compiler searches the nearest `root path` directory from this directory to the parent, and find the module according to the name just from the `root path`. If no `root path` is found, find the module according to the name from the folder the `.k` file including this `import` statement exists. - - **root path**: the directory contains a `kcl.mod` file. If matched, the module is imported. Otherwise, continue to **Step 4**. -- **Step 4**: Then the compiler checks if the name is the name of any library module that requires explicit loading. If matched, the library module is imported. Otherwise, continue to **Step 6**. -- **Step 5**. For relative importing, find the module according to the name from the folder the `.k` file including this `import` statement exists. Interpret leading dots using the following rule: -- One dot: Ignore. -- Tow or more dots: Suppose there are `n` leading dots, then the searching starts at `n - 1` levels above this folder. If matched, the module is imported. Otherwise, continue to **Step 6**. -- **Step 6**. Module not found, report an error. - -Do case-sensitive search when the operating system allows. If case-sensitive search is not allowed, search directories before regular files. - -In KCL, the `from <> import <>` is unsupported, and relative import is performed with the `import <>` syntax. - -### Uniqueness of Module - -Each module has a unique location path in its scope, so that a module or package could be located with a unique location path, such as `a.b.c`. - -Searching by location path should be supported by the kcl compiler, which needs to provide corresponding searching features through the command line and api form. - -## Standard System Packages - -KCL supports a few standard system modules. The following is the full list of these standard system modules: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PackageMember
datetimetoday
now
ticks
date
mathceil
exp
expm1
factorial
floor
gcd
isfinite
isinf
isnan
log
log1p
log2
log10
modf
pow
sqrt
regexreplace
match
compile
findall
search
split
unitsn
u
m
k
K
M
G
T
P
Ki
Mi
Gi
Ti
Pi
to_n
to_u
to_m
to_K
to_M
to_G
to_T
to_P
to_Ki
to_Mi
to_Gi
to_Ti
to_Pi
jsonencode
decode
dump_to_file
yamlencode
decode
dump_to_file
netsplit_host_port
join_host_port
fqdn
parse_IP
to_IP4
to_IP16
IP_string
is_IPv4
is_IP
is_loopback_IP
is_multicast_IP
is_interface_local_multicast_IP
is_link_local_multicast_IP
is_link_local_unicast_IP
is_global_unicast_IP
is_unspecified_IP
base64encode
decode
cryptomd5
sha1
sha224
sha256
sha384
sha512
- -- datetime - - ticks() -> float - Return the current time in seconds since the Epoch. Fractions of a second may be present if the system clock provides them. - - date() -> str - return the `%Y-%m-%d %H:%M:%S` format date. - - now() -> str - return the local time. e.g. `'Sat Jun 06 16:26:11 1998'` - - today() -> str - return the `%Y-%m-%d %H:%M:%S.%{ticks}` format date. -- math - - ceil(x) -> int - Return the ceiling of x as an Integral. This is the smallest integer >= x. - - factorial(x) -> int - Return x!. Raise a error if x is negative or non-integral. - - floor(x) -> int - Return the floor of x as an Integral. This is the largest integer <= x. - - gcd(a: int, b: int) -> int - Return the greatest common divisor of x and y - - isfinite(x) -> bool - Return True if x is neither an infinity nor a NaN, and False otherwise. - - isinf(x) -> bool - Return True if x is a positive or negative infinity, and False otherwise. - - isnan(x) -> bool - Return True if x is a NaN (not a number), and False otherwise. - - modf(x) -> Listfloat, float] - Return the fractional and integer parts of x. Both results carry the sign of x and are floats. - - exp(x) -> float - Return e raised to the power of x. - - expm1(x) -> float - Return exp(x)-1. This function avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small x. - - log(x, base=2.71828182845904523536028747135266250) -> float - Return the logarithm of x to the base e. - - log1p(x) -> float - Return the natural logarithm of 1+x (base e). The result is computed in a way which is accurate for x near zero. - - log2(x) -> float - Return the base 2 logarithm of x. - - log10(x) -> float - Return the base 10 logarithm of x. - - pow(x, y) -> float - Return x\*\*y (x to the power of y). - - sqrt(x) -> float - Return the square root of x. -- regex - - replace(string: str, pattern: str, replace: str, count=0) -> str - Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement. - - match(string: str, pattern: str) -> bool - Try to apply the pattern at the start of the string, returning a bool value True if any match was found, or False if no match was found. - - compile(pattern: str) -> bool - Compile a regular expression pattern, returning a bool value denoting whether the pattern is valid. - - findall(string: str, pattern: str) -> List[str] - Return a list of all non-overlapping matches in the string. - - search(string: str, pattern: str) -> bool - Scan through string looking for a match to the pattern, returning a bool value True if any match was found, or False if no match was found. - - split(string: str, pattern: str, maxsplit=0) -> List[str] - Scan through string looking for a match to the pattern, returning a Match object, or None if no match was found. -- units - - Unit constants - - Fixed point: `n`, `u`, `m`, `k`, `K`, `G`, `T` and `P`. - - Power of 2: `Ki`, `Mi`, `Gi`, `Ti` and `Pi`. - - Functions - - to_n(num: int) -> str - Int literal to string with `n` suffix - - to_u(num: int) -> str - Int literal to string with `u` suffix - - to_m(num: int) -> str - Int literal to string with `m` suffix - - to_K(num: int) -> str - Int literal to string with `K` suffix - - to_M(num: int) -> str - Int literal to string with `M` suffix - - to_G(num: int) -> str - Int literal to string with `G` suffix - - to_T(num: int) -> str - Int literal to string with `T` suffix - - to_P(num: int) -> str - Int literal to string with `P` suffix - - to_Ki(num: int) -> str - Int literal to string with `Ki` suffix - - to_Mi(num: int) -> str - Int literal to string with `Mi` suffix - - to_Gi(num: int) -> str - Int literal to string with `Gi` suffix - - to_Ti(num: int) -> str - Int literal to string with `Ti` suffix - - to_Pi(num: int) -> str - Int literal to string with `Pi` suffix -- json - - encode(data: any, sort_keys: bool = False, indent: int = None, ignore_private: bool = False, ignore_none: bool = False) -> str - Serialize a KCL object `data` to a JSON formatted str. - - decode(value: str) -> any - Deserialize `value` (a string instance containing a JSON document) to a KCL object. - - dump_to_file(data: any, filename: str, ignore_private: bool = False, ignore_none: bool = False) -> None - Serialize a KCL object `data` to a JSON formatted str and write it into the file `filename`. -- yaml - - encode(data: any, sort_keys: bool = False, ignore_private: bool = False, ignore_none: bool = False) -> str - Serialize a KCL object `data` to a YAML formatted str. - - decode(value: str) -> any - Deserialize `value` (a string instance containing a YAML document) to a KCL object. - - dump_to_file(data: any, filename: str, ignore_private: bool = False, ignore_none: bool = False) -> None - Serialize a KCL object `data` to a YAML formatted str and write it into the file `filename`. -- net - - split_host_port(ip_end_point: str) -> List[str] - Split the 'host' and 'port' from the ip end point. - - join_host_port(host, port) -> str - Merge the 'host' and 'port'. - - fqdn(name: str = '') -> str - Return Fully Qualified Domain Name (FQDN). - - parse_IP(ip) -> str - Parse 'ip' to a real IP address - - to_IP4(ip) -> str - Get the IP4 form of 'ip'. - - to_IP16(ip) -> int - Get the IP16 form of 'ip'. - - IP_string(ip: str | int) -> str - Get the IP string. - - is_IPv4(ip: str) -> bool - Whether 'ip' is a IPv4 one. - - is_IP(ip: str) -> bool - Whether ip is a valid ip address. - - is_loopback_IP(ip: str) -> bool - Whether 'ip' is a loopback one. - - is_multicast_IP(ip: str) -> bool - Whether 'ip' is a multicast one. - - is_interface_local_multicast_IP(ip: str) -> bool - Whether 'ip' is a interface, local and multicast one. - - is_link_local_multicast_IP(ip: str) -> bool - Whether 'ip' is a link local and multicast one. - - is_link_local_unicast_IP(ip: str) -> bool - Whether 'ip' is a link local and unicast one. - - is_global_unicast_IP(ip: str) -> bool - Whether 'ip' is a global and unicast one. - - is_unspecified_IP(ip: str) -> bool - Whether 'ip' is a unspecified one. -- base64 - - encode(value: str, encoding: str = "utf-8") -> str - Encode the string `value` using the codec registered for encoding. - - decode(value: str, encoding: str = "utf-8") -> str - Decode the string `value` using the codec registered for encoding. -- crypto - - md5(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `MD5` and the codec registered for encoding. - - sha1(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA1` and the codec registered for encoding. - - sha224(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA224` and the codec registered for encoding. - - sha256(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA256` and the codec registered for encoding. - - sha384(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA384` and the codec registered for encoding. - - sha512(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA512` and the codec registered for encoding. -- manifests - - `yaml_stream(values: [any], opts: {str:} = {sort_keys = False, ignore_private = True, ignore_none = False, sep = "---"}`. This function is used to serialize the KCL object list into YAML output with the `---` separator - -### The Built-in System Package - -KCL provides a list of built-in system modules, which are loaded automatically and can be directly used without providing any module name. For example, `print` is a widely used built-in module. - -The following is the full list of these built-in system modules: - -- print() - - The print function. -- multiplyof(a, b) - - Check if the modular result of a and b is 0 -- isunique(inval) - - Check if a list has duplicated elements -- len(inval) - Return the length of a value -- abs(x) - Return the absolute value of the argument. -- all(iterable) - Return True if bool(x) is True for all values x in the iterable. If the iterable is empty, return True. -- any(iterable) - Return True if bool(x) is True for any x in the iterable. If the iterable is empty, return False. -- bin(number) - Return the binary representation of an integer. -- hex(number) - Return the hexadecimal representation of an integer. -- oct(number) - Return the octal representation of an integer. -- ord(c) -> int - Return the Unicode code point for a one-character string. -- sorted(iterable) - Return a new list containing all items from the iterable in ascending order. A custom key function can be supplied to customize the sort order, and the reverse flag can be set to request the result in descending order. -- range(start, end, step=1) - Return the range of a value with start, end and step parameter. -- min(iterable) - With a single iterable argument, return its smallest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the smallest argument. -- max(iterable) - With a single iterable argument, return its biggest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the largest argument. -- sum(iterable, start) - Return the sum of a 'start' value (default: 0) plus an iterable of numbers. When the iterable is empty, return the start value. This function is intended specifically for use with numeric values and may reject non-numeric types. -- pow(x, y, z) - Equivalent to `x**y` (with two arguments) or `x**y % z` (with three arguments). Some types, such as ints, are able to use a more efficient algorithm when invoked using the three argument form. -- round(number, ndigits) - Round a number to a given precision in decimal digits. The return value is an integer if ndigits is omitted or None. Otherwise the return value has the same type as the number. ndigits may be negative. -- typeof(x: any, \*, full_name: bool = False) -> str - Return the type of the value 'x' at runtime. When the 'full_name' is 'True', return the full package type name such as `pkg.schema`. - -### Plugin Modules - -KCL compiler needs to provide the ability to dynamically expand and load plugin modules without modifying the compiler itself. KCL compiler needs to support flexible pluggable module extension mechanism, so that KCL users can use more abundant built-in function capabilities to simplify writing. - -KCL compiler needs to ensure the stability and safety of the expansion mechanism, without affecting the core of the compiler. - -Searching extended plugin module is performed after the standard system module. The standard system module has a higher priority in naming. If it exists a standard or built-in system module with the same name, the extended plugin module will be ignored. - -Importing and using the extended plugin module should be consistent with the standard or built-in system module. - -### Replacing Standard System Packages - -Replacing standard system modules is not allowed. - -## Examples - -We show more module features through an example. - -Suppose we have the following directories and files: - -``` - . - ├── mod1.k - ├── mod2.k - ├── pkg1 - │   ├── def1.k - │   ├── def2.k - │   └── def3init.k - └── pkg2 - ├── file2.k - └── subpkg3 - └── file3.k -``` - -From the structure we can see that `pkg1` and `pkg2` are two packages, `subpkg3` is a subpackage of `pkg2`, and `mod1.k` and `mod2.k` are regular modules. - -### Importing a Standard System Package - -The following statement can import the standard system module `math` - -```python -import math -``` - -This is the only way to import a standard system module. After importing a standard system module, functions, variables and schemas defined in it can be used. For example, the following statement uses the `log10` function -defined in `math` - -```python -a = math.log10(100) # a is 2 after computation. -``` - -### Importing a Regular Module - -In `mod1.k`, we can import `mod2` using one of the following syntaxes. - -```python -import mod2 -``` - -```python -import .mod2 -``` - -The difference is that in the first syntax, the KCL compiler will first try to check if `mod2` matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where `mod1.k` resists in, like what the second statement does. - -Suppose in `mod2.k` there is a definition of a variable:: - -```python -a = 100 -``` - -After importing `mod2`, we can access `a` in `mod1.k` using the following syntax - -```python -b = mod2.a -``` - -### Importing a Package - -In `mod1.k`, we can import `pkg1` using one of the following syntaxes. - -```python -import pkg1 -``` - -```python -import .pkg1 -``` - -The difference is that in the first syntax, the KCL compiler will first try to check if `pkg1` matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where `mod1.k` resists in, like what the second statement does. - -We can use similar statements to import `pkg2`. Note that importing `pkg2` will not import `subpkg3`. - -The name of the package is the name of the imported module. - -Suppose in `file2.k` that is inside `pkg2` there is a definition to variable `foo` - -```python -foo = 100 -``` - -This variable can be used in `mod1.k` after importing `pkg2` like the following - -```python -bar = pkg2.foo -``` - -### Importing a Subpackage - -To import `subpkg3` from `mod1.k`, one of the following statements can be used. - -```python -import pkg2.subpkg3 -``` - -```python -import .pkg2.subpkg3 -``` - -The behaviors of these statements are identical. - -The name of the subpackage is the name of the imported module. - -Suppose in `file3.k` that is inside `subpkg3` there is a definition to variable `foo` - -```python -foo = 100 -``` - -This variable can be used in `mod1.k` after importing `subpkg3` like the following - -```python -bar = subpkg3.foo -``` - -### Relative Importing - -Relative importing is useful when there is code trying to import modules that does not exist recursively inside the current directory. - -For example, the following statements, if written in `file3.k`, can be used to import `pkg2`, `pkg1` and `mod2` respectively. - -```python -import ...pkg2 # Go two levels up then import pkg2 -import ...pkg1 # Go two levels up then import pkg1 -import ...mod2 # Go two levels up then import mod2 -``` - -### Importing from a Root Path - -Suppose we have a `kcl.mod` file in the directory to mark it as a root path, then we have the following files: - -``` - . - |── kcl.mod - ├── mod1.k - ├── mod2.k - ├── pkg1 - │   ├── def1.k - │   ├── def2.k - │   └── def3init.k - └── pkg2 - ├── file2.k - └── subpkg3 - └── file3.k -``` - -In `pkg1` `def1.k`, we can import `pkg2.subpkg3` `file3` using the following syntaxes. - -```python -import pkg2.subpkg3.file3 -``` - -Importing from the root path is very convenient when the code is trying to import modules from a directory needs to look up multiple directories above this directory. At also, it is helpful to organize a large number of files in a root directory. - -### Importing a Module Inside a Package - -Note that `subpkg3` is only implemented with one file `file3.k`. The file can be regarded as a regular module and imported directly. - -In `mod1.k`, the importing statement would be:: - -```python -import pkg2.subpkg3.file3 -``` - -Different from importing `subpkg3`, now the name of the module is `file3`. We can access the variable `foo` defined in this module with the following -statement - -```python -bar = file3.foo -``` - -### Precedence of Importing - -When an import statement specifies a package to import, the virtual machine first looks for a directory named according to the import statement in the file system. - -If such a directory is not found, the virtual machine looks for a single file module. - -For example, when the statement `import a.b.c` appears, the virtual machine first looks for the directory `a/b/c` from the directory of the current file. If `a/b/c` is not found, the virtual machine looks for a file named `a/b/c.k`. If the file is also absent, an error is reported. - -### Package Implemented with Multiple Files - -Package `pkg1` is implemented with multiple KCL files. - -Multiple files can be used to define variables, schemas and functions, and they can access names defined in other files of this package. - -For example, suppose `def1.k` defines a variable `foo`, `def2.k` defines `bar`, and `def3init.k` defines a variable `baz`, when `pkg1` is imported by `mod1.k`, all these variable can be used - -```python -import pkg1 -a = pkg1.foo + pkg1.bar + pkg1.baz -``` - -Inside a module, names defined in a file can be accessed in another file without further importing. For example, suppose `bar` in `def2.k` would invoke `foo` defined in `def1.k`, it can directly use `foo` like the following - -```python -bar = foo + 1 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/schema.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/schema.md deleted file mode 100644 index c3d09f65..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/schema.md +++ /dev/null @@ -1,916 +0,0 @@ ---- -title: "Schema" -linkTitle: "Schema" -type: "docs" -weight: 2 -description: Schema ---- - -## Syntax - -### Schema Definition - -A schema is a language element to define a type of configuration data. - -To define a schema, the syntax is the following: - -```bnf -schema_stmt: [decorators] "schema" ["relaxed"] identifier ["[" [arguments] "]"] ["(" operand_name ")"] ":" NEWLINE [schema_body] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt | schema_index_signature | statement)* [check_block] _DEDENT -``` - -Attributes could be defined in a schema, the syntax is the following: - -```bnf -schema_attribute_stmt: [decorators] identifier ["?"] ":" type [(ASSIGN | augassign) test] NEWLINE -``` - -Index signature could be defined in a schema, the syntax is the following: - -```bnf -schema_index_signature: LEFT_BRACKETS [NAME COLON] [ELLIPSIS] basic_type RIGHT_BRACKETS COLON type [ASSIGN test] NEWLINE -``` - -Once defined, an attribute must have a valid type: - -```bnf -type: type_element ("|" type_element)* -type_element: schema_type | basic_type | list_type | dict_type -schema_type: operand_name -basic_type: "str" | "int" | "float" | "bool" -list_type: "[" (type)? "]" -dict_type: "{" (type)? COLON (type)? "}" -``` - -The followings are some basic examples: - -```python -# A person has a first name, a last name and an age. -schema person: - firstName: str - lastName: str - # fullName is generated by firstName and lastName - fullName: str = firstName + ' ' + lastName - # The default value of age is 0 - age: int = 0 - -# An employee IS a person, and has some additional information. -schema employee(person): - bankCard: int - nationality: str - -# A company has a name and many employees. -schema company: - name: str - employees: [employee] -``` - -More complex schema definitions will be elaborated after other concepts are -introduced. - -#### Optional Attribute - -Each attribute **must** be assigned with a not-None value as a schema instance unless it is modified by a question mark as an optional attribute. - -Examples: - -```bnf -schema employee(person): - bankCard?: int # bankCard is an optional attribute - nationality?: str # # nationality is an optional attribute -``` - -When there is an inheritance relationship: - -- If the attribute is optional in the base schema, it could be optional or required in the sub-schema. -- If the attribute is required in the base schema, it must be required in the sub-schema. - -### Configuration Definition - -A configuration is structured data stored in a dict-like structure. In KCL, we have introduced -the configuration definition syntax as a variant of dict definition syntax. - -```bnf -schema_expr: operand_name ("(" [arguments] ")")? dict_expr -``` - -As can be seen, apart from having an identifier as schema type, a configuration definition -is just an ordinary dict definition, and each key in the dict matches an attribute in the schema. - -To simplify configuration, schema attribute key is much easier to define as: - -- schema attribute key can be unquoted. When the attribute key has the same name as a variable, it must be quoted as a normal dict to avoid naming conflict. -- schema attribute key can be defined nested through `select expression`, such as `a.b.c`. - -The comma at the end of each line can be omitted. - -For example, we can define a `person` named `John Doe` using the following statement: - -```python -johnDoe = person { - # In the result, 'lastName' appears later than 'firstName', according the schema - lastName = 'Doe' - firstName = 'John' - # If we don't specify the 'age', the default value 0 is used. - # 'age': 20 -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' - 'age': 0 -} -``` - -Compared to the ordinary dict definition, a configuration definition has the following features: - -- Each attribute defined in the schema (or one of the schemas) could be configured, and config data has higher priority than the default value. -- When an attribute defined in the schema (or one of the schemas) is not configured in the configuration definition statement, and it has a default value, the default value is used. -- Unless the schema (or one of the schemas) is a **relaxed schema**, no more attributes can be defined. -- The quotation marks of dict key can be omitted. -- The comma at the end of each line can be omitted. -- Cases of **inheritance** will be discussed separately. - -For attributes of list, dict and schema types, the config data is added by **union** instead of reassignment. For instance: - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name = { - firstNam = "John" - lastName = "default" - } - -JohnDoe = Person { - name.lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' -} -``` - -#### Attribute Identify - -Each key identifier in the configuration expr identifies an element or a range of elements in a schema. The key identifier may consist of multiple attribute identifiers, and each attribute may be a basic type value, a list, a dict or schema. For example, the key identifier 'a.b.c' identifies the element 'c' in the 'A' schema: - -```python - -schema C: - c: int - -schema B: - b: C - -schema A: - a: B - -A { - a.b.c: 5 -} -``` - -To make the key identifier usage rules as clear as possible, we define the way of identifying with complex data types as follows. - -##### List - -Suppose we have a list attribute a. - -Identify an element in a: - -```python -a[0] # the first element -a[3] # the 4th element -a[-1] # the last element -a[-2] # the penultimate element -``` - -Identify a range of elements in the list: - -```python -a[2:5] # a slice of the third, 4th, and 5th elements -a[:5] # a slice of the first to 5th elements -``` - -#### Attribute Operator - -Once we identified the element(s), we can declare operation on it. It follows the pattern of `identifier op E`. - -#### Union - -Pattern: `identifier : E` - -The value of the expression `E` will be unioned into the element value. - -Examples: - -```python -a = A { - # union {d:4} into the element b.c, suppose c is a schema with an int type attribute d. - b.c : { - d : 4 - } -} -``` - -See 'union' in `expressions` spec for more details. - -#### Override - -Pattern: `identifier = E` - -The value of the expression `E` will override the element value. - -Examples: - -```python -a = A { - # override {c:4} to the element b, suppose b is a schema with an int type attribute c. - b = { - c: 4 - } -} -``` - -Unlike union, the override operation will reassign the element with a brand new value. -For basic type value, `union` and `override` have equivalent effects. - -Note: - -- Especially, we can "delete" its content by overriding the element to `Undefined`, such as `{ a = Undefined }`. - -#### Insert - -Pattern: `identifier += E` -Insert only works for list type `identifier`. - -List `E` will be inserted just after the specified index of the list `identifier`, and the following elements after the index will be automatically shifted. - -Examples: - -```python -a = A { - # insert {c:4} to the end position(just after index=1), suppose b is a list of schema with an int type attribute c. - b += { - c: 4 - } -} -``` - -If no index is specified, the last index will be used. - -The type of 'E' must be compatible with the type of list. See `types` for more details. - -#### Index Signature - -Index signatures can be defined in the KCL schema, and it means that the key-value constraints of the index signature can be used to construct a dict with the schema type, or additional checks can be added to the relaxed schema attributes to enhance the KCL type and semantic checks. - -- Use the form `[{attr_alias}: {key_type}]: {value_type}` to define an index signature in the schema, and `{attr_alias}` can be omitted. - -```python -schema Map: - """ - Map is a relaxed schema with a key of str type and a value of str type - """ - [str]: str # `{attr_alias}` can be omitted. - -data = Map { - key1 = "value1" - key2 = "value2" -} -``` - -- Mandatory all attributes of the schema key and value types - -```python -schema Person: - name: str - age: int # error, conflicts with the index signature definition `[str]: str` - [str]: str # The values of all attributes of the schema can only be strings -``` - -- Mandatory all attribute key and value types are defined in the schema, which is equivalent to restricting all attribute types except the relaxed attributes. - -```python -schema Person: - name: str - age: int - [...str]: str # Except for the `name` and `age` attributes, the key type of all other attributes of the schema must be `str`, and the value type must also be `str`. -``` - -- Define the index signature attribute alias and use it with the check block. - -```python -schema Data: - [dataName: str]: str - check: - dataName in ["Alice", "Bob", "John"] - -data = Data { - Alice = "10" - Bob = "12" - Jonn = "8" # error Jonn not in ["Alice", "Bob", "John"] -} -``` - -```python -import regex - -schema DataMap: - [attr: str]: str - check: - regex.match(attr, r'^[-._a-zA-Z0-9]+$') - -data = DataMap { - key1 = "value1" - "foo.bar" = "value2" # check error -} -``` - -### Schema Context - -The schema definition space can be regarded as a separate function context. - -Init statement could be defined inside the schema, the syntax is the following: - -```bnf -statement: small_stmt NEWLINE | if_stmt -``` - -The following is an example: - -```python -schema Person: - firstName: str = "John" - lastName: str - # fullName is generated by firstName and lastName in a separate init statement - fullName: str = firstName + ' ' + lastName - -JohnDoe = Person { - lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' -} -``` - -If statement, expr statement and assert statement are supported as a schema init -statement. See more in statement spec. - -- The attributes must be defined first, including inherited ones, and then used in the init statement. -- Statements in the schema context will be executed sequentially. -- The value of attributes referenced in the init statement will be evaluated at runtime. - See the **Configuration Definition** section for the assignment rules of non-referenced attributes. For example, `"fullName"` in Person is generated by `"firstName"` and `"lastName"` evaluated at runtime, in which firstName is 'John', and lastName is "Doe". - -The immutability of attributes in the schema context follows the same rules as the immutability of global variables: - -```python -schema Person: - age: int = 1 # Immutable attribute - _name: str = "Alice" # Mutable attribute - - age = 10 # Error - _name = "Bob" # Ok -``` - -#### Arguments - -Schema context can also have arguments. The following is an example. - -```python -schema Person[separator]: - firstName: str = "John" - lastName: str - fullName: str = firstName + separator + lastName - -JohnDoe = Person('_') { - lastName = "Doe" -} -``` - -The example is similar to the previous one, except that the separator character used in -the `"fullName"` member is passed in as an argument. The way to perform a schema generation -when the schema has an initialization function with arguments is demonstrated in the code. - -### Check Block - -Optionally, a check block can be added to a schema definition to allow -additional checking to be performed. - -The syntax is the following: - -```bnf -check_block: "check" ":" NEWLINE _INDENT check_expr+ _DEDENT -check_expr: test (IF test)? [":" primary_expr] NEWLINE -``` - -In terms of grammatical definition, a check block consists of a list of conditional expressions. The following is an example: - -```python -schema employee(person): - bankCard: int - gender: str - - check: - len(str(bankCard)) == 16 - gender in ['male', 'female'], "The gender {} is unsupported".format(gender) -``` - -The ability of KCL check expressions covers the abilities that can be defined by OpenAPI spec and is aligned with the ability of logical expressions. We consider further aligning the syntax with `CEL` spec. -Whether to support `lambda expressions` is still under discussion. - -Summary: - -- A check block consists of one or more logical **expressions**. -- When defining a configuration, the expressions in the check block are evaluated - in any order. If any of the expression is `False`, an error is reported. -- A custom error message can be provided after an expression. - -### Specifying Types - -Optionally, the type of any member of a schema can be specified. As previous examples have shown. - -A member can be of a basic type, such as a string (`str`), a floating-point number (`float`), a fixed-point number (`int`) or a boolean number (`bool`). - -A member can also be of a dictionary generated from another schema. In such a case, the name of the other schema is used as the type name. - -A member can also be a list or an ordinary dict: - -- A list with unspecified type of elements is `[]`. -- A list with elements of type `t` is `[t]`. Here `t` is another type. -- A dict with keys of type `kt` and values of type `vt` is `{kt:vt}`. -- `kt`, `vt` or both of them can be missing, like a list with unspecified type of elements. - -The followings are some more examples: - -- A list of lists of strings: `[[str]]`. -- A dict of keys with the type string and unspecified value types: `{str:}`. - -A member can be a **union type** defined by `|`, such as `a | b`, which means the type of the member could be a or b. - -A union type can include types of `int`, `str`, `float`, `bool`, `list` and `dict` and support type nesting e.g. `{str:str|int}` and `[[int|str]|str|float]`, etc. - -Examples: - -```python -schema x: - p: int | str # p could be defined as a int or string -``` - -### Immutability - -KCL pursues strict immutability of schema attributes. It's generally followed the rules: - -- For the attributes of the basic type, such as string, int and float, it's allowed to be reassigned - through the init statement in **schema context** or by the **configuration definition**. -- For the attributes of list, dict and schema type, it's allowed to be reassigned only by the init statement in **schema context**. The content of it is allowed to be operated in **schema context** or by the **configuration definition**. -- Any other attempt to reassign or modify schema attribute will report an error. - -#### Assign by Value - -When using a schema variable to assign the value to another variable, we can only get a deep copy of its value, not a pointer or reference. That is, modifying the assigned value will not change the assigned schema variable. - -```python -schema Person: - name: str - -person = { - name = "Alice" -} -personCopy = person # 'personCopy' is a deep copy of 'person' and modifying 'personCopy' will not affect 'person' -``` - -### Union Operator - -For list, dict and schema, we can union delta to existing data. For example: - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name = { - firstName = "John" - } - - # union a schema and a dict - name: Name { - lastName = "Doe" - } - -person = Person {} -``` - -The result is a **dict**: - -```python -{ - 'person': { - 'name': { - 'firstName': 'Jhon', - 'lastName': 'Doe' - } - } -} -``` - -### Other Operators - -Except for `assignment` and `union assignment`, it's not support other operators on schema type data. -Report an error if trying to use other operators on schema type data. - -### Deprecated - -The schema attribute can be marked as deprecated once it's considered invalid. - -```python -schema Person: - @deprecated(version="1.1.0", reason="use fullName instead", strict=True) - name: str - ... # Omitted contents - -person = Person { - # report an error on configing a deprecated attribute - name = "name" -} -``` - -- Deprecated attributes cannot be configured under any circumstances. Report an error or warning once the attribute is assigned. -- Define the expired version of the attribute through **version**, and define the reason for the attribute expired through **reason**. -- When strict is true, the attribute assignment will cause an error, otherwise it will report a warning and ignore the attribute assignment. - -### Composition - -The composition is a common way to define complex structures. KCL provides simplified means for the configuration definition of combined structures. - -Assuming we have the following schemas, which is defined by a combination of multiple schemas. - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name - age: int - -schema Group: - name: str - persons: [Person] -``` - -To config a group: - -```python -group = Group { - name = "group" - persons = [{ - name = { - firstName = "John" - lastName = "Doe" - } - age = 24 - }] -} -``` - -- Top-level schema name is required to config a schema. -- The schema of the attributes in the schema can be omitted. - -Multi-level nested schemas will make the configuration verbose. KCL supports defining attributes in the schema through `selector expression`. The selector form is **x.y.z**, see the following example: - -```python -group = Group { - name = "group" - persons = [{ - name.firstName = "John" - name.lastName = "Doe" - age = 24 - }] -} -``` - -- Selector can be used to represent attribute in a schema - -### Inheritance - -Inheritance is an effective means to define a hierarchical structure definition, and KCL supports limited **single inheritance** of the schema. - -```python -schema Person: - firstName: str - lastName: str - -# schema Scholar inherits schema Person -schema Scholar(Person): - fullName: str = firstName + '_' + lastName - subject: str - -JohnDoe = Scholar { - firstName = "John", - lastName = "Doe", - subject = "CS" -} -``` - -The result is a **dict**: - -```python -{ - 'JohnDoe': { - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' - 'subject': 'CS' - } -} -``` - -Each schema can be treated as a separated function context. Statements, including attribute statements and init statements, in the context of schemas will be evaluated from base schema to subschema according to the inheritance order. Each schema context is evaluated only once sequentially. The same goes for expressions in the check block. In the example, firstName and lastName are configured in the context of Person schema, and fullName is formed by splicing firstName and lastName in the context of Scholar schema. - -The default value can be modified in each schema. Value defined in **Configuration Definition** has a higher priority than the default value. Attributes with default values in any schema context ​​will eventually be unioned by configuration data. References to attributes in the schema context statements will use the value with unioned configuration data on evaluating at runtime. For example: - -```python -schema a: - x = 1 - y = x * 2 - -schema b(a): - x = 2 - -v = a { - x = 3 -} - -``` - -The result is a **dict**: - -```python -{ - 'v': { - 'x': 3 - 'y': 6 - } -} -``` - -Notes: - -- Report an error if inheriting more than one base schema. -- The type of the base schema attribute cannot be modified in the subschema. -- Report an error if inheriting a **mixin**. -- Report an error when a circular dependency occurs. - -Limitations: - -Since inheritance will derive some complex demands, we are cautious about these complex demands. There are still some restrictions on inheritance, and it's still under discussion. - -- KCL provides limited and deterministic polymorphism support, more complex and flexible polymorphism support, such as **self**, **super** keywords, are temporarily not included in the schema definition. -- Currently, KCL only supports the polymorphism of the inherited attributes of the schema, and does not support the polymorphism of the expressions in the check block. -- For the case of multiple levels of schema inheritance, the schema arguments can only be passed to the last level of sub-schema. - -### Mixin - -In addition to **composition** and **inheritance**, KCL supports declarative reuse of schema code through the **mixin** mechanism. To use a mixin, we only need to declare the **mixin** in the schema definition. - -The **mixin** syntax is the following: - -```bnf -//////////// mixin_stmt //////////// -mixin_stmt: "mixin" "[" [mixins | multiline_mixins] "]" "\n" -multiline_mixins: "\n" _INDENT mixins "\n" _DEDENT -mixins: operand_name ("," ("\n" mixins | operand_name))* -``` - -Here is a simple example: - -```python -schema Person: - mixin [FullNameMixin] - firstName: str = "default" - lastName: str - -schema FullNameMixin: - fullName: str = "{} {}".format(firstName, lastName) - -JohnDoe = Person { - firstName = "John" - lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'JohnDoe': { - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' - } -} -``` - -Multiple mixins can be added to a single schema, and mixins context will be evaluated after the host schema context at runtime. In the inheritance scenario, the mixin context can be regarded as a part of the host schema context, and the overall evaluation of schema context order is not affected. - -Notes: - -- The name of **mixin** schema must end with 'Mixin', otherwise an error will be reported. -- The attributes referenced in the **mixin** must be defined in the **mixin** itself or host schema, otherwise an error will be reported. - -### Protocol - -In addition to schema, an additional type definition method `protocol` is provided in KCL, and its properties are as follows: - -- In a protocol, only attributes and their types can be defined, complex logic and check expressions cannot be written, and mixins cannot be used. -- A protocol can only inherit or refer to other protocols, but cannot inherit or refer to other schemas. - -We can use **protocol** to add an optional host type to the dynamically inserted **mixin**. - -The **mixin** can define its host type through the `for` keyword, and internally it will query the type corresponding to the attribute from the host type. - -```python -protocol DataProtocol: # A mixin host type - data: str - -mixin DataMixin for DataProtocol: # Using the `for` keyword to define a mixin host type - x: int = data # The type of `data` is `str`, which is from `data` of `DataProtocol` -``` - -In `DataMixin`, the `data` attribute is obtained according to the `DataProtocol` host type as `str` type, and then a type error will occur when the value is assigned to `x` of type `int`: - -```python -protocol DataProtocol: - data: str - -mixin DataMixin for DataProtocol: - x: int = data # Error: expect int, got str - x: str = data # Error: can't change schema field type of 'x' from int to str -``` - -Please note that the host type **protocol** can only be used for **mixin** definitions (the suffix name is `Mixin`), otherwise an error will be reported. - -```python -protocol DataProtocol: - data: str - -schema Data for DataProtocol: # Error: only schema mixin can inherit from protocol - x: str = data -``` - -### Schema Context Evaluation - -The schema definition is composed of attribute statements, configuration data, init statements, mixins, and checks. In a separate schema context, the evaluation top-down order is as follows: - -``` -|------------------------------------------| -| attribute defaulting | -|------------------------------------------| -| configuration union | -|------------------------------------------| -| attribute templating | -|------------------------------------------| -| statements in declaration order | -|------------------------------------------| -| mixins in declaration order | -|------------------------------------------| -| check expressions in any order | -|------------------------------------------| -``` - -In the case of schema inheritance, each schema context is evaluated from the base schema in the order of inheritance, and each context is evaluated only once. -Suppose there are schemas a, b, and c, where c inherits b and b inherits a. Schema contexts will be evaluated in top-down order as: - -``` -|-----------------| -| schema a | -|-----------------| -| schema b | -|-----------------| -| schema c | -|-----------------| -``` - -### Members - -Built-in function and members of schema - -- instances() - Return the list of existing instances of a schema. - -### Irrelevant Order Calculation - -The irrelevant order calculation in the schema indicates the reference relationship between the internal attributes of the schema. For example, when we declare an expression of the form `a = b + 1`, the calculation of the value of `a` depends on the calculation of the value of `b`. When the compiler calculate the value of `a` and the value of `a` depends on the value of `b`, the compiler will choose to first calculate the value of `b`, and then calculate the value of a according to the expression `a = b + 1`, which is slightly different from the calculation method of traditional procedural language the difference. - -Since the calculation of values in the schema is based on dependencies, just like a directed acyclic graph traverses each node in the graph according to the order of topological sorting, the order of declaration of attributes in the schema is not so important, so the feature is called the irrelevant order calculation. - -Please note that there can be no circular references between different schema attribute values. - -We can see this feature through the following examples. - -```python -schema Person: - name?: str - age: int = _age - - _age = 10 - - if name == "Son": - _age = 18 - -schema Son(Person): - name: str = "Son" - -person = Person {} -son = Son {} -``` - -The output is - -```yaml -person: - name: null - age: 10 -son: - name: Son - age: 18 -``` - -Besides, we can achieve KCL polymorphism such as - -```python -schema Person: - name?: str - _age: int = _age - - _age = 10 - if name == "Son": - _age = 18 - elif name == "SonConf": - _age = 24 - -schema Son(Person): - name: str = "Son" - -person = Person() {} -son = Son() { - name = "SonConf" -} -``` - -The output is - -```yaml -person: - name: null - age: 10 -son: - name: SonConf - age: 24 -``` - -More examples: - -```python -schema Fib: - n1: int = n - 1 - n2: int = n1 - 1 - n: int - value: int = _value - - if n <= 2: - _value = 1 - else: - _value = (Fib {n = n1}).value + (Fib {n = n2}).value - -fib8 = (Fib {n = 8}).value -``` - -The output is - -```yaml -fib8: 21 -``` - -As in the above examples, we can see that in the schema, we only need to simply specify the dependency between attributes, and the compiler will automatically calculate the value based on the dependency, which can help us save a lot of boilerplate code and reduce configuration difficulty of writing. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/statements.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/statements.md deleted file mode 100644 index b09488b9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/statements.md +++ /dev/null @@ -1,185 +0,0 @@ ---- -title: "Statements" -linkTitle: "Statements" -type: "docs" -weight: 2 -description: Statements ---- - -## Syntax - -In KCL, statements consist of small statements and compound statements. The syntax is the following: - -```bnf -preamble_statement: preamble_small_stmt | preamble_compound_stmt -preamble_small_stmt: (small_stmt | import_stmt) NEWLINE -preamble_compound_stmt: compound_stmt | schema_stmt -statement: small_stmt NEWLINE | compound_stmt -compound_stmt: if_stmt -small_stmt: assign_stmt | expr_stmt | assert_stmt -``` - -The preamble statement is used to define the module level statements, consist of `statement`, `import_stmt`, and `schema_stmt`. The statement is used to define the block level statements, which are used in the `if` statement and `schema` statement. - -### Small Statements - -A small statement is comprised of a single logical line. Multiple statements in one-line are not allowed. - -#### Assignment Statements - -Generally, assign_stmt is divided into assignment and augmented assignment. The syntax is the following: - -```bnf -assign_stmt: target_primary ("=" target_primary)* "=" test | target_primary augassign test -augassign: "+=" | "-=" | "*=" | "**=" | "/=" | "//=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>=" | "or" | "and" -target_primary: identifier | target_primary DOT identifier -``` - -An assignment statement has the form `lhs = rhs`. It evaluates the expression on the right-hand side then assigns its value (or values) to the variable (or variables) on the left-hand side. - -The **target_primary** on the left-hand side is an `identifier` or an `identifier` followed by select dots. - -Note: When using **target_primary** will cause collisions, use **primary_expr** as an alternative. - -Examples: - -```python -k = 1 -a.b = "a.b" -``` - -To keep it simple, the compound target is not supported as **target_primary**. - -The right value of an assignment statement is a conditional expression, which is discussed separately. - -An augmented assignment, which has the form `lhs op= rhs` updates the variable `lhs` by applying a binary arithmetic operator op (one of +, -, \*, /, //, %, &, |, ^, <<, >>) to the previous value of `lhs` and the value of `rhs`. - -The **target_primary** on the left-hand side is the same as assignment statement. Examples: - -```python -_x -= 1 -_filename += ".k" -``` - -There is no concept of in-place modification in KCL. The `augassign` statement will modify a copy of the **target_primary** and assign the copy to **target_primary**. - -In particular, in KCL, the `|=` symbol represents the **union** operation, which is defined as follows: - -- The behavior of the **union** operation needs to be consistent with the behavior of the **configuration definition**. - -See **expressions** spec for more details of union operator in **Arithmetic Operations**. - -#### Expression Statements - -An expression statement evaluates an expression and discards its result. - -Syntax: - -```bnf -expr_stmt: expression -``` - -An expression statement supported in KCL is function invocation expression, which is discussed in **expression** spec. - -```python -print(k) # print a variable -``` - -#### Import Statements - -Import statements are used to **search** and **load** a module, and define a name or names in the local namespace for the scope where the import statement occurs. - -Syntax: - -```bnf -import_stmt: "import" dot_name ("as" NAME)? -dot_name: [leading_dots] identifier (DOT identifier)* -leading_dots: "."+ -``` - -Examples: - -```python -import math # import a built-in module math -import pkg # import pkg -import pkg.foo # import pkg.foo -import pkg.subpkg # import a subpkg in a pkg -import .pkg2.subpkg3 # import a subpkg in a pkg inside of current pkg -import ...pkg2 # Go two levels up then import pkg2 -``` - -See **module** spec for more details of module spec. - -#### Assert Statements - -Assert statements are a convenient way to insert debugging assertions into KCL code. - -The syntax is the following: - -``` -assert_stmt: ASSERT test ("," test)? -``` - -The conditional expression in assert will be evaluated and get a boolean. Report an error if returning a `False`. - -Examples: - -```python -assert: x > 1 # report an error on x <= 1 -``` - -#### Conditional Statements - -KCL allows using conditional statements to control the instructions to -be executed. They are also called the control-flow statements. - -The only type of control-flow syntax is the well-known `if-elif-else` syntax. - -The syntax of the `if-elif-else` statement is the following. - -```bnf -if_stmt: "if" test ":" suite ("elif" test ":" suite)* (ELSE ":" suite)? -suite: small_stmt | NEWLINE _INDENT statement+ _DEDENT -``` - -An `if` or `elif` statement evaluates a given expression. When the expression -is evaluated to `True`, a list of statements following `:` are executed. - -The following is an example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - print("maybe a is negative") -else: - print("a >= 100") -``` - -`if-elif-else` statements can be nested. For example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - if a < 0: - print("a is negative") - print("No matter a is negative or positive, this message is printed") -else: - print("a >= 100") -``` - -#### Schema Statements - -Schema statements are used to define a type of configuration data. The syntax is the following: - -```bnf -schema_stmt: [decorators] "schema" ["relaxed"] identifier ["[" [arguments] "]"] ["(" operand_name ")"] ":" NEWLINE [schema_body] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt | statement)* [check_block] _DEDENT -``` - -See **schema** spec for more details of schema spec. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/tour.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/tour.md deleted file mode 100644 index 93a080e5..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/tour.md +++ /dev/null @@ -1,3208 +0,0 @@ ---- -title: "KCL 之旅" -sidebar_position: 1 ---- - -本文展示了如何使用 KCL 的核心特性,包含变量、运算符、schema 和库,前提是您有使用其他语言编程的经验。KCL 主要受 Python 启发,了解 Python 对学习 KCL 非常有帮助。 - -### 重要概念 - -在学习 KCL 语言时,请牢记以下事实和概念: - -- KCL 是一种配置策略语言。它为编写配置和策略提供了简单且自洽的语言设计和库支持。它不能用于应用程序开发或其他通用编程语言(GPL)支持的场景。 -- KCL 吸收了经典 **OOP** 的元素,并且提供了**类型**、**复用**和**合并**等简单、开发人员友好、可靠且利于传播的配置编写实践。 -- KCL 更倾向于**不可变性**,建议使用**合并**来添加增量的变更。不可变性降低了副作用,例如不可预测的问题。 -- KCL 的 **schema** 结构体定义了严格的属性和静态类型,并且支持表达式验证。**schema** 结构体主要由带类型的属性、schema 上下文和检查块构成。 -- KCL 的 **config** 是一个类 **JSON** 表达式,通过它我们可以复用 schema 的完整定义。KCL 通过分离 schema 和 config 来提供定义和配置的能力。 -- KCL 的 **rule** 是一个书写规则约束表达式的结构,可用于数据校验和策略编写。 -- KCL 的代码文件以包(目录)和模块(文件)的形式进行管理。同一包中的 schema 彼此可见;跨包的数据需要通过 **import 语句**导入。包级变量虽然可以导出,但是它们不能被其他包修改。 -- KCL 语法定义主要使用声明式表达式,并且只提供少量必要的声明式语句,例如 import、 if...else、assert、assignment 以及 schema。 -- 没有主函数,每个 `.k` 文件可以作为单独的配置文件执行。 -- 支持**内置函数**和**插件**以简化编写。 - -### 关键字 - -下表列出了 KCL 语言的关键字。 - -```txt -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -### 标识符 - -在 KCL 中, 标识符是标识一个值的名称,可以带有选择器。 - -- 标识符由字母、数字、下划线或前缀 `$` 组成。 -- 标识符不能与关键字重复,除非它们有 `$` 前缀。 -- 标识符不得包含任何嵌入的空格或符号。 -- 可以在标识符中的任何位置使用字母和下划线。 -- 数字不能放在标识符的第一位。 -- `$` 字符只能放在标识符的第一个位置。 - -示例: - -```python -x -a -b1 -b_2 -_c -$if -``` - -为了简化限定标识符(例如 `pkg.type`)的定义,我们还定义了 `qualified identifier`: - -示例: - -```python -pkg.a -``` - -在 `qualified identifier` 中的包名必须通过 `import` 关键字导入。 - -#### 标识符前缀 - -使用 `$` 前缀符号定义关键字标识符。 - -```python -$if = 1 -$else = "s" -``` - -请注意,非关键字标识符是否有 `$` 符号都是同样的效果。 - -```python -_a = 1 -$_a = 2 # equal to `_a = 2` -``` - -### 变量 - -以下是如何创建并实例化变量的例子: - -```python -name = "Foo" # Declare a variable named `name` and its value is a string literal "Foo" -``` - -它对应了如下 YAML 输出: - -```yaml -name: Foo -``` - -在 KCL 中,我们可以通过定义包级变量将变量导出为配置数据。使其直接、清晰、可维护。导出的变量是不可变的。因此一旦声明它,就无法对其进行修改,例如,假设我们有一个名为 `example.k` 的配置文件,变量 `name` 在声明后就禁止修改,就像标准的命令式语言一样。 - -```python -name = "Foo" # exported - -... - -name = "Bar" # error: a exported declaration variable can only be set once. -``` - -作为补充,我们可以在模块级别定义一个非导出变量,这个变量是可变的,不会显示在 YAML 输出当中。 - -```python -_name = "Foo" # _ variables are not output to YAML and are mutable -_name = "Bar" -``` - -请注意,变量的名称不能为 `True`、`False`、`None` 或者 `Undefined`,因为它们与 KCL 内置的名称常量之间存在二义性。 - -```python -False = 1 # Error -True = False # Error -None = Undefined # Error -Undefined = None # Error -``` - -### 内置类型 - -KCL 支持以下类型: - -- 数字 -- 字符串 -- 布尔 -- 列表 -- 字典 - -#### 数字 - -KCL 的数字类型有两种形式: - -- 64 位有符号整数。值的范围为 -9223372036854775808~9223372036854775807. -- 64 位浮点数,遵循 IEEE 754 标准。我们不建议在配置中使用 float 类型,我们可以使用字符串代替并在运行时进行解析。 - -整数和浮点数都支持基本运算符,例如 `+`,`-`,`/` 和 `*`,而复杂的运算,例如 `abs()`, `ceil()` 和 `floor()`,都是通过内置的数学库来支持。 - -整数是不带小数点的数字。以下是一些定义整数的例子: - -```python -a = 1 -b = -1 -c = 0x10 # hexadecimal literal -d = 0o10 # octal literal -e = 010 # octal literal -f = 0b10 # binary literal -g = int("10") # int constructor -``` - -如果一个数字包含小数点,则它是浮点数。以下是一些浮点数的示例: - -```python -a = 1.10 -b = 1.0 -c = -35.59 -d = 32.3e+18 -f = -90. -h = 70.2E-12 -i = float("112") # float constructor -``` - -内置数学库可用于数字类型: - -```python -import math - -assert abs(-40) == 40 -assert round(70.23456) == 70 -assert min(80, 100, 1000) == 80 -assert max(80, 100, 1000) == 1000 -assert sum([0,1,2]) == 3 -assert math.ceil(100.12) == 101.0 -assert math.floor(100.12) == 100.0 -assert math.pow(100, 2) == 10000.0 -``` - -KCL 默认使用 64 位数字类型。我们可以在 KCL 命令行使用 `-r` 参数执行严格的 32 位范围检查。 - -```bash -kcl main.k -r -d -``` - -请注意,为了性能考虑该功能只能在 `debug` 模式中使用。 - -##### 单位字面值 - -在 KCL 中,我们可以给一个整数添加如下的单位后缀,这不影响它的真实值。 - -- 通用整形和定点数: `P`, `T`, `G`, `M`, `K`, `k`, `m`, `u`, `n` -- 2 的幂: `Pi`, `Ti`, `Gi`, `Mi`, `Ki` - -```python -# SI -n = 1n # 1e-09 -u = 1u # 1e-06 -m = 1m # 1e-03 -k = 1k # 1000 -K = 1K # 1000 -M = 1M # 1000000 -G = 1G # 1000000000 -T = 1T # 100000000000 -P = 1P # 1000000000000000 -# IEC -Ki = 1Ki # 1024 -Mi = 1Mi # 1024 ** 2 -Gi = 1Gi # 1024 ** 3 -Ti = 1Ti # 1024 ** 4 -Pi = 1Pi # 1024 ** 5 -``` - -此外,我们还可以使用定义在 `units` 模块中的单位常量: - -```python -import units - -n = 1 * units.n # 1e-09 -u = 1 * units.u # 1e-06 -m = 1 * units.m # 1e-03 -k = 1 * units.k # 1000 -K = 1 * units.K # 1000 -M = 1 * units.M # 1000000 -G = 1 * units.G # 1000000000 -T = 1 * units.T # 1000000000000 -P = 1 * units.P # 1000000000000000 -# IEC -Ki = 1 * units.Ki # 1024 -Mi = 1 * units.Mi # 1024 ** 2 -Gi = 1 * units.Gi # 1024 ** 3 -Ti = 1 * units.Ti # 1024 ** 4 -Pi = 1 * units.Pi # 1024 ** 5 -``` - -我们还可以使用定义在 `units` 模块内的整数和单位字符串之间的转换函数 - -```python -import units -# SI -K = units.to_K(1000) # "1K" -M = units.to_M(1000000) # "1M" -G = units.to_G(1000000000) # "1G" -T = units.to_T(1000000000000) # "1T" -P = units.to_P(1000000000000000) # "1P" -# IEC -Ki = units.to_Ki(1024) # "1Ki" -Mi = units.to_Mi(1024 ** 2) # "1Mi" -Gi = units.to_Gi(1024 ** 3) # "1Gi" -Ti = units.to_Ti(1024 ** 4) # "1Ti" -Pi = units.to_Pi(1024 ** 5) # "1Pi" -``` - -```python -import units -# SI -K = units.to_K(int("1M")) # "1000K" -M = units.to_M(int("1G")) # "1000M" -G = units.to_G(int("1T")) # "1000G" -T = units.to_T(int("1P")) # "1000T" -P = units.to_P(int("10P")) # "10P" -# IEC -Ki = units.to_Ki(int("1Mi")) # "1024Ki" -Mi = units.to_Mi(int("1Gi")) # "1024Mi" -Gi = units.to_Gi(int("1Ti")) # "1024Gi" -Ti = units.to_Ti(int("1Pi")) # "1024Ti" -Pi = units.to_Pi(int("10Pi")) # "10Pi" -``` - -单位类型定义在 `units` 模块中,单位类型的值不能进行任何四则运算。 - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -x0: NumberMultiplier = 1M # Ok -x1: NumberMultiplier = x0 # Ok -x2 = x0 + x1 # Error: unsupported operand type(s) for +: 'number_multiplier(1M)' and 'number_multiplier(1M)' -``` - -我们可以使用 `int()`、`float()` 和 `str()` 函数将数值单位类型转换为数字类型或字符串类型。 - -```python -a: int = int(1Ki) # 1024 -b: float = float(1Ki) # 1024.0 -c: str = str(1Mi) # "1Mi" -``` - -#### 字符串 - -字符串是一个不可变的 Unicode 字符序列。我们可以使用单引号或双引号创建字符串: - -```python -'allows embedded "double" quotes' # Single quotes -"allows embedded 'single' quotes" # Double quotes -'''Three single quotes''', """Three double quotes""" # Triple quoted -``` - -三引号用于定义多行字符串。 - -```python -"""This is a long triple quoted string -may span multiple lines. -""" -``` - -请注意,KCL 的单引号和双引号字符串的使用几乎没有区别。唯一可以简化的是,我们不需要在单引号字符串中转义双引号,也不需要在双引号中转义单引号。 - -```python -'This is my book named "foo"' # Don’t need to escape double quotes in single quoted strings. -"This is my book named 'foo'" # Don’t need to escape single quotes in double quoted strings. -``` - -我们可以使用 `+` 操作符连接字符串: - -```python -x = 'The + operator ' + 'works, as well.' -``` - -我们可以使用 `str` 内置函数将 int 或 float 转为字符串: - -```python -x = str(3.5) # "3.5" -``` - -可以使用很多内置的字符串函数: - -```python -x = "length" -assert len(x) == 6 # True -assert x.capitalize() == "Length" -assert x.count("gt") == 1 -assert x.endswith("th") == True -assert x.find("gth") == 3 -assert "{} {}".format("hello", "world") == 'hello world' -assert x.index("gth") == 3 -assert x.isalnum() == True -assert x.isalpha() == True -assert "123456".isdigit() == True -assert x.islower() == True -assert " ".isspace() == True -assert "This Is Title Example".istitle() == True -assert x.isupper() == False -assert "|".join(["a", "b", "c"]) == "a|b|c" -assert "LENGTH".lower() == "length" -assert ' spacious '.lstrip() == 'spacious ' -assert x.replace("th", "ht") == "lenght" -assert "lengthlength".rfind("le") == 6 -assert "lengthlength".rindex("le") == 6 -assert "length length".rsplit() == ["length", "length"] -assert "length ".rstrip() == "length" -assert "length length".split() == ["length", "length"] -assert 'ab c\n\nde fg\rkl\r\n'.splitlines() == ['ab c', '', 'de fg', 'kl'] -assert "length".startswith('len') == True -assert "***length***".strip('*') == "length" -assert "length length".title() == "Length Length" -assert x.upper() == "LENGTH" -``` - -格式化字符串有两种使用方法: 使用 `"{}".format()` 内置函数, 或者使用花括号指定变量并使用 `$` 标记取变量值。在 KCL 中叫做**插值字符串**。在下面的例子中,`a` 和 `b` 的值都是 `"hello world"`。 - -此外,要序列化的变量可以以特殊的数据格式提取,例如 YAML 或 JSON。在这种情况中,`#yaml` 或 `#json` 可以包含在花括号中。 - -具体来说,当 `$` 符号本身需要出现在**插值字符串**中,需要使用 `$$` 转义。或者使用 `+` 符号连接 `$` 符号和插值字符串来避免转义。在以下示例中,`c` 和 `c2` 的值都是 `$hello world$`。 - -```python -world = "world" -a = "hello {}".format(world) # "hello world" -b = "hello ${world}" # "hello world" -c = "$$hello ${world}$$" # "$hello world$" -c2 = "$" + "hello ${world}" + "$" # "$hello world$" - -myDict = { - "key1" = "value1" - "key2" = "value2" -} - -d = "here is myDict in json: ${myDict: #json}" -# d: 'here is myDict in json: {"key1": "value1", "key2": "value2"}' - -e = "here is myDict in yaml:\n${myDict: #yaml}" -# e: | -# here is myDict in yaml: -# key1: value1 -# key2: value2 -``` - -此外,我们可以在上面的示例代码输出 **YAML 字符串** 中看到一些符号,例如 `|`、`>`、`+`、`-`。 - -- `|` 表示 **块文字样式**,指示块内换行符的行为方式。 -- `>` 表示块标量中的**块折叠样式**,换行符将被空格替换。 -- `+` 和 `-` 是 **block chomping 指示符**,用于控制字符串末尾的换行符。 默认值 **clip** 在字符串的末尾放置一个换行符。 要删除所有换行符,请通过在样式指示符 `|` 或 `>` 后面添加 `-` 来**删除**它们。 clip 和 strip 都忽略块末尾实际有多少换行符; 在样式指示符后面添加一个 `+` 来**保留**它们。 - -例如,**strip 块文字样式** yaml 字符串是 - -```yaml -example: |- - Several lines of text, - with some "quotes" of various 'types', - and also a blank line: - - plus another line at the end. -``` - -结果为: - -```plain -Several lines of text, -with some "quotes" of various 'types', -and also a blank line: - -plus another line at the end. -``` - -更多信息可见 [Yaml Multiline String](https://yaml-multiline.info/) 和 [YAML Specification v1.2](https://yaml.org/spec/1.2.1/) 。 - -##### 原始字符串 - -KCL 原始字符串是通过在字符串字面值前加上 `'r'` 或 `'R'` 来创建的。 KCL 原始字符串将反斜杠 (`\`) 和字符串插值 (`${}`) 视为普通的非字符。当我们想要一个包含反斜杠、字符串插值的字符串并且不希望它们被视为转义字符时,原始字符串是很有用的。 - -- 对于包含反斜杠(`\`)的原始字符串,KCL 代码和输出 YAML 如下: - -```python -s = "Hi\nHello" -raw_s = r"Hi\nHello" # This is a KCL raw string with the `r` prefix. -``` - -```yaml -s: |- - Hi - Hello -raw_s: Hi\nHello -``` - -- 对于包含字符串插值(`${}`)的原始字符串,KCL 代码和输出 YAML 如下: - -```python -worldString = "world" -s = "Hello ${worldString}" -raw_s = r"Hello ${worldString}" # This is a KCL raw string with the `r` prefix. -``` - -```yaml -worldString: world -s: Hello world -raw_s: Hello ${worldString} -``` - -此外,原始字符串最常用的场景是在正则表达式中使用: - -```python -import regex - -key = "key" -result = regex.match(key, r"[A-Za-z0-9_.-]*") # True -``` - -#### 布尔值 - -布尔值有两个常量对象:`False` 和 `True`. - -```python -a = True -b = False -``` - -#### List - -List 是一个序列,通常用于存储同质项的集合。下面是一个简单的 KCL 列表的例子: - -```python -list = [1, 2, 3] -assert len(list) == 3 # True -assert list[0] == 1 # True -``` - -我们可以使用列表推导式构建列表: - -```python -list = [ _x for _x in range(20) if _x % 2 == 0] -assert list == [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] # True -``` - -并且还可以使用嵌套的列表推导式: - -```python -matrix = [[1, 2], [3,4], [5,6], [7,8]] -transpose = [[row[_i] for row in matrix] for _i in range(2)] -assert transpose == [[1, 3, 5, 7], [2, 4, 6, 8]] # True -``` - -此外,我们可以在列表推导式中使用两个变量。第一个变量表示列表中的索引,第二个变量表示列表中的项。 - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use `_` to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -我们可以通过 `+` 连接列表: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -joined_list = _list0 + _list1 # [1, 2, 3, 4, 5, 6] -``` - -我们可以使用解包操作符 `*` 合并多个列表: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -union_list = [*_list0, *_list1] # [1, 2, 3, 4, 5, 6] -``` - -我们可以使用 `if` 表达式动态的将元素添加到列表,符合条件的元素会被添加到列表,不符合条件的元素会被忽略。 - -```python -a = 1 # 1 -data = [ - 1 - if a == 1: 2 - if a > 0: 3 - if a < 0: 4 -] # [1, 2, 3] -``` - -```python -a = 1 # 1 -data1 = [ - 1 - if a == 1: - 2 - elif a == 2: - 3 - else: - 3 -] # [1, 2] -data2 = [ - 1 - if a == 1: 2 - elif a == 2: 2 - else: 3 -] # [1, 2] -``` - -我们可以合并(union)列表: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -union_list = _list0 | _list1 # [4, 5, 6] -``` - -我们可以使用 `for k in list_var` 表达式遍历列表: - -```python -data = [1, 2, 3] -dataAnother = [val * 2 for val in data] # [2, 4, 6] -``` - -#### Dict - -Dict 是将可哈希的值映射到任意对象的映射对象。字典是有序的。键的顺序遵循其声明的顺序: - -这里有几个简单的 KCL 字典: - -```python -a = {"one" = 1, "two" = 2, "three" = 3} -b = {'one' = 1, 'two' = 2, 'three' = 3} -assert a == b # True -assert len(a) == 3 # True -``` - -在写多行的键-值时,可以省略每个键-值对行尾的逗号 `,`: - -```python -data = { - "key1" = "value1" # Ignore the comma ',' at the end of line - "key2" = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -在 Dict 键上使用简单的字面值时可以省略引号: - -```python -data = { - key1 = "value1" # Ignore key quotation '"' - key2 = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -此外,**选择表达式**可以用于定义包含嵌套键 dict 实例。 - -```python -person = { - base.count = 2 - base.value = "value" - labels.key = "value" -} # {"base": {"count": 2, "value": "value"}, "labels": {"key": "value"}} -``` - -输出 YAML 为: - -```yaml -person: - base: - count: 2 - value: value - labels: - key: value -``` - -在 KCL 中,dict 中的不同的字段可以直接引用,比如如下的例子 - -```python -config = { - name = "me" - metadata.name = name # Reference `name` with the value `"me"` in `config` directly. -} -``` - -输出 YAML 为: - -```yaml -config: - name: me - metadata: - name: me -``` - -我们可以使用字典推导式构建字典: - -```python -x = {str(i): 2 * i for i in range(3)} -assert x == {"0" = 0, "1" = 2, "2" = 4} -``` - -此外,我们可以在字典推导式中使用两个变量。第一个变量表示字典的键,第二个变量表示字典中键对应的值。 - -```python -data = {key1 = "value1", key2 = "value2"} -# Single variable loop -dataKeys1 = {k: k for k in data} # {"key1": "key1", "key2": "key2"} -dataValues1 = {k: data[k] for k in data} # {"key1": "value1", "key2": "value2"} -# Double variable loop -dataKeys2 = {k: k for k, v in data} # {"key1": "key1", "key2": "key2"} -dataValues2 = {v: v for k, v in data} # {"value1": "value1", "value2": "value2"} -dataFilter = {k: v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use `_` to ignore loop variables -dataKeys3 = {k: k for k, _ in data} # {"key1": "key1", "key2": "key2"} -dataValues3 = {v: v for _, v in data} # {"value1": "value1", "value2": "value2"} -``` - -我们可以使用解包操作符 `**` 来合并字典: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = {**_part1, **_part2} # {"a: "b", "c": "d"} -``` - -此外,union 操作符 `|` 也能达到同样的效果: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = _part1 | _part2 # {"a: "b", "c": "d"} -``` - -我们可以使用 `if` 表达式动态的将元素添加到字典,符合条件的元素会被添加到字典,不符合条件的元素会被忽略。 - -```python -a = 1 # 1 -data = { - key1 = "value1" - if a == 1: key2 = "value2" - if a > 0: key3 = "value3" - if a < 0: key4 = "value4" -} # {"key1": "value1", "key2": "value2", "key3": "value3"} -``` - -```python -a = 1 # 1 -data1 = { - key1 = "value1" - if a == 1: - key2 = "value2" - elif a > 0: - key3 = "value3" - else: - key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -data2 = { - key1 = "value1" - if a == 1: key2 = "value2" - elif a > 0: key3 = "value3" - else: key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -``` - -我们可以使用 `for k in dict_var` 表达式来遍历字典, 并且可以使用 `in` 操作符来判断 dict 是否包含某个键。 - -```python -data = {key1 = "value1", key2 = "value2"} -dataAnother = {k: data[k] + "suffix" for k in data} # {"key1": "value1suffix", "key2": "value2suffix"} -containsKey1 = "key1" in data # True -containsKey2 = "key" in data # False -``` - -#### None - -在 KCL 中, `None` 表示对象的值为空, 这与 Go 中的 `nil` 和 Java 中的 `null` 一样,并且对应于 YAML 中的 `null`。 - -```python -a = None -b = [1, 2, None] -c = {key1 = "value1", key2 = None} -``` - -输出如下: - -```yaml -a: null -b: - - 1 - - 2 - - null -c: - key1: value1 - key2: null -``` - -请注意,`None` 不能参与四则运算,但它可以参与逻辑运算和比较运算。 - -```python -a = 1 + None # error -b = int(None) # error -c = not None # True -d = None == None # True -e = None or 1 # 1 -f = str(None) # None -``` - -#### Undefined - -`Undefined` 与 `None` 类似,但其语义是变量没有分配任何值,也不会输出到 YAML。 - -```python -a = Undefined -b = [1, 2, Undefined] -c = {key1 = "value1", key2 = Undefined} -``` - -输出如下: - -```yaml -b: - - 1 - - 2 -c: - key1: value1 -``` - -请注意,`Undefined` 不能参与四则运算,但它可以参与逻辑运算和比较运算。 - -```python -a = 1 + Undefined # error -b = int(Undefined) # error -c = not Undefined # True -d = Undefined == Undefined # True -e = Undefined or 1 # 1 -f = str(Undefined) # Undefined -``` - -### 运算符 - -以下字符表示运算符: - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != @ \ -``` - -#### 算数运算符 - -KCL 支持常见的算数运算符: - -```python -assert 2 + 3 == 5 -assert 2 - 3 == -1 -assert 2 * 3 == 6 -assert 5 / 2 == 2.5 -assert 5 // 2 == 2 -assert 5 % 2 == 1 -``` - -#### 相等和关系运算符 - -KCL 支持相等和关系运算符: - -```python -assert 2 == 2 -assert 2 != 3 -assert 3 > 2 -assert 2 < 3 -assert 3 >= 3 -assert 2 <= 3 -``` - -#### 逻辑运算符 - -我们可以使用逻辑运算符反转或组合布尔表达式,例如:`and` 和 `or`: - -```python -if not done and (col == 0 or col == 3): - # ...Do something... - -``` - -#### 位运算符和移位运算符 - -以下是位运算符和移位运算符的例子: - -```python -value = 0x22 -bitmask = 0x0f - -assert (value & bitmask) == 0x02 -assert (value & ~bitmask) == 0x20 -assert (value | bitmask) == 0x2f -assert (value ^ bitmask) == 0x2d -assert (value << 4) == 0x220 -assert (value >> 4) == 0x02 -``` - -`|` 运算符可用于位运算,合并基本类型和集合及结构化数据,例如**列表**、**字典**和 **schema**。 - -位运算示例: - -```python -0x12345678 | 0xFF # 0x123456FF -``` - -联合基本类型示例: - -```python -schema x: - a: int | str # attribute a could be a int or string -``` - -#### 赋值运算符 - -以下 token 作为语法中的分隔符: - -```txt - ( ) [ ] { } - , : . ; = -> - += -= *= /= //= %= - &= ^= >>= <<= **= -``` - -以下是使用赋值和参数赋值赋值运算符的例子: - -```python -_a = 2 -_a *= 3 -_a += 1 -assert _a == 7 -``` - -#### Identity 运算符 - -以下关键字作为语法中的 identity 运算符: - -```python -is, is not -``` - -Identity 运算符检查右侧和左侧是否时同一对象。它们通常用于检查某个变量是否是 `None/Undefined/True/False`。以下是一些例子: - -```python -empty_String = "" -empty_String is not None # True -``` - -#### 成员运算符 - -以下关键字作为语法中的成员运算符: - -```python -in, not in -``` - -- `in` 运算符计算了第一个操作数是否是第二个操作数的成员,第二个运算符必须是 list、dict、schema 或 string。 -- `not in` 运算符与 `in` 相反。它们都返回一个布尔值。 - -成员的含义因第二个操作数的类型而异:列表的成员是其元素;字典的成员是其键;字符串的成员是其所有子字符串。 - -```python -1 in [1, 2, 3] # True - -d = {one = 1, two = 2} -"one" in d # True -"three" in d # False -1 in d # False -[] in d # False - -"nasty" in "dynasty" # True -"a" in "banana" # True -"f" not in "way" # True - -d = Data {one = 1, two = 2} # Data is a schema with attributes one and two -"one" in d # True -"three" in d # False -``` - -#### 推导式 - -一个推导表达式通过遍历一个或多个迭代项并计算表达式生成的结果来生成连续的元素,并以此构造新的列表或字典。 - -我们可以如下使用列表和字典的推导表达式: - -```python -listVar = [_x for _x in range(20) if _x % 2 == 0] # list comprehension -dictVar = {str(_i): 2*_i for _i in range(3)} # dict comprehension -``` - -#### 其他运算符 - -- 使用 **()** 表示函数调用, 例如 `"{} {}".format("hello", world)`。 -- 使用 **[]** 引用列表中指定索引处的值。 -- 使用 **:** 定义类型注解。 -- 使用 **.** 引用成员字段。 -- 使用 **\\** 续行符编写长表达式。 - -```python -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " -``` - -### 表达式 - -#### 条件表达式 - -条件表达式的形式为 `a if cond else b`。它首先计算条件 `cond`。如果为真,则会计算 `a` 并生成它的值;否则,它会生成 `b` 的值。 - -示例: - -```python -x = True if enabled else False # If enabled is True, x is True, otherwise x is False -``` - -#### 索引表达式 - -索引表达式 `a[i]` 生成可索引类型的第 `i` 个元素,例如字符串或数组。索引 `i` 必须是 `-n` ≤ `i` < `n` 范围内的 `int` 值,其中 `n` 等于 `len(a)`。其他任何索引都会导致错误。 - -有效的负索引的行为类似于 `n+i`,允许方便的对序列末尾进行索引。 - -```python -val = "abc" -list = ["zero", "one", "two"] -str_0 = val[0] # "a" -str_1 = val[1] # "b" -str_n1 = val[-1] # "c" - -list_0 = list[0] # "zero" -list_1 = list[1] # "one" -list_n1 = list[-1] # "two" -``` - -索引表达式 `d[key]` 也可以用于字典 `d`,以获取指定键对应的值。如果字典中不包含这个键则会返回 `Undefined` - -出现在赋值符左侧的索引表达式会更新指定的列表或字典元素。 - -```python -d = {key1 = "value1", key2 = "value2"} -key1value = d["key1"] # value1 -key2value = d["key2"] # value2 -``` - -尝试更新不可变类型的元素值(如列表或字符串)或可变类型的不可变变量会产生错误。 - -#### 切片表达式 - -切片表达式 `a[start:stop:step]` 会生成 `a` 包含的一个子序列,其中 `a` 必须是字符串或者数组。 - -`start`、`stop` 和 `step` 三个操作数都是可选的。如果有的话,每个值都必须为整数。`step` 的默认值为 1。如果 `step` 未指定,它前面的冒号也可以省略。指定 `step` 为 0 会产生错误。 - -从概念上来说,这些操作数指定了一系列值,索引 `i` 从 `start` 开始,每次增加 `step` 直到 `i` 到达或超过 `stop`。结果由有效的 `i` 的 `a[i]` 组成。 - -如下所示,从三个操作数计算有效的开始和结束的索引。`n` 是序列的长度。 - -```python -val = "abc" -len = len(val) -a = val[1:len] # "bc" (remove first element) -b = val[0:-1] # "ab" (remove last element) -c = val[1:-1] # "b" (remove first and last element) -``` - -```python -"abc"[1:] # "bc" (remove first element) -"abc"[:-1] # "ab" (remove last element) -"abc"[1:-1] # "b" (remove first and last element) -"banana"[1::2] # "aaa" (select alternate elements starting at index 1) -"banana"[4::-2] # "nnb" (select alternate elements in reverse, starting at index 4) -``` - -KCL 禁止将切片表达式定义为左值。原因是列表和字符串是不可变的,重新切片可以直接操作操作数,以确保更好的性能。 - -#### 函数调用 - -KCL 允许调用内置函数,或者调用内置和系统模块中的函数。 - -调用函数的基本方法如下所示: - -```python -import math - -a = math.pow(2, 3) # 2 powers 3 is 8. -b = len([1, 2, 3]) # the length of [1, 2, 3] is 3 -``` - -参数以 `,` 分隔,并且 KCL 还支持位置参数和键-值对形式的参数。 - -```python -print("hello world", end="") -``` - -请注意: - -- 有些函数参数具有默认值。 -- 一些函数接受可变参数。 - -如果没有为没有默认值的参数提供参数,则会抛出错误。 - -#### 选择表达式 - -选择表达式选择值的属性或方法。KCL 提供了许多识别或过滤属性的方法: - -`x.y` - -- dict: 表示字典 `x` 中键 `y` 对应的值。 -- schema: 表示 schema `x` 中 `y` 属性的值。 -- package: 表示 package `x` 中 `y` 标示的标识符。 - -示例: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -name = person.name # "Alice" -age = person.age # 18 - -myDict = { - key = "value" -} -result = myDict.key # "value" -``` - -`x?.y` - -`x` 可以是 schema 实例或 dict。当 `x` 可能为 `None` 或者键 `y` 不在 `x` 中时这非常有用。 - -```python -# Example of dict: -data = {"key" = "value"} -a = data?.key # "value" -b = data?.name # Undefined - -# example of schema instance: -schema Company: - name: str - address: str - -schema Person: - name: str - job?: Company - -alice = Person { - name = "alice" -} - -if alice?.job?.name == "Group": - print("work in Group") -``` - -#### Quantifier 表达式 - -Quantifier 表达式用于集合:列表或字典。通常用于在处理集合后获得某个结果,主要有以下四种形式: - -- **all** - - 用于检测集合中所有元素都满足给定的逻辑表达式,并且返回一个布尔值作为结果。 - - 只有集合中所有元素都满足表达式为 true 时,`all` 表达式为 true,否则为 false。 - - 如果集合为空,返回 true。 - - 支持表达式执行期间逻辑表达式的短路。 -- **any** - - 用于检测集合中至少一个元素都满足给定的逻辑表达式,并且返回一个布尔值作为结果。 - - 当集合中至少一个元素都满足表达式为 true 时,`any` 表达式为 true,否则 false。 - - 如果集合为空,返回 false。 - - 支持表达式执行期间逻辑表达式的短路。 -- **map** - - 映射集合中的元素生成新的列表。 - - 新列表的长度严格等于原列表的长度。 -- **filter** - - 通过逻辑判断筛选原集合中的元素,返回一个经过筛选的子集合。 - - 当表达式为 true 时才将元素添加到子集合。 - - 产生的新集合的类型(list, dict 和 schema)与原集合的类型完全一致,并且长度为 `[0, len(original-collection)]`。 - -**all** 和 **any** 表达式的示例代码: - -```python -schema Config: - volumes: [{str:}] - services: [{str:}] - - check: - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - }, "invalid cluster ip" - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } -``` - -**map** 和 **filter** 表达式的示例代码: - -```python -a = map e in [{name = "1", value = 1}, {name = "2", value = 2}] { - {name = e.name, value = int(e.value) ** 2} -} # [{"name": "1", value: 1}, {"name": "2", "value": 4}] - -b = map k, v in {a = "foo", b = "bar"} { v } # ["foo", "bar"] - -c = filter e in [{name = "1", value = 1}, {name = "2", value = 2}] { - int(e.value) > 1 -} # [{"name": "2", "value": 2}] - -d = filter _, v in {a = "foo", b = "bar"} { - v == "foo" -} # {"a": "foo"} -``` - -请注意,区分 any 表达式和 any 类型的区别。当 `any` 在类型注解中使用,意味着变量的值是任意的,而 any 表达式意味着集合中的至少一个元素满足条件。 - -### 流程控制表达式 - -#### If 和 Else - -KCL 支持 `if` 表达式和可选的 `elif` 和 `else` 表达式, 示例如下: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - print("maybe a is negative") -else: - print("a >= 100") -``` - -`elif` 的例子: - -```python -_result = 0 -if condition == "one": - _result = 1 -elif condition == "two": - _result = 2 -elif condition == "three": - _result = 3 -else: - _result = 4 -``` - -`if-elif-else` 表达式可以嵌套,示例如下: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - if a < 0: - print("a is negative") - print("No matter a is negative or positive, this message is printed") -else: - print("a >= 100") -``` - -此外,对于简单的 `if` 表达式如下: - -```python -if success: - _result = "success" -else: - _result = "failed" -``` - -我们可以使用 ` if else ` 的形式将它们写在一行: - -```python -_result = "success" if success else "failed" -``` - -`if` 或 `elif` 语句计算一个给定的表达式。当表达式的计算结果为 `True`, `:` 之后的语句将被计算,而当表达式为 `False` ,后面的语句不会被计算。 - -请注意,常量 `False`, `None`, 数字 `0`, 空列表 `[]`, 空字典 `{}` 和空字符串 `""` 都被视为 `False` 。 - -```python -_emptyStr = "" -_emptyList = [] -_emptyDict = {} -isEmptyStr = False if _emptyStr else True -isEmptyList = False if _emptyList else True -isEmptyDict = False if _emptyDict else True -``` - -结果为: - -```yaml -isEmptyStr: true -isEmptyList: true -isEmptyDict: true -``` - -### 断言语句 - -当发生错误时,开发人员应该能够检测到错误并终止执行。因此,KCL 引入了 `assert` 语法,示例如下: - -```python -a = 1 -b = 3 -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -``` - -此外,我们可以为 assert 语声明一个条件,当条件满足时,才进行 assert 断言 - -- 使用 if 语句书写条件断言 - -```python -a = None -if a: - assert a > 2: -``` - -- 使用 if 表达式书写条件断言 - -```python -a = None -assert a > 2 if a -``` - -### 函数 - -KCL 支持使用 lambda 关键字定义一个函数 - -```python -func = lambda x: int, y: int -> int { - x + y -} -a = func(1, 1) # 2 -``` - -lambda 函数具有如下特性: - -- lambda 函数将最后一个表达式的值作为函数的返回值,空函数体返回 None -- 返回值类型注解可以省略,返回值类型为最后一个表达式值的类型 -- 函数体中没有与顺序无关的特性,所有的表达式都是按顺序执行的 - -```python -_func = lambda x: int, y: int -> int { - x + y -} # Define a function using the lambda expression -_func = lambda x: int, y: int -> int { - x - y -} # Ok -_func = lambda x: int, y: int -> str { - str(x + y) -} # Error (int, int) -> str can't be assigned to (int, int) -> int -``` - -lambda 函数对象不能参与任何计算,只能在赋值语句和调用语句中使用。 - -```python -func = lambda x: int, y: int -> int { - x + y -} -x = func + 1 # Error: unsupported operand type(s) for +: 'function' and 'int(1)' -``` - -lambda 函数支持捕获其外部作用域的变量,并且可以作为其他函数的参数进行传递 - -```python -a = 1 -func = lambda x: int { - x + a -} -funcOther = lambda f, para: int { - f(para) -} -r0 = funcOther(func, 1) # 2 -r1 = funcOther(lambda x: int { - x + a -}, 1) # 2 -``` - -输出为: - -```yaml -a: 1 -r: 2 -``` - -此外,可以定义一个匿名函数并直接调用。 - -```python -result = (lambda x, y { - z = 2 * x - z + y -})(1, 1) # 3 -``` - -并且还可以在 for 循环使用使用匿名函数 - -```python -result = [(lambda x, y { - x + y -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 3, 3, 4] -``` - -请注意,KCL 中定义的函数的均为纯函数: - -- 函数的返回结果只依赖于它的参数。 -- 函数执行过程里面没有副作用。 - -因此,KCL 函数不能修改外部的变量,只能引用外部的变量,比如如下代码会发生错误: - -```python -globalVar = 1 -func = lambda { - x = globalVar # Ok - globalVar = 1 # Error -} -``` - -### 类型系统 - -#### 类型注解 - -类型注解可用于包级变量,schema 属性和参数。 - -- 属性可以是基本类型,例如字符串(`string`),浮点数(`float`),定点数(`int`) 或布尔值(`bool`)。 -- 属性可以是字面值类型,例如字符串文本(`"TCP"` 和 `"UDP"`),数字文本 (`"1"` 和 `"1.2"`),布尔值文本(`True` 和 `False`)。 -- 属性也可以是列表或字典: - - 未指定元素类型的列表为 `[]`。 - - 元素类型为 `t` 的列表为 `[t]`。这里 `t` 是另一种类型。 - - 键的类型为 `kt` 且值的类型为 `vt` 的字典为 `{kt:vt}`。 - - `kt`, `vt` 或两者都可以为空, 就像列表未指定元素类型一样。 -- 属性可以是由 `|` 定义的 **联合类型** ,例如 `a | b`, 意为类型可以是 a 或 b。 - - 联合类型可以包含 `int`, `str`, `float`, `bool`, `list`, `dict`, 字面值类型和 schema 类型,并且支持类型的嵌套,例如: `{str:str|int}`、`[[int|str]|str|float]` 和 `2 | 4 | 6` 等。 -- 属性可以是 schema 类型。在这种情况下,使用包名 + schema 名称作为类型名。 -- 属性可以声明为任意类型,例如 `any`。 - -示例 - -- 基本类型 - -```python -"""Top level variable type annotation""" -a: int = 1 # Declare a variable `a` that has the type `int` and the value `1` -b: str = "s" # Declare a variable `b` that has the type `str` and the value `"s"` -c: float = 1.0 # Declare a variable `c` that has the type `float` and the value `1.0` -d: bool = True # Declare a variable `d` that has the type `bool` and the value `True` -``` - -- List/Dict/Schema 类型 - -```python -schema Person: - name: str = "Alice" - age: int = 10 - -a: [int] = [1, 2, 3] # Declare a variable `a` that has the list type `[int]` and the value `[1, 2, 3]` -b: {str:str} = {k1 = "v1", k2 = "v2"} # Declare a variable `b` that has the dict type `{str:str}` and the value `{k1 = "v1", k2 = "v2"}` -c: Person = Person {} # Declare a variable `c` that has the schema type `Person` and the value `Person {}` -``` - -- 联合类型 - -```python -# Basic union types -schema x[argc: int]: # Schema argument type annotation - p: int | str # Schema attribute type annotation -``` - -```python -# Literal union types -schema LiteralType: - # String literal union types, x_01 can be one of "TCP" and "UDP" - x_01: "TCP" | "UDP" - # Number literal union types, x_02 can be one of 2, 4, and 6 - x_02: 2 | 4 | 6 - # Unit union types, x_03 can be one of 1Gi, 2Gi and 4Gi - x_03: 1Gi | 2Gi | 4Gi - -x = LiteralType { - x_01 = "TCP" - x_02 = 2 - x_03 = 1Gi -} -``` - -当属性的值不符合联合类型定义时,编译器会抛出错误: - -```python -# Literal union types -schema LiteralType: - # String literal union types, x_01 can be one of "TCP" and "UDP" - x_01: "TCP" | "UDP" - -x = LiteralType { - x_01 = "HTTP" # Error: the type got is inconsistent with the type expected, expect str(TCP)|str(UDP), got str(HTTP) -} -``` - -- Any 类型 - -```python -# Any type -schema Config: - literalConf: any = 1 - dictConf: {str:any} = {key = "value"} - listConf: [any] = [1, "2", True] - -config = Config {} -``` - -请注意,一般在配置编写中不提倡使用 `float` 和 `any` 类型,因为它们都存在一定的不稳定因素,比如精度丢失,无法进行静态类型检查等。 - -此外在 KCL 中,不允许修改一个变量的类型。如果在重新分配值时不满足类型,将引发类型错误。 - -```python -_a = 1 # The type of `_a` is `int` -_a = "s" # Error: expect int, got str(s) -``` - -变量可以赋值给其上界类型,但不能赋值给它的特化类型。 - -`None` 和 `Undefined` 可以赋值给任何类型: - -- 任何类型都可以赋值给 `any` 类型, `None` 和 `Undefined` 可以赋值给 `any` 类型。 - -```python -a: int = None -b: str = Undefined -c: any = 1 -d: any = "s" -e: any = None -``` - -- `int` 类型可以赋值给 `float` 类型, `float` 类型不能赋值给 `int` 类型. - -```python -a: float = 1 -b: int = 1.0 # Error: expect int, got float(1.0) -``` - -- `int` 类型可以赋值给 `int|str` 类型, `int|str` 不能赋值给 `int` 类型. - -```python -a: int | str = 1 -b: int = 1 if a else "s" # Error: expect int, got int(1)|str(s) -``` - -请注意,在 KCL 中虽然提供了 any 类型,但是它仍然是静态类型,所有变量的类型在编译期间不可变。 - -#### 类型推导 - -如果顶层或 schema 中的变量或常量声明没有使用显式的类型注解,则会从初始值推断类型。 - -- 整形数值被推断为 `int`。 - -```python -a = 1 # The variable `a` has the type `int` -``` - -- 浮点数被推断为 `float`。 - -```python -a = 1.0 # The variable `a` has the type `float` -``` - -- 字符串被推断为 `str`。 - -```python -a = "s" # The variable `a` has the type `str` -``` - -- 布尔值被推断为 `bool`。 - -```python -a = True # The variable `a` has the type `bool` -b = False # The variable `b` has the type `bool` -``` - -- `None` 和 `Undefined` 被推断为 `any`。 - -```python -a = None # The variable `a` has the type `any` -b = Undefined # The variable `b` has the type `any` -``` - -- 列表的类型根据元素类型推断,并且是可变大小的。 - -```python -a = [1, 2, 3] # The variable `a` has the type `[int]` -b = [1, 2, True] # The variable `b` has the list union type `[int|bool]` -c = ["s", 1] # The variable `c` has the list union type `[int|str]` -``` - -请注意,空列表将被推导为 `[any]` 类型。 - -```python -a = [] # The variable `a` has the type `[any]` -``` - -- 字典的类型是根据元素的键和值推断的,并且是可变大小的。 - -```python -a = {key = "value"} # The variable `a` has the type `{str:str}` -b = {key = 1} # The variable `b` has the type `{str:int}` -c = {key1 = 1, key2 = "s"} # The variable `c` has the type `{str:int|str}` -``` - -请注意,空字典将被推导为 `{any:any}` 类型。 - -```python -a = {} # The variable `a` has the type `{any:any}` -``` - -- 携带运行时值的 if 条件表达式的类型将被静态推断为所有可能结果的联合类型。 - -```python -a: bool = True # The variable `a` has the type `bool` -b = 1 if a else "s" # The variable `b` has the type `int|str` -``` - -当变量被推导为某个类型时,它的类型不能再改变。 - -```python -_a = 1 -_a = "s" # Error: expect int, got str(1) -``` - -#### 类型别名 - -在 KCL 中,我们可以使用 `type` 关键字为所有类型声明一个类型别名简化复杂类型的书写。 - -```python -type Int = int -type String = str -type StringOrInt = String | Int -type IntList = [int] -type StringAnyDict = {str:} -``` - -我们可以从一个包中导入一个类型并为它定义一个别名。 - -```py -import pkg - -type Data = pkg.Data -``` - -此外,我们还可以使用类型别名和字面值联合类型充当近似枚举的效果。 - -```python -# A type alias of string literal union types -type Color = "Red" | "Yellow" | "Blue" - -schema Config: - color: Color = "Red" # The type of color is `"Red" | "Yellow" | "Blue"`, and it has an alias `Color`, whose default value is `"Red"` - -config = Config { - color = "Blue" -} -``` - -上述代码执行的输出结果为: - -```yaml -config: - color: Blue -``` - -请注意,类型别名不能与已有的内置类型 `any`、`int`、`float`、`bool` 和 `str` 等相同 - -```python -type any = int | str # Error -type int = str # Error -type float = int # Error -type bool = True # Error -type str = "A" | "B" | "C" # Error -``` - -#### 类型守卫 - -KCL 支持在程序中使用 `typeof` 函数对任意值求得其运行时的类型。 - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person {} -t3 = typeof(_x1) - -_x2 = pkg.Person {} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# Output -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -除此之外,我们可以使用 `as` 关键字在运行时作类型转换。`as` 关键字的一般用法如下: - -- 具有偏序关系的基础类型,比如 `float -> int` -- 具有偏序关系的联合类型,比如 `int | str -> str` -- 对类型上界 `any` 的转换,比如 `any -> int` -- 具有偏序关系的结构类型,比如 `base-schema -> sub-schema` - -```python -schema Data1: - id?: int - -schema Data2: - name?: str - -data: Data1 | Data2 = Data1 {} - -if typeof(a) == "Data1": - data1 = data as Data1 # The type of `data1` is `Data1` -elif typeof(a) == "Data2": - data2 = data as Data2 # The type of `data2` is `Data2` -``` - -当类型转换失败时,一个运行时错误将被抛出。 - -```python -a: any = "s" -b: int = a as int # Error: The `str` type cannot be converted to the `int` type -``` - -如果不想要运行时类型转换失败,我们可以添加 `if` 防御式代码进行检查。 - -```python -a: any = "s" -b = a as int if typeof(a) == "int" else None # The type of b is `int` -``` - -请注意,`as` 转换的目标类型不能是字面值类型或者联合类型,因为它们在运行时不具有一个完全确定的类型。 - -### Schema - -#### 概述 - -Schema 是定义复杂配置的语言元素。我们可以定义带类型的属性,初始值和验证规则。此外,KCL 支持 schema 单继承、mixin 和 protocol 实现复杂配置的复用。 - -#### 基础部分 - -##### 属性 - -以下是 schema 基础定义的示例: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 -``` - -在 KCL 中, 我们可以使用类型注解在 schema 中定义一些属性,每个属性都可以设置一个可选的默认值(比如上述代码中的 `age` 属性,它的默认值是 `0`),没有设置默认值的属性的初始值为 `Undefined`, 它们不会在 YAML 当中进行输出。 - -###### 不可变性 - -schema 中属性的不可变性遵循和全局变量不可变性一样的规则,只有 schema 中的可变属性可以在 schema 中修改。此外,schema 的属性默认值可被 schema 配置值修改: - -```python -schema Person: - age: int = 1 # Immutable attribute - _name: str = "Alice" # Mutable attribute - - age = 10 # Error, can't change the default value of the attribute `age` in the schema context. - _name = "Bob" # Ok - -person = Person { - age = 3 # Ok, can change the default value of the attribute `age` in the schema config. -} -``` - -###### 可选属性 - -schema 实例中每个属性 **必须** 赋值一个非 `None`/`Undefined` 的值,否则编译器会抛出错误,除非它被 `?` 符号标记为可选属性。 - -示例: - -```python -schema Employee: - bankCard: int # bankCard is a required attribute, and it can NOT be None or Undefined - nationality?: str # nationality is an optional attribute, and it can be None or Undefined - -employee = Employee { - bankCard = None # Error, attribute 'bankCard' of Employee is required and can't be None or Undefined - nationality = None # Ok -} -``` - -##### 顺序无关计算 - -schema 中顺序无关计算表示 schema 内部属性之间的引用关系。例如,当我们声明一个形式为 `a = b + 1` 的表达式时,`a` 值的计算依赖于 `b` 值的计算。当编译器计算 `a` 的值并且 `a` 的值取决于 `b` 的值时,编译器会选择先计算 `b` 的值,然后根据 `b` 的值计算 a 的值表达式 `a = b + 1`,这与传统过程语言的计算方法略有不同。 - -由于 schema 中值的计算是基于依赖关系的,就像有向无环图按照拓扑排序的顺序遍历图中的每个节点一样, schema 中属性的声明顺序并不那么重要,因此特征称为顺序无关计算。 - -请注意,不同 schema 属性值之间不能有循环引用。 - -我们可以通过下面的例子看到这个特性。 - -```python -schema Fib: - n1: int = n - 1 # Refers to the attribute `n` declared after `n1` - n2: int = n1 - 1 - n: int - value: int = 1 if n <= 2 else Fib {n = n1}.value + Fib {n = n2}.value - -fib8 = Fib {n = 8}.value -``` - -结果为: - -```yaml -fib8: 21 -``` - -在 schema 中,我们只需要简单的指定属性之间的依赖关系,编译器就会根据依赖关系自动计算出值,这样可以帮助我们节省大量的样板代码,减少配置编写难度。 - -##### Schema 上下文 - -我们可以定义 schema 的上下文来管理 schema 的属性,可以直接在 schema 中编写 schema 参数、临时变量和表达式等: - -```python -schema Person[_name: str]: # define a schema argument - name: str = _name # define a schema attribute - age: int = 10 # define a schema attribute with default value - hands: [int] = [i for i in [1, 2, 3]] # define a for statement -``` - -然后,我们可以通过如下代码实例化一个 `Person` 并将其赋值给 `alice` 变量: - -```python -alice = Person("alice") -``` - -可以得到如下 YAML 输出: - -```yaml -alice: - name: alice - age: 10 - hands: - - 1 - - 2 - - 3 -``` - -##### 校验 - -KCL 中为了确保代码稳定性,除了使用 **静态类型** (类型注解) 和 **不可变性**,还支持在 **check** 块中定义验证规则 (KCL 几乎原生支持所有 [OpenAPI](https://www.openapis.org/) 的验证能力): - -```python -import regex - -schema Sample: - foo: str - bar: int - fooList: [str] - - check: - bar > 0 # Minimum, also support the exclusive case - bar < 100 # Maximum, also support the exclusive case - len(fooList) > 0 # Min length, also support exclusive case - len(fooList) < 100 # Max length, also support exclusive case - regex.match(foo, "^The.*Foo$") # Regex match - isunique(fooList) # Unique - bar in range(100) # Range - bar in [2, 4, 6, 8] # Enum - multiplyof(bar, 2) # MultipleOf -``` - -使用 schema, 所有的实例将在编译时验证: - -```python -# Ok -goodSample = Sample { - foo = "The Foo" - bar = 2 - fooList = ["foo0", "foo1"] -} - -# Error: validation failure: Check failed on check conditions: bar < 100. -badSample = Sample { - foo = "The Foo" - bar = 123 - fooList = ["foo0", "foo1"] -} -``` - -此外,我们可以使用 **and**, **or**, **if** 来构建更复杂的检查逻辑: - -```python -schema Sample: - bar: int - foo: str - doCheck: bool - - check: - regex.match(foo, "^The.*Foo$") and bar in [2, 4, 6, 8] if doCheck -``` - -为了确保所有检查规则都能很好地发挥其相应的作用,我们可以通过编写 KCL 测试用例来测试不同数据组合的合理性和正确性,并通过 kcl test tool 运行所有测试用例。 - -##### 文档 - -通常在我们写好 schema 模型之后,我们会为 schema 写文档注释,可以用一个三引号字符串来完成,如下所示: - -```python -schema Server: - """Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - - Attributes - ---------- - workloadType : str, default is Deployment - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - name : str, default is None - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - labels : {str:str}, optional, default is None - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - - Examples - ---------------------- - myCustomApp = AppConfiguration { - name = "componentName" - } - """ - workloadType: str = "Deployment" - name: str - labels?: {str:str} -``` - -更多详细内容可见 Doc tools。 - -##### 配置 - -假设我们有如下 schema 定义: - -```python -schema Person: - firstName: str - lastName: str - labels?: {str:str} -``` - -可以用类 JSON 的表达式定义配置: - -```python -person = Person { - firstName = "firstName" - lastName = "lastName" -} -``` - -schema 遵循严格的属性定义,配置未定义的属性将触发编译错误: - -```python -person = Person { - firstName = "firstName" - lastName = "lastName" - fullName = "fullName" # Error: Cannot add member 'fullName' to schema 'Person', 'fullName' is not defined in schema 'Person' -} -``` - -此外,我们可以使用 `if` 表达式将元素动态的添加到 schema 实例中,将满足条件的元素添加到 schema 实例并忽略不满足条件的元素。并且除了使用一个 schema 类型实例化一个 schema,我们也可以通过 schema 实例得到一个新的实例。 - -```python -env = "prod" -person = Person { - firstName = "firstName" - lastName = "lastName" - if env == "prod": - labels.env = env - else: - labels.env = "other" -} -# We can use the person instance to get a new instance named `personx` directly. -personx = person { - firstName = "NewFirstName" -} -``` - -输出为: - -```yaml -env: prod -person: - firstName: firstName - lastName: lastName - labels: - env: prod -personx: - firstName: NewFirstName - lastName: lastName - labels: - env: prod -``` - -#### 高级功能 - -##### Protocol & Mixin - -除了 schema, 在 KCL 中还提供了一种额外的类型定义方式 `protocol`,它的性质如下: - -- 在 protocol 中,只能定义属性及其类型,不能书写复杂的逻辑与 check 表达式,也不能使用 mixin。 -- protocol 只能对非 `_` 开头的属性进行约束。 -- protocol 只能继承自或者引用 protocol, 不能继承自或者引用 schema。 - -此外,我们可以使用可选的 **mixin** 组装复杂的 schema,并使用 **protocol** 为 **mixin** 添加可选的宿主类型, 使用 `for` 关键字为 **mixin** 定义宿主类型,并且在 mixin 内部它将从宿主类型中查询到属性的类型。 - -```python -schema Person: - mixin [FullNameMixin] - - firstName: str # Required - lastName: str # Required - fullName?: str # Optional -``` - -FullNameMixin 是一个产生 fullName 字段的简单例子: - -```python -protocol PersonProtocol: - firstName: str - lastName: str - fullName?: str - -mixin FullNameMixin for PersonProtocol: - fullName = "{} {}".format(firstName, lastName) -``` - -然后我们可以通过一下方式获取 schema 实例: - -```python -person = Person { - firstName = "John" - lastName = "Doe" -} -``` - -输出结果为: - -```yaml -person: - firstName: John - lastName: Doe - fullName: John Doe -``` - -请注意,宿主类型 **protocol** 只能用于 **mixin** 的定义 (后缀名为 `Mixin`), 否则将会报错。 - -```python -protocol DataProtocol: - data: str - -schema Data for DataProtocol: # Error: only schema mixin can inherit from protocol - x: str = data -``` - -##### 索引签名 - -在 KCL schema 中可以定义索引签名,这意味着索引签名的键-值约束可用于构造具有 schema 类型的字典。或者可以将其他检查添加到额外的 schema 属性中,以增强 KCL 类型和语义检查。 - -###### 基本用法 - -使用 `[{attr_alias}: {key_type}]: {value_type}` 的形式去定义 schema 的类型注解, 其中 `{attr_alias}` 可以省略。 - -```python -schema Map: - """ - Map is a schema with a key of str type and a value of str type - """ - [str]: str # `{attr_alias}` can be omitted. - -data = Map { - key1 = "value1" - key2 = "value2" -} -``` - -###### 同时定义属性和索引签名 - -可以在 schema 中同时定义 schema 属性和索引签名,通常用于表示 schema 中额外属性的类型约束,比如如下代码 - -```python -schema Person: - name: str - age: int - [...str]: str # Except for the `name` and `age` attributes, the key type of all other attributes of the schema must be `str`, and the value type must also be `str`. -``` - -###### 定义索引签名别名 - -可以为索引签名定义类型注解的属性别名,并将其与检查块一起使用。 - -```python -schema Data: - [dataName: str]: str - check: - dataName in ["Alice", "Bob", "John"] # We can use the index signature key name in the check block. - -data = Data { - Alice = "10" - Bob = "12" - Jonn = "8" # Error: Jonn not in ["Alice", "Bob", "John"] -} -``` - -##### 继承 - -类似于其他面向对象语言,KCL 提供了基础且有限的面向对象支持,例如 **属性复用**,**私有和公有变量**和**单继承**。KCL 不支持多继承。 - -以下是单继承的例子: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 - -# An employee **is** a person, and has some additional information. -schema Employee(Person): - bankCard: int - nationality?: str - -employee = Employee { - firstName = "Bob" - lastName = "Green" - age = 18 - bankCard = 123456 -} -``` - -结果为: - -```yaml -employee: - firstName: Bob - lastName: Green - age: 18 - bankCard: 123456 - nationality: null -``` - -请注意,KCL 只支持 schema 的 **单继承**。 - -此外,当 schema 存在继承关系时,可选属性的性质如下: - -- 如果该属性在基类 schema 中是可选的,则它在子类 schema 中是可选的,也可以是子类 schema 中必选的。 -- 如果该属性在基类 schema 中是必选的,则它在子类 schema 中也是必选的。 - -```python -schema Person: - bankCard?: int - nationality: str - -schema Employee(Person): - bankCard: int # Valid, both `bankCard: int` and `bankCard?: int` are allowed - nationality?: str # Error, only `nationality: str` is allowed -``` - -##### Schema 函数 - -schema 映射到函数上非常好用;它可以有任意数量的输入和输出参数。 例如,Fibonacci 函数可以使用递归 schema 如下编写: - -```python -schema Fib[n: int]: - n1 = n - 1 - n2 = n - 2 - if n == 0: - value = 0 - elif n == 1: - value = 1 - else: - value = Fib(n1).value + Fib(n2).value - -fib8 = Fib(8).value # 21 -``` - -##### 装饰器 - -像 Python 一样, KCL 支持在 schema 上使用装饰器。KCL 装饰器动态地改变 schema 的功能,而不必直接使用子 schema 或更改被装饰的 schema 的源代码。 和函数调用一样,装饰器支持传入额外的参数。 - -内置的 schema 装饰器: - -- `@deprecated` - 标识 schema 或 schema 属性被废弃. `@deprecated` 装饰器支持三种参数: - - **version** - 字符串类型,表示版本信息。 默认值为空。 - - **reason** - 字符串类型,表示不推荐使用的原因。 默认值为空。 - - **strict** - bool 类型,表示是报错还是警告。 默认值是 true。 如果 `strict` 为 `True` 并且抛出错误,程序将被中断。 如果 `strict` 为 `False`,则会输出警告并且不会中断程序。 - -示例: - -```python -@deprecated -schema ObsoleteSchema: - attr: str - -schema Person: - firstName: str = "John" - lastName: str - @deprecated(version="1.16", reason="use firstName and lastName instead", strict=True) - name: str - attrs: ObsoleteSchema = { # Error: ObsoleteSchema was deprecated - attr = "value" - } - -JohnDoe = Person { # Error: name was deprecated since version 1.16, use firstName and lastName instead - name = "deprecated" -} -``` - -- `@info` - 给 schema 或 schema 属性标识额外的信息,支持任意参数,用于语言静态分析 schema 或 schema 属性的扩展标记信息 - -示例: - -```python -@info(version="v1") -schema Person: - @info(message="name") - name: str - age: int -``` - -请注意,当前版本的 KCL 尚不支持用户自己定义装饰器。 - -##### 成员函数 - -内置函数和 schema 成员 - -- instances() - 返回 schema 的现有实例列表。 - -```python -schema Person: - name: str - age: int - -alice = Person { - name = "Alice" - age = 18 -} - -bob = Person { - name = "Bob" - age = 10 -} - -aliceAndBob = Person.instances() # Person is a schema type, instances() is its member method -``` - -输出为: - -```yaml -alice: - name: Alice - age: 18 -bob: - name: Bob - age: 10 -aliceAndBob: - - name: Alice - age: 18 - - name: Bob - age: 10 -``` - -### 配置操作 - -#### 配置合并 - -##### | 运算符 - -在 KCL 中,我们可以使用合并运算符 `|` 来合并配置。union 运算符支持的类型包括如下: - -```txt -SchemaInstance | SchemaInstance -SchemaInstance | Dict -Dict | Dict -List | List -``` - -合并集合和结构化数据: - -- 合并 List。使用 `|` 运算符右边的列表表达式按照**索引**逐一覆盖左边列表表达式中的元素。 - -```python -_a = [1, 2, 3] -_b = [4, 5, 6, 7] -x = _a | _b # [4, 5, 6, 7] 1 -> 4; 2 -> 5; 3 -> 6; Undefined -> 7 -``` - -合并特定索引或所有元素仍在讨论中。 - -- 合并 Dict. 使用 `|` 运算符右边的列表表达式按照**键**逐一覆盖左边列表表达式中的元素。 - -```python -_a = {key1 = "value1"} -_b = {key1 = "overwrite", key2 = "value2"} -x = _a | _b # {"key1": "overwrite", "key2": "value2"} -``` - -集合和 schema 的合并是一个新的集合,其属性是将 b 合并到 a,保留从左到右的操作数顺序。 - -- 合并 schema。Schema 的合并与 dict 相似。 - -Schema 的合并操作如下: - -```python -schema Person: - firstName?: str - lastName?: str - -_a = Person { - firstName = "John" -} -_b = {lastName = "Doe"} -_c = _a | _b # {"firstName": "John", "lastName": "Doe"} -_d = _a | None # {"firstName": "John"} -_e = _a | Undefined # {"firstName": "John"} -_f = None | _a # {"firstName": "John"} -_g = Undefined | _a # {"firstName": "John"} -``` - -请注意,当 union 运算符的左右操作数之一为 None 时,将立即返回另一个操作数。 - -```python -data1 = {key = "value"} | None # {"key": "value"} -data2 = None | [1, 2, 3] # [1, 2, 3] -data3 = None | None # None -``` - -输出如下: - -```yaml -data1: - key: value -data2: - - 1 - - 2 - - 3 -data3: null -``` - -##### : 运算符 - -模式: `identifier : E` - -表达式 `E` 的值将被合并到元素值。 - -示例: - -```python -schema Data: - labels: {str:} = {key1 = "value1"} - -data = Data { - # union {key2: "value2"} into the attribute labels of the schema Data. - labels: {key2 = "value2"} -} -``` - -输出: - -```yaml -data: - labels: - key1: value1 - key2: value2 -``` - -除了在 schema 属性上使用属性运算符之外,还可以使用属性运算符对配置块执行不同的操作。 - -- schema 外部使用合并运算符 `:` - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - data: Data - -# This is one configuration that will be merged. -config: Config { - data.d1 = 1 -} -# This is another configuration that will be merged. -config: Config { - data.d2 = 2 -} -``` - -与它等效的配置代码可以表示为: - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - data: Data - -config: Config { - data.d1 = 1 - data.d2 = 1 -} -``` - -输出结果为: - -```yaml -config: - data: - d1: 1 - d2: 1 -``` - -- schema 内部使用合并运算符 `:` - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - # This is one configuration that will be merged. - data: Data { - d1 = 1 - } - # This is another configuration that will be merged. - data: Data { - d2 = 1 - } - -config: Config {} -``` - -#### 配置覆盖 - -##### = 运算符 - -模式: `identifier = E` - -表达式 `E` 的值将覆盖元素值。 - -示例: - -```python -schema Data: - labels: {str:} = {key1 = "value1"} - -data = Data { - # override {key2: "value2"} into the attribute labels of the schema Data. - labels = {key2 = "value2"} -} -``` - -输出: - -```yaml -data: - labels: - key2: value2 -``` - -请注意,可以使用 `Undefined` 来覆盖,来“删除”内容。例如 `{ a = Undefined }`。 - -#### 配置添加 - -##### += 运算符 - -模式: `identifier += E` - -插入只能用于列表类型的 `identifier`. - -`E` 将插入到列表 `identifier` 指定索引后,并且索引以后的属性将自动后移。 - -示例: - -```python -schema Data: - labels: {str:} = {key1 = [0]} - -data = Data { - # insert [1] into the attribute labels.key1 of the schema Data. - labels: {key1 += [1]} -} -``` - -输出: - -```yaml -data: - labels: - key1: - - 0 - - 1 -``` - -如果没有定义索引,将使用最后一个索引。 - -#### 注意事项 - -合并运算符 `:` 是一个可交换的幂等运算符,当合并的值发生值的冲突时会发生值冲突错误,因此我们需要 `=` 和 `+=` 运算符表示配置的覆盖,添加和删除操作。 - -```python -data0 = {id: 1} | {id: 2} # Error:conflicting values between {'id': 2} and {'id': 1} -data1 = {id: 1} | {id = 2} # Ok, the value of `data` is {"id": 2} -``` - -`:` 运算符冲突检查的规则如下: - -- `None` 和 `Undefined` 不与任何值冲突 - -```python -data0 = None | {id: 1} # Ok -``` - -- 对于 `int`、`float`、`str` 和 `bool` 类型的变量,当它们的值不相同时发生冲突错误。 - -```python -data0 = 1 | 1 # Ok -data1 = 1 | "s" # Error -``` - -- 对于列表类型 - - 当它们的长度不相同时,它们被认为是冲突的 - - 当它们的长度相同时,当且仅当它们的任意一个子元素值冲突时,它们自身是冲突的 - -```python -data0 = [1] | [1] # Ok -data1 = [1, 2] | [1] # Error -``` - -- 对于 dict/schema 类型 - - 对于相同的 key,key 的值冲突时,它们自身是冲突的,否则是不冲突的 - -```python -data0 = {id: 1} | {id: 1} # Ok -data1 = {id: 1} | {id: 2} # Error -data1 = {id: 1} | {idAnother: 1} # Ok -``` - -### Rule - -KCL 支持使用 rule 关键字定义校验块,可用于数据校验,用法类似于 schema 中的 check 表达式。 - -```python -rule SomeRule: - age > 0, "rule check failure message" -``` - -可以像 schema 实例化那样调用一个 rule 进行校验 - -```python -age = 0 -name = "Bob" -rule SomeRule: - age > 0, "rule check failure message" - name == "Alice" - -rule1 = SomeRule() # Rule call -rule2 = SomeRule {} -``` - -可以使用 protocol 和 for 绑定语句为 rule 增加类型约束: - -```python -# Schema definition -protocol Service: - clusterIp: str - $type: str - -# Schema definition -protocol Volume: - mountPath: [str] - -# Protocol -protocol SomeProtocol: - id: int - env: {str: any} - services: [Service] - volumes: [Volume] - -rule SomeChecker for SomeProtocol: - id > 0, "id must >0" - - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - } - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } - -# Call rule to check with config parameter -SomeChecker { - id = 1 - env = { - MY_ENV = "MY_ENV_VALUE" - } - services = [ - { - type = "ClusterIP" - clusterIP = "NONE" - } - ] - volumes = [ - { - mountPath = "/home/admin" - } - { - mountPath = "/home/myapp" - } - ] -} -``` - -请注意,`protocol` 和 `rule` 的组合方式可以使属性和其约束定义进行分离,我们可以在不同的包中定义不同的 `rule` 和 `protocol` 按需进行组合,这与 schema 中的 check 表达式只能与 schema 属性定义在一起是不同的。 - -此外,有两种复用不同 rule 的方式 - -- 直接调用 - -```python -weather = "sunny" -day = "wednesday" - -rule IsSunny: - weather == "sunny" - -rule IsWednesday: - day == "wednesday" - -rule Main: - IsSunny() # Rule inline call - IsWednesday() # Rule inline call - -Main() # Rule call -``` - -使用 rule 的继承 (rule 不同于 schema, 可以多继承混用) - -```python -weather = "sunny" -day = "wednesday" - -rule IsSunny: - weather == "sunny" - -rule IsWednesday: - day == "wednesday" - -rule Main(IsSunny, IsWednesday): - id == 1 - -Main() -``` - -可以使用 option 函数与命令行 `-D` 参数获得外部数据进行校验 - -- 一个简单例子 - -```python -schema Day: - day: str - homework: str - -days: [Day] = option("days") - -rule Main: - filter d in days { - d.day not in ["saturday", "sunday"] and d.homework - } - -Main() -``` - -- 一个复杂例子 - -```python -data = option("data") -input = option("input") - -rule Allow: - UserIsAdmin() - any grant in UserIsGranted() { - input.action == grant.action and input.type == grant.type - } - -rule UserIsAdmin: - any user in data.user_roles[input.user] { - user == "admin" - } - -rule UserIsGranted: - [ - grant - for role in data.user_roles[input.user] - for grant in data.role_grants[role] - ] - -allow = Allow() or False -``` - -### 模块 - -KCL 配置文件以 **模块** 形式组织。 单个 KCL 文件被认为是一个 module,一个目录被认为是一个包。 - -同一个包内的模块是可见的,跨包引用需要通过导入可见。 - -```bash -. -└── root - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -model1.k: - -```python -# schema CatalogItem in model1.k - -schema CatalogItem: - id: int - image: CatalogItemImage # CatalogItemImage is defined in the module of the same package e.g., model2.k in package model - title: str -``` - -service1.k: - -```python -import ..model as model # cross-package references - -schema ImageService: - image: model.CatalogItemImage # CatalogItemImage is imported from another package e.g., model2.k in package model - name: str -``` - -#### 相对路径引用 - -我们可以使用 `.` 运算符来实现 KCL 入口文件的相对路径导入。 - -main.k: - -```python -import .model1 # Current directory module -import ..service # Parent directory -import ...root # Parent of parent directory - -s = service.ImageService {} -m = root.Schema {} -``` - -#### 绝对路径引用 - -`import a.b.c.d` 的语义为: - -1. 如果 `kcl.mod` 文件不存在,将当前目录作为包的根路径,并从当前目前查找 `a/b/c/d` 路径 -2. 如果 `kcl.mod` 文件存在,从 `ROOT_PATH/a/b/c/d` 查找,否则抛出一个导入错误 - -根路径 `ROOT_PATH` 的定义为: - -从当前目录或者父级目录中查找 `kcl.mod` 文件对应的目录。 - -```bash -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -main.k: - -```python -import service # `root package` and `kcl.mod` are in the same directory -import mixin # `root package` and `kcl.mod` are in the same directory - -myModel = model.CatalogItem {} -``` - -请注意,对于 KCL 入口文件 `main.k`,不能导入所在文件夹,否则会出现递归导入错误: - -```python -import model # Error: recursively loading -``` - -### 动态参数 - -假设某些字段需要像用户输入一样动态传入,我们可以在模块中定义一个动态参数: - -```python -bankCard = option("bankCard") # Get bankCard through the option function. -``` - -我们可以如下使用 module: - -```bash -kcl employee.k -D bankCard=123 -``` - -目前,支持顶级参数的类型有数字、字符串、布尔、列表和字典。 - -```bash -kcl main.k -D list_key='[1,2,3]' -D dict_key='{"key":"value"}' -``` - -请注意,命令行中引号 `"` 等符号需要使用 `\` 进行转义 - -#### Setting 文件形式的参数 - -此外,它还支持输入一个 YAML 文件作为顶级参数。 - -```yaml -kcl_options: - - key: key_number - value: 1 - - key: key_dict - value: - innerDictKey: innerDictValue - - key: key_list - value: - - 1 - - 2 - - 3 - - key: bankCard - value: 123 -``` - -```bash -kcl -Y setting.yaml employee.k -``` - -此外,setting 文件还支持配置命令行编译参数如下: - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - disable_none: true - strict_range_check: true - debug: 1 - verbose: 1 - sort_keys: true - output: ./stdout.golden - overrides: - - app.image=new_image - path_selector: - - config - package_maps: - k8s: /Users/.kcl/kpm/k8s_1.24 -kcl_options: - - key: image - value: docker.io/kcllang/kcl:latest -``` - -KCL CLI -Y 参数还支持多文件配置,并支持编译参数和顶级参数的单独写入与合并。 - -```bash -kcl -Y compile_setting.yaml option_setting.yaml -``` - -- `compile_setting.yaml` - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - disable_none: true - strict_range_check: true - debug: 1 - verbose: 1 - output: ./stdout.golden -``` - -- `option_setting.yaml` - -```yaml -kcl_options: - - key: image - value: docker.io/kcllang/kcl:latest -``` - -我们可以使用以下指令获取每个参数的含义 - -```bash -kcl --help -``` - -#### Option Functions - -我们可以在 KCL 代码中使用 `option` 获取顶级参数。 - -```python -value = option(key="key", type='str', default="default_value", required=True, help="Set key value") -``` - -参数 - -- **key**: 参数的键。 -- **type**: 要转换的参数类型。 -- **default**: 参数默认值。 -- **required**: 当未提供参数且参数的 required 为 True 是报告错误。 -- **help**: 帮助信息。 - -### 多文件编译 - -除了上面的 KCL 单文件执行之外,我们还可以使用以下命令同时编译多个 KCL 入口文件: - -```bash -kcl main_1.k main_2.k ... main_n.k -``` - -main_1.k - -```python -a = 1 -b = 2 -``` - -main_2.k - -```python -c = 3 -d = 4 -``` - -输出结果为: - -```yaml -a: 1 -b: 2 -c: 3 -d: 4 -``` - -利用**多文件编译**,我们可以组合多个 KCL 文件,而无需使用 import 管理文件。 我们来看一个结合**多文件编译**和 **schema 实例**的例子。 - -model.k - -```python -schema Model: - name: str - labels?: {str:} - annotations?: {str:} - replicas: int - -_model1 = Model { - name = "model1" - labels.key1 = "value1" - labels.key2 = "value2" - annotations.key = "value" - replicas = 2 -} - -_model2 = Model { - name = "model2" - replicas = 3 -} -``` - -backend.k - -```python -import yaml - -schema Backend: - apiVersion: str = "v1" - kind: str = "Deployment" - metadata: {str:} - spec: {str:} = { - minReadySeconds = 0 - paused = False - progressDeadlineSeconds = 600 - replicas = 1 - revisionHistoryLimit = 10 - selector = {} - } - -_backends = [Backend { - metadata.name = model.name - metadata.labels = model.labels - metadata.annotations = model.annotations - spec.selector.matchLabels: model.labels - spec.replicas = model.replicas -} for model in Model.instances()] # Schema Model is defined in model.k -print("---\n".join([yaml.encode(_b, ignore_private=True) for _b in _backends])) -``` - -命令为: - -```bash -kcl model.k backend.k -``` - -输出为: - -```yaml -apiVersion: v1 -kind: Deployment -metadata: - name: model1 - labels: - key1: value1 - key2: value2 - annotations: - key: value -spec: - minReadySeconds: 0 - paused: false - progressDeadlineSeconds: 600 - replicas: 2 - revisionHistoryLimit: 10 - selector: - matchLabels: - key1: value1 - key2: value2 ---- -apiVersion: v1 -kind: Deployment -metadata: - name: model2 -spec: - minReadySeconds: 0 - paused: false - progressDeadlineSeconds: 600 - replicas: 3 - revisionHistoryLimit: 10 - selector: {} -``` - -### KCL 变量查询 - -我们可以在 KCL CLI 使用 `-S|--path-selector` 参数从 KCL 模型中查询一个或多个值。 - -变量查询形式如下: - -`var.name` - -#### 示例 - -Code structure: - -```bash -. -├── kcl.mod -└── main.k - └── pkg - └── model.k -``` - -pkg/model.k: - -```python -schema Person: - name: str - age: int - -var = Person { - name = "Alice" - age = 18 -} -``` - -main.k - -```python -import pkg - -var = pkg.Person { - name = "Bob" - age = 10 -} -``` - -命令为: - -```bash -kcl main.k -S var -``` - -输出结果为: - -```yaml -var: - name: Bob ---- -var: - name: Alice - age: 18 -``` - -### KCL 变量修改 - -除了变量查询,KCL 还允许我们通过 KCL CLI 的 `-O|--overrides` 参数直接修改配置模型中的值。 - -变量修改参数的使用与变量查询类似,参数包含三部分,如 `pkg`、`identifier`、`attribute` 和 `override_value` . - -```bash -kcl main.k -O override_spec -``` - -- `override_spec`: 表示需要修改的配置模型字段和值的统一表示 - -```txt -override_spec: [[pkgpath] ":"] identifier ("=" value | "-") -``` - -- `pkgpath`: 表示需要修改标识符的包路径,通常为 `a.b.c` 的形式,对于 main 包,`pkgpath` 表示为 `__main__`, 可省略,省略不写时表示 main 包 -- `identifier`: 表示需要修改配置的标识符,通常为 `a.b.c` 的形式 -- `value`: 表示需要修改配置的值,可以是任意合法的 KCL 表达式,比如数字/字符串字面值,list/dict/schema 表达式等 -- `=`: 表示修改identifier的值 - - 当 identifier 存在时,修改已有 identifier的值为 value - - 当 identifier 不存在时,添加 identifier属性,并将其值设置为 value -- `-`: 表示删除 identifier属性 - - 当 identifier 存在时,直接进行删除 - - 当 identifier 不存在时,对配置不作任何修改 - -请注意,当 `identifier` 出现多次时,修改/删除全部 `identifier` 的值 - -此外,在 KCL 中还提供了 API 用于变量查询和修改,详见 [API 文档](../xlang-api/go-api.md) - -#### 示例 - -##### 修改示例 - -KCL 代码: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -``` - -命令为: - -```bash -kcl main.k -O :person.name=Bob -O :person.age=10 -``` - -输出结果为: - -```yaml -person: - name: Bob - age: 10 -``` - -此外,当我们使用 KCL CLI `-d` 参数时,KCL 文件将同时修改为以下内容 - -```bash -kcl main.k -O :person.name=Bob -O :person.age=10 -d -``` - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Bob" - age = 10 -} -``` - -##### 删除示例 - -KCL 代码: - -```python -schema Config: - x?: int = 1 - y?: str = "s" - -config = Config { - x = 2 -} -``` - -命令为: - -```bash -kcl main.k -O config.x- -``` - -输出结果为: - -```yaml -config: - x: 1 - y: s -``` - -### 总结 - -本页总结了 KCL 语言中的常用功能。 KCL 作为一种新的语言,会根据配置场景的需求,逐步增加功能特性。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/types/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/types/_category_.json deleted file mode 100644 index a8f40915..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/types/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "类型系统", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/types/types.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/types/types.md deleted file mode 100644 index 182ffaf2..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/types/types.md +++ /dev/null @@ -1,1401 +0,0 @@ -# 类型系统 - -本文档描述 KCL 的类型系统,包括: - -- 类型规则 -- 类型检查 -- 类型转换 -- 类型推导 - -## 类型规则 - -### 基础定义 - -#### 断言 - -$S$ 的所有自由变量都定义在 $\Gamma$ 中 - -$$ -\Gamma \vdash S -$$ - -$\Gamma$ 是一个变量的类型声明环境(well-formed environment),如:$x_1:T_1$, ..., $x_n:T_n$ - -$S$ 的断言有三种形式: - -**环境断言** 断言表示 $\Gamma$ 是良构类型 (well-formed type) - -$$ -\Gamma \vdash ◇ -$$ - -**良构类型断言** 在环境 $\Gamma$ 下,$nat$ 是类型表达式 - -$$ -\Gamma \vdash nat -$$ - -**类型判断断言** 在环境 $\Gamma$ 下,$E$ 具有类型 $T$ - -$$ -\Gamma \vdash E: T -$$ - -#### 推理规则 - -表示法 - -$$ -\frac{\Gamma \vdash S_1, ..., \Gamma \vdash S_n}{\Gamma \vdash S} -$$ - -推理规则中的 $u$, $v$, $w$ 用于表示变量,$i$, $j$, $k$ 用于表示整数,$a$, $b$ 用于表示浮点数,$s$ 用于表示字符串,$c$ 代表常量(整数、浮点数、字符串、布尔)的字面值, $f$ 用于表示函数, $T$, $S$, $U$ 用于表示类型。 - -## 环境规则 - -Env ⌀ - -$$ -\frac{}{⌀ \vdash ◇ } -$$ - -## 类型定义 - -Type Bool - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash boolean} -$$ - -Type Int - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash integer} -$$ - -Type Float - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash float} -$$ - -Type String - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash string} -$$ - -Type Literal - -$$ -\frac{ c \in \{boolean, integer, float, string\}}{\Gamma \vdash literalof(c)} -$$ - -Type List - -$$ -\frac{\Gamma \vdash T \ T \neq Void}{\Gamma \vdash listof(T) } -$$ - -Type Dict - -$$ -\frac{\Gamma \vdash T_1 \ \Gamma \vdash T_2\ T_1 \neq Void \ \ T_2 \neq Void}{\Gamma \vdash dictof(T_k=T_1, T_v=T_2)} -$$ - -Type Struct - -$$ -\frac{\Gamma \vdash T_{1} \ ... \ \Gamma \vdash T_{n} \ \ T_i \neq Void \ K_1 \neq K_n}{\Gamma \vdash structof(K_1 : T_{1}, ... , K_n : T_{n})} -$$ - -Type Union - -$$ -\frac{\Gamma \vdash T_1 \ ... \ \Gamma \vdash T_n \ \ T_i \neq Void}{\Gamma \vdash unionof(T_1, ..., T_n)} -$$ - -Type None - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash None} -$$ - -Type Undefined - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Undefined} -$$ - -Type Void - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Void} -$$ - -Type Any - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Any} -$$ - -Type Nothing - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Nothing} -$$ - -## 类型判断规则 - -### Operand Expr - -Exp Truth - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash true: boolean} -$$ - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash false: boolean} -$$ - -Exp Int - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash int: integer} -$$ - -Exp Flt - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash flt: float} -$$ - -Exp Str - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash str: string} -$$ - -Exp None - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash none: none} -$$ - -Exp Undefined - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash undefined: undefined} -$$ - -Expr ListExp - -$$ -\frac{\Gamma \vdash E_1: T_1 \ E_2: T_2 \ ... \ E_n: T_n}{\Gamma \vdash [E_1, E_2, ..., E_n]: listof \ sup(T_1, T_2, ..., T_n)} -$$ - -Expr ListComp - -$$ -\frac{\Gamma \vdash E_1: T_1 \ \Gamma \vdash v: T \ \Gamma \vdash E_2: listof \ T \ \Gamma \vdash E_3: boolean}{\Gamma \vdash [E_1 \ for \ v \ in \ E_2 \ if \ E_3]: listof(T_1) } -$$ - -Expr DictExp - -$$ -\frac{\Gamma \vdash E_{k1}: T_{k1} \ \Gamma \vdash E_{v1}: T_{v1} \ ... \ \Gamma \vdash E_{kn}: T_{kN} \ \Gamma \vdash E_{vn}: T_{vN}}{\Gamma \vdash \{E_{k1}: E_{v1}, ..., E_{{kn}}: E_{vn}\}: dictof(T_{k}=sup(T_{k1}, T_{k2}, ... T_{kn}), \ T_{v}=sup(T_{v1}, T_{v2}, ..., T_{vn}))} -$$ - -Expr DictComp - -$$ -\frac{\Gamma \vdash E_1: T_{rki} \ \Gamma \vdash E_2: T_{rvi} \ \Gamma \vdash v_1: T_k \ \Gamma \vdash v_2: T_v \ \Gamma \vdash E_3: dictof(T_{k}, \ T_{v}) \ \Gamma \vdash E_4: boolean}{\Gamma \vdash \{E_1:E_2 \ for \ (v_1, v_2) \ in \ E_3 \ if \ E_4\}: dictof(T_{k}=sup(T_{rk1}, T_{rk2}, ..., T_{rkn}), T_{v}=sup(T_{rv1}, T_{rv2}, ..., T_{rvn})) } -$$ - -Expr StructExpr - -$$ -\frac{\Gamma \vdash E_{1}: T_{1} \ ... \ \Gamma \vdash E_{n}: T_{n} \ K_1 \neq K_n}{\Gamma \vdash \{K_{1} = E_{1}, ..., K_{{n}} = E_{n}\}: structof(K_1 : T_{1}, ... , K_n : T_{n})} -$$ - -Literal 类型是基础类型的值类型,Union 类型是类型的组合类型,Void、Any、Nothing 是特殊的类型指代,本身没有直接的值表达式对应关系。 - -### Primary Expr - -Expr Index - -$$ -\frac{\Gamma \vdash E: listof(T) \ \Gamma \vdash Index: integer}{\Gamma \vdash E[Index]: T} -$$ - -Expr Call - -$$ -\frac{\Gamma \vdash E_1: T_1 \rightarrow T_2 \ \Gamma \vdash E_2: T_1}{\Gamma \vdash E_1 \ (E_2): T_2} -$$ - -Expr List Selector - -$$ -\frac{\Gamma \vdash E: listof(T) \ \Gamma \vdash Index: integer}{\Gamma \vdash E.[Index]: T} -$$ - -Expr Dict Selector - -$$ -\frac{\Gamma \vdash E: dictof(T_k = T_1, T_v=T_2) \ \Gamma \vdash S_1: string \ ... \ \Gamma \vdash S_n: string}{\Gamma \vdash E.\{S_1, ..., S_n\}: dictof(T_k = T_1, T_v=T_2)} -$$ - -Expr Struct Selector - -$$ -\frac{\Gamma \vdash E: structof(K_1 : T_{1}, ... , K_n : T_{n}) \ \Gamma \vdash K_i: string}{\Gamma \vdash E.K_i: T_{i}} -$$ - -### Unary Expr - -Expr + - -$$ -\frac{\Gamma \vdash E: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash \ +E: T} -$$ - -Expr - - -$$ -\frac{\Gamma \vdash E: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash \ -E: T} -$$ - -Expr ~ - -$$ -\frac{\Gamma \vdash E: integer}{\Gamma \vdash \ ~E: integer} -$$ - -Expr not - -$$ -\frac{\Gamma \vdash E: boolean}{\Gamma \vdash \ not \ E: boolean} -$$ - -### Binary Expr - -算数运算符 - -Expr op, op $\in$ {-, /, %, \*\*, //} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash E_1 \ op \ E_2: T} -$$ - -Expr + - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, float, string, listof(T_1)\}}{\Gamma \vdash E_1 \ + \ E_2: T} -$$ - -Expr \* - -$$ -\frac{\Gamma \vdash E_1: T_1 \ \ \ \Gamma \vdash E_2: T_2 \ \ \ \ (T_1==T_2 \in \{integer, float\}) \ or \ (T_1 == interger \ and \ T_2 \ \in \ \{string, listof(T_3)\}) \ or \ (T_2 == interger \ and \ T_1 \ \in \ \{string, listof(T_3)\})} {\Gamma \vdash E_1 \ * \ E_2: T} -$$ - -示例 - -Expr % - -$$ -\frac{\Gamma \vdash E_1: interger \ \ \ \Gamma \vdash E_2: integer}{\Gamma \vdash E_1 \ \% \ E_2: interger} -$$ - -逻辑运算符 - -Expr op, op $\in$ \{or, and\} - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ op \ E_2: boolean} -$$ - -示例 - -Expr and - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ and \ E_2: boolean} -$$ - -比较运算符 - -Expr op, op $\in$ \{==, !=, <, >, <=, >=\} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T}{\Gamma \vdash E_1 \ op \ E_2: boolean} -$$ - -示例 - -Expr > - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ > \ E_2: boolean} -$$ - -位运算符 - -Expr op, op $\in$ {&, ^, ~, <<, >>} - -$$ -\frac{\Gamma \vdash E_1: integer \ \ \ \Gamma \vdash E_2: integer}{\Gamma \vdash E_1 \ op \ E_2: integer} -$$ - -Expr | - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, listof(T_1), dictof(T_k, T_v), structof(K_1=T_1, ..., K_n=T_n)\}}{\Gamma \vdash E_1 \ | \ E_2: T} -$$ - -成员运算符 - -Expr op, op $\in$ {in, not in} - -$$ -\frac{\Gamma \vdash E_1: string \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{dictof, structof\}}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -Expr op, op $\in$ {in, not in} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: listof(S), T \sqsubseteq S}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -身份运算符 - -Expr op $\in$ {is, is not} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -### IF Expr - -Expr If - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: T \ \ \ \Gamma \vdash E_3: T}{\Gamma \vdash if \ E_1 \ then \ E_2 \ else \ E_3: T} -$$ - -### Stmt - -Stmt If - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash S_1: Void \ \ \ \Gamma \vdash S_2: Void}{\Gamma \vdash if \ E_1 \ then \ S_1 \ else \ S_2: Void} -$$ - -Stmt Assign - -$$ -\frac{\Gamma \vdash id: T_0 \ \ \ \Gamma \vdash T_1 \ \ \ \Gamma \vdash E: T_2}{\Gamma \vdash id: T_1 \ = \ E : Void} -$$ - -Type Alias - -$$ -\frac{\Gamma \vdash id: T_0 \ \ \ \Gamma \vdash T_1}{\Gamma \vdash type \ id \ = \ T_1 : Void} -$$ - -## Union - -### Union 规则 - -List Union - -$$ -\frac{\Gamma \vdash \ listof(T) \ \ \ \Gamma \vdash \ listof(S)}{\Gamma \vdash \ listof(unionof(T, S))} -$$ - -Dict Union - -$$ -\frac{\Gamma \vdash \ dictof(T_1, T_2) \ \ \ \Gamma \vdash \ dictof(S_1, S_2)}{\Gamma \vdash \ dictof(unionof(T_1, S_1), unionof(T_2, S_2))} -$$ - -Struct Union - -给定两个结构体 $structof(K_{1}: T_{1}, ..., K_{n}: T_{n}),structof(H_{1}: S_{1}, ..., H_{m}: S_{n})$ - -定义他们的 union 类型: - -$$ -structof(J_{1}: U_{1}, ..., J_{p}: U_{n}) = structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \bigcup structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) -$$ - -例如: - -$$ -structof() \ \bigcup \ structof(H_{1}: T_{1}, ..., H_{m}: T_{n}) = structof(H_{1}: T_{1}, ..., H_{m}: T_{n}) -$$ - -$$ -structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \ \bigcup \ structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) = structof(K_1: T_1) :: (structof(K_{2}: T_{2}, ..., K_{n}: T_{n}) \ \bigcup \ structof(H_{1}: S_{1}, ..., H_{m}: S_{n})) -$$ - -其中把 "::" 表示把一个对偶加入到一个结构的操作,定义如下: - -$$ -structof(K_{1}: T_{1}) :: structof() = structof(K_{1}: T_{1}) -$$ - -$$ -structof(K_{1}: T_{1}) :: structof(K_{1}: T_{1}', ..., K_n: T_{n}) = structof(K_{1}: union\_op(T_{1}, T_{1}'), ..., K_{n}: T_{n}) -$$ - -$$ -structof(K_{1}: T_{1}) :: structof(K_{2}: T_{2}, ..., K_n: T_{n}) = structof(K_{2}: T_2) :: structof(K_{1}: T_1) :: structof(K_{3}: T_3, ..., K_{n}: T_{n}) -$$ - -基于此,两个 Struct 的 union 定义为: - -$$ -\frac{\Gamma \vdash structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \ \Gamma \vdash structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) \ structof(J_{1}: U_{1}, ..., J_{p}: U_{n}) = structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \bigcup structof(H_{1}: S_{1}, ..., H_{m}: S_{n})}{\Gamma \vdash structof(J_{1}: U_{1}, ..., J_{p}: U_{n}))} -$$ - -其中 $union\_op(T_1, T_2)$ 表示对相同 $K_i$ 的不同类型的判断操作: - -- 当 $T_1$ 与 $T_2$ 有偏序关系时, 如果 $T_1 \sqsubseteq T_2$ 时,返回 $T_2$,否则返回 $T_1$,即取最小上界 -- 当 $T_1$ 与 $T_2$ 不存在偏序关系时,有三种可选的处理逻辑: - - 结构体 union 失败,返回 type_error - - 返回后者的类型,此处为 $T_2$ - - 返回类型 $unionof(T_1, T_2)$ - -此处需要根据实际需求选择适当的处理方式。 - -结构体继承可以看做一种特殊的 union,整体逻辑与 union 相似,但在 $union\_op(T_1, T_2)$ 中对相同 $K_i$ 的不同类型的判断操作如下: - -- 当 $T_1$ 与 $T_2$ 有偏序关系且 $T_1 \sqsubseteq T_2$ 时,返回 $T_1$,即仅当 $T_1$ 是 $T_2$ 的下界时以下界 $T_1$ 为准 -- 否则返回 type_error - -通过这样的继承设计可以实现分层的、自下而上逐层收缩的类型定义。 - -## Operation - -KCL 支持对结构体属性进行如 `p op E` 形式的操作。 即对给定结构体 $A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})$, 对结构体中的路径 `p` 以 `E` 的值进行指定的操作(如 union,assign,insert 等)。 - -定义如下更新操作: - -$$ -\frac{{\Gamma\vdash A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})}  {\Gamma\vdash p \in (K_{1}, ..., K_{n})} \ {\Gamma\vdash e:T}   k \neq k_1, ..., k \neq k_n} -{ A \{p \ op \ e\}:\{K_1:T_1, ..., K_n:T_n\}∪\{p:T\}} -$$ - -即对路径 $p$ 进行操作本质上是对两个结构体的一种 union,对同名属性类型 union 时的规则根据情况而定。例如路径 $p$ 是一个可用作字段名的标识符 $p=k_1$,并且结构体 A 中字段名也是 $k_1$,它的类型为 $T_1$,并且表达式 $e$ 的类型也为 $T_1$ ,那么 - -$$ -\frac{{\Gamma\vdash A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})}  {\Gamma\vdash p = K_{1}} \ {\Gamma\vdash e:T_1}   k \neq k_1, ..., k \neq k_n} -{ A \{p \ op \ e\}:\{K_1:T_1, ..., K_n:T_n\}} -$$ - -注意: - -- 此处表达式 $e$ 的类型 $T_1$ 同原先同名属性 $K_1$ 的具有相同的类型。可根据实际情况需要适当放松,如 $e$ 的类型 $\sqsubseteq T_1$ 即可。 -- 对于多层结构体嵌套的操作,递归的使用以上规则即可。 - -## 类型偏序 - -### 基础类型 - -$$ -Type \ T \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ T -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Bool \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Int \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Float \sqsubseteq Type \ Any -$$ - -$$ -Type \ Int \sqsubseteq Type \ Float -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ String \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Literal \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ List \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Dict \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Struct \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ None \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Void \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Any -$$ - -### 字面值类型 - -$$ -Type \ Literal(Bool) \sqsubseteq Type \ Bool -$$ - -$$ -Type \ Literal(Int) \sqsubseteq Type \ Int -$$ - -$$ -Type \ Literal(Float) \sqsubseteq Type \ Float -$$ - -$$ -Type \ Literal(String) \sqsubseteq Type \ String -$$ - -### 联合类型 - -$$ -Type \ X \sqsubseteq Type \ Union(X, Y) -$$ - -### 自反 - -$$ -Type \ X \sqsubseteq Type \ X -$$ - -示例 - -$$ -Type \ Bool \sqsubseteq Type \ Bool -$$ - -$$ -Type \ Int \sqsubseteq Type \ Int -$$ - -$$ -Type \ Float \sqsubseteq Type \ Float -$$ - -$$ -Type \ String \sqsubseteq Type \ String -$$ - -$$ -Type \ List \sqsubseteq Type \ List -$$ - -$$ -Type \ Dict \sqsubseteq Type \ Dict -$$ - -$$ -Type \ Struct \sqsubseteq Type \ Struct -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Nothing -$$ - -$$ -Type \ Any \sqsubseteq Type \ Any -$$ - -$$ -Type \ Union(Type Int, Type Bool) \sqsubseteq Type \ Union(Type Int, Type Bool) -$$ - -### 传递 - -$$ -Type \ X \sqsubseteq Type \ Z \ if \ Type \ X \sqsubseteq Type \ Y \ and \ Type \ Y \sqsubseteq \ Type \ Z -$$ - -### 包含 - -$$ -Type \ List(T_1) \sqsubseteq Type \ List(T_2) \ if \ T_1 \sqsubseteq T_2 -$$ - -$$ -Type \ Dict(T_{k1}, T_{v1}) \sqsubseteq Type \ Dict(T_{k2}, T_{v2}) \ if \ T_{k1} \sqsubseteq T_{k2} \ and \ T_{v1} \sqsubseteq T_{v1} -$$ - -$$ -Type \ Structure(K_1: T_{a1}, K_2: T_{a2}, ..., K_n: T_{an}) \sqsubseteq Type \ Structure(K_1: T_{b1}, K_2: T_{b2}, ..., K_n: T_{bn}) \ if \ T_{a1} \sqsubseteq T_{b1} \ and \ T_{a2} \sqsubseteq T_{b2} \ and \ ... \ and \ T_{an} \sqsubseteq T_{bn} -$$ - -### 继承 - -$$ -Type \ Struct \ A \sqsubseteq Type \ Struct \ B \ if \ A \ inherits \ B -$$ - -### None - -$$ -Type \ None \sqsubseteq Type \ X, X \notin \{Type \ Nothing, \ Type \ Void\} -$$ - -### Undefined - -$$ -Type \ Undefined \sqsubseteq Type \ X, X \notin \{Type \ Nothing, \ Type \ Void\} -$$ - -## 相等性 - -交换律 - -$$ -Type \ Union(X, Y) == Type \ Union(Y, X) -$$ - -示例 - -$$ -Type \ Union(Int, Bool) == Type \ Union(Bool, Int) -$$ - -结合律 - -$$ -Type \ Union(Union(X, Y), Z) == Type \ Union(X, Union(Y, Z)) -$$ - -示例 - -$$ -Type \ Union(Union(Int, String), Bool) == Type \ Union(Int, Union(String, Bool)) -$$ - -幂等性 - -$$ -Type \ Union(X, X) == Type \ X -$$ - -示例 - -$$ -Type \ Union(Int, Int) == Type \ Int -$$ - -偏序推导 - -$$ -Type \ Union(X, Y) == Type \ Y \ if \ X \sqsubseteq Y -$$ - -示例 - -假设 Struct A 继承 Struct B - -$$ -Type \ Union(A, B) == Type \ B -$$ - -幂等性是偏序自反的一个特例 - -### List - -$$ -Type \ List(X) == Type \ List(Y) \ if \ X == Y -$$ - -### Dict - -$$ -Type \ Dict(T_k, T_v) == Type \ Dict(S_k, S_v) \ if \ T_k == S_k \ and \ T_v == S_v -$$ - -### Struct - -$$ -Type \ Struct(K_1: T_{1}, K_2: T_{2}, ..., K_n: T_{n}) == Type \ Struct(K_1: S_{1}, K_2: S_{2}, ..., K_n: S_{n}) \ if \ T_{1} == S_{1} \ and \ ... \ and \ T_{n} == S_{n} -$$ - -### 偏序检查 - -$$ -Type \ X == Type \ Y \ if \ Type \ X \sqsubseteq Type \ Y \ and \ Type \ Y \sqsubseteq \ Type \ X -$$ - -## 基础方法 - -- sup(t1: T, t2: T) -> T: 根据类型偏序计算两类型 t1, t2 的最小上界。需要动态创建 union type。 -- typeEqual(t1: T, t2: T) -> bool: 比较两类型 t1, t2 是否相等。 -- typeToString(t: T) -> string: 自顶向下递归解析并转化类型成对应的字符串类型。 - -### Sup Function - -- 暂不考虑类型参数,条件类型等特性 -- 使用一个有序集合存储 UnionType 的所有类型 -- 使用一个全局的 Map 根据 UnionType 的名称存储产生的所有 UnionType -- 根据偏序关系计算类型之间的包含关系 - -```go -// The Sup function returns the minimum supremum of all types in an array of types -func Sup(types: T[]) -> T { - typeOf(types, removeSubTypes=true) -} - -// Build a sup type from types [T1, T2, ... , Tn] -func typeOf(types: T[], removeSubTypes: bool = false) -> T { - assert isNotNullOrEmpty(types) - // 1. Initialize an ordered set to store the type array - typeSet: Set[T] = {} - // 2. Add the type array to the ordered set for sorting by the type id and de-duplication - addTypesToTypeSet(typeSet, types) - // 3. Remove sub types according to partial order relation rules e.g. sub schema types - if removeSubTypes { - removeSubTypes(typeSet) - } - if len(typeSet) == 1 { - // If the typeSet has only one type, return it - return typeSet[0] - } - // 4. Get or set the union type from the global union type map - id := getIdentifierFromTypeSet(typeSet) - unionType := globalUnionTypeMap.get(id) - if !unionType { - unionType = createUnionType(typeSet) // Build a new union type - globalUnionTypeMap.set(id, unionType) - } - return unionType -} - -// Add many types into the type set -func addTypesToTypeSet(typeSet: Set[T], types: T[]) -> void { - for type in types { - addTypeToTypeSet(typeSet, type) - } -} - -// Add one type into the type set -func addTypeToTypeSet(typeSet: Set[T], type: T) -> void { - if isUnion(type) { - return addTypesToTypeSet(typeSet, toUnionOf(type).types) - } - // Ignore the void type check - if !isVoid(type) { - // De-duplication according to the type of id - typeSet.add(type) - } -} - -func removeSubTypes(types: Set[T]) -> void { - for source in types { - for target in types { - if !typeEqual(source, target) { - // If the two types have an inheritance relationship, the base class is retained, or if the two types have a partial order relationship according to the relation table. - if (isPartialOrderRelatedTo(source, target)) { - types.remove(source) - } - } - } - } -} - -// isPartialOrderRelatedTo function Determine whether two types have a partial order relationship `source \sqsubseteq target` -// according to the partial order relationship table and rules -func isPartialOrderRelatedTo(source: T, target: T) -> bool { - assert isNotNullOrEmpty(source) - assert isNotNullOrEmpty(target) - if isNoneOrUndefined(source) and !isNothing(target) and !isVoid(target) { - return true - } - if isAny(target) { - return true - } - if typeEqual(source, target) { - return true - } - if isUnion(target) and source in target.types { - return true - } - // Literal Type - if (isStringLiteral(source) and isString(target)) or \ - (isBooleanLiteral(source) and isBool(target)) or \ - (isIntLiteral(source) and isInt(target)) or \ - (isFloatLiteral(source) and isFloat(target)) { - return true - } - if isInt(source) and isFloat(target) { - return true - } - if isList(source) and isList(target) { - return isPartialOrderRelatedTo(toListOf(source).eleType, toListOf(target).eleType - } - if isDict(source) and isDict(target) { - return isPartialOrderRelatedTo(toDictOf(source).keyType, toDictOf(target).keyType) and isPartialOrderRelatedTo(toDictOf(source).valueType, toDictOf(target).valueType) - } - if isStruct(source) and isStruct(target) { - if isTypeDerivedFrom(source, target) { - return true - } - // Empty Object - if len(target.keys) == 0 { - return true - } - if any([key Not in source.keys for key in target.keys]) { - return false - } - for key, sourceType in (source.keys, source.types) { - targetType = getKeyType(target, key) ? getKeyType(target, key) : anyTypeOf() - if !isPartialOrderRelatedTo(sourceType, targetType) { - return false - } - } - return true - } - return false -} -``` - -## 类型检查 - -### 类型检查器 - -类型检查器通过语法制导翻译的方式,自顶向下遍历语法树,并根据上下文有关的**定型规则**来判定程序构造是否为良类型程序。 - -类型检查器依赖类型规则,类型环境 $\Gamma$ 的信息记入符号表。对类型表达式采用抽象语法,如 listof(T)。类型检查失败时产生 type_error,并根据语法上下文产生错误信息。 - -### 基础方法 - -1. isUpperBound(t1, t2): supUnify(t1, t2) == t2 -2. supUnify(t1, t2): - -- 对于基础类型,根据偏序关系计算 sup(t1, t2) -- 对于 list、 dict、 Struct, 递归地对其中元素的类型进行 supUnify -- 不存在偏序关系时,返回 Nothing - -### 检查逻辑 - -#### Operand Expr - -$D \to id: T$ - -``` -env.addtype(id.entry, T.type) -``` - -$T \to boolean$ - -``` -T.type = boolean -``` - -$T \to integer$ - -``` -T.type = integer -``` - -$T \to float$ - -``` -T.type = float -``` - -$T \to string$ - -``` -T.type = string -``` - -$T \to c, \ c \in \{boolean, integer, float, string\}$ - -``` -T.type = literalof(c) -``` - -$T \to None$ - -``` -T.type = None -``` - -$T \to Undefined$ - -``` -T.type = Undefined -``` - -$T \to \ [T_1]$ - -``` -T.type = listof (T1.type) -``` - -$T \to { \{T_1: T_2\} }$ - -``` -T.type = dictof (T1.type: T2.type) -``` - -$T \to { \{N_1: T_1, N2: T_2, ..., N_n: T_n\} }$ - -``` -T.type = structof (N1: T1.type, N2: T2.type, ..., Nn: Tn.type) -``` - -$E \to id$ - -``` -E.type = env.lookup(id.entry) -``` - -$E \to [E_1, E_2, ..., E_n]$ - -``` -func listExpr(E) { - supe = sup([e.type for e in E]]) - E.type = listof(type) -} -``` - -$E \to [E_1 \ for \ E_2 \ in \ E_3 \ if \ E_4]$ - -``` -func listComp(E) { - if !typeEqual(E4.type, boolean) { - raise type_error - } - if !isUpperBound(listof(Any), E3.type) { - raise type_error(E) - } - if !isUpperBound(E3.type, E2.type) { - raise type_error(E) - } - E.type = listof(E1.type) -} -``` - -$E \to \{E_{k1}: E_{v1}, ..., E_{kn}: E_{vn}\}$ - -``` -func dictExpr(E) { - supk := sup([e.type for e in E.keys()]]) - supv := sup([e.type for e in E.values()]]) - E.type = dictof(supk, supv) -} -``` - -$E \to \{E_1:E_2 \ for \ (E_3, E_4) \ in \ E_5 \ if \ E_6\}$ - -``` -func dictComp(E) { - if !typeEqual(E6.type, boolean) { - raise type_error(E) - } - if !isUpperBound(dictof(Any, Any), E5.type) { - raise type_error(E) - } - if !isUpperBound(E5.type, dictof(E3.type, E4.type)) { - raise type_error(E) - } - E.type = dictof(E1.type, E2.type) -} -``` - -$E \to \{E_{k1}: E_{v1}, ..., E_{kn}: E_{vn}\}$ - -``` -func dictExpr(E) { - supk := sup(Ek1, ..., Ekn) - supv = sup(Ev1, ..., Evn) - E.type = dictof(supk, supv) -} -``` - -$E \to \{N_{1} = E_{1}, ..., N_{{n}} = E_{n}\}$ - -``` -func structExpr(E) { - Struct = structof() - for n, e in E { - Struct.add(n, e.type) - } - E.type = Struct -} -``` - -#### Primary Expr - -$E \to E_1[E_2]$ - -``` -func sliceSuffix(E) { - if !isUpperBound(listof(Any), E.E1.type) { - raise type_error(E) - } - if typeEqual(E.E2.type, integer) { - raise type_error(E) - } - E.type = E.E1.type.eleType -} -``` - -$E \to E_1(E_2)$ - -``` -func callSuffix(E) { - if !typeEqual(E.E1.type, func) { - raise type_error(E) - } - if !isUpperBound(listof(E.E1.arguType), E.E2.type) { - raise type_error(E) - } - E.type = E.E1.returnType -} -``` - -#### Unary Expr - -根据每条双目运算符的推理规则推导,以 '+' 为例 - -$E \to + E_1$ - -``` -func Plus(E) { - if !typeEqual(E.E1.type, [integer, float]) { - raise type_error(E) - } - E.type = E.E1.type -} -``` - -#### Binary Expr - -根据每条双目运算符的推理规则推导,以 '%' 为例 - -$E \to E_1 \ % \ E_2$ - -``` -func Mod(E) { - if !(typeEqual(E.E1.type, [integer, float]) && typeEqual(E.E2.type, [integer, float])) { - raise type_error(E) - } - E.type = E.E1.type -} -``` - -#### IF Binary Expr - -$E \to if E_1 \ then \ E_2 else \ E_3$ - -``` -func ifExpr(E) { - if !typeEqual(E.type, boolean) { - raise type_error(E) - } - if !typeEqual(E_2.type, E_3.type) { - raise type_error(E) - } - E.type = E_2.type -} -``` - -#### Stmt - -$S \to if \ E \ then \ S_1 \ else \ S_2$ - -``` -func ifStmt(S) { - if !typeEqual(S.E.type, boolean) { - raise type_error(E) - } - if !typeEqual(S.S1.type, S.S2.type) { - raise type_error(E) - } - S.type = S.S1.type -} -``` - -$S \to id: T = E$ - -$S \to id = T E$ - -``` -func assignStmt(S) { - tpe := env.lookup(id.entry) - if tpe != nil && tpe != S.T { - raise type_error(E) - } - if isUpperBound(tpe, E.type) { - raise type_error(E) - } - env.addtype(id.entry, T.type) -} -``` - -## 类型转换 - -### 基础定义 - -通过语法制导翻译的方式,根据运算符特征,对参与运算的值类型进行自动类型转换 - -### 转换规则 - -$E \to E_1 \ op \ E_2, , op \in \{+, -, *, /, \%, **, //\}$ - -``` -func binOp(E) { - if E.E1.type == integer and E.E2.type == integer { - E.type = integer - } else if E.E1.type == integer and E.E2.type == float { - E.type = float - } else if E.E1.type == float and E.E2.type == integer { - E.type = float - } else if E.E1.type == float and E.E2.type == float { - E.type = float - } -} -``` - -## 类型推导 - -### 基础定义 - -- 在类型信息不完全的情况下类型规则推导、重建类型 -- 自底向上推导并重建数程序中的数据结构类型,如基础类型,list, dict, Struct - -### 基础方法 - -1. typeOf(expr, subst): 输入为表达式和代换规则集合,返回 expr 的类型和新的代换规则集合 -2. unifier(t1, t2, subst, expr) 用 t1=t2 尝试代换,如果代换成功(未出现且无冲突),则将 t1=t2 加入 subst 并返回 subst。否则报错已出现或有冲突。 - -### 推导逻辑 - -$E \to id = E_1$ - -``` -func assignExpr(E, subst) { - return unifier(E.id.type, E.E_1.type, subst, E) -} -``` - -$unifier(t1, t2, subst, expr) \rightarrow subst$ - -``` -func unifier(t1, t2, subst, expr) { - t1 = applySubstToTypeEquation(t1, subst) - t2 = applySubstToTypeEquation(t2, subst) - - if t1 == t2 { - return subst - } - - if isTypeVar(t1) { - if isNoOccur(t1, t2) { - addTypeEquationToSubst(subst, t1, t2) - return subst - } else { - raise occurrence_violation_error(t1, t2, expr) - } - } - - if isTypeVar(t2) { - if isNoOccur(t2, t1) { - addTypeEquationToSubst(subst, t2, t1) - return subst - } else { - raise occurrence_violation_error(t2, t1, expr) - } - } - - if isList(t1) and isList(t2) { - return unifier(toListOf(t1).eleType, toListOf(t2).eleType, subst, expr) - } - if isDict(t1) and isDict(t2) { - dict1of := toDictOf(t1) - dict2of := toDictOf(t2) - subst = unifier(dict1of.keyType, dict2of.keyType, subst, expr) - subst = unifier(dict1of.valueType, dict2of.valueType, subst, expr) - return subst - } - if isStruct(t1) and isStruct(t2) { - Struct1of := tostructof(t1) - Struct2of := tostructof(t2) - for key, _ in Struct1of { - subst = unifier(t1[key].type, t2[key].type, subst, expr) - } - return subst - } - - raise unification_error(t1, t2, expr) -} - -func applySubstToTypeEquation(t, subst) { - // walks through the type t, replacing each type variable by its binding in the substitution -σ. If a variable is Not bound in the substitution, then it is left unchanged. - if isBasicType(t) { - return t - } - if isList(t) { - return listOf(applySubstToTypeEquation(toListOf(t).eleType, subst)) - } - if isDict(t) { - dictof := toDictOf(t) - kT := applySubstToTypeEquation(dictof.keyType, subst) - vT := applySubstToTypeEquation(dictof.valueType, subst) - return dictOf(kT, vT) - } - if isStruct(t) { - structof := tostructof(t) - s := structof() - for key, type in Struct1of { - kT := applySubstToTypeEquation(type, subst) - s.add(key, kT) - } - return s - } - if hasTypeVar(t) { - for tvar in t.vars { - if tvar in subst { - *tvar = subst[tvar] - } - } - } - return t -} - -func addTypeEquationToSubst(subst, tvar, t) { - // takes the substitution σ and adds the equation tv = t to it - for _, t in subst { - for tvar in t.vars { - tmp := applyOneSubst(tsvar, tvar, t) - *tvar = tmp - } - } - subst.add(tvar, t) -} - -func applyOneSubst(t0, tvar, t1) { - // substituting t1 for every occurrence of tv in t0. - if isBasicType(t0) { - return t0 - } - if isList(t0) { - return listOf(applyOneSubst(toListOf(t).eleType, tvar, t1)) - } - if isDict(t0) { - dictof := toDictOf(t) - kT := applyOneSubst(dictof.keyType, tvar, t1) - vT := applyOneSubst(dictof.valueType, tvar, t1) - return dictOf(kT, vT) - } - if isStruct(t0) { - structof := tostructof(t) - s := structof() - for key, type in Struct1of { - kT := applyOneSubst(type, tvar, t1) - s.add(key, kT) - } - return s - } - if t0 == tvar { - return t1 - } - return t0 -} - -func isNoOccur(tvar, t) { - // No variable bound in the substitution occurs in any of the right-hand sides of the substitution. - if isBasicType(t) { - return true - } - if isList(t) { - return isNoOccur(tvar, toListOf(t).eleType) - } - if isDict(t) { - dictof := toDictOf(t) - return isNoOccur(tvar, dictof.keyType) and isNoOccur(tvar, dictof.valueType) - } - if isStruct(t) { - structof := tostructof(t) - noOccur := true - for _, type in structof { - noOccur = noOccur and isNoOccur(tvar, type) - } - return noOccur - } - return tvar != t -} -``` - -### 示例 - -#### 正常推导 - -``` -T : { - a = 1 - b = "2" - c = a * 2 - d = { - d0 = [a, c] - } -} - -x: T = { - a = 10 -} -``` - -#### Occurrence Violation Error - -``` -T = { - a = a -} -``` - -#### Type Unification Error - -``` -T : { - a = 1 -} - -T : { - a = "1" -} -``` - -## Reference - -- [https://en.wikipedia.org/wiki/Type_system](https://en.wikipedia.org/wiki/Type_system) -- Pierce, Benjamin C. (2002). Types and Programming Languages. MIT Press. -- [https://www.cs.cornell.edu/courses/cs4110/2010fa/](https://www.cs.cornell.edu/courses/cs4110/2010fa/) -- [https://www.typescriptlang.org/docs/handbook/basic-types.html](https://www.typescriptlang.org/docs/handbook/basic-types.html) -- [https://www.typescriptlang.org/docs/handbook/advanced-types.html](https://www.typescriptlang.org/docs/handbook/advanced-types.html) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/_category_.json deleted file mode 100644 index 53e27fd4..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "模块系统", - "position": 2 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/base64.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/base64.md deleted file mode 100644 index 0db738f0..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/base64.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: "base64" -linkTitle: "base64" -type: "docs" -description: base64 编码解码 -weight: 100 ---- - -## encode - -`encode(value: str, encoding: str = "utf-8") -> str` - -使用注册的编码器对字符串 `value` 进行编码。 - -## decode - -`decode(value: str, encoding: str = "utf-8") -> str` - -使用注册的编码器对字符串 `value` 进行解码。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/builtin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/builtin.md deleted file mode 100644 index 44085174..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/builtin.md +++ /dev/null @@ -1,401 +0,0 @@ ---- -title: "builtin" -sidebar_position: 1 ---- - -KCL 提供了一个内置系统模块的列表,这些模块是自动加载的,无需提供任何模块名称即可直接使用。例如,`print` 就是一个广泛使用的内置模块提供的函数。 - -## 类型转换函数 - -KCL的 `bool`、`int`、`float`、`str`、`list`、`dict`等类型有内置同名的转换函数。其中 `int` 不仅仅可以用于截断浮点数,也可以用来将字符串转化为整数(解析时为10进制,也可以制定其他值)。 - -下面是类型相关函数常见的用法: - -```py -b1 = bool(1) # true -b2 = bool(1.5) # true -b3 = bool("true") # true -b4 = bool("") # false -b5 = bool([]) # false -b6 = bool({}) # false - -i1 = int("11") # 11 -i2 = int("11", base=8) # 9 -i3 = int("11", base=2) # 3 - -f1 = float(1) # 1.0 -f2 = float("1.5") # 1.5 - -s1 = str(1) # 1 - -l1 = list([1, 2, 3]) -``` - -## String 类型成员函数 - -参考 [String 文档](/docs/reference/lang/spec/datatypes) - -## print - -`print(*args:any, end:str='\n')` - -内置的打印函数,提供不同类型的可变参数打印,默认在结尾添加一个换行符号。以下上常见的用法: - -```python -print("hello KCL") -print() -print(None, end=':') -print(None) -print(True) -print(False) -print(123) -print(123.0) -print('abc ${123}') -print("abc ${456}") -print([1,'a', True]) -print(1,'a', True) -print({}) -print({a: 123}) -``` - -输出格式如下: - -```shell -hello KCL - -None:None -True -False -123 -123.0 -abc 123 -abc 456 -[1, 'a', True] -1 a True -{} -{'a': 123} -``` - -如果不希望在默认换行时,可以通过 `end=''` 命名参数重新指定结尾的字符串。 - -## multiplyof - -`multiplyof(a:int, b:int) -> bool` - -判断整数 `a` 是否为 `b` 的整数倍,返回布尔值: - -```python -print(multiplyof(2, 1)) # True -print(multiplyof(1, 2)) # False -print(multiplyof(0, 1)) # True -print(multiplyof(0, 2)) # True -print(multiplyof(1, 0)) # Error -``` - -`0` 是任何数的倍数。但是 `b` 不能为 `0`,否则将抛出异常。 - -## isunique - -`isunique(list: [any]) -> bool` - -判断数组中是否存在重复的元素,返回布尔值: - -```python -print(isunique([])) # True -print(isunique([1])) # True -print(isunique([1, 2])) # True - -print(isunique([1, 1])) # False -print(isunique([1, 1.0])) # False -print(isunique([1.1, 1.1])) # False - -print(isunique(['abc', "abc"])) # False -print(isunique(['abc', "a${'bc'}"])) # False -``` - -需要注意的是整数和浮点数会忽略类型差异,根据值是否相等判断。 - -## len - -`len(x: str | [any] | {:}) -> int` - -返回字符串、列表和数组的长度: - -```python -print(len([])) # 0 -print(len({})) # 0 - -print(len([1])) # 1 -print(len({abc:123})) # 1 - -print("abc") # 3 -``` - -注:不支持对 `schema` 对象计算长度。 - -## abs - -`abs(x: number) -> number` - -计算 `x` 的绝对值。 - -## all_true - -`all_true(x:str|[]|{:}) -> bool` - -判断列表或字典类全部元素为真,用法如下: - -```python -print(all_true([])) # True -print(all_true({})) # True - -print(all_true([True])) # True -print(all_true([1])) # True - -print(all_true([True, False])) # False -print(all_true([True, None])) # False -``` - -当列表为空时返回真。 - - - -## any_true - -`any_true(x:str|[]|{:}) -> bool` - -判断可迭代对象中至少有一个元素为真,用法如下: - -```python -print(any_true([])) # False -print(any_true([1])) # True -``` - -## bin - -`bin(x:number) -> str` - -返回整数的二进制表示的字符串,用法如下: - -```python -print(bin(8)) # 0b1000 -``` - -## hex - -`hex(number)` - -返回整数的十六进制表示的字符串,用法如下: - -```python -print(hex(18)) # 0x12 -``` - -## oct - -`oct(number)` - -返回整数的八进制表示的字符串,用法如下: - -```python -print(oct(10)) # 0o12 -``` - -## option - -`option(key:str, type:str='', required=False, default=None, help="") -> any` - -获取命令行参数输入的值。 - -## ord - -`ord(c) -> int` - -获取字符的 Unicode 码点值,用法如下: - -```python -print(ord('A')) # 65 -print(ord('B')) # 66 -print(ord('C')) # 67 -``` - -## sorted - -`sorted(x: []) -> []` - -返回排序后的列表,用法如下: - -```python -_a = [] -_b = [2, 1] - -_c = sorted(_a) -_d = sorted(_b) - -print(_a) # [] -print(_b) # [2, 1] -print(_c) # [] -print(_d) # [1, 2] -``` - -## range - -`range(start:int, end:int, step=1) -> [int]` - -产生迭代列表,用法如下: - -```python -print(range(1,5)) # [1, 2, 3, 4] -print(range(1,5, 2)) # [1, 3] -print(range(5, 1, -1)) # [5, 4, 3, 2] -``` - -## min - -`min(x:[number]) -> number` - -返回列表中最小的元素,用法如下: - -```python -print(min([1,2])) # 1 -print(min([2,1])) # 1 -``` - - - -## max - -`max(x:[number]) -> number` - -返回列表中最大的元素,用法如下: - -```python -print(max([1,2])) # 2 -print(max([2,1])) # 2 -``` - -## sum - -`sum(x:[number], init_value=0) -> number` - -返回列表中全部元素的和,用法如下: - -``` -print(sum([1,2])) # 3 -print(sum([2,1], 1000)) # 1003 -``` - -## pow - -`pow(x: number, y: number, z: number = None) -> number` - -计算 `x**y`,如果 `z` 非空则计算 `(x**y)%z`,支持整数和浮点数。 - -下面的常见的用法: - -```python -print(pow(2,3)) # 8 -print(pow(2, 3, 5)) # 8%5 == 3 - -print(pow(2, 0.5)) # 1.414 -``` - -## round - -`round(number: int|float, ndigits:int|None) -> float | int` - -返回 `number` 的四舍五入近似值。如果 `ndigits` 非 `None` 则返回浮点数并保留指定位数的小数(不能为负数),否则返回整数结构。 - -下面是常用的用法: - -```python -print(round(1)) # 1 -print(round(1.4)) # 1 -print(round(1.5)) # 2 - -print(round(1.5555, 1)) # 1.6 -print(round(1.5555, 2)) # 1.56 - -print(round(1.5555)) # 2 -print(round(1.5555, 0)) # 2.0 -``` - -需要注意的是,`ndigits` 为 `None` 和 `0` 的区别是前缀返回 `int` 类型、后者返回 `float` 类型。 - -## typeof - -`typeof(x: any, full_name: bool = False) -> str` - -输出 `x` 在运算时的类型。当 `full_name` 参数设置为 `True` 时,将返回 `pkg.schema` 形式的包前缀。 - -下面是常见的用法: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person{} -t3 = typeof(_x1) - -_x2 = pkg.Person{} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# 输出 -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -## zip - -`zip(*args: str|list|dict)` - -用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。 - -下面是常见的用法: - -```py -a = zip([0, 1, 2], [3, 4, 5]) -b = zip([0, 1], [3, 4, 5]) -c = zip([0, 1, 2], [3, 4, 5, 6]) - -# 输出 -# a: -# - - 0 -# - 3 -# - - 1 -# - 4 -# - - 2 -# - 5 -# b: -# - - 0 -# - 3 -# - - 1 -# - 4 -# c: -# - - 0 -# - 3 -# - - 1 -# - 4 -# - - 2 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/crypto.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/crypto.md deleted file mode 100644 index cef03352..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/crypto.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "crypto" -linkTitle: "crypto" -type: "docs" -description: crypto 包 - 提供 SHA 相关的哈希函数 -weight: 100 ---- - -## md5 - -`md5(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `MD5` 算法对字符串 `value` 进行加密。 - -## sha1 - -`sha1(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA1` 算法对字符串 `value` 进行加密。 - -## sha224 - -`sha224(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA224` 算法对字符串 `value` 进行加密。 - -## sha256 - -`sha256(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA256` 算法对字符串 `value` 进行加密。 - -## sha384 - -`sha384(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA384` 算法对字符串 `value` 进行加密。 - -## sha512 - -`sha512(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA512` 算法对字符串 `value` 进行加密。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/datetime.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/datetime.md deleted file mode 100644 index 66cb4bca..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/datetime.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: "datetime" -linkTitle: "datetime" -type: "docs" -description: datetime 包 - 时间处理 -weight: 100 ---- - -## time - -`ticks() -> float` - -返回从 1970 年 1 月 1 日 0 时 0 分 0 秒(Epoch)开始到当前时间经过的秒数。如果系统时钟能提供更精确的时间,则秒数后可能会有小数部分。 - -## date - -`date() -> str` - -返回以 `%Y-%m-%d %H:%M:%S` 格式表示的时间。 - -## now - -`now() -> str` - -返回当地时间,例如 `'Sat Jun 06 16:26:11 1998'`。 - -## today - -`today() -> str` - -返回以 `%Y-%m-%d %H:%M:%S.%{ticks}` 格式表示的时间。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/index.md deleted file mode 100644 index c1f4b4a0..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# 系统模块 - -KCL 通过系统模块、用户模块和插件模块提供工程化的扩展能力。本节介绍系统模块的基本概念,插件模块可以参考插件系统。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/json.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/json.md deleted file mode 100644 index b19bdc88..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/json.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: "json" -linkTitle: "json" -type: "docs" -description: JSON 编码解码 -weight: 100 ---- - -## encode - -``` -encode( - data: any, - sort_keys: bool = False, - indent: int = None, - ignore_private: bool = False, - ignore_none: bool = False -) -> str -``` - -将 KCL 对象 `data` 序列化为 JSON 格式的字符串。 - -## decode - -`decode(value: str) -> any` - -反序列化 `value`(一个包含 JSON 格式文档的字符串实例)为一个 KCL 对象。 - -## dump_to_file - -``` -dump_to_file( - data: any, - filename: str, - ignore_private: bool = False, - ignore_none: bool = False -) -> None -``` - -将 KCL 对象 `data` 序列化为 JSON 格式的字符串,并将其写入文件 `filename` 中。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/manifests.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/manifests.md deleted file mode 100644 index 5c54e9c7..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/manifests.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: "manifests" -linkTitle: "manifests" -type: "docs" -description: manifests system module -weight: 100 ---- - -## yaml_stream - -```python -yaml_stream(values: [any], opts: {str:} = { - sort_keys = False - ignore_private = True - ignore_none = False - sep = "---" -}) -``` - -这个函数的功能是将 KCL 对象列表序列化为带 `---` 分隔符的样式 YAML 输出,它具有两个参数: - -- `values` - 一个 KCL 对象列表 -- `opts` - YAML 序列化选项 - - `sort_keys`:是否按属性名称的字典序对序列化结果进行排序(默认为 `False`)。 - - `ignore_private`:是否忽略名称以 `_` 开头的属性序列化输出(默认为 `True`)。 - - `ignore_none`:是否忽略值为 `None` 的属性(默认为 `False`)。 - - `sep`:在多个 YAML 文档之间选择怎样的分隔符(默认为 `"---"`)。 - -下面我们通过一个例子来说明: - -```python -# 使用 `import` 关键词导入 `manifests` 模块 -import manifests - -# `Deployment` schema 定义 -schema Deployment: - apiVersion: str = "v1" - kind: str = "Deployment" - metadata: {str:} = { - name = "deploy" - } - spec: {str:} = { - replica = 2 - } - -# `Service` schema 定义 -schema Service: - apiVersion: str = "v1" - kind: str = "Service" - metadata: {str:} = { - name = "svc" - } - spec: {str:} = {} - -# 定义两个 `Deployment` 资源 -deployments = [Deployment {}, Deployment {}] -# 定义两个 `Service` 资源 -services = [Service {}, Service {}] -# 将它们放入 KCL 列表,并调用 `manifests.yaml_stream` 函数。 -manifests.yaml_stream(deployments + services) -``` - -首先我们通过 `import` 关键字导入 `manifests` 模块并定义 2 个 Deployment 以及 2 个 Service 资源,当我们想以 YAML stream 并以 `---` 作为分隔符的格式依次输出这 4 个资源时,我们可以将它们合并为一个 KCL 列表并作为 `manifests.yaml_stream` 函数的 `values` 形参进行传入 (如无特殊需求,opts 参数一般使用默认值即可),最终得到 YAML 输出为: - -```yaml -apiVersion: v1 -kind: Deployment -metadata: - name: deploy -spec: - replica: 2 ---- -apiVersion: v1 -kind: Deployment -metadata: - name: deploy -spec: - replica: 2 ---- -apiVersion: v1 -kind: Service -metadata: - name: svc ---- -apiVersion: v1 -kind: Service -metadata: - name: svc -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/math.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/math.md deleted file mode 100644 index 3b2ff0cc..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/math.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: "math" -linkTitle: "math" -type: "docs" -description: math 包 - 数学函数 -weight: 100 ---- - -## ceil - -`ceil(x) -> int` - -返回 `x` 向上取整得到的整数,这是大于等于 `x` 的最小整数。 - -## factorial - -`factorial(x) -> int` - -返回 `x` 的阶乘(即 `x!`),如果 `x` 是负数或者不是整数,则会引发一个错误。 - -## floor - -`floor(x) -> int` - -返回 `x` 向下取整得到的整数,这是小于等于 `x` 的最大整数。 - -## gcd - -`gcd(a: int, b: int) -> int` - -返回 `x` 和 `y` 的最大公约数。 - -## isfinite - -`isfinite(x) -> bool` - -如果 `x` 既不是无穷大也不是 `NaN` 返回 `True`,否则返回 `False`。 - -## isinf - -`isinf(x) -> bool` - -如果 `x` 是正无穷或负无穷返回 `True`,否则返回 `False`。 - -## isnan - -`isnan(x) -> bool` - -如果 `x` 是 `NaN` 返回 `True`,否则返回 `False`。 - -## modf - -`modf(x) -> List[float, float]` - -返回 `x` 的整数和小数部分,两个结果均与 `x` 的正负号相同,并且均为浮点数。 - -## exp - -`exp(x) -> float` - -返回以 `e` 为底数, `x` 的幂。 - -## expm1 - -`expm1(x) -> float` - -返回 `e` 的 `x` 次方减去 1,该函数能够避免由于直接计算 `exp(x) - 1` 而引起的精度损失。 - -## log - -`log(x, base=2.71828182845904523536028747135266250) -> float` - -返回以 `e` 为底数,`x` 的对数。 - -## log1p - -`log1p(x) -> float` - -返回以 `e` 为底数,`1 + x` 的自然对数,该函数能够在 `x` 靠近 0 时精确计算结果。 - -## log2 - -`log2(x) -> float` - -返回 `x` 的以 2 为底的对数。 - -## log10 - -`log10(x) -> float` - -返回 `x` 的以 10 为底的对数。 - -## pow - -`pow(x, y) -> float` - -返回 `x` 的 `y` 次幂(即 `x` 的 `y` 次方)。 - -## sqrt - -`sqrt(x) -> float` - -返回 `x` 的平方根。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/net.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/net.md deleted file mode 100644 index 1050d16d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/net.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: "net" -linkTitle: "net" -type: "docs" -description: net 包 - 网络IP处理 -weight: 100 ---- - -## split_host_port - -`split_host_port(ip_end_point: str) -> List[str]` - -从 `ip_end_point` 分离出 `host` 和 `port`。 - -## join_host_port - -`join_host_port(host, port) -> str` - -合并 `host` 和 `port`。 - -## fqdn - -`fqdn(name: str = '') -> str` - -返回完全限定域名(FQDN)。 - -## parse_IP - -`parse_IP(ip) -> str` - -将 `ip` 解析为真实的 IP 地址。 - -## to_IP4 - -`to_IP4(ip) -> str` - -获取 `ip` 的 IPv4 表示形式。 - -## to_IP16 - -`to_IP16(ip) -> int` - -获取 `ip` 的 IPv6 表示形式。 - -## IP_string - -`IP_string(ip: str | int) -> str` - -返回 IP 字符串。 - -## is_IPv4 - -`is_IPv4(ip: str) -> bool` - -判断 `ip` 是否为 IPv4。 - -## is_IP - -`is_IP(ip: str) -> bool` - -判断 `ip` 是否为有效的 IP 地址。 - -## is_loopback_IP - -`is_loopback_IP(ip: str) -> bool` - -判断 `ip` 是否为回环地址。 - -## is_multicast_IP - -`is_multicast_IP(ip: str) -> bool` - -判断 `ip` 是否为组播地址。 - -## is_interface_local_multicast_IP - -`is_interface_local_multicast_IP(ip: str) -> bool` - -判断 `ip` 是否为接口、本地和组播地址。 - -## is_link_local_multicast_IP - -`is_link_local_multicast_IP(ip: str) -> bool` - -判断 `ip` 是否为链路本地和组播地址。 - -## is_link_local_unicast_IP - -`is_link_local_unicast_IP(ip: str) -> bool` - -判断 `ip` 是否为链路本地和单播地址。 - -## is_global_unicast_IP - -`is_global_unicast_IP(ip: str) -> bool` - -判断 `ip` 是否为全局单播地址。 - -## is_unspecified_IP - -`is_unspecified_IP(ip: str) -> bool` - -判断 `ip` 是否为 `unspecified` 地址。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/overview.md deleted file mode 100644 index aa3eaeb3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/overview.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -sidebar_position: 0 ---- - -# 概览 - -KCL 是面向配置的编程语言,通过内置模块、KCL 模块和插件模块提供工程化的扩展能力。 - -![](/img/docs/reference/lang/model/kcl-module.png) - -用户代码中不用导入直接使用 builtin 的函数(比如用 `len` 计算列表的长度、通过 `typeof` 获取值的类型等),而对于字符串等基础类型也提供了一些内置方法(比如转化字符串的大小写等方法)。对于相对复杂的通用工作则通过标准库提供,比如通过 import 导入 `math` 库就可以使用相关的数学函数,可以通过导入 `regex` 库使用正则表达式库。而针对 KCL 代码也可以组织为模块,比如 Konfig 大库中将基础设施和各种标准的应用抽象为模块供上层用户使用。此外还可以通过 Plugin 机制,采用 Python 为 KCL 开发插件,比如目前有 meta 插件可以通过网络查询中心配置信息,`app-context` 插件则可以用于获取当前应用的上下文信息从而简化代码的编写。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/regex.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/regex.md deleted file mode 100644 index e7b0c25c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/regex.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "regex" -linkTitle: "regex" -type: "docs" -description: regex 包 - 正则表达式 -weight: 100 ---- - -## replace - -`replace(string: str, pattern: str, replace: str, count=0) -> str` - -替换字符串 `string`中最左边、不重叠并且匹配模式 `pattern` 的部分替换为指定的字符串 `replace`,并返回替换后的字符串 - -## match - -`match(string: str, pattern: str) -> bool` - -尝试在字符串开头应用模式 `pattern`,找到了任何匹配项则返回 `True`,返回 `False` 表示没有找到匹配项 - -## compile - -`compile(pattern: str) -> bool` - -编译正则表达式模式 `pattern`,并返回一个布尔值,表示该模式是否有效 - -## findall - -`findall(string: str, pattern: str) -> List[str]` - -查找 `pattern` 在 `string` 中的所有非重叠匹配,并以字符串列表的形式返回 - -## search - -`search(string: str, pattern: str) -> bool` - -扫描字符串 `string` 以查找与模式匹配的项,如果找到任何匹配项,则返回布尔值 `True`,否则返回 `False` - -## split - -`split(string: str, pattern: str, maxsplit=0) -> List[str]` - -返回一个由字符串内单词组成的列表,使用 `pattern` 作为分隔字符串,最多进行 `maxsplit` 次拆分 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/units.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/units.md deleted file mode 100644 index 8c862d0e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/units.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: "units" -linkTitle: "units" -type: "docs" -description: units 包 - 单位处理 -weight: 100 ---- - -## 单位的常量 - -- 定点数: `n`, `u`, `m`, `k`, `K`, `G`, `T` 和 `P`. -- 2 的幂: `Ki`, `Mi`, `Gi`, `Ti` 和 `Pi`. - -## 函数列表 - -- `to_n(num: int) -> str` - 将 int 转换为以 `n` 作为后缀的字符串 -- `to_u(num: int) -> str` - 将 int 转换为以 `u` 作为后缀的字符串 -- `to_m(num: int) -> str` - 将 int 转换为以 `m` 作为后缀的字符串 -- `to_K(num: int) -> str` - 将 int 转换为以 `K` 作为后缀的字符串 -- `to_M(num: int) -> str` - 将 int 转换为以 `M` 作为后缀的字符串 -- `to_G(num: int) -> str` - 将 int 转换为以 `G` 作为后缀的字符串 -- `to_T(num: int) -> str` - 将 int 转换为以 `T` 作为后缀的字符串 -- `to_P(num: int) -> str` - 将 int 转换为以 `P` 作为后缀的字符串 -- `to_Ki(num: int) -> str` - 将 int 转换为以 `Ki` 作为后缀的字符串 -- `to_Mi(num: int) -> str` - 将 int 转换为以 `Mi` 作为后缀的字符串 -- `to_Gi(num: int) -> str` - 将 int 转换为以 `Gi` 作为后缀的字符串 -- `to_Ti(num: int) -> str` - 将 int 转换为以 `Ti` 作为后缀的字符串 -- `to_Pi(num: int) -> str` - 将 int 转换为以 `Pi` 作为后缀的字符串 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/yaml.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/yaml.md deleted file mode 100644 index e0faf129..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/model/yaml.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: "yaml" -linkTitle: "yaml" -type: "docs" -description: yaml 编码解码 -weight: 300 ---- - -## encode - -``` -encode( - data: any, - sort_keys: bool = False, - ignore_private: bool = False, - ignore_none: bool = False -) -> str -``` - -将 KCL 对象 `data` 序列化为 YAML 格式的字符串。 - -## decode - -`decode(value: str) -> any` - -反序列化 `value`(一个包含 YAML 格式文档的字符串实例)为一个 KCL 对象。 - -## dump_to_file - -``` -dump_to_file( - data: any, - filename: str, - ignore_private: bool = False, - ignore_none: bool = False -) -> None -``` - -将 KCL 对象 `data` 序列化为 YAML 格式的字符串,并将其写入文件 `filename` 中。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/_category_.json deleted file mode 100644 index edfe989e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "包管理", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/1.init.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/1.init.md deleted file mode 100644 index 0bfc0303..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/1.init.md +++ /dev/null @@ -1,45 +0,0 @@ -# kpm init - -初始化一个 kcl 包。 - -## 使用 - -```shell -kpm init [options][package_name] -``` - -## 介绍 - -`kpm init` 会在当前目录初始化一个 kcl 包。如果没有提供包名,会使用当前目录的名字作为包名。 - -如果提供了包名,会在当前目录下创建一个以包名命名的子目录,并在该目录下初始化 kcl 包。 - -`kpm init` 会在包目录下创建 `kcl.mod`、`kcl.mod.lock` 和 `main.k`。 - -## 选线 - -### --help, -h - -显示帮助信息。 - -## 示例 - -### 初始化当前目录为 kcl 包 - -```shell -# 创建一个目录 -$ mkdir my_package - -# 进入目录 -$ cd my_package - -# 初始化当前目录为 kcl 包 -$ kpm init -``` - -### 初始化一个名为 my_package 的 kcl 包 - -```shell -# 初始化一个名为 my_package 的 kcl 包 -kpm init my_package -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/10.help.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/10.help.md deleted file mode 100644 index 0fd9fa3a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/10.help.md +++ /dev/null @@ -1,21 +0,0 @@ -# kpm help - -输出 kpm 命令的帮助信息。 - -## 使用 - -```shell -kpm help -``` - -## 介绍 - -`kpm help` 会输出 kpm 命令的帮助信息。 - -## 示例 - -使用 `kpm help` 输出 kpm 命令的帮助信息。 - -```shell -kpm help -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/2.add.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/2.add.md deleted file mode 100644 index 09fd5d46..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/2.add.md +++ /dev/null @@ -1,53 +0,0 @@ -# kpm add - -添加一个依赖到 kcl 包。 - -## 使用 - -```shell -kpm add [options][package_reference] -``` - -## 介绍 - -`kpm add` 会添加一个依赖到 kcl 包。依赖可以来自 git 仓库,或者 kcl registry。 - -`package_reference` 是一个 kcl 包引用,格式为 `package_name:version`。 - -## 选项 - -### --git - -指定依赖来自 git 仓库的 git url。 - -### --tag - -指定依赖来自 git 仓库的 tag。 - -### --help, -h - -显示帮助信息。 - -## 示例 - -### 添加一个来自 kcl registry 的依赖 - -添加一个名为 `k8s` 的依赖,版本为最新版本。 - -```shell -kpm add k8s -``` - -添加一个名为 `k8s` 的依赖,版本为 `v1.27.2`。 - -```shell -kpm add k8s:v1.27.2 -``` - -### 添加一个来自 git 仓库的依赖 - -添加一个来自 git 仓库的 kcl 包依赖,tag 为 v0.1.0 - -```shell -kpm add --git https://github.com/awesome-kusion/konfig.git --tag v0.1.0 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/3.pkg.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/3.pkg.md deleted file mode 100644 index fd708d03..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/3.pkg.md +++ /dev/null @@ -1,33 +0,0 @@ -# kpm pkg - -打包一个 kcl 包。 - -## 使用 - -```shell -kpm pkg [options] -``` - -## 介绍 - -`kpm pkg` 会打包一个 kcl 包为 `*.tar`。 - -选项 `--target` 用于指定打包后的 `*.tar` 文件路径。 - -## 选项 - -### --target - -指定打包后的 `*.tar` 文件路径。 - -### --help, -h - -显示帮助信息。 - -## 示例 - -### 打包当前 kcl 包为 `*.tar` - -```shell -kpm pkg --target /Users/my_package_tar -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/4.metadata.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/4.metadata.md deleted file mode 100644 index 199ebd2e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/4.metadata.md +++ /dev/null @@ -1,41 +0,0 @@ -# kpm metadata - -打印 kcl 包的元数据。 - -## 使用 - -```shell -kpm metadata [options] -``` - -## 介绍 - -`kpm metadata` 会打印 kcl 包的元数据。元数据包括包的依赖信息。 - -`--update` 选项用于自动下载缺失的依赖包。 - -## 选项 - -### --update - -自动下载缺失的依赖包。 - -### --help, -h - -展示 `kpm metadata` 命令的帮助信息。 - -## 示例 - -### 打印 kcl 包的元数据 - -打印 kcl 包的元数据。 - -```shell -kpm metadata -``` - -打印 kcl 包的元数据,并自动下载缺失的依赖包。 - -```shell -kpm metadata --update -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/5.run.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/5.run.md deleted file mode 100644 index eee83e08..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/5.run.md +++ /dev/null @@ -1,69 +0,0 @@ -# kpm run - -编译一个 kcl 包。 - -## 使用 - -```shell -kpm run [options][package_source] -``` - -## 介绍 - -`kpm run` 会编译一个 kcl 包。 - -## 选项 - -### --input - -指定包的入口文件路径。 - -### --tag - -指定 oci url 的包的 tag。 - -### --vendor - -`--vendor` 选项会将依赖包移动到当前包,并自动下载缺失的依赖包。 - -### --kcl_args - -`--kcl_args` 描述了传递给 kcl 编译器的参数。 - -### --help, -h - -展示 `kpm run` 命令的帮助信息。 - -## 示例 - -### 编译当前 kcl 包 - -在 kcl 包目录下,`kpm run` 可以用于编译当前 kcl 包。 - -```shell -kpm run -``` - -### 编译一个 kcl 包 tar 文件 - -`kpm run` 可以用于编译一个 kcl 包 tar 文件。 - -```shell -kpm run /Users/demo/my_package.tar -``` - -### 编译一个 kcl 包来自 oci url - -`kpm run` 可以用于编译一个 kcl 包从 oci url。 - -```shell -kpm run --tag 0.0.1 oci://localhost:5001/test/my_package -``` - -### 编译一个 kcl 包来自 oci ref - -`kpm run` 可以用于编译一个 kcl 包从 oci ref。 - -```shell -kpm run test/my_package:0.0.1 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/6.login.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/6.login.md deleted file mode 100644 index 9055d8fb..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/6.login.md +++ /dev/null @@ -1,68 +0,0 @@ -# kpm login - -登陆 kpm registry. - -## 使用 - -```shell -kpm login [options][kpm_registry] -``` - -## 介绍 - -`kpm login` 将会登陆 kpm registry。 - -## 选项 - -### --username, -u - -指定 kpm registry 的用户名。 - -### --password, -p - -指定 kpm registry 的密码。 - -### --help, -h - -展示 `kpm login` 命令的帮助信息。 - -## 示例 - -### 登陆到 kpm registry, 通过参数输入用户名和密码 - -```shell -kpm login -u -p -``` - -期望输出为 - -```shell -Login succeeded -``` - -### 登陆到 kpm registry, 通过参数输入用户名,密码通过交互式输入 - -```shell -kpm login -u -``` - -期望输出为 - -```shell -Password: -Login succeeded -``` - -### 登陆到 kpm registry, 用户名和密码通过交互式输入 - -```shell -kpm login -``` - -期望输出为 - -```shell -Username: -Password: -Login succeeded -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/7.logout.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/7.logout.md deleted file mode 100644 index 65dd317e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/7.logout.md +++ /dev/null @@ -1,27 +0,0 @@ -# kpm logout - -从 kpm registry 登出。 - -## 使用 - -```shell -kpm logout [options][kpm_registry] -``` - -## 介绍 - -`kpm logout` 会从 kpm registry 登出。 - -## 选项 - -### --help, -h - -展示 `kpm logout` 命令的帮助信息。 - -## 示例 - -### 从 kpm registry 登出 - -```shell -kpm logout -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/8.push.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/8.push.md deleted file mode 100644 index 53c2e520..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/8.push.md +++ /dev/null @@ -1,46 +0,0 @@ -# kpm push - -上传一个 kcl 包到 kpm registry。 - -## 使用 - -```shell -kpm push [options][kpm_registry] -``` - -## 介绍 - -`kpm push` 将会上传一个 kcl 包到 kpm registry。 - -## 选项 - -### --tar_path - -指定上传的 `*.tar` 文件路径。 - -### --help, -h - -展示 `kpm push` 命令的帮助信息。 - -## 示例 - -### 上传当前 kcl 包到 kpm registry - -你可以在 kcl 包的根目录下使用 `kpm push` 命令上传一个 kcl 包到 kpm registry。 - -```shell -# 创建一个 kcl 包 -$ kpm init -# 进入 kcl 包目录 -$ cd -# 上传 kcl 包到 kpm registry -$ kpm push -``` - -### 上传一个 `*.tar` 文件到 kpm registry - -你也可以使用 `kpm push` 命令上传一个 `*.tar` 文件到 kpm registry。 - -```shell -kpm push --tar_path -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/9.pull.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/9.pull.md deleted file mode 100644 index cec49291..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/9.pull.md +++ /dev/null @@ -1,41 +0,0 @@ -# kpm pull - -下载 kcl 包从 kpm registry。 - -## 使用 - -```shell -kpm pull [options][package_source] -``` - -## 介绍 - -`kpm pull` 会从 kpm registry 下载 kcl 包。 - -## 选项 - -### --tag - -使用 oci url 下载包时, 指定要下载的 kcl 包的 tag。 - -### --help, -h - -展示 `kpm pull` 命令的帮助信息。 - -## 示例 - -### 从 kpm registry 下载 kcl 包 - -你可以使用 `kpm pull` 命令从 默认的 kpm registry 下载 kcl 包。 - -```shell -kpm pull : -``` - -### 下载 kcl 包通过 oci url - -你可以使用 `kpm pull` 命令从一个 oci url 下载 kcl 包。 - -```shell -kpm pull --tag -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/_category_.json deleted file mode 100644 index abcc956a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "命令参考", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/index.md deleted file mode 100644 index e3025db9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/package-management/command-reference/index.md +++ /dev/null @@ -1,36 +0,0 @@ -# kpm - -kpm 命令。 - -## 使用 - -```shell -kpm [arguments]... -``` - -## 介绍 - -`kpm` 是 kcl 包管理工具。它用于分发和管理 kcl 包。 - -## 选项 - -### --help, -h - -展示 `kpm` 命令的帮助信息。 - -### --version, -v - -展示 `kpm` 命令的版本信息。 - -## 子命令 - -- [kpm init](./1.init.md) - 初始化一个 kcl 包 -- [kpm add](./2.add.md) - 添加一个依赖到 kcl 包 -- [kpm pkg](./3.pkg.md) - 打包一个 kcl 包为 `*.tar` -- [kpm metadata](./4.metadata.md) - 打印一个 kcl 包的元数据 -- [kpm run](./5.run.md) - 编译一个 kcl 包为 yaml 并运行 -- [kpm login](./6.login.md) - 登录到一个 kcl registry -- [kpm logout](./7.logout.md) - 登出一个 kcl registry -- [kpm push](./8.push.md) - 上传一个 kcl 包到一个 registry -- [kpm pull](./9.pull.md) - 下载一个 kcl 包从一个 registry -- [kpm help](./10.help.md) - 打印 kpm 命令的帮助信息 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/plugin/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/plugin/_category_.json deleted file mode 100644 index 645deb88..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/plugin/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "插件系统", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/plugin/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/plugin/index.md deleted file mode 100644 index e2fe86d6..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/plugin/index.md +++ /dev/null @@ -1 +0,0 @@ -# 插件系统 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/plugin/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/plugin/overview.md deleted file mode 100644 index b3cc9469..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/plugin/overview.md +++ /dev/null @@ -1,183 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 简介 - -KCL 是声明式配置策略语言,对于不方便通过配置直接描述的复杂的业务逻辑可以通过通用的编程语言开发 KCL 插件对语言进行扩展。KCL 支持通过通用语言开发插件,KCL 程序导入插件中的函数。KCL 通过插件运行时和辅助的命令行工具提供插件支持。KCL 插件框架支持多种不同的通用语言开发插件,这里我们以 Python 为例简单说明插件的使用。 - -插件的 Git 仓库: [https://github.com/kcl-lang/kcl-plugin](https://github.com/kcl-lang/kcl-plugin) - -## 0. 前置依赖 - -使用 KCL Python 插件需要您的 `PATH` 中存在 `Python3.7+`。 - -## 1. 你好插件 - -KCL 插件在 KCL 的 `plugins` 子目录(通常安装在 `$HOME/.kcl/plugins` 目录),或者通过 `$KCL_PLUGINS_ROOT` 环境变量设置(环境变量优先级更高)。此外,`plugins` 插件目录还可以放在执行 KCL 命令的 `pwd` 路径或者父路径中。对于插件开发人员,插件都在 Git 仓库管理: [https://github.com/kcl-lang/kcl-plugin](https://github.com/kcl-lang/kcl-plugin) ,可以将插件仓库克隆到该目录进行开发。 - -输入 `kcl-plugin info` 命令查看查看插件目录(将其中的 `/Users/kcl_user` 替换成本地的 `$HOME` 路径): - -```shell -$ kcl-plugin info -# plugin_root: /Users/kcl_user/.kcl/plugins -``` - -通过 `kcl-plugin list` 子命令查看插件列表: - -```shell -$ kcl-plugin list -hello: hello doc - 0.0.1 -``` - -其中 `hello` 是 KCL 内置的示例插件(不要修改改插件)。 - -在 KCL 代码中,可以通过 `kcl_plugin.hello` 导入 `hello` 插件。`main.k` 代码如下: - -```python -import kcl_plugin.hello - -name = "kcl" -three = hello.add(1,2) -``` - -输出结果如下: - -```shell -$ python3 -m kclvm main.k -name: kcl -three: 3 -``` - -## 2. `kcl-plugin` 辅助命令 - -`kcl-plugin` 是提供的插件辅助工具,命令行帮助如下: - -```shell -$ kcl-plugin -usage: kcl-plugin [-h] {list,info,init,gendoc,test} ... -positional arguments: - {list,info,init,gendoc,test} - kcl plugin sub commands - list list all plugins - info show plugin document - init init a new plugin - gendoc gen all plugins document - test test plugin -optional arguments: - -h, --help show this help message and exit -``` - -其中 `list` 子命令用于查看插件列表;`info` 用户查看插件目录和每个插件的信息;`init` 可以用户初始化新插件;`gendoc` 更新全部插件的 API 文档;`test` 测试指定的插件。 - -## 3. 插件信息和文档 - -输入 `kcl-plugin info hello` 查看 `hello` 插件信息: - -```shell -$ kcl-plugin info hello -{ - "name": "hello", - "describe": "hello doc", - "long_describe": "long describe", - "version": "0.0.1", - "method": { - "add": "add two numbers, and return result", - "foo": "no doc", - "list_append": "no doc", - "say_hello": "no doc", - "tolower": "no doc", - "update_dict": "no doc" - } -} -``` - -插件的信息主要包含插件的名字和版本信息,插件提供的函数信息。该信息和插件目录中自动生成的 `api.md` 文件是一致的(插件 API 变化时通过 `kcl-plugin gendoc` 为全部的插件重新生成 `api.md` 文件)。 - -## 4. 插件的目录结构 - -插件的目录结构如下(将其中的 `/Users/kcl_user` 替换成本地的 `$HOME` 路径): - -```shell -$ tree /Users/kcl_user/.kcl/plugins/ -/Users/kcl_user/.kcl/plugins/ -├── _examples -├── _test -└── hello - ├── api.md - ├── plugin.py - └── plugin_test.py -$ -``` - -其中 `_examples` 目录下是插件的示例代码,`_test` 目录下是插件的 KCL 测试代码,其他以字母开头的目录是普通的插件(目录中同时包含 `plugin.py` 和 `plugin_test.py` 文件)。 - -KCL 的插件是有一个独立的纯 Python 代码文件实现,并且插件相互之间不能直接调用。插件的内容如下: - -```shell -$ cat ./hello/plugin.py -# Copyright 2020 The KCL Authors. All rights reserved. -INFO = { - 'name': 'hello', - 'describe': 'hello doc', - 'long_describe': 'long describe', - 'version': '0.0.1', -} -def add(a: int, b: int) -> int: - """add two numbers, and return result""" - return a + b -... -``` - -其中 `INFO` 指明了插件的名字、概要说明、详细说明和版本信息。而所有名字以字母开头的函数是插件给 KCL 提供的函数,因此 KCL 中可以直接调用 `add` 函数。 - -## 5. 创建一个插件 - -通过 `kcl-plugin init` 命令可以创建一个插件示例: - -``` -$ kcl-plugin init hi -$ kcl-plugin list -hello: hello doc - 0.0.1 -hi: hi doc - 0.0.1 -``` - -`kcl-plugin init` 命令会以内置的模板构造一个新的插件,然后通过 `kcl-plugin list` 命令可以查看到新创建的插件。 - -## 6. 插件的删除 - -KCL 插件在 KCL 的 `plugins` 子目录(通常安装在 `$HOME/.kcl/plugins` 目录)。 -可以通过命令 `kcl-plugin info` 查询插件安装目录。 - -```shell -$ kcl-plugin info -/Users/kcl_user/.kcl/plugins/ -$ tree /Users/kcl_user/.kcl/plugins/ -/Users/kcl_user/.kcl/plugins/ -├── _examples -├── _test -└── hello -- 删除这个目录就可以删除 hello plugin - ├── api.md - ├── plugin.py - └── plugin_test.py -$ -``` - -## 7. 插件的测试 - -插件是独立的纯 Python 文件实现,插件目录下有个 `plugin_test.py` 文件是插件的单元测试文件(基于 pytest 测试框架)。此外在 `_test` 目录下放置的是 KCL 文件的插件集成测试。`plugin_test.py` 单元测试是必须的,`_test` 目录下的 KCL 集成测试可以根据情况添加。 - -可以通过 `kcl-plugin test` 执行插件的单元测试: - -```shell -$ kcl-plugin test hello -============================= test session starts ============================== -platform darwin -- Python 3.7.6+, pytest-5.3.5, py-1.9.0, pluggy-0.13.1 -rootdir: /Users/kcl_user -collected 5 items -.kcl/plugins/hello/plugin_test.py ..... [100%] -============================== 5 passed in 0.03s =============================== -$ -``` - -集成测试可以通过在 `_test` 目录下执行 `python3 -m pytest` 命令进行测试。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/_category_.json deleted file mode 100644 index e26f646c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "多语言", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/go-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/go-api.md deleted file mode 100644 index 2a978250..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/go-api.md +++ /dev/null @@ -1,665 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Go API - -```go -import kcl "kcl-lang.io/kcl-go" -``` - -## KCL Go SDK - -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ kcl files │ │ KCL-Go-API │ │ KCLResultList │ -│ ┌───────────┐ │ │ │ │ │ -│ │ 1.k │ │ │ │ │ │ -│ └───────────┘ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ ┌───────────┐ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.Get("a.b.c") │ -│ │ 2.k │ │ │ │ Run(path) │ │ │ └───────────┘ │ └───────────────┘ -│ └───────────┘ │────┐ │ └───────────┘ │ │ │ -│ ┌───────────┐ │ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ │ 3.k │ │ │ │ │ │ │ KCLResult │──┼────────▶│x.Get("k", &v) │ -│ └───────────┘ │ │ │ │ │ └───────────┘ │ └───────────────┘ -│ ┌───────────┐ │ ├───▶│ ┌───────────┐ │──────────▶│ │ -│ │setting.yml│ │ │ │ │RunFiles() │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ └───────────┘ │ │ │ └───────────┘ │ │ │ KCLResult │──┼────────▶│x.JSONString() │ -└─────────────────┘ │ │ │ │ └───────────┘ │ └───────────────┘ - │ │ │ │ │ -┌─────────────────┐ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ Options │ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.YAMLString() │ -│WithOptions │ │ │ │MustRun() │ │ │ └───────────┘ │ └───────────────┘ -│WithOverrides │────┘ │ └───────────┘ │ │ │ -│WithWorkDir │ │ │ │ │ -│WithDisableNone │ │ │ │ │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ -``` - -
Example -

- -```go -{ - const k_code = ` -name = "kcl" -age = 1 - -two = 2 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {} -x1 = Person { - age = 101 -} -` - - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First().YAMLString() - fmt.Println(yaml) - - fmt.Println("----") - - result := kcl.MustRun("./testdata/main.k").First() - fmt.Println(result.JSONString()) - - fmt.Println("----") - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - - fmt.Println("----") - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x1", &person)) -} -``` - -

-
- -## Index - -- [Go API](#go-api) - - [KCL Go SDK](#kcl-go-sdk) - - [Index](#index) - - [Constants](#constants) - - [func FormatCode](#func-formatcode) - - [func FormatPath](#func-formatpath) - - [func InitKclvmPath](#func-initkclvmpath) - - [func InitKclvmRuntime](#func-initkclvmruntime) - - [func LintPath](#func-lintpath) - - [func ListDepFiles](#func-listdepfiles) - - [func ListDownStreamFiles](#func-listdownstreamfiles) - - [func ListUpStreamFiles](#func-listupstreamfiles) - - [func OverrideFile](#func-overridefile) - - [func ValidateCode](#func-validatecode) - - [type KCLResult](#type-kclresult) - - [type KCLResultList](#type-kclresultlist) - - [func MustRun](#func-mustrun) - - [func Run](#func-run) - - [func RunFiles](#func-runfiles) - - [type KclType](#type-kcltype) - - [func GetSchemaType](#func-getschematype) - - [type ListDepFilesOption](#type-listdepfilesoption) - - [type ListDepsOptions](#type-listdepsoptions) - - [type Option](#type-option) - - [func WithCode](#func-withcode) - - [func WithDisableNone](#func-withdisablenone) - - [func WithKFilenames](#func-withkfilenames) - - [func WithOptions](#func-withoptions) - - [func WithOverrides](#func-withoverrides) - - [func WithPrintOverridesAST](#func-withprintoverridesast) - - [func WithSettings](#func-withsettings) - - [func WithSortKeys](#func-withsortkeys) - - [func WithWorkDir](#func-withworkdir) - - [type ValidateOptions](#type-validateoptions) - -## Constants - -KclvmAbiVersion is the current kclvm ABI version. - -```go -const KclvmAbiVersion = scripts.KclvmAbiVersion -``` - -## func [FormatCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L110) - -```go -func FormatCode(code interface{}) ([]byte, error) -``` - -FormatCode returns the formatted code. - -
Example -

- -```go -{ - out, err := kcl.FormatCode(`a = 1+2`) - if err != nil { - log.Fatal(err) - } - fmt.Println(string(out)) - -} -``` - -``` -a = 1 + 2 -``` - -

-
- -## func [FormatPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L122) - -```go -func FormatPath(path string) (changedPaths []string, err error) -``` - -FormatPath formats files from the given path path: if path is \`.\` or empty string, all KCL files in current directory will be formatted, not recursively if path is \`path/file.k\`, the specified KCL file will be formatted if path is \`path/to/dir\`, all KCL files in the specified dir will be formatted, not recursively if path is \`path/to/dir/...\`, all KCL files in the specified dir will be formatted recursively - -the returned changedPaths are the changed file paths \(relative path\) - -
Example -

- -```go -{ - changedPaths, err := kcl.FormatPath("testdata/fmt") - if err != nil { - log.Fatal(err) - } - fmt.Println(changedPaths) -} -``` - -

-
- -## func [InitKclvmPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L54) - -```go -func InitKclvmPath(kclvmRoot string) -``` - -InitKclvmPath init kclvm path. - -## func [InitKclvmRuntime](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L59) - -```go -func InitKclvmRuntime(n int) -``` - -InitKclvmRuntime init kclvm process. - -## func [LintPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L142) - -```go -func LintPath(paths []string) (results []string, err error) -``` - -LintPath lint files from the given path - -
Example -

- -```go -{ - - results, err := kcl.LintPath([]string{"testdata/lint/import.k"}) - if err != nil { - log.Fatal(err) - } - for _, s := range results { - fmt.Println(s) - } - -} -``` - -``` -Module 'a' is reimported multiple times -Module 'a' imported but unused -``` - -

-
- -## func [ListDepFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L127) - -```go -func ListDepFiles(workDir string, opt *ListDepFilesOption) (files []string, err error) -``` - -ListDepFiles return the depend files from the given path - -## func [ListDownStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L137) - -```go -func ListDownStreamFiles(workDir string, opt *ListDepsOptions) ([]string, error) -``` - -ListDownStreamFiles return a list of downstream depend files from the given changed path list. - -## func [ListUpStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L132) - -```go -func ListUpStreamFiles(workDir string, opt *ListDepsOptions) (deps []string, err error) -``` - -ListUpStreamFiles return a list of upstream depend files from the given path list - -## func [OverrideFile](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L154) - -```go -func OverrideFile(file string, specs, importPaths []string) (bool, error) -``` - -OverrideFile rewrites a file with override spec file: string. The File that need to be overridden specs: \[\]string. List of specs that need to be overridden. - -``` -Each spec string satisfies the form: := or :- -When the pkgpath is '__main__', it can be omitted. -``` - -importPaths. List of import statements that need to be added - -## func [ValidateCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L159) - -```go -func ValidateCode(data, code string, opt *ValidateOptions) (ok bool, err error) -``` - -ValidateCode validate data match code - -## type [KCLResult](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L47) - -```go -type KCLResult = kcl.KCLResult -``` - -
Example -

- -```go -{ - const k_code = ` -name = "kcl" -age = 1 - -two = 2 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {name = "kcl-go"} -x1 = Person {age = 101} -` - - result := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First() - - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - -} -``` - -``` -x0.name: kcl-go -x1.age: 101 -``` - -

-
- -
Example ('et_struct) -

- -```go -{ - const k_code = ` -schema Person: - name: str = "kcl" - age: int = 1 - X: int = 2 - -x = { - "a": Person {age = 101} - "b": 123 -} -` - - result := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First() - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x.a", &person)) - fmt.Printf("person: %+v\n", person) - -} -``` - -``` -person: &{Name:kcl Age:101} -person: {Name:kcl Age:101} -``` - -

-
- -## type [KCLResultList](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L48) - -```go -type KCLResultList = kcl.KCLResultList -``` - -### func [MustRun](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L64) - -```go -func MustRun(path string, opts ...Option) *KCLResultList -``` - -MustRun is like Run but panics if return any error. - -
Example -

- -```go -{ - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(`name = "kcl"`)).First().YAMLString() - fmt.Println(yaml) - -} -``` - -``` -name: kcl -``` - -

-
- -
Example (Raw Yaml) -

- -```go -{ - const code = ` -b = 1 -a = 2 -` - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(code)).GetRawYamlResult() - fmt.Println(yaml) - - yaml_sorted := kcl.MustRun("testdata/main.k", kcl.WithCode(code), kcl.WithSortKeys(true)).GetRawYamlResult() - fmt.Println(yaml_sorted) - -} -``` - -``` -b: 1 -a: 2 -a: 2 -b: 1 -``` - -

-
- -
Example (Schema Type) -

- -```go -{ - const code = ` -schema Person: - name: str = "" - -x = Person() -` - json := kcl.MustRun("testdata/main.k", kcl.WithCode(code)).First().JSONString() - fmt.Println(json) - -} -``` - -``` -{ - "x": { - "name": "" - } -} -``` - -

-
- -
Example (Settings) -

- -```go -{ - yaml := kcl.MustRun("./testdata/app0/kcl.yaml").First().YAMLString() - fmt.Println(yaml) -} -``` - -

-
- -### func [Run](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L69) - -```go -func Run(path string, opts ...Option) (*KCLResultList, error) -``` - -Run evaluates the KCL program with path and opts, then returns the object list. - -
Example (Get Field) -

- -```go -{ - - x, err := kcl.Run("./testdata/app0/kcl.yaml") - assert(err == nil, err) - - fmt.Println(x.First().Get("deploy_topology.1.zone")) - -} -``` - -``` -R000A -``` - -

-
- -### func [RunFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L74) - -```go -func RunFiles(paths []string, opts ...Option) (*KCLResultList, error) -``` - -RunFiles evaluates the KCL program with multi file path and opts, then returns the object list. - -
Example -

- -```go -{ - result, _ := kcl.RunFiles([]string{"./testdata/app0/kcl.yaml"}) - fmt.Println(result.First().YAMLString()) -} -``` - -

-
- -## type [KclType](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L50) - -```go -type KclType = kcl.KclType -``` - -### func [GetSchemaType](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L176) - -```go -func GetSchemaType(file, code, schemaName string) ([]*KclType, error) -``` - -GetSchemaType returns schema types from a kcl file or code. - -file: string - -``` -The kcl filename -``` - -code: string - -``` -The kcl code string -``` - -schema_name: string - -``` -The schema name got, when the schema name is empty, all schemas are returned. -``` - -## type [ListDepFilesOption](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L45) - -```go -type ListDepFilesOption = list.Option -``` - -## type [ListDepsOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L44) - -```go -type ListDepsOptions = list.DepOptions -``` - -## type [Option](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L43) - -```go -type Option = kcl.Option -``` - -### func [WithCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L79) - -```go -func WithCode(codes ...string) Option -``` - -WithCode returns a Option which hold a kcl source code list. - -### func [WithDisableNone](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L97) - -```go -func WithDisableNone(disableNone bool) Option -``` - -WithDisableNone returns a Option which hold a disable none switch. - -### func [WithKFilenames](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L82) - -```go -func WithKFilenames(filenames ...string) Option -``` - -WithKFilenames returns a Option which hold a filenames list. - -### func [WithOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L85) - -```go -func WithOptions(key_value_list ...string) Option -``` - -WithOptions returns a Option which hold a key=value pair list for option function. - -
Example -

- -```go -{ - const code = ` -name = option("name") -age = option("age") -` - x, err := kcl.Run("hello.k", kcl.WithCode(code), - kcl.WithOptions("name=kcl", "age=1"), - ) - if err != nil { - log.Fatal(err) - } - - fmt.Println(x.First().YAMLString()) - -} -``` - -``` -age: 1 -name: kcl -``` - -

-
- -### func [WithOverrides](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L88) - -```go -func WithOverrides(override_list ...string) Option -``` - -WithOverrides returns a Option which hold a override list. - -### func [WithPrintOverridesAST](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L100) - -```go -func WithPrintOverridesAST(printOverridesAST bool) Option -``` - -WithPrintOverridesAST returns a Option which hold a printOverridesAST switch. - -### func [WithSettings](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L91) - -```go -func WithSettings(filename string) Option -``` - -WithSettings returns a Option which hold a settings file. - -### func [WithSortKeys](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L105) - -```go -func WithSortKeys(sortKeys bool) Option -``` - -WithSortKeys returns a Option which hold a sortKeys switch. - -### func [WithWorkDir](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L94) - -```go -func WithWorkDir(workDir string) Option -``` - -WithWorkDir returns a Option which hold a work dir. - -## type [ValidateOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L46) - -```go -type ValidateOptions = validate.ValidateOptions -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/index.md deleted file mode 100644 index ea02d458..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/index.md +++ /dev/null @@ -1 +0,0 @@ -# 多语言 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/java-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/java-api.md deleted file mode 100644 index 1cea9e49..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/java-api.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Java API - -目前 KCL Java SDK 还处于早期预览版本,后续 KCL 团队会持续更新并提供更丰富的功能,更多信息请参阅:[https://github.com/kcl-lang/kcl-java](https://github.com/kcl-lang/kcl-java)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/overview.md deleted file mode 100644 index 29c8680d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/overview.md +++ /dev/null @@ -1,295 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 简介 - -KCL 语言提供 C/Rust/Go/Python/Java 等通用编程语言接口,相关语言正在开发完整中。 - -## C/Rust 语言 - -KCL 核心采用 Rust 语言开发,对外导出 C 语言 API 供 Go/Python/Java 等高级语言包装和集成。 - -## Go 语言 - -Go 语言是通过 CGO 包装 KCL 提供的 C-API,同时提供更深度的定制特性以满足上层工具的需求。 - -### API 抽象模型 - -Go 语言 API 的抽象模型如下图: - -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ kcl files │ │ KCL-Go-API │ │ KCLResultList │ -│ ┌───────────┐ │ │ │ │ │ -│ │ 1.k │ │ │ │ │ │ -│ └───────────┘ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ ┌───────────┐ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.Get("a.b.c") │ -│ │ 2.k │ │ │ │ Run(path) │ │ │ └───────────┘ │ └───────────────┘ -│ └───────────┘ │────┐ │ └───────────┘ │ │ │ -│ ┌───────────┐ │ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ │ 3.k │ │ │ │ │ │ │ KCLResult │──┼────────▶│x.Get("k", &v) │ -│ └───────────┘ │ │ │ │ │ └───────────┘ │ └───────────────┘ -│ ┌───────────┐ │ ├───▶│ ┌───────────┐ │──────────▶│ │ -│ │setting.yml│ │ │ │ │RunFiles() │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ └───────────┘ │ │ │ └───────────┘ │ │ │ KCLResult │──┼────────▶│x.JSONString() │ -└─────────────────┘ │ │ │ │ └───────────┘ │ └───────────────┘ - │ │ │ │ │ -┌─────────────────┐ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ Options │ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.YAMLString() │ -│WithOptions │ │ │ │MustRun() │ │ │ └───────────┘ │ └───────────────┘ -│WithOverrides │────┘ │ └───────────┘ │ │ │ -│WithWorkDir │ │ │ │ │ -│WithDisableNone │ │ │ │ │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ -``` - -其中输入的文件包含 KCL 文件和 `setting.yml` 配置文件,`Options` 可以用于指定额外的参数和工作目录等信息。“KCL-Go-API”部分是提供的 KCL 执行函数,执行函数根据输入文件和额外的参数执行 KCL 程序,最终输出 `KCLResultList` 结果。`KCLResultList` 是一个 `KCLResult` 构成的列表,每个 `KCLResult` 对应一个生成的配置文件或 `map[string]interface{}`。 - -### 例子 - -```go -package main - -import ( - "fmt" - - kcl "kcl-lang.io/kcl-go" -) - - -func main() { - const k_code = ` -name = "kcl" -age = 1 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person{} -x1 = Person{age:101} -` - - result := kcl.MustRun("hello.k", kcl.WithCode(k_code)).First() - fmt.Println(result.YAMLString()) - - fmt.Println("----") - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - - fmt.Println("----") - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x1", &person)) -} -``` - -输出结果: - -```yaml -age: 1 -name: kcl -x0: - age: 1 - name: kcl -x1: - age: 101 - name: kcl - ----- -x0.name: kcl -x1.age: 101 ----- -person: &{Name:kcl Age:101} -``` - -## REST-API - -KCL 提供的 C-API 并没有 REST-API,REST-API 是通过 Protobuf 定义,最终由上层的 Go-SDK 提供实现。 - -### 启动 REST 服务 - -通过以下方式可以启动 RestAPI 服务: - -```shell -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -然后可以通过 POST 协议请求服务: - -```shell -$ curl -X POST http://127.0.0.1:2021/api:protorpc/BuiltinService.Ping --data '{}' -{ - "error": "", - "result": {} -} -``` - -其中 POST 请求和返回的 JSON 数据和 Protobuf 定义的结构保持一致。 - -### `BuiltinService` 服务 - -其中 `/api:protorpc/BuiltinService.Ping` 路径表示 `BuiltinService` 服务的 `Ping` 方法。 - -完整的 `BuiltinService` 由 Protobuf 定义: - -```protobuf -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} -``` - -其中 `Ping` 方法可以验证服务是否正常,`ListMethod` 方法可以查询提供的全部服务和函数列表。 - -### `KclvmService` 服务 - -`KclvmService` 服务是和 KCL 功能相关的服务。用法和 `BuiltinService` 服务一样。 - -比如有以下的 `Person` 结构定义: - -```python -schema Person: - key: str - - check: - "value" in key # 'key' is required and 'key' must contain "value" -``` - -然后希望通过 `Person` 来校验以下的 JSON 数据: - -```json -{ "key": "value" } -``` - -可以通过 `KclvmService` 服务的 `ValidateCode` 方法完成。参考 `ValidateCode` 方法的 `ValidateCode_Args` 参数结构: - -```protobuf -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} -``` - -根据 `ValidateCode_Args` 参数结构构造 POST 请求需要的 JSON 数据,其中包含 `Person` 定义和要校验的 JSON 数据: - -```json -{ - "code": "\nschema Person:\n key: str\n\n check:\n \"value\" in key # 'key' is required and 'key' must contain \"value\"\n", - "data": "{\"key\": \"value\"}" -} -``` - -将该 JSON 数据保存到 `vet-hello.json` 文件,然后通过以下命令进行校验: - -```shell -$ curl -X POST \ - http://127.0.0.1:2021/api:protorpc/KclvmService.ValidateCode \ - -H "accept: application/json" \ - --data @./vet-hello.json -{ - "error": "", - "result": { - "success": true - } -} -``` - -说明校验成功。 - -## Python 语言 - -使用 Python SDK 要求您本地具备高于 3.7.3 的 Python 版本和 pip 包管理工具,可以通过如下命令进行安装并获得帮助信息 - -```bash -python3 -m pip install kclvm --user && python3 -m kclvm --help -``` - -### 命令行工具 - -编写名为 `main.k` 的 KCL 文件: - -```python -name = "kcl" -age = 1 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {} -x1 = Person { - age = 101 -} -``` - -执行如下命令并获得输出: - -```shell -$ python3 -m kclvm hello.k -name: kcl -age: 1 -x0: - name: kcl - age: 1 -x1: - name: kcl - age: 101 -``` - -### API - -此外,我们还可以通过 Python 代码实现对 KCL 文件的执行 - -编写名为 `main.py` 的 python 文件: - -```python -import kclvm.program.exec as kclvm_exec -import kclvm.vm.planner as planner - -print(planner.plan(kclvm_exec.Run(["hello.k"]).filter_by_path_selector())) -``` - -执行如下命令并获得输出: - -```shell -$ python3 main.py -name: kcl -age: 1 -x0: - name: kcl - age: 1 -x1: - name: kcl - age: 101 -``` - -可以看出通过命令行工具和 API 可以获得同样的输出。 - -目前 KCL Python SDK 还处于早期预览版本,后续 KCL 团队会持续更新并提供更丰富的功能,更多信息请参阅:[https://github.com/kcl-lang/kcl-py](https://github.com/kcl-lang/kcl-py) - -## 其它语言 - -用户也可以基于 C-API 和 RestAPI 包装其它语言的 SDK。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/python-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/python-api.md deleted file mode 100644 index ad3ad867..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/python-api.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Python API - -目前 KCL Python SDK 还处于早期预览版本,后续 KCL 团队会持续更新并提供更丰富的功能,更多信息请参阅:[https://github.com/kcl-lang/kcl-py](https://github.com/kcl-lang/kcl-py)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/rest-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/rest-api.md deleted file mode 100644 index 74a9bf4c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/xlang-api/rest-api.md +++ /dev/null @@ -1,455 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Rest API - -## 1. 启动 REST 服务 - -通过以下方式可以启动 RestAPI 服务: - -```shell -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -或者 - -```shell -go install kcl-lang.io/kcl-go/cmds/kcl-go@main -kcl-go rest-server -``` - -然后可以通过 POST 协议请求服务: - -```shell -curl -X POST http://127.0.0.1:2021/api:protorpc/BuiltinService.Ping --data '{}' -``` - -期望输出为 - -```shell -{ - "error": "", - "result": {} -} -``` - -其中 POST 请求和返回的 JSON 数据和 Protobuf 定义的结构保持一致。 - -## 2. `BuiltinService` 服务 - -其中 `/api:protorpc/BuiltinService.Ping` 路径表示 `BuiltinService` 服务的 `Ping` 方法。 - -完整的 `BuiltinService` 由 Protobuf 定义: - -```protobuf -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} -``` - -其中 `Ping` 方法可以验证服务是否正常,`ListMethod` 方法可以查询提供的全部服务和函数列表。 - -## 3. `KclvmService` 服务 - -`KclvmService` 服务是和 KCL 功能相关的服务。用法和 `BuiltinService` 服务一样。 - -比如有以下的 `Person` 结构定义: - -```python -schema Person: - key: str - - check: - "value" in key # 'key' is required and 'key' must contain "value" -``` - -然后希望通过 `Person` 来校验以下的 JSON 数据: - -```json -{ "key": "value" } -``` - -可以通过 `KclvmService` 服务的 `ValidateCode` 方法完成。参考 `ValidateCode` 方法的 `ValidateCode_Args` 参数结构: - -```protobuf -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} -``` - -根据 `ValidateCode_Args` 参数结构构造 POST 请求需要的 JSON 数据,其中包含 `Person` 定义和要校验的 JSON 数据: - -```json -{ - "code": "\nschema Person:\n key: str\n\n check:\n \"value\" in key # 'key' is required and 'key' must contain \"value\"\n", - "data": "{\"key\": \"value\"}" -} -``` - -将该 JSON 数据保存到 `vet-hello.json` 文件,然后通过以下命令进行校验: - -```shell -curl -X POST \ - http://127.0.0.1:2021/api:protorpc/KclvmService.ValidateCode \ - -H "accept: application/json" \ - --data @./vet-hello.json -``` - -如果看到输出 - -```json -{ - "error": "", - "result": { - "success": true - } -} -``` - -说明校验成功。 - -## 4. 完整的 Protobuf 服务定义 - -跨语言的 API 通过 Protobuf 定义([https://github.com/kcl-lang/kcl-go/blob/main/pkg/spec/gpyrpc/gpyrpc.proto](https://github.com/kcl-lang/kcl-go/blob/main/pkg/spec/gpyrpc/gpyrpc.proto)): - -```protobuf -// Copyright 2023 The KCL Authors. All rights reserved. -// -// This file defines the request parameters and return structure of the KCL RPC server. -// We can use the following command to start a KCL RPC server. - -syntax = "proto3"; - -package gpyrpc; - -import "google/protobuf/any.proto"; -import "google/protobuf/descriptor.proto"; - -// ---------------------------------------------------------------------------- - -// kcl main.k -D name=value -message CmdArgSpec { - string name = 1; - string value = 2; -} - -// kcl main.k -O pkgpath:path.to.field=field_value -message CmdOverrideSpec { - string pkgpath = 1; - string field_path = 2; - string field_value = 3; - string action = 4; -} - -// ---------------------------------------------------------------------------- -// gpyrpc request/response/error types -// ---------------------------------------------------------------------------- - -message RestResponse { - google.protobuf.Any result = 1; - string error = 2; - KclError kcl_err = 3; -} - -message KclError { - string ewcode = 1; // See kclvm/kcl/error/kcl_err_msg.py - string name = 2; - string msg = 3; - repeated KclErrorInfo error_infos = 4; -} - -message KclErrorInfo { - string err_level = 1; - string arg_msg = 2; - string filename = 3; - string src_code = 4; - string line_no = 5; - string col_no = 6; -} - -// ---------------------------------------------------------------------------- -// service requset/response -// ---------------------------------------------------------------------------- - -// gpyrpc.BuiltinService -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -// gpyrpc.KclvmService -service KclvmService { - rpc Ping(Ping_Args) returns(Ping_Result); - - rpc ExecProgram(ExecProgram_Args) returns(ExecProgram_Result); - - rpc FormatCode(FormatCode_Args) returns(FormatCode_Result); - rpc FormatPath(FormatPath_Args) returns(FormatPath_Result); - rpc LintPath(LintPath_Args) returns(LintPath_Result); - rpc OverrideFile(OverrideFile_Args) returns (OverrideFile_Result); - - rpc GetSchemaType(GetSchemaType_Args) returns(GetSchemaType_Result); - rpc GetSchemaTypeMapping(GetSchemaTypeMapping_Args) returns(GetSchemaTypeMapping_Result); - rpc ValidateCode(ValidateCode_Args) returns(ValidateCode_Result); - - rpc ListDepFiles(ListDepFiles_Args) returns(ListDepFiles_Result); - rpc LoadSettingsFiles(LoadSettingsFiles_Args) returns(LoadSettingsFiles_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} - -message ParseFile_AST_Args { - string filename = 1; - string source_code = 2; -} -message ParseFile_AST_Result { - string ast_json = 1; // json value - KclError kcl_err = 2; -} - -message ParseProgram_AST_Args { - repeated string k_filename_list = 1; -} -message ParseProgram_AST_Result { - string ast_json = 1; // json value - KclError kcl_err = 2; -} - -message ExecProgram_Args { - string work_dir = 1; - - repeated string k_filename_list = 2; - repeated string k_code_list = 3; - - repeated CmdArgSpec args = 4; - repeated CmdOverrideSpec overrides = 5; - - bool disable_yaml_result = 6; - - bool print_override_ast = 7; - - // -r --strict-range-check - bool strict_range_check = 8; - - // -n --disable-none - bool disable_none = 9; - // -v --verbose - int32 verbose = 10; - - // -d --debug - int32 debug = 11; - - // yaml/json: sort keys - bool sort_keys = 12; - // include schema type path in JSON/YAML result - bool include_schema_type_path = 13; -} -message ExecProgram_Result { - string json_result = 1; - string yaml_result = 2; - - string escaped_time = 101; -} - -message ResetPlugin_Args { - string plugin_root = 1; -} -message ResetPlugin_Result { - // empty -} - -message FormatCode_Args { - string source = 1; -} - -message FormatCode_Result { - bytes formatted = 1; -} - -message FormatPath_Args { - string path = 1; -} - -message FormatPath_Result { - repeated string changed_paths = 1; -} - -message LintPath_Args { - repeated string paths = 1; -} - -message LintPath_Result { - repeated string results = 1; -} - -message OverrideFile_Args { - string file = 1; - repeated string specs = 2; - repeated string import_paths = 3; -} - -message OverrideFile_Result { - bool result = 1; -} - -message EvalCode_Args { - string code = 1; -} -message EvalCode_Result { - string json_result = 2; -} - -message ResolveCode_Args { - string code = 1; -} - -message ResolveCode_Result { - bool success = 1; -} - -message GetSchemaType_Args { - string file = 1; - string code = 2; - string schema_name = 3; -} -message GetSchemaType_Result { - repeated KclType schema_type_list = 1; -} - -message GetSchemaTypeMapping_Args { - string file = 1; - string code = 2; - string schema_name = 3; -} -message GetSchemaTypeMapping_Result { - map schema_type_mapping = 1; -} - -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} - -message ValidateCode_Result { - bool success = 1; - string err_message = 2; -} - -message Position { - int64 line = 1; - int64 column = 2; - string filename = 3; -} - -message ListDepFiles_Args { - string work_dir = 1; - bool use_abs_path = 2; - bool include_all = 3; - bool use_fast_parser = 4; -} - -message ListDepFiles_Result { - string pkgroot = 1; - string pkgpath = 2; - repeated string files = 3; -} - -// --------------------------------------------------------------------------------- -// LoadSettingsFiles API -// Input work dir and setting files and return the merged kcl singleton config. -// --------------------------------------------------------------------------------- - -message LoadSettingsFiles_Args { - string work_dir = 1; - repeated string files = 2; -} - -message LoadSettingsFiles_Result { - CliConfig kcl_cli_configs = 1; - repeated KeyValuePair kcl_options = 2; -} - -message CliConfig { - repeated string files = 1; - string output = 2; - repeated string overrides = 3; - repeated string path_selector = 4; - bool strict_range_check = 5; - bool disable_none = 6; - int64 verbose = 7; - bool debug = 8; -} - -message KeyValuePair { - string key = 1; - string value = 2; -} - -// ---------------------------------------------------------------------------- -// JSON Schema Lit -// ---------------------------------------------------------------------------- - -message KclType { - string type = 1; // schema, dict, list, str, int, float, bool, any, union, number_multiplier - repeated KclType union_types = 2 ; // union types - string default = 3; // default value - - string schema_name = 4; // schema name - string schema_doc = 5; // schema doc - map properties = 6; // schema properties - repeated string required = 7; // required schema properties, [property_name1, property_name2] - - KclType key = 8; // dict key type - KclType item = 9; // dict/list item type - - int32 line = 10; - - repeated Decorator decorators = 11; // schema decorators -} - -message Decorator { - string name = 1; - repeated string arguments = 2; - map keywords = 3; -} - -// ---------------------------------------------------------------------------- -// END -// ---------------------------------------------------------------------------- -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/Ide/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/Ide/_category_.json deleted file mode 100644 index fcdc7f10..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/Ide/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "集成开发环境", - "position": 2 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/Ide/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/Ide/index.md deleted file mode 100644 index 2ba6e5b4..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/Ide/index.md +++ /dev/null @@ -1,6 +0,0 @@ -# IDE - -我们为 KCL 提供了两种简单的 IDE 插件。您可以通过以下链接获得更多帮助信息: - -- IntelliJ 插件: https://github.com/kcl-lang/intellij-kcl -- VSCode 插件: https://github.com/kcl-lang/vscode-kcl diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/Ide/intellij.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/Ide/intellij.md deleted file mode 100644 index be637514..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/Ide/intellij.md +++ /dev/null @@ -1,3 +0,0 @@ -# IntelliJ IDEA - -- IntelliJ Plugin: https://github.com/kcl-lang/intellij-kcl diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/Ide/vs-code.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/Ide/vs-code.md deleted file mode 100644 index d3db7e01..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/Ide/vs-code.md +++ /dev/null @@ -1,54 +0,0 @@ -# Visual Studio Code KCL 插件 - -## 快速开始 - -- 1. [安装 KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) 并检查 `kcl` 和 `kcl-language-server` 命令在您的 PATH 中: - - ```bash - which kcl - which kcl-language-server - ``` - -- 2. 安装 [VS Code KCL 插件](https://marketplace.visualstudio.com/items?itemName=kcl.kcl-vscode-extension). 需要您的 VS Code 版本大于 1.50+ -- 3. 重新打开 VS Code 并创建一个 KCL 文件验证 IDE 插件功能 - -## 特性 - -此扩展提供了一些 KCL 编码帮助,包括以下功能: - -- **语法高亮** - ![Highlight](/img/docs/tools/Ide/vs-code/Highlight.png) -- **跳转** - ![Goto Definition](/img/docs/tools/Ide/vs-code/GotoDef.gif) -- **补全** - ![Completion](/img/docs/tools/Ide/vs-code/Completion.gif) -- **大纲** - ![Outline](/img/docs/tools/Ide/vs-code/Outline.gif) -- **悬停** - ![Hover](/img/docs/tools/Ide/vs-code/Hover.gif) -- **诊断** - ![Diagnostics](/img/docs/tools/Ide/vs-code/Diagnostics.gif) - -> 提示:您可以通过安装 [Error Lens 插件](https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens) 来增强诊断效果 - -其他一些有用的功能,如代码重构和智能感知等正在开发中。 - -## 最小依赖 - -我们建议您使用最新版本的 KCL,但此扩展所需的 KCL 最低版本为 v0.4.6。如果您使用的是更早期版本,则此扩展可能无法正常工作。 - -## 已知问题 - -[详见](https://github.com/kcl-lang/kcl/issues/524) - -## 寻求帮助 - -如果扩展没有如您所期望的那样工作,请通过[社区](https://kcl-lang.io/docs/community/intro/support)与我们联系和寻求帮助。 - -## 参与贡献 - -目前 VS Code KCL 插件处于早期版本,我们正在积极改进 VS Code KCL 插件体验,欢迎参考[贡献指南](https://kcl-lang.io/docs/community/contribute) 一起共建! - -## 许可 - -Apache License 2.0 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/_category_.json deleted file mode 100644 index 5170334a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "工具", - "position": 3 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/_category_.json deleted file mode 100644 index 8fac9ad8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "命令行工具", - "position": 1 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/index.md deleted file mode 100644 index f754b5ca..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# 命令行工具 - -KCL 提供了 IDE 插件、丰富的语言工具和 OpenAPI 工具。通过这些工具,可以提供一整套解决方案,包括配置语言、模型界面、自动化工具和最佳实践。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/_category_.json deleted file mode 100644 index b22440b7..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KCL 语言工具", - "position": 2 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/docgen.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/docgen.md deleted file mode 100644 index 37b660ed..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/docgen.md +++ /dev/null @@ -1,313 +0,0 @@ ---- -sidebar_position: 5 ---- - -# 文档生成工具 - -KCL 命令行工具支持从 KCL 源码中一键提取模型文档,并支持丰富的输出格式:JSON,YAML 和 Markdown 等。本文介绍 KCL 语言的文档规范,举例说明如何使用 KCL 文档生成工具提取文档,并展示新增本地化语言文档的流程。 - -## 1. KCL 语言的文档规范 - -KCL文件的文档主要包含如下两个部分: - -- 当前 KCL Moudle 的文档:对当前 KCL 文件的说明 -- KCL 文件内包含的所有 Schema 的文档:对当前 Schema 的说明,其中包含 Schema 描述、Schema 各属性的描述、Examples 三部分,具体格式如下: - -1. Schema 描述 - -```python -"""这是Schema一个简短的描述信息 -""" -``` - -2. Schema 各属性的描述:包含属性描述、属性类型、默认值、是否可选 - -```python -""" -Attributes ----------- -x : type, default is a, optional. - Description of parameter `x`. -y : type, default is b, required. - Description of parameter `y`. -""" -``` - -其中,使用 `----------` 表示 `Attributes` 为一个标题(`-` 符号长度与标题长度保持一致),属性名称与属性类型用冒号 `:` 分隔,属性的说明另起一行并增加缩进进行书写。属性的默认值说明跟在属性类型之后使用逗号 `,` 分隔,书写为 `default is {默认值}` 形式,此外需要说明属性是否为可选/必选,对于可选属性在默认值之后书写 `optional`,对于必选属性在默认值之后书写 `required`。 - -3. Examples - -```python -""" -Examples --------- -val = Schema { - name = "Alice" - age = 18 -} -""" -``` - -此外,KCL 文档字符串语法应采用 [re-structured text (reST)](https://docutils.sourceforge.io/rst.html) 语法子集,并使用 [Sphinx](https://www.sphinx-doc.org/en/master/) 渲染呈现。 - -## 2. 从 KCL 源码生成文档 - -使用 kcl-doc generate 命令,从用户指定的文件或目录中提取文档,并输出到指定目录。 - -1. 参数说明 - -``` -usage: kcl-doc generate [-h] [--format YAML] [-o OUTPUT] [--r] - [--i18n-locale LOCALE] [--repo-url REPO_URL] - [files [files ...]] - -positional arguments: - files KCL file paths. If there's more than one files to - generate, separate them by space - -optional arguments: - -h, --help show this help message and exit - --format YAML Doc file format, support YAML, JSON and MARKDOWN. - Defaults to MARKDOWN - -o OUTPUT, --output-path OUTPUT - Specify the output directory. Defaults to ./kcl_doc - --r, -R, --recursive Search directory recursively - --i18n-locale LOCALE I18n locale, e.g.: zh, zh_cn, en, en_AS. Defaults to - en - --repo-url REPO_URL The source code repository url. It will be displayed in - the generated doc to link to the source code. -``` - -2. 从指定的一个或多个文件中提取文档,并输出到指定目录 - -```text -kcl-doc generate your_config.k your_another_config.k -o your_docs_output_dir -``` - -3. 从指定目录内,递归地查找 KCL 源码文件,并提取文档 - -```text -kcl-doc generate your_config_dir -r -o your_docs_output_dir -``` - -4. 在生成文档时,指定源码仓库地址。一经指定,生成的文档中将包含指向源码文件的链接 - -```text -kcl-doc generate your_config.k -o your_docs_output_dir --repo-url https://url/to/source_code -``` - -## 3. 新增本地化语言的文档 - -如前所示,默认情况下,文档生成工具提取的文档以源码 docstring 的内容为准,因而文档的语言随 docstring 编写语言而定。如果需要为源文件新增本地化语言的文档,则可以遵循按如下步骤: - -1. 初始化 i18n 配置文件。该步骤基于指定的 KCL 源码文件,生成相应的 i18n 配置文件,文件格式可选 JSON/YAML,默认为 YAML. 输出的配置文件名称将以指定的目标本地化方言结尾 - -```text -kcl-doc init-i18n your_config.k --format JSON --i18n-locale your_target_locale -``` - -2. 手动修改上述生成的 i18n 配置文件,使用目标语言修改配置中的 doc 字段 - -3. 基于修改后的 i18n 配置,生成本地化语言的文档。工具将查找指定目标语言的 i18n 配置文件,并转化为最终的文档 - -```text -kcl-doc generate your_config_dir --i18n-locale your_target_locale --format Markdown -``` - -接下来,通过一个小例子演示新增本地化语言文档的过程。 - -3.1 准备 KCL 源码文件,例如 server.k: - - ```python - schema Server: - """Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - - Attributes - ---------- - workloadType : str, default is "Deployment", required - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - name : str, required - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - labels : {str:str}, optional - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - - Examples - ---------------------- - myCustomApp = AppConfiguration { - name = "componentName" - } - """ - - workloadType: str = "Deployment" - name: str - labels?: {str: str} - ``` - -3.2 从 server.k 得到初始化的 i18n 配置文件,例如希望为其增加中文文档,指定生成的配置文件格式为 YAML - - ```text - kcl-doc init-i18n server.k --format YAML --i18n-locale zh_cn - ``` - - 该命令将在当前目录下创建 kcl_doc 目录,并生成 i18n 配置文件 kcl_doc/i18n_server_zh_cn.yaml,其内容如下: - - ```yaml - name: server - relative_path: ./server.k - schemas: - - name: Server - doc: | - Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - attributes: - - name: workloadType - doc: | - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - default_value: '"Deployment"' - is_optional: false - - name: name - doc: | - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: false - default_value: '' - - name: labels - doc: | - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - type: - type_str: '{str: str}' - type_category: DICT - dict_type: - key_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - value_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: true - default_value: '' - examples: | - myCustomApp = AppConfiguration { - name = "componentName" - } - doc: '' - source_code_url: '' - ``` - -3.3 修改初始化得到的 i18n 配置,将其中的 doc 字段修改为中文的描述,修改后的配置如下: - - ```yaml - name: server - relative_path: ./server.k - schemas: - - name: Server - doc: | - Server 模型定义了采用 Kubernetes 最佳实践的持续运行的服务的通用配置接口 - attributes: - - name: workloadType - doc: | - workloadType 属性定义了服务的类型,是服务级别的属性。合法的取值有:Deployment, CafeDeployment. - 另请查看:k8s/core/v1/workload_metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - default_value: '"Deployment"' - is_optional: false - - name: name - doc: | - name 为服务的名称,是服务级别的属性。 - 另请查看:k8s/core/v1/metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: false - default_value: '' - - name: labels - doc: | - labels 为服务的标签,是服务级别的属性。 - 另请查看:k8s/core/v1/metadata.k. - type: - type_str: '{str: str}' - type_category: DICT - dict_type: - key_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - value_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: true - default_value: '' - examples: | - myCustomApp = AppConfiguration { - name = "componentName" - } - doc: '' - source_code_url: '' - ``` - -3.4 基于修改后的 i18n 配置,生成本地化语言的文档,执行如下命令,将输出中文的文档 kcl_doc/doc_server_zh_cn.md,命令及生成的文档内容如下: - - ```text - kcl-doc generate server.k --i18n-locale zh_cn --format Markdown - ``` - - ~~~markdown - # server - ## Schema Server - Server 模型定义了采用 Kubernetes 最佳实践的持续运行的服务的通用配置接口 - - ### Attributes - |Name and Description|Type|Default Value|Required| - |--------------------|----|-------------|--------| - |**workloadType**
workloadType 属性定义了服务的类型,是服务级别的属性。合法的取值有:Deployment, CafeDeployment.
另请查看:k8s/core/v1/workload_metadata.k.|str|"Deployment"|**required**| - |**name**
name 为服务的名称,是服务级别的属性。
另请查看:k8s/core/v1/metadata.k.|str|Undefined|**required**| - |**labels**
labels 为服务的标签,是服务级别的属性。
另请查看:k8s/core/v1/metadata.k.|{str: str}|Undefined|optional| - ### Examples - ``` - myCustomApp = AppConfiguration { - name = "componentName" - } - ``` - - - - ~~~ - -## 4. 附录 - -### 1. 常见的 reST 概念 - -对于 reST 格式的文档,段落和缩进很重要,新段落用空白行标记,缩进即为表示输出中的缩进。可以使用如下方式表示字体样式: - -- \*斜体\* -- \*\*粗体\*\* -- \`\`等宽字体\`\` - -参考 [reST 文档](https://docutils.sourceforge.io/rst.html)获得更多帮助。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/fmt.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/fmt.md deleted file mode 100644 index 11199215..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/fmt.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -sidebar_position: 2 ---- - -# 格式化代码 - -KCL 支持通过内置的命令行工具一键格式化多个 KCL 文件文档。本文展示 KCL 编码风格和 KCL 格式化工具的使用方式。 - -## KCL 编码风格 - -KCL 格式化对文件的修改样式具体见 KCL 编码风格:[Style Guide for KCL Code](/docs/reference/lang/spec/codestyle) - -## 使用方式 - -- 单文件格式化 - -```text -kcl-fmt your_config.k -``` - -- 文件夹内多文件格式化 - -```text -kcl-fmt your_config_path -R -``` - -- 命令行参数 - - `-R|--recursive` 设置是否递归遍历子文件夹 - - `-w|--fmt-output` 设置是否输出到标准输出流,不加 `-w` 表示原地格式化 KCL 文件 - -## 格式化文件效果展示 - -- 格式化前 - -```py -import math -mixin DeploymentMixin: - service:str ="my-service" -schema DeploymentBase: - name: str - image : str -schema Deployment[replicas] ( DeploymentBase ) : - mixin[DeploymentMixin] - replicas : int = replicas - command: [str ] - labels: {str: str} -deploy = Deployment(replicas = 3){} -``` - -- 格式化后 - -```py -import math - -mixin DeploymentMixin: - service: str = "my-service" - -schema DeploymentBase: - name: str - image: str - -schema Deployment[replicas](DeploymentBase): - mixin [DeploymentMixin] - replicas: int = replicas - command: [str] - labels: {str:str} - -deploy = Deployment(replicas=3) {} - -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/index.md deleted file mode 100644 index 51f69ee6..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# KCL 语言工具 - -KCL 不仅提供了 kcl 命令编译和执行配置程序,还提供了 fmt、lint、test、vet、docgen 等配套的辅助工具。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/lint.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/lint.md deleted file mode 100644 index 7a66d3b3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/lint.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Lint 检查代码风格 - -KCL 支持通过内置的命令行工具对 KCL 代码进行检查,并支持多种输出格式。本文档展示 KCL Lint 工具的使用方式。 - -## 示例 - -### 工程结构 - -```text -. -└── Test - └── kcl.mod - └── a.k - └── b.k - └── dir - └── c.k - └── test.k -``` - -`a.k`,`b.k`,`c.k`,`test.k` 为测试的 kcl 文件。 - -命令: - -```shell -kcl-lint your_config.k -``` - -或 - -```shell -kcl-lint your_config_path -``` - -### CLI 参数 - -```shell -USAGE: - kcl-lint [OPTIONS] [--] [input]... - -ARGS: - ... Sets the input file to use - -OPTIONS: - --emit_warning Emit warning message - -h, --help Print help information - -v, --verbose Print test information verbosely - -Y, --setting ... Sets the input file to use -``` - -- input: 需要检查的单个 `.k` 文件路径或路径目录下的所有 `.k` 文件,支持绝对路径或当前目录的相对路径 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/overview.md deleted file mode 100644 index 4fa606dc..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/overview.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 概览 - -KCL 工具链是 KCL 语言的工具集合,旨在提升 KCL 的批量迁移、编写、编译和测试的效率。 - -| 类别 | 工具名称 | 说明 | -| ---------- | ---------------------- | --------------------------------------------------------- | -| 主工具集 | **kcl** | kcl 命令行工具提供对基于 KCL 语言的配置编写、编译和运行。 | -| | kcl-test | 即将提供 | -| | kcl-fmt | kcl-fmt 工具提供对 KCL 代码的格式化 | -| | kcl-lint | kcl-lint 工具提供对 KCL 代码的 lint 检查和自动修复 | -| | kcl-doc | kcl-doc 工具提供对 KCL 代码的文档解析和生成 | -| | kcl-vet | 使用 KCL 代码校验诸如 JSON 和 YAML 的数据格式 | -| ide 插件集 | IntelliJ IDEA KCL 插件 | 提供 IntelliJ IDEA 平台的 KCL 编写、编译辅助 | -| | VS Code KCL 插件 | 提供 VS Code 平台的 KCL 编写、编译辅助 | - -## KCL 工具 - -### 命令行参数 - -```shell -USAGE: - kcl [OPTIONS] [--] [input]... - -Arguments: - [input]... Specify the input files to run - -Options: - -o, --output - Specify the YAML output file path - -Y, --setting ... - Specify the input setting file - -v, --verbose... - Print test information verbosely - -n, --disable_none - Disable dumping None values - -r, --strict_range_check - Do perform strict numeric range checks - -d, --debug - Run in debug mode (for developers only) - -k, --sort_keys - Sort result keys - -D, --argument ... - Specify the top-level argument - -S, --path_selector ... - Specify the path selector - -O, --overrides ... - Specify the configuration override path and value - --target - Specify the target type - -E, --external ... - Mapping of package name and path where the package is located - -h, --help - Print help -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/test.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/test.md deleted file mode 100644 index f8707ff9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/test.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 5 ---- - -# 测试工具 - -即将到来! diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/vet.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/vet.md deleted file mode 100644 index 2c70ce91..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/kcl/vet.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Validation 校验代码 - -## 简介 - -KCL 支持通过内置的 `kcl-vet` 命令行工具提供了基本的配置数据校验能力,可以编写 KCL schema 对输入的 JSON/YAML 格式文件进行类型以及数值的校验。 - -## 使用方式 - -假设有 data.json 文件,代码如下: - -```json -{ - "name": "Alice", - "age": 18, - "message": "This is Alice", - "data": { - "id": 1, - "value": "value1" - }, - "labels": { - "key": "value" - }, - "hc": [1, 2, 3] -} -``` - -构造 schema.k 校验文件,内容如下: - -```py -schema User: - name: str - age: int - message?: str - data: Data - labels: {str:} - hc: [int] - - check: - age > 10 - -schema Data: - id: int - value: str -``` - -在目录下执行如下命令 - -```shell -$ kcl-vet data.json schema.k -``` - -## 指定校验的 schema - -当校验的 KCL 文件中存在多个 schema 定义时,kcl-vet 工具会默认取第一个 schema 定义进行校验,如果需要指定校验的 schema,可以使用 `-d|--schema` 参数 - -```shell -$ kcl-vet data.json schema.k -d User -``` - -## 命令行参数 - -```shell -$ kcl-vet -h -USAGE: - kcl-vet [OPTIONS] [ARGS] - -ARGS: - Validation data file - KCL file - -OPTIONS: - -d, --schema - Iterate through subdirectories recursively - - --format - Validation data file format, support YAML and JSON, default is JSON - - -h, --help - Print help information - - -n, --attribute_name - The attribute name for the data loading -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/openapi/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/openapi/_category_.json deleted file mode 100644 index 5df621d8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/openapi/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "OpenAPI 工具", - "position": 3 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/openapi/crd-to-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/openapi/crd-to-kcl.md deleted file mode 100644 index 5b6f070c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/openapi/crd-to-kcl.md +++ /dev/null @@ -1,118 +0,0 @@ -# CRD to KCL - -命令 - -```shell -kcl-openapi generate model --crd -f ${your_CRD.yaml} -t ${the_kcl_files_output_dir} --skip-validation -``` - -# 示例 - -- 输入文件:test_crontab_CRD.yaml: - -```yaml -# Deprecated in v1.16 in favor of apiextensions.k8s.io/v1 -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - # name must match the spec fields below, and be in the form: . - name: crontabs.stable.example.com -spec: - # group name to use for REST API: /apis// - group: stable.example.com - # list of versions supported by this CustomResourceDefinition - versions: - - name: v1 - # Each version can be enabled/disabled by Served flag. - served: true - # One and only one version must be marked as the storage version. - storage: true - # either Namespaced or Cluster - scope: Namespaced - names: - # plural name to be used in the URL: /apis/// - plural: crontabs - # singular name to be used as an alias on the CLI and for display - singular: crontab - # kind is normally the CamelCased singular type. Your resource manifests use this. - kind: CronTab - # shortNames allow shorter string to match your resource on the CLI - shortNames: - - ct - preserveUnknownFields: false - validation: - openAPIV3Schema: - type: object - properties: - spec: - type: object - properties: - cronSpec: - type: string - image: - type: string - replicas: - type: integer -``` - -- 命令 - -```shell -kcl-openapi generate model -f test_crontab_CRD.yaml -t ~/ --skip-validation --crd -``` - -- 输出文件: ~/models/stable_example_com_v1_cron_tab.k - -```python -""" -This file was generated by the KCL auto-gen tool. DO NOT EDIT. -Editing this file might prove futile when you re-run the KCL auto-gen generate command. -""" -import kusion_kubernetes.apimachinery.apis - - -schema CronTab: - """stable example com v1 cron tab - - Attributes - ---------- - apiVersion : str, default is "stable.example.com/v1", required - APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - kind : str, default is "CronTab", required - Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - metadata : apis.ObjectMeta, default is Undefined, optional - metadata - spec : StableExampleComV1CronTabSpec, default is Undefined, optional - spec - """ - - - apiVersion: "stable.example.com/v1" = "stable.example.com/v1" - - kind: "CronTab" = "CronTab" - - metadata?: apis.ObjectMeta - - spec?: StableExampleComV1CronTabSpec - - -schema StableExampleComV1CronTabSpec: - """stable example com v1 cron tab spec - - Attributes - ---------- - cronSpec : str, default is Undefined, optional - cron spec - image : str, default is Undefined, optional - image - replicas : int, default is Undefined, optional - replicas - """ - - - cronSpec?: str - - image?: str - - replicas?: int -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/openapi/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/openapi/index.md deleted file mode 100644 index 0654db2a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/openapi/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# OpenAPI Tools - -kcl-openapi 工具支持将通过 OpenAPI 规范描述的模型转换为 KCL 配置策略语言,除了能直接转换 OpenAPI 描述文件之外,还可以从 Kubernetes CRD 中提取并转换为 KCL schema. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/openapi/openapi-to-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/openapi/openapi-to-kcl.md deleted file mode 100644 index 6d9f8e54..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/openapi/openapi-to-kcl.md +++ /dev/null @@ -1,64 +0,0 @@ -# OpenAPI to KCL - -命令 - -```shell -kcl-openapi generate model -f ${your_open_api_spec.yaml} -t ${the_kcl_files_output_dir} -``` - -示例: - -- 输入文件:test_open_api_spec.yaml: - -```yaml -definitions: - v1.TestInt: - type: object - properties: - name: - type: string - format: int-or-string - required: - - name - x-kcl-type: - import: - package: v1.test_int - alias: test_int - type: TestInt -swagger: "2.0" -info: - title: KCL - version: v0.0.2 -paths: {} -``` - -- 命令: - -```shell -kcl-openapi generate model -f test_open_api_spec.yaml -t ~/ -``` - -- 输出:~/models/v1/test_int.k - -```python -""" -This is the test_int module in v1 package. -This file was generated by the KCL auto-gen tool. DO NOT EDIT. -Editing this file might prove futile when you re-run the KCL auto-gen generate command. -""" - - -schema TestInt: - """v1 test int - - Attributes - ---------- - name : int | str, default is Undefined, required - name - """ - - - name: int | str - - -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/openapi/quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/openapi/quick-start.md deleted file mode 100644 index 3d6a125d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/openapi/quick-start.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 快速开始 - -## 1. 安装 KCLOpenAPI 工具 - -目前有多种安装方式可选: - -- [通过 go install 安装](#11-通过-go-install-安装) -- [通过 curl|sh 安装(仅限 MacOS & Linux)](#12-通过-curlsh-安装(仅限-MacOS--Linux)) -- [下载发布包](#13-下载发布包) - -## 1.1 通过 go install 安装 - -```shell -go install kcl-lang.io/kcl-openapi@latest -``` - -## 1.2 通过 curl|sh 安装(仅限 MacOS & Linux) - -```shell -curl -fsSL https://kcl-lang.io/script/install-kcl-openapi.sh | /bin/bash -``` - -## 1.3 下载发布包 - -```shell -# 1. 下载二进制程序 -# https://github.com/kcl-lang/kcl-openapi/releases - -# 2. 解压发布包,并将命令添加至 PATH -export PATH=":$PATH" -``` - -## 1.4 验证安装结果 - -```shell -➜ kcl-openapi -v -kcl-openapi 0.5.0 -``` - -## 2. 生成 KCL 文件 - -- [将 OpenAPI 描述文件转换为 KCL](../openapi/openapi-to-kcl.md) -- [将 Kubernetes CRD 转换为 KCL](../openapi/crd-to-kcl.md) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/openapi/spec.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/openapi/spec.md deleted file mode 100644 index aee9fc92..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/tools/cli/openapi/spec.md +++ /dev/null @@ -1,424 +0,0 @@ -# KCL OpenAPI 规范 - -[OpenAPI](https://www.openapis.org/) 允许 API 提供方规范地描述 API 操作和模型,并基于它生成自动化工具和特定语言的客户端。 - -## KCL OpenAPI 文件结构 - -依据 OpenAPI 3.0 规范,OpenAPI 文件中应至少包含 openapi、components、 info、paths 四种根节点对象,KCL OpenAPI 聚焦于其中模型定义的部分,即 OpenAPI 文件中的 `definitions`,而描述操作的 Restful API 部分(即 OpenAPI 文件中的 `paths`)则不属于 KCL OpenAPI 定义的范畴。 -​ - -注:除以上列出的节点外,OpenAPI 官方规范还支持 servers、security、tags、externalDocs 四种可选的根节点,但都不是 KCL OpenAPI 所关心的,因此用户无需填写这部分内容,即使填写了也不会产生任何影响。 -​ - -| OpenAPI 顶层对象 | 类型 | 含义 | KCL OpenAPI 工具支持情况 | -| ---------------- | ----------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | -| swagger | string | openapi 版本信息 | 必填项,目前支持 openapi 2.0,即合法取值为 "2.0" | -| definitions | Definition Object | 模型定义 | 必填项 | -| info | Info Object | 当前 API 文件的元数据信息,例如标题、描述信息、版本、开源协议等 | 必填项,定义当前 OpenAPI 文件的基本信息,不会输出到 KCL 代码,但可用于 Swagger-UI 工具可视化展示 | - -为方便初学者快速理解,下面给出一个典型的 KCL OpenAPI 文件(截取自 swagger example [Petstore](https://petstore.swagger.io/))应包含的节点图示。KCL OpenAPI 工具重点关注其中的 definitions 节点,可以看到文件中定义了两个模型(Pet 和 Category),并且 Pet 模型中包含三个属性(name、id、category) - -## KCL schema - -KCL 中使用 schema 结构来定义配置数据的“类型”,关于 KCL schema,可参考文档:传送门 -在 definitions 节点下新增 definition 元素,即可定义 KCL schema. -示例: -下例在 KCL 代码中定义了 Pet、Category 两个 schema,同样地,其对应的 OpenAPI 也在 definitions 节点下包含这两个模型的描述。 - -```python -# KCL schema: -schema Pet: - name: str - id?: int - category?: Category - -schema Category: - name?: str - -# 对应的 OpenAPI 描述 -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "id": { - "type": "integer", - "format": "int64" - }, - "category": { - "$ref": "#/definitions/Category" - } - }, - "required": [ - "name" - ] - }, - "Category": { - "type": "object", - "properties": { - "name": { - "type": "string" - } - } - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -``` - -### schema 名称 - -在 KCL 中,schema 名称紧跟在 schema 关键字后声明,在 OpenAPI 中,模型的名称通过 definition 元素的 key 来定义。 - -### schema 类型 - -KCL schema 在 OpenAPI 中的类型为 "object". 例如上例中 "Pet" 的 "type" 值应为 "object". - -### schema 属性 - -KCL schema 中可以定义若干属性,属性的声明一般包含如下几部分: - -- 属性注解:可选,以 @ 开头,例如 @deprecated 注解表示属性被废弃 -- 属性名称:必须 -- 属性 optional 修饰符(?):可选,带问号表示当前属性为可选属性,可以不被赋值。反之,不带问号表示必填属性 -- 属性类型:必须,可以是基本数据类型,也可以是 schema 类型, 或者是前述两种类型的并集 -- 属性默认值:非必须 - -它们与 OpenAPI 规范的对应关系如下: - -| KCL schema 属性元素 | OpenAPI 元素 | -| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- | -| 属性注解 | 暂不支持,计划扩展一个 deprecate 字段用于描述 deprecated 注解 | | -| 属性名称 | properties 节点下,每个属性的 key 即为属性名称 | -| 属性 optional 修饰符(?) | 模型节点下,通过 required 字段列出该模型的所有必填属性的名称,未被列出的属性即为 optional | -| 属性类型 | 属性节点下,设置 type + format 可以标识属性的基本类型,如果是 schema 类型则用 $ref 字段表示,类型 union 则由扩展字段 x-kcl-types 来标识,此外,属性节点的 enum、pattern 也可以用于表示 KCL 类型。 | -| KCL-OpenAPI 关于类型的对照关系,详见“基本数据类型”小节 | | -| 属性默认值 | 属性节点下,设置 default 字段即可为属性设置默认值 | - -示例: -下例中 Pet 模型包含了 2 个属性:name(string 类型,必填属性,无注解,无默认值)、id(int64 类型,无注解,非必填,默认值为 -1) - -```python -# KCL schema Pet,包含两个属性 name 和 id -schema Pet: - name: str - id?: int = -1 - -# 对应的 OpenAPI 文档 -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - "id": { - "type": "integer", - "format": "int64", - "default": -1 - } - }, - "required": [ - "name" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### schema 索引签名 - -KCL schema 允许定义索引签名,用于定义属性名不固定的 dict,起到静态模板的作用。具体来说,KCL schema 索引签名包含如下几个元素: - -- 索引签名中 key 的类型:在方括号中声明,必须是基础类型 -- 索引签名中 value 的类型:在冒号后声明,可以是任意合法的 KCL 类型 -- 索引签名中的省略符:在方括号中,key 类型之前声明,使用"..."表示。如果带有该符号,表示该索引签名只用于约束未在 schema 中定义的属性;否则,表示 schema 中所有已定义和未定义属性都收到该索引签名的约束。 -- 索引签名中 key 的别名:在方括号中,紧随左方括号之后声明,使用名称 + 冒号表示,该别名可用于按名称引用索引签名 -- 索引签名的默认值:可以为索引签名设置默认值 - -在 OpenAPI 中,可以借助在模型节点的 `additionalProperties` 字段描述某些 key 为 string 的索引签名。但对于 KCL 索引签名中非 string 类型的 dict key、索引签名 key 的 check 校验,在 OpenAPI 规范没有对等的描述。它们与 OpenAPI 规范的对应关系如下: - -| KCL 索引签名元素 | OpenAPI 元素 | -| ----------------------- | ---------------------------------------------------------------------- | -| 索引签名中 key 的类型 | OpenAPI 仅支持 key 为 string 类型,无法自定义 | -| 索引签名中 value 的类型 | 模型节点的下 additionalProperties 下的 "type" 字段 | -| 索引签名中的省略符 | OpenAPI 中表示索引签名时,只能表示 KCL 中带有省略符的情况 | -| 索引签名中 key 的别名 | OpenAPI 中不支持为索引签名定义 key 别名,(预计通过扩展支持:x-alias) | -| 索引签名的默认值 | 目前不支持 | - -示例:下例中的 KCL schema Pet,包含两个预定义的属性 name 和 id,除此之外,还允许使用该 schema 的配置额外地赋值其他 key 为 string 类型,value 为 bool 类型的属性: - -```python -# KCL schema Pet,包含两个预定义的属性 name 和 id,允许额外给 key 为 string、value 为 bool 的属性赋值 -schema Pet: - name: str - id?: int - [...str]: bool - -# 对应的 OpenAPI 描述 -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - "id": { - "type": "integer", - "format": "int64", - } - }, - "additionalProperties": { - "type": "bool" - }, - "required": [ - "name" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### schema 继承关系 - -### 内联 schema - -OpenAPI 支持嵌套地定义 schema,但 KCL 目前暂不支持 schema 的内联。OpenAPI 中内联定义的 schema 将被转换为 KCL 中带名称的 schema,其名称的命名规则为:在该内联 schema 的上层 schema 名称的基础上,增加相应的后缀。在拼接后缀时,根据定义了该内联 schema 的外层 OpenAPI 元素类型,后缀内容如下: - -| OpenAPI 文档中定义内联 schema 的元素 | KCL schema 名称拼接规则 | -| ------------------------------------ | ------------------------------ | -| 某属性节点 | 增加该属性节点的名称为后缀 | -| AdditionalProperties 节点 | 增加"AdditionalProperties"后缀 | - -注:KCL 未来也可能会支持内联 schema,届时再更新这部分转换规则 -示例 1:下例中的模型 Deployment 包含有 kind、spec 两个属性,其中 deploymentSpec 属性的 schema 通过内联的方式定义: - -```python -# OpenAPI 文档 -{ - "definitions": { - "Deployment": { - "type": "object", - "properties": { - "kind": { - "type": "string", - }, - "spec": { - "type": "object", - "properties": { - "replicas": { - "type": "integer", - "format": "int64" - } - } - } - }, - "required": [ - "kind", - "spec" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -# 转换为 KCL Schema 如下: -schema Deployment: - kind: str - spec: DeploymentSpec - -schema DeploymentSpec: - replicas?: int -``` - -示例 2:下例中的模型 Person 中除固定属性 name 外,还允许包含额外的属性(additionalProperties),并且这部分额外属性的属性值的 schema 通过内联的方式定义: - -```python -# OpenAPI 文档 -{ - "definitions": { - "Person": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - }, - "required": [ - "name", - "spec" - ], - "additionalProperties": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "description": { - "type": "string" - } - }, - "required": [ - "name" - ] - }, - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -# 转换为 KCL Schema 如下: -schema Person: - name: str - [...str]: [PersonAdditionalProperties] - -schema PersonAdditionalProperties: - name: str - description?: str -``` - -## KCL 文档 - -KCL doc 规范请参考:[传送门](../kcl/docgen.md) -KCL 文档包含 module 文档、schema 文档两类,其中 schema 文档可以由 OpenAPI 转换得到。KCL schema 文档包含: - -- schema 描述信息:位于 schema 声明之后、schema 属性声明之前,是对 schema 的总体介绍 -- schema 属性信息:位于 shcema 描述信息之后,以 Attributes + 分割线分隔 -- schema 附加信息:位于 schema 属性信息之后,以 See Also + 分割线分隔 -- schema 示例信息:位于 schema 附加信息之后,以 Examples + 分割线分隔 - -它们与 OpenAPI 规范的对应关系如下: - -| KCL 文档元素 | OpenAPI 元素 | -| --------------- | ---------------------------------------------------- | -| schema 描述信息 | definitions 节点下,每个模型节点的 description 字段 | -| schema 属性信息 | properties 节点下,每个属性节点的 description 字段 | -| schema 附加信息 | definitions 节点下,每个模型节点的 externalDocs 字段 | -| schema 示例信息 | definitions 节点下,每个模型节点的 example 字段 | - -示例: -下例中为 Pet 模型定义了其 schema 描述文档 "The schema Pet definition";Pet 的两个属性 "name" 和 "id" 也分别定义了其属性文档 "The name of the pet" 及 "The id of the pet";Pet 的附加信息为 "Find more info here. [https://petstore.swagger.io/](https://petstore.swagger.io/)";此外,Pet 模型还提供了模型实例的示例写法。 - -```python -# KCL schema Pet,采用规范的 KCL 文档格式 -schema Pet: - """The schema Pet definition - - Attributes - ---------- - name : str, default is Undefined, required - The name of the pet - id : int, default is -1, optional - The age of the pet - - See Also - -------- - Find more info here. https://petstore.swagger.io/ - - Examples - -------- - pet = Pet { - name = "doggie" - id = 123 - } - """ - name: str - id?: int = -1 - -# 对应的 OpenAPI 文档 -{ - "definitions": { - "Pet": { - "description": "The schema Pet definition", - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "The name of the pet" - }, - "id": { - "type": "integer", - "format": "int64", - "default": -1, - "description": "The age of the pet" - } - }, - "required": [ - "name" - ], - "externalDocs": { - "description": "Find more info here", - "url": "https://petstore.swagger.io/" - }, - "example": { - "name": "doggie", - "id": 123 - } - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -​ - -## 基本数据类型 - -| JSON Schema type | swagger type | KCL type | comment | -| ---------------- | --------------------------- | --------------- | --------------------------------------------------------------------------- | -| boolean | boolean | bool | | -| number | number | float | | -| | number format double | **unsupported** | | -| | number format float | float | | -| integer | integer | int (32) | | -| | integer format int64 | **unsupported** | | -| | integer format int32 | int (32) | | -| string | string | str | | -| | string format byte | str | | -| | string format int-or-string | int | str | -| | string format binay | str | | -| | string format date | unsupported | As defined by full-date - [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) | -| | string format date-time | unsupported | As defined by date-time - [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) | -| | string format password | unsupported | for swagger: A hint to UIs to obscure input. | -| | datetime | datetime | | - -## Reference - -- openapi spec 2.0:[https://swagger.io/specification/v2/](https://swagger.io/specification/v2/) -- openapi spec 3.0:[https://spec.openapis.org/oas/v3.1.0](https://spec.openapis.org/oas/v3.1.0) -- openapi spec 3.0(swagger 版本):[https://swagger.io/specification/](https://swagger.io/specification/) -- openapi spec 2.0 #SchemaObject:[https://swagger.io/specification/v2/#schemaObject](https://swagger.io/specification/v2/#schemaObject) -- go swagger:[https://goswagger.io/use/models/schemas.html](https://goswagger.io/use/models/schemas.html) -- swagger data models:[https://swagger.io/docs/specification/data-models/](https://swagger.io/docs/specification/data-models/) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/concepts/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/concepts/_category_.json deleted file mode 100644 index d3ae7a0a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/concepts/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "核心概念", - "position": 5 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/concepts/concepts.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/concepts/concepts.md deleted file mode 100644 index e2034db2..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/concepts/concepts.md +++ /dev/null @@ -1,3 +0,0 @@ -# 核心概念 - -学习更多关于 KCL 核心概念。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/concepts/package-and-module.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/concepts/package-and-module.md deleted file mode 100644 index fbde28f3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/concepts/package-and-module.md +++ /dev/null @@ -1,156 +0,0 @@ -# 模块和包 - -本节主要介绍如何组织 KCL 中的文件。 - -## 概述 - -在一个**module**中,KCL 按**package**进行组织文件。package 可以在 module 内定义,也可以通过 KCL 包管理器 `kpm` 从外部导入。在后一种情况下,KCL 在专用位置中维护包的副本。 - -## Module - -KCL 模块按目录层次结构布置配置。它包含了确定 KCL 配置结果所需的一切。此目录的根标记为包含 `kcl.mod` 目录。此目录的内容大多由 kcl 工具(如 `kpm` 等)管理。从这个意义上讲,`kcl.mod` 类似于 `.git` 目录,标记着仓库的根目录,但它的内容主要由 git 工具管理。此外,KCL 模块是文件组织的最大单位,具有所有 KCL 文件和依赖项的固定位置。 - -> 注意: 使用 KCL 模块(例如 `kcl.mod`)是可选的,但如果您想使用语义版本管理、分发、共享和重用代码,则需要使用它。 - -### 创建一个 module - -可以通过在模块根目录中运行以下命令来创建模块: - -```bash -kpm init [module name] -``` - -模块名在需要在模块内导入另一个模块的包时是**必需的**。也可以通过手动设置 `kcl.mod` 文件来创建模块。 - -## Package - -在 KCL 中,一个包通常由包含 KCL 文件的“文件夹”组成。这个文件夹可以是实际的磁盘物理路径,也可以由多个 KCL 文件(通常是主包)组成。不同的包通过不同的包路径(如 `kubernetes.core.v1`)唯一地定位。 - -在同一个模块内,可以通过相对或绝对路径的 import 语句互相导入不同的包。在 KCL 解析过程中,相对 import 将被替换为绝对 import,并通过包路径找到相应的 KCL 代码。 - -### 相对导入路径 - -我们可以使用 `.` 运算符来实现 KCL 入口文件的相对路径导入。 - -main.k: - -```python -import .model1 # Current directory module -import ..service # Parent directory -import ...root # Parent of parent directory - -s = service.ImageService {} -m = root.Schema {} -``` - -### 绝对导入路径 - -KCL 语句`import a.b.c.d` 的语义是: - -1. 如果 `kcl.mod` 不存在,则将当前目录视为包根目录,并从当前目录搜索路径 `a/b/c/d`。 -2. 如果当前目录搜索失败,则从根路径 `ROOT_PATH/a/b/c/d` 搜索,否则引发导入错误。 - -根路径 `ROOT_PATH` 的定义是相对于 `kcl.mod` 文件的目录。 - -代码结构: - -```bash -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -### 内置包 - -KCL 有一系列内置包,例如 `math`,`regex` 等。要使用内置包,直接导入并使用其限定标识符调用函数。例如, - -```python -import regex - -image = "nginx:1.14.2" -is_match = regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$") - -``` - -输出的 YAML 为 - -```yaml -image: nginx:1.14.2 -is_match: true -``` - -### 插件包 - - - -KCL 还有一系列插件包,例如 `hello`,`project_context` 等。要使用插件包,需要用 `kcl_plugin.` 包路径前缀导入,并使用其限定标识符调用函数。例如, - -```python -import kcl_plugin.hello - -result = hello.add(1, 1) -``` - -输出的 YAML 为 - -```yaml -result: 2 -``` - -### 主包 - -在 KCL 中,主包的组成通常由编译器参数确定。这是因为KCL模式和约束可以在包中的文件中分隔,甚至可以在目录中组织,考虑将配置写入和维护在隔离块中的便利性。 - -#### 属于主包的文件 - -用户可以使用KCL命令行决定使用哪些配置和约束,例如, - -```bash -kcl file1.k file2.k -``` - -因此,主包包含两个名为 `file1.k` 和 `file2.k` 的 KCL 文件。 - -如果 KCL 被告知为特定目录加载文件,例如: - -```bash -kcl ./path/to/package -``` - -它将只查找 `.k` 后缀的 KCL 文件,并忽略 `_` 或 `_test.k` 前缀的 KCL 文件合并到主包中。此外,如果 `./path/to/package` 包含 `kcl.yaml` 文件,则 `kcl.yaml` 文件将被忽略。 - -此外,我们可以通过配置命令行编译设置文件(例如 `kcl.yaml`)来设置主包文件,如下所示: - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k -``` - -```bash -kcl -Y kcl.yaml -``` - -> 注意:如果没有为 KCL 指定任何输入文件,KCL 将从命令行执行路径查找默认的 `kcl.yaml` 文件读取输入文件。此外,如果我们告诉KCL输入文件和编译设置文件,KCL将把用户输入的输入文件作为最终值。 - -```bash -# 无论`kcl.yaml` 中是否配置 `files` 字段,输入文件的最终值为["file1.k", "file2.k"] -kcl -Y kcl.yaml file1.k file2.k -``` - -## kcl.mod 和 kcl.yaml 异同 - -首先,在 KCL 中,`kcl.mod` 和 `kcl.yaml` 都是可选的。它们之间的区别在于 `kcl.mod` 确定包路径的根路径以及 KCL 模块是否具有分发和重用要求,而 `kcl.yaml` 确定主包的 KCL 文件组成。 - -其次,对于仅用于外部使用的 kcl module,`kcl.yaml` 是可选的,但 `kcl.mod` 是必需的,因为 `kcl.mod` 需要声明 KCL 版本,模块版本,依赖关系和其他信息。 - -最后,对于 KCL IDE 插件,它需要知道主包信息才能形成完整的编译过程,因此它需要根据光标位置自动查找主包组成,因为没有人可以通过 KCL 命令行指定这些信息。一般的查询逻辑是查找 `kcl.yaml` 的存在性。如果找到了,主包由 `kcl.yaml` 中的文件属性组成,如果找不到,主包由当前文件组成。KCL IDE 插件会有选择地了解 `kcl.mod` 文件。当 `kcl.mod` 文件存在时,IDE 插件会读取所有包路径及其在外部依赖项中的实际路径的相应信息。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/getting-started/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/getting-started/_category_.json deleted file mode 100644 index c826d665..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/getting-started/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "快速开始", - "position": 1 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/getting-started/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/getting-started/index.md deleted file mode 100644 index 5d58acf6..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/getting-started/index.md +++ /dev/null @@ -1 +0,0 @@ -# 快速开始 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/getting-started/install.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/getting-started/install.md deleted file mode 100644 index 74510232..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/getting-started/install.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -sidebar_position: 2 ---- - -# 安装 - -## 1. 安装 KCL - -### 二进制下载 - -KCL 的每个版本都包含各种操作系统和体系结构。这些二进制版本可以从 [Github](https://github.com/kcl-lang/kcl/releases/) 或者 [Gitee](https://gitee.com/kusionstack/kcl/releases) 手动下载并安装,下载完成后将 `{install-location}/kclvm/bin` 添加到环境变量 PATH 中。 - -> ⚠️ 如果您不能成功访问 Github, 也可以访问 Gitee 获得二进制进行安装 - -#### MacOS & Linux - -```bash -export PATH=$PATH:{install-location}/kclvm/bin -``` - -#### Windows - -```powershell -$env:PATH += ";{install-location}\kclvm\bin;" -``` - -### 使用脚本安装最新版本 - -#### MacOS - -将 KCL darwin 最新版本安装到 /usr/local/kclvm/bin - -```bash -curl -fsSL https://kcl-lang.io/script/install.sh | /bin/bash -``` - -#### Linux - -将 KCL linux 最新版本安装到 /usr/local/kclvm/bin - -```bash -wget -q https://kcl-lang.io/script/install.sh -O - | /bin/bash -``` - -#### Windows - -将 KCL windows 最新版本安装到 $Env:SystemDrive\kclvm\bin,并将该目录添加到用户 PATH 环境变量中。 - -```bash -powershell -Command "iwr -useb https://kcl-lang.io/script/install.ps1 | iex" -``` - -### Homebrew (MacOS) - -- 安装 - -```bash -brew install kcl-lang/tap/kcl -``` - -- 升级 - -```bash -brew upgrade kcl-lang/tap/kcl -``` - -- 卸载 - -```bash -brew uninstall kcl-lang/tap/kcl -``` - -### Scoop (Windows) - -首先安装 [Scoop](https://scoop.sh/), 然后通过如下命令安装 `kcl`: - -```bash -scoop bucket add kcl-lang https://github.com/kcl-lang/scoop-bucket.git -scoop install kcl-lang/kcl -``` - -### 使用 Go 安装 - -通过 `Go` 命令安装 (Go 要求 1.18+) - -```bash -go install kcl-lang.io/kcl-go/cmds/kcl-go@main -``` - -添加一个 kcl 命令的别名 (可选) - -```bash -alias kcl='kcl-go run' -``` - -> 注意:`kcl-go` 并不依赖是否安装了 `kcl`,但如果 PATH 中存在 `kcl`,`kcl-go` 将优先使用 `PATH` 中的 `kcl`。 - -### 使用 Docker 镜像安装 - -- 基本命令 - -```bash -docker run --rm -it kcllang/kcl -``` - -- 更新镜像 - -```bash -docker pull kcllang/kcl -``` - -### 注意 - -可以执行运行如下命令确保 KCL 已经正确安装 - -```bash -kcl -V -``` - -如果安装成功,输出可能为如下形式 (不同版本结果可能稍微不同): - -```bash -Version: {kcl version} -Platform: {your platform} -GitCommit: {git commit} -``` - -对于上述所有安装方式, 如果您想使用 [KCL Python 插件](/docs/reference/plugin/overview), 需要确保您已经安装了 Python 3.7+ 并将 python3 命令添加到您的 PATH 中。 - -## 2. 安装 KCL IDE 插件 - -### VS Code - -KCL 为 VS Code 本地版本提供了插件支持,并提供了高亮、自动补全、跳转、悬停、大纲等功能。您可以[点击这里](/docs/tools/Ide/vs-code)进行安装。 - -![Completion](/img/docs/tools/Ide/vs-code/Completion.gif) - -### IntelliJ IDEA - -从[这里](https://github.com/kcl-lang/intellij-kcl/releases)下载发行版,在 IntelliJ IDEA 中,点击 Preference -> plugins -> install Plugin from Disk... -> 选择 kcl-idea-plugin zip -> 重启 IDE。此插件需要 IntelliJ IDEA 2020.2+ diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/getting-started/intro.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/getting-started/intro.md deleted file mode 100644 index aaa364e3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/getting-started/intro.md +++ /dev/null @@ -1,199 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 简介 - -## KCL 是什么? - -[KCL](https://github.com/kcl-lang/kcl) 是一个开源的基于约束的记录及函数语言。KCL 通过成熟的编程语言技术和实践来改进对大量繁杂配置比如云原生 Kubernetes 配置场景的编写,致力于构建围绕配置的更好的模块化、扩展性和稳定性,更简单的逻辑编写,以及更简单的自动化和生态工具集成。 - -## 为什么使用 KCL? - -KCL 期望通过更现代化的声明式配置语言在 Kubernetes 资源管理解决如下问题: - -- 通过**代码抽象**等手段屏蔽基础设施和平台的细节,降低研发者负担 -- **编辑**和**校验**已有的存量配置或模版 -- 通过配置语言无副作用地管理跨团队的大规模配置数据,提升团队协作效率 - - 用**生产级高性能编程语言**以**编写代码**的方式提升配置的灵活度,比如条件语句、循环、函数、包管理等特性提升配置重用的能力 - - 在代码层面提升**配置语义验证**的能力,比如字段可选/必选、类型、范围等配置检查能力 - - 提供**配置分块编写、组合和抽象的能力**,比如结构定义、结构继承、约束定义等能力 - - 通过**多语言 SDK**,**KCL 语言插件**等手段提升其**自动化**集成能力 - -您可以将 KCL 用于 - -- 生成静态配置数据如 JSON, YAML 等 -- 使用 schema 对配置数据进行建模并减少配置数据中的样板文件 -- 为配置数据定义带有规则约束的 schema 并对数据进行自动验证 -- 无副作用地组织、简化、统一和管理庞大的配置 -- 通过分块编写配置数据可扩展地管理庞大的配置 -- 与 [KusionStack](https://kusionstack.io) 一起,用作平台工程语言来交付现代应用程序 - -除了语言自身,KCL 还提供了许多额外的工具如格式化,测试、文档、包管理等工具帮助您使用、理解和检查编写的配置或策略;通过 VS Code 等 IDE 插件和 Playground 降低配置编写、分享的成本;通过 Rust, Go, 和 Python 多语言 SDK 自动化地管理和执行配置。 - -![](/img/docs/user_docs/intro/kcl-overview.png) - -此外,KCL 是一种现代高级领域编程语言,并且它是一种编译静态的强类型语言。KCL 为开发人员提供了通过记录和函数语言设计将**配置(config)**、**建模抽象(schema)**、**逻辑(lambda)**和**策略(rule)**作为核心能力。 - -![](/img/docs/user_docs/intro/kcl-concepts.png) - -KCL 试图提供独立于运行时的可编程性,不在本地提供线程和IO等系统功能,但支持云本地操作场景的功能,并试图为解决领域问题并提供稳定、安全、低噪声、低副作用、易于自动化和易于管理的编程支持。 - -总之,KCL 具备如下特点: - -- **简单易用**:源于 Python、Golang 等高级语言,采纳函数式编程语言特性,低副作用 -- **设计良好**:独立的 Spec 驱动的语法、语义、运行时和系统库设计 -- **快速建模**:以 [Schema](https://kcl-lang.io/docs/reference/lang/tour#schema) 为中心的配置类型及模块化抽象 -- **功能完备**:基于 [Config](https://kcl-lang.io/docs/reference/lang/tour#config-operations)、[Schema](https://kcl-lang.io/docs/reference/lang/tour#schema)、[Lambda](https://kcl-lang.io/docs/reference/lang/tour#function)、[Rule](https://kcl-lang.io/docs/reference/lang/tour#rule) 的配置及其模型、逻辑和策略编写 -- **可靠稳定**:依赖[静态类型系统](https://kcl-lang.io/docs/reference/lang/tour/#type-system)、[约束](https://kcl-lang.io/docs/reference/lang/tour/#validation)和[自定义规则](https://kcl-lang.io/docs/reference/lang/tour#rule)的配置稳定性 -- **强可扩展**:通过独立配置块[自动合并机制](https://kcl-lang.io/docs/reference/lang/tour/#-operators-1)保证配置编写的高可扩展性 -- **易自动化**:[CRUD APIs](https://kcl-lang.io/docs/reference/lang/tour/#kcl-cli-variable-override),[多语言 SDK](https://kcl-lang.io/docs/reference/xlang-api/overview),[语言插件](https://github.com/kcl-lang/kcl-plugin) 构成的梯度自动化方案 -- **极致性能**:使用 Rust & C,[LLVM](https://llvm.org/) 实现,支持编译到本地代码和 [WASM](https://webassembly.org/) 的高性能编译时和运行时 -- **API 亲和**:原生支持 [OpenAPI](https://github.com/kcl-lang/kcl-openapi)、 Kubernetes CRD, Kubernetes YAML 等 API 生态规范 -- **开发友好**:[语言工具](https://kcl-lang.io/docs/tools/cli/kcl/) (Format,Lint,Test,Vet,Doc 等)、 [IDE 插件](https://github.com/kcl-lang/vscode-kcl) 构建良好的研发体验 -- **安全可控**:面向领域,不原生提供线程、IO 等系统级功能,低噪音,低安全风险,易维护,易治理 -- **多语言 SDK**:[Go](https://kcl-lang.io/docs/reference/xlang-api/go-api),[Python](https://kcl-lang.io/docs/reference/xlang-api/python-api),[Java](https://kcl-lang.io/docs/reference/xlang-api/java-api) 和 [REST API](https://kcl-lang.io/docs/reference/xlang-api/rest-api) 满足不同场景和应用使用需求 -- **生态集成**:通过 [Kustomize KCL 插件](https://github.com/kcl-lang/kustomize-kcl), [Helm KCL 插件](https://github.com/kcl-lang/helm-kcl) 或者 [KPT KCL SDK](https://github.com/kcl-lang/kpt-kcl-sdk) 直接编辑或校验资源 -- **生产可用**:广泛应用在蚂蚁集团平台工程及自动化的生产环境实践中 - -虽然 KCL 不是通用语言,但它有相应的应用场景。开发人员可以通过 KCL 编写**config**、**schema**、**function**和**rule**,其中 config 用于定义数据,schema 用于描述数据的模型定义,rule 用于验证数据,schema 和 rule 还可以组合使用模型和约束来充分描述数据。此外,还可以使用 KCL 中的 lambda 纯函数来组织数据代码,封装通用代码,并在需要时直接调用它。 - -KCL 配置通常遵循如下模式: - -$$ -k = (T) v -$$ - -其中,$k$ 是属性名称,$v$ 是属性值,$T$ 是类型注解。由于 KCL 具有类型推导的能力,因此 $T$ 通常可以省略。 - -下面是一个用 KCL 生成 kubernetes 资源的例子 - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = name -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -我们可以使用上述 KCL 代码生成一个 Kubernetes YAML 配置 - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## 如何选择 - -目前社区已经进行了大量的尝试来改进其配置技术,主要可分为三类: - -- 用于模板、修补和验证的基于低级数据格式的工具,使用外部工具来增强重用和验证。 -- 领域特定语言(DSL)和配置语言(CL),以增强语言能力。 -- 基于通用语言(GPL)的解决方案,使用 GPL 的云开发工具包(CDK)或框架来定义配置。 - -简单的选择答案: - -- 如果您需要编写结构化的静态的 K-V,或使用 Kubernetes 原生的技术工具,建议选择 YAML。 -- 如果您希望引入编程语言便利性以消除文本(如 YAML、JSON) 模板,有良好的可读性,或者你已是 Terraform 的用户,建议选择 HCL。 -- 如果您希望引入类型功能提升稳定性,维护可扩展的配置文件,建议选择 CUE。 -- 如果您希望以现代语言方式编写复杂类型和建模,维护可扩展的配置文件,原生的纯函数和策略,和生产级的性能和自动化,建议直接选择 KCL 或将 KCL 用于对已有配置手段或工具进行增强。 - -### vs. YAML/JSON - -YAML/JSON 适用于小型配置场景。对于需要频繁修改的大型云原生配置场景,它们更适合 KCL。所涉及的主要区别是配置数据抽象和部署之间的区别: - -使用 KCL 进行配置的优点是:对于静态数据,抽象一层的优点意味着整个系统具有部署灵活性。不同的配置环境、租户和运行时可能对静态数据有不同的要求,甚至不同的组织可能有不同的规范和产品要求。KCL 可用于公开最需要的和经常修改的配置。 - -### vs. Jsonnet/GCL - -GCL 是一种用 Python 实现的声明式配置语言,它提供了支持模板抽象的必要语言功能。然而 GCL 编译器本身是用Python编写的,且语言本身是解释执行的。对于大型模板实例(如 kubernetes 模型),性能较差。 - -Jsonnet 是一种用 C++ 实现的数据模板语言,适用于应用程序和工具开发人员,可以生成配置数据并通过代码组织、简化和管理大型配置,而不会产生副作用。 - -Jsonnet 和 GCL 非常擅长减少样板。它们都可以使用代码生成配置,就像工程师只需要编写高级 GPL 代码,而不是手动编写容易出错且难以理解的服务器二进制代码一样。Jsonnet 减少了 GCL 的一些复杂性,但在很大程度上属于同一类别。两者都有许多运行时错误,类型检查和约束能力不足。 - -### vs. HCL - -HCL 是一种 Go 实现的结构化配置语言。HCL 的原生语法受到 libucl 和 nginx 配置的启发。它用于创建一种对人类和机器友好的结构化配置语言,作为 [Terraform 语言](https://www.terraform.io/language)主要用于 DevOps工具、服务器配置和资源配置等。 - -HCL 的用户界面不能通过 Terraform 提供者 Schema 定义直接感知。此外,在编写复杂对象和必需/可选字段定义时,用户界面很麻烦。动态参数受变量的条件字段约束。资源本身的约束需要由提供程序模式定义,或者与 Sentinel/Rego 和其他策略语言相结合。语言本身的完整性不能自我封闭,其实现方法也不统一。 - -### vs. CUE - -CUE 可以通过结构、无继承和其他特性用作建模,当模型定义之间没有冲突时可以实现高度抽象。因为 CUE 在运行时执行所有约束检查,所以它在大规模配置建模场景中可能存在性能瓶颈。CUE 将类型和值组合为一个概念,并通过各种语法简化了约束的编写。例如,不需要泛型类型和枚举,求和类型和空值合并是一回事。CUE 支持配置合并,但它是完全幂等的。它可能无法满足复杂的多租户和多环境配置场景的要求。对于复杂的循环和约束场景,编写起来很复杂,编写需要精确配置修改或者 Patch 的场景也很麻烦。 - -对于 KCL,建模是通过 KCL Schema 进行的,通过语言级工程和一些面向对象的特性(如单一继承、Mixin 复用)可以实现高模型抽象。KCL 是一种静态编译语言,用于大规模建模场景是运行时开销较低 (性能更高,更低的内存消耗)。KCL 提供了更丰富的检查声明性约束语法,这使得配置和策略编写更加容易。对于一些配置字段组合约束,它更容易编写(与 CUE 相比,KCL 提供了更多的 if-guard 组合约束、all/any/map/filter 表达式和其他集合约束编写方法,这使得编写更容易)。 - -### vs. Dhall - -Dhall 是一种可编程配置语言,它组合了 JSON、函数、类型和 imports 导入等功能, 本身风格偏向函数式,如果您学过 Haskell 等函数式风格语言,可能会对它感到熟悉的。相比于 Dhall, KCL 也提供了类似功能的组合,提供给用户配置可编程和抽象的能力,不过 KCL 在建模、约束检查、自动化等方面做了更多的改进,同时能够通过包管理手段进行模型共享。此外,KCL 的语法语义更贴近于面向对象语言,在一定程度上会比纯函数式风格接受程度更高。 - -### vs. Nickel - -Nickel 是一种简单的配置语言。它的目的是自动生成静态配置文件,本质上是带有函数和类型的 JSON。 - -KCL 和 Nickel 都有类似的渐进式类型系统(静态+动态)、合并策略、函数和约束定义。不同之处在于 KCL 是一种类似 Python 的语言,而 Nickel 是一种类似 JSON 的语言。此外,KCL 提供了 schema 关键字来区分配置定义和配置数据,以避免混合使用。 - -### vs. Starlark - -Starlark 主要用作 Bazel 的配置语言并且是 Python 的一种方言。它没有类型,并且禁止递归。 - -KCL 一定程度上也可以看作 Python 的变种,但是它极大地增强了静态类型和配置扩展性相关的设计,并且是一个编译型语言,这与 Starlark 有着本质的不同。 - -### vs. Kustomize - -Kustomize 的核心功能是其文件级覆盖功能。但是它存在多个覆盖链的问题,因为找到特定属性值的语句不能保证它是最终值,因为其他地方出现的另一个特定值可以覆盖它。对于复杂的场景,Kustomsize 文件的继承链的检索通常不如 KCL 代码的继承链检索方便,需要仔细考虑指定的配置文件覆盖顺序。此外,Kustomize 无法解决 YAML 配置编写、约束验证、模型抽象和开发等问题,更适合于简单的配置场景。 - -在 KCL 中,配置合并操作可以对代码中的每个配置属性进行细粒度处理,合并策略可以灵活设置,而不限于整体资源,配置之间的依赖关系可以通过KCL的import语句进行静态分析。 - -### vs. Helm - -Helm 的概念源于操作系统的包管理机制。它是一个基于模板化 YAML 文件的包管理工具,支持包中资源的执行和管理。 - -KCL 自然提供了 Helm 功能的超集,因此您可以直接使用 KCL 作为替代。对于采用 Helm 的用户,KCL 中的堆栈编译结果可以打包并以 Helm 格式使用,通过 kpm 包管理工具进行分发复用。此外,我们还可以直接使用 Helm-KCL 插件直接对已有的 Helm Charts 进行无侵入的可编程扩展。 - -### vs. CDK - -用CDK的高级语言编写可以很好地集成到应用程序项目中,这实际上是客户端运行时的一部分。对于KCL,由KCL编写的外部配置和策略与客户端运行时分离。 - -通用语言通常远远超出了需要解决的问题,例如安全问腿、能力边界问题(启动本地线程、访问IO、网络、代码无限循环和其他安全风险)。例如,在音乐领域,有专门的音符来表达音乐,这便于学习和交流,它不能用一般语言表达清楚。 - -此外,由于通用语言风格多样,需要统一维护、管理和自动化。通用语言通常用于编写客户端运行时,它是服务器运行时的延续,不适合编写独立于运行时的配置,被编译成二进制文件,并最终从进程开始运行。此外,GPL 稳定性和可扩展性不易控制。然而,KCL 配置语言通常用于编写数据,将数据与简单逻辑相结合,它描述了预期的最终结果,然后由编译器或引擎使用,既具备丰富的编程抽象能力,又具备方便的数据处理方式。 - -### vs. OPA/Rego - -Rego 起源于逻辑编程,它基于 Datalog,是一种受限制的 Prolog 形式,而 KCL 基于静态类型结构,具备部分 OOP 特性。Rego 类型化特征结构的设计是为了解决 Prolog 在人类语言编码应用中的缺点,将 Datalog 变量用于编程本质上是约束验证任务,Datalog 是一种优秀的查询语言。但对于约束强制执行,它有点麻烦,因为实际上首先需要查询要应用约束的值才能进行校验。 - -此外,KCL 的方法更易于找到规范化、简化、面向人类易读,面向运行时性能优良的约束和校验表示,具备静态类型,并且它更适合于从 OpenAPI 生成或者创建 OpenAPI。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/getting-started/kcl-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/getting-started/kcl-quick-start.md deleted file mode 100644 index 8d75e878..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/getting-started/kcl-quick-start.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -sidebar_position: 3 ---- - -# KCL 语言速览 - -KCL 是一个面相云原生配置策略领域的编程语言。KCL 设计之初受 Python3 启发,同时吸收了声明式、OOP 编程范式的设计理念,是一种专用于配置策略定义、校验的静态强类型的面相配置和策略场景的语言。本节我们将快速展示 KCL 语言的基本特性。 - -## 1. Hello KCL - -学习新语言的最佳途径是自己亲手写几个小程序,配置语言也是如此。KCL 作为一种配置策略语言,我们可以像写配置一样写 KCL 程序。 - -下面是一个简单的 `hello.k` 程序: - -```python -hello = "KCL" -``` - -将 `hello` 属性设置为 `"KCL"` 字符串。然后将代码保存到 `hello.k` 文件中。 - -如何执行这个程序取决于具体的开发环境,我们先假设本地的 macOS 或者是 Linux 系统已经安装了 `kcl` 命令(或者通过 `docker run --rm -it kcllang/kcl` 进入 Docker 环境测试)。然后在文件所在的目录命令行输入以下命令执行: - -```shell -kcl hello.k -``` - -输出为 - -```yaml -hello: KCL -``` - -命令行执行的效果如图所示: - -![](/img/docs/user_docs/getting-started/hello.gif) - -输出的是 YAML 格式的配置数据。这个程序虽然简单,但是我们可以通过执行 KCL 配置程序到输出结果验证了开发环境和 `kcl` 命令行的基本用法。 - -## 2. 再复杂一点的配置 - -常见的配置数据除了的普通的 key-value 对,还有嵌套的字典和列表类型,同时 value 基础类型除了字符串还有布尔和数值等类型。下面是更为复杂一点的 `server.k` 配置: - -```python -# This is a KCL document - -title = "KCL Example" - -owner = { - name = "The KCL Authors" - data = "2020-01-02T03:04:05" -} - -database = { - enabled = True - ports = [8000, 8001, 8002] - data = [["delta", "phi"], [3.14]] - temp_targets = {cpu = 79.5, case = 72.0} -} - -servers = [ - {ip = "10.0.0.1", role = "frontend"} - {ip = "10.0.0.2", role = "backend"} -] -``` - -其中 `#` 开头的表示行注释。`owner` 的 value 是一个字典,字典的面值通过 `{}` 方式包含的内容,字典内部的 key-value 和 `hello = "KCL"` 例子的写法类似。`database` 则是另一个字典,其中字典属性的 value 出现了布尔 `True`、列表 `[]` 和 `{}` 字典,其中列表和字典中还出现了数值类型的 value。 最后一个 `servers` 属性则是一个列表,列表内部嵌套着字典(字典和列表以及后续将要讲到的 `schema` 都可以相互嵌套)。 - -该配置输出的 YAML 结果如下: - -```yaml -$ kcl server.k -title: KCL Example -owner: - name: The KCL Authors - data: '2020-01-02T03:04:05' -database: - enabled: true - ports: - - 8000 - - 8001 - - 8002 - data: - - - delta - - phi - - - 3.14 - temp_targets: - cpu: 79.5 - case: 72.0 -servers: -- ip: 10.0.0.1 - role: frontend -- ip: 10.0.0.2 - role: backend -``` - -## 3. schema 定义配置的结构 - -KCL 通过 `schema` 语法结构为有着固定属性结构和默认值行为的属性提供抽象支持。 - -比如上面例子的中 `database` 的配置一般是用默认值即可。这样我们可以通过为数据库的默认配置定义一个结构: - -```python -schema DatabaseConfig: - enabled: bool = True - ports: [int] = [8000, 8001, 8002] - data: [[str|float]] = [["delta", "phi"], [3.14]] - temp_targets: {str: float} = {cpu = 79.5, case = 72.0} -``` - -`enabled` 是布尔类型;`ports` 为整数列表类型;`data` 为列表的列表,内层的列表元素是字符串或者浮点数类型;`temp_targets` 则是一个字典类型,字典的属性值是浮点数类型。并且 `DatabaseConfig` 的每个属性都定义了默认值。 - -然后通过 `database = DatabaseConfig {}` 就可以产生和默认值相同属性的结构。用户也可以修改默认值: - -```python -database = DatabaseConfig { - ports = [2020, 2021] -} -``` - -`schema DatabaseConfig` 不仅仅为属性提供了默认值,还为属性添加了类型信息。因此,如果用户不小心写错属性值类型的话,KCL 将会给出友好的错误提示,比如下面的例子将 `ports` 错误地写成了浮点数类型: - -```python -database = DatabaseConfig { - ports = [1.2, 1.3] -} -``` - -执行时将产生类似以下的错误(显示的文件路径和本地环境有关): - -```shell -kcl server.k -``` - -输出为 - -```shell -error[E2G22]: TypeError - --> /path/to/server.k:8:5 - | -8 | ports = [1.2, 1.3] - | ^ expected [int], got [float(1.2)|float(1.3)] - | - - --> /path/to/server.k:3:5 - | -3 | ports: [int] = [8000, 8001, 8002] - | ^ variable is defined here, its type is [int], but got [float(1.2)|float(1.3)] - | -``` - -类似地我们可以用以下的代码封装 `servers` 部分的属性: - -```python -schema ServerConfig: - ip: str - role: "frontend" | "backend" - -servers = [ - ServerConfig {ip = "10.0.0.1", role = "frontend"} - ServerConfig {ip = "10.0.0.2", role = "backend"} -] -``` - -其中 `ServerConfig` 的 `ip` 是字符串类型,并没有给出默认值。用户在生成 `ServerConfig` 类型的属性时必须手工添加 `ip` 属性的值,否则 KCL 将会报出缺少必填属性的错误。`role` 属性是 `"frontend" | "backend"` 枚举字符串类型。 - -此外,`schema` 还可以结合 `check`、`mixin`、可选属性、继承和扩展模块实现更为复杂的配置和策略数据的抽象,细节可以参考手册部分的文档。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/_category_.json deleted file mode 100644 index 1fdf894e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "用户手册", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/automation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/automation.md deleted file mode 100644 index 83eb6446..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/automation.md +++ /dev/null @@ -1,205 +0,0 @@ ---- -title: "自动化" -sidebar_position: 6 ---- - -## 简介 - -在 KCL 中提供了很多自动化相关的能力,主要包括工具和多语言 API。 通过 `package_identifier : key_identifier`的模式支持对任意配置键值的索引,从而完成对任意键值的增删改查。比如下图所示修改某个应用配置的镜像内容,可以直接执行如下指令修改镜像,修改前后的 diff 如下图所示。 - -![](/img/blog/2022-09-15-declarative-config-overview/14-kcl-image-update.png) - -此外,KCL 的自动化能力也可以被集成到 CI/CD 中。 - -![](/img/blog/2022-09-15-declarative-config-overview/15-kcl-automation.png) - -## 使用 KCL 进行自动化 - -### 0. 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. 获得示例 - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/automation -``` - -我们可以执行如下命令显示配置 - -```bash -cat main.k -``` - -输出为 - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "app" - replicas = 1 - labels.key = "value" -} -``` - -我们可以执行如下命令输出配置 - -```bash -kcl main.k -``` - -输出为 - -```yaml -app: - name: app - replicas: 1 - labels: - app: app - key: value -``` - -### 2. 使用 KCL CLI 进行自动化 - -KCL 允许使用通过 CLI `-O|--overrides` 参数修改配置模型中的值,这个参数通常由三个部分组成: 包名 `pkg`, 配置标识符 `identifier`, 配置属性 `attribute` 和覆盖值 `override_value` - -```bash -kcl main.k -O override_spec -``` - -- `override_spec`: 表示需要修改的配置模型字段和值的统一表示 - -```bash -override_spec: [[pkgpath] ":"] identifier ("=" value | "-") -``` - -- `pkgpath`: 表示需要修改标识符的包路径,通常为 `a.b.c` 的形式,对于 main 包,`pkgpath` 表示为 `__main__`, 可省略,省略不写时表示 main 包 -- `identifier`: 表示需要修改配置的标识符,通常为 `a.b.c` 的形式 -- `value`: 表示需要修改配置的值,可以是任意合法的 KCL 表达式,比如数字/字符串字面值,`list`/`dict`/`schema` 表达式等 -- `=`: 表示修改identifier的值 -- `-`: 表示删除 identifier 属性 - -请注意,当 `identifier` 多次出现时,修改/删除全部 `identifier` 的值 - -#### 修改配置 - -执行如下命令可以更新应用名称: - -```bash -kcl main.k -O app.name='new_app' -``` - -输出为 - -```yaml -app: - name: new_app - replicas: 1 - labels: - app: new_app - key: value -``` - -可以看出 `app` 的 `name` 属性的值被修改为了 `new_app` - -此外,当我们使用 KCL CLI `-d` 参数时,KCL 文件将同时修改为以下内容 - -```bash -kcl main.k -O app.name='new_app' -d -``` - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "new_app" - replicas = 1 - labels: {key = "value"} -} -``` - -#### 删除配置 - -执行如下命令可以删除 `labels` 中的 `key` 字段 - -```bash -kcl main.k -O app.labels.key- -``` - -输出为: - -```yaml -app: - name: app - replicas: 1 - labels: - app: app -``` - -执行如下命令 - -```bash -kcl main.k -O config.x- -``` - -输出结果为: - -```yaml -config: - x: 1 - y: s -``` - -### 3. 使用 KCL API 进行自动化 - -此外,我们还可以通过[多语言 API](/docs/reference/xlang-api/overview) 自动修改配置属性 - -以 RestAPI 为例 - -执行如下命令启动 RestAPI 服务端 - -```bash -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -通过如下命令 POST 命令请求配置修改服务 - -```bash -curl -X POST http://127.0.0.1:2021/api:protorpc/KclvmService.OverrideFile -H 'content-type: accept/json' -d '{ - "file": "main.k", - "specs": ["app.name=\"nginx\""] -}' -``` - -服务调用完成后,`main.k` 会被修改为如下形式: - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "nginx" - replicas = 1 - labels: { - "key" = "value" - } -} -``` - -## 小结 - -该文档介绍了KCL的自动化功能,包括工具和多语言 API。它支持对任何配置的键值进行索引,允许添加、删除、修改和查询任何键值。它也可以集成到 CI/CD 中。本文档提供了一个使用 KCL 自动化配置管理的示例,包括使用 KCL CLI/API 覆盖和删除配置。更多信息请参阅[此处](/docs/reference/lang/tour#KCL-cli-variable-Override)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/ci-integration/_2-gitlab-ci.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/ci-integration/_2-gitlab-ci.md deleted file mode 100644 index 5ec96ce9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/ci-integration/_2-gitlab-ci.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -id: gitlab-ci -sidebar_label: Gitlab CI ---- - -Coming Soon - -## Introduction - -## How to - -## Summary diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/index.md deleted file mode 100644 index c0613d42..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/index.md +++ /dev/null @@ -1 +0,0 @@ -# 用户手册 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/1-overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/1-overview.md deleted file mode 100644 index ce7b13cb..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/1-overview.md +++ /dev/null @@ -1,3 +0,0 @@ -# 简介 - -KCL 通过包管理工具 [kpm](https://github.com/kcl-lang/kpm) 对 KCL 包进行管理。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/2-installation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/2-installation.md deleted file mode 100644 index 7b0892a5..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/2-installation.md +++ /dev/null @@ -1,53 +0,0 @@ -# 安装 - -## 安装 `kpm` - -kpm 将调用 `KCL`编译器来编译 KCL 程序。在使用 `kpm` 之前,您需要确保 `KCL` 编译器已经成功安装,您可以参照[如何安装 KCL 编译器](https://kcl-lang.io/docs/user_docs/getting-started/install)。 - -### 使用 `go install` 安装 `kpm` - -您可以使用 go install 命令安装 kpm。 - -```shell -go install kcl-lang.io/kpm@latest -``` - -### 从 Github release 页面手动安装 `kpm` - -您可以从 [kpm Github Release](https://github.com/kcl-lang/kpm/releases) 中获取 `kpm` ,并将 `kpm` 的二进制文件路径设置到环境变量 PATH 中。 - -```shell -# KPM_INSTALLATION_PATH 是 `kpm` 二进制文件的所在目录. -export PATH=$KPM_INSTALLATION_PATH:$PATH -``` - -请使用以下命令以确保您成功安装了`kpm`。 - -```shell -kpm --help -``` - -如果你看到以下输出信息,那么你已经成功安装了`kpm`,可以继续执行下一步操作。 - -```shell -NAME: - kpm - kpm is a kcl package manager - -USAGE: - kpm [arguments]... - -COMMANDS: - init initialize new module in current directory - add add new dependency - pkg package a kcl package into tar - metadata output the resolved dependencies of a package - run compile kcl package. - login login to a registry - logout logout from a registry - push push kcl package to OCI registry. - pull pull kcl package from OCI registry. - help, h Shows a list of commands or help for one command - -GLOBAL OPTIONS: - --help, -h show help -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/3-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/3-quick-start.md deleted file mode 100644 index 455987c8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/3-quick-start.md +++ /dev/null @@ -1,108 +0,0 @@ -# 快速开始 - -## 1. 初始化一个空的 KCL 包 - -使用 `kpm init` 命令创建一个名为 `my_package` 的 kcl 程序包, 并且在我们创建完成一个名为 `my_package` 的包后,我们需要通过命令 `cd my_package` 进入这个包来进行后续的操作。 - -```shell -kpm init my_package && cd my_package -``` - -![kpm_init](/img/docs/user_docs/guides/package-management/gifs/kpm_init.gif) - -`kpm` 将会在执行`kpm init my_package`命令的目录下创建两个默认的配置文件 `kcl.mod` 和 `kcl.mod.lock`。 - -```shell -- my_package - |- kcl.mod - |- kcl.mod.lock - |- # 你可以直接在这个目录下写你的kcl程序。 -``` - -`kcl.mod.lock` 是 `kpm` 用来固定依赖版本的文件,是自动生成的,请不要人工修改这个文件。 - -`kpm` 将会为这个新包创建一个默认的 `kcl.mod`。如下所示: - -```shell -[package] -name = "my_package" -edition = "0.0.1" -version = "0.0.1" -``` - -## 2. 为 KCL 包添加依赖 - -然后,您可以通过 `kpm add` 命令来为您当前的库添加一个外部依赖。 - -如下面的命令所示,为当前包添加一个版本号为 `1.27.2` 并且名为 `k8s` 的依赖包。 - -```shell -kpm add k8s:1.27.2 -``` - -![kpm_add_k8s](/img/docs/user_docs/guides/package-management/gifs/kpm_add_k8s.gif) - -`kpm` 会为您将依赖添加到 kcl.mod 文件中. - -```shell -[package] -name = "my_package" -edition = "0.0.1" -version = "0.0.1" - -[dependencies] -k8s = "1.27.2" # The dependency 'k8s' with version '1.27.2' -``` - -## 编写一个程序使用包 `konfig` 中的内容 - -在当前包中创建 `main.k`。 - -```shell -- my_package - |- kcl.mod - |- kcl.mod.lock - |- main.k # Your KCL program. -``` - -并且将下面的内容写入 `main.k` 文件中。 - -```kcl -# 导入并使用外部依赖 `k8s` 包中的内容。 -import k8s.api.core.v1 as k8core - -k8core.Pod { - metadata.name = "web-app" - spec.containers = [{ - name = "main-container" - image = "nginx" - ports = [{containerPort = 80}] - }] -} - -``` - -## 3. 运行 KCL 代码 - -你可以使用 kpm 编译刚才编写的 `main.k` 文件, 得到编译后的结果。 - -```shell -kpm run -``` - -输出为 - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: web-app -spec: - containers: - - image: nginx - name: main-container - ports: - - containerPort: 80 -``` - -![kpm_run](/img/docs/user_docs/guides/package-management/gifs/kpm_run.gif) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md deleted file mode 100644 index 23dd53a5..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md +++ /dev/null @@ -1,73 +0,0 @@ -# 发布 KCL 包到 ghcr.io - -本文将指导您如何使用 kcl 包管理将您的 kcl 包推送到发布到 OCI Registry 中。kcl 包管理默认使用 [ghcr.io](https://ghcr.io) 作为 OCI Registry, 您可以通过修改 kcl 包管理配置文件来更改默认的 OCI Registry。关于如何修改 kcl 包管理配置文件的信息,请参阅 [kcl oci registry](https://github.com/kcl-lang/kpm/blob/main/docs/kpm_oci-zh.md#kpm-registry) - -下面是一个简单的步骤,指导您如何使用 kcl 包管理将您的 kcl 包推送到 ghcr.io。 - -## 步骤 1:安装 KCL CLI - -首先,您需要在您的计算机上安装 KCL CLI。您可以按照 [KCL CLI 安装文档](https://kcl-lang.io/zh-CN/docs/user_docs/getting-started/install)中的说明进行操作。 - -## 步骤 2:创建一个 ghcr.io 令牌 - -如果您使用默认的 OCI Registry, 要将 kcl 包推送到 ghcr.io,您需要创建一个用于身份验证的令牌。您可以参考以下文档。 - -- [创建 ghcr.io token](https://docs.github.com/zh/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic) - -## 步骤 3:登录 ghcr.io - -在安装了 kcl 包管理并创建了 ghcr.io 令牌后,您需要使用 kcl 包管理登录 ghcr.io。您可以使用以下命令进行操作: - -```shell -kcl registry login -u -p ghcr.io -``` - -其中 `` 是您的 GitHub 用户名,`` 是您在步骤 2 中创建的令牌。 - -关于如何使用 kcl 包管理登录 ghcr.io 的更多信息,请参阅 [kcl registry login](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/login)。 - -## 步骤 4:推送您的 kcl 包 - -现在,您可以使用 kcl 包管理将您的 kcl 包推送到 ghcr.io。 - -### 1. 一个合法的 kcl 包 - -首先,您需要确保您推送的内容是符合一个 kcl 包的规范,即必须包含合法的 kcl.mod 和 kcl.mod.lock 文件。 - -如果您不知道如何得到一个合法的 `kcl.mod` 和 `kcl.mod.lock`。您可以使用 `kcl mod init` 命令。 - -```shell -# 创建一个名为 my_package 的 kcl 包 -kcl mod init my_package -``` - -`kcl mod init my_package` 命令将会为您创建一个新的 kcl 包 `my_package`, 并为这个包创建 `kcl.mod` 和 `kcl.mod.lock` 文件。 - -如果您已经有了一个包含 kcl 文件的目录 `exist_kcl_package`,您可以使用以下命令将其转换为一个 kcl 包,并为其创建合法的 `kcl.mod` 和 `kcl.mod.lock`。 - -```shell -# 在 exist_kcl_package 目录下 -$ pwd -/home/user/exist_kcl_package - -# 执行 kcl 包管理init 命令来创建 kcl.mod 和 kcl.mod.lock -$ kcl mod init -``` - -关于如何使用 kcl 包管理init 的更多信息,请参阅 [kcl mod init](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/init)。 - -### 2. 推送 kcl 包 - -您可以在 `kcl` 包的根目录下使用以下命令进行操作: - -```shell -# 在 exist_kcl_package 包的根目录下 -$ pwd -/home/user/exist_kcl_package - -# 推送 kcl 包到默认的 OCI Registry -$ kcl mod push -``` - -完成上述步骤后,您就成功地将您的 kcl 包推送到了默认的 OCI Registry 中。 -关于如何使用 kcl mod push 的更多信息,请参阅 [kcl mod push](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/push)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md deleted file mode 100644 index 9bb9f1cc..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md +++ /dev/null @@ -1,65 +0,0 @@ -# 发布 KCL 包到 docker.io - -本文将指导您如何使用 kcl 包管理将您的 kcl 包推送到发布到 docker.io 中。 - -## 步骤 1:安装 KCL CLI - -首先,您需要在您的计算机上安装 KCL CLI。您可以按照 [KCL CLI 安装文档](https://kcl-lang.io/zh-CN/docs/user_docs/getting-started/install)中的说明进行操作。 - -## 步骤 2:创建一个 docker.io 账户 - -您需要创建一个 docker.io 账户以支持您的 kcl 包的推送。 - -## 步骤 3:登录 docker.io - -您可以直接使用 docker.io 的账户名和密码登录。 - -```shell -kcl registry login -u -p docker.io -``` - -其中 `` 是您的 docker.io 用户名,`` 是您 docker.io 账户的密码。 - -关于如何使用 KCL CLI 登录 docker.io 的更多信息,请参阅 [kcl registry login](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/login)。 - -## 步骤 4:推送您的 kcl 包 - -现在,您可以使用 KCL CLI 将您的 kcl 包推送到 docker.io。 - -### 1. 一个合法的 kcl 包 - -首先,您需要确保您推送的内容是符合一个 kcl 包的规范,即必须包含合法的 kcl.mod 和 kcl.mod.lock 文件。 - -如果您不知道如何得到一个合法的 `kcl.mod` 和 `kcl.mod.lock`。您可以使用 `kcl mod init` 命令。 - -例如:创建一个名为 my_package 的 kcl 包 - -```shell -# 创建一个名为 my_package 的 kcl 包 -kcl mod init my_package -``` - -`kcl mod init my_package` 命令将会为您创建一个新的 kcl 包 `my_package`, 并为这个包创建 `kcl.mod` 和 `kcl.mod.lock` 文件。 - -如果您已经有了一个包含 kcl 文件的目录 `exist_kcl_package`,您可以使用以下命令将其转换为一个 kcl 包,并为其创建合法的 `kcl.mod` 和 `kcl.mod.lock`。 - -在 `exist_kcl_package` 目录下执行: - -```shell -kcl mod init -``` - -关于如何使用 kpm init 的更多信息,请参阅 [kcl mod init](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/init)。 - -### 2. 推送 kcl 包 - -您可以在 `kcl` 包的根目录下使用以下命令进行操作: - -在 `exist_kcl_package` 包的根目录下, 执行 - -```shell -kcl mod push oci://docker.io//exist_kcl_package -``` - -完成上述步骤后,您就成功地将您的 kcl 包 `exist_kcl_package` 推送到了 docker.io 中。 -关于如何使用 kcl mod push 的更多信息,请参阅 [kcl mod push](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/push)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/4-how-to/6-push_github_action.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/4-how-to/6-push_github_action.md deleted file mode 100644 index 2f18b66f..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/4-how-to/6-push_github_action.md +++ /dev/null @@ -1,83 +0,0 @@ -# 如何在 github action 中使用 kcl 包管理发布您的 KCL 包 - -本文将指导您如何在 GitHub Action 中使用 kcl 包管理将您的 kcl 包推送到发布到 ghcr.io 中。 - -## 步骤 1:安装 KCL CLI - -首先,您需要在您的计算机上安装 KCL CLI。您可以按照 [KCL CLI 安装文档](https://kcl-lang.io/zh-CN/docs/user_docs/getting-started/install)中的说明进行操作。 - -## 步骤 2:创建一个 GitHub 账号 - -如果您已经有 GitHub 帐号了,您可以选择跳过这一步 - -[注册新的一个 GitHub 账号](https://docs.github.com/zh/get-started/signing-up-for-github/signing-up-for-a-new-github-account) - -## 步骤 3: 为您的 KCL 包创建一个 GitHub 仓库并进行相关配置 - -### 1. 为您的 KCL 程序包准备仓库 - -您需要为您的 KCL 程序包准备一个 GitHub 仓库。 - -[创建一个 GitHub 仓库](https://docs.github.com/zh/get-started/quickstart/create-a-repo) - -在这个仓库中添加您的 KCL 程序,以仓库 https://github.com/awesome-kusion/catalog.git 为例, - -```bash -├── .github -│ └── workflows -│ └── push.yaml # github action 文件 -├── LICENSE -├── README.md -├── kcl.mod # kcl.mod 将当前仓库内容定义为一个 kcl 包 -├── kcl.mod.lock # kcl.mod.lock 是 kcl 包管理工具自动生成的文件 -└── main.k # 您的 KCL 程序 -``` - -### 2. 为您的仓库设置 OCI Registry,账户和密码 - -以 docker.io 为例,您可以为您的仓库设置 secrets `REG`, `REG_ACCOUNT` 和 `REG_TOKEN`。`REG` 的值为 `docker.io`,`REG_ACCOUNT` 的值为您的 docker.io 账户, `REG_TOKEN` 为您的 `docker.io` 登录密码。 - -[为仓库添加 secrets](https://docs.github.com/zh/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) - -如果您使用 `ghcr.io` 作为 `Registry`, 您需要使用 GitHub token 作为 secrets。 - -[创建一个 GitHub Token](https://docs.github.com/zh/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#personal-access-tokens-classic) - -## 步骤 4: 将您的 KCL 包添加到仓库中并编写 github action workflow - -为这个仓库添加 github action 文件 `.github/workflows/push.yml`,内容如下: - -```yaml -name: KPM Push Workflow - -on: - push: - branches: - - main - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Set up Go 1.21 - uses: actions/setup-go@v2 - with: - go-version: 1.21 - - - name: Install KCL CLI - run: go install kcl-lang.io/cli/cmd/kcl@latest - - - name: Login and Push - env: - # 通过环境变量指定 OCI Registry 和账户 - KPM_REG: ${{ secrets.REG }} - KPM_REPO: ${{ secrets.REG_ACCOUNT }} - # kcl registry login 时使用 secrets.REG_TOKEN - run: kcl registry login -u ${{ secrets.REG_ACCOUNT }} -p ${{ secrets.REG_TOKEN }} ${{ secrets.REG }} && kcl mod push - - - name: Run KCL project from oci registry - run: kcl run oci://${{ secrets.REG }}/${{ secrets.REG_ACCOUNT }}/catalog --tag 0.0.1 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/4-how-to/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/4-how-to/_category_.json deleted file mode 100644 index 370cb4e9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/4-how-to/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "如何使用", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/_category_.json deleted file mode 100644 index d1600bfd..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/package-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "包管理", - "position": 7 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/validation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/validation.md deleted file mode 100644 index 2368ec22..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/validation.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: "校验" -sidebar_position: 2 ---- - -## 简介 - -验证是校验数据是否准确、可靠并满足某些要求或限制的过程,包括检查数据的完整性、一致性、准确性和相关性。进行数据验证是为了确保数据符合其预期目的,并能有效使用。 - -我们可以使用 KCL 及其校验工具手动或自动进行数据验证,以确保数据的一致性。 - -## 使用 KCL 校验数据 - -除了使用 KCL 代码生成 JSON/YAML 等配置格式,KCL 还支持对 JSON/YAML 数据进行格式校验。作为一种配置语言,KCL 在验证方面几乎涵盖了 OpenAPI 的所有功能。在 KCL 中可以通过一个结构定义来约束配置数据,同时支持通过 check 块自定义约束规则,在 schema 中书写校验表达式对 schema 定义的属性进行校验和约束。通过 check 表达式可以非常清晰简单地校验输入的 JSON/YAML 是否满足相应的 schema 结构定义与 check 约束。 - -### 0. 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. 获得示例 - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/validation -``` - -我们可以执行如下命令显示配置 - -```bash -cat schema.k -``` - -输出为 - -```python -schema User: - name: str - age: int - message?: str - data: Data - labels: {str:} - hc: [int] - - check: - age > 10, "age must > 10" - -schema Data: - id: int - value: str -``` - -在 schema 中,我们可以使用 `check` 关键字来编写每个 schema 属性的验证规则。`check` 块中的每一行都对应于一个条件表达式。当满足条件时,验证成功。条件表达式后面可以跟 `, "报错信息"`,以指示检查失败时要给用户显示的消息。 - -综上所述,KCL Schema 中支持的校验类型为: - -| 校验类型 | 使用方法 | -| -------- | ---------------------------------------------------------- | -| 范围校验 | 使用 `<`, `>` 等比较运算符 | -| 正则校验 | 使用 `regex` 系统库中的 `match` 等方法 | -| 长度校验 | 使用 `len` 内置函数,可以求 `list/dict/str` 类型的变量长度 | -| 枚举校验 | 使用字面值联合类型 | -| 非空校验 | 使用 schema 的可选/必选属性 | -| 条件校验 | 使用 check if 条件表达式 | - -### 2. 验证数据 - -新建一个名为 `data.json` 的 JSON 配置文件: - -```json -{ - "name": "Alice", - "age": 18, - "message": "This is Alice", - "data": { - "id": 1, - "value": "value1" - }, - "labels": { - "key": "value" - }, - "hc": [1, 2, 3] -} -``` - -执行如下命令获得校验结果 - -```bash -kcl-vet data.json schema.k -``` - -## 小结 - -KCL 是一种配置语言,通过其结构定义和用户定义的约束规则来支持数据验证。KCL Schema 中支持的验证类型包括范围、正则表达式、长度、枚举、可选/必需和条件。并且可以使用 KCL 验证工具或在此基础上构建的可视化产品来验证数据。 - -## 未来计划 - -KCL 校验能力的提升将逐渐围绕"静态化"方面展开工作,即在编译时,结合形式化验证的能力直接分析得出数据是否满足约束条件、约束条件是否冲突等结论,并且可以通过 IDE 实时透出约束错误,而无需在运行时发现错误。 - -我们还期望 KCL Schema 和约束可以作为一个包来管理(这个包只有 KCL 文件)。例如,Kubernetes 模型和约束可以开箱即用。用户可以生成配置或验证现有配置,并且可以通过 KCL 继承简单地扩展用户想要的模型和约束。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md deleted file mode 100644 index 5ebfe83c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: "从 Kubernetes 迁移" -sidebar_position: 1 ---- - -## 简介 - -KCL 对 Kubernetes 配置提供了许多开箱即用的支持,通过 KCL 工具,我们可以将 Kubernetes Schema 和 配置集成到 KCL 中,本节内容将介绍如何使用 KCL 对 Kubernetes 进行集成 - -### 1. Kubernetes OpenAPI Spec - -从 Kubernetes 1.4 开始,引入了对 OpenAPI 规范(在捐赠给 Open API Initiative 之前称为 swagger 2.0)的 alpha 支持,API 描述遵循 [OpenAPI 规范 2.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md),从 Kubernetes 1.5 开始,Kubernetes 能够直接从[源码自动地提取模型并生成 OpenAPI 规范](https://github.com/kubernetes/kube-openapi),自动化地保证了规范和文档与操作/模型的更新完全同步。 - -此外,Kubernetes CRD 使用 [OpenAPI v3.0 validation](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation) 来描述(除内置属性 apiVersion、kind、metadata 之外的)自定义 schema,在 CR 的创建和更新阶段,APIServer 会使用这个 schema 对 CR 的内容进行校验。 - -### 2. KCL OpenAPI 支持 - -KCLOpenAPI 工具支持从 OpenAPI/CRD 定义提取并生成 KCL schema. 在 KCLOpenAPI Spec 中明确定义了 OpenAPI 规范与 KCL 语言之间的映射关系。 - -### 3. 从 Kubernetes 模型迁移到 KCL - -#### 3.1 基于 kusion_models 编写配置 - -我们为你提供了一个开箱即用的 `kusion_models` 包,让你可以快速开始。其中包含一个精心设计的前端模型,称为[服务器模型](https://github.com/KusionStack/konfig/blob/main/base/pkg/kusion_models/kube/frontend/server.k)(Server schema)。你可以通过初始化 `Server schema` 来声明其配置。有关模式及其属性的说明和用法,请参阅 [Server schema 文档](https://kusionstack.io/docs/reference/model/kusion_models/kube/frontend/doc_server)。 - -#### 3.2 创建自定义的 models 前端模型 - -现有的 `kusion_models` 模型可能无法满足你的特定业务需求,那么你也可以设计自定义前端模型包。 您可基于预先生成的 Kubernetes KCL 包自定义您的前端模型。您还可以仿照`kube2kcl` 工具的模式,开发自定义脚本,完成配置数据的迁移。 - -##### 3.2.1 获取 Kubernetes KCL 模型 - -我们提供了预生成的各版本[Kubernetes KCL模型](https://github.com/orgs/KusionStack/packages/container/package/k8s),您可以在项目下执行 `kpm add k8s:` 来获得它。有关 kpm 使用的详细信息,请参考 [kpm快速入门指南](https://github.com/kcl-lang/kpm#quick-start)。 - -或者,如果您需要自己生成这些包,请参考[从 Kubernetes OpenAPI 文件生成 KCL 包](https://github.com/kcl-lang/kcl-openapi/blob/main/docs/generate_from_k8s_spec.md)。 - -##### 3.2.2 编写自定义前端模型 - -由于 Kubernetes 内置模型较为原子化和复杂,我们推荐以 Kubernetes 原生模型作为后端输出的模型,对其进一步抽象,而向用户暴露一份更为友好和简单的前端模型界面,具体您可参照 Konfig 仓库中 [kusion_models Server](https://github.com/KusionStack/konfig/blob/main/base/pkg/kusion_models/kube/frontend/server.k) 模型的设计方式进行。 - -##### 3.2.3 迁移配置数据 - -对于存量的 Kubernetes 配置数据,您可以仿照 kube2Kcl 工具的做法,编写自定义的转换脚本,进行一键迁移。Kusion 后续将提供该脚本的编写脚手架和编写指南。 - -### 4. 从 Kubernetes CRD 迁移 - -如果您的项目中使用了 CRD,也可以采用类似的模式,生成 CRD 对应的 KCL schema,并基于该 schema 声明 CR。 - -- 从 CRD 生成 KCL Schema - - ``` - kcl-openapi generate model --crd --skip-validation -f your_crd.yaml - ``` - -- 使用 KCL 声明 CR - - 使用 KCL 声明 CR 的模式与声明 Kubernetes 内置模型配置的模式相同,在此不做赘述。 - -## 小结 - -本节介绍了如何使用 kcl-openapi 工具将 OpenAPI 规范映射到 KCL 语言特性,此外提供了将 KCL 与 OpenAPI 和 Kubernetes CRD 一起使用的快速入门指南帮助从 Kubernetes 进行迁移或集成。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md deleted file mode 100644 index e674c946..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md +++ /dev/null @@ -1,249 +0,0 @@ ---- -title: "使用 KCL 生成并管理 Kubernetes 资源配置" -sidebar_position: 2 ---- - -## 简介 - -当我们管理 Kubernetes 资源清单时,我们常常会手写维护,或者使用 Helm 和 Kustomize 等工具来维护我们 YAML 配置或者配置模版,然后通过 kubectl 和 helm 命令行等工具将资源下发到集群。但是作为一个 "YAML 工程师" 每天维护 YAML 配置无疑是琐碎且无聊的,并且容易出错。 - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: ... # Omit -spec: - selector: - matchlabels: - cell: RZ00A - replicas: 2 - template: - metadata: ... # Omit - spec: - tolerations: - - effect: NoSchedules - key: is-over-quota - operator: Equal - value: 'true' - containers: - - name: test-app - image: images.example/app:v1 # Wrong ident - resources: - limits: - cpu: 2 # Wrong type. The type of cpu should be str - memory: 4Gi - # Field missing: ephemeral-storage - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: is-over-quota - operator: In - values: - - 'true' -``` - -- YAML 中的结构化数据是无类型的,缺乏验证方法,无法立即检查所有数据的有效性 -- YAML 编程能力欠佳,容易写出不正确的缩进,也没有逻辑判断等常见代码组织方式,容易写出大量重复配置,难以维护 -- Kubernetes 设计是复杂的,用户很难理解所有细节,比如上面配置中的 `toleration` 和 `affinity` 字段,如果用户不理解调度逻辑,它可能被错误地省略掉或者多余的添加 - -因此,KCL 期望在 Kubernetes YAML 资源管理解决如下问题: - -- 用**生产级高性能编程语言**以**编写代码**的方式提升配置的灵活度,比如条件语句、循环、函数、包管理等特性提升配置重用的能力 -- 在代码层面提升**配置语义验证**的能力,比如字段可选/必选、类型、范围等配置检查能力 -- 提供**配置分块编写、组合和抽象的能力**,比如结构定义、结构继承、约束定义等能力 - -## 先决条件 - -首先可以在 [KCL 快速开始](/docs/user_docs/getting-started/kcl-quick-start) 根据指导下载并安装 KCL,然后准备一个 [Kubernetes](https://kubernetes.io/) 环境 - -## 快速开始 - -### 1. 生成 Kubernetes 资源 - -我们可以编写如下 KCL 代码并命名为 main.k ,KCL 受 Python 启发,基础语法十分接近 Python, 比较容易学习和上手, 配置模式写法很简单,`k [: T] = v`, 其中 `k` 表示配置的属性名称; `v` 表示配置的属性值; `: T` 表示一个可选的类型注解。 - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -上述 KCL 代码中我们分别声明了一个 Kubernetes Deployment 资源的 `apiVersion`、`kind`、`metadata` 和 `spec` 等变量,并分别赋值了相应的内容,特别地,我们将 `metadata.labels` 字段分别重用在 `spec.selector.matchLabels` 和 `spec.template.metadata.labels` 字段。可以看出,相比于 YAML,KCL 定义的数据结构更加紧凑,而且可以通过定义局部变量实现配置重用。 - -我们可以执行如下命令行得到一个 Kubernetes YAML 文件 - -```bash -kcl main.k -``` - -输出为: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -当然我们可以将 KCL 工具与 kubectl 等工具结合使用,让我们执行如下命令并看看效果 - -```shell -kcl main.k | kubectl apply -f - -``` - -输出为 - -```shell -deployment.apps/nginx-deployment configured -``` - -可以从命令行的结果看出与我们使用直接使用 YAML 配置和 kubectl apply 的一个 Deployment 体验完全一致 - -通过 kubectl 检查部署状态 - -```shell -kubectl get deploy -``` - -输出为 - -```shell -NAME READY UP-TO-DATE AVAILABLE AGE -nginx-deployment 3/3 3 3 15s -``` - -### 2. 编写代码管理 Kubernetes 资源 - -对于 Kubernetes 资源发布时,我们常常会遇到配置参数需要动态指定的场景,比如不同的环境需要设置不同的 `image` 字段值生成不同环境的资源。对于这种场景,我们可以通过 KCL 的条件语句和 `option` 函数动态地接收外部参数。我们可以在上述例子的基础上根据不同的环境调整配置参数,比如对于如下代码,我们编写了一个条件语句并输入一个名为 `env` 的动态参数 - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" if option("env") == "prod" else "${metadata.name}:latest" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -使用 KCL 命令行 `-D` 标记接收一个外部设置的动态参数: - -```bash -kcl main.k -D env=prod -``` - -输出为: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -上述代码片段中的 `image = metadata.name + ":1.14.2" if option("env") == "prod" else metadata.name + ":latest"` 意思为:当动态参数 `env` 的值被设置为 `prod` 时,image 字段值为 `nginx:1.14.2`, 否则为 `nginx:latest`,因此我们可以根据需要为 env 设置为不同的值获得不同内容的 Kubernetes 资源。 - -并且 KCL 支持将 option 函数动态参数维护在配置文件中,比如编写下面展示的 `kcl.yaml` 文件 - -```yaml -kcl_options: - - key: env - value: prod -``` - -使用如下命令行也可以得到同样的 YAML 输出,以简化 KCL 动态参数的输入过程 - -```bash -kcl main.k -Y kcl.yaml -``` - -输出为: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## 小结 - -KCL 可以用于生成和管理 Kubernetes 资源,解决管理 YAML 配置的局限性,例如缺乏验证方法和较弱的编程能力等,并可以通过条件语句和 option 函数动态接收外部参数,从而能够根据不同的环境调整配置参数。此外,KCL 可以与 kubectl 等其他工具一起使用将配置一键生效到集群。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md deleted file mode 100644 index 5fe97d05..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: "Kubectl KCL 插件" -sidebar_position: 1 ---- - -## 简介 - -[Kubectl](https://kubernetes.io/docs/reference/kubectl/) is a command line tool for communicating with a Kubernetes cluster's control plane, using the Kubernetes API. You can use the `Kubectl-KCL-Plugin` to - -- Edit the YAML configuration in a hook way to separate data and logic for the Kubernetes manifests management. -- For multi-environment and multi-tenant scenarios, you can maintain these configurations gracefully rather than simply copy and paste. -- Validate all KRM resources using the KCL schema. - -## 前置条件 - -- Install [Kubectl](https://github.com/kubernetes/kubectl) -- Install [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) - -## 快速开始 - -Let’s write a KCL function which add annotation `managed-by=krm-kcl` only to `Deployment` resources in the helm chart. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/kubectl-kcl.git/ -cd ./kubectl-kcl/examples/ -``` - -### 2. Test and Run - -Run the KCL code via the `Kubectl KCL Plugin`. - -```bash -kubectl kcl run -f ./kcl-run.yaml -``` - -The output yaml is - -```yaml -apiVersion: config.kubernetes.io/v1 -kind: ResourceList -items: - - apiVersion: apps/v1 - kind: Deployment - metadata: - annotations: - managed-by: krm-kcl - labels: - app: nginx - name: nginx-deployment - spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - image: "nginx:1.14.2" - name: nginx - ports: - - containerPort: 80 - - apiVersion: v1 - kind: Service - metadata: - name: test - spec: - ports: - - port: 80 - protocol: TCP - targetPort: 9376 - selector: - app: MyApp -functionConfig: - # kcl-fn-config.yaml - apiVersion: krm.kcl.dev/v1alpha1 - kind: KCLRun - metadata: - # EDIT THE SOURCE! - # This should be your KCL code which preloads the `ResourceList` to `option("resource_list") - spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "krm-kcl"}} for resource in option("resource_list").items] -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md deleted file mode 100644 index 271f08e8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: "Helm KCL 插件" -sidebar_position: 2 ---- - -## 简介 - -[Helm](https://github.com/helm/helm) 是一个管理 Charts 的工具。Charts 是预配置的 Kubernetes 资源的包。您可以使用 `Helm-KCL-Plugin` 来完成以下操作: - -- 以 hook 的方式编辑 Helm charts,将数据和逻辑分离以便更好地管理 Kubernetes manifests -- 对于多环境和多租户方案,可以优雅地维护这些配置,而不仅仅是简单地复制和粘贴 -- 使用 KCL 模式验证所有 KRM 资源 - -## 先决条件 - -- 安装 [Helm](https://github.com/helm/helm) -- 安装 [Helm KCL 插件](https://github.com/kcl-lang/helm-kcl) - -## 快速开始 - -让我们编写一个仅向 `Deployment` 资源添加 annotation `managed-by=helm-kcl-plugin` 的 KCL 函数 - -### 1. 获取示例 - -```bash -git clone https://github.com/kcl-lang/helm-kcl.git/ -cd ./helm-kcl/examples/workload-charts-with-kcl -``` - -### 2. 测试和运行 - -通过 `Helm KCL Plugin` 运行KCL代码。 - -```bash -helm kcl template --file ./kcl-run.yaml -``` - -输出的YAML为 - -```yaml -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: workload - app.kubernetes.io/version: 0.1.0 - helm.sh/chart: workload-0.1.0 - name: workload -spec: - ports: - - name: www - port: 80 - protocol: TCP - targetPort: 80 - selector: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - type: ClusterIP ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: workload - app.kubernetes.io/version: 0.1.0 - helm.sh/chart: workload-0.1.0 - name: workload - annotations: - managed-by: helm-kcl-plugin -spec: - selector: - matchLabels: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - template: - metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - spec: - containers: - - image: nginx:alpine - name: frontend -``` - -## KCL 开发指南 - -以下是您可以在 KCL 代码中执行的操作: - -- 从 `option("resource_list")` 读取资源。`option("resource_list")` 符合 [KRM 函数规范](https://kpt.dev/book/05-developing-functions/01-functions-specification)。 你可以从 `option("resource_list")["items"]` 读取输入资源,并从 `option("resource_list")["functionConfig"]` 读取 `functionConfig`。 -- 返回输出资源的 KPM 列表。 -- 使用 `assert {condition},{error_message}` 返回错误消息。 - -## 更多文档和示例 - -- [Helm KCL 插件](https://github.com/kcl-lang/helm-kcl) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md deleted file mode 100644 index 4f1c8c56..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -title: "Kustomize KCL 插件" -sidebar_position: 3 ---- - -## 简介 - -[Kustomize](https://github.com/kubernetes-sigs/kustomize) 允许自定义用于多种目的原始的、无模板的 YAML 文件,同时保留原始 YAML 不变和可用。 - -KCL 可用于创建函数,以改变和/或验证 Kubernetes 资源模型(KRM)的 YAML 输入/输出格式,并且我们提供 Kustomize KCL 函数来简化函数编写过程。 - -## 先决条件 - -- 安装 [kustomize](https://github.com/kubernetes-sigs/kustomize) - -## 快速开始 - -让我们编写一个仅向 Deployment 资源添加 annotation `managed-by=kustomize-kcl` 的 KCL 函数 - -### 1. 获取示例 - -```bash -git clone https://github.com/kcl-lang/kustomize-kcl.git -cd ./kustomize-kcl/examples/set-annotation/ -``` - -### 2. 测试和运行 - -```bash -kustomize fn run ./local-resource/ --dry-run -``` - -输出的YAML为 - -```yaml -apiVersion: krm.kcl.dev/v1alpha1 -kind: KCLRun -metadata: - name: set-annotation - annotations: - config.kubernetes.io/function: | - container: - image: docker.io/kcllang/kustomize-kcl:v0.2.0 - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml -# EDIT THE SOURCE! -# This should be your KCL code which preloads the `ResourceList` to `option("resource_list") -spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "kustomize-kcl"}} for resource in option("resource_list").items] ---- -apiVersion: v1 -kind: Service -metadata: - name: test - annotations: - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml -spec: - selector: - app: MyApp - ports: - - protocol: TCP - port: 80 - targetPort: 9376 ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx - annotations: - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml - managed-by: kustomize-kcl -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## KCL 开发指南 - -以下是可以使用 KCL 执行的操作: - -- 从 `option("resource_list")` 读取资源。`option("resource_list")` 符合 [KRM 函数规范](https://kpt.dev/book/05-developing-functions/01-functions-specification)。 你可以从 `option("resource_list")["items"]` 读取输入资源,并从 `option("resource_list")["functionConfig"]` 读取 `functionConfig`。 -- 返回输出资源的 KPM 列表。 -- 使用 `assert {condition},{error_message}` 返回错误消息。 - -## 更多文档和示例 - -- [Kustomize KCL 插件](https://github.com/kcl-lang/kustomize-kcl) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md deleted file mode 100644 index 1981ae3d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: "KPT KCL SDK" -sidebar_position: 4 ---- - -## 简介 - -[kpt](https://github.com/GoogleContainerTools/kpt) 是一个以包为中心的工具链,可实现配置原地编辑、自动化和交付,通过将声明性配置作为数据进行操作,从而简化 Kubernetes 平台和 KRM 驱动的基础设施(例如,Config Connector、Crossplane)的大规模管理,以实现 Kubernetes 配置编辑的自动化包括转换和验证。 - -KCL 可用于创建函数来转换和/或验证 YAML Kubernetes 资源模型 (KRM) 输入/输出格式,但我们提供 KPT KCL SDK 来简化函数编写过程。 - -## 先决条件 - -- 安装 [kpt](https://github.com/GoogleContainerTools/kpt) -- 安装 [Docker](https://www.docker.com/) - -## 快速开始 - -让我们编写一个仅向 Deployment 资源添加 annotation `managed-by=kpt` 的 KCL 函数 - -### 1. 获取示例 - -```bash -git clone https://github.com/kcl-lang/kpt-kcl-sdk.git/ -cd ./kpt-kcl-sdk/get-started/set-annotation -``` - -### 2. 显示 KRM - -```bash -kpt pkg tree -``` - -输出为 - -```bash -set-annotation -├── [kcl-fn-config.yaml] KCLRun set-annotation -└── data - ├── [resources.yaml] Deployment nginx-deployment - └── [resources.yaml] Service test -``` - -### 3. 显示和更新 KCL `FunctionConfig` - -```bash -cat ./kcl-fn-config.yaml -``` - -输出为 - -```yaml -# kcl-fn-config.yaml -apiVersion: krm.kcl.dev/v1alpha1 -kind: KCLRun -metadata: # kpt-merge: /set-annotation - name: set-annotation -spec: - # 编辑此源代码 - # 您在此的 KCL 代码将 `ResourceList` 预加载到 `option("resource_list")` - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "kpt"}} for resource in option("resource_list").items] -``` - -### 4. 测试和运行 - -通过 kpt 运行 KCL 代码 - -```bash -kpt fn eval ./data -i docker.io/kcllang/kpt-kcl:v0.2.0 --fn-config kcl-fn-config.yaml - -# 验证 annotation 是否添加到 `Deployment` 资源并且其他资源 `Service` 没有这个 annotation。 -cat ./data/resources.yaml | grep annotations -A1 -B0 -``` - -输出为 - -```bash - annotations: - managed-by: kpt -``` - -可以看出,我们确实成功添加了 `managed-by=kpt` 标签 - -## 更多文档和示例 - -- [KPT KCL SDK](https://github.com/kcl-lang/kpt-kcl-sdk) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-konfig/1-overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-konfig/1-overview.md deleted file mode 100644 index b112e946..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-konfig/1-overview.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -id: overview -sidebar_label: 概述 ---- - -# Konfig 概述 - -在 KCL 中推荐通过**配置库**的方式统一管理所有的配置清单和模型库,即不仅存放抽象模型本身的 KCL 定义,还存放各种类型的配置清单,比如应用的运维配置、策略配置等。配置大库推荐托管在各类 VCS 系统中,以方便做配置的回滚和漂移检查。配置大库的最佳实践代号为 Konfig,仓库托管在 [Github](https://github.com/KusionStack/konfig)。 - -⚡️ 配置大库主要包括: - -- KCL 模块声明文件(kcl.mod) -- KCL 领域模型库 (Kubernetes, Prometheus 等) -- 各类配置清单目录 (应用运维配置等) -- 配置构建和测试脚本 (Makefile,Github CI 文件等) - -之所以用一个统一的仓库管理全部的 KCL 配置代码,是由于不同代码包的研发主体不同,会引发出包管理和版本管理的问题。将业务配置代码、基础配置代码在一个统一仓库中,代码间的版本依赖管理会比较简单,通过定位唯一代码库的目录及文件即可,可以将配置代码统一管理,便于查找、修改、维护。 - -下面是配置大库(Konfig)的架构图: - -![](/img/docs/user_docs/guides/konfig/konfig-arch.png) - -Konfig 提供给用户开箱即用、高度抽象的配置界面,模型库最初朴素的出发点就是改善 YAML 用户的效率和体验,我们希望通过将代码更繁杂的模型抽象封装到统一的模型中,从而简化用户侧配置代码的编写。Konfig 由以下部分组成: - -- **核心模型**: - - **前端模型**:前端模型即「用户界面」,包含平台侧暴露给用户的所有可配置属性,其中省略了一些重复的、可推导的配置,抽象出必要属性暴露给用户,具有用户友好的特性,比如 server.k。 - - **后端模型**:后端模型是「模型实现」,是让前端模型属性生效的模型,主要包含前端模型实例的渲染逻辑,后端模型中可借助 KCL 编写校验和逻辑判断等以提高配置代码复用性和健壮性,对用户不感知,比如 server_backend.k -- **领域模型**:是不包含任何实现逻辑和抽象的模型,往往由工具转换生成,无需修改,和真正生效的 YAML 属性一一对应,底层模型需要经过进一步抽象,一般不直接被用户使用。比如,kusion_kubernetes 是 Kubernetes 场景的底层模型库。 - -此外,核心模型内部通过前端模型和后端模型两层抽象简化前端用户的配置代码,底层模型则是通过 KCL OpenAPI 工具自动生成。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-konfig/2-structure.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-konfig/2-structure.md deleted file mode 100644 index cc54087e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-konfig/2-structure.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -id: structure -sidebar_label: 工程结构 ---- - -# Konfig 工程结构 - -本文主要解释 Konfig 配置大库的目录和代码结构 - -## 整体结构 - -```bash -. -├── .github # CI 脚本 -├── Makefile # 通过 Makefile 封装常用命令 -├── README.md # 配置大库说明 -├── appops # 应用运维目录,用来放置所有应用的 KCL 运维配置 -│ ├── clickhouse-operator -│ ├── code-city -│ ├── guestbook -│ ├── http-echo -│ └── nginx-example -├── base # 模型库 -│ ├── examples # 样例代码 -│ │ ├── monitoring # 监控配置样例 -│ │ ├── native # Kubernetes 资源配置样例 -│ │ ├── provider # 基础资源配置样例 -│ │ └── server # 云原生应用运维配置模型样例 -│ └── pkg -│ ├── kusion_kubernetes # Kubernetes 底层模型库 -│ ├── kusion_models # 核心模型库 -│ ├── kusion_prometheus # Prometheus 底层模型库 -│ └── kusion_provider # 基础资源 底层模型库 -└── kcl.mod # 大库配置文件,通常用来标识大库根目录位置以及大库所需依赖 -``` - -## 核心模型库结构 - -核心模型库一般命名为 kusion_models,主要包含前端模型、后端模型、Mixin、渲染器等,目录结构为: - -```bash -├── commons # 基础资源核心模型库 -├── kube # 云原生资源核心模型库 -│ ├── backend # 后端模型 -│ ├── frontend # 前端模型 -│ │ ├── common # 通用前端模型 -│ │ ├── configmap # ConfigMap 前端模型 -│ │ ├── container # 容器前端模型 -│ │ ├── ingress # Ingress 前端模型 -│ │ ├── resource # 资源规格前端模型 -│ │ ├── secret # Secret 前端模型 -│ │ ├── service # Service 前端模型 -│ │ ├── sidecar # Sidecar 容器前端模型 -│ │ ├── strategy # 策略前端模型 -│ │ ├── volume # Volume 前端模型 -│ │ └── server.k # 云原生应用运维前端模型 -│ ├── metadata # 应用运维的元数据模型 -│ ├── mixins # 统一放置可复用的 Mixin -│ ├── render # 渲染器,把前后端模型联系在一起的桥梁 -│ ├── templates # 静态配置 -│ └── utils # 工具方法 -└── metadata # 通用元数据模型 -``` - -## Project 和 Stack 结构 - -![](/img/docs/user_docs/concepts/project-stack.png) - -Project 和 Stack 是用于组织 Konfig 的逻辑隔离概念。 - -### Project - -任何包含文件 "project.yaml" 的文件夹都将被视为一个 Project,"project.yaml" 用于描述此 Project 的元数据,如 "name" 和 "tenant" 等。项目必须具有明确的业务语义,用户可以将应用程序或运维场景映射到项目。 - -### Stack - -与Project一样,包含文件 "stack.yaml" 的任何文件夹都将被视为一个 Stack,"stack.yaml" 用于描述此 Stack 的元数据。Stack 是一组 KCL 文件,表示可以单独配置和部署的最小操作单元,它通常代表 CI/CD 过程中的不同阶段。 - -### Project 与 Stack 之间的关系 - -一个 Project 包含一个或多个 Stack,Stack 必须属于且只能属于一个 Project。用户可以根据自己的需要解释 Project 和 Stack 的含义,并灵活组织 Konfig 结构。根据我们的经验,我们提供以下示例作为最佳实践: - -```bash -├── README.md # Project 介绍文件 -├── base # 各环境通用配置 -│ └── base.k # 通用 KCL 配置 -├── dev # 环境特有配置 -│ ├── ci-test # 测试目录 -│ │ ├── settings.yaml # 测试数据 -│ │ └── stdout.golden.yaml # 测试期望结果 -│ ├── kcl.yaml # 多文件编译配置,是 KCL 编译的入口 -│ ├── main.k # 当前环境 KCL 配置 -│ └── stack.yaml # Stack 配置文件 -└── project.yaml # Project 配置文件 -``` - -Project 通常表示一个应用程序,Stack 表示该应用程序的不同环境的配置,例如 dev、pre 和 prod 等。通用配置可以存储在该 Project 下的 "base" 目录中。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-konfig/3-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-konfig/3-quick-start.md deleted file mode 100644 index 92c9849d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-konfig/3-quick-start.md +++ /dev/null @@ -1,198 +0,0 @@ ---- -id: guide -sidebar_label: 快速开始 ---- - -# 简介 - -本篇指南向你展示,如何使用 KCL 语言与其相对应的 CLI 工具,完成一个运行在 Kubernetes 中的 Long-Running 应用的部署,我们将组织配置的单位叫做应用(Application),描述应用部署和运维细节的配置集合叫做应用服务(Server),它本质上是通过 KCL 定义的运维模型。 - -要将一个运行在 Kubernetes 中的应用完全部署起来,一般需要下发多个 Kubernetes 资源,本次演示的样例涉及以下 Kubernetes 资源: - -- 命名空间(Namespace) -- 无状态工作负载(Deployment) -- 服务(Service) - -> 不清楚相关概念的,可以前往 Kubernetes 官方网站,查看相关说明: - -- [Learn Kubernetes Basics](https://kubernetes.io/docs/tutorials/kubernetes-basics/) -- [Namespace](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/) -- [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) -- [Service](https://kubernetes.io/docs/concepts/services-networking/service/) - -## 准备工作 - -在开始之前,我们需要做以下准备工作: - -1. 安装 KCL, 详情信息请参阅[下载和安装](/docs/user_docs/getting-started/install)。 - -2. 下载开源 Konfig 大库,仓库地址: [https://github.com/KusionStack/konfig.git](https://github.com/KusionStack/konfig.git) - -```shell -git clone https://github.com/KusionStack/konfig.git && cd konfig -``` - -## 快速开始 - -### 1. 配置编译 - -Konfig 的编程语言是 KCL,不是 Kubernetes 认识的 JSON/YAML,因此还需要编译得到最终输出。 - -进入到项目的 Stack 目录(`appops/nginx-example/dev`)并执行编译: - -```bash -cd appops/nginx-example/dev && kcl -Y kcl.yaml -D __konfig_output_format__=raw -``` - -可以获得如下 YAML 输出: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-exampledev - namespace: nginx-example -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - template: - metadata: - labels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - spec: - containers: - - image: nginx:1.7.8 - name: main - ports: - - containerPort: 80 - protocol: TCP - resources: - limits: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi - requests: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi ---- -apiVersion: v1 -kind: Namespace -metadata: - name: nginx-example ---- -apiVersion: v1 -kind: Service -metadata: - name: nginx-example - namespace: nginx-example -spec: - ports: - - nodePort: 30201 - port: 80 - targetPort: 80 - selector: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - type: NodePort -``` - -完成编译,可以看到 3 个资源: - -- 一个 name 为 nginx-exampledev 的 Deployment -- 一个 name 为 nginx-example 的 Namespace -- 一个 name 为 nginx-example 的 Service - -以上就完成了配置生效,后续可以使用 `kubectl apply` 等命令下发并检查资源的实际状态,本文不在赘述。 - -### 2. 配置修改 - -Server 模型中的 image 属性用于声明应用的业务容器镜像,我们可以修改 base/main.k 中的 image 的值进行镜像修改或升级: - -```diff -14c14 -< image = "nginx:1.7.8" ---- -> image = "nginx:latest" -``` - -重新编译配置代码可以获得修改后的 YAML 输出: - -```shell -kcl -Y kcl.yaml -D __konfig_output_format__=raw -``` - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-exampledev - namespace: nginx-example -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - template: - metadata: - labels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - spec: - containers: - - image: nginx:latest - name: main - ports: - - containerPort: 80 - protocol: TCP - resources: - limits: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi - requests: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi ---- -apiVersion: v1 -kind: Namespace -metadata: - name: nginx-example ---- -apiVersion: v1 -kind: Service -metadata: - name: nginx-example - namespace: nginx-example -spec: - ports: - - nodePort: 30201 - port: 80 - targetPort: 80 - selector: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - type: NodePort -``` - -## 小结 - -本文主要介绍了如何使用 KCL 语言与其相对应的 Konfig 库,完成一个运行在 Kubernetes 中的 Long-Running 应用的部署。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-konfig/4-best-practice.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-konfig/4-best-practice.md deleted file mode 100644 index c4bf4b08..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-konfig/4-best-practice.md +++ /dev/null @@ -1,271 +0,0 @@ ---- -id: practice -sidebar_label: 最佳实践 ---- - -# 最佳实践 - -本文档旨在讲解新的业务模型接入 Konfig 大库以及 KCL 代码模型设计与编写的最佳实践,新业务模型一般采用前-后端模型分离的最佳实践进行设计与抽象,区分前端模型和后端模型的直接目的是将「用户界面」和「模型实现」进行分离,实现用户友好的简单的配置界面以及自动化配置增删改查接口。 - -## 工作流程 - -![](/img/docs/user_docs/guides/konfig/workflow.png) - -1. 首先使用 KCL OpenAPI 工具生成下游所需配置的 KCL 模型代码,对于 Kubernetes 模型;可以根据 CRD 或者 Swagger Model 生成,对于其他场景,可以使用 Terraform provider schema、Java Class 或者 Go Struct 生成相应 KCL Schema (建设中),作为后端模型并存放在 "基础配置代码" 中; -2. 使用 KCL 开发工具(包括 KCL 编译器、KCL format,doc,lint,test 等工具和 IDE 插件等),根据业务语义抽象前端模型; -3. 依据 Project & Stack 方式在 Konfig 仓库中组织用户侧配置代码(主要是对前端模型的实例化),Konfig 会自动根据 project.yaml 和 stack.yaml 文件进行测试; -4. 最后编译 KCL 代码生成 YAML,通过测试后,利用 CI/CD 流程完成配置的 diff 与分发。 - -## 模型结构 - -正如 web 应用会提供友好的用户界面,而在应用的后端对用户输入进行进一步推演得到最终落库的数据,类似地,使用 KCL 进行模型设计时同样遵循前后端分离的逻辑。此外当下游所需的数据内容发生变化时,我们仅需修改用户配置数据到后端模型的渲染/逻辑即可,从而避免了大规模修改用户配置的情况。以应用服务的 sidecar 配置为例,直接暴露给用户的只有 `user_sidecar_feature_gates`,而最终交给下游处理的数据中,则应是把 `user_sidecar_feature_gates` 作为 `sidecars` 配置的一部分包装起来的结果。比如如下代码: - -```python -# 用户可配的: -user_sidecar_feature_gates: str - -# 下游能处理的: -sidecars = [ - { - name = "sidecar_name" # sidecars 参数的额外模版参数,用户不需要进行配置 - feature_gates = user_sidecar_feature_gates - } -] -``` - -## Konfig 建模的一些最佳实践 - -### 使用一个属性代替配置模板 - -对于一些后端模型所需要填写的配置字段往往是大而全的设计,需要用户主动输入较为复杂的配置模版,并且不同用户对于该字段的填写内容基本一致,比如在下面示出的超卖逻辑的配置就需要用户填写大量的模板数据,心智成本较高。 - -对于此类常用复杂的模板一个简单的最佳实践是在前端模型中抽象为一个简单的 bool 类型的变量 overQuota,让用户做选择题而不是填空题,比如当 overQuota 变量为 True 时,后端模型才会渲染这个复杂逻辑。 - -- 前端模型属性 `overQuota` - -```python -overQuota: bool -``` - -- 后端模型 YAML 输出 - -```yaml -spec: - template: - spec: - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: k8s/is-over-quota - operator: In - values: - - "true" -``` - -此外也可以根据具体的业务场景设计不同的模版名称来填空,比如如下所示的代码设计一个属性 template 来辅助用户做模版的选择而不是直接填入模板内容。合法的 template 值可以为 "success_ratio" 或者 "service_cost", 当后端模型扩展更多的模版时,前端代码无需作出任何修改,仅需在后端模型中适配相应模板逻辑即可。 - -```python -schema SLI: - template: str = "success_ratio" -``` - -此外,尽量不采用复杂的结构直接作为前端模型属性,避免用户使用该模型时需要借助过多的 KCL 语法特性(比如解包、循环等特性)或者书写很多临时变量完成该结构的实例化。 - -### 使用字面值类型和联合类型 - -在上述小节提到了可以使用一个字符串属性表示不同的模板名称,更进一步地是可以使用字面值类型表述 template 可选的内容,比如可以进行如下改进。 - -```python -schema SLI: - template: "success_ratio" | "service_cost" = "success_ratio" -``` - -其中 template 的类型为两个字符串类型的联合,表示 template 只能为 "success_ratio" 或者 "service_cost",当用户填写了其他字符串的值时,KCL 编译器会进行报错。 - -除了对字面值类型使用联合类型外,KCL 还支持对复杂类型如 schema 类型的联合。对于这种后端 oneof 配置的支持,KCL 内置了复合结构的联合类型进行支持。比如我们可以针对多种种场景定义自己的 SLI 前端类型:CustomSliDataSource,PQLSLIDataSource 和 StackSLIDataSource。 - -```python -schema CustomSLIDataSource: - customPluginUrl: str - -schema PQLSLIDataSource: - total?: str - error?: str - success?: str - cost?: str - count?: str - -schema StackSLIDataSource: - stack: str - groupBy?: str - metric?: str - -# Simplify type definitions using type aliases -type DataSource = CustomSLIDataSource | PQLSLIDataSource | StackSLIDataSource - -schema DataConfiguration: - sources: {str: DataSource} -``` - -这样前端模型设计的好处是编译器可以静态地检查出用户书写的类型只能是某一种类型,如果直接使用后端模型无法从模型上直接获得不同类型 type 与需要填写字段的映射关系。 - -此外,前端模型的整体设计上也应该考虑横向扩展性,尽可能地采用联合类型,充分利用代码化的优势,避免对接不同后端或者后端模型发生改变时带来不必要的大量代码前端代码与用户代码重构与修改。此外,对于其他 GPL 语言中常用的工厂模式,在 KCL 中也可以使用联合类型代替,比如想要根据某个字符串内容获得某个类型的构造函数,可以直接使用联合类型进行优化。 - -KCL 中书写工厂模式 - -```python -schema DataA: - id?: int = 1 - value?: str = "value" - -schema DataB: - name?: str = "DataB" - -_dataFactory: {str:} = { - DataA = DataA - DataB = DataB -} -dataA = _dataFactory["DataA"]() -dataB = _dataFactory["DataB"]() -``` - -使用联合类型替换工厂模式 - -```python -schema DataA: - id?: int = 1 - value?: str = "value" - -schema DataB: - name?: str = "DataB" - -# 直接使用联合类型即可 -dataA: DataA | DataB = DataA() -dataB: DataA | DataB = DataB() -``` - -### 列表/数组属性字典化 - -为了便于作配置的原地修改或者程序自动化查询修改,尽量将列表/数组属性定义为字典类型方便索引,因为在大部分配置场景对于复杂结构的列表类型,列表的索引 0, 1, 2, ..., n 不具备任何业务含义,列表中元素的顺序对该列表配置无任何影响,此时采用字典类型而不是列表类型更方便数据的查询与修改。首先以一个简单例子举例: - -```python -schema Person: - name: str - age: int - -schema House: - persons: [Person] - -house = House { - persons = [ - Person { - name = "Alice" - age = 18 - } - Person { - name = "Bob" - age = 10 - } - ] -} -``` - -比如在上述例子中,想要查询 name 为 "Alice" 的年龄 age, 就需要在 house.persons 这个列表中作遍历才能很查询到 Alice 的 age。而将 persons 定义为如下代码所示的字典,不仅从代码上看起来更加简洁,并且可以通过 house.persons.Alice.age 直接获得 Alice 的 age,并且整个配置的信息完整且无冗余信息。 - -```python -schema Person: - age: int - -schema House: - persons: {str: Person} # 将 persons 定义为字典而不是数组 - -house = House { - persons = { - Alice = Person { age = 18 } - Bob = Person { age = 10 } - } -} -``` - -### 为模型书写校验表达式 - -对于前端模型,往往需要对用户填写的字段进行校验,此时可以使用 KCL 的 check 表达式与 KCL 的内置函数/语法/系统库进行配合对字段进行校验。对于前端模型的校验尽可能直接书写在前端模型的定义中进行校验前置,避免错误传递到后端模型中发生意想不到的错误。 - -使用 all/any 表达式与 check 表达式进行校验 - -```python -import regex - -schema ConfigMap: - name: str - data: {str:str} - configMounts?: [ConfigMount] - - check: - all k in data { - regex.match(k, r"[A-Za-z0-9_.-]*") - }, "a valid config key must consist of alphanumeric characters, '-', '_' or '.'" - -schema ConfigMount: - containerName: str - mountPath: str - subPath?: str - - check: - ":" not in mountPath, "mount path must not contain ':'" -``` - -### 使用数值单位类型 - -KCL 中带单位的数字具有一个内置的类型 units.NumberMultiplier, 不允许进行任意四则运算。 - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -x0: NumberMultiplier = 1M # Ok -x1: NumberMultiplier = x0 # Ok -x2 = x0 + x1 # Error: unsupported operand type(s) for +: 'number_multiplier(1M)' and 'number_multiplier(1M)' -``` - -可以使用 `int()/float()` 函数和 `str()` 函数将数字单位类型转换为整数类型或者字符串类型,产生的字符串保留原有数字单位类型的单位。 - -```python -a: int = int(1Ki) # 1024 -b: str = str(1Mi) # "1Mi" -``` - -对于在 Konfig 中的 Kubernetes Resource 资源相关的定义均可使用数值单位类型进行书写 - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -schema Resource: - cpu?: NumberMultiplier | int = 1 - memory?: NumberMultiplier = 1024Mi - disk?: NumberMultiplier = 10Gi - epchygontee?: int -``` - -### 前端模型实例的自动化修改 - -在 KCL,可以通过命令行和 API 界面实现对前端模型实例的自动化修改,比如想要修改某个应用(Konfig Stack Path: appops/nginx-example/dev)配置的镜像内容,可以直接执行如下指令修改镜像 - -```python -kcl -Y kcl.yaml ci-test/settings.yaml -o ci-test/stdout.golden.yaml -d -O :appConfiguration.image=\"test-image-v1\" -``` - -更多与自动化相关的使用文档请参考 [自动化](/docs/user_docs/guides/automation) 一节 - -### 为模型添加代码注释 - -为便于用户理解以及模型文档自动生成,需要对定义的模型编写注释,注释内容一般包括模型的解释,模型字段的解释,类型,默认值,使用样例等。详细的 KCL Schema 代码注释编写规范以及模型文档自动生成可以参考 [KCL 文档规范](/docs/tools/cli/kcl/docgen) - -## 后端模型 - -后端模型是「模型实现」,主要包括将前端模型映射为后端模型的逻辑代码。当编写完成前端模型后,我们可以使用前端模型 Schema 新建前端模型的实例 instance 并编写相应的后端映射/渲染代码将这些前端 instance 转换为后端模型,并且利用 KCL 多文件编译和 `Schema.instances()` 函数可以做到前端代码和后端代码的高度解耦,用户仅需关心前端的配置而不感知模型复杂的校验、逻辑判断等代码。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-kusion/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-kusion/index.md deleted file mode 100644 index 2906ab83..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-kusion/index.md +++ /dev/null @@ -1,15 +0,0 @@ -# KusionStack - -**KusionStack 是开源的云原生可编程技术栈!** - -KusionStack 是一个可编程、高灵活性的应用交付及运维技术栈,灵感源于融合(Fusion)一词,旨在帮助企业构建的应用运维配置管理平面及 DevOps 生态。 - -1. 融合**专有云**,**混合云**,**多云**混合场景 -2. 融合以**云原生技术**为主,同时采用**多种平台技术**的混合平台技术选型 -3. 融合**多项目**、**多团队**、**多角色**、**多租户**、**多环境**的企业级诉求 - -基于 Platform as Code (平台服务即代码)理念,研发者可以快速收敛围绕**应用运维生命周期**的全量配置定义,面向**混合技术体系及云环境**,完成从应用运维研发到上线的**端到端工作流程**,真正做到**一处编写,随处交付**。 - -![](/img/docs/user_docs/intro/kusion-stack-1.png) - -更多文档请参考: [https://kusionstack.io/](https://kusionstack.io/) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/support/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/support/_category_.json deleted file mode 100644 index d670513b..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/support/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "常见问答", - "position": 6 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/support/faq-cli.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/support/faq-cli.md deleted file mode 100644 index 035c021c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/support/faq-cli.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -sidebar_position: 4 ---- - -# 命令行工具 - -## 1. Konfig 大库应用目录下的 settings.yaml 文件的作用是什么? - -KCL 中 settings.yaml 文件表示 KCL 命令行工具的配置参数文件,可以将编译的配置放入其中进行调用比如需要编译的文件,需要输入的 option 动态参数 `-d`,是否需要忽略掉空值 None `-n` 等配置。 - -比如对于如下的命令行运行参数 - -```shell -kcl main.k -D key=value -n -r -``` - -就可以使用如下的命令行参数和 settings.yaml 配置文件代替 - -```shell -kcl -Y settings.yaml -``` - -settings.yaml - -```yaml -kcl_cli_configs: - files: - - main.k - disable_none: true - strict_range_check: true -kcl_options: - - key: key - value: value -``` - -- `kcl_cli_configs` 表示可以配置的编译参数,`file` 用于配置编译的 KCL 文件,`disable_none` 表示是否使用 `-n` 参数,`strict_range_check` 表示是否使用 `-r` 参数。 -- `kcl_options` 表示可以配置的动态参数,`key` 表示动态参数的名称,`value` 表示动态参数的值 - -注意:settings.yaml 的文件名称可替换,只要其中的配置结构满足规定即可 - -## 2. 如何传入动态参数?如何在代码中获取命令行传入的动态参数? - -KCL 支持多种方式传入动态参数 - -- `-D`: 使用 KCL 命令行的-D 参数可以直接传入动态参数,支持基本数据类型 str/int/float/bool, 以及结构数据类型 list/dict - -```shell -kcl main.k -D env-type=TEST -D deploy-topology='[{"cluster":"my-cluster","idc":"my-idc","replicas":2,"workspace":"my-idc","zone":"my-zone"}]' -``` - -- `-Y`: 使用 KCL 命令行的-Y 参数可以间接通过配置文件传入动态参数: - -```yaml -kcl_options: - - key: env-type - value: TEST - - key: deploy-topology - value: - - cluster: my-cluster - idc: my-idc - replicas: 2 - workspace: my-workspace - zone: my-zone -``` - -在代码中使用内置的 option 函数获取即可 - -```python -env = option("env-type") -deploy_topology = option("deploy-topology") -``` - -输出 YAML - -```yaml -env: TEST -deploy_topology: - - cluster: my-cluster - idc: my-idc - replicas: 2 - workspace: my-workspace - zone: my-zone -``` - -## 3. 如何使用 kcl 的多文件编译特性? - -- 使用 KCL 命令行工具直接书写多文件编译 - -```shell -kcl file1.k file2.k file3.k -``` - -- 在配置文件中配置并配合 KCL 命令行工具参数 `-Y` 使用 - -settings.yaml - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - - file3.k -``` - -```shell -kcl -Y settings.yaml -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/support/faq-install.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/support/faq-install.md deleted file mode 100644 index 1c98f224..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/support/faq-install.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -sidebar_position: 5 ---- - -# 安装问题 - -## MacOS 提示无法打开 "kcl",因为 Apple 无法检查其是否包含恶意软件 - -MacOS 提示无法打开 "kcl",因为 Apple 无法检查其是否包含恶意软件。这个错误是因为 macOS 操作系统中的 Gatekeeper 安全功能阻止了应用程序的运行。要解决此问题,请按照以下步骤操作: - -打开"系统偏好设置"并点击"安全性与隐私"。 在"通用"选项卡中,您将看到一个消息:"kcl" 已被阻止。单击"仍要打开"。 或者,你可以单击"打开任何方式"以打开你的应用程序。(可能需要使用管理员权限来打开应用程序。) - -如果不想在每次打开应用程序时都执行这些步骤,则可以的应用程序添加到白名单中,以便在不受阻止的情况下运行。要将您的应用程序添加到白名单中,请执行以下操作: - -打开终端并输入以下命令: - -```shell -xattr -rd com.apple.quarantine /path/to/kcl -``` - -其中,/path/to/kcl 是 kcl 应用程序的完整路径。运行命令后,应用程序将被添加到白名单中,Gatekeeper 将不再阻止其运行。 - -## 在 Windows/Linux/MacOS 平台上抱 program not found 或者 run linker failed 错误 - -请确保如下依赖在您的 PATH 中 - -- MacOS: `clang` -- Linux: `gcc` -- Windows: `cl.exe` (可以通过安装 MSVC 获得) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/support/faq-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/support/faq-kcl.md deleted file mode 100644 index 8330dfd6..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/support/faq-kcl.md +++ /dev/null @@ -1,2355 +0,0 @@ ---- -sidebar_position: 2 ---- - -# KCL 语法 - -## 1. 如何用 KCL 写一个简单的 key-value 对配置 - -创建一个名为 `config.k` 的文件 - -```python -cpu = 256 -memory = 512 -image = "nginx:1.14.2" -service = "my-service" -``` - -上述 KCL 代码中,定义了 4 个变量 `cpu` 和 `memory` 被声明为整数类型,并且它们的值分别为 `256` 和 `512`,而 `image` 和 `service` 是字符串类型,它们的值分别为 `image` 和 `service` - -使用如下命令可以将上述 KCL 文件编译为 YAML 进行输出 - -``` -kcl config.k -``` - -得到的 YAML 输出为: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -如果想要输出到文件,可以使用 `-o|--output` 参数: - -``` -kcl config.k -o config.yaml -``` - -## 2. KCL 中有哪些基本的数据类型? - -KCL 目前的基本数值类型和值包含: - -- 整数类型 `int` - - 举例: 十进制正整数 `1`, 十进制负整数 `-1`, 十六进制整数 `0x10`, 八进制整数 `0o10`, 二进制整数 `0b10` -- 浮点数类型 `float` - - 举例: 正浮点数 `1.10`, `1.0`, 负浮点数 `-35.59`, `-90.`, 科学记数法浮点数 `32.3e+18`, `70.2E-12` -- 布尔类型 `bool` - - 举例: 真值 `True`, 假值 `False` -- 字符串类型 `str` - 使用引号 `'`, `"` 标记 - - 举例: 双引号字符串 `"string"`, `"""string"""`, 单引号字符串 `'string'`, `'''string'''` -- 列表类型 `list` - 使用 `[`, `]` 标记 - - 举例: 空列表 `[]`, 字符串列表 `["string1", "string2", "string3"]` -- 字典类型 `dict` - 使用 `{`, `}` 标记 - - 举例: 空字典 `{}`, 键值均为字符串类型的字典 `{"key1": "value1", "key2": "value2"}` -- 结构类型 `schema` - 使用关键字 `schema` 定义,并使用相应的 schema 名称进行实例化 -- 空值类型 `None` - 用于表示一个变量的值为空,与输出 YAML 的 `null` 值对应 -- 未定义值类型 `Undefined` - 用于表示一个变量未被赋值,值为 `Undefined` 的变量不会被输出到 YAML 中 - -```python -schema Person: - name: str - age: int - -alice = Person { - name = "Alice" - age = 18 -} -bob = Person { - name = "Bob" - age = 10 -} -``` - -注意: 所有 KCL 类型的变量均可赋值为空值 `None` 和未定义的值 `Undefined` - -## 3. 有些 KCL 变量名带 `_` 下划线前缀表示什么?和不带 `_` 下划线前缀的区别是什么?分别适合什么场景下使用? - -KCL 中带下划线前缀的变量表示一个**隐藏**的,**可变**的变量,**隐藏**表示带下划线前缀的变量不会被输出到 YAML 当中,包括包级别的下划线前缀变量和 schema 当中的下划线前缀变量。**可变**表示带下划线前缀的变量可被多次重复赋值,不带下划线前缀的变量被赋值后不可变。 - -带 `_` 下划线前缀的变量与不带 `_` 下划线前缀变量的区别是: 不带 `_` 下划线前缀变量默认是导出到 YAML 当中的,并且具有强不可变性;带 `_` 下划线前缀变量是不导出的,可变的。 - -```python -name = 'Foo' # 导出变量,不可变变量 -name = 'Bar' # 错误:导出变量只能设置一次 -``` - -```python -_name = 'Foo' # 隐藏变量,可变变量 -_name = 'Bar' - -schema Person: - _name: str # hidden and mutable -``` - -## 4. 如何向 dict 中添加元素? - -可以使用 union 运算符 `|`, 或者 dict 解包运算符 `**` 来向 dict 中添加一个元素,并且可以使用 `in`,`not in` 等关键字判断 dict 变量当中是否包含某一个键值 - -```python -_left = {key: {key1 = "value1"}, intKey = 1} # 注意使用 = 表示覆盖 -_right = {key: {key2 = "value2"}, intKey = 2} -dataUnion = _left | _right # {"key": {"key1": "value1", "key2": "value2"}, "intKey": 2} -dataUnpack = {**_left, **_right} # {"key": {"key1": "value1", "key2": "value2"}, "intKey": 2} -``` - -输出 YAML 为: - -```yaml -dataUnion: - key: - key1: value1 - key2: value2 - intKey: 2 -dataUnpack: - key: - key1: value1 - key2: value2 - intKey: 2 -``` - -此外还可以使用 `字符串插值` 或者字符串 `format` 成员函数特性向 kcl dict 添加变量键值对 - -```python -dictKey1 = "key1" -dictKey2 = "key2" -data = { - "${dictKey1}" = "value1" - "{}".format(dictKey2) = "value2" -} -``` - -输出 YAML 为: - -```yaml -dictKey1: key1 -dictKey2: key2 -data: - key1: value1 - key2: value2 -``` - -## 5. 如何修改 dict 中的元素? - -我们可以使用 union 运算符 `|`, 或者解包运算符 `**` 修改 dict 当中的元素 - -```python -_data = {key = "value"} # {"key": "value"} -_data = _data | {key = "override_value1"} # {"key": "override_value1"} -_data = {**_data, **{key = "override_value2"}} # {"key": "override_value2"} -``` - -如果想要删除 dict 中某个键为 `key` 的值,可以使用解包运算符 `**{key = Undefined}` 或者合并运算符 `| {key = Undefined}` 进行覆盖,覆盖后 key 的值为 Undefined,不会进行 YAML 输出。 - -## 6. 如何向 list 中添加元素? - -在 list 中添加元素有两种方式: - -- 使用 `+`, `+=` 和 slice 切片连接组装 list 变量达到向 list 中添加元素的目的 - -```python -_args = ["a", "b", "c"] -_args += ["end"] # 在list尾部添加元素"end", ["a", "b", "c", "end"] -_args = _args[:2] + ["x"] + _args[2:] # 在list索引为2的地方插入元素"x", ["a", "b", "x", "c", "end"] -_args = ["start"] + _args # 在list头部添加元素"start", ["start", "a", "b", "x", "c", "end"] -``` - -- 使用 `*` 解包运算符连接合并 list - -```python -_args = ["a", "b", "c"] -_args = [*_args, "end"] # 在list尾部添加元素"end", ["a", "b", "c", "end"] -_args = ["start", *_args] # 在list头部添加元素"start", ["start", "a", "b", "c", "end"] -``` - -注意:当接连的变量为 `None/Undefined` 时,使用 `+` 可能会发生错误,这时使用 list 解包运算符 `*` 或者使用 `or` 运算符取 list 的默认值可以避免空值判断 - -```python -data1 = [1, 2, 3] -data2 = None -data3 = [*data1, *data2] # Right [1, 2, 3] -data4 = data1 + data2 or [] # Right [1, 2, 3], 使用 or 取 data2 的默认值为 [], 当 data2 为 None/Undefined 时,取空列表 [] 进行计算 -data5 = data1 + data2 # Error: can only concatenate list (not "NoneType") to list -``` - -## 7. 如何修改/删除 list 中的元素? - -修改 list 中的元素分为两种方式: - -- 直接修改 list 某个索引处的值,使用 slice 切片 - -```python -_index = 1 -_args = ["a", "b", "c"] -_args = _args[:index] + ["x"] + _args[index+1:] # 修改list索引为1的元素为"x", ["a", "x", "c"] -``` - -- 根据某个条件修改 list 当中的元素,使用 list comprehension 列表推导式 - -```python -_args = ["a", "b", "c"] -_args = ["x" if a == "b" else a for a in _args] # 将list当中值为"b"的值都修改为"x", ["a", "x", "c"] -``` - -删除 list 中的元素分为两种方式: - -- 使用 list for 推导表达式中 if 过滤条件 -- 使用 filter 表达式对 list 进行元素过滤 - -比如想要删除一个列表 `[1, 2, 3, 4, 5]` 中大于 2 的数字,则在 KCL 中可以写为: - -```python -originList = [1, 2, 3, 4, 5] -oneWayDeleteListItem = [item for item in originList if item <= 2] -anotherWayDeleteListItem = filter item in originList { - item <= 2 -} -``` - -输出如下结果 - -```yaml -originList: - - 1 - - 2 - - 3 - - 4 - - 5 -oneWayDeleteListItem: - - 1 - - 2 -anotherWayDeleteListItem: - - 1 - - 2 -``` - -## 8. 怎样写 for 循环?怎样理解和使用 list comprehension 列表推导式 和 dict comprehension 字典推导式 ? - -KCL 目前仅支持函数式/声明式的推导式 for 循环方式,可以按照如下方式遍历 dict 和 list 变量: - -list 推导式具体形式为(其中推导式两边使用方括号 `[]`): - -```txt -[expression for expr in sequence1 - if condition1 - for expr2 in sequence2 - if condition2 - for expr3 in sequence3 ... - if condition3 - for exprN in sequenceN - if conditionN] -``` - -dict 推导式具体形式为(其中推导式两边使用花括号 `{}`): - -```txt -{expression for expr in sequence1 - if condition1 - for expr2 in sequence2 - if condition2 - for expr3 in sequence3 ... - if condition3 - for exprN in sequenceN - if conditionN} -``` - -上述推导式中的 `if` 表示过滤条件,满足条件的表达式 `expr` 才会生成到新的 list 或 dict 中 - -list 推导式举例: - -```python -_listData = [1, 2, 3, 4, 5, 6] -_listData = [l * 2 for l in _listData] # _listData中所有元素都乘以2,[2, 4, 6, 8, 10, 12] -_listData = [l for l in _listData if l % 4 == 0] # 筛选出_listData中可以被4整除的所有元素,[4, 8, 12] -_listData = [l + 100 if l % 8 == 0 else l for l in _listData] # 遍历_listData, 当其中的元素可以被8整除时,将该元素加100,否则保持不变, [4, 108, 12] -``` - -注意上述代码中第 3 行和第 4 行两个 `if` 的区别: - -- 第一个 `if` 表示 list 变量 `_listData` 本身的推导式过滤条件,后不能跟 `else`,满足该过滤条件的元素会继续放在该列表中,不满足条件的元素被剔除,有可能会使列表长度发生变化 -- 第二个 `if` 表示 list 迭代变量 `l` 的选择条件,表示 `if-else` 三元表达式,后必须跟 `else`,不论是否满足该条件,产生的元素仍然在该列表中,列表长度不变 - -dict 推导式举例: - -```python -_dictData = {key1 = "value1", key2 = "value2"} -_dictData = {k = _dictData[k] for k in _dictData if k == "key1" and _dictData[k] == "value1"} # 将_dictData中key为"key1", value为"value1"的元素筛选出来, {"key1": "value1"} -``` - -使用推导式获得 dict 所有 key: - -```python -dictData = {key1 = "value1", key2 = "value2"} -dictDataKeys = [k for k in _dictData] # ["key1", "key2"] -``` - -使用推导式对 dict 按照 key 的字典序升序进行排序: - -```python -dictData = {key3 = "value3", key2 = "value2", key1 = "value1"} # {'key3': 'value3', 'key2': 'value2', 'key1': 'value1'} -dictSortedData = {k = dictData[k] for k in sorted(dictData)} # {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'} -``` - -多级推导式举例: - -```python -array1 = [1, 2, 3] -array2 = [4, 5, 6] -data = [a1 + a2 for a1 in array1 for a2 in array2] # [5, 6, 7, 6, 7, 8, 7, 8, 9] len(data) == len(array1) * len(array2) -``` - -双变量循环(for 推导表达式支持 list 的索引迭代以及 dict 的 value 迭代,可以简化 list/dict 迭代过程代码书写): - -- list - -```python -data = [1000, 2000, 3000] -# 单变量循环 -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# 双变量循环 -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# 使用_忽略循环变量 -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -- dict - -```python -data = {key1 = "value1", key2 = "value2"} -# 单变量循环 -dataKeys1 = [k for k in data] # ["key1", "key2"] -dataValues1 = [data[k] for k in data] # ["value1", "value2"] -# 双变量循环 -dataKeys2 = [k for k, v in data] # ["key1", "key2"] -dataValues2 = [v for k, v in data] # ["value1", "value2"] -dataFilter = {k = v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# 使用_忽略循环变量 -dataKeys3 = [k for k, _ in data] # ["key1", "key2"] -dataValues3 = [v for _, v in data] # ["value1", "value2"] -``` - -## 9. 怎样写 if 条件语句? - -KCL 支持两种方式书写 if 条件语句: - -- if-elif-else 块语句,其中 elif 和 else 块均可省略,并且 elif 块可以使用多次 - -```python -success = True -_result = "failed" -if success: - _result = "success" -``` - -```python -success = True -if success: - _result = "success" -else: - _result = "failed" -``` - -```python -_result = 0 -if condition == "one": - _result = 1 -elif condition == "two": - _result = 2 -elif condition == "three": - _result = 3 -else: - _result = 4 -``` - -- 条件表达式 ` if else `, 类似于 C 语言当中的 ` ? : ` 三元表达式 - -```python -success = True -_result = "success" if success else "failed" -``` - -注意:在书写 if-elif-else 块语句时注意书写 if 条件后的冒号 `:` 以及保持缩进的统一 - -除此之外,还可以在 list 或者 dict 结构中直接书写条件表达式(不同的是,在结构中书写的 if 表达式中需要书写的值而不是语句): - -- list - -```python -env = "prod" -data = [ - "env_value" - ":" - if env == "prod": - "prod" # 书写需要添加到 data 中的值,而不是语句 - else: - "other_prod" -] # ["env_value", ":", "prod"] -``` - -- dict - -```python -env = "prod" -config = { - if env == "prod": - MY_PROD_ENV = "prod_value" # 书写需要添加到 config 中的键-值对,而不是语句 - else: - OTHER_ENV = "other_value" -} # {"MY_PROD_ENV": "prod_value"} -``` - -## 10. 怎样表达 "与" "或" "非" 等逻辑运算? - -在 KCL 中,使用 `and` 表示"逻辑与", 使用 `or` 表示"逻辑或", 使用 `not` 表示"非", 与 C 语言当中的 `&&`, `||` 和 `~` 语义一致; - -```python -done = True -col == 0 -if done and (col == 0 or col == 3): - ok = 1 -``` - -对于整数的"按位与", "按位或"和"按位异或",在 KCL 中使用 `&`, `|` 和 `^` 运算符表示, 与 C 语言当中的 `&`, `|` 和 `^` 语义一致; - -```python -value = 0x22 -bitmask = 0x0f - -assert (value & bitmask) == 0x02 -assert (value & ~bitmask) == 0x20 -assert (value | bitmask) == 0x2f -assert (value ^ bitmask) == 0x2d -``` - -"逻辑或" `or` 的妙用:当需要书写诸如 `A if A else B` 类似的模式时,可以使用 `A or B` 进行简化,比如如下代码: - -```python -value = [0] -default = [1] -x0 = value if value else default -x1 = value or default # 使用 value or default 代替 value if value else default -``` - -## 11. 如何判断变量是否为 None/Undefined、字符串/dict/list 是否为空? - -请注意,在 if 表达式的条件判断中,`False`、`None`、`Undefined`、数字 `0`、空列表 `[]`、空字典 `{}` 和空字符串 `""`, `''`, `""""""`, `''''''` 都被视为值为 `假` 的表达式。 - -比如判断一个字符串变量 `strData` 既不为 `None/Undefined` 也不为空字符串时(字符串长度大于 0),就可以简单的使用如下表达式: - -```python -strData = "value" -if strData: - isEmptyStr = False -``` - -空字典和空列表判断举例: - -```python -_emptyList = [] -_emptyDict = {} -isEmptyList = False if _emptyList else True -isEmptyDict = False if _emptyDict else True -``` - -YAML 输出为: - -```yaml -isEmptyList: true -isEmptyDict: true -``` - -或者使用布尔函数 `bool` 进行判断 - -```python -_emptyList = [] -_emptyDict = {} -isEmptyList = bool(_emptyList) -isEmptyDict = bool(_emptyDict) -``` - -## 12. 字符串怎样拼接、怎样格式化字符串、怎样检查字符串前缀、后缀?怎样替换字符串内容? - -- KCL 中可以使用 `+` 运算符连接两个字符串 - -```python -data1 = "string1" + "string2" # "string1string2" -data2 = "string1" + " " + "string2" # "string1 string2" -``` - -- KCL 中目前存在两种格式化字符串的方式: - - 字符串变量的 format 方法 `"{}".format()` - - 字符串插值 `${}` - -```python -hello = "hello" -a = "{} world".format(hello) -b = "${hello} world" -``` - -注意,如果想在 `"{}".format()` 中单独使用 `{` 字符或者 `}`, 则需要使用 `{{` 和 `}}` 分别对 `{` 和 `}` 进行转义,比如转义一个 JSON 字符串如下代码: - -```python -data = "value" -jsonData = '{{"key": "{}"}}'.format(data) -``` - -输出 YAML 为: - -```yaml -data: value -jsonData: '{"key": "value"}' -``` - -注意,如果想在 `${}` 插值字符串中单独使用 `$` 字符,则需要使用 `$$` 对 `$` 进行转义 - -```python -world = "world" -a = "hello {}".format(world) # "hello world" -b = "hello ${world}" # "hello world" -c = "$$hello ${world}$$" # "$hello world$" -c2 = "$" + "hello ${world}" + "$" # "$hello world$" -``` - -输出 YAML 为: - -```yaml -world: world -a: hello world -b: hello world -c: $hello world$ -c2: $hello world$ -``` - -- KCL 中使用字符串的 `startswith` 和 `endswith` 方法检查字符串的前缀和后缀 - -```python -data = "length" -isEndsWith = data.endswith("th") # True -isStartsWith = "length".startswith('len') # True -``` - -- KCL 中使用字符串的 replace 方法或者 regex.replace 函数替换字符串的内容 - -```python -import regex -data1 = "length".replace("len", "xxx") # 使用"xxx"替换"len", "xxxgth" -data2 = regex.replace("abc123", r"\D", "0") # 替换"abc123"中的所有非数字为"0", "000123" -``` - -其中,`r"\D"` 表示不需要使用 `\\` 转义 `\D` 中的反斜杠 `\`,多用于正则表达式字符串中 - -此外,我们可以在字符串格式化表达式中插入索引占位符或者关键字占位符用于格式化多个字符串 - -- 索引占位符 - -```python -x = '{2} {1} {0}'.format('directions', 'the', 'Read') -y = '{0} {0} {0}'.format('string') -``` - -输出为: - -```yaml -x: Read the directions -y: string string string -``` - -- 关键字占位符 - -```python -x = 'a: {a}, b: {b}, c: {c}'.format(a = 1, b = 'Two', c = 12.3) -``` - -输出为: - -```yaml -x: "a: 1, b: Two, c: 12.3" -``` - -## 13. 字符串中使用单引号和双引号的区别是什么? - -KCL 单引号和双引号字符串几乎没有区别。唯一的区别是,不需要在单引号字符串中使用 `\"` 转义双引号 `"`,不需要在双引号字符串中使用 `\'` 转义单引号引号 `'`。 - -```python -singleQuotedString = 'This is my book named "foo"' # Don’t need to escape double quotes in single quoted strings. -doubleQuotedString = "This is my book named 'foo'" # Don’t need to escape single quotes in double quoted strings. -``` - -此外在 KCL 中,使用三个单引号或者三个双引号组成的长字符串,无需在其中对单引号或者三引号进行转义 (除字符串首尾),比如如下例子: - -```python -longStrWithQuote0 = """Double quotes in long strings "(not at the beginning and end)""" -longStrWithQuote1 = '''Double quotes in long strings "(not at the beginning and end)''' -longStrWithQuote2 = """Single quotes in long strings '(not at the beginning and end)""" -longStrWithQuote3 = '''Single quotes in long strings '(not at the beginning and end)''' -``` - -输出 YAML: - -```yaml -longStrWithQuote0: Double quotes in long strings "(not at the beginning and end) -longStrWithQuote1: Double quotes in long strings "(not at the beginning and end) -longStrWithQuote2: Single quotes in long strings '(not at the beginning and end) -longStrWithQuote3: Single quotes in long strings '(not at the beginning and end) -``` - -## 14. 如何编写跨行的长字符串? - -KCL 中可以使用单引号字符串 + 换行符 `\n` 或者三引号字符串书写一个多行字符串,并且可以借助续行符 `\` 优化 KCL 字符串的形式,比如对于如下代码中的三个多行字符串变量,它们的制是相同的: - -```python -string1 = "The first line\nThe second line\nThe third line\n" -string2 = """The first line -The second line -The third line -""" -string3 = """\ -The first line -The second line -The third line -""" # 推荐使用 string3 长字符串的书写形式 -``` - -输出 YAML 为: - -```yaml -string1: | - The first line - The second line - The third line -string2: | - The first line - The second line - The third line -string3: | - The first line - The second line - The third line -``` - -## 15. 如何使用正则表达式? - -通过在 KCL 中导入正则表达式库 `import regex` 即可使用正则表达式,其中包含了如下函数: - -- **match**: 正则表达式匹配函数,根据正则表达式对输入字符串进行匹配,返回 bool 类型表示是否匹配成功 -- **split**: 正则表达式分割函数,根据正则表达式分割字符串,返回分割字串的列表 -- **replace**: 正则表达式替换函数,替换字符串中所有满足正则表达式的子串,返回被替换的字符串 -- **compile**: 正则表达式编译函数,返回 bool 类型表示是否是一个合法的正则表达式 -- **search**: 正则表达式搜索函数,搜索所有满足正则表达式的子串,返回子串的列表 - -使用举例: - -```python -import regex - -regex_source = "Apple,Google,Baidu,Xiaomi" -regex_split = regex.split(regex_source, ",") -regex_replace = regex.replace(regex_source, ",", "|") -regex_compile = regex.compile("$^") -regex_search = regex.search("aaaa", "a") -regex_find_all = regex.findall("aaaa", "a") -regex_result = regex.match("192.168.0.1", "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$") # 判断是否是一个IP字符串 -regex_result_false = regex.match("192.168.0,1", "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$") # 判断是否是一个IP字符串 -``` - -输出 YAML: - -```yaml -regex_source: Apple,Google,Baidu,Xiaomi -regex_split: - - Apple - - Google - - Baidu - - Xiaomi -regex_replace: Apple|Google|Baidu|Xiaomi -regex_compile: true -regex_search: true -regex_find_all: - - a - - a - - a - - a -regex_result: true -regex_result_false: false -``` - -对于比较长的正则表达式,还可以使用 r-string 忽略 `\` 符号的转义简化正则表达式字符串的书写: - -```python -import regex - -isIp = regex.match("192.168.0.1", r"^(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)$") # 判断是否是一个IP字符串 -``` - -更多举例: - -```python -import regex - -schema Resource: - cpu: str = "1" - memory: str = "1024Mi" - disk: str = "10Gi" - check: - regex.match(cpu, r"^([+-]?[0-9.]+)([m]*[-+]?[0-9]*)$"), "cpu must match specific regular expression" - regex.match(memory, r"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"), "memory must match specific regular expression" - regex.match(disk, r"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"), "disk must match specific regular expression" -``` - -```python -import regex - -schema Env: - name: str - value?: str - check: - len(name) <= 63, "a valid env name must be no more than 63 characters" - regex.match(name, r"[A-Za-z_][A-Za-z0-9_]*"), "a valid env name must start with alphabetic character or '_', followed by a string of alphanumeric characters or '_'" -``` - -## 16. KCL 当中的 schema 是什么含义? - -schema 是 KCL 中一种语言元素,用于定义配置数据的类型,像 C 语言中的 struct 或者 Java 中的 class 一样,在其中可以定义属性,每种属性具有相应的类型。 - -## 17. 如何声明 schema? - -KCL 中使用 schema 关键字可以定义一个结构,在其中可以申明 schema 的各个属性 - -```python -# 一个Person结构,其中具有属性字符串类型的firstName, 字符串类型的lastName, 整数类型的age -schema Person: - firstName: str - lastName: str - # age属性的默认值为0 - age: int = 0 -``` - -一个复杂例子: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels: {str:str} -``` - -在上面的代码中,`cpu` 和 `memory` 被定义为整数 int 类型;`name`,`image` 和 `service` 是字符串 str 类型; `command` 是字符串类型的列表; labels 是字典类型,其键类型和值类型均为字符串。 - -## 18. 如何为 schema 属性添加 "不可变"、"必选" 约束? - -KCL 中使用 `?` 运算符定义一个 schema 的"可选"约束,schema 属性默认都是"必选"的 - -```python -# 一个Person结构,其中具有属性字符串类型的firstName, 字符串类型的lastName, 整数类型的age -schema Person: - firstName?: str # firstName是一个可选属性,可以赋值为None/Undefined - lastName?: str # age是一个可选属性,可以赋值为None/Undefined - # age属性的默认值为0 - age: int = 18 # age是一个必选属性,不能赋值为None/Undefined,并且是一个不可变属性 - age = 10 # Error, age是一个不可变的属性 -``` - -## 19. 如何为 schema 中的属性编写校验规则? - -在 schema 定义当中可以使用 check 关键字编写 schema 属性的校验规则, 如下所示,check 代码块中的每一行都对应一个条件表达式,当满足条件时校验成功,当不满足条件时校验失败。条件表达式后可跟 `, "check error message"` 表示当校验失败时需要显示的信息 - -```python -import regex - -schema Sample: - foo: str # Required, 不能为None/Undefined, 且类型必须为str - bar: int # Required, 不能为None/Undefined, 且类型必须为int - fooList: [int] # Required, 不能为None/Undefined, 且类型必须为int列表 - color: "Red" | "Yellow" | "Blue" # Required, 字面值联合类型,且必须为"Red", "Yellow", "Blue"中的一个,枚举作用 - id?: int # Optional,可以留空,类型必须为int - - check: - bar >= 0 # bar必须大于等于0 - bar < 100 # bar必须小于100 - len(fooList) > 0 # fooList不能为None/Undefined,并且长度必须大于0 - len(fooList) < 100 # fooList不能为None/Undefined,并且长度必须小于100 - regex.match(foo, "^The.*Foo$") # regex 正则表达式匹配 - bar in range(100) # range, bar范围只能为1到99 - bar in [2, 4, 6, 8] # enum, bar只能取2, 4, 6, 8 - bar % 2 == 0 # bar必须为2的倍数 - all foo in fooList { - foo > 1 - } # fooList中的所有元素必须大于1 - any foo in fooList { - foo > 10 - } # fooList中至少有一个元素必须大于10 - abs(id) > 10 if id # check if 表达式,当 id 不为空时,id的绝对值必须大于10 -``` - -此外,上述 check 当中比较表达式还可以简写为: - -```python -0 <= bar < 100 -0 < len(fooList) < 100 -``` - -综上所述,KCL Schema 中支持的校验类型为: - -| 校验类型 | 使用方法 | -| -------- | ---------------------------------------------------------- | -| 范围校验 | 使用 `<`, `>` 等比较运算符 | -| 正则校验 | 使用 `regex` 系统库中的 `match` 等方法 | -| 长度校验 | 使用 `len` 内置函数,可以求 `list/dict/str` 类型的变量长度 | -| 枚举校验 | 使用字面值联合类型 | -| 非空校验 | 使用 schema 的可选/必选属性 | -| 条件校验 | 使用 check if 条件表达式 | - -## 20. 如何为 schema 及其属性添加文档注释? - -一个完整的 schema 属性注释使用三引号字符串表示,其中的结构如下所示: - -```python -schema Person: - """The schema person definition - - Attributes - ---------- - name : str - The name of the person - age : int - The age of the person - - See Also - -------- - Son: - Sub-schema Son of the schema Person. - - Examples - -------- - person = Person { - name = "Alice" - age = 18 - } - """ - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -``` - -## 21. 如何基于 schema 编写配置?多个配置之间如何复用公共的配置? - -在 schema 实例化的过程中可以使用解包运算符 `**` 对公共的配置进行展开 - -```python -schema Boy: - name: str - age: int - hc: int - -schema Girl: - name: str - age: int - hc: int - -config = { - age = 18 - hc = 10 -} - -boy = Boy { - **config - name = "Bob" -} -girl = Girl { - **config - name = "Alice" -} -``` - -输出 YAML 为: - -```yaml -config: - age: 18 - hc: 10 -boy: - name: Bob - age: 18 - hc: 10 -girl: - name: Alice - age: 18 - hc: 10 -``` - -## 22. 基于 schema 编写配置时如何覆盖 schema 属性的默认值? - -在定义 schema 后,可以使用 schema 名称实例化相应的配置,使用 `:` 运算符对 schema 默认值进行 union, 使用 `=` 对 schema 默认值进行覆盖。对于 int/float/bool/str 类型的 schema 属性,union 和覆盖的效果相同; 对于 list/dict/schema 类型的 schema 属性,union 和覆盖的效果不同; - -```python -schema Meta: - labels: {str:str} = {"key1" = "value1"} - annotations: {str:str} = {"key1" = "value1"} - -meta = Meta { - labels: {"key2": "value2"} - annotations = {"key2" = "value2"} -} -``` - -输出 YAML 为: - -```yaml -meta: - labels: - key1: value1 - key2: value2 - annotations: - key2: value2 -``` - -## 23. 如何通过继承来复用 schema 定义? - -可以在 schema 定义处声明 schema 需要继承的 schema 名称: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 - -# An employee **is** a person, and has some additional information. -schema Employee(Person): - bankCard: int - nationality: str - -employee = Employee { - firstName = "Bob" - lastName = "Green" - age = 18 - bankCard = 123456 - nationality = "China" -} -``` - -输出 YAML 为: - -```yaml -employee: - firstName: Bob - lastName: Green - age: 18 - bankCard: 123456 - nationality: China -``` - -注意: KCL 只允许 schema 单继承 - -## 24. 如何通过组合复用 schema 逻辑? - -可以使用 KCL schema mixin 复用 schema 逻辑,mixin 一般被用于 schema 内部属性的分离数据,和数据映射等功能,可以使 KCL 代码更具模块化和声明性。注意不同的 mixin 之间的混入属性不建议定义依赖关系,会使得 mixin 使用方式复杂,一般一个 mixin 中作不超过三个属性混入即可。 - -```python -schema Person: - mixin [FullNameMixin, UpperMixin] - - firstName: str - lastName: str - fullName: str - upper: str - -schema FullNameMixin: - fullName = "{} {}".format(firstName, lastName) - -schema UpperMixin: - upper = fullName.upper() - -person = Person { - firstName = "John" - lastName = "Doe" -} -``` - -输出 YAML 为: - -```yaml -person: - firstName: John - lastName: Doe - fullName: John Doe - upper: JOHN DOE -``` - -## 25. 如何导入其他 KCL 文件? - -通过 import 关键字可以导入其他 KCL 文件,KCL 配置文件被组织为模块。单个 KCL 文件被视为一个模块,目录被视为一个包,作为一个特殊的模块。import 关键字支持相对路径导入和绝对路径导入两种方式 - -比如对于如下目录结构: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ │── service1.k - │ └── service2.k - └── mixin - └── mixin1.k -``` - -对于 `main.k`, 相对路径导入和绝对路径导入分别可以表示为: - -```python -import service # 绝对路径导入, 根目录为kcl.mod所在的路径 -import mixin # 绝对路径导入, 根目录为kcl.mod所在的路径 - -import .model1 # 相对路径导入, 当前目录模块 -import ..service # 相对路径导入, 父目录 -import ...root # 相对路径导入, 父目录的父目录 -``` - -注意,对于 KCL 的入口文件 `main.k`, 其不能导入自身所在的文件夹,否则会发生循环导入错误: - -```python -import model # Error: recursively loading -``` - -## 26. 什么情况下可以省略 import ? - -除了 main 包当中的同一文件夹下的 KCL 可以相互引用而不需通过 import 相互引用,比如对于如下目录结构: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ │── service1.k - │ └── service2.k - └── mixin - └── mixin1.k -``` - -当 main.k 作为 KCL 命令行入口文件时, model 文件夹中的 main.k, model1.k 和 model2.k 中的变量不能相互引用,需要通过 import 导入,但是 service 文件夹中的 service1.k 和 service2.k 当中的变量可以互相引用,忽略 import - -service1.k - -```python -schema BaseService: - name: str - namespace: str -``` - -service2.k - -```python -schema Service(BaseService): - id: str -``` - -## 27. 有一行代码太长了,如何在语法正确的情况下优雅地换行? - -在 KCL 中可以使用续行符 `\` 进行换行, 并且在字符串中也可以使用 `\` 表示续行 - -长字符串连接续行举例: - -```python -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " -``` - -推导表达式续行举例: - -```python -data = [1, 2, 3, 4] -dataNew = [ - d + 2 \ - for d in data \ - if d % 2 == 0 -] -``` - -if 表达式续行举例: - -```python -condition = 1 -data1 = 1 \ - if condition \ - else 2 -data2 = 2 \ -if condition \ -else 1 -``` - -三引号字符串内部续行举例: - -```python -longString = """\ -The first line\ -The continue second line\ -""" -``` - -注意: 使用续行符 `\` 的同时缩进的保持, 如下所示: - -错误用例: - -```python -data1 = [ - 1, 2, - 3, 4 \ -] # Error, 需要保持右方括号]的缩进 - -data2 = [ - 1, 2, - 3, 4 -] # Error, 需要数字1和3的缩进统一 -``` - -正确用例: - -```python -data1 = [ - 1, 2, - 3, 4 -] # Right, 带缩进的列表定义 - -data2 = [ \ - 1, 2, \ - 3, 4 \ -] # Right, 使用续行符的列表定义, 实际效果是单行列表 - -data3 = [ \ - 1, 2, \ - 3, 4 \ -] # Right, 使用续行符的列表定义, 无需保持缩进, 实际效果是单行列表 -``` - -## 28. \*_, _ 这些符号是什么意思? - -- `**`, `*` 出现在 dict/list 外部时分别表示乘方运算符和乘法运算符 - -```python -data1 = 2 ** 4 # 2的4次方等于16 -data2 = 2 * 3 # 2乘以3等于6 -``` - -- `**`, `*` 出现在 dict/list 内部时表示解包运算符,经常用于 list/dict 的解包和合并, 与 Python 当中的解包运算符用法相同 - -dict 的解包: - -```python -data = {"key1" = "value1"} -dataUnpack = {**data, "key2" = "value2"} # 将data解包合并入dataUnpack中, {"key1": "value1", "key2": "value2"} -``` - -list 的解包: - -```python -data = [1, 2, 3] -dataUnpack = [*data, 4, 5, 6] # 将data解包合并入dataUnpack中, [1, 2, 3, 4, 5, 6] -``` - -## 29. 如何取 list/dict/schema 的子元素 - -在 KCL 中可以使用 select 表达式或者 subscript 表达式取 list/dict/schema 的子元素 - -- 对于 list 类型,可以使用 `[]` 取列表中的某一个元素或者某一些元素 - -```python -data = [1, 2, 3] # 定义一个整数类型的数组 -theFirstItem = data[0] # 取数组中索引为0的元素,即第一个元素 1 -theSecondItem = data[1] # 取数组中索引为1的元素,即第一个元素 2 -``` - -注意:索引的取值不能超出列表的长度,否则会发生错误,可以使用 `len` 函数获得数组的长度 - -```python -data = [1, 2, 3] -dataLength = len(data) # 数组长度为3 -item = data[3] # 发生数组索引越界错误 -``` - -此外,还可以使用负数索引倒序获得列表中的元素 - -```python -data = [1, 2, 3] -item1 = data[-1] # 取数组中索引为-1的元素,即最后一个元素 3 -item2 = data[-2] # 取数组中索引为-2的元素,即倒数第二个元素 2 -``` - -综上,列表索引的取值范围为 `[-len, len - 1]` - -当想要取得列表的一部分时,可以在 `[]` 中使用切片表达式,其具体语法为 `[<列表开始索引>:<列表终止索引>:<列表遍历步长>]`,注意索引开始终止的取值区间为 `左闭右开[<列表开始索引>, <列表终止索引>)`,注意三个参数均可省略不写 - -```python -data = [1, 2, 3, 4, 5] -dataSlice0 = data[1:2] # 取列表中索引开始为 1, 终止索引为 2 的元素集合 [2] -dataSlice1 = data[1:3] # 取列表中索引开始为 1, 终止索引为 3 的元素集合 [2, 3] -dataSlice2 = data[1:] # 取列表中索引开始为 1, 终止索引为 最后一个索引 的元素集合 [2, 3, 4, 5] -dataSlice3 = data[:3] # 取列表中索引开始为 第一个索引, 终止索引为 3 的元素集合 [1, 2, 3] -dataSlice4 = data[::2] # 取列表中索引开始为 第一个索引, 终止索引为 最后一个索引 的元素集合(步长为2) [1, 3, 5] -dataSlice5 = data[::-1] # 反转一个列表,[5, 4, 3, 2, 1] -dataSlice6 = data[2:1] # 当开始,终止,步长三个参数组合不满足条件时返回空列表 [] - -``` - -- 对于 dict/schema 类型,可以使用 `[]` 和 `.` 两种方式取 dict/schema 中的子元素 - -```python -data = {key1: "value1", key2: "value2"} -data1 = data["key1"] # "value1" -data2 = data.key1 # "value1" -data3 = data["key2"] # "value2" -data4 = data.key2 # "value2" -``` - -```python -schema Person: - name: str = "Alice" - age: int = 18 - -person = Person {} -name1 = person.name # "Alice" -name2 = person["name"] # "Alice" -age1 = person.age # 18 -age2 = person.age # 18 -``` - -当键值在 dict 中不存在时,返回未定义值 `Undefined` - -```python -data = {key1 = "value1", key2 = "value2"} -data1 = data["not_exist_key"] # Undefined -data2 = data.not_exist_key # Undefined -``` - -可以使用 `in` 关键字判断某个键值是否在 dict/schema 中存在 - -```python -data = {key1 = "value1", key2 = "value2"} -exist1 = "key1" in data # True -exist2 = "not_exist_key" in data # False -``` - -当键值中存在 `.` 时或者需要运行时取一个键值变量对应的值时,只能使用 `[]` 方式,如无特殊情况,使用 `.` 即可: - -```python -name = "key1" -data = {key1 = "value1", key2 = "value2", "contains.dot" = "value3"} -data1 = data[name] # "value1" -data2 = data["contains.dot"] # "value3" -# 注意这样子是不对的 data3 = data.contains.dot -``` - -注意:上述取子元素的运算符不能对非 list/dict/schema 集合类型的值进行操作,比如整数,空值等。 - -```python -data = 1 -data1 = 1[0] # error -``` - -```python -data = None -data1 = None[0] # error -``` - -在取集合类型的子元素时往往要进行非空或者长度判断: - -```python -data = [] -item = data[0] if data else None -``` - -可以使用非空判断符 `?` 添加在 `[]`, `.` 的前面表示进行 if 非空判断,当不满足条件时返回 None,比如上述代码可以简化为: - -```python -data = [] -item1 = data?[0] # 当data为空时,返回空值 None -item2 = data?[0] or 1 # 当data为空时,返回空值 None, 如果不想返回 None, 还可与 or 运算符连用返回其他默认值 -``` - -使用 `?` 可以进行递归调用, 避免复杂繁琐的非空判断 - -```python -data = {key1.key2.key3 = []} -item = data?.key1?.key2?.key3?[0] -``` - -## 30. 如何在 KCL 代码中判断变量的类型 - -KCL typeof built-in 函数可以在该函数执行时立即返回一个变量的类型(字符串表示)用于类型断言 - -用法举例: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person{} -t3 = typeof(_x1) - -_x2 = pkg.Person{} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# 输出 -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -## 31. 关键字和 KCL 变量名冲突了可以怎么解决? - -对于与关键字冲突的标识符,可以在标识符前添加 `$` 前缀用于定义一个关键字标识符,比如如下代码中使用了 `if`, `else` 等关键字作为标识符并且可以得到相应的 YAML 输出 - -```python -$if = 1 -$else = "s" - -schema Data: - $filter: str = "filter" - -data = Data {} -``` - -输出 YAML: - -```yaml -data: - filter: filter -if: 1 -else: s -``` - -注意:在非关键字标识符前添加 `$` 前缀的效果与不添加相同 - -```python -_a = 1 -$_a = 2 # 等效于 `_a = 2` -``` - -## 32. KCL 的内置类型是 KCL 的关键字吗?是否可用于变量的定义 - -KCL 的内置类型包括 `int`, `float`, `bool` 和 `str` 四种类型,它们不是 KCL 的关键字,可用于变量的定义,比如如下代码: - -```py -int = 1 -str = 2 -``` - -输出 YAML 为: - -```yaml -int: 1 -str: 2 -``` - -注意:如无特殊需求,不建议变量的名称取这些内置类型,因为在有些语言当中,它们作为关键字存在 - -## 33. 如何在 KCL 中实现类似 Enum 枚举的功能 - -有两种方式可以在 KCL 中实现 Enum 枚举的方式 - -- (推荐)使用**字面值类型**的**联合类型** - -```python -schema Person: - name: str - gender: "Male" | "Female" - -person = Person { - name = "Alice" - gender = "Male" # gender 只能为 "Male" 或者 "Female" -} -``` - -一个复杂例子 - -```python -schema Config: - colors: ["Red" | "Yellow" | "Blue"] # colors 是一个枚举数组 - -config = Config { - colors = [ - "Red" - "Blue" - ] -} -``` - -- 使用 schema 的 check 表达式 - -```python -schema Person: - name: str - gender: "Male" | "Female" - - check: - gender in ["Male", "Female"] - -person = Person { - name = "Alice" - gender = "Male" # gender 只能为 "Male" 或者 "Female" -} -``` - -## 34. 如何求字典 dict 的长度 - -在 KCL 中可以使用 `len` 内置函数直接求 dict 的长度 - -```python -len1 = len({k1: "v1"}) # 1 -len2 = len({k1: "v1", k2: "v2"}) # 2 -varDict = {k1 = 1, k2 = 2, k3 = 3} -len3 = len(varDict) # 3 -``` - -此外,使用 `len` 函数还可以求 `str` 和 `list` 类型长度 - -```python -len1 = len("hello") # 5 -len2 = len([1, 2, 3]) # 3 -``` - -## 35. 如何在 KCL 中编写带条件的配置 - -在 KCL 中,除了支持在顶级的语句中书写 `if-elif-else` 条件表达式以外,还支持在 KCL 复杂结构(list/dict/schema)中书写条件表达式,支持带条件的配置书写。 - -```python -x = 1 -# List 结构中的 if 条件语句 -dataList = [ - if x == 1: 1 -] -# Dict 结构中的 if 条件语句 -dataDict = { - if x == 1: key1 = "value1" # 可以同一行书写 - elif x == 2: - key2 = "value2" # 可以跨行书写 -} -# Schema 结构中的 if 条件语句 -schema Config: - id?: int -env = "prod" -dataSchema = Config { - if env == "prod": - id = 1 - elif env == "pre": - id = 2 - elif env == "test": - id = 3 -} -``` - -## 36. KCL 中的 == 运算符会作深度比较嘛? - -KCL 中的 `==` 运算符 - -- 对于基本类型 `int`, `float`, `bool`, `str` 的变量是直接比较它们的值是否相等 -- 对于复合类型 `list`, `dict`, `schema` 的变量会深度递归地比较其中的子元素是否相等 - - `list` 类型深度递归递归比较每个索引的值以及长度 - - `dict`/`schema` 类型深度递归比较每个属性的值(与属性出现的顺序无关) - -```python -print([1, 2] == [1, 2]) # True -print([[0, 1], 1] == [[0, 1], 1]) # True -print({k1 = 1, k2 = 2} == {k2 = 2, k1 = 1}) # True - -print([1, 2] == [1, 2, 3]) # False -print({k1 = 1, k2 = 2, k3 = 3} == {k2 = 2, k1 = 1}) # False -``` - -## 37. 如何对 KCL 中已有的配置块进行修改 - -在 KCL 中,存在三种**属性运算符** `=`、`+=`、`:`,可以用来对已有配置块进行修改,并且可以使用**解包运算符** `**` 等"继承"一个配置块的所有属性字段和值。 - -- `=` 属性运算符表示覆盖,使用 `=` 运算符可以对属性进行有优先级的覆盖/删除,(如果是用 `Undefined` 覆盖则表示删除) -- `+=` 属性运算符表示添加,一般用于对 list 类型的属性添加子元素,`+=` 属性运算符后跟的操作数类型也只能为 list 类型 -- `:` 属性运算符表示幂等合并,当值发生冲突时进行报错,不冲突时进行合并 - -### 覆盖属性运算符= - -最常使用的属性运算符是 `=`,表示一个属性的赋值,多次对同一个属性进行使用时表示覆盖,对于 `{}` 外的全局变量或者 `{}` 内的属性均表示使用值覆盖这个全局变量或者属性 - -```python -data = { # 定义一个字典类型的变量 data - a = 1 # 使用 = 在 data 中声明一个值为 1 的属性 a - b = 2 # 使用 = 在 data 中声明一个值为 1 的属性 b -} # 最终 data 的值为 {"a": 1, "b": 1} -``` - -在 schema 实例化处也可以使用覆盖属性运算符实现对 schema 默认值的覆盖效果,一般在创建新的 schema 实例时如无特殊的需求,一般使用 `=` 即可 - -```python -schema Person: - name: str = "Alice" # schema Person 的 name 属性具有默认值 "Alice" - age: int = 18 # schema Person 的 age 属性具有默认值 18 - -bob = Person { - name = "Bob" # "Bob" -> "Alice", 属性 name 的值 "Bob" 的值会覆盖 schema Person name 属性的默认值 "Alice" - age = 10 # 10 -> 18, 属性 age 的值 10 的值会覆盖 schema Person age 属性的默认值 18 -} # 最终 bob 的值为 {"name": "Bob", age: 10} -``` - -### 插入属性运算符 += - -插入属性运算符表示对一个属性的值进行原地添加,比如向一个 list 类型的属性添加新的元素 - -```python -data = { - args = ["kcl"] # 使用 = 在 data 中声明一个值为 ["kcl"] 的属性 args - args += ["-Y", "settings.yaml"] # 使用 += 运算符向属性 args 中添加两个元素"-Y", "settings.yaml" -} # 最终 data 的值为 {"args": ["kcl", "-Y", "settings.yaml"]} -``` - -### 合并属性运算符: - -合并属性运算符表示对一个属性的不同配置块值进行幂等的合并,当需要合并的值发生冲突时进行报错,多用于复杂配置合并场景 - -```python -data = { - labels: {key1: "value1"} # 定义一个 labels, 它的类型为 dict, 值为 {"key1": "value1"} - labels: {key2: "value2"} # 使用 : 将 labels 不同的配置值进行合并 -} # 最终 data 的值为 {"labels": {"key1": "value1", "key2": "value2"}} -``` - -合并属性运算符属于幂等运算符,需要合并的配置块的书写顺序不影响其最终结果,比如上述例子中的两个 `labels` 属性也可以调换顺序书写 - -```python -data = { # 同一个属性 labels 的合并书写顺序不影响最终结果 - labels: {key2: "value2"} # 定义一个 labels, 它的类型为 dict, 值为 {"key2": "value2"} - labels: {key1: "value1"} # 使用 : 将 labels 不同的配置值进行合并 -} # 最终 data 的值为 {"labels": {"key1": "value1", "key2": "value2"}} -``` - -注意:合并属性运算符会对合并的值进行冲突检查,当需要合并的配置值发生冲突时进行报错 - -```python -data = { - a: 1 # a 的值为 1 - a: 2 # Error: a 的值 2 不能与 a 的值 1 进行合并,因为其结果存在冲突,且合并是不可交换的 -} -``` - -```python -data = { - labels: {key: "value"} - labels: {key: "override_value"} # Error: 两个 labels 的 key 属性的值 "value" 和 "override_value" 是冲突的,不可合并 -} -``` - -合并运算符对不同类型的使用方式不同 - -- 不同类型的属性不能进行合并 -- 当属性为 int/float/str/bool 等基本类型时,运算符会判断需要合并的值是否相等,不相等时发生合并冲突错误 - -```python -data = { - a: 1 - a: 1 # Ok - a: 2 # Error -} -``` - -- 当属性为 list 类型时 - - 当需要合并的两个 list 长度不相等时,发生合并冲突错误 - - 当需要合并的两个 list 长度相等时,按照索引递归地合并 list 当中的每一个元素 - -```python -data = { - args: ["kcl"] - args: ["-Y", "settings.yaml"] # Error: 两个 args 属性的长度不相同,不能进行合并 - env: [{key1: "value1"}] - env: [{key2: "value2"}] # Ok: 最终 env 属性的值为 [{"key1": "value1"}, {"key2": "value2"}] -} -``` - -- 当属性为 dict/schema 类型时,按照 key 递归地合并 dict/schema 当中的每一个元素 - -```python -data = { - labels: {key1: "value1"} - labels: {key2: "value2"} - labels: {key3: "value3"} -} # 最终 data 的值为 {"labels": {"key1": "value1", "key2": "value2", "key3": "value3"}} -``` - -- 任意类型的属性与 None/Undefined 合并的结果都是其自身 - -```python -data = { - args: ["kcl"] - args: None # Ok - args: Undefined #Ok -} # 最终 data 的值为 {"args": ["kcl"]} -``` - -支持顶级变量使用 `:` 属性声明与合并(仍然可使用 `config = Config {}` 的方式声明一个配置块) - -```python -schema Config: - id: int - value: str - -config: Config { - id: 1 -} -config: Config { - value: "1" -} -""" -此处定义了两个 Config 配置块,使用 : 运算符将可以两个配置块合并在一起,其合并的等效代码如下: -config: Config { - id: 1 - value: "1" -} -""" -``` - -综上所述,合并属性运算符 `:` 的使用场景主要为复杂数据结构 list/dict/schema 的合并操作,一般情况如无特殊需求使用 `=` 和 `+=` 两种属性运算符即可,因此属性运算符的最佳实践如下 - -- 对于基本类型,采用 `=` 运算符 -- 对于 list 类型,一般采用 `=` 和 `+=` 运算符,使用 `=` 表示完全覆盖 list 属性,使用 `+=` 表示向 list 中添加元素 -- 对于 dict/schema 类型,一般采用 `:` 运算符 - -此外,当已经存在一个配置时,可以使用解包运算符 `**` 获得此配置的所有字段值并对其中的字段使用不同属性运算符进行修改,并获得一个新的配置 - -```python -configBase = { - intKey = 1 # 一个 int 类型的属性 - floatKey = 1.0 # 一个 float 类型的属性 - listKey = [0] # 一个 list 类型的属性 - dictKey = {key1: "value1"} # 一个 dict 类型的属性 -} -configNew = { - **configBase # 将 configBase 解包内联到 configNew 中 - intKey = 0 # 使用 覆盖属性运算符 = 将 intKey 属性覆盖为 1 - floatKey = Undefined # 使用 覆盖属性运算符 = 删除 floatKey 属性 - listKey += [1] # 使用 添加属性运算符 += 为 listKey 属性尾部添加一个属性 1 - dictKey: {key2: "value2"} # 使用 合并属性运算符 : 为 dictKey 属性扩展一个键-值对 -} -``` - -输出的 YAML 结果为: - -```yaml -configBase: - intKey: 1 - floatKey: 1.0 - listKey: - - 0 - dictKey: - key1: value1 -configNew: - intKey: 0 - listKey: - - 0 - - 1 - dictKey: - key1: value1 - key2: value2 -``` - -或者可以使用 `|` 运算符对两个配置块合并: - -```python -configBase = { - intKey = 1 # 一个 int 类型的属性 - floatKey = 1.0 # 一个 float 类型的属性 - listKey = [0] # 一个 list 类型的属性 - dictKey = {key1: "value1"} # 一个 dict 类型的属性 -} -configNew = configBase | { # 使用 | 进行合并 - intKey = 0 # 使用 覆盖属性运算符 = 将 intKey 属性覆盖为 1 - floatKey = Undefined # 使用 覆盖属性运算符 = 删除 floatKey 属性 - listKey += [1] # 使用 添加属性运算符 += 为 listKey 属性尾部添加一个属性 1 - dictKey: {key2: "value2"} # 使用 合并属性运算符 : 为 dictKey 属性扩展一个键-值对 -} -``` - -输出的 YAML 结果为: - -```yaml -configBase: - intKey: 1 - floatKey: 1.0 - listKey: - - 0 - dictKey: - key1: value1 -configNew: - intKey: 0 - listKey: - - 0 - - 1 - dictKey: - key1: value1 - key2: value2 -``` - -### KCL 发生 conflicting values on the attribute 'attr' between {value1} and {value2} 错误的解决方式 - -当 KCL 发生类似 conflicting values on the attribute 'attr' between {value1} and {value2} 错误时,一般是合并属性运算符 `:` 的使用问题,表明 `value1` 和 `value2` 配置进行合并时在属性 `attr` 处发生了冲突错误。一般情况将 value2 的 attr 属性修改为其他属性运算符即可,使用 `=` 表示覆盖,使用 `+=` 表示添加 - -比如对于如下代码: - -```python -data = {k: 1} | {k: 2} # Error: conflicting values on the attribute 'k' between {'k': 1} and {'k': 2} -``` - -则可以使用 `=` 属性运算符修改为如下形式 - -```python -data = {k: 1} | {k = 2} # Ok: the value 2 will override the value 1 through the `=` operator -``` - -## 38. KCL 中如何同时遍历多个元素 - -KCL 中可以使用 for 推导表达式遍历多个元素 - -- 举例 1: 使用 for 进行 2 维元素遍历 - -```python -dimension1 = [1, 2, 3] # dimension1 列表的长度是 3 -dimension2 = [1, 2, 3] # dimension2 列表的长度是 3 -matrix = [x + y for x in dimension1 for y in dimension2] # matrix 列表的长度是 9 = 3 * 3 -``` - -输出结果如下: - -```yaml -dimension1: - - 1 - - 2 - - 3 -dimension2: - - 1 - - 2 - - 3 -matrix: - - 2 - - 3 - - 4 - - 3 - - 4 - - 5 - - 4 - - 5 - - 6 -``` - -- 举例 2: 使用 for 循环配合 zip 内置函数按照索引一一对应对多个列表进行遍历 - -```python -dimension1 = [1, 2, 3] # dimension1 列表的长度是 3 -dimension2 = [1, 2, 3] # dimension2 列表的长度是 3 -dimension3 = [d[0] + d[1] for d in zip(dimension1, dimension2)] # dimension3 列表的长度是 3 -``` - -输出结果如下: - -```yaml -dimension1: - - 1 - - 2 - - 3 -dimension2: - - 1 - - 2 - - 3 -dimension3: - - 2 - - 4 - - 6 -``` - -## 39. KCL 中如何为 option 函数设定默认值 - -在 KCL 中,当 option 属性的值为 None/Undefined 空时,可以使用逻辑或 `or` 直接指定一个默认值 - -```python -value = option("key") or "default_value" # 当 key 的值存在时,取 option("key") 的值,否则取 "default_value" -``` - -或者使用 option 函数的 default 参数 - -```python -value = option("key", default="default_value") # 当 key 的值存在时,取 option("key") 的值,否则取 "default_value" -``` - -## 40. KCL 中 schema 怎么检查多个属性不能同时为空或同时设置 - -在 KCL 中,对于 schema 的单个属性不能为空可以使用属性非空标记 - -```python -schema Person: - name: str # required. name 不能为空 - age: int # required. age 不能为空 - id?: int # optional. id 可以留空 -``` - -而对于需要检查 schema 属性不能同时为空或者只能有一者为空的情况时,需要借助 schema check 表达式进行书写,下面以同一个 schema Config 的两个属性 a, b 为例进行说明 - -- Config 的 a, b 属性不能同时为空 - -```python -schema Config: - a?: str - b?: str - - check: - a or b, "a属性和b属性不能同时为空" -``` - -- Config 的 a, b 属性只能有一个为空或者都为空(不能同时存在或不为空) - -```python -schema Config: - a?: str - b?: str - - check: - not a or not b, "a属性和b属性不能同时填写" -``` - -## 41. KCL 中 import 了某个文件但是找不到其同目录下其他 KCL 文件定义的 schema 可能是什么原因 - -可能是与使用 import 仅导入了这个文件夹的这一个文件导致,在 KCL 中,import 支持导入整个文件夹,也支持导入某一个文件夹下的的某一个 KCL 文件,比如对于如下目录结构 - -``` -. -├── kcl.mod -├── main.k -└── pkg - ├── pkg1.k - ├── pkg2.k - └── pkg3.k -``` - -在根目录下存在入口文件 main.k,可以在 main.k 中书写如下代码导入整个 pkg 文件夹,此时 pkg 文件夹下的所有 schema 定义互相可见 - -```python -import pkg -``` - -还可以书写如下代码导入单个文件 pkg/pkg1.k,此时 pkg1.k 不能找到其他文件即 pkg2.k/pkg3.k 下的 schema 定义 - -```python -import pkg.pkg1 -``` - -## 42. KCL 中的缩进是如何处理的? - -在 KCL 中,在出现冒号 `:`、中括号对 `[]` 以及大括号对 `{}` 时,一般需要使用换行 + 缩进,同一缩进级的缩进空格数需要保持一致,一个缩进级一般采用 4 个空格表示 - -- 冒号 `:` 后跟换行 + 缩进 - -```python -"""if 语句中的缩进""" -_a = 1 -_b = 1 -if _a >= 1: # 冒号后跟换行+缩进 - if _a > 8: - _b = 2 - elif a > 6: - _b = 3 - -"""schema 定义中的缩进""" -schema Person: # 冒号后跟换行+缩进 - name: str - age: int -``` - -- 中括号对 `[]` 后跟换行 + 缩进 - -```python -data = [ # 左中括号 [ 后跟换行+缩进 - 1 - 2 - 3 -] # 右中括号 ] 前取消缩进 -``` - -```python -data = [ # 左中括号 [ 后跟换行+缩进 - i * 2 for i in range(5) -] # 右中括号 ] 前取消缩进 -``` - -- 大括号对 `{}` 后跟换行 + 缩进 - -```python -data = { # 左大括号 { 后跟换行+缩进 - k1 = "v1" - k2 = "v2" -} # 右大括号 } 前取消缩进 -``` - -```python -data = { # 左大括号 { 后跟换行+缩进 - str(i): i * 2 for i in range(5) -} # 右大括号 } 前取消缩进 -``` - -## 43. 如何为 KCL 代码编写简单的测试? - -KCL 目前的版本还不支持内部程序调试,可以使用 assert 语句以及 print 函数实现数据的断言和打印查看 - -```python -a = 1 -print("The value of a is", a) -assert a == 1 -``` - -此外,还可以借助 kcl-test 测试工具编写 KCL 内部编写测试用例 - -假设有 hello.k 文件,代码如下: - -```python -schema Person: - name: str = "kcl" - age: int = 1 - -hello = Person { - name = "hello kcl" - age = 102 -} -``` - -构造 hello_test.k 测试文件,内容如下: - -```python -schema TestPerson: - a = Person{} - assert a.name == 'kcl' - -schema TestPerson_age: - a = Person{} - assert a.age == 1 - -schema TestPerson_ok: - a = Person{} - assert a.name == "kcl" - assert a.age == 1 -``` - -然后在目录下执行 kcl-test 命令: - -``` -$ kcl-test -ok /pkg/to/app [365.154142ms] -$ -``` - -## 44. KCL 中如何定义函数或定义方法? - -schema 结构在一定程度上充当了函数的功能,并且这个函数具有多个输入参数和多个输出参数的能力,比如如下代码可以实现一个斐波那契数列的功能: - -```python -schema Fib: - n: int - value: int = 1 if n <= 2 else (Fib {n: n - 1}).value + (Fib {n: n - 2}).value - -fib8 = (Fib {n: 8}).value -``` - -输出结果为: - -```yaml -fib8: 21 -``` - -一个合并列表为字典的 schema 函数 - -```python -schema UnionAll[data, n]: - _?: [] = data - value?: {:} = ((UnionAll(data=data, n=n - 1) {}).value | data[n] if n > 0 else data[0]) if data else {} - -schema MergeList[data]: - """Union一个列表中的所有元素返回合并字典 - - [{"key1": "value1"}, {"key2": "value2"}, {"key3": "value3"}] -> {"key1": "value1", "key2": "value2", "key3": "value3"} - """ - _?: [] = data - value?: {:} = (UnionAll(data=data, n=len(data) - 1) {}).value if data else {} -``` - -此外,KCL 支持使用 `lambda` 关键字定义一个函数: - -```python -func = lambda x: int, y: int -> int { - x + y -} -a = func(1, 1) # 2 -``` - -lambda 函数具有如下特性: - -- lambda 函数将最后一个表达式的值作为函数的返回值,空函数体返回 None。 -- 返回值类型注解可以省略,返回值类型为最后一个表达式值的类型 -- 函数体中没有与顺序无关的特性,所有的表达式都是按顺序执行的 - -```python -_func = lambda x: int, y: int -> int { - x + y -} # 使用 lambda 表达式定义一个函数 -_func = lambda x: int, y: int -> int { - x - y -} # Ok -_func = lambda x: int, y: int -> str { - str(x + y) -} # Error (int, int) -> str can't be assigned to (int, int) -> int -``` - -lambda 函数对象不能参与任何计算,只能在赋值语句和调用语句中使用。 - -```python -func = lambda x: int, y: int -> int { - x + y -} -x = func + 1 # Error: unsupported operand type(s) for +: 'function' and 'int(1)' -``` - -```python -a = 1 -func = lambda x: int { - x + a -} -funcOther = lambda f, para: int { - f(para) -} -r = funcOther(func, 1) # 2 -``` - -输出为: - -```python -a: 1 -r: 2 -``` - -可以定义一个匿名函数并直接调用 - -```python -result = (lambda x, y { - z = 2 * x - z + y -})(1, 1) # 3 -``` - -可以在 for 循环使用使用匿名函数 - -```python -result = [(lambda x, y { - x + y -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 3, 3, 4] -``` - -可以在 KCL schema 中定义并使用函数 - -```python -_funcOutOfSchema = lambda x: int, y: int { - x + y -} -schema Data: - _funcInSchema = lambda x: int, y: int { - x + y - } - id0: int = _funcOutOfSchema(1, 1) - id1: int = _funcInSchema(1, 1) - id2: int = (lambda x: int, y: int { - x + y - })(1, 1) -``` - -输出 YAML 为: - -```yaml -data: - id0: 2 - id1: 2 - id2: 2 -``` - -## 45. 为什么变量赋值为枚举类型(字面值联合类型)时会报错 - -在 KCL 中,被定义为字面值联合类型的属性,在赋值时仅允许接收一个字面值或者同为字面值联合类型的变量,比如如下代码是正确的: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -data = Data { - color = "Red" # Ok, 赋值为 "Red"、"Yellow" 和 "Blue" 均可 -} -``` - -然而以下代码是错误的: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -_color = "Red" - -data = Data { - color = _color # Error: expect str(Red)|str(Yellow)|str(Blue), got str -} -``` - -这是因为没有为变量 `_color` 申明一个类型,它会被 KCL 编译器推导为 `str` 字符串类型,因此当一个 “较大” 的类型 `str` 赋值为一个 “较小” 的类型时 `"Red" | "Yellow" | "Blue"` 会报错,一个解决方式是为 `_color` 变量声明一个类型,以下代码是正确的: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -_color: "Red" | "Yellow" | "Blue" = "Red" - -data = Data { - color = _color # Ok -} -``` - -进一步地,我们可以使用类型别名来简化枚举(字面值联合类型的书写),比如如下代码: - -```python -type Color = "Red" | "Yellow" | "Blue" # 定义一个类型别名,可以在不同的地方重复使用,降低代码书写量 - -schema Data: - color: Color - -_color: Color = "Red" - -data = Data { - color = _color # Ok -} -``` - -## 46. 过程式的 for 循环 - -KCL 中为何不支持过程式的 for 循环! - -KCL 提供了推导表达式以及 all/any/map/filter 表达式等用于对一个集合元素进行处理,满足大部分需求,提供过程式的 for 循环体从目前场景看需求暂时不强烈,因此暂未提供过程式的 for 循环支持 - -此外,KCL 中虽然没有支持过程式的 for 循环,但是可以通过 for 循环和 lambda 函数“构造”相应的过程式 for 循环 - -```python -result = [(lambda x: int, y: int -> int { - # 在其中书写过程式的 for 循环逻辑 - z = x + y - x * 2 -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 2, 4, 4] -``` - -## 47. 默认变量不可变 - -KCL 变量不可变性是指 KCL 顶层结构中的非下划线 `_` 开头的导出变量初始化后不能被改变。 - -```python -schema Person: - name: str - age: int - -a = 1 # a会输出到YAML中,一旦赋值不可修改 -_b = 1 # _b变量以下划线开头命名,不会输出到YAML中, 可多次赋值修改 -_b = 2 -alice = Person { - name = "Alice" - age = 18 -} -``` - -规定变量不可变的方式分为两类: - -- schema 外的非下划线顶层变量 - -```python -a = 1 # 不可变导出变量 -_b = 2 # 可变非导出变量 -``` - -## 48. 在 KCL 中存在类似 Go `interface{}`/`any` 或者 Java `Object` 的类型嘛? - -在 KCL 中,我们可以使用 `any` 类型注解来定义一个变量存储任意类型比如整数、字符串、schema 结构等数据。比如如下例子: - -```python -schema Data: - id: int = 1 - -var_list: [any] = [1, "12", Data {}] -``` - -输出 YAML 为: - -```yaml -var_list: - - 1 - - "12" - - id: 1 -``` - -此外,我们可以使用 `typeof` 函数来判断 KCL 变量的类型: - -```python -schema Data1: - id: int = 1 - -schema Data2: - name: str = "name" - -data_list: [any] = [Data1 {}, Data2 {}] -data_type_list: [str] = [typeof(data) for data in data_list] -``` - -输出 YAML 为: - -```yaml -data_list: - - id: 1 - - name: name -data_type_list: - - Data1 - - Data2 -``` - -## 49. 如何通过编写 KCL 插件进行扩展? - -KCL 插件在 KCL 的 plugins 子目录(通常安装在 `$HOME/.kcl/plugins` 目录),或者通过 `$KCL_PLUGINS_ROOT` 环境变量设置(环境变量优先级更高)。对于插件开发人员,插件都在 [Git 仓库](https://github.com/kcl-lang/kcl-plugin)管理,可以将插件仓库克隆到该目录进行开发。 - -KCL 内置了 kcl-plugin 脚手架命令用于辅助用户使用 Python 语言编写 KCL 插件,以便在 KCL 文件当中调用相应的插件对 KCL 语言本身进行增强,比如访问网络,读写 IO,CMDB 查询和加密解密等功能。 - -``` -usage: kcl-plugin [-h] {list,init,info,gendoc,test} ... - -positional arguments: - {list,init,info,gendoc,test} - kcl plugin sub commands - list list all plugins - init init a new plugin - info show plugin document - gendoc gen all plugins document - test test plugin - -optional arguments: - -h, --help show this help message and exit -``` - -比如想要开发一个名为 io 插件,就可以使用如下命令成功新建一个 io 插件 - -``` -kcl-plugin init io -``` - -然后可以使用如下命令获得 plugin 的根路径并 cd 到相应的 io 插件目录进行开发 - -``` -kcl-plugin info -``` - -比如想要开发一个读文件的函数 read_file,就可以在 `$plugin_root/io` 的 `plugin.py` 中进行 python 代码编写: - -```python -# Copyright 2020 The KCL Authors. All rights reserved. - -import pathlib - -INFO = { - 'name': 'io', - 'describe': 'my io plugin description test', - 'long_describe': 'my io plugin long description test', - 'version': '0.0.1', -} - - -def read_file(file: str) -> str: - """Read string from file""" - return pathlib.Path(file).read_text() - -``` - -另外可以在 `plugin_test.py` 中编写相应的测试函数,也可以直接编写如下所示 KCL 文件进行测试: - -```python -import kcl_plugin.io - -text = io.read_file('test.txt') -``` - -还可以使用 info 命令查看 io 插件的信息 - -``` -kcl-plugin info io -``` - -``` -{ - "name": "io", - "describe": "my io plugin description test", - "long_describe": "my io plugin long description test", - "version": "0.0.1", - "method": { - "read_file": "Read string from file" - } -} -``` - -最后将编写测试完成的插件在 `kcl_plugins` 仓库提 MR 合并即可 - -## 50. 如何在 KCL 中进行基本类型转换 - -可以使用`int()`, `float()`和`str()` 这些内置的方法来进行 `int`, `float` 和 `str` 之间的基本类型转换. - -``` -_t = 1 - -t_str: str = str(_t) # 输出的 t_str 为一个字符串 "t_str: '1'" -t_int: int = int(t_str) # 输出的 t_int 为一个整型 "t_int: 1" -t_float: float = float(t_str) # 输出的 t_float 为一个浮点型 "t_float: 1.0" -``` - -如果您想查看更多详细的关于KCL类型系统和类型转换的内容,您可以查阅 [KCL 内置类型](https://kcl-lang.io/docs/reference/lang/tour#built-in-types) 和 [KCL 类型系统](https://kcl-lang.io/docs/reference/lang/tour#type-system)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/support/faq-yaml.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/support/faq-yaml.md deleted file mode 100644 index 4dd12c00..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/support/faq-yaml.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -sidebar_position: 3 ---- - -# YAML 语法 - -## 1. YAML 字符串使用单引号和双引号的区别是什么? - -- YAML 双引号字符串是唯一能够表达任意字符串的样式,通过使用 `\` 转义字符,比如使用 `\"` 转义双引号 `"`,使用 `\\` 转义反斜杠 `\`,并且可以使用单个反斜杠 `\` 作为双引号字符串的续行符 -- YAML 单引号字符串与 YAML 双引号字符串不同的是可以自由地使用 `\` 和 `"` 而不需要转义,但是使用两个单引号 `''` 转义单引号 `'` 字符 - -比如对于如下的例子,三个字符串变量的内容是相同的 - -```yaml -string1: 'here '' s to "quotes"' -string2: 'here''s to "quotes"' -string3: here's to "quotes" -``` - -因此,KCL 输出 YAML 字符串的策略是当字符串内容出现单引号时,优先输出无引号字符串或双引号字符串,其他情况输出单引号字符串以避免理解上的负担。 - -更多细节可参考: [YAML 规范 v1.2](https://yaml.org/spec/1.2.1/) - -## 2. YAML 中出现的 | - + > 等符号是什么含义? - -在使用 KCL 多行字符串(使用三引号括起来的字符串),输出的 YAML 经常会携带一些特殊的记号,如 `|`,`-`,`+` 和 `>` 等,这些记号通常为 YAML 多行字符串的表示方法,比如对于如下 KCL 代码: - -```python -data = """This is a KCL multi line string (the first line) -This is a KCL multi line string (the second line) -This is a KCL multi line string (the third line) - - -""" -var = 1 -``` - -输出 YAML 为: - -```yaml -data: |+ - This is a KCL multi line string (the first line) - This is a KCL multi line string (the second line) - This is a KCL multi line string (the third line) - - -var: 1 -``` - -- `|` 表示**块字符串样式**,用于表示一个多行字符串,其中的所有换行符都表示字符串真实的换行; -- `>` 表示**块折叠样式**,在其中所有的换行符将被空格替换; -- `+` 和 `-` 用于控制在字符串末尾使用换行符的情况。默认情况为字符串末尾保留单个换行符,如果要删除所有换行符,可以在样式指示符 `|` 或 `>` 后面放置一个 `-` 来完成,如果要保留末尾的换行符,则需要在 `|` 或 `>` 后面放置一个 `+` - -更多细节可参考: [YAML 多行字符串](https://yaml-multiline.info/) 和 [YAML 规范 v1.2](https://yaml.org/spec/1.2.1/) - -## 3. YAML 中在 | - + > 等符号之后出现的数字是什么含义? - -数字表示 YAML 当中的**显式缩进指示符**。对于 YAML 中的长字符串,YAML 通常第一个非空行确定字符串的缩进级别,而当第一个非空行前面具有非前导字符时,比如换行符,YAML 要求必须使用**显式缩进指示符**来指定内容的缩进级别,比如 `|2` 和 `|1` 等 - -比如对于如下 KCL 代码: - -```python -longStringStartWithNewline = """ -This is the second line -This is the third line -""" - -``` - -```yaml -longStringStartWithNewline: |2 - - This is the second line - This is the third line -``` - -如果不需要长字符串开头的空行或换行符,则可以以如下两种方式进行 KCL 长字符串书写 - -- 长字符串从第 1 行开始书写 - -```python -longString = """This is the second line -This is the third line -""" -``` - -- 使用续行符 - -```python -longString = """\ -This is the second line -This is the third line -""" -``` - -以上两种方式输出的 YAML 均为: - -```yaml -longString: | - This is the second line - This is the third line -``` - -更多细节可参考: [YAML 规范 v1.2](https://yaml.org/spec/1.2.1/) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/support/support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/support/support.md deleted file mode 100644 index 648ee5a3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/support/support.md +++ /dev/null @@ -1,3 +0,0 @@ -# 常见问答 - -KCL 安装、使用过程中遇到的常见问题,包括基本概念解释、KCL 语法、KCL 语言设计、命令行工具和 YAML 等常见问题。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5.json deleted file mode 100644 index a9e8bfe5..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "sidebar.user_docs.category.Get Started": { - "message": "快速开始" - }, - "sidebar.user_docs.category.Introduction": { - "message": "简介" - }, - "sidebar.user_docs.category.User Guide": { - "message": "用户手册" - }, - "sidebar.user_docs.guides.category.Automation": { - "message": "自动化" - }, - "sidebar.user_docs.category.Configuration": { - "message": "配置" - }, - "sidebar.user_docs.category.Data Integration": { - "message": "数据集成" - }, - "sidebar.user_docs.category.Package Management": { - "message": "包管理工具" - }, - "sidebar.user_docs.category.How to": { - "message": "如何使用" - }, - "sidebar.user_docs.category.Schema Definition": { - "message": "模型定义" - }, - "sidebar.user_docs.category.Validation": { - "message": "验证" - }, - "sidebar.user_docs.category.Concepts": { - "message": "核心概念" - }, - "sidebar.user_docs.category.FAQ": { - "message": "常见问答" - }, - "sidebar.reference.category.Tutorial": { - "message": "教程" - }, - "sidebar.reference.category.Code Lab": { - "message": "代码实验室" - }, - "sidebar.reference.category.Spec": { - "message": "语言规范" - }, - "sidebar.reference.category.Errors and Warnings": { - "message": "错误与警告" - }, - "sidebar.reference.category.Types": { - "message": "类型系统" - }, - "sidebar.reference.category.System Package": { - "message": "系统模块" - }, - "sidebar.reference.category.Plugin System": { - "message": "插件系统" - }, - "sidebar.reference.category.Multi-Language": { - "message": "多语言集成" - }, - "sidebar.reference.category.Cheat Sheet": { - "message": "备忘表" - }, - "sidebar.reference.category.Package Management": { - "message": "包管理工具" - }, - "sidebar.reference.category.Command Reference": { - "message": "命令参考" - }, - "sidebar.reference.category.Advanced-Concepts": { - "message": "进阶概念" - }, - "sidebar.reference.category.Best-Practices": { - "message": "最佳实践" - }, - "sidebar.tools.category.Command Line Tools": { - "message": "命令行工具" - }, - "sidebar.tools.category.KCL Tools": { - "message": "语言工具" - }, - "sidebar.tools.category.OpenAPI Tools": { - "message": "OpenAPI 工具" - }, - "sidebar.community.category.Community": { - "message": "简介" - }, - "sidebar.community.category.Types": { - "message": "类型系统" - }, - "sidebar.community.category.Contribution Guide": { - "message": "贡献指南" - }, - "sidebar.community.category.Release Policy": { - "message": "发布策略" - }, - "sidebar.docs.category.GitOps": { - "message": "GitOps", - "description": "The label for category GitOps in sidebar docs" - }, - "sidebar.docs.category.CI Integration": { - "message": "CI 集成", - "description": "The label for category CI Integration in sidebar docs" - }, - "sidebar.user_docs.category.GitOps": { - "message": "GitOps", - "description": "The label for category GitOps in sidebar user_docs" - }, - "sidebar.user_docs.category.CI Integration": { - "message": "CI 集成", - "description": "The label for category CI Integration in sidebar user_docs" - }, - "sidebar.docs.category.Mutate or Validate Kubernetes Manifests": { - "message": "编辑或验证 Kubernetes 资源", - "description": "The label for category Mutate or Validate Kubernetes Manifests in sidebar docs" - }, - "sidebar.user_docs.category.Mutate or Validate Kubernetes Manifests": { - "message": "编辑或验证 Kubernetes 资源", - "description": "The label for category Mutate or Validate Kubernetes Manifests in sidebar user_docs" - }, - "sidebar.docs.category.Secret Management": { - "message": "敏感信息管理", - "description": "The label for category Secret Management in sidebar docs" - }, - "sidebar.user_docs.category.Secret Management": { - "message": "敏感信息管理", - "description": "The label for category Secret Management in sidebar user_docs" - } -} \ No newline at end of file diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/_category_.json deleted file mode 100644 index f763b5c8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "社区", - "position": 5 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/contribute/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/contribute/_category_.json deleted file mode 100644 index 131bb8e3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/contribute/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "贡献指南", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/contribute/contribute-code.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/contribute/contribute-code.md deleted file mode 100644 index 8e8392fe..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/contribute/contribute-code.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -sidebar_position: 2 ---- - -# 如何贡献代码? - -欢迎参与 KCL 共建贡献完善代码、完善代码文档和测试,同时也欢迎通过 Issue 提供反馈。本文主要针对修改和完善已有的代码,如果是希望增加 KCL 语言特性请通过 KEP 流程提交。 - -## 1. 代码和注释中的错别字 - -如果只是修改代码和注释中的错别字,不涉及代码逻辑的调整,那么可以直接在 Github 克隆仓库后直接修改并提交 PR。需要注意的是尽量保持代码风格一致。 - -## 2. 如何贡献 KCL 代码 - -- 先确保本地测试环境正常 -- 修改代码并补充测试 -- 本地测试通过后提交 PR - -## 3. 如何贡献 VS Code 插件代码 - -请参考 VS Code 插件仓库的相关文档 - -## 4. 开发流程相关代码 - -欢迎通过 Issue 和讨论组讨论。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/contribute/contribute-docs.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/contribute/contribute-docs.md deleted file mode 100644 index 7b846680..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/contribute/contribute-docs.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 如何贡献文档? - -本文主要针对已有的文档做局部修改。如果是投稿博客文章、添加新的文档或者调整文档目录结构请先联系团队成员。 - -KCL 文档分为用户指南、开发文档、内部文档、参考手册和博客文章等,他们的区别如下: - -- 用户指南:对应使用文档,是让用户以最小的代价快速使用 KCL 工具完整工作,不要涉及太多的内部原理和实现 -- 开发文档:内部是怎么实现的,主要针对希望了解 KCL 原理和参与贡献和开发的同学 -- 内部文档:针对企业用户的一些内部场景定制的文档 -- 参考手册:KCL 语言、工具和 IDE 等全部特性的文档,内容覆盖最广但比较琐碎 -- 博客文章:没有特别的限制,可以是针对某些具体的场景、某些技术点或者是整体发展展望等分享文章 - -在贡献不同类型的文档时,最好能够结合上面的定位对不同的内容做一些适当的裁剪,给读者最佳体验。 - -## 1. 基本规范 - -- 除标题外,内部小标题尽量带编号,便于阅读 -- 工具自动输出的文档需要由到源代码的链接,小标题可以不带编号 -- 尽量不要贴大段的代码(30行以内),代码最好给出文字解释和对应的参考链接 -- 有图有真相,但是不推荐过度复杂的架构图 -- 内部链接:采用 `/docs/user_docs/getting-started/intro` 绝对路径形式 - -**标点和空格** - -- 在中文的文档中优先使用中文的标点 -- 中文和英文之间需要增加 1 个空格 -- 中文和数字之间需要增加 1 个空格 -- 中文使用全角标点,标点前后均不添加空格 -- 英文内容使用半角标点,标点后面加 1 个空格 -- 链接前后需要保留一个空格,但是段落开头和中文全角标点附近不用添加空格。 - -**图片和资源文件名** - -- 文件名和目录名只能用数字、英文字母、下划线 `_` 和减号 `-` 组成 -- 当前文档的图片放在当前目录的 images 目录下 -- 矢量图片可以通过 [drawio 离线版](https://github.com/jgraph/drawio-desktop/releases) 绘制(并同时提交源文件),以 200% 分辨率导出 png 格式图片 - -## 2. 使用文档内容的基本模式 - -每个使用文档可以看作是一个相对完整的分享或博客文章(参考手册不再此类)。使用文档遵循以下模式组织内容: - -1. 概览:本文希望解决什么问题,达到什么效果,可以先放最终效果截图 -1. 依赖的环境:需要安装什么工具,并给出相关链接 -1. 引入本文构建资源的关系图或架构图 - - 需要用到的 Konfig 模型,给出模型参考页面链接,以及对应的上游原始模型的文档链接 -1. 具体的操作步骤 - - 尽量确保最小化代码,甚至可以刻意隐藏一些干扰代码,同时给出完整代码对应的链接 - - 列出每个步骤命令的概要输出信息,并配以文字描述 -1. 给出测试方式 - - 尽量采用社区通用的方式(比如kube、curl命令、或浏览器)测试 - - 给出测试结果的截图(和开头呼应) -1. 总结和展望 - - 简单回顾当前操作的流程,以及一些可以展开的地方(可以给出一些链接) - -## 3. 测试和提交 PR - -先克隆文档仓库,本地通过 `npm run start` 和 `npm run build` 命令测试查看效果,确保可以正常浏览后提交 PR 即可。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/contribute/contribute.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/contribute/contribute.md deleted file mode 100644 index 692df6ab..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/contribute/contribute.md +++ /dev/null @@ -1 +0,0 @@ -# 贡献指南 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/contribute/git-guideline.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/contribute/git-guideline.md deleted file mode 100644 index c475057d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/contribute/git-guideline.md +++ /dev/null @@ -1,132 +0,0 @@ -# Git 提交指南 - -本文介绍了 Git 提交变更时需要注意的事项,如果拒绝接受本文的内容会导致提交的变更无法被接受。 - -## 1. 关于 issue - -在提交一个 issue 之前,请先查阅已经关闭的 issue ,也许在关闭的 issue 中已经存在合适的解决方案。 - -如果没有找到合适的方案,我们提供了4种模版在创建 issue 的时候使用。 - -- Bug Report : 发现了一个 Bug,可以通过 Bug Report 模版创建 issue 与我们联系。 -- Enhancement : 开发者对工具进行了增强,可以通过 Enhancement 模版创建 issue 来介绍增加的内容。 -- Feature Request : 在使用的过程中想要为工具增加某些新的特性或者功能,可以通过 Feature Request 模版创建 issue 来描述新特性。 -- Ask a Question : 如果有任何的疑问,可以通过 Ask a Question 模版来创建一个 issue 与我们联系。 - -在选择合适的模版后,只需要填写模版上的要求填写的内容即可。如果在创建 issue 的时候发现没有模版,或者模版内容为空,可以通过微信群,钉钉群或者邮件向我们反馈这个问题。 - -## 2. 关于 Git 分支 - -要向 kcl-lang 贡献代码,您必须拥有一个 GitHub 帐户,以便您可以将代码推送到您自己的分支并创建拉取请求。我们推荐参考 [Angular 规范](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines) 为您自己的分支命名。 -推荐的格式如下: - -``` -{type}-{a_short_description} -``` - -分支名称主要包括两个字段,并通过 “-” 分割。其中: - -- {type} : 当前分支内容的类型。 -- {a_short_description}: 一个简短的描述,介绍这个分支的主要内容。 - -e.g. 张三首先 Fork 仓库到自己账户下,然后创建对应名称 `zhangsan:fix-output-fmt-bug` 的分支(冒号之前是张三的账号),用于修复输出格式化 bug。 - -## 3. 关于 Git Commit - -我们参考 [Commitizen](https://github.com/commitizen/cz-cli) 书写 Commit Message。 - -``` -注: 如果直接使用 Commitizen 生成 Commit Message,需要注意因为 Commitizen -是开发人员管理 commit 的工具,与项目本身无关联,因此由 Commitizen 生成的中间产物 -(如: node_modules 文件目录)可能没有在项目 .gitignore 文件中。 - -您可以 git add {filename} 选择要提交的文件而忽视中间产物。 -或者您可以向 .gitignore 文件中添加如下内容而自动忽视中间产物: -# commitizen -package.json -package-lock.json -node_modules/* -``` - -如果手动编写 Commit Message,我们也建议采用 [Commitizen](https://github.com/commitizen/cz-cli) 的 commit message 格式。 - -``` -{type} ( {component_or_file} ) {a_short_description} - {a_longer_description} - BREAKING CHANGE: {breaking_change_description}. - {linked issue} -``` - -其中主要包括6个字段: - -- {type} : 当前 commit 对应的分支的类型。 -- {component_or_file}: 当前 commit 改动的模块或者文件的名称。 -- {a_short_description}: 简短的描述介绍 commit 中的内容。 -- {a_longer_description}: 详细的描述用来介绍 commit 中的内容。 -- {breaking_change_description}: 如果 commit 中包含破环兼容性的改动,需要对兼容性改动产生的影响进行介绍。 -- {linked issue}: 与当前这个 commit 关联的 issue。 - -其中 {breaking_change_description} 和 {linked issue} 如果 commit 中不包含破坏兼容性的改动和关联的 issue,可以省略。 - -e.g. 张三在分支 `zhangsan:fix-output-fmt-bug` 中创建的 commit。 - -``` - - fix(kcl-printer): fix an output format bug in kcl-printer - - There is an output format bug in kcl-printer because ..., - So, The calling of method "XXX" is replaced by "HHHH"..., - ... - - -- 如果没有破坏兼容性的改动和关联的 issue 可以省略下面内容。 - - BREAKING CHANGE: This change maybe cause ....... - - fix #123 - -``` - -## 4. 关于 pull request - -在提交一个 PR 之前,可能需要优先考虑以下几个问题: - -- 请先查阅已经关闭的 PR ,也许在已经关闭的 PR 中,可能存在已经完成的解决方案。 -- 我们建议在提交变更之前,提交一个对应的 issue 描述变更中将要解决的问题,并将变更对应的 PR 与 issue 关联。 -- 在向我们提交 PR 之后,请签署 [Contributor License Agreement (CLA)](#cla) ,如果拒绝签署,我们将无法接受 PR。 -- 请确保每次改动都创建了一个新的分支,并根据上文中提到的规范为分支命名。 -- 一次 PR 请不要超过两个 commit ,请将多余的 commit 通过 squash 压缩,并根据上文中提到的规范,编写 commit message 。 -- 我们提供了 [PR 模版](https://github.com/kcl-lang/.github/blob/main/.github/PULL_REQUEST_TEMPLATE.md),只需要添加模版中要求的内容即可,如果在创建PR时发现没有模版或者模版内容为空,可以通过微信群,钉钉群或者邮件向我们反馈这个问题。 - -我们建议PR的标题与分支名、commit message 风格保持一致: - -``` -{type} ( {component_name_or_file_name} ) :{a_short_description} -``` - -e.g. 张三为分支`fix/zhangsan/fix_output_fmt_bug`创建的PR名称。 - -``` -fix(kcl-printer): fix an output format bug in kcl-printer. -``` - -## 5. 目前 type 支持的类型 - -参考[Angular 规范](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines),type 支持类型的类型如下: - -``` -- feat: -- 添加了新的功能特性。 -- fix: -- 进行了 Bug 的修复。 -- docs: -- 进行了文档部分的修改。 -- style: -- 对代码格式的修改,并不影响代码的功能,如:删除多余空格,代码缩进等。 -- refactor: -- 在不改变代码功能的基础上对代码进行了的重构。 -- perf: -- 对代码进行了性能优化。 -- test: -- 添加或者调整已有的测试用例。 -- build: -- 对构建系统或者外部依赖库进行了调整。 -- ci: -- 调整了 CI 的配置文件或者脚本。 -- chore: -- 对源代码和测试文件之外其他部分的调整。 -- revert: -- 对 commit 进行回滚。 -``` - -## 6. Contributor License Agreement (CLA) - -在第一次向我们提交 PR 之后,在 PR 中的 CLA 检查将会失败并提示签署 CLA。您可以通过自己的账户之间在 PR 回复 "I have read the CLA Document and I hereby sign the CLA" 表示同意签署 CLA,然后手动重启失败的 CLA 检查 Action 即可。当 PR 被成功合并之后将会被锁定不能再修改。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/intro/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/intro/_category_.json deleted file mode 100644 index e4cb1869..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/intro/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "简介", - "position": 1 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/intro/intro.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/intro/intro.md deleted file mode 100644 index af94bc33..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/intro/intro.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 社区 - -欢迎来到 KCL 开源社区,每个人的参与都是所有开源项目健康成长的动力!有很多方法可以参与开源。每个人都可以通过提交PR(Pull Request)来创建问题或修复 bug、改进文档或修改代码, - -可以查看[社区](https://github.com/kcl-lang/community)并加入我们。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/intro/license.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/intro/license.md deleted file mode 100644 index fe1db435..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/intro/license.md +++ /dev/null @@ -1,211 +0,0 @@ ---- -sidebar_position: 99 ---- - -# 许可 - -KCL 使用 [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0): - -``` - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2023 The KCL Authors. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/intro/support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/intro/support.md deleted file mode 100644 index 70ecd7e8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/intro/support.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 寻求帮助 - -KCL拥有一个由众多爱好者组成的开发者和用户社区。在此页面上,我们列出了您可以参与的KCL相关社区;有关其他在线和离线学习材料,请参阅本节的其他页面。 - -在加入 KCL 社区之前,请阅读[贡献者条款](https://www.contributor-covenant.org/version/2/0/code_of_conduct/),所有社区成员都需要遵守这些条款。 - -## 讨论 - -- 在 Github 上提交问题 -- 在 Github 讨论组中交流 -- 通过官方网站、Github、Twitter、微信和其他帐户获取 KCL 最新状态。可以查看[社区](https://github.com/kcl-lang/community)并加入我们。 - -## 新功能 - -请尽量避免提交新功能的拉取请求,我们可能已经有人在处理这些功能,或者这个功能已经是我们未来计划的一部分。总之,请在提交新功能之前与我们联系! diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/release-policy/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/release-policy/_category_.json deleted file mode 100644 index bf01a053..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/release-policy/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "发布策略", - "position": 3 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/release-policy/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/release-policy/index.md deleted file mode 100644 index a4a0bc3d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/release-policy/index.md +++ /dev/null @@ -1 +0,0 @@ -# 发布策略 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/release-policy/kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/release-policy/kcl.md deleted file mode 100644 index 0f9115b8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/release-policy/kcl.md +++ /dev/null @@ -1,39 +0,0 @@ -# KCL 发布策略 - -KCL 开发团队采用 [语义化版本](https://semver.org/lang/zh-CN/) 来简化管理。版本格式:主版本号.次版本号.修订号。版本号递增规则如下:主版本号对应不兼容的 API 修改,次版本号对应向下兼容的功能性新增,修订号对应向下兼容的问题修正。总体目标是每一个半月发布一个特性增强的次要版本,根据需要不定期发布其他版本的修订。 - -KCL 项目版本发布策略如下: - -- 主版本号:当进行重大的架构调整或者加入重大的新功能时,需要提升主版本号。对于 KCL 项目来说,目前的主版本号为 0。 -- 次版本号:当添加的功能和特性有较大的变化时,提升次版本号。目前的次版本号为 5,2023 年度会相继发布 0.5, 0.6, 0.7 版本。 -- 修订号:通过修复漏洞或者改进性能来更新程序时,会提升修订号,修订号从 0 开始计数以此加 1。 -- 发布周期:在未达到 v1.0.0 版本之前,计划每隔 3 个月发布一个新的次要版本。在此期间,需要持续收集用户反馈,并进行必要的修复和改进。 -- 发布流程:在发布新版本之前,需要进行严格的测试和审核,确保新版本的质量。封板并测试完成后,会在 Github 上发布新版本的源代码,二进制和镜像,并提供详细的文档和使用指南。 -- 版本支持:我们将对最新的版本提供长期支持,包括漏洞修复和安全更新。对于旧版本,我们将提供有限的支持,仅在必要时进行修复。 - -## 发布流程与规则 - -- 特性开发:main 分支主干开发,分支发布,block 用户使用的问题和严重的 bug, 安全隐患,高优先级解决,尽可能保持在一周内收敛,高于一般的功能研发。 -- 迭代周期:我们的迭代周期通常为 3 个月,即每 3 个月发布一个新的次要版本。 -- 版本规划:发版前两周产出 alpha 版本,前一周产出 beta 版本,alpha 版本仍可进行特性合并,beta 版本只合并错误修复,最终产出正式版本并打 tag 作为长期保存的 release 分支。 -- 发版计划:在每个发布周期开始时制定详细的发版计划(Github Milestone),包括发布日期、版本号、功能列表和测试计划等。需要尽可能地遵守发版计划,确保按时发布新版本。 -- 发布前测试:在发布新版本之前,需要进行全面的测试,包括单元测试、集成测试,模糊测试,压测,用户验收测试等。只有经过测试并无问题后,我们才会发布新版本。 -- 版本回滚:如果在发布后发现了严重的问题,需要立即回滚版本,并尽快修复问题。并通过邮件、社交媒体等渠道及时通知用户,并提供解决方案。 -- 发布文档:需要在发布时提供详细的文档,包括发布说明、更新日志、API 文档和使用指南等,帮助用户了解和使用新版本。在 KCL 中,我们统一在 KCL 网站进行维护。 -- 版本兼容性:在发布新版本时,需要尽可能保持兼容性,以确保用户无需进行过多的修改和适应。KCL 还没有达到 v1,暂时没有兼容性保证。KCL 的目标是尽可能少地进行重大更改,不应轻率地考虑对语言的更改,为了语言自身更好地演进和发展,一般认为更改具有重大好处时才会进行(较好地解决了目标场景的问题或者提升了绝大用户的使用体验)。对于可能引入兼容性问题的功能或变更,提供相应的提示和解决方案,同时会提供逐步升级的指南或提供自动迁移的工具,以帮助用户平滑地迁移到新版本。 - -## 发布组件 - -![](/img/docs/community/release-policy/kcl-components.png) - -每次版本发布时,KCL 相关所有组件保持一个依赖同一个 KCL 核心主要版本,整体采用树形结构组织依赖顺序发布并进行回归测试,直到发布测试完成,尽力避免三角依赖,禁止循环依赖。 - -## 一个 Feature 的生命周期 - -- 设计方案/文档:通过 Issue 回答清楚这个 feature 的动机是什么,它解决什么问题以及目标是什么,用户需求和用户故事是怎样的;这个 feature 做什么,如何做,难度怎样,需要多长时间,依赖项,需要做什么测试等。(Tips: 大的设计尽量拆分成小的设计,通过权衡和广泛的调研找到一个简单且可持续的解决方案,并且具备一定得到可扩展以适应未来的业务或技术变化,通过持续讨论和方案评审确定最终设计)。 -- 编写代码:通过高频小改动进行迭代、持续沟通和协作,提前设计单元测试、集成测试和 benchmark 等测试用例,确保编写代码 100% 测试覆盖,注释完整和逻辑清晰,并通过 Demo 演示持续收集反馈。 -- 文档撰写:在 [KCL 网站](https://kcl-lang.io) 中更新用户文档。 -- 测试和反馈:在发布功能之前,让一些同行/用户通过**随循文档**而不是口述来尝试和测试这些新功能。接收反馈并改进。 -- 发布和公告:撰写 Release Note, PR 文章,场景和新特性解读等以及渠道宣发等。 - -> 注:以上所有信息全是公开的,需要透出给所有社区研发者进行参与、讨论和贡献。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/release-policy/roadmap.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/release-policy/roadmap.md deleted file mode 100644 index 2f0ee86a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/community/release-policy/roadmap.md +++ /dev/null @@ -1,3 +0,0 @@ -# 路线规划 - -![](/img/docs/community/release-policy/roadmap.jpg) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/_category_.json deleted file mode 100644 index 1910abe4..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "参考手册", - "position": 5 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/cheatsheets/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/cheatsheets/_category_.json deleted file mode 100644 index 7839b7a2..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/cheatsheets/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "备忘录", - "position": 10 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/cheatsheets/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/cheatsheets/index.md deleted file mode 100644 index 6bfb2e4c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/cheatsheets/index.md +++ /dev/null @@ -1,5 +0,0 @@ -# KCL 备忘录 - -![](/img/docs/reference/cheatsheets/cheatsheet.png) - -[Download PDF](https://github.com/kcl-lang/kcl-lang.io/blob/main/cheatsheet/cheatsheet.pdf) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/index.md deleted file mode 100644 index 9fd0c276..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/index.md +++ /dev/null @@ -1 +0,0 @@ -# 学习 KCL diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/_category_.json deleted file mode 100644 index 6066c82b..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KCL", - "position": 1 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/codelab/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/codelab/_category_.json deleted file mode 100644 index c0133443..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/codelab/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "代码实验室", - "position": 2 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/codelab/collaborative.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/codelab/collaborative.md deleted file mode 100644 index 883f4853..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/codelab/collaborative.md +++ /dev/null @@ -1,345 +0,0 @@ ---- -title: "使用配置操作分块编写配置" -linkTitle: "使用配置操作分块编写配置" -type: "docs" -weight: 2 -description: 使用配置操作分块编写配置 -sidebar_position: 3 ---- - -## 1. Introduction - -KCL 是一种简单易用的配置语言,用户可以简单地编写可重复使用的配置代码。 - -在这个教程中,我们将学习如何使用 KCL 配置操作(config operation)功能以协同的方式编写配置。 - -### 本节将会学习 - -1. 定义 schema 并组织项目目录。 -2. 通过KCL的配置操作功能创建多个环境配置。 -3. 配置编译参数和测试。 - -## 2. 定义 Schema 和 组织项目目录 - -### Schema 定义 - -假设我们想定义具有某些属性的服务器配置,我们可以通过创建一个 `server.k` 文件来创建一个简单的配置,我们可以填写以下代码来定义服务器配置的可重用模式: - -```python -import units - -type Unit = units.NumberMultiplier - -schema Server: - replicas: int = 1 - image: str - resource: Resource = {} - mainContainer: Main = {} - labels?: {str:str} - annotations?: {str:str} - -schema Main: - name: str = "main" - command?: [str] - args?: [str] - ports?: [Port] - -schema Resource: - cpu?: int = 1 - memory?: Unit = 1024Mi - disk?: Unit = 10Gi - -schema Port: - name?: str - protocol: "HTTP" | "TCP" - port: 80 | 443 - targetPort: int - - check: - targetPort > 1024, "targetPort must be larger than 1024" -``` - -在上面的代码中,我们定义了一个名为 Server 的 schema,该 schema 表示用户将要编写的配置类型,其中包含一些基本类型属性(例如`replicas`、`image` 等)和一些复合类型属性(例如 `resource`、`main` 等)。除了一些在 [schema codelab](./schema.md)中提到的基本类型之外,我们可以看到上面的代码中有两种类型 `Unit` 和 `units.NumberMultiplier`。其中,`units.NumberMultiplier` 表示 KCL 数字单位类型,意味着可以在 KCL 数字后添加自然单位或二进制单位,例如 `1K` 表示 `1000`,`1Ki` 表示 `1024`。 `Unit` 是 `units.NumberMultiplier` 的类型别名,用于简化类型注释的编写。 - -### 项目目录 - -为了完成协同的配置的开发,我们首先需要一个配置项目,其中包含测试应用程序的配置以及不同环境的差异化配置,因此我们正在创建以下项目目录: - -``` -. -├── appops -│ └── test_app -│ ├── base -│ │ └── base.k -│ ├── dev -│ │ ├── ci-test -│ │ │ └── stdout.golden.yaml -│ │ ├── kcl.yaml -│ │ └── main.k -│ └── prod -│ ├── ci-test -│ │ └── stdout.golden.yaml -│ ├── kcl.yaml -│ └── main.k -├── kcl.mod -└── pkg - └── sever.k -``` - -该项目目录主要包含三个部分: - -- `kcl.mod`:用于标识KCL项目的根目录的文件。 -- `pkg`:不同应用程序配置所共用的 `Server Schema` 结构。 -- `appops`:不同应用程序的 Server 配置,目前仅包含一个名为 `test_app` 的应用程序。 - - `base`:供所有环境使用的应用程序通用配置。 - - `dev`:供开发环境使用的应用程序配置。 - - `prod`:供生产环境使用的应用程序配置。 - -后续章节将会介绍`base.k`、`main.k`、`kcl.yaml` 和 `ci-test/stdout.golden.yaml` 的含义。 - -## 3. 通过 KCL 配置操作功能创建多个环境配置 - -### 创建基线配置 - -在组织好项目目录和基本的服务器配置模型之后,我们可以编写用户应用程序的配置。我们可以创建自己的测试应用程序文件夹 `test_app`,并将其放置在应用程序配置文件夹 `appops` 中。 - -对于应用程序的配置,我们通常将其分为基本配置和多个环境的差异化配置并进行合并。通过 KCL 的配置合并功能,我们可以轻松实现这一点。假设我们有开发环境和生产环境的两个配置,我们可以创建三个文件夹:`base`、`dev` 和 `prod` 分别存储基线、开发环境和生产环境的配置。首先,我们编写 `base/base.k` 的配置: - -```python -import pkg - -server: pkg.Server { - # 设置镜像的值为 "nginx:1.14.2" - image = "nginx:1.14.2" - # 添加 app label - labels.app = "test_app" - # 添加一个mainContainer配置,它的端口是 [{protocol = "HTTP", port = 80, targetPort = 1100}] - mainContainer.ports = [{ - protocol = "HTTP" - port = 80 - targetPort = 1100 - }] -} -``` - -正如上述代码中所示,我们使用 `import` 关键字在 `base.k` 中导入放置在 `pkg` 下的 `Server` schema,并使用它实例化一个名为`server` 的配置,在其中将 `image` 属性设置为 `"nginx:1.14.2"`,并添加一个带有值为 `test_app` 的标签 `app`。此外,我们还在 `ports` 属性中添加了主容器 `mainContainer` 的配置,其值为 `[{protocol = "HTTP", port = 80, targetPort = 1100}]`。 - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k -``` - -输出: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2 - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app -``` - -当前,我们已经有了一个基线配置。 - -### 创建多重环境配置 - -接下来我们将配置一个差异化的多环境配置。首先假设我们想在开发环境中使用自己的临时镜像 `nginx:1.14.2-dev`,然后使用它来覆盖基准中的服务器配置,我们可以在 `dev/main.k` 中编写以下配置: - -```python -import pkg - -server: pkg.Server { - # 覆盖 base 配置中的声明的镜像 - image = "nginx:1.14.2-dev" -} -``` - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -输出: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app -``` - -可以看出输出的 YAML 文件的 `image` 字段被覆盖为 `nginx:1.14.2-dev`。假设我们还想将一个具有键为 `env`,值为 `dev` 的标签添加到 `dev` 环境中,我们将以下代码添加到 `dev/main.k` 中: - -```python -import pkg - -server: pkg.Server { - # 覆盖 base 配置中的声明的镜像 - image = "nginx:1.14.2-dev" - # 将新标签 env 合并到 base 标签中 - labels.env = "dev" -} -``` - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app - env: dev -``` - -可以看到输出的 YAML 文件的 `labels` 字段中有两个标签。 - -此外,我们还可以使用 `+=` 运算符将新值添加到列表类型属性中,例如在基准环境中的 `mainContainer.ports` 配置,继续修改 `dev/main.k` 中的代码: - -```python -import pkg - -server: pkg.Server { - # 覆盖 base 配置中的声明的镜像 - image = "nginx:1.14.2-dev" - # 将新标签 env 合并到 base 标签中 - labels.env = "dev" - # 在 base ports配置中添加一个 port - mainContainer.ports += [{ - protocol = "TCP" - port = 443 - targetPort = 1100 - }] -} -``` - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -输出: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - - protocol: TCP - port: 443 - targetPort: 1100 - labels: - app: test_app - env: dev -``` - -使用相同的方法,我们可以构建生产配置,在 `dev/main.k` 文件中编写代码,并为其添加标签。 - -```python -import pkg - -server: pkg.Server { - # 将新标签 env 合并到 base 标签中 - labels.env = "prod" -} -``` - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k appops/test_app/prod/main.k -``` - -输出: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2 - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app - env: prod -``` - -## 4. 配置编译参数和测试 - -在前面的章节中,我们通过代码构建了一个多环境配置。可以看出不同环境的 KCL 命令行编译参数相似,因此我们可以将这些编译参数配置到一个文件中,并将其输入到 KCL 命令行中进行调用。请将以下代码配置在 `dev/kcl.yaml`中: - -```yaml -kcl_cli_configs: - files: - - ../base/base.k - - main.k - output: ./ci-test/stdout.golden.yaml -``` - -然后我们可以使用以下命令在开发环境中编译配置: - -```bash -cd appops/test_app/dev && kcl -Y ./kcl.yaml -``` - -此外,我们已经在 `dev/kcl.yaml` 中配置了 `output` 字段,以将 YAML 输出到文件,以便进行后续配置分发或测试。您可以通过遍历每个环境中的 `kcl.yaml` 构建,并将其与 `./ci-test/stdout.golden.yaml` 进行比较,可以验证应用程序的配置是否符合预期。 - -## 5. 最后 - -恭喜! - -我们已经完成了关于 KCL 的第三课。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/codelab/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/codelab/index.md deleted file mode 100644 index 123c0878..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/codelab/index.md +++ /dev/null @@ -1 +0,0 @@ -# 代码实验室 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/codelab/schema.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/codelab/schema.md deleted file mode 100644 index 434e1f5c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/codelab/schema.md +++ /dev/null @@ -1,814 +0,0 @@ ---- -title: "使用 KCL Schema 编写复杂配置" -linkTitle: "使用 KCL Schema 编写复杂配置" -type: "docs" -weight: 2 -description: 使用 KCL Schema 编写复杂配置 -sidebar_position: 2 ---- - -## 1. 介绍 - -KCL 是一种简单易用的配置语言,用户可以简单地编写可重用的配置代码。 - -在本节教程中,我们将学习如何使用 KCL 编写定制配置,这样我们就可以定义一个架构并以协作方式编写配置。 - -### 本节将会学习 - -1. 定义一个简单的 schema -2. 为 schema 字段设置默认的不可变值 -3. 基于简单的 schema 创建配置 -4. 在 schema 中编写复杂的逻辑 -5. 通过 schema 的组合创建新的 schema -6. 使用 dict/map 创建具有深度嵌套 schema 的配置 -7. 通过 schema 继承创建新的 schema -8. 通过多个 mixin schema 创建新的 schema -9. 声明 schema 验证规则 -10. 配置 schema 的输出布局 -11. 共享和重用 schema - -## 2. 编写简单的 Schema - -假设我们希望定义一个具有特定属性的工作负载,我们可以通过创建一个 `my_config.k` 文件来创建一个简单的配置。我们可以按以下方式填写下面的代码,定义一个可重复使用的部署配置的 schema: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels: {str:str} -``` - -在上述代码中,`cpu` 和 `memory` 被定义为 int 值;`name`、`image` 和 `service` 是字符串;`command` 是由字符串构成的列表;`labels` 是字典类型,其键和值的类型均为字符串。 - -另外,每个属性都**必须**被赋予非 None 值作为 schema 实例,除非它被标记问号 **?** 而作为可选参数。 - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels?: {str:str} # labels 是一个可选的参数 -``` - -当存在继承关系时: - -- 如果在基 schema 中该属性为可选(optional)参数,则在子 schema 中它应该是可选的(optional)或必需的(required)。 -- 如果在基 schema 中该属性为必需(required)属性,则在子 schema 中它需要是必需的(required)。 - -## 3. Enhance Schema as Needed - -Suppose we need to set default values to service and replica, we can make them as below: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str = "my-service" # defaulting - replica: int = 1 # defaulting - command: [str] - labels?: {str:str} # labels is an optional attribute -``` - -And then we can set the service type annotation as the string literal type to make it immutable: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: "my-service" = "my-service" - replica: int = 1 - command: [str] - labels?: {str:str} -``` - -In the schema, type hint is a `must`, for example we can define cpu as `cpu: int`. - -Specially, we can define a string-interface dict as `{str:}`, and in case we want to define an object or interface, just define as `{:}`. - -## 4. 基于简单 Schema 创建配置 - -现在我们有了一个简单的 schema 定义,我们可以用它来定义配置: - -```python -nginx = Deployment { - name = "my-nginx" - cpu = 256 - memory = 512 - image = "nginx:1.14.2" - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python - kcl my_config.k -``` - -标准输出: - -```yaml -nginx: - name: my-nginx - cpu: 256 - memory: 512 - image: nginx:1.14.2 - service: my-service - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -> 有关集合数据类型和块的更多详细信息,请查看手册和规范。 - -此外,**配置选择器表达式**(config selector expressions)可以用于初始化 schema 实例,我们可以忽略配置表达式中行末的逗号。 - -```python -nginx = Deployment { - name = "my-nginx" - cpu = 256 - memory = 512 - image = "nginx:1.14.2" - command = ["nginx"] # 忽略行尾的逗号 - labels.run = "my-nginx" # schema 中的字典变量可以使用选择器表达式 - labels.env = "pre-prod" # schema 中的字典变量可以使用选择器表达式 -} -``` - -## 5. 在 Schema 中编写更为复杂的逻辑 - -假设我们有一些schema逻辑,我们可以将它包装进 schema 中: - -```python -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - image: str - service: "my-service" = "my-service" - replica: int = 1 - command: [str] - labels?: {str:str} - - _cpu = 2048 - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 -``` - -现在,我们可以通过创建 schema 实例来定义配置,并将优先级作为参数传递给模式: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl my_config.k -``` - -标准输出: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - image: nginx:1.14.2 - service: my-service - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 6. 通过 Schema 组合创建新 Schema - -现在我们想要定义一个详细的 schema,包括服务(service)和卷(volumes),我们可以按以下方式进行操作: - -```python -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - volumes?: [Volume] - image: str - service?: Service - replica: int = 1 - command: [str] - labels?: {str:str} - - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 - -schema Port: - name: str - protocol: str - port: int - targetPort: int - -schema Service: - name: "my-service" = "my-service" - ports: [Port] - -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -在这种情况下,Deployment 由 Service 和一系列 Volume 组成,而 Service 又由一系列 Port 组成。 - -## 7. 使用 dict/map 创建具有深度嵌套 schema 的配置 - -现在我们有一个新的 Deployment schema,但我们可能会注意到,它包含多层嵌套的结构,在复杂的结构定义中,这是非常常见的,我们通常必须编写命令式组装代码来生成最终结构。 - -使用 KCL,我们可以使用简单的字典声明创建配置,并具有完整的 schema 初始化和验证功能。例如,我们可以按照以下方式使用新的 Deployment schema简单地配置 nginx: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl my_config.k -``` - -标准输出: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -请注意,我们用于定义 Deployment 配置的字典必须与 schema 定义对齐,否则我们将会得到一个错误。例如,假设我们将服务端口的类型定义错误如下: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = [80] # 错误的数据类型,试图将 List 分配给 int - targetPort = 9376 - }] -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl my_config.k -``` - -标准错误输出: - -``` -The type got is inconsistent with the type expected: expect int, got [int(80)] -``` - -## 8. 声明 Schema 验证规则 - -现在我们已经看到了一个复杂的 schema,在其中每个字段都有一个类型提示,以使其更加不容错(error-prone)。 - -但是这还不够好,我们希望为我们的 schema 支持更多的增强验证,以便尽快发现 schema 和配置中的代码错误。许多验证规则,如 None 类型检查、范围检查、值检查、长度检查、正则表达式匹配、枚举检查已经被添加或陆续添加进来。以下是一段代码示例: - -```python -import regex - -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - volumes?: [Volume] - image: str - service?: Service - replica: int = 1 - command: [str] - labels?: {str:str} - - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 - - check: - multiplyof(cpu, 256), "cpu must be a multiplier of 256" - regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$"), "image name should be like 'nginx:1.14.2'" - 1 <= replica < 100, "replica should be in range (1, 100)" - len(labels) >= 2 if labels, "the length of labels should be large or equal to 2" - "env" in labels, "'env' must be in labels" - len(command) > 0, "the command list should be non-empty" - -schema Port: - name: str - protocol: str - port: int - targetPort: int - - check: - port in [80, 443], "we can only expose 80 and 443 port" - protocol in ["HTTP", "TCP"], "protocol must be either HTTP or TCP" - 1024 < targetPort, "targetPort must be larger than 1024" - -schema Service: - name: "my-service" = "my-service" - ports: [Port] - - check: - len(ports) > 0, "ports list must be non-empty" - -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -由于schema定义的属性默认是**必需的**(required),因此可以省略判断变量不能为 None/Undefined 的验证。 - -```python -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -现在我们可以基于新的 schema 编写配置,并及时暴露配置错误。例如,使用以下无效的配置: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1142" # 镜像值不匹配正则表达式 - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -每个字段都是类型有效的,但镜像名无效。 - -运行 KCL,我们将看到如下错误信息: - -KCL 命令: - -```python -kcl my_config.k -``` - -标准错误输出: - -``` -Schema check is failed to check condition: regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$"), "image name should be like 'nginx:1.14.2'" -``` - -> KCL 的验证功能涵盖了 Openapi 定义的验证,因此我们可以通过 KCL 编写任何 API 验证。 - -## 9. 通过 Schema 继承创建新 Schema - -现在,我们拥有了一个稳定的部署 schema 定义,可以用它来声明配置。 - -通常,部署 schema 将被用于多个场景中。我们可以直接使用 schema 在不同的用例中声明配置(见上文的部分),或者我们可以通过继承生成一个更具体的 schema 定义。 - -例如,我们可以使用部署 schema 作为基础,来定义 nginx 的基本 schema,并在每个场景中扩展定义。在这种情况下,我们定义了一些常用的属性。请注意,我们使用“final”关键字将名称标记为不可变,以防止被覆盖。 - -```python -schema Nginx(Deployment): - """ A base nginx schema """ - name: "my-nginx" = "my-nginx" - image: str = "nginx:1.14.2" - replica: int = 3 - command: [str] = ["nginx"] - -schema NginxProd(Nginx): - """ A prod nginx schema with stable configurations """ - volumes: [Volume] = [{ - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - """ A volume mapped to host path """ - service: Service = { - ports = [{ - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] - } - """ An 80 port to target backend server """ -``` - -现在我们有了一些 nginx 的静态配置。建议将我们认为是静态的配置声明在那里,并将更多的动态配置放在下面: - -```python -nginx = Nginx { - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -```python -nginx = NginxProd { - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -现在,我们只需要通过运行时标签值 “prod” 来简单定义 不那么静态的 nginx 生产环境配置。 - -实际上,在某些复杂情况下,我们可以将所有配置分为基本配置、业务配置和环境配置定义,并基于此实现团队成员之间的协作。 - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl prod_config.k -``` - -标准输出: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 3 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 10. Create New Schema by Multiple Protocol and Mixin Schemas Inheritance - -现在,我们可以通过 Deployment schema 完成服务器配置的声明。 - -然而,通常实际情况更为复杂,部署可能有各种可选变量附件。 - -例如,我们想要在现有 schema 中支持声明持久卷,作为可重用的 Kubernetes schema。在这种情况下,我们可以通过以下 `mixin` 和 `protocal` 进行包装: - -```python -import k8spkg.api.core.v1 - -protocol PVCProtocol: - pvc?: {str:} - -mixin PersistentVolumeClaimMixin for PVCProtocol: - """ - PersistentVolumeClaim (PVC) sample: - Link: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims - """ - - # Mix in a new attribute `kubernetesPVC` - kubernetesPVC?: v1.PersistentVolumeClaim - - if pvc: - kubernetesPVC = v1.PersistentVolumeClaim { - metadata.name = pvc.name - metadata.labels = pvc.labels - spec = { - accessModes = pvc.accessModes - resources = pvc.resources - storageClassName = pvc.storageClassName - } - } -``` - -有了 PersistentVolumeClaimMixin,我们使用清晰的用户界面(user interface)定义了一个 PVC schema,并使用 Kubernetes PVC 作为实现。然后,我们可以使用 Deployment schema 和 PVC mixin schema 定义一个 server schema。 - -```python -schema Server(Deployment): - mixin [PersistentVolumeClaimMixin] - pvc?: {str:} - """ pvc user interface data defined by PersistentVolumeClaimMixin """ -``` - -在 Server schema 中,Deployment schema 是基础 schema,而 PersistentVolumeClaimMixin 是一个可选附加项,其用户界面数据为`pvc?:{str:}`。 - -请注意,mixin 通常用于向宿主 schema 添加新属性,或修改宿主 schema 的现有属性。因此,mixin 可以使用宿主 schema 中的属性。由于其被设计为可重用,因此我们需要一个额外的协议来限制 mixin 中宿主 schema 中属性的名称和类型。 - -现在,如果我们想要使用 PVC 进行部署,只需声明用户界面: - -```python -server = Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] - pvc = { - name = "my_pvc" - accessModes = ["ReadWriteOnce"] - resources.requests.storage = "8Gi" - storageClassName = "slow" - } -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl server.k -``` - -标准输出: - -```yaml -server: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod - pvc: - name: my_pvc - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 8Gi - storageClassName: slow ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: my_pvc -spec: - accessModes: - - ReadWriteOnce - storageClassName: slow - resources: - requests: - storage: 8Gi -``` - -如果我们不需要持久卷,只需删除 pvc 配置块。 - -## 11. 共享和重用 Schema - -可以通过导入来共享 Server schema,我们只需要将代码与 KCL 一起打包即可。 - -```python -import pkg - -server = pkg.Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -另一个关于共享代码的技巧是:在同一包下的模块不需要相互导入。 - -假设我们在 pkg 中有如下 models: - -``` -pkg/ - - deploy.k - - server.k - - pvc.k -``` - -在 `server.k` 中,我们可以只使用 `deploy.k` 中的 Deployment schema 和 `pvc.k` 中的 pvc schema 而无需导入: - -```python -# 无需 import -schema Server(Deployment): - mixin [PersistentVolumeClaimMixin] - pvc?: {str:} - """ pvc user interface data defined by PersistentVolumeClaimMixin """ -``` - -然后用户必须导入 pkg 才能作为一个整体使用它: - -```python -import pkg - -server = pkg.Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [pkg.Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } - service.ports = [pkg.Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -运行 KCL 命令: - -```python -kcl pkg_server.k -``` - -Output: - -```yaml -server: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 12. 最后 - -恭喜! - -我们已经完成了 KCL 的第二节课。我们使用 KCL 来替换我们的 key-value 文本文件,以便获得更好的可编程性。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/codelab/simple.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/codelab/simple.md deleted file mode 100644 index 32ad2612..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/codelab/simple.md +++ /dev/null @@ -1,495 +0,0 @@ ---- -title: "使用 KCL 编写简单配置" -linkTitle: "使用 KCL 编写简单配置" -type: "docs" -weight: 2 -description: 使用 KCL 编写简单配置 -sidebar_position: 1 ---- - -## 1. 介绍 - -KCL 是一种简单易用的配置语言,用户可以简单地编写可重用的配置代码。 - -在这个第一个教程中,我们将学习如何使用 KCL 编写一个简单的配置。 - -学习这个代码实验只需要基本的编程知识,如果你有 Python 经验,将会更容易上手。 - -### 本节将会学习 - -1. 用一种可编程的方式编写简单的 key-value 配置 -2. 使用 KCL 编写简单的逻辑 -3. 使用 KCL 编写集合(collections) -4. 使用 KCL 代码进行测试和调试 -5. 在 KCL 代码中使用内置(built-in)支持 -6. 共享和重用 KCL 代码 -7. 使用动态输入参数编写配置 - -## 2. 编写Key-Value键值对 - -通过创建 `my_config.k` 来生成一个简单的配置,我们可以填充下面的代码,并且不需要严格的格式描述部署的配置。 - -```python -cpu = 256 -memory = 512 -image = "nginx:1.14.2" -service = "my-service" -``` - -在上述代码中,cpu 和 memory 被声明为 int 类型的值,而 image 和 service 被声明为字符串字面值。 - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -KCL 命令: - -```bash -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -可导出变量(exported variable)默认情况下是不可变的,一旦声明,就不能在其他地方修改它。 - -## 3. 编写简单逻辑 - -有时候我们想在配置中编写一些逻辑,那么我们就可以使用: - -- 以 `_` 开头的非导出可变变量(mutable and non-exported variable) -- if-else 语句 - -非导出变量表示它不会出现在输出的 YAML 中,且它可以被多次赋值。 - -这是一个示例,显示如何根据条件调整资源。 - -KCL 命令: - -```python -kcl my_config.k -``` - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -image = "nginx:1.14.2" -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -```python -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -.. 注意:: -KCL 对运算符和字符串成员函数有丰富的支持,请阅读手册和规范以了解更多细节。 - -## 4. 编写集合 - -我们可以使用集合来表示复杂的数据类型。已支持的集合类型有: - -- list -- dict - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -command = ["nginx"] # 列表 -labels = {run = "my-nginx"} # a dict -image = "nginx:1.14.2" -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -KCL 命令: - -```bash -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx -image: nginx:1.14.2 -service: my-service -``` - -> 有关集合数据类型和成员函数的更多信息,请查阅手册和规范。 - -## 5. 在集合中添加元素 - -我们可以将逻辑表达式、推导式、切片、联合类型等特性组合起来,动态地将元素添加到集合中。 - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 -_env = "pre-prod" - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -_command = ["nginx"] # 列表 -_command = _command + ["-f", "file"] # 使用 + 运算符将元素附加到命令中以连接两个列表 -command = [c.lower() for c in _command] # # 将列表中的每个元素转为小写 -_labels = { - run = "my-nginx" - if _env: - env = _env # 当 _env 不是 None/Undefined 或为空时使用 if 表达式添加一个字典键值对 -} # 字典 -labels = _labels -image = "nginx:1.14.2" -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -```python -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 256 -memory: 512 -command: - - nginx - - -f - - file -labels: - run: my-nginx -image: nginx:1.14.2 -service: my-service -``` - -## 6. 编写断言 - -为了使代码可测试且健壮,我们可以使用断言(assertions)验证配置数据。 - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -command = ["nginx"] # 列表 -labels = {run = "my-nginx"} # 字典 -image = "nginx:1.14.2" -service = "my-service" -assert "env" in labels, "env label is a must" -assert cpu >= 256, "cpu cannot be less than 256" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -```bash -kcl my_config.k -``` - -标准错误输出: - -```bash -Assertion failure: env label is a must. -``` - -将 env:pre-prod 对添加到标签中后,我们将得到如下输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 7. 使用方便的内置支持 - -更重要的是,我们可以使用内置函数来帮助我们调试或简化编码。 - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -_name = "nginx" -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # 列表 -labels = { - run = "my-{}".format(_name) - env = "pre-prod" -} # a dict -image = "{}:1.14.2".format(_name) # 字符串格式 -service = "my-service" - -# debugging -print(labels) # 通过打印调式 - -# test -assert len(labels) > 0, "labels can't be empty" # 使用 len() 得到列表长度 -assert "env" in labels, "env label is a must" -assert cpu >= 256, "cpu cannot be less than 256" -``` - -此示例展示了我们如何使用 `format()`、`len()`、`print()` 函数来帮助自定义配置。 - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -KCL 命令: - -```bash -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -run: my-nginx -env: pre-prod -``` - -注意:更多的内置函数和模块可以在 spec/module 目录中查看。 - -## 8. 重用另一个模块的变量 - -为了使我们的代码得到良好的组织,我们可以将代码简单地分为 `my_config.k` 和 `my_config_test.k` 两个文件。 - -在 `my_config.k` 中定义配置数据: - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 -_name = "nginx" - -# 可导出变量 -cpu = _cpu -memory = _cpu * 2 -command = [_name] # 列表 -labels = { - run = "my-{}".format(_name) - env = "pre-prod" -} # a dict -image = "{}:1.14.2".format(_name) # 字符串格式 -service = "my-service" -``` - -而测试代码定义在 `my_config_test.k` 中,我们可以在其中导入 `my_config.k`: - -```python -import my_config - -# debugging -print(my_config.labels) # 通过打印调试 - -# test -assert len(my_config.labels) > 0, "labels can't be empty" # 使用 len() 得到列表长度 -assert "env" in my_config.labels, "env label is a must" -assert my_config.cpu >= 256, "cpu cannot be less than256" -``` - -## 9. 配置输入参数 - -有时我们需要获得通过从最终用户或平台动态获取的外部输入参数。 - -在这种情况下,我们可以按需传递 `priority` 和 `env` 参数: - -- 通过参数传递: `-D priority=1 -D env=pre-prod` -- 可以在 KCL 代码中使用 `option` 关键字获取这些值 - -```python -_priority = option("priority") # 非导出可变变量 -_env = option("env") # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -_name = "nginx" -# 可导出变量 -cpu = _cpu -memory = _cpu * 2 -command = [_name] # 列表 -labels = { - run = "my-{}".format(_name) - env = _env -} # a dict -image = "{}:1.14.2".format(_name) # 字符串格式 -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -```bash -kcl my_config.k -D priority=2 -D env=pre-prod -``` - -标准输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 10. 使用 Dict 简化逻辑表达式 - -当我们需要编写复杂的逻辑时,可以使用dict来简化逻辑的编写。 - -```python -_priority = option("priority") # 非导出可变变量 -_env = option("env") # 非导出可变变量 -_priorityCpuMap = { - "1" = 256 - "2" = 512 - "3" = 1024 -} -# 使用字典简化逻辑,默认值为2048 -_cpu = _priorityCpuMap[_priority] or 2048 -_name = "nginx" -# 可导出变量 -cpu = _cpu -memory = _cpu * 2 -command = [_name] # 列表 -labels = { - run = "my-{}".format(_name) - env = _env -} # a dict -image = "{}:1.14.2".format(_name) # 字符串格式 -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -KCL 命令: - -```bash -kcl my_config.k -D priority=2 -D env=pre-prod -``` - -标准输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 11. 最后 - -恭喜! - -我们已经完成了关于 KCL 的第一课程,我们使用 KCL 来替换我们的键值文本文件,以获得更好的编程支持。 - -建议立即查看架构代码实验,以了解如何使用 KCL `schema` 机制协作编写高级配置。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/error/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/error/_category_.json deleted file mode 100644 index 4f285ced..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/error/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "错误与警告", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/error/_error.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/error/_error.md deleted file mode 100644 index a2f192b8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/error/_error.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: "错误检查" -linkTitle: "错误检查" -type: "docs" -weight: 1 -description: KCL 语言规范 ---- - -When errors happen, developers should be able to detect the error and abort -execution. Thus, KCL introduce the `assert` syntax. - -In the previous topic of `schema` syntax. Errors can also be raised when a -schema is violated. - -## Syntax - -The syntax of the `assert` statement is the following. - -``` -assert_stmt: 'assert' test [',' test] -``` - -In the basic form, an `assert` statement evaluates an expression. If the -expression is evaluated to `False`, the assertion is failed, and an error -should be reported. - -In the extended form, an error message can be provided. The error message is -another expression. It is only evaluated when the expression to be evaluated -is evaluated to `False`. The evaluation result of the error message is printed -when reporting the error. - -The following is an example: - -```py -a = 1 -b = 3 -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -``` - -## The Implementation - -When an error happens, no matter it is caused by the `assert` or the `schema` syntax, -the virtual machine should exit with an exit code greater than `0`. - -The virtual machine may choose to dump the back trace information, and it is strongly -recommended to implement it. - -In practice, KCL can dump back trace by default, and an argument can be introduced -to disable it. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/error/exception.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/error/exception.md deleted file mode 100644 index cd18995f..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/error/exception.md +++ /dev/null @@ -1,1584 +0,0 @@ ---- -title: "KCL 错误与警告" -linkTitle: "KCL 错误与警告" -type: "docs" -weight: 2 -description: KCL 错误与警告 ---- - -# KCL 错误与警告 - -文档的此部分中的文章介绍了由 KCL 生成的诊断错误和警告消息。 - -**注意:** -**KCL 可以报告多种错误和警告。找到错误或警告后,KCL 可能会对代码意向作出假设并尝试继续,以便可以同时报告更多问题。 如果工具做出错误假设,则后续错误或警告可能不适应与当前 KCL 程序。 因此,纠正项目中的问题时,请先纠正第一个错误或警告,然后重新运行获取新的错误信息。 一个修补程序可能会导致后续错误消失。** - -此部分文档的主要内容包括: - -[KCL 语法错误 (E1xxx)](#11-kcl-%E8%AF%AD%E6%B3%95%E9%94%99%E8%AF%AF-e1xxx) : 如果 KCL 在当前 KCL 程序中发现了非法的 KCL 语法,KCL 就会停止运行并输出 KCL 程序语法错误的提示信息. - -[KCL 编译错误 (E2xxx)](#12-kcl-%E7%BC%96%E8%AF%91%E9%94%99%E8%AF%AF-e2xxx) : 如果 KCL 在一个不包含语法错误的 KCL 程序中发现了与 KCL 语义不符的代码,KCL 就会停止运行并输出编译错误的提示信息。 - -[KCL 运行时错误 (E3xxx)](#13-kcl-%E8%BF%90%E8%A1%8C%E6%97%B6%E9%94%99%E8%AF%AF-e3xxx) : KCL 程序通过编译后会生成 KCL 字节码,如果 KCL 在执行 KCL 字节码过程中出现错误,KCL 就会停止运行并输出运行时错误的提示信息. - -[KCL 编译警告 (W2xxx)](#14-kcl-%E7%BC%96%E8%AF%91%E8%AD%A6%E5%91%8A-w2xxx) : 当 KCL 发现可能导致运行失败的 KCL 代码,KCL 不会立即停止运行,但是会输出潜在错误的警告提示。 - -## 1.1 KCL 语法错误 (E1xxx) - -KCL 会出现的语法错误信息如下表所示: - -| ewcode | KCL exception | messages | -| ------ | ------------------------------------------------------------------- | ----------------------- | -| E1001 | [InvalidSyntaxError](#111-invalidsyntaxerror-e1001) | Invalid syntax | -| E1002 | [KCLTabError](#112-kcltaberror-e1002) | Tab Error | -| E1003 | [KCLIndentationError](#113-kclindentationerror-e1003) | Indentation Error | -| E1I37 | [IllegalArgumentSyntaxError](#114-illegalargumentsyntaxerror-e1i37) | Illegal argument syntax | - -### 1.1.1 InvalidSyntaxError [E1001] - -如果在运行 KCL 时遇到错误: - -- `InvalidSyntaxError`, 对应的 encode 为 `E1001` - -那么此时 KCL 程序中出现了 - -- 非法的 KCL 语法。 - -可能出现错误的 KCL 程序片段如下: - -```python -a, b = 1, 2 # 通过 “=” 赋值多个变量在KCL中是非法的。 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> /syntax_error/general/multiple_assign/case0/main.k:1:2 - | -1 | a, b = 1, 2 # Multiple assign is illegal in KCL syntax - | ^ expected statement - | -``` - -### 1.1.2 KCLTabError - -如果在运行 KCL 时遇到错误: `KCLTabError` - -那么此时 KCL 程序中出现了 - -- Tab 与空格混用的问题。KCL 中禁止在代码缩进中混用 Tab 和空格。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - name: str # 通过tab表示缩进 - age: int # 通过四个空格标识缩进, - # 在当前运行环境中的四个空格与tab不同 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> File /syntax_error/tab/tab_error_0/main.k:6:5 - | -3 | age: int = 1 - | ^ inconsistent use of tabs and spaces in indentation - | -``` - -可以尝试以下步骤来修复这个错误: - -- 在 KCL 程序中全部使用 Tab 或者全部使用四个空格,不要混用。 - -### 1.1.3 KCLIndentationError - -如果在运行 KCL 时遇到错误: `KCLIndentationError` - -那么此时 KCL 程序中出现了 - -- 程序缩进错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - name: str # 使用一个tab或者四个空格表示缩进 - age: int # KCL不支持使用三个空格表示缩进 - info: str # KCL不支持使用两个空格表示缩进 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> /syntax_error/indent/indent_error_0/main.k:3:4 - | -3 | age: int # three white spaces are illegal - | ^ unindent 3 does not match any outer indentation level - | -``` - -可以尝试以下步骤来修复这个错误: - -- 在 KCL 程序中全部使用 Tab 或者全部使用四个空格来表示缩进。 - -### 1.1.4 IllegalArgumentSyntaxError - -如果在运行 KCL 时遇到错误: `IllegalArgumentSyntaxError` - -那么此时 KCL 程序中出现了 - -- 参数语法错误 - -可能出现错误的 KCL 程序片段如下: - -```python -# KCL中带有keyword的参数必须出现在不带有keyword参数后面 -# 带有keyword的参数: type="list", default={"key": "value"} -# 不带有keyword的参数: "key1" -a = option(type="list", default={"key": "value"}, "key1") -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> /option/type_convert_fail_2/main.k:3:57 - | -3 | a = option(type="list", default={"key": "value"}, "key1") - | ^ positional argument follows keyword argument - | -``` - -可以尝试以下步骤来修复这个错误: - -- KCL 中带有 keyword 的参数必须出现在不带有 keyword 参数后面, 参数正常顺序: - -```python -func(input_1, ..., input_n, param_with_key_1 = input_with_key_1, ..., param_with_key_n = input_with_key_n) -``` - -## 1.2 KCL 编译错误 (E2xxx) - -KCL 会出现的编译错误信息如下表所示: - -| ewcode | KCL exception | messages | -| ------ | ----------------------------------------------------------------------- | --------------------------------------------------- | -| E2F04 | [CannotFindModule](#121-cannotfindmodule-e2f04) | Cannot find the module | -| E2F05 | [FailedLoadModule](#122-failedloadmodule-e2f05) | Failed to load module | -| E2H13 | [UnKnownDecoratorError](#123-unknowndecoratorerror-e2h13) | UnKnown decorator | -| E2H14 | [InvalidDecoratorTargetError](#124-invaliddecoratortargeterror-e2h14) | Invalid Decorator Target | -| E2C15 | [MixinNamingError](#125-mixinnamingerror-e2c15) | Illegal mixin naming | -| E2C16 | [MixinStructureIllegal](#126-mixinstructureillegal-e2c16) | Illegal mixin structure | -| E2B17 | [CannotAddMembersComplieError](#127-cannotaddmemberscomplieerror-e2b17) | Cannot add members to a schema | -| E2B20 | [IndexSignatureError](#128-indexsignatureerror-e2b20) | Invalid index signature | -| E2G22 | [TypeComplieError](#129-typecomplieerror-e2g22) | The type got is inconsistent with the type expected | -| E2L23 | [CompileError](#1210-compileerror-e2l23) | A complie error occurs during compiling | -| E2L25 | [KCLNameError](#1211-kclnameerror-e2l25) | Name Error | -| E2L26 | [KCLValueError](#1212-kclvalueerror-e2l26) | Value Error | -| E2L27 | [KCLKeyError](#1213-kclkeyerror-e2l27) | Key Error | -| E2L28 | [UniqueKeyError](#1214-uniquekeyerror-e2l28) | Unique key error | -| E2A29 | [KCLAttributeComplieError](#1215-kclattributecomplieerror-e2a29) | Attribute error occurs during compiling | -| E2D32 | [MultiInheritError](#1216-multiinheriterror-e2d32) | Multiple inheritance is illegal | -| E2D34 | [IllegalInheritError](#1217-illegalinheriterror-e2d34) | Illegal inheritance | -| E2I36 | [IllegalArgumentComplieError](#1218-illegalargumentcomplieerror-e2i36) | Illegal argument during compiling | -| E3L41 | [ImmutableCompileError](#1219-immutablecompileerror-e3l41) | Immutable variable is modified | - -### 1.2.1 CannotFindModule [E2F04] - -如果在运行 KCL 时遇到错误: - -- `CannotFindModule`, 对应的 encode 为 `E2F04` - -那么此时 KCL 程序中出现了 - -- 无法找到导入模块错误 - -可能出现错误的 KCL 程序片段如下: - -```python -import .some0.pkg1 as some00 # some0 not found in package - -Name1 = some00.Name # some0.pkg1.name -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2F04]: CannotFindModule - --> import_abs_fail_0/app-main/main.k:1:1 - | -1 | import .some0.pkg1 as some00 # some0 not found in package - | Cannot find the module .some0.pkg1 - | -``` - -可以尝试以下步骤来修复这个错误: - -- 在 import 路径下添加导入模块文件。 - -### 1.2.2 FailedLoadModule [E2F05] - -如果在运行 KCL 时遇到错误: - -- `FailedLoadModule`, 对应的 encode 为 `E2F05` - -那么此时 KCL 程序中出现了 - -- 导入模块加载错误 - -可以尝试以下步骤来修复这个错误: - -- 查看文件是否可读 -- 查看文件是否为 kcl 文件 - -### 1.2.3 UnKnownDecoratorError - -如果在运行 KCL 时遇到错误: - -- `UnKnownDecoratorError`, 对应的 encode 为 `E2H13` - -那么此时 KCL 程序中出现了 - -- 未知的装饰器错误 - -可能出现错误的 KCL 程序片段如下: - -```python -@err_deprecated # 这是一个非法的装饰器 -schema Person: - firstName: str = "John" - lastName: str - name: str - -JohnDoe = Person { - name: "deprecated" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> deprecated/unknown_fail_1/main.k:1:2 - | -1 | @err_deprecated # 这是一个非法的装饰器 - | ^ UnKnown decorator err_deprecated - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查装饰器是否存在。 - -### 1.2.4 InvalidDecoratorTargetError [E2H14] - -如果在运行 KCL 时遇到错误: - -- `InvalidDecoratorTargetError`, 对应的 encode 为 `E2H14` - -那么此时 KCL 程序中出现了 - -- 无效的装饰器目标错误。 - -可以尝试以下步骤来修复这个错误: - -- 检查使用装饰器的 KCL 代码是否出现异常。 - -### 1.2.5 MixinNamingError [E2C15] - -如果在运行 KCL 时遇到错误: - -- `MixinNamingError`, 对应的 encode 为 `E2C15` - -那么此时 KCL 程序中出现了 - -- Mixin 命名错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - firstName: str - lastName: str - fullName: str - -schema Fullname: # Mixin的名称应该以Mixin结尾 - fullName = "{} {}".format(firstName, lastName) - -schema Scholar(Person): - mixin [Fullname] - school: str - -JohnDoe = Scholar { - "firstName": "John", - "lastName": "Doe", - "fullName": "Doe Jon" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2D34]: IllegalInheritError - --> mixin/invalid_name_failure/main.k:10:12 - | -10 | mixin [Fullname] - | ^ illegal schema mixin object type 'Fullname' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 如果 schema 是一个 mixin,那么这个 schema 的名称应该以 Mixin 结尾。 - -### 1.2.6 MixinStructureIllegal [E2C16] - -如果在运行 KCL 时遇到错误: - -- `MixinStructureIllegal`, 对应的 encode 为 `E2C16` - -那么此时 KCL 程序中出现了 - -- Mixin 结构错误。 - -可以尝试以下步骤来修复这个错误: - -- 检查作为 Mixin 的 Schema 的结构。 - -### 1.2.7 CannotAddMembersComplieError [E2B17] - -如果在运行 KCL 时遇到错误: - -- `CannotAddMembersComplieError`, 对应的 encode 为 `E2B17` - -那么此时 KCL 程序中出现了 - -- 使用 Schema 中不存在的成员。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Girl: - gender: str = "female" - -alice = Girl { - "first": "alice", # Schema中没有成员“first” - "last": " Green", # Schema中没有成员“last” - "age": 10 # Schema中没有成员“age” -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:5:5 - | -5 | "first": "alice", - | ^ Cannot add member 'first' to schema 'Girl' - | - -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:6:5 - | -6 | "last": " Green", - | ^ Cannot add member 'last' to schema 'Girl' - | - -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:7:5 - | -7 | "age": 10 - | ^ Cannot add member 'age' to schema 'Girl' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 为 Schema 添加缺少的成员。 -- 不要使用 Schema 中不存在的成员。 - -### 1.2.8 IndexSignatureError [E2B20] - -如果在运行 KCL 时遇到错误: - -- `IndexSignatureError`, 对应的 encode 为 `E2B20` - -那么此时 KCL 程序中出现了 - -1. 在一个 schema 中使用多个索引签名。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Data: - [str]: str - [str]: int # 在同一个schema中使用了多个索引签名 - -data = Data { - name: "test" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError ----> index_signature/fail_1/main.k:3:5 - | -3 | [str]: int - | 5 ^ only one index signature is allowed in the schema - | -``` - -可以尝试以下步骤来修复这个错误: - -- 删除多余的索引签名。 - -2. schema 中索引签名的名称与 schema 中其他属性的名称存在同名冲突。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Data: - name: str # name - [name: str]: str # 已有名称为name的schema属性 - -data = Data { - name: "test" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: IndexSignatureError - --> index_signature/fail_2/main.k:3:5 - | -3 | [name: str]: str # the same name with the above attribute - | ^ index signature attribute name 'name' cannot have the same name as schema attributes - | -``` - -可以尝试以下步骤来修复这个错误: - -- 删除 schema 中出现同名冲突的属性或者索引签名,或者为它们更换不同的名称。 - -3. schema 索引签名的类型与 schema 实例化的属性类型冲突。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Data: - [str]: int - -data = Data { - name: "test" # 索引签名为 [str]:int, "test"的类型不是int. -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> index_signature/fail_3/main.k:5:5 - | -5 | name: "test" # Conflict with [str]:int, "test" is a string. - | ^ expected int, got str(test) - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 schema 索引签名的类型与 schema 实例中的属性类型是否一致。 - -4. Schema 中的属性与索引签名冲突 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Data: - count: int # int 和 str 冲突 - [str]: str - -data = Data { - count: 1 -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: IndexSignatureError - --> index_signature/fail_4/main.k:2:5 - | -2 | count: int - | ^ the type 'int' of schema attribute 'count' does not meet the index signature definition [str]: str - | -``` - -可以尝试以下步骤来修复这个错误: - -- 调整 Schema 属性或者调整索引签名。 - -### 1.2.9 TypeComplieError [E2G22] - -如果在运行 KCL 时遇到错误: - -- `TypeComplieError`, 对应的 encode 为 `E2G22` - -那么此时 KCL 程序中出现了 - -- 静态类型检查错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - firstName: str - lastName: int - -JohnDoe = Person { - "firstName": "John", - "lastName": "Doe" # Schema中定义lastName: int -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> type/type_fail_0/main.k:7:5 - | -7 | "lastName": "Doe" # Type Error,lastName: int,“Doe” is a string. - | ^ expected int, got str(Doe) - | - - --> type/type_fail_0/main.k:3:5 - | -3 | lastName: int - | ^ variable is defined here, its type is int, but got str(Doe) - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查赋给某个变量的值的类型与这个变量的类型是否一致。 - -### 1.2.10 CompileError [E2L23] - -如果在运行 KCL 时遇到错误: - -- `CompileError`, 对应的 encode 为 `E2L23` - -那么此时 KCL 程序中出现了 - -1. 不支持的类型合并 - -可能出现错误的 KCL 程序片段如下: - -```python -_data = [1, 2, 3] -_data |= "value" -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> union/fail/fail_1/main.k:2:1 - | -2 | _data |= "value" - | ^ unsupported operand type(s) for |: '[int]' and 'str(value)' - | -``` - -1. 不支持的操作符类型 - -可能出现错误的 KCL 程序片段如下: - -```python -a = None -b = 1 + None # KCL中不支持None和int之间进行+操作 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> operator/operator_fail_0/main.k:2:5 - | -2 | b = 1 + None # Unsupport operand type + for int and None - | ^ unsupported operand type(s) for +: 'int(1)' and 'NoneType' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 调整操作符号,使其同时支持两个操作数的类型。 -- 调整操作数,使其同时符合操作符号的约束。 - -1. 没有定义的变量 - -可能出现错误的 KCL 程序片段如下: - -```python -a = 1 -b = "${c + 1}" # 'c' 没有定义 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> var_not_define_fail_0/main.k:2:8 - | -2 | b = "${c + 1}" # 'c' is not defined - | ^ name 'c' is not defined - | -``` - -可以尝试以下步骤来修复这个错误: - -- 对未定义的变量进行定义。 -- 在表达式中去掉对未定义变量的操作。 - -4. 无效的赋值表达式 - -可能出现错误的 KCL 程序片段如下: - -```python -# pkg.k -a = 1 - -# main.k -import pkg -pkg.a |= 2 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> pkg_inplace_modify_1/main.k:3:1 - | -6 | pkg |= 2 - | ^ unsupported operand type(s) for |: 'module 'pkg'' and 'int(2)' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查赋值表达式的内容。 - -1. 无效的字符串表达式 - -可能出现错误的 KCL 程序片段如下: - -```python -a = 1 -b = "${b = a + 1}" # Invalid string interpolation expression -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> invalid_format_value_fail_0/main.k:2:5 - | -2 | b = "${b = a + 1}" - | 5 ^ invalid string interpolation expression 'b = a + 1' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查字符串表达式的内容。 - -1. 无效的循环变量 - -可能出现错误的 KCL 程序片段如下: - -```python -data = {"key1": "value1", "key2": "value2"} -dataLoop = [i for i, j, k in data] # the number of loop variables can only be 1 or 2 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> dict/invalid_loop_var_fail_0/main.k:2:25 - | -2 | dataLoop = [i for i, j, k in data] # the number of loop variables can only be 1 or 2 - | ^ the number of loop variables is 3, which can only be 1 or 2 - | -``` - -### 1.2.11 KCLNameError [E2L25] - -如果在运行 KCL 时遇到错误: - -- `KCLNameError`, 对应的 encode 为 `E2L25` - -那么此时 KCL 程序中出现了 - -- 试图访问的变量名不存在 - -可以尝试以下步骤来修复这个错误: - -- 检查报错信息中出现的变量是否存在。 - -### 1.2.12 KCLValueError [E2L26] - -如果在运行 KCL 时遇到错误: - -- `KCLValueError`, 对应的 encode 为 `E2L26` - -那么此时 KCL 程序中出现了 - -- 值错误,传给参数的类型不正确 - -可以尝试以下步骤来修复这个错误: - -- 检查参数的具体类型。 - -### 1.2.13 KCLKeyError [E2L27] - -如果在运行 KCL 时遇到错误: - -- `KCLKeyError`, 对应的 encode 为 `E2L27` - -那么此时 KCL 程序中出现了 - -- 使用了 dict 中不存在的 key 时引发的 key 错误 - -可以尝试以下步骤来修复这个错误: - -- 检查字典中是否存在 key。 - -### 1.2.14 UniqueKeyError [E2L28] - -如果在运行 KCL 时遇到错误: - -- `UniqueKeyError`, 对应的 encode 为 `E2L28` - -那么此时 KCL 程序中出现了 - -- 变量同名或重复定义。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - name: str = "kcl" - age: int = 1 - -schema Person: - aa: int - -x0 = Person{} -x1 = Person{age:101} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L28]: UniqueKeyError - --> /schema/same_name/main.k:5:8 - | -5 | schema Person: - | ^ Unique key error name 'Person' - | - - --> /schema/same_name/main.k:1:8 - | -1 | schema Person: - | ^ The variable 'Person' is declared here - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查出现错误的名称是否已经被使用。 - -### 1.2.15 KCLAttributeComplieError [E2A29] - -如果在运行 KCL 时遇到错误: - -- `KCLAttributeComplieError`, 对应的 encode 为 `E2A29` - -那么此时 KCL 程序中出现了 - -- Schema 的属性错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -# pkg -schema A: - field_A: str - -# main -import pkg as p - -a = p.D + 1 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2G22]: TypeError - --> /import/module/no_module_attr_fail_0/main.k:4:5 - | -4 | a = p.D + 1 - | ^ module 'pkg' has no attribute D - | -``` - -可以尝试以下步骤来修复这个错误: - -- 在使用 Schema 属性时检查这个属性是否存在。 - -### 1.2.16 MultiInheritError [E2D32] - -如果在运行 KCL 时遇到错误: - -- `MultiInheritError`, 对应的 encode 为 `E2D32` - -那么此时 KCL 程序中出现了 - -- 多继承错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - firstName: str - lastName: str - -schema KnowledgeMixin: - firstName: int - subject: str - -schema Scholar(KnowledgeMixin, Person): # KCL中不支持多继承 - school: str -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: InvalidSyntax - --> /schema/inherit/multi_inherit_fail_1/main.k:9:30 - | -9 | schema Scholar(KnowledgeMixin, Person): - | ^ expected one of [")"] got , - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查程序的继承结构,KCL 中不支持多继承。 - -### 1.2.17 IllegalInheritError [E2D34] - -如果在运行 KCL 时遇到错误: - -- `IllegalInheritError`, 对应的 encode 为 `E2D34` - -那么此时 KCL 程序中出现了 - -- 不合法的继承结构 - -可能出现错误的 KCL 程序片段如下: - -```python -schema FullnameMixin: - fullName = "{} {}".format(firstName, lastName) - -schema Scholar(FullnameMixin): # KCL中不支持Schema继承Mixin - school: str -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError -Invalid value for top level arguments -``` - -可以尝试以下步骤来修复这个错误: - -- KCL 中 Schema 支持单继承 Schema。 - -### 1.2.18 IllegalArgumentComplieError [E2I36] - -如果在运行 KCL 时遇到错误: - -- `IllegalArgumentComplieError`, 对应的 encode 为 `E2I36` - -那么此时 KCL 程序中出现了 - -- 参数错误 - -可能出现错误的 KCL 程序片段如下: - -```python -a = option("key") - -# kcl main.k -D key=value= -# key=value= is an illegal expression -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError -Invalid value for top level arguments -``` - -可以尝试以下步骤来修复这个错误: - -- 检查通过命令设置的 KCL option 参数是否为合法参数。 - -### 1.2.19 ImmutableCompileError [E3L41] - -如果在运行 KCL 时遇到错误: - -- `ImmutableCompileError`, 对应的 encode 为 `E3L41` - -那么此时 KCL 程序中出现了 - -- 不可变量的值发生改变 - -可能出现错误的 KCL 程序片段如下: - -```python -a = 2147483646 -a += 1 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E1001]: ImmutableError - --> augment_assign/main.k:2:1 - | -2 | a += 1 - | ^ Immutable variable 'a' is modified during compiling - | - - --> augment_assign/main.k:1:1 - | -1 | a = 2147483646 - | ^ The variable 'a' is declared here firstly - | -note: change the variable name to '_a' to make it mutable -``` - -可以尝试以下步骤来修复这个错误: - -- 将被改变的不可变量设置为私有或者去掉对不可变量值的改动。 - -## 1.3 KCL 运行时错误 (E3xxx) - -KCL 会出现的运行时错误信息如下表所示: - -| ewcode | KCL exception | messages | -| ------ | ----------------------------------------------------------------------- | --------------------------------------------------- | -| E3F06 | [RecursiveLoad](#131-recursiveload-e3f06) | Recursively loading module | -| E3K04 | [FloatOverflow](#132-floatoverflow-e3k04) | Float overflow | -| E3K09 | [IntOverflow](#133-intoverflow-e3k09) | Integer overflow | -| E3N11 | [DeprecatedError](#134-deprecatederror-e3n11) | Deprecated error | -| E3A30 | [KCLAttributeRuntimeError](#135-kclattributeruntimeerror-e3a30) | Attribute error occurs at runtime | -| E3G21 | [TypeRuntimeError](#136-typeruntimeerror-e3g21) | The type got is inconsistent with the type expected | -| E3B17 | [SchemaCheckFailure](#137-schemacheckfailure-e3b17) | Schema check is failed to check condition | -| E3B19 | [CannotAddMembersRuntimeError](#138-cannotaddmembersruntimeerror-e3b19) | Cannot add members to a schema | -| E3M38 | [EvaluationError](#139-evaluationerror-e3m38) | Evaluation failure | -| E3M39 | [InvalidFormatSpec](#1310-invalidformatspec-e3m39) | Invalid format specification | -| E3M40 | [KCLAssertionError](#1311-kclassertionerror-e3m40) | Assertion failure | -| E3M44 | [ImmutableRuntimeError](#1312-immutableruntimeerror-e3m44) | Immutable variable is modified | -| E2D33 | [CycleInheritError](#1313-cycleinheriterror-e2d33) | Cycle Inheritance is illegal | -| E3M42 | [KCLRecursionError](#1314-kclrecursionerror-e3m42) | Recursively reference | - -### 1.3.1 RecursiveLoad [E3F06] - -如果在运行 KCL 时遇到错误: - -- `RecursiveLoad`, 对应的 encode 为 `E3F06` - -那么此时 KCL 程序中出现了 - -- 循环导入错误 - -可能出现错误的 KCL 程序片段如下: - -``` -# module.k -import main # module.k 导入了 main.k - -print('module') - -# main.k -import module # main.k 导入了 module.k - -print('main') -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /import/recursive_import_fail/main.k:4 - | -2 | import module # main.k imports module.k - | ^ There is a circular import reference between module main and module - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查包的导入部分是否存在循环导入的问题。 - -### 1.3.2 FloatOverflow [E3K04] - -如果在运行 KCL 时遇到错误: - -- `FloatOverflow`, 对应的 encode 为 `E3K04` - -那么此时 KCL 程序中出现了 - -- 浮点数溢出 - -可能出现错误的 KCL 程序片段如下: - -```python -uplimit = 3.402823466e+39 -epsilon = 2.220446049250313e-16 -a = uplimit * (1 + epsilon) - -# kcl main.k -r -d -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /range_check_float/overflow/number_0/main.k:3:1 - | -3 | a = uplimit * (1 + epsilon) - | 3.4028234660000003e+39: A 32-bit floating point number overflow - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查浮点数的值是否在 KCL 支持的数字范围内。 - -### 1.3.3 IntOverflow [E3K09] - -如果在运行 KCL 时遇到错误: - -- `IntOverflow`, 对应的 encode 为 `E3K09` - -那么此时 KCL 程序中出现了 - -- 整数溢出 - -可能出现错误的 KCL 程序片段如下: - -```python -_a = 9223372036854775807 -_a += 1 - -# kcl test.k -d -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /range_check_int/augment_assign_fail_1/main.k:2:1 - | -2 | _a += 1 - | 9223372036854775808: A 64 bit integer overflow - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查整数的值是否在 KCL 支持的数字范围内。 - -### 1.3.4 DeprecatedError [E3N11] - -如果在运行 KCL 时遇到错误: - -- `DeprecatedError`, 对应的 encode 为 `E3N11` - -那么此时 KCL 程序中出现了 - -- 使用废弃代码 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - firstName: str = "John" - lastName: str - @deprecated(version="1.16", reason="use firstName and lastName instead", strict=True) - name: str - -JohnDoe = Person { - name: "deprecated" # name已经被过时,并且strict设置为True -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /range_check_float/overflow/number_0/main.k:7:1 - | -7 | JohnDoe = Person { - | name was deprecated since version 1.16, use firstName and lastName instead - | -``` - -可以尝试以下步骤来修复这个错误: - -- strict 设置为 True 时无法使用过时的代码,可以将 strict 设置为 False,将不会出现错误,而是输出一个警告。 -- 调整代码,不使用已经过时的代码。 - -### 1.3.5 KCLAttributeRuntimeError [E3A30] - -如果在运行 KCL 时遇到错误: - -- `KCLAttributeRuntimeError`, 对应的 encode 为 `E3A30` - -那么此时 KCL 程序中出现了 - -- 属性错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -import math - -a = math.err_func(1) # err_func is not found in math -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /import/module/no_module_attr_fail_2/main.k:3:5 - | -3 | a = math.err_func(1) # err_func is not found in math - | ^ module 'math' has no attribute err_func - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查属性调用是否正确。 - -### 1.3.6 TypeRuntimeError [E3G21] - -如果在运行 KCL 时遇到错误: - -- `TypeRuntimeError`, 对应的 encode 为 `E3G21` - -那么此时 KCL 程序中出现了 - -- 类型检查错误 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - name: str = "Alice" - -_personA = Person {} -_personA |= {"name" = 123.0} # name: str = "Alice" -personA = _personA -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /fail/fail_4/main.k:2:1 - | -2 | name: str = "Alice" - | expect str, got float - | -``` - -可以尝试以下步骤来修复这个错误: - -- 停止错误的类型合并或者将类型调整为 KCL 支持的类型合并。 - -### 1.3.7 SchemaCheckFailure [E3B17] - -如果在运行 KCL 时遇到错误: - -- `SchemaCheckFailure`, 对应的 encode 为 `E3B17` - -那么此时 KCL 程序中出现了 - -- Schema 中的 check 条件冲突 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - lastName: str - age: int - check: - age < 140, "age is too large" - -JohnDoe = Person { - "lastName": "Doe", - "age": 1000 # Schema中的check条件为: age < 140 -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /check_block/check_block_fail_1/main.k:7:11 - | -7 | JohnDoe = Person { - | ^ Instance check failed - | - - --> /check_block/check_block_fail_1/main.k:5:1 - | -5 | age < 140, "age is too large" - | Check failed on the condition - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 Schema 的属性与 check 中的条件是否符合 - -### 1.3.8 CannotAddMembersRuntimeError [E3B19] - -如果在运行 KCL 时遇到错误: - -- `CannotAddMembersRuntimeError`, 对应的 encode 为 `E3B19` - -那么此时 KCL 程序中出现了 - -- 访问 Schema 中不存在的成员 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Name: - name: str - -schema Person: - name: Name - -person = Person { - name.err_name: "Alice" # err_name is not found in schema Name -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /nest_var/nest_var_fail_1/main.k:8:5 - | -8 | name.err_name: "Alice" # err_name is not found in schema Name - | ^ Cannot add member 'err_name' to schema 'Name' - | -``` - -可以尝试以下步骤来修复这个错误: - -- 为 Schema 添加不存在的成员。 -- 访问 Schema 中存在的成员。 - -### 1.3.9 EvaluationError [E3M38] - -如果在运行 KCL 时遇到错误: - -- `EvaluationError`, 对应的 encode 为 `E3M38` - -那么此时 KCL 程序中出现了 - -- 当 KCL 中数值计算过程出现了错误。 - -可能出现错误的 KCL 程序片段如下: - -```python -_list1 = [1, 2, 3] # _list1 is a variable, and its type can only be known at runtime -_list2 = None # _list1 is a variable, and its type can only be known at runtime - -result2 = _list1 + _list2 # list + NoneType is illegal -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /datatype/list/add_None_fail/main.k:1 - | -4 | result2 = _list1 + _list2 # list + NoneType is illegal - | can only concatenate list (not "NoneType") to list - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查表达式中是否存在变量为 None,或者非法的计算过程。 - -### 1.3.10 InvalidFormatSpec [E3M39] - -如果在运行 KCL 时遇到错误: - -- `InvalidFormatSpec`, 对应的 encode 为 `E3M39` - -那么此时 KCL 程序中出现了 - -- 非法的字符串格式 - -可能出现错误的 KCL 程序片段如下: - -```python -a = 1 -b = 1 -data = "${a: #js}" + " $$ " # KCL插值字符串中,#js是非法的 -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /datatype/str_interpolation/invalid_format_spec_fail_0/main.k:3 - | -3 | data = "${a: #js}" + " $$ " # #js is illegal string - | ^ #js is a invalid format spec - | -``` - -可以尝试以下步骤来修复这个错误: - -- 将非法 String 调整为 KCL 标准支持的 String。 - -### 1.3.11 KCLAssertionError [E3M40] - -如果在运行 KCL 时遇到错误: - -- `KCLAssertionError`, 对应的 encode 为 `E3M40` - -那么此时 KCL 程序中出现了 - -- Assert False - -可能出现错误的 KCL 程序片段如下: - -```python -assert False -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /assert/invalid/fail_0/main.k:1 - | -1 | assert False - | - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 Assert 的条件,Assert 条件为 False 时,就会出现此类错误,去掉 Assert 语句或改变条件为 True。 - -### 1.3.12 ImmutableRuntimeError [E3M44] - -如果在运行 KCL 时遇到错误: - -- `ImmutableRuntimeError`, 对应的 encode 为 `E3M44` - -那么此时 KCL 程序中出现了 - -- 不可变量的值发生改变 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Person: - final firstName : str - lastName : str - - -schema Scholar(Person): - firstName = "CBA" - - -scholar = Scholar { - "firstName": "ABC" # firstName in schema Person is final. -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E3M38]: EvaluationError - --> /final/fail_lazy_init_0/main.k:8:1 - | -8 | scholar = Scholar { - | attribute 'lastName' of Scholar is required and can't be None or Undefined - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 final 修饰的不可变量是否出现了赋值等改变值的操作。 - -### 1.3.13 CycleInheritError [E2D33] - -如果在运行 KCL 时遇到错误: - -- `CycleInheritError`, 对应的 encode 为 `E2D33` - -那么此时 KCL 程序中出现了 - -- 循环继承 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Parent(Son): - parent_field: str - -schema Son(GrandSon): - son_field: str - -schema GrandSon(Parent): - grandson_field: str - -parent = Parent { - parent_field: "" -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -error[E2L23]: CompileError - --> /inherit/cycle_inherit_fail_1/main.k:7:8 - | -7 | schema GrandSon(Parent): - | ^ There is a circular reference between schema GrandSon and Parent - | -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 Schema 的继承关系,避免出现 A 继承 B,B 继承 A 的情况。 - -### 1.3.14 KCLRecursionError [E3M42] - -如果在运行 KCL 时遇到错误: - -- `KCLRecursionError`, 对应的 encode 为 `E3M42` - -那么此时 KCL 程序中出现了 - -- 循环引用 - -可能出现错误的 KCL 程序片段如下: - -```python -schema Parent(Son): - parent_field: str - son: Son = Son { # Parent has attribute Son - parent: Parent { - parent_field: "123" - } - } - -schema Son: - son_field: str - parent: Parent = Parent { # Son has attribute Parent - son: Son { - son_field: "123" - } - } - -parent = Parent { - parent_field: "", -} -``` - -KCL 在运行上述 KCL 程序片段时的输出信息如下. - -```shell -thread 'main' has overflowed its stack -fatal runtime error: stack overflow -``` - -可以尝试以下步骤来修复这个错误: - -- 检查 Schema 中的属性成员,避免出现循环引用的问题。 - -## 1.4 KCL 编译警告 (W2xxx) - -KCL 中的编译警告如下表所示: - -| ewcode | KCL exception | messages | -| ------ | ------------------------------------------------- | ------------------ | -| W2K04 | [FloatUnderflow](#141-floatunderflow-w2k08) | Float underflow | -| W2P10 | [InvalidDocstring](#142-invaliddocstring-w2p10) | Invalid docstring | -| W2N12 | [DeprecatedWarning](#143-deprecatedwarning-w2n12) | Deprecated warning | - -### 1.4.1 FloatUnderflow [W2K08] - -如果在运行 KCL 时遇到错误: - -- `FloatUnderflow`, 对应的 encode 为 `W2K08` - -可以尝试以下步骤来修复这个错误: - -- 检查浮点数的值是否在 KCL 支持的数字范围内。 - -### 1.4.2 InvalidDocstring [W2P10] - -如果在运行 KCL 时遇到错误: - -- `InvalidDocstring`, 对应的 encode 为 `W2P10` - -那么此时 KCL 程序中出现了 - -- 无效的 doc 内容 - -可以尝试以下步骤来修复这个错误: - -- 请按照 KCL 标准编写 doc。 - -### 1.4.3 DeprecatedWarning [W2N12] - -如果在运行 KCL 时遇到错误: - -- `DeprecatedWarning`, 对应的 encode 为 `W2N12` - -那么此时 KCL 程序中出现了 - -- 过时的代码警告 - -可以尝试以下步骤来修复这个错误: - -- 尽量不要使用已经过时的代码。如果将 strict 设置为 True,KCL 将会输出错误,并停止运行。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/error/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/error/index.md deleted file mode 100644 index e4f702ec..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/error/index.md +++ /dev/null @@ -1 +0,0 @@ -# 错误与警告 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/index.md deleted file mode 100644 index 66fd3dde..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/index.md +++ /dev/null @@ -1 +0,0 @@ -# KCL diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/_category_.json deleted file mode 100644 index c088e386..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "规范", - "position": 3 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/error.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/error.md deleted file mode 100644 index 2a58b553..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/error.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: "Errors" -linkTitle: "Errors" -type: "docs" -weight: 2 -description: Errors ---- - -When errors happen, developers should be able to detect the error and abort -execution. Thus, KCL introduce the `assert` syntax. - -In the previous topic of `schema` syntax. Errors can also be raised when a -schema is violated. - -## Syntax - -The syntax of the `assert` statement is the following. - -```bnf -assert_stmt: 'assert' test ['if' test] [',' test] -``` - -In the basic form, an `assert` statement evaluates an expression. If the -expression is evaluated to `False`, the assertion is failed, and an error -should be reported. - -In the extended form, an error message can be provided. The error message is -another expression. It is only evaluated when the expression to be evaluated -is evaluated to `False`. The evaluation result of the error message is printed -when reporting the error. - -The following is an example: - -```python -a = 1 -b = 3 -condition = False -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -# if condition is True, then assert `a == b`, if failed, the message "error message" will be printed. -assert a == b if condition, "error message" -``` - -## The Implementation - -When an error happens, no matter it is caused by the `assert` or the `schema` syntax, -the virtual machine should exit with an exit code greater than `0`. - -The virtual machine may choose to dump the back trace information, and it is strongly recommended to implement it. - -In practice, KCL can dump back trace by default, and an argument can be introduced to disable it. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/expressions.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/expressions.md deleted file mode 100644 index b52c10f3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/expressions.md +++ /dev/null @@ -1,915 +0,0 @@ ---- -title: "Expressions" -linkTitle: "Expressions" -type: "docs" -weight: 2 -description: Expressions ---- - -## Syntax - -In KCL, an expression specifies the computation of a value. - -The syntax is the following: - -```bnf -expression: test ("," test)* -test: if_expr | primary_expr | unary_expr | binary_expr -``` - -KCL expressions consist of `if` expression, `primary` expression, `unary` expression, and `binary` expression. - -### Primary Expressions - -Primary expressions are the operands for unary and binary expressions. - -Operands are self-delimiting. An **operand** may be followed by any number of selector dot, a function call, or slice suffixes, to form a primary expression. The grammar uses `expression`, where a multiple-component expression is allowed, and `test` where it accepts an expression of only a single component. - -Syntax: - -```bnf -primary_expr: operand | primary_expr select_suffix | primary_expr call_suffix | primary_expr subscript_suffix -``` - -### Operands - -Operand denotes the elementary value in an expression. An operand may be an identifier, a literal, or a parenthesized expression. - -Syntax: - -```bnf -operand: operand_name | number | string | "True" | "False" | "None" | "Undefined" | list_expr | list_comp | dict_expr | dict_comp | "(" expression ")" -operand_name: identifier | qualified_identifier -``` - -### Identifiers - -In KCL, an identifier is a name, may with selectors, that identifies a value. - -Syntax: - -```bnf -identifier: NAME -``` - -Examples: - -```python -x -a -_b -``` - -Use the `$` character prefix to define keyword identifiers. - -```python -$if = 1 -$else = "s" -``` - -Please note: whether the non-keyword identifier is prefixed with `$` has the same effect. - -```python -_a = 1 -$_a = 2 # equal to `_a = 2` -``` - -To simplify the definition of the qualified identifier, such as 'pkg.type', we additionally define `qualified_identifier`: - -Syntax: - -```bnf -qualified_identifier: identifier "." identifier -``` - -Examples: - -```python -pkg.a -``` - -The package name in qualified_identifier must be imported. - -### Basic Literals - -Basic literals supported in KCL are `int`, `float`, `string` and `bool` including `True` and `False`. Evaluation of basic literal yields a value of the given type with the given value. - -Syntax: - -```bnf -operand: number | string | "True" | "False" | "None" | "Undefined" -``` - -Examples: - -```python -1 -2.3 -"abc" -True -False -None -Undefined -``` - -See more details about **data type** spec. - -### Parenthesized Expressions - -An expression enclosed in parentheses yields the result of that expression. - -Syntax: - -```bnf -operand: '(' expression ')' -``` - -Examples: - -```python -x = (1 + 2) * (3 + 4) # 21 -``` - -### Dictionary Expressions - -A dictionary expression is a comma-separated immutable list of colon-separated key/value expression pairs, enclosed in curly brackets, and it yields a new dictionary object. An optional comma may follow the final pair. - -```bnf -config_expr: '{' config_entries '}' -config_entries: config_entry [config_entry*] -config_comp: '{' (config_entry comp_clause+) '}' -config_entry: expr (':' | '=' | '+=') expr | double_star_expr | if_entry -double_star_expr: "**" expression -if_entry: - 'if' expr ';' if_entry_exec_block - ('elif' expr ':' if_entry_exec_block)* - ('else' ':' if_entry_exec_block)? -NEWLINE: '/r?/n' -``` - -Examples: - -```python -{} -{"one": 1} -{"one": 1, "two": 2} -``` - -The key and value expressions are evaluated in left-to-right order. Evaluation fails if the same key is used multiple times. - -Only hashable values may be used as the keys of a dictionary. This includes all built-in types except dictionaries, and lists. - -We can ignore the comma `,` at the end of the line for writing dict key-value pairs in multiple lines: - -```python -data = { - "key1" = "value1" # Ignore the comma ',' at the end of line - "key2" = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -We can ignore the key quotation marks when we writing simple literals on the key. - -```python -data = { - key1 = "value1" # Ignore the comma ',' at the end of line - key2 = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -In addition, the **config selector expressions** can be used to init a schema instance. - -```python -person = { - base.count = 2 - base.value = "value" - labels.key = "value" -} # {"base": {"count": 2, "value": "value"}, "labels": {"key": "value"}} -``` - -We can **merge** dict using the dict unpacking operator `**` like this: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = {**_part1, **_part2} # {"a: "b", "c": "d"} -``` - -We can use `if expressions` to dynamically add elements to the dict element, elements that meet the conditions are added to the dict, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = { - key1 = "value1" - if a == 1: key2 = "value2" - if a > 0: key3 = "value3" - if a < 0: key4 = "value4" -} # {"key1": "value1", "key2": "value2", "key3": "value3"} -``` - -```python -a = 1 # 1 -data1 = { - key1 = "value1" - if a == 1: - key2 = "value2" - elif a > 0: - key3 = "value3" - else: - key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -data2 = { - key1 = "value1" - if a == 1: key2 = "value2" - elif a > 0: key3 = "value3" - else: key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -``` - -### List Expressions - -A list expression is a comma-separated immutable list of element expressions, enclosed in square brackets, and it yields a new list. An optional comma may follow the last element expression. - -```bnf -list_expr: '[' [list_item [',']] ']' -list_item: test | "*" primary_expr | if_expr -``` - -Element expressions are evaluated in left-to-right order. - -Examples: - -```python -[] # [], empty list -[1] # [1], a 1-element list -[1, 2, 3] # [1, 2, 3], a 3-element list -``` - -We can use `if expressions` to dynamically add elements to the list element, elements that meet the conditions are added to the list, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = [ - 1 - if a == 1: 2 - if a > 0: 3 - if a < 0: 4 -] # [1, 2, 3] -``` - -```python -a = 1 # 1 -data1 = [ - 1 - if a == 1: - 2 - elif a == 2: - 3 - else: - 3 -] # [1, 2] -data2 = [ - 1 - if a == 1: 2 - elif a == 2: 2 - else: 3 -] # [1, 2] -``` - -### Comprehensions - -A comprehension constructs a new list or dictionary value by looping over one or more iterables and evaluating a body expression that produces successive elements of the result. - -Syntax: - -```bnf -list_comp: '[' list_item comp_clause+ ']' . -dict_comp: '{' entry comp_clause+ '}' . - -comp_clause: 'for' loop_variables [","] 'in' test ['if' test] -loop_variables: primary_expr (',' primary_expr)* -``` - -A list comprehension consists of a single expression followed by one or more clauses, the first of which must be a `for` clause. Each `for` clause resembles a `for` statement, and specifies an iterable operand and a set of variables to be assigned by successive values of the iterable. An `if` cause resembles an `if` statement, and specifies a condition that must be met for the body expression to be evaluated. A sequence of `for` and `if` clauses acts like a nested sequence of `for` and `if` statements. - -Examples: - -```python -[x * x for x in range(5)] # [0, 1, 4, 9, 16] -[x * x for x in range(5) if x % 2 == 0] # [0, 4, 16] -[[x, y] for x in range(5) \ - if x % 2 == 0 \ - for y in range(5) \ - if y > x] # [[0, 1], [0, 2], [0, 3], [0, 4], [2, 3], [2, 4]] -``` - -Besides, we can use two variables in the list comprehension, the first variable denotes the list index and the second variable denotes the list item. - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use `_` to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -A dict comprehension resembles a list comprehension, but its body is a pair of expressions, key: value, separated by a colon, and its result is a dictionary containing the key/value pairs for which the body expression was evaluated. Evaluation fails if the value of any key is un-hashable. - -Besides, we can use two variables in the dict comprehension, the first variable denotes the dict key and the second variable denotes the dict value of the key. - -```python -data = {"key1" = "value1", "key2" = "value2"} -# Single variable loop -dataKeys1 = {k: k for k in data} # {"key1": "key1", "key2": "key2"} -dataValues1 = {k: data[k] for k in data} # {"key1": "value1", "key2": "value2"} -# Double variable loop -dataKeys2 = {k: k for k, v in data} # {"key1": "key1", "key2": "key2"} -dataValues2 = {v: v for k, v in data} # {"value1": "value1", "value2": "value2"} -dataFilter = {k: v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use `_` to ignore loop variables -dataKeys3 = {k: k for k, _ in data} # {"key1": "key1", "key2": "key2"} -dataValues3 = {v: v for _, v in data} # {"value1": "value1", "value2": "value2"} -``` - -As with a `for` loop, the loop variables may exploit compound assignment: - -```python -[x * y + z for [x, y], z in [[[2, 3], 5], [["o", 2], "!"]]] # [11, 'oo!'] -``` - -KCL does not accept an un-parenthesized list as the operand of a for clause: - -```python -[x * x for x in 1, 2, 3] # parse error: unexpected comma -``` - -Comprehensions defines a new lexical block, so assignments to loop variables have no effect on variables of the same name in an enclosing block: - -```python -x = 1 -_ = [x for x in [2]] # new variable x is local to the comprehension -print(x) # 1 -``` - -The operand of a comprehension's first clause (always a for) is resolved in the lexical block enclosing the comprehension. In the examples below, identifiers referring to the outer variable named x have been distinguished by subscript. - -```python -x0 = [1, 2, 3] -[x * x for x in x0] # [1, 4, 9] -[x * x for x in x0 if x % 2 == 0] # [4] -``` - -All subsequent for and if expressions are resolved within the comprehension's lexical block, as in this rather obscure example: - -```python -x0 = [[1, 2], [3, 4], [5, 6]] -[x * x for x in x0 for x in x if x % 2 == 0] # [4, 16, 36] -``` - -which would be more clearly rewritten as: - -```python -x = [[1, 2], [3, 4], [5, 6]] -[z * z for y in x for z in y if z % 2 == 0] # [4, 16, 36] -``` - -### Conditional Expressions - -A conditional expression has the form `a if cond else b`. It first evaluates the condition `cond`. If it's true, it evaluates `a` and yields its value; otherwise it yields the value of `b`. - -Syntax: - -```bnf -if_expr: test "if" test "else" test -``` - -Examples: - -```python -x = True if enabled else False # if enabled is -``` - -### Unary Expressions - -In KCL, supported unary operators are `+`, `-`, `~`, and `not`. - -Syntax: - -```bnf -unary_expr: ("+" | "-" | "~") primary_expr - | "not" test -``` - -Usage: - -```bnf -+ number unary positive (int, float) -- number unary negation (int, float) -~ number unary bitwise inversion (int) -not x logical negation (any type) -``` - -The `+` and `-` operators may be applied to any number (int or float) and return the number. -The `not` operator returns the negation of the truth value of its operand. - -Examples: - -```python -~1 # -2 -~-1 # 0 -~0 # -1 -not True # False -not 0 # True -``` - -### Binary Expressions - -In KCL, binary expressions consist of `comparisons`, `logical operations`, `arithmetic operations` and `membership tests`. - -Syntax: - -```bnf -binary_expr: test bin_op test -bin_op: 'or' - | 'and' - | '==' | '!=' | '<' | '>' | '<=' | '>=' - | 'in' | 'not' 'in' - | '|' - | '^' - | '&' - | '-' | '+' - | '*' | '%' | '/' | '//' - | '<<' | '>>' -``` - -#### Logical Operations - -The `or` and `and` operators yield the logical disjunction and conjunction of their arguments, which need not be Booleans. - -The expression `x or y` yields the value of `x` if its truth value is `True`, or the value of `y` otherwise. - -```python -False or False # False -False or True # True -True or True # True -1 or "hello" # 1 -``` - -Similarly, `x` and `y` yields the value of `x` if its truth value is `False`, or the value of `y` otherwise. - -```python -False and False # False -False and True # False -True and True # True -1 and "hello" # "hello" -``` - -These operators use "short circuit" evaluation, so the second expression is not evaluated if the value of the first expression has already determined the result, allowing constructions like these: - -```python -x and x[0] == 1 # x[0] is not evaluated if x is empty -len(x) == 0 or x[0] == "" -not x or not x[0] -``` - -#### Comparisons - -The `==` operator reports whether its operands are equal; the `!=` operator is its negation. - -The operators `<`, `>`, `<=`, and `>=` perform an ordered comparison of their operands. It is an error to apply these operators to operands of unequal type, unless one of the operands is an `int` and the other is a `float`. Of the built-in types, only the following support ordered comparison, using the ordering relation shown: - -```bnf -NoneType # None <= None -bool # False < True -int # mathematical -float # as defined by IEEE 754 -string # lexicographical -list # lexicographical -``` - -Comparison of floating-point values follows the IEEE 754 standard, which breaks several mathematical identities. For example, if `x` is a `NaN` value, the comparisons `x < y`, `x == y`, and `x > y` all yield false for all values of `y`. - -The remaining built-in types support only equality comparisons. Values of type `dict` and `schema` compare equal if their elements compare equal, and values of type function or `builtin_function_or_method` are equal only to themselves. - -```bnf -dict # equal contents -schema # equal exported-attributes -function # identity -builtin_function_or_method # identity -``` - -#### Arithmetic Operations - -The following table summarizes the binary arithmetic operations available for built-in types: - -```bnf -Arithmetic (int or float; result has type float unless both operands have type int) - number + number # addition - number - number # subtraction - number * number # multiplication - number / number # real division (result is always a float) - number // number # floored division - number % number # remainder of floored division - number ^ number # bitwise XOR - number << number # bitwise left shift - number >> number # bitwise right shift - -Concatenation - string + string - list + list - -Repetition (string/list) - int * sequence - sequence * int - -Union - int | int - list | list - dict | dict - schema | schema - schema | dict -basictype | basictype -``` - -The operands of the arithmetic operators `+`, `-`, `*`, `//`, and `%` must both be numbers (`int` or `float`) but need not have the same type. The type of the result has type `int` only if both operands have that type. The result of real division / always has type `float`. - -The `+` operator may be applied to non-numeric operands of the same type, such as two lists, or two strings, in which case it computes the concatenation of the two operands and yields a new value of the same type. - -```python -"Hello, " + "world" # "Hello, world" -[1, 2] + [3, 4] # [1, 2, 3, 4] -``` - -The `*` operator may be applied to an integer n and a value of type `string`, `list`, in which case it yields a new value of the same sequence type consisting of n repetitions of the original sequence. The order of the operands is immaterial. Negative values of n behave like zero. - -```python -'mur' * 2 # 'murmur' -3 * range(3) # [0, 1, 2, 0, 1, 2, 0, 1, 2] -``` - -The `&` operator requires two operands of the same type, such as `int`. For integers, it yields the bitwise intersection (AND) of its operands. - -The `|` operator likewise computes bitwise, unions basic types and unions collection and schema data, such as **list**, **dict** and **schema**. - -Computing bitwise examples: - -```python -0x12345678 | 0xFF # 0x123456FF -``` - -Unioning basic types examples: - -```python -schema x: - a: int | str # attribute a could be a int or string -``` - -A union type is used to define a schema attribute type. See more details in **schema** spec. -Supported types in a union type are `int`, `str`, `float`, `bool`, `list` and `dict`. - -Unioning collection and schema data: - -- Unioning List. Overwrite the list expression on the right side of the operator `|` to the list variable on the left side of the operator one by one according to the **index**. - -```python -_a = [1, 2, 3] -_b = [4, 5, 6, 7] -x = _a | _b # [4, 5, 6, 7] 4 -> 1; 5 -> 2; 6 -> 3; 7 -> None -``` - -Unioning to the specific index or all elements is still under discussion. - -- Unioning Dict. Union the dict expression on the right side of the operator `|` one by one to the dict variable on the left side of the operator according to the **key** - -```python -_a = {key1 = "value1"} -_b = {key1 = "overwrite", key2 = "value2"} -_c = _a | _b # {"key1": "overwrite", "key2": "value2"} -``` - -The union of collection and schema is a new one whose attributes are unioning b to a, preserving the order of the attributes of the operands, left before right. - -Unioning to the specific key or all keys is still under discussion. - -- Unioning Schema. - -The union operation for schema is similar to dict. - -Schema union could be done as: - -```bnf -schema Person: - firstName: str - lastName: str - -_a = Person { - firstName = "John" -} -_b = {lastName = "Doe"} -_a = _a | _b # {"firstName": "John", "lastName": "Doe"} -``` - -Unioning to a specific attribute is still under discussion. Unioning to all attributes is not applicable to schema instances. - -See **selector expression** in **expression** spec for more details. - -The `^` operator accepts operands of `int`. For integers, it yields the bitwise XOR (exclusive OR) of its operands. - -The `<<` and `>>` operators require operands of `int` type both. They shift the first operand to the left or right by the number of bits given by the second operand. It is a dynamic error if the second operand is negative. Implementations may impose a limit on the second operand of a left shift. - -```python -0x12345678 & 0xFF # 0x00000078 -0b01011101 ^ 0b110101101 # 0b111110000 -0b01011101 >> 2 # 0b010111 -0b01011101 << 2 # 0b0101110100 -``` - -#### Membership Tests - -Usage: - -```bnf - any in sequence (list, dict, schema, string) - any not in sequence -``` - -The `in` operator reports whether its first operand is a member of its second operand, which must be a list, dict, schema, or string. The `not in` operator is its negation. Both return a Boolean. - -The meaning of membership varies by the type of the second operand: the members of a list are its elements; the members of a dict are its keys; the members of a string are all its substrings. - -```python -1 in [1, 2, 3] # True - -d = {"one" = 1, "two" = 2} -"one" in d # True -"three" in d # False -1 in d # False -[] in d # False - -"nasty" in "dynasty" # True -"a" in "banana" # True -"f" not in "way" # True - -d = data {one = 1, two = 2} # data is a schema with attributes one and two -"one" in d # True -"three" in d # False -``` - -### Function Invocations - -KCL allows calling built-in functions and functions from built-in and system modules. Whether KCL allows defining new functions is under discussion. - -Syntax: - -```bnf -call_suffix: "(" [arguments [","]] ")" -arguments: argument ("," argument)* -argument: test | identifier "=" test | "*" test | "**" test -``` - -To call a function, the basic way is shown as the following code excerpt: - -```python -print("An argument") - -import math -# 2 powers 3 is 8. -a = math.pow(2, 3) -``` - -As you can see, arguments are separated with `,`. Arguments can only be passed in this way. KCL supports positional arguments and key-value arguments. - -Note that: - -- Some functions have parameters with default values. -- Some functions accept variadic arguments. - -When an argument is not supplied for a parameter without a default value, -an error will be reported. - -### Selector Expressions - -A selector expression selects the attribute or method of the value. - -#### Select Attributes - -Syntax: - -```bnf -select_suffix: ["?"] "." identifier -``` - -KCL provides a wealth of ways to identify or filter attributes. - -x.y - -- schema: it denotes the attribute value of a schema `x` identified by `y` -- package: it denotes the identifier of a package `x` identified by `y` - -Examples: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -name = person.name # "Alice" -age = person.age # 18 -``` - -x?.y - -If the x if None/Undefined or empty(empty list or dict), just return None, otherwise behave as x.y. - -Examples - -```python -noneData = None -data?.name # None - -emptyDict = {} -emptyDict?.name # None - -emptyList = [] -emptyList?[0] # None -``` - -As a supplementary of the `selector` expression in KCL code, the KCL compiler needs to provide corresponding identifying and filtering features through the command line and api form. - -#### Select Methods - -Syntax: - -```bnf -select_suffix: "." identifier -``` - -A `identifier` identifies method belongs to the built-in types `string`, `list`, `dict`, and `schema`. - -- A selector expression fails if the value does not have an attribute of the specified name. -- A selector expression that selects a method typically appears within a call expression, as in these examples: - -Examples: - -```python -["able", "baker", "charlie"].index("baker") # 1 -"banana".count("a") # 3 -"banana".reverse() # error: string has no .reverse field or method -Person.instances() # all instances of schema Person -``` - -But when not called immediately, the selector expression evaluates to a bound method, that is, a method coupled to a specific receiver value. A bound method can be called like an ordinary function, without a receiver argument: - -```bnf -f = "banana".count -f # -f("a") # 3 -f("n") # 2 -``` - -### Index Expressions - -An index expression `a[i]` yields the `i` th element of an indexable type such as a string or list. The index `i` must be an `int` value in the range `-n` ≤ `i` < `n`, where `n` is `len(a)`; any other index results in an error. - -Syntax: - -```bnf -subscript_suffix: "[" [test] "]" -``` - -A valid negative index `i` behaves like the non-negative index `n+i`, allowing for convenient indexing relative to the end of the sequence. - -```python -"abc"[0] # "a" -"abc"[1] # "b" -"abc"[-1] # "c" - -["zero", "one", "two"][0] # "zero" -["zero", "one", "two"][1] # "one" -["zero", "one", "two"][-1] # "two" -``` - -An index expression `d[key]` may also be applied to a dictionary `d`, to obtain the value associated with the specified key. It returns `Undefined` if the dictionary contains no such key. - -An index expression appearing on the left side of an assignment causes the specified list or dictionary element to be updated: - -```python -a = range(3) # a == [0, 1, 2] -b = a[2] # 2 - - -``` - -It is a dynamic error to attempt to update an element of an immutable type, such as a list or string, or a frozen value of a mutable type. - -### Slice Expressions - -A slice expression `a[start:stop:stride]` yields a new value containing a sub-sequence of `a`, which must be a string, or list. - -```bnf -subscript_suffix: "[" [test] [":" [test] [":" [test]]] "]" -``` - -Each of the `start`, `stop`, and `stride` operands is optional; if present, and not `None`, each must be an integer. -The `stride` value defaults to 1. If the stride is not specified, the colon preceding it may be omitted too. It is an error to specify a stride of zero. - -Conceptually, these operands specify a sequence of values `i` starting at start and successively adding `stride` until `i` reaches or passes `stop`. The result consists of the concatenation of values of `a[i]` for which `i` is valid.` - -The effective start and stop indices are computed from the three operands as follows. Let `n` be the length of the sequence. - -**If the stride is positive**: If the `start` operand was omitted, it defaults to -infinity. If the `end` operand was omitted, it defaults to +infinity. For either operand, if a negative value was supplied, `n` is added to it. The `start` and `end` values are then "clamped" to the nearest value in the range 0 to `n`, inclusive. - -**If the stride is negative**: If the `start` operand was omitted, it defaults to +infinity. If the `end` operand was omitted, it defaults to -infinity. For either operand, if a negative value was supplied, `n` is added to it. The `start` and `end` values are then "clamped" to the nearest value in the range -1 to `n`-1, inclusive. - -```python -"abc"[1:] # "bc" (remove first element) -"abc"[:-1] # "ab" (remove last element) -"abc"[1:-1] # "b" (remove first and last element) -"banana"[1::2] # "aaa" (select alternate elements starting at index 1) -"banana"[4::-2] # "nnb" (select alternate elements in reverse, starting at index 4) -``` - -It's not allowed to define a slice expression as a left value in KCL. -Cause list and string are immutable, re-slicing can directly operate to operand to ensure better performance. - -#### Quantifier Expressions - -Quantifier expressions act on collection: list or dict, generally used to obtain a certain result after processing the collection, mainly in the following four forms: - -```bnf -quant_expr: quant_op [ identifier ',' ] identifier 'in' quant_target '{' expr ['if' expr] '}' -quant_target: string | identifier | list_expr |list_comp | dict_expr | dict_comp -quant_op: 'all' | 'any' | 'filter' | 'map' -``` - -- **all** - - Used to detect that all elements in the collection satisfy the given logical expression, and return a boolean value as the result. - - Only when all elements in the collection satisfy the expression true, the `all` expression is true, otherwise it is false. - - If the original collection is empty, return true. - - Supports short-circuiting of logical expressions during expression execution. -- **any** - - Used to detect that at least one element in the collection satisfies the given logical expression, and returns a boolean value as the result. - - When at least one element in the collection satisfies the expression true, the `any` expression is true, otherwise it is false. - - If the original collection is empty, return false. - - Supports short-circuiting of logical expressions during expression execution. -- **map** - - Generate a new **list** by mapping the elements in the original collection. - - The length of the new list is exactly the same as the original collection. -- **filter** - - By logically judging and filtering the elements in the original collection, and returning the filtered sub-collection. - - Only when the element judges the expression to be true, it is added to the sub-collection. - - The type (list, dict and schema) of the new collection is exactly the same as the original collection, and the length range is `[0, len(original-collection)]`. - -**all** and **any** expression sample codes: - -```python -schema Config: - volumes: [{str:}] - services: [{str:}] - - check: - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - }, "invalid cluster ip" - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } -``` - -**map** and **filter** expression sample codes: - -```python -a = map e in [{name = "1", value = 1}, {name = "2", value = 2}] { - {name = e.name, value = int(e.value) ** 2} -} # [{"name": "1", value: 1}, {"name": "2", "value": 4}] - -b = map k, v in {a = "foo", b = "bar"} { v } # ["foo", "bar"] - -c = filter e in [{name = "1", value = 1}, {name = "2", value = 2}] { - int(e.value) > 1 -} # [{"name": "2", "value": 2}] - -d = filter _, v in {a = "foo", b = "bar"} { - v == "foo" -} # {"a": "foo"} -``` - -Please pay attention to distinguish the difference between any expression and any type. When `any` is used in type annotations, it means that the value of the variable is arbitrary, while the any expression means that one of the elements in a set satisfies the condition. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/index.md deleted file mode 100644 index c3ecc162..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/index.md +++ /dev/null @@ -1 +0,0 @@ -# KCL 语言规范 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/kcl-spec.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/kcl-spec.md deleted file mode 100644 index 63a9d6e7..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/kcl-spec.md +++ /dev/null @@ -1,343 +0,0 @@ ---- -title: "KCL Spec" -linkTitle: "KCL Spec" -type: "docs" -weight: 2 -description: KCL Spec ---- - -## Lexical rules - -### Keywords and reserved words - -The following are the keywords of the KCL: - -```python -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -The following are reserved words for the KCL: - -```python -pass return validate rule flow -def del raise except try -finally while from with yield -global nonlocal struct class final -``` - -### Line comment - -```python -# a comment -``` - -### Operators - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != = -+= -= *= **= /= //= %= -<<= >>= &= ^= -``` - -### Delimiters - -```python -( ) [ ] { } -, : . ; @ -``` - -### Operator precedence - -The following list of operators is ordered from **highest to lowest**: - -| Operator | Description | -| -------------------------------------------------------------------------------- | -------------------------------------------------------- | -| `**` | Exponentiation (highest priority) | -| `+x` `-x` `~x` | Positive, negative, bitwise NOT | -| `*` `/` `%` `//` | Multiplication, division, floor division and remainder | -| `+` `-` | Addition and subtraction | -| `<<` `>>` | Left and right shifts | -| `&` | Bitwise AND | -| `^` | Bitwise XOR | -| \| | Bitwise OR | -| `in`, `not in`, `is`, `is not`, `<`, `<=`, `>`, `>=`, `!=`, `==` | Comparisons, including membership and identity operators | -| `not` | Boolean NOT | -| `and` | Boolean AND | -| `or` | Boolean OR | -| `if – else` | Conditional expression = | -| `=`, `+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `=`, `^=`, `\*\*=`, `//=`, `<<=`, `>>=` | Assign | - -## Grammar - -KCL uses Python's [LarkParser](https://lark-parser.readthedocs.io/en/latest/) tool to describe the grammar, and the specification rules are as follows: - -```bnf -//////////// KCL grammar //////////// -start: (NEWLINE | statement)* - -statement: simple_stmt | compound_stmt -simple_stmt: (assign_stmt | unification_stmt | expr_stmt | assert_stmt | import_stmt | type_alias_stmt) NEWLINE -compound_stmt: if_stmt | schema_stmt | rule_stmt - -//////////// import_stmt //////////// -import_stmt: IMPORT dot_name (AS NAME)? -dot_name: (leading_dots identifier) | identifier -leading_dots: DOT+ - -/////////// assert_stmt //////////// -assert_stmt: ASSERT simple_expr (IF simple_expr)? (COMMA test)? - -//////////// if_stmt //////////// -if_stmt: IF test COLON execution_block (ELIF test COLON execution_block)* (ELSE COLON execution_block)? -execution_block: if_simple_stmt | NEWLINE _INDENT schema_init_stmt+ _DEDENT -if_simple_stmt: (simple_assign_stmt | unification_stmt | expr_stmt | assert_stmt) NEWLINE - -//////////// assign_stmt //////////// -assign_stmt: identifier [COLON type] (ASSIGN identifier)* ASSIGN test - | identifier (COMP_PLUS | COMP_MINUS | COMP_MULTIPLY | COMP_DOUBLE_STAR | COMP_DIVIDE - | COMP_DOUBLE_DIVIDE | COMP_MOD | COMP_AND | COMP_OR | COMP_XOR | COMP_SHIFT_LEFT - | COMP_SHIFT_RIGHT) test - -simple_assign_stmt: identifier ASSIGN test - | identifier (COMP_PLUS | COMP_MINUS | COMP_MULTIPLY | COMP_DOUBLE_STAR | COMP_DIVIDE - | COMP_DOUBLE_DIVIDE | COMP_MOD | COMP_AND | COMP_OR | COMP_XOR | COMP_SHIFT_LEFT - | COMP_SHIFT_RIGHT) test - -//////////// unification_stmt //////////// -unification_stmt: identifier COLON schema_expr - -//////////// schema_stmt //////////// -schema_stmt: [decorators] (SCHEMA|MIXIN|PROTOCOL) NAME [LEFT_BRACKETS [schema_arguments] RIGHT_BRACKETS] [LEFT_PARENTHESES identifier (COMMA identifier)* RIGHT_PARENTHESES] [for_host] COLON NEWLINE [schema_body] -schema_arguments: schema_argument (COMMA schema_argument)* -schema_argument: NAME [COLON type] [ASSIGN test] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt|schema_init_stmt|schema_index_signature)* [check_block] _DEDENT -schema_attribute_stmt: attribute_stmt NEWLINE -attribute_stmt: [decorators] identifier [QUESTION] COLON type [(ASSIGN|COMP_OR) test] -schema_init_stmt: if_simple_stmt | if_stmt -schema_index_signature: LEFT_BRACKETS [NAME COLON] [ELLIPSIS] basic_type RIGHT_BRACKETS COLON type [ASSIGN test] NEWLINE - -//////////// rule_stmt //////////// -rule_stmt: [decorators] RULE NAME [LEFT_BRACKETS [schema_arguments] RIGHT_BRACKETS] [LEFT_PARENTHESES identifier (COMMA identifier)* RIGHT_PARENTHESES] [for_host] COLON NEWLINE [rule_body] -rule_body: _INDENT (string NEWLINE)* check_expr+ _DEDENT - -for_host: FOR identifier - -/////////// decorators //////////// -decorators: (AT decorator_expr NEWLINE)+ -decorator_expr: identifier [call_suffix] - -//////////// type //////////// -type: type_element (OR type_element)* -type_element: schema_type | basic_type | compound_type | literal_type -schema_type: identifier -basic_type: STRING_TYPE | INT_TYPE | FLOAT_TYPE | BOOL_TYPE | ANY_TYPE -compound_type: list_type | dict_type -list_type: LEFT_BRACKETS (type)? RIGHT_BRACKETS -dict_type: LEFT_BRACE (type)? COLON (type)? RIGHT_BRACE -literal_type: string | number | TRUE | FALSE | NONE - -//////////// type alias //////////// -type_alias_stmt: TYPE NAME ASSIGN type - -//////////// check_stmt //////////// -check_block: CHECK COLON NEWLINE _INDENT check_expr+ _DEDENT -check_expr: simple_expr [IF simple_expr] [COMMA primary_expr] NEWLINE - -//////////// mixin_stmt //////////// -mixin_stmt: MIXIN LEFT_BRACKETS [mixins | multiline_mixins] RIGHT_BRACKETS NEWLINE -multiline_mixins: NEWLINE _INDENT mixins NEWLINE _DEDENT -mixins: identifier (COMMA (NEWLINE mixins | identifier))* - - -//////////// expression_stmt //////////// -expr_stmt: testlist_expr -testlist_expr: test (COMMA test)* -test: if_expr | simple_expr -if_expr: simple_expr IF simple_expr ELSE test - -simple_expr: unary_expr | binary_expr | primary_expr - -unary_expr: un_op simple_expr -binary_expr: simple_expr bin_op simple_expr - -bin_op: L_OR | L_AND - | OR | XOR | AND - | SHIFT_LEFT | SHIFT_RIGHT - | PLUS | MINUS | MULTIPLY | DIVIDE | MOD | DOUBLE_DIVIDE - | DOUBLE_STAR - | EQUAL_TO | NOT_EQUAL_TO - | LESS_THAN | GREATER_THAN | LESS_THAN_OR_EQUAL_TO | GREATER_THAN_OR_EQUAL_TO - | IN | L_NOT IN | IS | IS L_NOT | L_NOT | AS -un_op: L_NOT | PLUS | MINUS | NOT - -primary_expr: identifier call_suffix | operand | primary_expr select_suffix | primary_expr call_suffix | primary_expr slice_suffix -operand: identifier | number | string | constant | quant_expr | list_expr | list_comp | config_expr | dict_comp | schema_expr | lambda_expr | LEFT_PARENTHESES test RIGHT_PARENTHESES -select_suffix: [QUESTION] DOT NAME -call_suffix: LEFT_PARENTHESES [arguments [COMMA]] RIGHT_PARENTHESES -slice_suffix: [QUESTION] LEFT_BRACKETS (test | [test] COLON [test] [COLON [test]]) RIGHT_BRACKETS -arguments: argument (COMMA argument)* -argument: test | NAME ASSIGN test | MULTIPLY test | DOUBLE_STAR test - - -//////////// operand //////////// -identifier: NAME (DOT NAME)* -quant_expr: quant_op [ identifier COMMA ] identifier IN quant_target LEFT_BRACE (simple_expr [IF simple_expr] | NEWLINE _INDENT simple_expr [IF simple_expr] NEWLINE _DEDENT)? RIGHT_BRACE -quant_target: string | identifier | list_expr | list_comp | config_expr | dict_comp -quant_op: ALL | ANY | FILTER | MAP -list_expr: LEFT_BRACKETS [list_items | NEWLINE [_INDENT list_items _DEDENT]] RIGHT_BRACKETS -list_items: list_item ((COMMA [NEWLINE] | [NEWLINE]) list_item)* [COMMA] [NEWLINE] -list_item: test | star_expr | if_item -list_comp: LEFT_BRACKETS (list_item comp_clause+ | NEWLINE _INDENT list_item comp_clause+ _DEDENT) RIGHT_BRACKETS -dict_comp: LEFT_BRACE (entry comp_clause+ | NEWLINE _INDENT entry comp_clause+ _DEDENT) RIGHT_BRACE -entry: test (COLON | ASSIGN | COMP_PLUS) test -comp_clause: FOR loop_variables [COMMA] IN simple_expr [NEWLINE] [IF test [NEWLINE]] -if_entry: IF test COLON if_entry_exec_block (ELIF test COLON if_entry_exec_block)* (ELSE COLON if_entry_exec_block)? -if_entry_exec_block: (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry) [NEWLINE] | NEWLINE _INDENT (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry) ((COMMA [NEWLINE] | [NEWLINE]) (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry))* [COMMA] [NEWLINE] _DEDENT -if_item: IF test COLON if_item_exec_block (ELIF test COLON if_item_exec_block)* (ELSE COLON if_item_exec_block)? -if_item_exec_block: list_item [NEWLINE] | NEWLINE _INDENT list_item ((COMMA [NEWLINE] | NEWLINE) list_item)* [COMMA] [NEWLINE] _DEDENT - -star_expr: MULTIPLY test -double_star_expr: DOUBLE_STAR test -loop_variables: primary_expr (COMMA primary_expr)* -schema_expr: identifier (LEFT_PARENTHESES [arguments] RIGHT_PARENTHESES)? config_expr -config_expr: LEFT_BRACE [config_entries | NEWLINE [_INDENT config_entries _DEDENT]] RIGHT_BRACE -config_entries: config_entry ((COMMA [NEWLINE] | [NEWLINE]) config_entry)* [COMMA] [NEWLINE] -config_entry: test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry - -//////////// lambda_expr //////////// -lambda_expr: LAMBDA [schema_arguments] [RIGHT_ARROW type] LEFT_BRACE [expr_stmt | NEWLINE _INDENT schema_init_stmt+ _DEDENT] RIGHT_BRACE - -//////////// misc //////////// -number: DEC_NUMBER [multiplier] | HEX_NUMBER | BIN_NUMBER | OCT_NUMBER | FLOAT_NUMBER -multiplier: SI_N_L | SI_U_L | SI_M_L | SI_K_L | SI_K | SI_M | SI_G | SI_T | SI_P - | SI_K_IEC | SI_M_IEC | SI_G_IEC | SI_T_IEC | SI_P_IEC -string: STRING | LONG_STRING -constant : TRUE | FALSE | NONE | UNDEFINED -// Tokens - -ASSIGN: "=" -COLON: ":" -SEMI_COLON: ";" -COMMA: "," -QUESTION: "?" -ELLIPSIS: "..." -RIGHT_ARROW: "->" -LEFT_PARENTHESES: "(" -RIGHT_PARENTHESES: ")" -LEFT_BRACKETS: "[" -RIGHT_BRACKETS: "]" -LEFT_BRACE: "{" -RIGHT_BRACE: "}" -PLUS: "+" -MINUS: "-" -MULTIPLY: "*" -DIVIDE: "/" -MOD: "%" -DOT: "." -AND: "&" -OR: "|" -XOR: "^" -NOT: "~" -LESS_THAN: "<" -GREATER_THAN: ">" -EQUAL_TO: "==" -NOT_EQUAL_TO: "!=" -GREATER_THAN_OR_EQUAL_TO: ">=" -LESS_THAN_OR_EQUAL_TO: "<=" -DOUBLE_STAR: "**" -DOUBLE_DIVIDE: "//" -SHIFT_LEFT: "<<" -SHIFT_RIGHT: ">>" -AT: "@" - -COMP_PLUS: "+=" -COMP_MINUS: "-=" -COMP_MULTIPLY: "*=" -COMP_DIVIDE: "/=" -COMP_MOD: "%=" -COMP_AND: "&=" -COMP_OR: "|=" -COMP_XOR: "^=" -COMP_DOUBLE_STAR: "**=" -COMP_DOUBLE_DIVIDE: "//=" -COMP_SHIFT_LEFT: "<<=" -COMP_SHIFT_RIGHT: ">>=" - -// Special tokens -IMPORT: "import" -AS: "as" -RULE: "rule" -SCHEMA: "schema" -MIXIN: "mixin" -PROTOCOL: "protocol" -CHECK: "check" -FOR: "for" -ASSERT: "assert" -IF: "if" -ELIF: "elif" -ELSE: "else" -L_OR: "or" -L_AND: "and" -L_NOT: "not" -IN: "in" -IS: "is" -LAMBDA: "lambda" -ALL: "all" -ANY: "any" -FILTER: "filter" -MAP: "map" -TYPE: "type" - -ANY_TYPE: "any" -STRING_TYPE: "str" -INT_TYPE: "int" -FLOAT_TYPE: "float" -BOOL_TYPE: "bool" - -// Constant tokens -TRUE: "True" -FALSE: "False" -NONE: "None" -UNDEFINED: "Undefined" - -// Binary prefix -SI_N_L: "n" -SI_U_L: "u" -SI_M_L: "m" -SI_K_L: "k" -SI_K: "K" -SI_M: "M" -SI_G: "G" -SI_T: "T" -SI_P: "P" -SI_K_IEC: "Ki" -SI_M_IEC: "Mi" -SI_G_IEC: "Gi" -SI_T_IEC: "Ti" -SI_P_IEC: "Pi" -IEC: "i" - -NAME: /\$?[a-zA-Z_]\w*/ -COMMENT: /#[^\n]*/ -NEWLINE: ( /\r?\n[\t ]*/ | COMMENT )+ - -STRING: /r?("(?!"").*?(? **note** -> -> Any character except the ASCII space, tab (`\t`) and formfeed (`\f`) is considered a none-space character. - -- A line ending in a backslash cannot carry a comment (, which will be introduced shortly afterwards). -- A backslash does not continue a comment. -- A backslash does not continue a token except for string literals (i.e., tokens other than string literals cannot be split across physical lines using a backslash). -- A backslash is illegal elsewhere on a line outside a string literal. - -### Implicit Line Joining - -Expressions in parentheses, square brackets or curly braces can be split over more than one physical line without using backslashes. - -- Implicitly continued lines can carry comments. -- The indentation of the continuation lines is not important. -- Blank continuation lines are allowed. -- There is no `NEWLINE` token between implicit continuation lines. -- Implicitly continued lines can also occur within triple-quoted strings (see below); in that case they cannot carry comments. - -### Blank Lines - -### Indentation - -### Comments - -Starting with a `#` character that is not part of a string literal is a comment. A comment ends at the end of the physical line. - -A comment signifies the end of the logical line unless the implicit line joining rules are invoked. - -Comments are ignored by the syntax. - -### Identifiers and Keywords - -Identifiers (also referred to as names) are described by the following lexical definitions. - -Within the ASCII range (from `U+0001` to `U+007F`), the valid characters for identifiers are the uppercase and lowercase letters `A` through `Z`, the underscore `_` and, except for the first character, the digits `0` through `9`. - -Identifiers are unlimited in length. The case is significant. - -### Keywords - -The following identifiers are used as reserved words, or keywords of the language, and cannot be used as ordinary identifiers. They must be spelled exactly as written here: - -```python -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -The following tokens are not used, but they are reserved as possible future keywords: - -```python -pass return validate rule flow -def del raise except try -finally while from with yield -global nonlocal struct class final -``` - -### Literals - -Literals are notations for constant values of some built-in types. - -### String Literals - -String literals are described by the following lexical definitions: - -``` -stringliteral ::= [stringprefix](shortstring | longstring) -stringprefix ::= "r" | "R" -shortstring ::= "'" shortstringitem* "'" | '"' shortstringitem* '"' -longstring ::= "'''" longstringitem* "'''" | '"""' longstringitem* '"""' -shortstringitem ::= shortstringchar | stringescapeseq -longstringitem ::= longstringchar | stringescapeseq -shortstringchar ::= -longstringchar ::= -stringescapeseq ::= "\" -``` - -Multiple adjacent string or bytes literals (delimited by whitespace),possibly using different quoting conventions, are allowed, and their meaning is the same as their concatenation. - -### Numeric Literals - -There are two types of numeric literals: integers and floating-point numbers. - -Integer literals are described by the following lexical definitions: - -``` -integer ::= decinteger | bininteger | octinteger | hexinteger -decinteger ::= nonzerodigit (["_"] digit)* | "0"+ (["_"] "0")* -bininteger ::= "0" ("b" | "B") (["_"] bindigit)+ -octinteger ::= "0" ("o" | "O") (["_"] octdigit)+ -hexinteger ::= "0" ("x" | "X") (["_"] hexdigit)+ -nonzerodigit ::= "1"..."9" -digit ::= "0"..."9" -bindigit ::= "0" | "1" -octdigit ::= "0"..."7" -hexdigit ::= digit | "a"..."f" | "A"..."F" -``` - -Floating-point literals are described by the following lexical definitions: - -``` -floatnumber ::= pointfloat | exponentfloat -pointfloat ::= [digitpart] fraction | digitpart "." -exponentfloat ::= (digitpart | pointfloat) exponent -digitpart ::= digit (["_"] digit)* -fraction ::= "." digitpart -exponent ::= ("e" | "E") ["+" | "-"] digitpart -``` - -## Operators and Delimiters - -### Operators - -The following tokens are operators: - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != @ -``` - -### Delimiters - -The following tokens serve as delimiters in the grammar: - -```python -( ) [ ] { } -, : . ; = += --= *= **= /= //= %= -<<= >>= &= |= ^= -``` - -The period can also occur in floating-point literals. - -The following printing ASCII characters have special meaning as part of other tokens or are otherwise significant to the lexical analyzer: - -``` -' " # \ -``` - -The following printing ASCII characters are not used in KCL. Their occurrence outside string literals and comments is an unconditional error: - -``` -? ` -``` - -## Reference - -Since the lexical conventions of KCL is very similar to that of Python, we use the following document as the reference when writing this chapter. - -- [https://docs.python.org/3/reference/lexical_analysis.html](https://docs.python.org/3/reference/lexical_analysis.html) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/modules.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/modules.md deleted file mode 100644 index f8608619..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/modules.md +++ /dev/null @@ -1,621 +0,0 @@ ---- -title: "Modules" -linkTitle: "Modules" -type: "docs" -weight: 2 -description: Modules ---- - -## Modules and the Import System - -KCL code is organized in **modules**. For code in one module to access the code defined in another module, a process called **importing** must be used. - -Importing is undertaken at compile-time in KCL. The advantage is to have static checking enabled. - -A regular KCL module is a file on the file system. It is required to have a `.k` suffix. - -## Packages - -To help manage modules and provide a naming hierarchy, KCL has the concept of packages. In KCL, a package maps to exactly a file system directory, and a regular module maps to a file. - -Files directly under a package are considered parts of the package, instead of individual regular modules. - -Packages can have sub-packages. - -Packages are special modules: - -- All packages in KCL are modules. -- A single-file module can never be a package. - -All modules have a name. - -Sub package names are separated from their parent package name by dots. - -To summary, a regular KCL module is a `.k` file, and a package is a directory on the file system. All `.k` files directly under the directory are included in the package, other files are ignored. If the directory has subdirectories, they become sub-packages as long as there are `.k` files underneath. - -### Intra-Package Name Space Sharing - -Inside a package, all `.k` files are considered parts of the package, instead of regular modules. Code in these files share a single name space and can access names defined in other files, without explicitly granted. - -### Package Initialization - -A package can have the initialization code. The code must exist in only one of the `.k` files under this package. The interpreter guarantees that the initialization code is executed after all definitions. - -## Searching - -The searching begins when an `import` statement is used to import a module. - -### Module Cache - -In KCL, only standard system modules are cached. When a cached module is imported, the cached version is used. In other words, KCL runtime would not create another copy of the standard system module in memory. - -However, other modules are uncached. Importing a module multiple time would create multiple instances of the module. - -### Module Names - -An `import` statement specifies the name of the module to import. The syntax is: - -``` -import [as ] -``` - -The rule to search with the module name is very simple: - -- **Step 1**: Searches the module name from the **standard system modules**, then **plugins modules**. - - See **standard system modules** and **plugins modules** for more details. If matched, the module is imported. Otherwise, continue to **Step 2**. -- **Step 2**. Whether a module name starts with a `.` is checked. If yes, the name is a so-called relative pathname, and we go to **Step 5**. Otherwise, continue to **Step 3**. -- **Step 3**: If the module name does not start with any `.`, then the compiler searches the nearest `root path` directory from this directory to the parent, and find the module according to the name just from the `root path`. If no `root path` is found, find the module according to the name from the folder the `.k` file including this `import` statement exists. - - **root path**: the directory contains a `kcl.mod` file. If matched, the module is imported. Otherwise, continue to **Step 4**. -- **Step 4**: Then the compiler checks if the name is the name of any library module that requires explicit loading. If matched, the library module is imported. Otherwise, continue to **Step 6**. -- **Step 5**. For relative importing, find the module according to the name from the folder the `.k` file including this `import` statement exists. Interpret leading dots using the following rule: -- One dot: Ignore. -- Tow or more dots: Suppose there are `n` leading dots, then the searching starts at `n - 1` levels above this folder. If matched, the module is imported. Otherwise, continue to **Step 6**. -- **Step 6**. Module not found, report an error. - -Do case-sensitive search when the operating system allows. If case-sensitive search is not allowed, search directories before regular files. - -In KCL, the `from <> import <>` is unsupported, and relative import is performed with the `import <>` syntax. - -### Uniqueness of Module - -Each module has a unique location path in its scope, so that a module or package could be located with a unique location path, such as `a.b.c`. - -Searching by location path should be supported by the kcl compiler, which needs to provide corresponding searching features through the command line and api form. - -## Standard System Packages - -KCL supports a few standard system modules. The following is the full list of these standard system modules: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PackageMember
datetimetoday
now
ticks
date
mathceil
exp
expm1
factorial
floor
gcd
isfinite
isinf
isnan
log
log1p
log2
log10
modf
pow
sqrt
regexreplace
match
compile
findall
search
split
unitsn
u
m
k
K
M
G
T
P
Ki
Mi
Gi
Ti
Pi
to_n
to_u
to_m
to_K
to_M
to_G
to_T
to_P
to_Ki
to_Mi
to_Gi
to_Ti
to_Pi
jsonencode
decode
dump_to_file
yamlencode
decode
dump_to_file
netsplit_host_port
join_host_port
fqdn
parse_IP
to_IP4
to_IP16
IP_string
is_IPv4
is_IP
is_loopback_IP
is_multicast_IP
is_interface_local_multicast_IP
is_link_local_multicast_IP
is_link_local_unicast_IP
is_global_unicast_IP
is_unspecified_IP
base64encode
decode
cryptomd5
sha1
sha224
sha256
sha384
sha512
- -- datetime - - ticks() -> float - Return the current time in seconds since the Epoch. Fractions of a second may be present if the system clock provides them. - - date() -> str - return the `%Y-%m-%d %H:%M:%S` format date. - - now() -> str - return the local time. e.g. `'Sat Jun 06 16:26:11 1998'` - - today() -> str - return the `%Y-%m-%d %H:%M:%S.%{ticks}` format date. -- math - - ceil(x) -> int - Return the ceiling of x as an Integral. This is the smallest integer >= x. - - factorial(x) -> int - Return x!. Raise a error if x is negative or non-integral. - - floor(x) -> int - Return the floor of x as an Integral. This is the largest integer <= x. - - gcd(a: int, b: int) -> int - Return the greatest common divisor of x and y - - isfinite(x) -> bool - Return True if x is neither an infinity nor a NaN, and False otherwise. - - isinf(x) -> bool - Return True if x is a positive or negative infinity, and False otherwise. - - isnan(x) -> bool - Return True if x is a NaN (not a number), and False otherwise. - - modf(x) -> Listfloat, float] - Return the fractional and integer parts of x. Both results carry the sign of x and are floats. - - exp(x) -> float - Return e raised to the power of x. - - expm1(x) -> float - Return exp(x)-1. This function avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small x. - - log(x, base=2.71828182845904523536028747135266250) -> float - Return the logarithm of x to the base e. - - log1p(x) -> float - Return the natural logarithm of 1+x (base e). The result is computed in a way which is accurate for x near zero. - - log2(x) -> float - Return the base 2 logarithm of x. - - log10(x) -> float - Return the base 10 logarithm of x. - - pow(x, y) -> float - Return x\*\*y (x to the power of y). - - sqrt(x) -> float - Return the square root of x. -- regex - - replace(string: str, pattern: str, replace: str, count=0) -> str - Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement. - - match(string: str, pattern: str) -> bool - Try to apply the pattern at the start of the string, returning a bool value True if any match was found, or False if no match was found. - - compile(pattern: str) -> bool - Compile a regular expression pattern, returning a bool value denoting whether the pattern is valid. - - findall(string: str, pattern: str) -> List[str] - Return a list of all non-overlapping matches in the string. - - search(string: str, pattern: str) -> bool - Scan through string looking for a match to the pattern, returning a bool value True if any match was found, or False if no match was found. - - split(string: str, pattern: str, maxsplit=0) -> List[str] - Scan through string looking for a match to the pattern, returning a Match object, or None if no match was found. -- units - - Unit constants - - Fixed point: `n`, `u`, `m`, `k`, `K`, `G`, `T` and `P`. - - Power of 2: `Ki`, `Mi`, `Gi`, `Ti` and `Pi`. - - Functions - - to_n(num: int) -> str - Int literal to string with `n` suffix - - to_u(num: int) -> str - Int literal to string with `u` suffix - - to_m(num: int) -> str - Int literal to string with `m` suffix - - to_K(num: int) -> str - Int literal to string with `K` suffix - - to_M(num: int) -> str - Int literal to string with `M` suffix - - to_G(num: int) -> str - Int literal to string with `G` suffix - - to_T(num: int) -> str - Int literal to string with `T` suffix - - to_P(num: int) -> str - Int literal to string with `P` suffix - - to_Ki(num: int) -> str - Int literal to string with `Ki` suffix - - to_Mi(num: int) -> str - Int literal to string with `Mi` suffix - - to_Gi(num: int) -> str - Int literal to string with `Gi` suffix - - to_Ti(num: int) -> str - Int literal to string with `Ti` suffix - - to_Pi(num: int) -> str - Int literal to string with `Pi` suffix -- json - - encode(data: any, sort_keys: bool = False, indent: int = None, ignore_private: bool = False, ignore_none: bool = False) -> str - Serialize a KCL object `data` to a JSON formatted str. - - decode(value: str) -> any - Deserialize `value` (a string instance containing a JSON document) to a KCL object. - - dump_to_file(data: any, filename: str, ignore_private: bool = False, ignore_none: bool = False) -> None - Serialize a KCL object `data` to a JSON formatted str and write it into the file `filename`. -- yaml - - encode(data: any, sort_keys: bool = False, ignore_private: bool = False, ignore_none: bool = False) -> str - Serialize a KCL object `data` to a YAML formatted str. - - decode(value: str) -> any - Deserialize `value` (a string instance containing a YAML document) to a KCL object. - - dump_to_file(data: any, filename: str, ignore_private: bool = False, ignore_none: bool = False) -> None - Serialize a KCL object `data` to a YAML formatted str and write it into the file `filename`. -- net - - split_host_port(ip_end_point: str) -> List[str] - Split the 'host' and 'port' from the ip end point. - - join_host_port(host, port) -> str - Merge the 'host' and 'port'. - - fqdn(name: str = '') -> str - Return Fully Qualified Domain Name (FQDN). - - parse_IP(ip) -> str - Parse 'ip' to a real IP address - - to_IP4(ip) -> str - Get the IP4 form of 'ip'. - - to_IP16(ip) -> int - Get the IP16 form of 'ip'. - - IP_string(ip: str | int) -> str - Get the IP string. - - is_IPv4(ip: str) -> bool - Whether 'ip' is a IPv4 one. - - is_IP(ip: str) -> bool - Whether ip is a valid ip address. - - is_loopback_IP(ip: str) -> bool - Whether 'ip' is a loopback one. - - is_multicast_IP(ip: str) -> bool - Whether 'ip' is a multicast one. - - is_interface_local_multicast_IP(ip: str) -> bool - Whether 'ip' is a interface, local and multicast one. - - is_link_local_multicast_IP(ip: str) -> bool - Whether 'ip' is a link local and multicast one. - - is_link_local_unicast_IP(ip: str) -> bool - Whether 'ip' is a link local and unicast one. - - is_global_unicast_IP(ip: str) -> bool - Whether 'ip' is a global and unicast one. - - is_unspecified_IP(ip: str) -> bool - Whether 'ip' is a unspecified one. -- base64 - - encode(value: str, encoding: str = "utf-8") -> str - Encode the string `value` using the codec registered for encoding. - - decode(value: str, encoding: str = "utf-8") -> str - Decode the string `value` using the codec registered for encoding. -- crypto - - md5(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `MD5` and the codec registered for encoding. - - sha1(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA1` and the codec registered for encoding. - - sha224(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA224` and the codec registered for encoding. - - sha256(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA256` and the codec registered for encoding. - - sha384(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA384` and the codec registered for encoding. - - sha512(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA512` and the codec registered for encoding. -- manifests - - `yaml_stream(values: [any], opts: {str:} = {sort_keys = False, ignore_private = True, ignore_none = False, sep = "---"}`. This function is used to serialize the KCL object list into YAML output with the `---` separator - -### The Built-in System Package - -KCL provides a list of built-in system modules, which are loaded automatically and can be directly used without providing any module name. For example, `print` is a widely used built-in module. - -The following is the full list of these built-in system modules: - -- print() - - The print function. -- multiplyof(a, b) - - Check if the modular result of a and b is 0 -- isunique(inval) - - Check if a list has duplicated elements -- len(inval) - Return the length of a value -- abs(x) - Return the absolute value of the argument. -- all(iterable) - Return True if bool(x) is True for all values x in the iterable. If the iterable is empty, return True. -- any(iterable) - Return True if bool(x) is True for any x in the iterable. If the iterable is empty, return False. -- bin(number) - Return the binary representation of an integer. -- hex(number) - Return the hexadecimal representation of an integer. -- oct(number) - Return the octal representation of an integer. -- ord(c) -> int - Return the Unicode code point for a one-character string. -- sorted(iterable) - Return a new list containing all items from the iterable in ascending order. A custom key function can be supplied to customize the sort order, and the reverse flag can be set to request the result in descending order. -- range(start, end, step=1) - Return the range of a value with start, end and step parameter. -- min(iterable) - With a single iterable argument, return its smallest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the smallest argument. -- max(iterable) - With a single iterable argument, return its biggest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the largest argument. -- sum(iterable, start) - Return the sum of a 'start' value (default: 0) plus an iterable of numbers. When the iterable is empty, return the start value. This function is intended specifically for use with numeric values and may reject non-numeric types. -- pow(x, y, z) - Equivalent to `x**y` (with two arguments) or `x**y % z` (with three arguments). Some types, such as ints, are able to use a more efficient algorithm when invoked using the three argument form. -- round(number, ndigits) - Round a number to a given precision in decimal digits. The return value is an integer if ndigits is omitted or None. Otherwise the return value has the same type as the number. ndigits may be negative. -- typeof(x: any, \*, full_name: bool = False) -> str - Return the type of the value 'x' at runtime. When the 'full_name' is 'True', return the full package type name such as `pkg.schema`. - -### Plugin Modules - -KCL compiler needs to provide the ability to dynamically expand and load plugin modules without modifying the compiler itself. KCL compiler needs to support flexible pluggable module extension mechanism, so that KCL users can use more abundant built-in function capabilities to simplify writing. - -KCL compiler needs to ensure the stability and safety of the expansion mechanism, without affecting the core of the compiler. - -Searching extended plugin module is performed after the standard system module. The standard system module has a higher priority in naming. If it exists a standard or built-in system module with the same name, the extended plugin module will be ignored. - -Importing and using the extended plugin module should be consistent with the standard or built-in system module. - -### Replacing Standard System Packages - -Replacing standard system modules is not allowed. - -## Examples - -We show more module features through an example. - -Suppose we have the following directories and files: - -``` - . - ├── mod1.k - ├── mod2.k - ├── pkg1 - │   ├── def1.k - │   ├── def2.k - │   └── def3init.k - └── pkg2 - ├── file2.k - └── subpkg3 - └── file3.k -``` - -From the structure we can see that `pkg1` and `pkg2` are two packages, `subpkg3` is a subpackage of `pkg2`, and `mod1.k` and `mod2.k` are regular modules. - -### Importing a Standard System Package - -The following statement can import the standard system module `math` - -```python -import math -``` - -This is the only way to import a standard system module. After importing a standard system module, functions, variables and schemas defined in it can be used. For example, the following statement uses the `log10` function -defined in `math` - -```python -a = math.log10(100) # a is 2 after computation. -``` - -### Importing a Regular Module - -In `mod1.k`, we can import `mod2` using one of the following syntaxes. - -```python -import mod2 -``` - -```python -import .mod2 -``` - -The difference is that in the first syntax, the KCL compiler will first try to check if `mod2` matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where `mod1.k` resists in, like what the second statement does. - -Suppose in `mod2.k` there is a definition of a variable:: - -```python -a = 100 -``` - -After importing `mod2`, we can access `a` in `mod1.k` using the following syntax - -```python -b = mod2.a -``` - -### Importing a Package - -In `mod1.k`, we can import `pkg1` using one of the following syntaxes. - -```python -import pkg1 -``` - -```python -import .pkg1 -``` - -The difference is that in the first syntax, the KCL compiler will first try to check if `pkg1` matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where `mod1.k` resists in, like what the second statement does. - -We can use similar statements to import `pkg2`. Note that importing `pkg2` will not import `subpkg3`. - -The name of the package is the name of the imported module. - -Suppose in `file2.k` that is inside `pkg2` there is a definition to variable `foo` - -```python -foo = 100 -``` - -This variable can be used in `mod1.k` after importing `pkg2` like the following - -```python -bar = pkg2.foo -``` - -### Importing a Subpackage - -To import `subpkg3` from `mod1.k`, one of the following statements can be used. - -```python -import pkg2.subpkg3 -``` - -```python -import .pkg2.subpkg3 -``` - -The behaviors of these statements are identical. - -The name of the subpackage is the name of the imported module. - -Suppose in `file3.k` that is inside `subpkg3` there is a definition to variable `foo` - -```python -foo = 100 -``` - -This variable can be used in `mod1.k` after importing `subpkg3` like the following - -```python -bar = subpkg3.foo -``` - -### Relative Importing - -Relative importing is useful when there is code trying to import modules that does not exist recursively inside the current directory. - -For example, the following statements, if written in `file3.k`, can be used to import `pkg2`, `pkg1` and `mod2` respectively. - -```python -import ...pkg2 # Go two levels up then import pkg2 -import ...pkg1 # Go two levels up then import pkg1 -import ...mod2 # Go two levels up then import mod2 -``` - -### Importing from a Root Path - -Suppose we have a `kcl.mod` file in the directory to mark it as a root path, then we have the following files: - -``` - . - |── kcl.mod - ├── mod1.k - ├── mod2.k - ├── pkg1 - │   ├── def1.k - │   ├── def2.k - │   └── def3init.k - └── pkg2 - ├── file2.k - └── subpkg3 - └── file3.k -``` - -In `pkg1` `def1.k`, we can import `pkg2.subpkg3` `file3` using the following syntaxes. - -```python -import pkg2.subpkg3.file3 -``` - -Importing from the root path is very convenient when the code is trying to import modules from a directory needs to look up multiple directories above this directory. At also, it is helpful to organize a large number of files in a root directory. - -### Importing a Module Inside a Package - -Note that `subpkg3` is only implemented with one file `file3.k`. The file can be regarded as a regular module and imported directly. - -In `mod1.k`, the importing statement would be:: - -```python -import pkg2.subpkg3.file3 -``` - -Different from importing `subpkg3`, now the name of the module is `file3`. We can access the variable `foo` defined in this module with the following -statement - -```python -bar = file3.foo -``` - -### Precedence of Importing - -When an import statement specifies a package to import, the virtual machine first looks for a directory named according to the import statement in the file system. - -If such a directory is not found, the virtual machine looks for a single file module. - -For example, when the statement `import a.b.c` appears, the virtual machine first looks for the directory `a/b/c` from the directory of the current file. If `a/b/c` is not found, the virtual machine looks for a file named `a/b/c.k`. If the file is also absent, an error is reported. - -### Package Implemented with Multiple Files - -Package `pkg1` is implemented with multiple KCL files. - -Multiple files can be used to define variables, schemas and functions, and they can access names defined in other files of this package. - -For example, suppose `def1.k` defines a variable `foo`, `def2.k` defines `bar`, and `def3init.k` defines a variable `baz`, when `pkg1` is imported by `mod1.k`, all these variable can be used - -```python -import pkg1 -a = pkg1.foo + pkg1.bar + pkg1.baz -``` - -Inside a module, names defined in a file can be accessed in another file without further importing. For example, suppose `bar` in `def2.k` would invoke `foo` defined in `def1.k`, it can directly use `foo` like the following - -```python -bar = foo + 1 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/schema.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/schema.md deleted file mode 100644 index c3d09f65..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/schema.md +++ /dev/null @@ -1,916 +0,0 @@ ---- -title: "Schema" -linkTitle: "Schema" -type: "docs" -weight: 2 -description: Schema ---- - -## Syntax - -### Schema Definition - -A schema is a language element to define a type of configuration data. - -To define a schema, the syntax is the following: - -```bnf -schema_stmt: [decorators] "schema" ["relaxed"] identifier ["[" [arguments] "]"] ["(" operand_name ")"] ":" NEWLINE [schema_body] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt | schema_index_signature | statement)* [check_block] _DEDENT -``` - -Attributes could be defined in a schema, the syntax is the following: - -```bnf -schema_attribute_stmt: [decorators] identifier ["?"] ":" type [(ASSIGN | augassign) test] NEWLINE -``` - -Index signature could be defined in a schema, the syntax is the following: - -```bnf -schema_index_signature: LEFT_BRACKETS [NAME COLON] [ELLIPSIS] basic_type RIGHT_BRACKETS COLON type [ASSIGN test] NEWLINE -``` - -Once defined, an attribute must have a valid type: - -```bnf -type: type_element ("|" type_element)* -type_element: schema_type | basic_type | list_type | dict_type -schema_type: operand_name -basic_type: "str" | "int" | "float" | "bool" -list_type: "[" (type)? "]" -dict_type: "{" (type)? COLON (type)? "}" -``` - -The followings are some basic examples: - -```python -# A person has a first name, a last name and an age. -schema person: - firstName: str - lastName: str - # fullName is generated by firstName and lastName - fullName: str = firstName + ' ' + lastName - # The default value of age is 0 - age: int = 0 - -# An employee IS a person, and has some additional information. -schema employee(person): - bankCard: int - nationality: str - -# A company has a name and many employees. -schema company: - name: str - employees: [employee] -``` - -More complex schema definitions will be elaborated after other concepts are -introduced. - -#### Optional Attribute - -Each attribute **must** be assigned with a not-None value as a schema instance unless it is modified by a question mark as an optional attribute. - -Examples: - -```bnf -schema employee(person): - bankCard?: int # bankCard is an optional attribute - nationality?: str # # nationality is an optional attribute -``` - -When there is an inheritance relationship: - -- If the attribute is optional in the base schema, it could be optional or required in the sub-schema. -- If the attribute is required in the base schema, it must be required in the sub-schema. - -### Configuration Definition - -A configuration is structured data stored in a dict-like structure. In KCL, we have introduced -the configuration definition syntax as a variant of dict definition syntax. - -```bnf -schema_expr: operand_name ("(" [arguments] ")")? dict_expr -``` - -As can be seen, apart from having an identifier as schema type, a configuration definition -is just an ordinary dict definition, and each key in the dict matches an attribute in the schema. - -To simplify configuration, schema attribute key is much easier to define as: - -- schema attribute key can be unquoted. When the attribute key has the same name as a variable, it must be quoted as a normal dict to avoid naming conflict. -- schema attribute key can be defined nested through `select expression`, such as `a.b.c`. - -The comma at the end of each line can be omitted. - -For example, we can define a `person` named `John Doe` using the following statement: - -```python -johnDoe = person { - # In the result, 'lastName' appears later than 'firstName', according the schema - lastName = 'Doe' - firstName = 'John' - # If we don't specify the 'age', the default value 0 is used. - # 'age': 20 -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' - 'age': 0 -} -``` - -Compared to the ordinary dict definition, a configuration definition has the following features: - -- Each attribute defined in the schema (or one of the schemas) could be configured, and config data has higher priority than the default value. -- When an attribute defined in the schema (or one of the schemas) is not configured in the configuration definition statement, and it has a default value, the default value is used. -- Unless the schema (or one of the schemas) is a **relaxed schema**, no more attributes can be defined. -- The quotation marks of dict key can be omitted. -- The comma at the end of each line can be omitted. -- Cases of **inheritance** will be discussed separately. - -For attributes of list, dict and schema types, the config data is added by **union** instead of reassignment. For instance: - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name = { - firstNam = "John" - lastName = "default" - } - -JohnDoe = Person { - name.lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' -} -``` - -#### Attribute Identify - -Each key identifier in the configuration expr identifies an element or a range of elements in a schema. The key identifier may consist of multiple attribute identifiers, and each attribute may be a basic type value, a list, a dict or schema. For example, the key identifier 'a.b.c' identifies the element 'c' in the 'A' schema: - -```python - -schema C: - c: int - -schema B: - b: C - -schema A: - a: B - -A { - a.b.c: 5 -} -``` - -To make the key identifier usage rules as clear as possible, we define the way of identifying with complex data types as follows. - -##### List - -Suppose we have a list attribute a. - -Identify an element in a: - -```python -a[0] # the first element -a[3] # the 4th element -a[-1] # the last element -a[-2] # the penultimate element -``` - -Identify a range of elements in the list: - -```python -a[2:5] # a slice of the third, 4th, and 5th elements -a[:5] # a slice of the first to 5th elements -``` - -#### Attribute Operator - -Once we identified the element(s), we can declare operation on it. It follows the pattern of `identifier op E`. - -#### Union - -Pattern: `identifier : E` - -The value of the expression `E` will be unioned into the element value. - -Examples: - -```python -a = A { - # union {d:4} into the element b.c, suppose c is a schema with an int type attribute d. - b.c : { - d : 4 - } -} -``` - -See 'union' in `expressions` spec for more details. - -#### Override - -Pattern: `identifier = E` - -The value of the expression `E` will override the element value. - -Examples: - -```python -a = A { - # override {c:4} to the element b, suppose b is a schema with an int type attribute c. - b = { - c: 4 - } -} -``` - -Unlike union, the override operation will reassign the element with a brand new value. -For basic type value, `union` and `override` have equivalent effects. - -Note: - -- Especially, we can "delete" its content by overriding the element to `Undefined`, such as `{ a = Undefined }`. - -#### Insert - -Pattern: `identifier += E` -Insert only works for list type `identifier`. - -List `E` will be inserted just after the specified index of the list `identifier`, and the following elements after the index will be automatically shifted. - -Examples: - -```python -a = A { - # insert {c:4} to the end position(just after index=1), suppose b is a list of schema with an int type attribute c. - b += { - c: 4 - } -} -``` - -If no index is specified, the last index will be used. - -The type of 'E' must be compatible with the type of list. See `types` for more details. - -#### Index Signature - -Index signatures can be defined in the KCL schema, and it means that the key-value constraints of the index signature can be used to construct a dict with the schema type, or additional checks can be added to the relaxed schema attributes to enhance the KCL type and semantic checks. - -- Use the form `[{attr_alias}: {key_type}]: {value_type}` to define an index signature in the schema, and `{attr_alias}` can be omitted. - -```python -schema Map: - """ - Map is a relaxed schema with a key of str type and a value of str type - """ - [str]: str # `{attr_alias}` can be omitted. - -data = Map { - key1 = "value1" - key2 = "value2" -} -``` - -- Mandatory all attributes of the schema key and value types - -```python -schema Person: - name: str - age: int # error, conflicts with the index signature definition `[str]: str` - [str]: str # The values of all attributes of the schema can only be strings -``` - -- Mandatory all attribute key and value types are defined in the schema, which is equivalent to restricting all attribute types except the relaxed attributes. - -```python -schema Person: - name: str - age: int - [...str]: str # Except for the `name` and `age` attributes, the key type of all other attributes of the schema must be `str`, and the value type must also be `str`. -``` - -- Define the index signature attribute alias and use it with the check block. - -```python -schema Data: - [dataName: str]: str - check: - dataName in ["Alice", "Bob", "John"] - -data = Data { - Alice = "10" - Bob = "12" - Jonn = "8" # error Jonn not in ["Alice", "Bob", "John"] -} -``` - -```python -import regex - -schema DataMap: - [attr: str]: str - check: - regex.match(attr, r'^[-._a-zA-Z0-9]+$') - -data = DataMap { - key1 = "value1" - "foo.bar" = "value2" # check error -} -``` - -### Schema Context - -The schema definition space can be regarded as a separate function context. - -Init statement could be defined inside the schema, the syntax is the following: - -```bnf -statement: small_stmt NEWLINE | if_stmt -``` - -The following is an example: - -```python -schema Person: - firstName: str = "John" - lastName: str - # fullName is generated by firstName and lastName in a separate init statement - fullName: str = firstName + ' ' + lastName - -JohnDoe = Person { - lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' -} -``` - -If statement, expr statement and assert statement are supported as a schema init -statement. See more in statement spec. - -- The attributes must be defined first, including inherited ones, and then used in the init statement. -- Statements in the schema context will be executed sequentially. -- The value of attributes referenced in the init statement will be evaluated at runtime. - See the **Configuration Definition** section for the assignment rules of non-referenced attributes. For example, `"fullName"` in Person is generated by `"firstName"` and `"lastName"` evaluated at runtime, in which firstName is 'John', and lastName is "Doe". - -The immutability of attributes in the schema context follows the same rules as the immutability of global variables: - -```python -schema Person: - age: int = 1 # Immutable attribute - _name: str = "Alice" # Mutable attribute - - age = 10 # Error - _name = "Bob" # Ok -``` - -#### Arguments - -Schema context can also have arguments. The following is an example. - -```python -schema Person[separator]: - firstName: str = "John" - lastName: str - fullName: str = firstName + separator + lastName - -JohnDoe = Person('_') { - lastName = "Doe" -} -``` - -The example is similar to the previous one, except that the separator character used in -the `"fullName"` member is passed in as an argument. The way to perform a schema generation -when the schema has an initialization function with arguments is demonstrated in the code. - -### Check Block - -Optionally, a check block can be added to a schema definition to allow -additional checking to be performed. - -The syntax is the following: - -```bnf -check_block: "check" ":" NEWLINE _INDENT check_expr+ _DEDENT -check_expr: test (IF test)? [":" primary_expr] NEWLINE -``` - -In terms of grammatical definition, a check block consists of a list of conditional expressions. The following is an example: - -```python -schema employee(person): - bankCard: int - gender: str - - check: - len(str(bankCard)) == 16 - gender in ['male', 'female'], "The gender {} is unsupported".format(gender) -``` - -The ability of KCL check expressions covers the abilities that can be defined by OpenAPI spec and is aligned with the ability of logical expressions. We consider further aligning the syntax with `CEL` spec. -Whether to support `lambda expressions` is still under discussion. - -Summary: - -- A check block consists of one or more logical **expressions**. -- When defining a configuration, the expressions in the check block are evaluated - in any order. If any of the expression is `False`, an error is reported. -- A custom error message can be provided after an expression. - -### Specifying Types - -Optionally, the type of any member of a schema can be specified. As previous examples have shown. - -A member can be of a basic type, such as a string (`str`), a floating-point number (`float`), a fixed-point number (`int`) or a boolean number (`bool`). - -A member can also be of a dictionary generated from another schema. In such a case, the name of the other schema is used as the type name. - -A member can also be a list or an ordinary dict: - -- A list with unspecified type of elements is `[]`. -- A list with elements of type `t` is `[t]`. Here `t` is another type. -- A dict with keys of type `kt` and values of type `vt` is `{kt:vt}`. -- `kt`, `vt` or both of them can be missing, like a list with unspecified type of elements. - -The followings are some more examples: - -- A list of lists of strings: `[[str]]`. -- A dict of keys with the type string and unspecified value types: `{str:}`. - -A member can be a **union type** defined by `|`, such as `a | b`, which means the type of the member could be a or b. - -A union type can include types of `int`, `str`, `float`, `bool`, `list` and `dict` and support type nesting e.g. `{str:str|int}` and `[[int|str]|str|float]`, etc. - -Examples: - -```python -schema x: - p: int | str # p could be defined as a int or string -``` - -### Immutability - -KCL pursues strict immutability of schema attributes. It's generally followed the rules: - -- For the attributes of the basic type, such as string, int and float, it's allowed to be reassigned - through the init statement in **schema context** or by the **configuration definition**. -- For the attributes of list, dict and schema type, it's allowed to be reassigned only by the init statement in **schema context**. The content of it is allowed to be operated in **schema context** or by the **configuration definition**. -- Any other attempt to reassign or modify schema attribute will report an error. - -#### Assign by Value - -When using a schema variable to assign the value to another variable, we can only get a deep copy of its value, not a pointer or reference. That is, modifying the assigned value will not change the assigned schema variable. - -```python -schema Person: - name: str - -person = { - name = "Alice" -} -personCopy = person # 'personCopy' is a deep copy of 'person' and modifying 'personCopy' will not affect 'person' -``` - -### Union Operator - -For list, dict and schema, we can union delta to existing data. For example: - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name = { - firstName = "John" - } - - # union a schema and a dict - name: Name { - lastName = "Doe" - } - -person = Person {} -``` - -The result is a **dict**: - -```python -{ - 'person': { - 'name': { - 'firstName': 'Jhon', - 'lastName': 'Doe' - } - } -} -``` - -### Other Operators - -Except for `assignment` and `union assignment`, it's not support other operators on schema type data. -Report an error if trying to use other operators on schema type data. - -### Deprecated - -The schema attribute can be marked as deprecated once it's considered invalid. - -```python -schema Person: - @deprecated(version="1.1.0", reason="use fullName instead", strict=True) - name: str - ... # Omitted contents - -person = Person { - # report an error on configing a deprecated attribute - name = "name" -} -``` - -- Deprecated attributes cannot be configured under any circumstances. Report an error or warning once the attribute is assigned. -- Define the expired version of the attribute through **version**, and define the reason for the attribute expired through **reason**. -- When strict is true, the attribute assignment will cause an error, otherwise it will report a warning and ignore the attribute assignment. - -### Composition - -The composition is a common way to define complex structures. KCL provides simplified means for the configuration definition of combined structures. - -Assuming we have the following schemas, which is defined by a combination of multiple schemas. - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name - age: int - -schema Group: - name: str - persons: [Person] -``` - -To config a group: - -```python -group = Group { - name = "group" - persons = [{ - name = { - firstName = "John" - lastName = "Doe" - } - age = 24 - }] -} -``` - -- Top-level schema name is required to config a schema. -- The schema of the attributes in the schema can be omitted. - -Multi-level nested schemas will make the configuration verbose. KCL supports defining attributes in the schema through `selector expression`. The selector form is **x.y.z**, see the following example: - -```python -group = Group { - name = "group" - persons = [{ - name.firstName = "John" - name.lastName = "Doe" - age = 24 - }] -} -``` - -- Selector can be used to represent attribute in a schema - -### Inheritance - -Inheritance is an effective means to define a hierarchical structure definition, and KCL supports limited **single inheritance** of the schema. - -```python -schema Person: - firstName: str - lastName: str - -# schema Scholar inherits schema Person -schema Scholar(Person): - fullName: str = firstName + '_' + lastName - subject: str - -JohnDoe = Scholar { - firstName = "John", - lastName = "Doe", - subject = "CS" -} -``` - -The result is a **dict**: - -```python -{ - 'JohnDoe': { - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' - 'subject': 'CS' - } -} -``` - -Each schema can be treated as a separated function context. Statements, including attribute statements and init statements, in the context of schemas will be evaluated from base schema to subschema according to the inheritance order. Each schema context is evaluated only once sequentially. The same goes for expressions in the check block. In the example, firstName and lastName are configured in the context of Person schema, and fullName is formed by splicing firstName and lastName in the context of Scholar schema. - -The default value can be modified in each schema. Value defined in **Configuration Definition** has a higher priority than the default value. Attributes with default values in any schema context ​​will eventually be unioned by configuration data. References to attributes in the schema context statements will use the value with unioned configuration data on evaluating at runtime. For example: - -```python -schema a: - x = 1 - y = x * 2 - -schema b(a): - x = 2 - -v = a { - x = 3 -} - -``` - -The result is a **dict**: - -```python -{ - 'v': { - 'x': 3 - 'y': 6 - } -} -``` - -Notes: - -- Report an error if inheriting more than one base schema. -- The type of the base schema attribute cannot be modified in the subschema. -- Report an error if inheriting a **mixin**. -- Report an error when a circular dependency occurs. - -Limitations: - -Since inheritance will derive some complex demands, we are cautious about these complex demands. There are still some restrictions on inheritance, and it's still under discussion. - -- KCL provides limited and deterministic polymorphism support, more complex and flexible polymorphism support, such as **self**, **super** keywords, are temporarily not included in the schema definition. -- Currently, KCL only supports the polymorphism of the inherited attributes of the schema, and does not support the polymorphism of the expressions in the check block. -- For the case of multiple levels of schema inheritance, the schema arguments can only be passed to the last level of sub-schema. - -### Mixin - -In addition to **composition** and **inheritance**, KCL supports declarative reuse of schema code through the **mixin** mechanism. To use a mixin, we only need to declare the **mixin** in the schema definition. - -The **mixin** syntax is the following: - -```bnf -//////////// mixin_stmt //////////// -mixin_stmt: "mixin" "[" [mixins | multiline_mixins] "]" "\n" -multiline_mixins: "\n" _INDENT mixins "\n" _DEDENT -mixins: operand_name ("," ("\n" mixins | operand_name))* -``` - -Here is a simple example: - -```python -schema Person: - mixin [FullNameMixin] - firstName: str = "default" - lastName: str - -schema FullNameMixin: - fullName: str = "{} {}".format(firstName, lastName) - -JohnDoe = Person { - firstName = "John" - lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'JohnDoe': { - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' - } -} -``` - -Multiple mixins can be added to a single schema, and mixins context will be evaluated after the host schema context at runtime. In the inheritance scenario, the mixin context can be regarded as a part of the host schema context, and the overall evaluation of schema context order is not affected. - -Notes: - -- The name of **mixin** schema must end with 'Mixin', otherwise an error will be reported. -- The attributes referenced in the **mixin** must be defined in the **mixin** itself or host schema, otherwise an error will be reported. - -### Protocol - -In addition to schema, an additional type definition method `protocol` is provided in KCL, and its properties are as follows: - -- In a protocol, only attributes and their types can be defined, complex logic and check expressions cannot be written, and mixins cannot be used. -- A protocol can only inherit or refer to other protocols, but cannot inherit or refer to other schemas. - -We can use **protocol** to add an optional host type to the dynamically inserted **mixin**. - -The **mixin** can define its host type through the `for` keyword, and internally it will query the type corresponding to the attribute from the host type. - -```python -protocol DataProtocol: # A mixin host type - data: str - -mixin DataMixin for DataProtocol: # Using the `for` keyword to define a mixin host type - x: int = data # The type of `data` is `str`, which is from `data` of `DataProtocol` -``` - -In `DataMixin`, the `data` attribute is obtained according to the `DataProtocol` host type as `str` type, and then a type error will occur when the value is assigned to `x` of type `int`: - -```python -protocol DataProtocol: - data: str - -mixin DataMixin for DataProtocol: - x: int = data # Error: expect int, got str - x: str = data # Error: can't change schema field type of 'x' from int to str -``` - -Please note that the host type **protocol** can only be used for **mixin** definitions (the suffix name is `Mixin`), otherwise an error will be reported. - -```python -protocol DataProtocol: - data: str - -schema Data for DataProtocol: # Error: only schema mixin can inherit from protocol - x: str = data -``` - -### Schema Context Evaluation - -The schema definition is composed of attribute statements, configuration data, init statements, mixins, and checks. In a separate schema context, the evaluation top-down order is as follows: - -``` -|------------------------------------------| -| attribute defaulting | -|------------------------------------------| -| configuration union | -|------------------------------------------| -| attribute templating | -|------------------------------------------| -| statements in declaration order | -|------------------------------------------| -| mixins in declaration order | -|------------------------------------------| -| check expressions in any order | -|------------------------------------------| -``` - -In the case of schema inheritance, each schema context is evaluated from the base schema in the order of inheritance, and each context is evaluated only once. -Suppose there are schemas a, b, and c, where c inherits b and b inherits a. Schema contexts will be evaluated in top-down order as: - -``` -|-----------------| -| schema a | -|-----------------| -| schema b | -|-----------------| -| schema c | -|-----------------| -``` - -### Members - -Built-in function and members of schema - -- instances() - Return the list of existing instances of a schema. - -### Irrelevant Order Calculation - -The irrelevant order calculation in the schema indicates the reference relationship between the internal attributes of the schema. For example, when we declare an expression of the form `a = b + 1`, the calculation of the value of `a` depends on the calculation of the value of `b`. When the compiler calculate the value of `a` and the value of `a` depends on the value of `b`, the compiler will choose to first calculate the value of `b`, and then calculate the value of a according to the expression `a = b + 1`, which is slightly different from the calculation method of traditional procedural language the difference. - -Since the calculation of values in the schema is based on dependencies, just like a directed acyclic graph traverses each node in the graph according to the order of topological sorting, the order of declaration of attributes in the schema is not so important, so the feature is called the irrelevant order calculation. - -Please note that there can be no circular references between different schema attribute values. - -We can see this feature through the following examples. - -```python -schema Person: - name?: str - age: int = _age - - _age = 10 - - if name == "Son": - _age = 18 - -schema Son(Person): - name: str = "Son" - -person = Person {} -son = Son {} -``` - -The output is - -```yaml -person: - name: null - age: 10 -son: - name: Son - age: 18 -``` - -Besides, we can achieve KCL polymorphism such as - -```python -schema Person: - name?: str - _age: int = _age - - _age = 10 - if name == "Son": - _age = 18 - elif name == "SonConf": - _age = 24 - -schema Son(Person): - name: str = "Son" - -person = Person() {} -son = Son() { - name = "SonConf" -} -``` - -The output is - -```yaml -person: - name: null - age: 10 -son: - name: SonConf - age: 24 -``` - -More examples: - -```python -schema Fib: - n1: int = n - 1 - n2: int = n1 - 1 - n: int - value: int = _value - - if n <= 2: - _value = 1 - else: - _value = (Fib {n = n1}).value + (Fib {n = n2}).value - -fib8 = (Fib {n = 8}).value -``` - -The output is - -```yaml -fib8: 21 -``` - -As in the above examples, we can see that in the schema, we only need to simply specify the dependency between attributes, and the compiler will automatically calculate the value based on the dependency, which can help us save a lot of boilerplate code and reduce configuration difficulty of writing. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/statements.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/statements.md deleted file mode 100644 index b09488b9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/statements.md +++ /dev/null @@ -1,185 +0,0 @@ ---- -title: "Statements" -linkTitle: "Statements" -type: "docs" -weight: 2 -description: Statements ---- - -## Syntax - -In KCL, statements consist of small statements and compound statements. The syntax is the following: - -```bnf -preamble_statement: preamble_small_stmt | preamble_compound_stmt -preamble_small_stmt: (small_stmt | import_stmt) NEWLINE -preamble_compound_stmt: compound_stmt | schema_stmt -statement: small_stmt NEWLINE | compound_stmt -compound_stmt: if_stmt -small_stmt: assign_stmt | expr_stmt | assert_stmt -``` - -The preamble statement is used to define the module level statements, consist of `statement`, `import_stmt`, and `schema_stmt`. The statement is used to define the block level statements, which are used in the `if` statement and `schema` statement. - -### Small Statements - -A small statement is comprised of a single logical line. Multiple statements in one-line are not allowed. - -#### Assignment Statements - -Generally, assign_stmt is divided into assignment and augmented assignment. The syntax is the following: - -```bnf -assign_stmt: target_primary ("=" target_primary)* "=" test | target_primary augassign test -augassign: "+=" | "-=" | "*=" | "**=" | "/=" | "//=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>=" | "or" | "and" -target_primary: identifier | target_primary DOT identifier -``` - -An assignment statement has the form `lhs = rhs`. It evaluates the expression on the right-hand side then assigns its value (or values) to the variable (or variables) on the left-hand side. - -The **target_primary** on the left-hand side is an `identifier` or an `identifier` followed by select dots. - -Note: When using **target_primary** will cause collisions, use **primary_expr** as an alternative. - -Examples: - -```python -k = 1 -a.b = "a.b" -``` - -To keep it simple, the compound target is not supported as **target_primary**. - -The right value of an assignment statement is a conditional expression, which is discussed separately. - -An augmented assignment, which has the form `lhs op= rhs` updates the variable `lhs` by applying a binary arithmetic operator op (one of +, -, \*, /, //, %, &, |, ^, <<, >>) to the previous value of `lhs` and the value of `rhs`. - -The **target_primary** on the left-hand side is the same as assignment statement. Examples: - -```python -_x -= 1 -_filename += ".k" -``` - -There is no concept of in-place modification in KCL. The `augassign` statement will modify a copy of the **target_primary** and assign the copy to **target_primary**. - -In particular, in KCL, the `|=` symbol represents the **union** operation, which is defined as follows: - -- The behavior of the **union** operation needs to be consistent with the behavior of the **configuration definition**. - -See **expressions** spec for more details of union operator in **Arithmetic Operations**. - -#### Expression Statements - -An expression statement evaluates an expression and discards its result. - -Syntax: - -```bnf -expr_stmt: expression -``` - -An expression statement supported in KCL is function invocation expression, which is discussed in **expression** spec. - -```python -print(k) # print a variable -``` - -#### Import Statements - -Import statements are used to **search** and **load** a module, and define a name or names in the local namespace for the scope where the import statement occurs. - -Syntax: - -```bnf -import_stmt: "import" dot_name ("as" NAME)? -dot_name: [leading_dots] identifier (DOT identifier)* -leading_dots: "."+ -``` - -Examples: - -```python -import math # import a built-in module math -import pkg # import pkg -import pkg.foo # import pkg.foo -import pkg.subpkg # import a subpkg in a pkg -import .pkg2.subpkg3 # import a subpkg in a pkg inside of current pkg -import ...pkg2 # Go two levels up then import pkg2 -``` - -See **module** spec for more details of module spec. - -#### Assert Statements - -Assert statements are a convenient way to insert debugging assertions into KCL code. - -The syntax is the following: - -``` -assert_stmt: ASSERT test ("," test)? -``` - -The conditional expression in assert will be evaluated and get a boolean. Report an error if returning a `False`. - -Examples: - -```python -assert: x > 1 # report an error on x <= 1 -``` - -#### Conditional Statements - -KCL allows using conditional statements to control the instructions to -be executed. They are also called the control-flow statements. - -The only type of control-flow syntax is the well-known `if-elif-else` syntax. - -The syntax of the `if-elif-else` statement is the following. - -```bnf -if_stmt: "if" test ":" suite ("elif" test ":" suite)* (ELSE ":" suite)? -suite: small_stmt | NEWLINE _INDENT statement+ _DEDENT -``` - -An `if` or `elif` statement evaluates a given expression. When the expression -is evaluated to `True`, a list of statements following `:` are executed. - -The following is an example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - print("maybe a is negative") -else: - print("a >= 100") -``` - -`if-elif-else` statements can be nested. For example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - if a < 0: - print("a is negative") - print("No matter a is negative or positive, this message is printed") -else: - print("a >= 100") -``` - -#### Schema Statements - -Schema statements are used to define a type of configuration data. The syntax is the following: - -```bnf -schema_stmt: [decorators] "schema" ["relaxed"] identifier ["[" [arguments] "]"] ["(" operand_name ")"] ":" NEWLINE [schema_body] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt | statement)* [check_block] _DEDENT -``` - -See **schema** spec for more details of schema spec. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/tour.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/tour.md deleted file mode 100644 index 93a080e5..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/tour.md +++ /dev/null @@ -1,3208 +0,0 @@ ---- -title: "KCL 之旅" -sidebar_position: 1 ---- - -本文展示了如何使用 KCL 的核心特性,包含变量、运算符、schema 和库,前提是您有使用其他语言编程的经验。KCL 主要受 Python 启发,了解 Python 对学习 KCL 非常有帮助。 - -### 重要概念 - -在学习 KCL 语言时,请牢记以下事实和概念: - -- KCL 是一种配置策略语言。它为编写配置和策略提供了简单且自洽的语言设计和库支持。它不能用于应用程序开发或其他通用编程语言(GPL)支持的场景。 -- KCL 吸收了经典 **OOP** 的元素,并且提供了**类型**、**复用**和**合并**等简单、开发人员友好、可靠且利于传播的配置编写实践。 -- KCL 更倾向于**不可变性**,建议使用**合并**来添加增量的变更。不可变性降低了副作用,例如不可预测的问题。 -- KCL 的 **schema** 结构体定义了严格的属性和静态类型,并且支持表达式验证。**schema** 结构体主要由带类型的属性、schema 上下文和检查块构成。 -- KCL 的 **config** 是一个类 **JSON** 表达式,通过它我们可以复用 schema 的完整定义。KCL 通过分离 schema 和 config 来提供定义和配置的能力。 -- KCL 的 **rule** 是一个书写规则约束表达式的结构,可用于数据校验和策略编写。 -- KCL 的代码文件以包(目录)和模块(文件)的形式进行管理。同一包中的 schema 彼此可见;跨包的数据需要通过 **import 语句**导入。包级变量虽然可以导出,但是它们不能被其他包修改。 -- KCL 语法定义主要使用声明式表达式,并且只提供少量必要的声明式语句,例如 import、 if...else、assert、assignment 以及 schema。 -- 没有主函数,每个 `.k` 文件可以作为单独的配置文件执行。 -- 支持**内置函数**和**插件**以简化编写。 - -### 关键字 - -下表列出了 KCL 语言的关键字。 - -```txt -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -### 标识符 - -在 KCL 中, 标识符是标识一个值的名称,可以带有选择器。 - -- 标识符由字母、数字、下划线或前缀 `$` 组成。 -- 标识符不能与关键字重复,除非它们有 `$` 前缀。 -- 标识符不得包含任何嵌入的空格或符号。 -- 可以在标识符中的任何位置使用字母和下划线。 -- 数字不能放在标识符的第一位。 -- `$` 字符只能放在标识符的第一个位置。 - -示例: - -```python -x -a -b1 -b_2 -_c -$if -``` - -为了简化限定标识符(例如 `pkg.type`)的定义,我们还定义了 `qualified identifier`: - -示例: - -```python -pkg.a -``` - -在 `qualified identifier` 中的包名必须通过 `import` 关键字导入。 - -#### 标识符前缀 - -使用 `$` 前缀符号定义关键字标识符。 - -```python -$if = 1 -$else = "s" -``` - -请注意,非关键字标识符是否有 `$` 符号都是同样的效果。 - -```python -_a = 1 -$_a = 2 # equal to `_a = 2` -``` - -### 变量 - -以下是如何创建并实例化变量的例子: - -```python -name = "Foo" # Declare a variable named `name` and its value is a string literal "Foo" -``` - -它对应了如下 YAML 输出: - -```yaml -name: Foo -``` - -在 KCL 中,我们可以通过定义包级变量将变量导出为配置数据。使其直接、清晰、可维护。导出的变量是不可变的。因此一旦声明它,就无法对其进行修改,例如,假设我们有一个名为 `example.k` 的配置文件,变量 `name` 在声明后就禁止修改,就像标准的命令式语言一样。 - -```python -name = "Foo" # exported - -... - -name = "Bar" # error: a exported declaration variable can only be set once. -``` - -作为补充,我们可以在模块级别定义一个非导出变量,这个变量是可变的,不会显示在 YAML 输出当中。 - -```python -_name = "Foo" # _ variables are not output to YAML and are mutable -_name = "Bar" -``` - -请注意,变量的名称不能为 `True`、`False`、`None` 或者 `Undefined`,因为它们与 KCL 内置的名称常量之间存在二义性。 - -```python -False = 1 # Error -True = False # Error -None = Undefined # Error -Undefined = None # Error -``` - -### 内置类型 - -KCL 支持以下类型: - -- 数字 -- 字符串 -- 布尔 -- 列表 -- 字典 - -#### 数字 - -KCL 的数字类型有两种形式: - -- 64 位有符号整数。值的范围为 -9223372036854775808~9223372036854775807. -- 64 位浮点数,遵循 IEEE 754 标准。我们不建议在配置中使用 float 类型,我们可以使用字符串代替并在运行时进行解析。 - -整数和浮点数都支持基本运算符,例如 `+`,`-`,`/` 和 `*`,而复杂的运算,例如 `abs()`, `ceil()` 和 `floor()`,都是通过内置的数学库来支持。 - -整数是不带小数点的数字。以下是一些定义整数的例子: - -```python -a = 1 -b = -1 -c = 0x10 # hexadecimal literal -d = 0o10 # octal literal -e = 010 # octal literal -f = 0b10 # binary literal -g = int("10") # int constructor -``` - -如果一个数字包含小数点,则它是浮点数。以下是一些浮点数的示例: - -```python -a = 1.10 -b = 1.0 -c = -35.59 -d = 32.3e+18 -f = -90. -h = 70.2E-12 -i = float("112") # float constructor -``` - -内置数学库可用于数字类型: - -```python -import math - -assert abs(-40) == 40 -assert round(70.23456) == 70 -assert min(80, 100, 1000) == 80 -assert max(80, 100, 1000) == 1000 -assert sum([0,1,2]) == 3 -assert math.ceil(100.12) == 101.0 -assert math.floor(100.12) == 100.0 -assert math.pow(100, 2) == 10000.0 -``` - -KCL 默认使用 64 位数字类型。我们可以在 KCL 命令行使用 `-r` 参数执行严格的 32 位范围检查。 - -```bash -kcl main.k -r -d -``` - -请注意,为了性能考虑该功能只能在 `debug` 模式中使用。 - -##### 单位字面值 - -在 KCL 中,我们可以给一个整数添加如下的单位后缀,这不影响它的真实值。 - -- 通用整形和定点数: `P`, `T`, `G`, `M`, `K`, `k`, `m`, `u`, `n` -- 2 的幂: `Pi`, `Ti`, `Gi`, `Mi`, `Ki` - -```python -# SI -n = 1n # 1e-09 -u = 1u # 1e-06 -m = 1m # 1e-03 -k = 1k # 1000 -K = 1K # 1000 -M = 1M # 1000000 -G = 1G # 1000000000 -T = 1T # 100000000000 -P = 1P # 1000000000000000 -# IEC -Ki = 1Ki # 1024 -Mi = 1Mi # 1024 ** 2 -Gi = 1Gi # 1024 ** 3 -Ti = 1Ti # 1024 ** 4 -Pi = 1Pi # 1024 ** 5 -``` - -此外,我们还可以使用定义在 `units` 模块中的单位常量: - -```python -import units - -n = 1 * units.n # 1e-09 -u = 1 * units.u # 1e-06 -m = 1 * units.m # 1e-03 -k = 1 * units.k # 1000 -K = 1 * units.K # 1000 -M = 1 * units.M # 1000000 -G = 1 * units.G # 1000000000 -T = 1 * units.T # 1000000000000 -P = 1 * units.P # 1000000000000000 -# IEC -Ki = 1 * units.Ki # 1024 -Mi = 1 * units.Mi # 1024 ** 2 -Gi = 1 * units.Gi # 1024 ** 3 -Ti = 1 * units.Ti # 1024 ** 4 -Pi = 1 * units.Pi # 1024 ** 5 -``` - -我们还可以使用定义在 `units` 模块内的整数和单位字符串之间的转换函数 - -```python -import units -# SI -K = units.to_K(1000) # "1K" -M = units.to_M(1000000) # "1M" -G = units.to_G(1000000000) # "1G" -T = units.to_T(1000000000000) # "1T" -P = units.to_P(1000000000000000) # "1P" -# IEC -Ki = units.to_Ki(1024) # "1Ki" -Mi = units.to_Mi(1024 ** 2) # "1Mi" -Gi = units.to_Gi(1024 ** 3) # "1Gi" -Ti = units.to_Ti(1024 ** 4) # "1Ti" -Pi = units.to_Pi(1024 ** 5) # "1Pi" -``` - -```python -import units -# SI -K = units.to_K(int("1M")) # "1000K" -M = units.to_M(int("1G")) # "1000M" -G = units.to_G(int("1T")) # "1000G" -T = units.to_T(int("1P")) # "1000T" -P = units.to_P(int("10P")) # "10P" -# IEC -Ki = units.to_Ki(int("1Mi")) # "1024Ki" -Mi = units.to_Mi(int("1Gi")) # "1024Mi" -Gi = units.to_Gi(int("1Ti")) # "1024Gi" -Ti = units.to_Ti(int("1Pi")) # "1024Ti" -Pi = units.to_Pi(int("10Pi")) # "10Pi" -``` - -单位类型定义在 `units` 模块中,单位类型的值不能进行任何四则运算。 - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -x0: NumberMultiplier = 1M # Ok -x1: NumberMultiplier = x0 # Ok -x2 = x0 + x1 # Error: unsupported operand type(s) for +: 'number_multiplier(1M)' and 'number_multiplier(1M)' -``` - -我们可以使用 `int()`、`float()` 和 `str()` 函数将数值单位类型转换为数字类型或字符串类型。 - -```python -a: int = int(1Ki) # 1024 -b: float = float(1Ki) # 1024.0 -c: str = str(1Mi) # "1Mi" -``` - -#### 字符串 - -字符串是一个不可变的 Unicode 字符序列。我们可以使用单引号或双引号创建字符串: - -```python -'allows embedded "double" quotes' # Single quotes -"allows embedded 'single' quotes" # Double quotes -'''Three single quotes''', """Three double quotes""" # Triple quoted -``` - -三引号用于定义多行字符串。 - -```python -"""This is a long triple quoted string -may span multiple lines. -""" -``` - -请注意,KCL 的单引号和双引号字符串的使用几乎没有区别。唯一可以简化的是,我们不需要在单引号字符串中转义双引号,也不需要在双引号中转义单引号。 - -```python -'This is my book named "foo"' # Don’t need to escape double quotes in single quoted strings. -"This is my book named 'foo'" # Don’t need to escape single quotes in double quoted strings. -``` - -我们可以使用 `+` 操作符连接字符串: - -```python -x = 'The + operator ' + 'works, as well.' -``` - -我们可以使用 `str` 内置函数将 int 或 float 转为字符串: - -```python -x = str(3.5) # "3.5" -``` - -可以使用很多内置的字符串函数: - -```python -x = "length" -assert len(x) == 6 # True -assert x.capitalize() == "Length" -assert x.count("gt") == 1 -assert x.endswith("th") == True -assert x.find("gth") == 3 -assert "{} {}".format("hello", "world") == 'hello world' -assert x.index("gth") == 3 -assert x.isalnum() == True -assert x.isalpha() == True -assert "123456".isdigit() == True -assert x.islower() == True -assert " ".isspace() == True -assert "This Is Title Example".istitle() == True -assert x.isupper() == False -assert "|".join(["a", "b", "c"]) == "a|b|c" -assert "LENGTH".lower() == "length" -assert ' spacious '.lstrip() == 'spacious ' -assert x.replace("th", "ht") == "lenght" -assert "lengthlength".rfind("le") == 6 -assert "lengthlength".rindex("le") == 6 -assert "length length".rsplit() == ["length", "length"] -assert "length ".rstrip() == "length" -assert "length length".split() == ["length", "length"] -assert 'ab c\n\nde fg\rkl\r\n'.splitlines() == ['ab c', '', 'de fg', 'kl'] -assert "length".startswith('len') == True -assert "***length***".strip('*') == "length" -assert "length length".title() == "Length Length" -assert x.upper() == "LENGTH" -``` - -格式化字符串有两种使用方法: 使用 `"{}".format()` 内置函数, 或者使用花括号指定变量并使用 `$` 标记取变量值。在 KCL 中叫做**插值字符串**。在下面的例子中,`a` 和 `b` 的值都是 `"hello world"`。 - -此外,要序列化的变量可以以特殊的数据格式提取,例如 YAML 或 JSON。在这种情况中,`#yaml` 或 `#json` 可以包含在花括号中。 - -具体来说,当 `$` 符号本身需要出现在**插值字符串**中,需要使用 `$$` 转义。或者使用 `+` 符号连接 `$` 符号和插值字符串来避免转义。在以下示例中,`c` 和 `c2` 的值都是 `$hello world$`。 - -```python -world = "world" -a = "hello {}".format(world) # "hello world" -b = "hello ${world}" # "hello world" -c = "$$hello ${world}$$" # "$hello world$" -c2 = "$" + "hello ${world}" + "$" # "$hello world$" - -myDict = { - "key1" = "value1" - "key2" = "value2" -} - -d = "here is myDict in json: ${myDict: #json}" -# d: 'here is myDict in json: {"key1": "value1", "key2": "value2"}' - -e = "here is myDict in yaml:\n${myDict: #yaml}" -# e: | -# here is myDict in yaml: -# key1: value1 -# key2: value2 -``` - -此外,我们可以在上面的示例代码输出 **YAML 字符串** 中看到一些符号,例如 `|`、`>`、`+`、`-`。 - -- `|` 表示 **块文字样式**,指示块内换行符的行为方式。 -- `>` 表示块标量中的**块折叠样式**,换行符将被空格替换。 -- `+` 和 `-` 是 **block chomping 指示符**,用于控制字符串末尾的换行符。 默认值 **clip** 在字符串的末尾放置一个换行符。 要删除所有换行符,请通过在样式指示符 `|` 或 `>` 后面添加 `-` 来**删除**它们。 clip 和 strip 都忽略块末尾实际有多少换行符; 在样式指示符后面添加一个 `+` 来**保留**它们。 - -例如,**strip 块文字样式** yaml 字符串是 - -```yaml -example: |- - Several lines of text, - with some "quotes" of various 'types', - and also a blank line: - - plus another line at the end. -``` - -结果为: - -```plain -Several lines of text, -with some "quotes" of various 'types', -and also a blank line: - -plus another line at the end. -``` - -更多信息可见 [Yaml Multiline String](https://yaml-multiline.info/) 和 [YAML Specification v1.2](https://yaml.org/spec/1.2.1/) 。 - -##### 原始字符串 - -KCL 原始字符串是通过在字符串字面值前加上 `'r'` 或 `'R'` 来创建的。 KCL 原始字符串将反斜杠 (`\`) 和字符串插值 (`${}`) 视为普通的非字符。当我们想要一个包含反斜杠、字符串插值的字符串并且不希望它们被视为转义字符时,原始字符串是很有用的。 - -- 对于包含反斜杠(`\`)的原始字符串,KCL 代码和输出 YAML 如下: - -```python -s = "Hi\nHello" -raw_s = r"Hi\nHello" # This is a KCL raw string with the `r` prefix. -``` - -```yaml -s: |- - Hi - Hello -raw_s: Hi\nHello -``` - -- 对于包含字符串插值(`${}`)的原始字符串,KCL 代码和输出 YAML 如下: - -```python -worldString = "world" -s = "Hello ${worldString}" -raw_s = r"Hello ${worldString}" # This is a KCL raw string with the `r` prefix. -``` - -```yaml -worldString: world -s: Hello world -raw_s: Hello ${worldString} -``` - -此外,原始字符串最常用的场景是在正则表达式中使用: - -```python -import regex - -key = "key" -result = regex.match(key, r"[A-Za-z0-9_.-]*") # True -``` - -#### 布尔值 - -布尔值有两个常量对象:`False` 和 `True`. - -```python -a = True -b = False -``` - -#### List - -List 是一个序列,通常用于存储同质项的集合。下面是一个简单的 KCL 列表的例子: - -```python -list = [1, 2, 3] -assert len(list) == 3 # True -assert list[0] == 1 # True -``` - -我们可以使用列表推导式构建列表: - -```python -list = [ _x for _x in range(20) if _x % 2 == 0] -assert list == [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] # True -``` - -并且还可以使用嵌套的列表推导式: - -```python -matrix = [[1, 2], [3,4], [5,6], [7,8]] -transpose = [[row[_i] for row in matrix] for _i in range(2)] -assert transpose == [[1, 3, 5, 7], [2, 4, 6, 8]] # True -``` - -此外,我们可以在列表推导式中使用两个变量。第一个变量表示列表中的索引,第二个变量表示列表中的项。 - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use `_` to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -我们可以通过 `+` 连接列表: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -joined_list = _list0 + _list1 # [1, 2, 3, 4, 5, 6] -``` - -我们可以使用解包操作符 `*` 合并多个列表: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -union_list = [*_list0, *_list1] # [1, 2, 3, 4, 5, 6] -``` - -我们可以使用 `if` 表达式动态的将元素添加到列表,符合条件的元素会被添加到列表,不符合条件的元素会被忽略。 - -```python -a = 1 # 1 -data = [ - 1 - if a == 1: 2 - if a > 0: 3 - if a < 0: 4 -] # [1, 2, 3] -``` - -```python -a = 1 # 1 -data1 = [ - 1 - if a == 1: - 2 - elif a == 2: - 3 - else: - 3 -] # [1, 2] -data2 = [ - 1 - if a == 1: 2 - elif a == 2: 2 - else: 3 -] # [1, 2] -``` - -我们可以合并(union)列表: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -union_list = _list0 | _list1 # [4, 5, 6] -``` - -我们可以使用 `for k in list_var` 表达式遍历列表: - -```python -data = [1, 2, 3] -dataAnother = [val * 2 for val in data] # [2, 4, 6] -``` - -#### Dict - -Dict 是将可哈希的值映射到任意对象的映射对象。字典是有序的。键的顺序遵循其声明的顺序: - -这里有几个简单的 KCL 字典: - -```python -a = {"one" = 1, "two" = 2, "three" = 3} -b = {'one' = 1, 'two' = 2, 'three' = 3} -assert a == b # True -assert len(a) == 3 # True -``` - -在写多行的键-值时,可以省略每个键-值对行尾的逗号 `,`: - -```python -data = { - "key1" = "value1" # Ignore the comma ',' at the end of line - "key2" = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -在 Dict 键上使用简单的字面值时可以省略引号: - -```python -data = { - key1 = "value1" # Ignore key quotation '"' - key2 = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -此外,**选择表达式**可以用于定义包含嵌套键 dict 实例。 - -```python -person = { - base.count = 2 - base.value = "value" - labels.key = "value" -} # {"base": {"count": 2, "value": "value"}, "labels": {"key": "value"}} -``` - -输出 YAML 为: - -```yaml -person: - base: - count: 2 - value: value - labels: - key: value -``` - -在 KCL 中,dict 中的不同的字段可以直接引用,比如如下的例子 - -```python -config = { - name = "me" - metadata.name = name # Reference `name` with the value `"me"` in `config` directly. -} -``` - -输出 YAML 为: - -```yaml -config: - name: me - metadata: - name: me -``` - -我们可以使用字典推导式构建字典: - -```python -x = {str(i): 2 * i for i in range(3)} -assert x == {"0" = 0, "1" = 2, "2" = 4} -``` - -此外,我们可以在字典推导式中使用两个变量。第一个变量表示字典的键,第二个变量表示字典中键对应的值。 - -```python -data = {key1 = "value1", key2 = "value2"} -# Single variable loop -dataKeys1 = {k: k for k in data} # {"key1": "key1", "key2": "key2"} -dataValues1 = {k: data[k] for k in data} # {"key1": "value1", "key2": "value2"} -# Double variable loop -dataKeys2 = {k: k for k, v in data} # {"key1": "key1", "key2": "key2"} -dataValues2 = {v: v for k, v in data} # {"value1": "value1", "value2": "value2"} -dataFilter = {k: v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use `_` to ignore loop variables -dataKeys3 = {k: k for k, _ in data} # {"key1": "key1", "key2": "key2"} -dataValues3 = {v: v for _, v in data} # {"value1": "value1", "value2": "value2"} -``` - -我们可以使用解包操作符 `**` 来合并字典: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = {**_part1, **_part2} # {"a: "b", "c": "d"} -``` - -此外,union 操作符 `|` 也能达到同样的效果: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = _part1 | _part2 # {"a: "b", "c": "d"} -``` - -我们可以使用 `if` 表达式动态的将元素添加到字典,符合条件的元素会被添加到字典,不符合条件的元素会被忽略。 - -```python -a = 1 # 1 -data = { - key1 = "value1" - if a == 1: key2 = "value2" - if a > 0: key3 = "value3" - if a < 0: key4 = "value4" -} # {"key1": "value1", "key2": "value2", "key3": "value3"} -``` - -```python -a = 1 # 1 -data1 = { - key1 = "value1" - if a == 1: - key2 = "value2" - elif a > 0: - key3 = "value3" - else: - key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -data2 = { - key1 = "value1" - if a == 1: key2 = "value2" - elif a > 0: key3 = "value3" - else: key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -``` - -我们可以使用 `for k in dict_var` 表达式来遍历字典, 并且可以使用 `in` 操作符来判断 dict 是否包含某个键。 - -```python -data = {key1 = "value1", key2 = "value2"} -dataAnother = {k: data[k] + "suffix" for k in data} # {"key1": "value1suffix", "key2": "value2suffix"} -containsKey1 = "key1" in data # True -containsKey2 = "key" in data # False -``` - -#### None - -在 KCL 中, `None` 表示对象的值为空, 这与 Go 中的 `nil` 和 Java 中的 `null` 一样,并且对应于 YAML 中的 `null`。 - -```python -a = None -b = [1, 2, None] -c = {key1 = "value1", key2 = None} -``` - -输出如下: - -```yaml -a: null -b: - - 1 - - 2 - - null -c: - key1: value1 - key2: null -``` - -请注意,`None` 不能参与四则运算,但它可以参与逻辑运算和比较运算。 - -```python -a = 1 + None # error -b = int(None) # error -c = not None # True -d = None == None # True -e = None or 1 # 1 -f = str(None) # None -``` - -#### Undefined - -`Undefined` 与 `None` 类似,但其语义是变量没有分配任何值,也不会输出到 YAML。 - -```python -a = Undefined -b = [1, 2, Undefined] -c = {key1 = "value1", key2 = Undefined} -``` - -输出如下: - -```yaml -b: - - 1 - - 2 -c: - key1: value1 -``` - -请注意,`Undefined` 不能参与四则运算,但它可以参与逻辑运算和比较运算。 - -```python -a = 1 + Undefined # error -b = int(Undefined) # error -c = not Undefined # True -d = Undefined == Undefined # True -e = Undefined or 1 # 1 -f = str(Undefined) # Undefined -``` - -### 运算符 - -以下字符表示运算符: - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != @ \ -``` - -#### 算数运算符 - -KCL 支持常见的算数运算符: - -```python -assert 2 + 3 == 5 -assert 2 - 3 == -1 -assert 2 * 3 == 6 -assert 5 / 2 == 2.5 -assert 5 // 2 == 2 -assert 5 % 2 == 1 -``` - -#### 相等和关系运算符 - -KCL 支持相等和关系运算符: - -```python -assert 2 == 2 -assert 2 != 3 -assert 3 > 2 -assert 2 < 3 -assert 3 >= 3 -assert 2 <= 3 -``` - -#### 逻辑运算符 - -我们可以使用逻辑运算符反转或组合布尔表达式,例如:`and` 和 `or`: - -```python -if not done and (col == 0 or col == 3): - # ...Do something... - -``` - -#### 位运算符和移位运算符 - -以下是位运算符和移位运算符的例子: - -```python -value = 0x22 -bitmask = 0x0f - -assert (value & bitmask) == 0x02 -assert (value & ~bitmask) == 0x20 -assert (value | bitmask) == 0x2f -assert (value ^ bitmask) == 0x2d -assert (value << 4) == 0x220 -assert (value >> 4) == 0x02 -``` - -`|` 运算符可用于位运算,合并基本类型和集合及结构化数据,例如**列表**、**字典**和 **schema**。 - -位运算示例: - -```python -0x12345678 | 0xFF # 0x123456FF -``` - -联合基本类型示例: - -```python -schema x: - a: int | str # attribute a could be a int or string -``` - -#### 赋值运算符 - -以下 token 作为语法中的分隔符: - -```txt - ( ) [ ] { } - , : . ; = -> - += -= *= /= //= %= - &= ^= >>= <<= **= -``` - -以下是使用赋值和参数赋值赋值运算符的例子: - -```python -_a = 2 -_a *= 3 -_a += 1 -assert _a == 7 -``` - -#### Identity 运算符 - -以下关键字作为语法中的 identity 运算符: - -```python -is, is not -``` - -Identity 运算符检查右侧和左侧是否时同一对象。它们通常用于检查某个变量是否是 `None/Undefined/True/False`。以下是一些例子: - -```python -empty_String = "" -empty_String is not None # True -``` - -#### 成员运算符 - -以下关键字作为语法中的成员运算符: - -```python -in, not in -``` - -- `in` 运算符计算了第一个操作数是否是第二个操作数的成员,第二个运算符必须是 list、dict、schema 或 string。 -- `not in` 运算符与 `in` 相反。它们都返回一个布尔值。 - -成员的含义因第二个操作数的类型而异:列表的成员是其元素;字典的成员是其键;字符串的成员是其所有子字符串。 - -```python -1 in [1, 2, 3] # True - -d = {one = 1, two = 2} -"one" in d # True -"three" in d # False -1 in d # False -[] in d # False - -"nasty" in "dynasty" # True -"a" in "banana" # True -"f" not in "way" # True - -d = Data {one = 1, two = 2} # Data is a schema with attributes one and two -"one" in d # True -"three" in d # False -``` - -#### 推导式 - -一个推导表达式通过遍历一个或多个迭代项并计算表达式生成的结果来生成连续的元素,并以此构造新的列表或字典。 - -我们可以如下使用列表和字典的推导表达式: - -```python -listVar = [_x for _x in range(20) if _x % 2 == 0] # list comprehension -dictVar = {str(_i): 2*_i for _i in range(3)} # dict comprehension -``` - -#### 其他运算符 - -- 使用 **()** 表示函数调用, 例如 `"{} {}".format("hello", world)`。 -- 使用 **[]** 引用列表中指定索引处的值。 -- 使用 **:** 定义类型注解。 -- 使用 **.** 引用成员字段。 -- 使用 **\\** 续行符编写长表达式。 - -```python -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " -``` - -### 表达式 - -#### 条件表达式 - -条件表达式的形式为 `a if cond else b`。它首先计算条件 `cond`。如果为真,则会计算 `a` 并生成它的值;否则,它会生成 `b` 的值。 - -示例: - -```python -x = True if enabled else False # If enabled is True, x is True, otherwise x is False -``` - -#### 索引表达式 - -索引表达式 `a[i]` 生成可索引类型的第 `i` 个元素,例如字符串或数组。索引 `i` 必须是 `-n` ≤ `i` < `n` 范围内的 `int` 值,其中 `n` 等于 `len(a)`。其他任何索引都会导致错误。 - -有效的负索引的行为类似于 `n+i`,允许方便的对序列末尾进行索引。 - -```python -val = "abc" -list = ["zero", "one", "two"] -str_0 = val[0] # "a" -str_1 = val[1] # "b" -str_n1 = val[-1] # "c" - -list_0 = list[0] # "zero" -list_1 = list[1] # "one" -list_n1 = list[-1] # "two" -``` - -索引表达式 `d[key]` 也可以用于字典 `d`,以获取指定键对应的值。如果字典中不包含这个键则会返回 `Undefined` - -出现在赋值符左侧的索引表达式会更新指定的列表或字典元素。 - -```python -d = {key1 = "value1", key2 = "value2"} -key1value = d["key1"] # value1 -key2value = d["key2"] # value2 -``` - -尝试更新不可变类型的元素值(如列表或字符串)或可变类型的不可变变量会产生错误。 - -#### 切片表达式 - -切片表达式 `a[start:stop:step]` 会生成 `a` 包含的一个子序列,其中 `a` 必须是字符串或者数组。 - -`start`、`stop` 和 `step` 三个操作数都是可选的。如果有的话,每个值都必须为整数。`step` 的默认值为 1。如果 `step` 未指定,它前面的冒号也可以省略。指定 `step` 为 0 会产生错误。 - -从概念上来说,这些操作数指定了一系列值,索引 `i` 从 `start` 开始,每次增加 `step` 直到 `i` 到达或超过 `stop`。结果由有效的 `i` 的 `a[i]` 组成。 - -如下所示,从三个操作数计算有效的开始和结束的索引。`n` 是序列的长度。 - -```python -val = "abc" -len = len(val) -a = val[1:len] # "bc" (remove first element) -b = val[0:-1] # "ab" (remove last element) -c = val[1:-1] # "b" (remove first and last element) -``` - -```python -"abc"[1:] # "bc" (remove first element) -"abc"[:-1] # "ab" (remove last element) -"abc"[1:-1] # "b" (remove first and last element) -"banana"[1::2] # "aaa" (select alternate elements starting at index 1) -"banana"[4::-2] # "nnb" (select alternate elements in reverse, starting at index 4) -``` - -KCL 禁止将切片表达式定义为左值。原因是列表和字符串是不可变的,重新切片可以直接操作操作数,以确保更好的性能。 - -#### 函数调用 - -KCL 允许调用内置函数,或者调用内置和系统模块中的函数。 - -调用函数的基本方法如下所示: - -```python -import math - -a = math.pow(2, 3) # 2 powers 3 is 8. -b = len([1, 2, 3]) # the length of [1, 2, 3] is 3 -``` - -参数以 `,` 分隔,并且 KCL 还支持位置参数和键-值对形式的参数。 - -```python -print("hello world", end="") -``` - -请注意: - -- 有些函数参数具有默认值。 -- 一些函数接受可变参数。 - -如果没有为没有默认值的参数提供参数,则会抛出错误。 - -#### 选择表达式 - -选择表达式选择值的属性或方法。KCL 提供了许多识别或过滤属性的方法: - -`x.y` - -- dict: 表示字典 `x` 中键 `y` 对应的值。 -- schema: 表示 schema `x` 中 `y` 属性的值。 -- package: 表示 package `x` 中 `y` 标示的标识符。 - -示例: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -name = person.name # "Alice" -age = person.age # 18 - -myDict = { - key = "value" -} -result = myDict.key # "value" -``` - -`x?.y` - -`x` 可以是 schema 实例或 dict。当 `x` 可能为 `None` 或者键 `y` 不在 `x` 中时这非常有用。 - -```python -# Example of dict: -data = {"key" = "value"} -a = data?.key # "value" -b = data?.name # Undefined - -# example of schema instance: -schema Company: - name: str - address: str - -schema Person: - name: str - job?: Company - -alice = Person { - name = "alice" -} - -if alice?.job?.name == "Group": - print("work in Group") -``` - -#### Quantifier 表达式 - -Quantifier 表达式用于集合:列表或字典。通常用于在处理集合后获得某个结果,主要有以下四种形式: - -- **all** - - 用于检测集合中所有元素都满足给定的逻辑表达式,并且返回一个布尔值作为结果。 - - 只有集合中所有元素都满足表达式为 true 时,`all` 表达式为 true,否则为 false。 - - 如果集合为空,返回 true。 - - 支持表达式执行期间逻辑表达式的短路。 -- **any** - - 用于检测集合中至少一个元素都满足给定的逻辑表达式,并且返回一个布尔值作为结果。 - - 当集合中至少一个元素都满足表达式为 true 时,`any` 表达式为 true,否则 false。 - - 如果集合为空,返回 false。 - - 支持表达式执行期间逻辑表达式的短路。 -- **map** - - 映射集合中的元素生成新的列表。 - - 新列表的长度严格等于原列表的长度。 -- **filter** - - 通过逻辑判断筛选原集合中的元素,返回一个经过筛选的子集合。 - - 当表达式为 true 时才将元素添加到子集合。 - - 产生的新集合的类型(list, dict 和 schema)与原集合的类型完全一致,并且长度为 `[0, len(original-collection)]`。 - -**all** 和 **any** 表达式的示例代码: - -```python -schema Config: - volumes: [{str:}] - services: [{str:}] - - check: - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - }, "invalid cluster ip" - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } -``` - -**map** 和 **filter** 表达式的示例代码: - -```python -a = map e in [{name = "1", value = 1}, {name = "2", value = 2}] { - {name = e.name, value = int(e.value) ** 2} -} # [{"name": "1", value: 1}, {"name": "2", "value": 4}] - -b = map k, v in {a = "foo", b = "bar"} { v } # ["foo", "bar"] - -c = filter e in [{name = "1", value = 1}, {name = "2", value = 2}] { - int(e.value) > 1 -} # [{"name": "2", "value": 2}] - -d = filter _, v in {a = "foo", b = "bar"} { - v == "foo" -} # {"a": "foo"} -``` - -请注意,区分 any 表达式和 any 类型的区别。当 `any` 在类型注解中使用,意味着变量的值是任意的,而 any 表达式意味着集合中的至少一个元素满足条件。 - -### 流程控制表达式 - -#### If 和 Else - -KCL 支持 `if` 表达式和可选的 `elif` 和 `else` 表达式, 示例如下: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - print("maybe a is negative") -else: - print("a >= 100") -``` - -`elif` 的例子: - -```python -_result = 0 -if condition == "one": - _result = 1 -elif condition == "two": - _result = 2 -elif condition == "three": - _result = 3 -else: - _result = 4 -``` - -`if-elif-else` 表达式可以嵌套,示例如下: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - if a < 0: - print("a is negative") - print("No matter a is negative or positive, this message is printed") -else: - print("a >= 100") -``` - -此外,对于简单的 `if` 表达式如下: - -```python -if success: - _result = "success" -else: - _result = "failed" -``` - -我们可以使用 ` if else ` 的形式将它们写在一行: - -```python -_result = "success" if success else "failed" -``` - -`if` 或 `elif` 语句计算一个给定的表达式。当表达式的计算结果为 `True`, `:` 之后的语句将被计算,而当表达式为 `False` ,后面的语句不会被计算。 - -请注意,常量 `False`, `None`, 数字 `0`, 空列表 `[]`, 空字典 `{}` 和空字符串 `""` 都被视为 `False` 。 - -```python -_emptyStr = "" -_emptyList = [] -_emptyDict = {} -isEmptyStr = False if _emptyStr else True -isEmptyList = False if _emptyList else True -isEmptyDict = False if _emptyDict else True -``` - -结果为: - -```yaml -isEmptyStr: true -isEmptyList: true -isEmptyDict: true -``` - -### 断言语句 - -当发生错误时,开发人员应该能够检测到错误并终止执行。因此,KCL 引入了 `assert` 语法,示例如下: - -```python -a = 1 -b = 3 -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -``` - -此外,我们可以为 assert 语声明一个条件,当条件满足时,才进行 assert 断言 - -- 使用 if 语句书写条件断言 - -```python -a = None -if a: - assert a > 2: -``` - -- 使用 if 表达式书写条件断言 - -```python -a = None -assert a > 2 if a -``` - -### 函数 - -KCL 支持使用 lambda 关键字定义一个函数 - -```python -func = lambda x: int, y: int -> int { - x + y -} -a = func(1, 1) # 2 -``` - -lambda 函数具有如下特性: - -- lambda 函数将最后一个表达式的值作为函数的返回值,空函数体返回 None -- 返回值类型注解可以省略,返回值类型为最后一个表达式值的类型 -- 函数体中没有与顺序无关的特性,所有的表达式都是按顺序执行的 - -```python -_func = lambda x: int, y: int -> int { - x + y -} # Define a function using the lambda expression -_func = lambda x: int, y: int -> int { - x - y -} # Ok -_func = lambda x: int, y: int -> str { - str(x + y) -} # Error (int, int) -> str can't be assigned to (int, int) -> int -``` - -lambda 函数对象不能参与任何计算,只能在赋值语句和调用语句中使用。 - -```python -func = lambda x: int, y: int -> int { - x + y -} -x = func + 1 # Error: unsupported operand type(s) for +: 'function' and 'int(1)' -``` - -lambda 函数支持捕获其外部作用域的变量,并且可以作为其他函数的参数进行传递 - -```python -a = 1 -func = lambda x: int { - x + a -} -funcOther = lambda f, para: int { - f(para) -} -r0 = funcOther(func, 1) # 2 -r1 = funcOther(lambda x: int { - x + a -}, 1) # 2 -``` - -输出为: - -```yaml -a: 1 -r: 2 -``` - -此外,可以定义一个匿名函数并直接调用。 - -```python -result = (lambda x, y { - z = 2 * x - z + y -})(1, 1) # 3 -``` - -并且还可以在 for 循环使用使用匿名函数 - -```python -result = [(lambda x, y { - x + y -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 3, 3, 4] -``` - -请注意,KCL 中定义的函数的均为纯函数: - -- 函数的返回结果只依赖于它的参数。 -- 函数执行过程里面没有副作用。 - -因此,KCL 函数不能修改外部的变量,只能引用外部的变量,比如如下代码会发生错误: - -```python -globalVar = 1 -func = lambda { - x = globalVar # Ok - globalVar = 1 # Error -} -``` - -### 类型系统 - -#### 类型注解 - -类型注解可用于包级变量,schema 属性和参数。 - -- 属性可以是基本类型,例如字符串(`string`),浮点数(`float`),定点数(`int`) 或布尔值(`bool`)。 -- 属性可以是字面值类型,例如字符串文本(`"TCP"` 和 `"UDP"`),数字文本 (`"1"` 和 `"1.2"`),布尔值文本(`True` 和 `False`)。 -- 属性也可以是列表或字典: - - 未指定元素类型的列表为 `[]`。 - - 元素类型为 `t` 的列表为 `[t]`。这里 `t` 是另一种类型。 - - 键的类型为 `kt` 且值的类型为 `vt` 的字典为 `{kt:vt}`。 - - `kt`, `vt` 或两者都可以为空, 就像列表未指定元素类型一样。 -- 属性可以是由 `|` 定义的 **联合类型** ,例如 `a | b`, 意为类型可以是 a 或 b。 - - 联合类型可以包含 `int`, `str`, `float`, `bool`, `list`, `dict`, 字面值类型和 schema 类型,并且支持类型的嵌套,例如: `{str:str|int}`、`[[int|str]|str|float]` 和 `2 | 4 | 6` 等。 -- 属性可以是 schema 类型。在这种情况下,使用包名 + schema 名称作为类型名。 -- 属性可以声明为任意类型,例如 `any`。 - -示例 - -- 基本类型 - -```python -"""Top level variable type annotation""" -a: int = 1 # Declare a variable `a` that has the type `int` and the value `1` -b: str = "s" # Declare a variable `b` that has the type `str` and the value `"s"` -c: float = 1.0 # Declare a variable `c` that has the type `float` and the value `1.0` -d: bool = True # Declare a variable `d` that has the type `bool` and the value `True` -``` - -- List/Dict/Schema 类型 - -```python -schema Person: - name: str = "Alice" - age: int = 10 - -a: [int] = [1, 2, 3] # Declare a variable `a` that has the list type `[int]` and the value `[1, 2, 3]` -b: {str:str} = {k1 = "v1", k2 = "v2"} # Declare a variable `b` that has the dict type `{str:str}` and the value `{k1 = "v1", k2 = "v2"}` -c: Person = Person {} # Declare a variable `c` that has the schema type `Person` and the value `Person {}` -``` - -- 联合类型 - -```python -# Basic union types -schema x[argc: int]: # Schema argument type annotation - p: int | str # Schema attribute type annotation -``` - -```python -# Literal union types -schema LiteralType: - # String literal union types, x_01 can be one of "TCP" and "UDP" - x_01: "TCP" | "UDP" - # Number literal union types, x_02 can be one of 2, 4, and 6 - x_02: 2 | 4 | 6 - # Unit union types, x_03 can be one of 1Gi, 2Gi and 4Gi - x_03: 1Gi | 2Gi | 4Gi - -x = LiteralType { - x_01 = "TCP" - x_02 = 2 - x_03 = 1Gi -} -``` - -当属性的值不符合联合类型定义时,编译器会抛出错误: - -```python -# Literal union types -schema LiteralType: - # String literal union types, x_01 can be one of "TCP" and "UDP" - x_01: "TCP" | "UDP" - -x = LiteralType { - x_01 = "HTTP" # Error: the type got is inconsistent with the type expected, expect str(TCP)|str(UDP), got str(HTTP) -} -``` - -- Any 类型 - -```python -# Any type -schema Config: - literalConf: any = 1 - dictConf: {str:any} = {key = "value"} - listConf: [any] = [1, "2", True] - -config = Config {} -``` - -请注意,一般在配置编写中不提倡使用 `float` 和 `any` 类型,因为它们都存在一定的不稳定因素,比如精度丢失,无法进行静态类型检查等。 - -此外在 KCL 中,不允许修改一个变量的类型。如果在重新分配值时不满足类型,将引发类型错误。 - -```python -_a = 1 # The type of `_a` is `int` -_a = "s" # Error: expect int, got str(s) -``` - -变量可以赋值给其上界类型,但不能赋值给它的特化类型。 - -`None` 和 `Undefined` 可以赋值给任何类型: - -- 任何类型都可以赋值给 `any` 类型, `None` 和 `Undefined` 可以赋值给 `any` 类型。 - -```python -a: int = None -b: str = Undefined -c: any = 1 -d: any = "s" -e: any = None -``` - -- `int` 类型可以赋值给 `float` 类型, `float` 类型不能赋值给 `int` 类型. - -```python -a: float = 1 -b: int = 1.0 # Error: expect int, got float(1.0) -``` - -- `int` 类型可以赋值给 `int|str` 类型, `int|str` 不能赋值给 `int` 类型. - -```python -a: int | str = 1 -b: int = 1 if a else "s" # Error: expect int, got int(1)|str(s) -``` - -请注意,在 KCL 中虽然提供了 any 类型,但是它仍然是静态类型,所有变量的类型在编译期间不可变。 - -#### 类型推导 - -如果顶层或 schema 中的变量或常量声明没有使用显式的类型注解,则会从初始值推断类型。 - -- 整形数值被推断为 `int`。 - -```python -a = 1 # The variable `a` has the type `int` -``` - -- 浮点数被推断为 `float`。 - -```python -a = 1.0 # The variable `a` has the type `float` -``` - -- 字符串被推断为 `str`。 - -```python -a = "s" # The variable `a` has the type `str` -``` - -- 布尔值被推断为 `bool`。 - -```python -a = True # The variable `a` has the type `bool` -b = False # The variable `b` has the type `bool` -``` - -- `None` 和 `Undefined` 被推断为 `any`。 - -```python -a = None # The variable `a` has the type `any` -b = Undefined # The variable `b` has the type `any` -``` - -- 列表的类型根据元素类型推断,并且是可变大小的。 - -```python -a = [1, 2, 3] # The variable `a` has the type `[int]` -b = [1, 2, True] # The variable `b` has the list union type `[int|bool]` -c = ["s", 1] # The variable `c` has the list union type `[int|str]` -``` - -请注意,空列表将被推导为 `[any]` 类型。 - -```python -a = [] # The variable `a` has the type `[any]` -``` - -- 字典的类型是根据元素的键和值推断的,并且是可变大小的。 - -```python -a = {key = "value"} # The variable `a` has the type `{str:str}` -b = {key = 1} # The variable `b` has the type `{str:int}` -c = {key1 = 1, key2 = "s"} # The variable `c` has the type `{str:int|str}` -``` - -请注意,空字典将被推导为 `{any:any}` 类型。 - -```python -a = {} # The variable `a` has the type `{any:any}` -``` - -- 携带运行时值的 if 条件表达式的类型将被静态推断为所有可能结果的联合类型。 - -```python -a: bool = True # The variable `a` has the type `bool` -b = 1 if a else "s" # The variable `b` has the type `int|str` -``` - -当变量被推导为某个类型时,它的类型不能再改变。 - -```python -_a = 1 -_a = "s" # Error: expect int, got str(1) -``` - -#### 类型别名 - -在 KCL 中,我们可以使用 `type` 关键字为所有类型声明一个类型别名简化复杂类型的书写。 - -```python -type Int = int -type String = str -type StringOrInt = String | Int -type IntList = [int] -type StringAnyDict = {str:} -``` - -我们可以从一个包中导入一个类型并为它定义一个别名。 - -```py -import pkg - -type Data = pkg.Data -``` - -此外,我们还可以使用类型别名和字面值联合类型充当近似枚举的效果。 - -```python -# A type alias of string literal union types -type Color = "Red" | "Yellow" | "Blue" - -schema Config: - color: Color = "Red" # The type of color is `"Red" | "Yellow" | "Blue"`, and it has an alias `Color`, whose default value is `"Red"` - -config = Config { - color = "Blue" -} -``` - -上述代码执行的输出结果为: - -```yaml -config: - color: Blue -``` - -请注意,类型别名不能与已有的内置类型 `any`、`int`、`float`、`bool` 和 `str` 等相同 - -```python -type any = int | str # Error -type int = str # Error -type float = int # Error -type bool = True # Error -type str = "A" | "B" | "C" # Error -``` - -#### 类型守卫 - -KCL 支持在程序中使用 `typeof` 函数对任意值求得其运行时的类型。 - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person {} -t3 = typeof(_x1) - -_x2 = pkg.Person {} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# Output -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -除此之外,我们可以使用 `as` 关键字在运行时作类型转换。`as` 关键字的一般用法如下: - -- 具有偏序关系的基础类型,比如 `float -> int` -- 具有偏序关系的联合类型,比如 `int | str -> str` -- 对类型上界 `any` 的转换,比如 `any -> int` -- 具有偏序关系的结构类型,比如 `base-schema -> sub-schema` - -```python -schema Data1: - id?: int - -schema Data2: - name?: str - -data: Data1 | Data2 = Data1 {} - -if typeof(a) == "Data1": - data1 = data as Data1 # The type of `data1` is `Data1` -elif typeof(a) == "Data2": - data2 = data as Data2 # The type of `data2` is `Data2` -``` - -当类型转换失败时,一个运行时错误将被抛出。 - -```python -a: any = "s" -b: int = a as int # Error: The `str` type cannot be converted to the `int` type -``` - -如果不想要运行时类型转换失败,我们可以添加 `if` 防御式代码进行检查。 - -```python -a: any = "s" -b = a as int if typeof(a) == "int" else None # The type of b is `int` -``` - -请注意,`as` 转换的目标类型不能是字面值类型或者联合类型,因为它们在运行时不具有一个完全确定的类型。 - -### Schema - -#### 概述 - -Schema 是定义复杂配置的语言元素。我们可以定义带类型的属性,初始值和验证规则。此外,KCL 支持 schema 单继承、mixin 和 protocol 实现复杂配置的复用。 - -#### 基础部分 - -##### 属性 - -以下是 schema 基础定义的示例: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 -``` - -在 KCL 中, 我们可以使用类型注解在 schema 中定义一些属性,每个属性都可以设置一个可选的默认值(比如上述代码中的 `age` 属性,它的默认值是 `0`),没有设置默认值的属性的初始值为 `Undefined`, 它们不会在 YAML 当中进行输出。 - -###### 不可变性 - -schema 中属性的不可变性遵循和全局变量不可变性一样的规则,只有 schema 中的可变属性可以在 schema 中修改。此外,schema 的属性默认值可被 schema 配置值修改: - -```python -schema Person: - age: int = 1 # Immutable attribute - _name: str = "Alice" # Mutable attribute - - age = 10 # Error, can't change the default value of the attribute `age` in the schema context. - _name = "Bob" # Ok - -person = Person { - age = 3 # Ok, can change the default value of the attribute `age` in the schema config. -} -``` - -###### 可选属性 - -schema 实例中每个属性 **必须** 赋值一个非 `None`/`Undefined` 的值,否则编译器会抛出错误,除非它被 `?` 符号标记为可选属性。 - -示例: - -```python -schema Employee: - bankCard: int # bankCard is a required attribute, and it can NOT be None or Undefined - nationality?: str # nationality is an optional attribute, and it can be None or Undefined - -employee = Employee { - bankCard = None # Error, attribute 'bankCard' of Employee is required and can't be None or Undefined - nationality = None # Ok -} -``` - -##### 顺序无关计算 - -schema 中顺序无关计算表示 schema 内部属性之间的引用关系。例如,当我们声明一个形式为 `a = b + 1` 的表达式时,`a` 值的计算依赖于 `b` 值的计算。当编译器计算 `a` 的值并且 `a` 的值取决于 `b` 的值时,编译器会选择先计算 `b` 的值,然后根据 `b` 的值计算 a 的值表达式 `a = b + 1`,这与传统过程语言的计算方法略有不同。 - -由于 schema 中值的计算是基于依赖关系的,就像有向无环图按照拓扑排序的顺序遍历图中的每个节点一样, schema 中属性的声明顺序并不那么重要,因此特征称为顺序无关计算。 - -请注意,不同 schema 属性值之间不能有循环引用。 - -我们可以通过下面的例子看到这个特性。 - -```python -schema Fib: - n1: int = n - 1 # Refers to the attribute `n` declared after `n1` - n2: int = n1 - 1 - n: int - value: int = 1 if n <= 2 else Fib {n = n1}.value + Fib {n = n2}.value - -fib8 = Fib {n = 8}.value -``` - -结果为: - -```yaml -fib8: 21 -``` - -在 schema 中,我们只需要简单的指定属性之间的依赖关系,编译器就会根据依赖关系自动计算出值,这样可以帮助我们节省大量的样板代码,减少配置编写难度。 - -##### Schema 上下文 - -我们可以定义 schema 的上下文来管理 schema 的属性,可以直接在 schema 中编写 schema 参数、临时变量和表达式等: - -```python -schema Person[_name: str]: # define a schema argument - name: str = _name # define a schema attribute - age: int = 10 # define a schema attribute with default value - hands: [int] = [i for i in [1, 2, 3]] # define a for statement -``` - -然后,我们可以通过如下代码实例化一个 `Person` 并将其赋值给 `alice` 变量: - -```python -alice = Person("alice") -``` - -可以得到如下 YAML 输出: - -```yaml -alice: - name: alice - age: 10 - hands: - - 1 - - 2 - - 3 -``` - -##### 校验 - -KCL 中为了确保代码稳定性,除了使用 **静态类型** (类型注解) 和 **不可变性**,还支持在 **check** 块中定义验证规则 (KCL 几乎原生支持所有 [OpenAPI](https://www.openapis.org/) 的验证能力): - -```python -import regex - -schema Sample: - foo: str - bar: int - fooList: [str] - - check: - bar > 0 # Minimum, also support the exclusive case - bar < 100 # Maximum, also support the exclusive case - len(fooList) > 0 # Min length, also support exclusive case - len(fooList) < 100 # Max length, also support exclusive case - regex.match(foo, "^The.*Foo$") # Regex match - isunique(fooList) # Unique - bar in range(100) # Range - bar in [2, 4, 6, 8] # Enum - multiplyof(bar, 2) # MultipleOf -``` - -使用 schema, 所有的实例将在编译时验证: - -```python -# Ok -goodSample = Sample { - foo = "The Foo" - bar = 2 - fooList = ["foo0", "foo1"] -} - -# Error: validation failure: Check failed on check conditions: bar < 100. -badSample = Sample { - foo = "The Foo" - bar = 123 - fooList = ["foo0", "foo1"] -} -``` - -此外,我们可以使用 **and**, **or**, **if** 来构建更复杂的检查逻辑: - -```python -schema Sample: - bar: int - foo: str - doCheck: bool - - check: - regex.match(foo, "^The.*Foo$") and bar in [2, 4, 6, 8] if doCheck -``` - -为了确保所有检查规则都能很好地发挥其相应的作用,我们可以通过编写 KCL 测试用例来测试不同数据组合的合理性和正确性,并通过 kcl test tool 运行所有测试用例。 - -##### 文档 - -通常在我们写好 schema 模型之后,我们会为 schema 写文档注释,可以用一个三引号字符串来完成,如下所示: - -```python -schema Server: - """Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - - Attributes - ---------- - workloadType : str, default is Deployment - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - name : str, default is None - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - labels : {str:str}, optional, default is None - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - - Examples - ---------------------- - myCustomApp = AppConfiguration { - name = "componentName" - } - """ - workloadType: str = "Deployment" - name: str - labels?: {str:str} -``` - -更多详细内容可见 Doc tools。 - -##### 配置 - -假设我们有如下 schema 定义: - -```python -schema Person: - firstName: str - lastName: str - labels?: {str:str} -``` - -可以用类 JSON 的表达式定义配置: - -```python -person = Person { - firstName = "firstName" - lastName = "lastName" -} -``` - -schema 遵循严格的属性定义,配置未定义的属性将触发编译错误: - -```python -person = Person { - firstName = "firstName" - lastName = "lastName" - fullName = "fullName" # Error: Cannot add member 'fullName' to schema 'Person', 'fullName' is not defined in schema 'Person' -} -``` - -此外,我们可以使用 `if` 表达式将元素动态的添加到 schema 实例中,将满足条件的元素添加到 schema 实例并忽略不满足条件的元素。并且除了使用一个 schema 类型实例化一个 schema,我们也可以通过 schema 实例得到一个新的实例。 - -```python -env = "prod" -person = Person { - firstName = "firstName" - lastName = "lastName" - if env == "prod": - labels.env = env - else: - labels.env = "other" -} -# We can use the person instance to get a new instance named `personx` directly. -personx = person { - firstName = "NewFirstName" -} -``` - -输出为: - -```yaml -env: prod -person: - firstName: firstName - lastName: lastName - labels: - env: prod -personx: - firstName: NewFirstName - lastName: lastName - labels: - env: prod -``` - -#### 高级功能 - -##### Protocol & Mixin - -除了 schema, 在 KCL 中还提供了一种额外的类型定义方式 `protocol`,它的性质如下: - -- 在 protocol 中,只能定义属性及其类型,不能书写复杂的逻辑与 check 表达式,也不能使用 mixin。 -- protocol 只能对非 `_` 开头的属性进行约束。 -- protocol 只能继承自或者引用 protocol, 不能继承自或者引用 schema。 - -此外,我们可以使用可选的 **mixin** 组装复杂的 schema,并使用 **protocol** 为 **mixin** 添加可选的宿主类型, 使用 `for` 关键字为 **mixin** 定义宿主类型,并且在 mixin 内部它将从宿主类型中查询到属性的类型。 - -```python -schema Person: - mixin [FullNameMixin] - - firstName: str # Required - lastName: str # Required - fullName?: str # Optional -``` - -FullNameMixin 是一个产生 fullName 字段的简单例子: - -```python -protocol PersonProtocol: - firstName: str - lastName: str - fullName?: str - -mixin FullNameMixin for PersonProtocol: - fullName = "{} {}".format(firstName, lastName) -``` - -然后我们可以通过一下方式获取 schema 实例: - -```python -person = Person { - firstName = "John" - lastName = "Doe" -} -``` - -输出结果为: - -```yaml -person: - firstName: John - lastName: Doe - fullName: John Doe -``` - -请注意,宿主类型 **protocol** 只能用于 **mixin** 的定义 (后缀名为 `Mixin`), 否则将会报错。 - -```python -protocol DataProtocol: - data: str - -schema Data for DataProtocol: # Error: only schema mixin can inherit from protocol - x: str = data -``` - -##### 索引签名 - -在 KCL schema 中可以定义索引签名,这意味着索引签名的键-值约束可用于构造具有 schema 类型的字典。或者可以将其他检查添加到额外的 schema 属性中,以增强 KCL 类型和语义检查。 - -###### 基本用法 - -使用 `[{attr_alias}: {key_type}]: {value_type}` 的形式去定义 schema 的类型注解, 其中 `{attr_alias}` 可以省略。 - -```python -schema Map: - """ - Map is a schema with a key of str type and a value of str type - """ - [str]: str # `{attr_alias}` can be omitted. - -data = Map { - key1 = "value1" - key2 = "value2" -} -``` - -###### 同时定义属性和索引签名 - -可以在 schema 中同时定义 schema 属性和索引签名,通常用于表示 schema 中额外属性的类型约束,比如如下代码 - -```python -schema Person: - name: str - age: int - [...str]: str # Except for the `name` and `age` attributes, the key type of all other attributes of the schema must be `str`, and the value type must also be `str`. -``` - -###### 定义索引签名别名 - -可以为索引签名定义类型注解的属性别名,并将其与检查块一起使用。 - -```python -schema Data: - [dataName: str]: str - check: - dataName in ["Alice", "Bob", "John"] # We can use the index signature key name in the check block. - -data = Data { - Alice = "10" - Bob = "12" - Jonn = "8" # Error: Jonn not in ["Alice", "Bob", "John"] -} -``` - -##### 继承 - -类似于其他面向对象语言,KCL 提供了基础且有限的面向对象支持,例如 **属性复用**,**私有和公有变量**和**单继承**。KCL 不支持多继承。 - -以下是单继承的例子: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 - -# An employee **is** a person, and has some additional information. -schema Employee(Person): - bankCard: int - nationality?: str - -employee = Employee { - firstName = "Bob" - lastName = "Green" - age = 18 - bankCard = 123456 -} -``` - -结果为: - -```yaml -employee: - firstName: Bob - lastName: Green - age: 18 - bankCard: 123456 - nationality: null -``` - -请注意,KCL 只支持 schema 的 **单继承**。 - -此外,当 schema 存在继承关系时,可选属性的性质如下: - -- 如果该属性在基类 schema 中是可选的,则它在子类 schema 中是可选的,也可以是子类 schema 中必选的。 -- 如果该属性在基类 schema 中是必选的,则它在子类 schema 中也是必选的。 - -```python -schema Person: - bankCard?: int - nationality: str - -schema Employee(Person): - bankCard: int # Valid, both `bankCard: int` and `bankCard?: int` are allowed - nationality?: str # Error, only `nationality: str` is allowed -``` - -##### Schema 函数 - -schema 映射到函数上非常好用;它可以有任意数量的输入和输出参数。 例如,Fibonacci 函数可以使用递归 schema 如下编写: - -```python -schema Fib[n: int]: - n1 = n - 1 - n2 = n - 2 - if n == 0: - value = 0 - elif n == 1: - value = 1 - else: - value = Fib(n1).value + Fib(n2).value - -fib8 = Fib(8).value # 21 -``` - -##### 装饰器 - -像 Python 一样, KCL 支持在 schema 上使用装饰器。KCL 装饰器动态地改变 schema 的功能,而不必直接使用子 schema 或更改被装饰的 schema 的源代码。 和函数调用一样,装饰器支持传入额外的参数。 - -内置的 schema 装饰器: - -- `@deprecated` - 标识 schema 或 schema 属性被废弃. `@deprecated` 装饰器支持三种参数: - - **version** - 字符串类型,表示版本信息。 默认值为空。 - - **reason** - 字符串类型,表示不推荐使用的原因。 默认值为空。 - - **strict** - bool 类型,表示是报错还是警告。 默认值是 true。 如果 `strict` 为 `True` 并且抛出错误,程序将被中断。 如果 `strict` 为 `False`,则会输出警告并且不会中断程序。 - -示例: - -```python -@deprecated -schema ObsoleteSchema: - attr: str - -schema Person: - firstName: str = "John" - lastName: str - @deprecated(version="1.16", reason="use firstName and lastName instead", strict=True) - name: str - attrs: ObsoleteSchema = { # Error: ObsoleteSchema was deprecated - attr = "value" - } - -JohnDoe = Person { # Error: name was deprecated since version 1.16, use firstName and lastName instead - name = "deprecated" -} -``` - -- `@info` - 给 schema 或 schema 属性标识额外的信息,支持任意参数,用于语言静态分析 schema 或 schema 属性的扩展标记信息 - -示例: - -```python -@info(version="v1") -schema Person: - @info(message="name") - name: str - age: int -``` - -请注意,当前版本的 KCL 尚不支持用户自己定义装饰器。 - -##### 成员函数 - -内置函数和 schema 成员 - -- instances() - 返回 schema 的现有实例列表。 - -```python -schema Person: - name: str - age: int - -alice = Person { - name = "Alice" - age = 18 -} - -bob = Person { - name = "Bob" - age = 10 -} - -aliceAndBob = Person.instances() # Person is a schema type, instances() is its member method -``` - -输出为: - -```yaml -alice: - name: Alice - age: 18 -bob: - name: Bob - age: 10 -aliceAndBob: - - name: Alice - age: 18 - - name: Bob - age: 10 -``` - -### 配置操作 - -#### 配置合并 - -##### | 运算符 - -在 KCL 中,我们可以使用合并运算符 `|` 来合并配置。union 运算符支持的类型包括如下: - -```txt -SchemaInstance | SchemaInstance -SchemaInstance | Dict -Dict | Dict -List | List -``` - -合并集合和结构化数据: - -- 合并 List。使用 `|` 运算符右边的列表表达式按照**索引**逐一覆盖左边列表表达式中的元素。 - -```python -_a = [1, 2, 3] -_b = [4, 5, 6, 7] -x = _a | _b # [4, 5, 6, 7] 1 -> 4; 2 -> 5; 3 -> 6; Undefined -> 7 -``` - -合并特定索引或所有元素仍在讨论中。 - -- 合并 Dict. 使用 `|` 运算符右边的列表表达式按照**键**逐一覆盖左边列表表达式中的元素。 - -```python -_a = {key1 = "value1"} -_b = {key1 = "overwrite", key2 = "value2"} -x = _a | _b # {"key1": "overwrite", "key2": "value2"} -``` - -集合和 schema 的合并是一个新的集合,其属性是将 b 合并到 a,保留从左到右的操作数顺序。 - -- 合并 schema。Schema 的合并与 dict 相似。 - -Schema 的合并操作如下: - -```python -schema Person: - firstName?: str - lastName?: str - -_a = Person { - firstName = "John" -} -_b = {lastName = "Doe"} -_c = _a | _b # {"firstName": "John", "lastName": "Doe"} -_d = _a | None # {"firstName": "John"} -_e = _a | Undefined # {"firstName": "John"} -_f = None | _a # {"firstName": "John"} -_g = Undefined | _a # {"firstName": "John"} -``` - -请注意,当 union 运算符的左右操作数之一为 None 时,将立即返回另一个操作数。 - -```python -data1 = {key = "value"} | None # {"key": "value"} -data2 = None | [1, 2, 3] # [1, 2, 3] -data3 = None | None # None -``` - -输出如下: - -```yaml -data1: - key: value -data2: - - 1 - - 2 - - 3 -data3: null -``` - -##### : 运算符 - -模式: `identifier : E` - -表达式 `E` 的值将被合并到元素值。 - -示例: - -```python -schema Data: - labels: {str:} = {key1 = "value1"} - -data = Data { - # union {key2: "value2"} into the attribute labels of the schema Data. - labels: {key2 = "value2"} -} -``` - -输出: - -```yaml -data: - labels: - key1: value1 - key2: value2 -``` - -除了在 schema 属性上使用属性运算符之外,还可以使用属性运算符对配置块执行不同的操作。 - -- schema 外部使用合并运算符 `:` - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - data: Data - -# This is one configuration that will be merged. -config: Config { - data.d1 = 1 -} -# This is another configuration that will be merged. -config: Config { - data.d2 = 2 -} -``` - -与它等效的配置代码可以表示为: - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - data: Data - -config: Config { - data.d1 = 1 - data.d2 = 1 -} -``` - -输出结果为: - -```yaml -config: - data: - d1: 1 - d2: 1 -``` - -- schema 内部使用合并运算符 `:` - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - # This is one configuration that will be merged. - data: Data { - d1 = 1 - } - # This is another configuration that will be merged. - data: Data { - d2 = 1 - } - -config: Config {} -``` - -#### 配置覆盖 - -##### = 运算符 - -模式: `identifier = E` - -表达式 `E` 的值将覆盖元素值。 - -示例: - -```python -schema Data: - labels: {str:} = {key1 = "value1"} - -data = Data { - # override {key2: "value2"} into the attribute labels of the schema Data. - labels = {key2 = "value2"} -} -``` - -输出: - -```yaml -data: - labels: - key2: value2 -``` - -请注意,可以使用 `Undefined` 来覆盖,来“删除”内容。例如 `{ a = Undefined }`。 - -#### 配置添加 - -##### += 运算符 - -模式: `identifier += E` - -插入只能用于列表类型的 `identifier`. - -`E` 将插入到列表 `identifier` 指定索引后,并且索引以后的属性将自动后移。 - -示例: - -```python -schema Data: - labels: {str:} = {key1 = [0]} - -data = Data { - # insert [1] into the attribute labels.key1 of the schema Data. - labels: {key1 += [1]} -} -``` - -输出: - -```yaml -data: - labels: - key1: - - 0 - - 1 -``` - -如果没有定义索引,将使用最后一个索引。 - -#### 注意事项 - -合并运算符 `:` 是一个可交换的幂等运算符,当合并的值发生值的冲突时会发生值冲突错误,因此我们需要 `=` 和 `+=` 运算符表示配置的覆盖,添加和删除操作。 - -```python -data0 = {id: 1} | {id: 2} # Error:conflicting values between {'id': 2} and {'id': 1} -data1 = {id: 1} | {id = 2} # Ok, the value of `data` is {"id": 2} -``` - -`:` 运算符冲突检查的规则如下: - -- `None` 和 `Undefined` 不与任何值冲突 - -```python -data0 = None | {id: 1} # Ok -``` - -- 对于 `int`、`float`、`str` 和 `bool` 类型的变量,当它们的值不相同时发生冲突错误。 - -```python -data0 = 1 | 1 # Ok -data1 = 1 | "s" # Error -``` - -- 对于列表类型 - - 当它们的长度不相同时,它们被认为是冲突的 - - 当它们的长度相同时,当且仅当它们的任意一个子元素值冲突时,它们自身是冲突的 - -```python -data0 = [1] | [1] # Ok -data1 = [1, 2] | [1] # Error -``` - -- 对于 dict/schema 类型 - - 对于相同的 key,key 的值冲突时,它们自身是冲突的,否则是不冲突的 - -```python -data0 = {id: 1} | {id: 1} # Ok -data1 = {id: 1} | {id: 2} # Error -data1 = {id: 1} | {idAnother: 1} # Ok -``` - -### Rule - -KCL 支持使用 rule 关键字定义校验块,可用于数据校验,用法类似于 schema 中的 check 表达式。 - -```python -rule SomeRule: - age > 0, "rule check failure message" -``` - -可以像 schema 实例化那样调用一个 rule 进行校验 - -```python -age = 0 -name = "Bob" -rule SomeRule: - age > 0, "rule check failure message" - name == "Alice" - -rule1 = SomeRule() # Rule call -rule2 = SomeRule {} -``` - -可以使用 protocol 和 for 绑定语句为 rule 增加类型约束: - -```python -# Schema definition -protocol Service: - clusterIp: str - $type: str - -# Schema definition -protocol Volume: - mountPath: [str] - -# Protocol -protocol SomeProtocol: - id: int - env: {str: any} - services: [Service] - volumes: [Volume] - -rule SomeChecker for SomeProtocol: - id > 0, "id must >0" - - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - } - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } - -# Call rule to check with config parameter -SomeChecker { - id = 1 - env = { - MY_ENV = "MY_ENV_VALUE" - } - services = [ - { - type = "ClusterIP" - clusterIP = "NONE" - } - ] - volumes = [ - { - mountPath = "/home/admin" - } - { - mountPath = "/home/myapp" - } - ] -} -``` - -请注意,`protocol` 和 `rule` 的组合方式可以使属性和其约束定义进行分离,我们可以在不同的包中定义不同的 `rule` 和 `protocol` 按需进行组合,这与 schema 中的 check 表达式只能与 schema 属性定义在一起是不同的。 - -此外,有两种复用不同 rule 的方式 - -- 直接调用 - -```python -weather = "sunny" -day = "wednesday" - -rule IsSunny: - weather == "sunny" - -rule IsWednesday: - day == "wednesday" - -rule Main: - IsSunny() # Rule inline call - IsWednesday() # Rule inline call - -Main() # Rule call -``` - -使用 rule 的继承 (rule 不同于 schema, 可以多继承混用) - -```python -weather = "sunny" -day = "wednesday" - -rule IsSunny: - weather == "sunny" - -rule IsWednesday: - day == "wednesday" - -rule Main(IsSunny, IsWednesday): - id == 1 - -Main() -``` - -可以使用 option 函数与命令行 `-D` 参数获得外部数据进行校验 - -- 一个简单例子 - -```python -schema Day: - day: str - homework: str - -days: [Day] = option("days") - -rule Main: - filter d in days { - d.day not in ["saturday", "sunday"] and d.homework - } - -Main() -``` - -- 一个复杂例子 - -```python -data = option("data") -input = option("input") - -rule Allow: - UserIsAdmin() - any grant in UserIsGranted() { - input.action == grant.action and input.type == grant.type - } - -rule UserIsAdmin: - any user in data.user_roles[input.user] { - user == "admin" - } - -rule UserIsGranted: - [ - grant - for role in data.user_roles[input.user] - for grant in data.role_grants[role] - ] - -allow = Allow() or False -``` - -### 模块 - -KCL 配置文件以 **模块** 形式组织。 单个 KCL 文件被认为是一个 module,一个目录被认为是一个包。 - -同一个包内的模块是可见的,跨包引用需要通过导入可见。 - -```bash -. -└── root - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -model1.k: - -```python -# schema CatalogItem in model1.k - -schema CatalogItem: - id: int - image: CatalogItemImage # CatalogItemImage is defined in the module of the same package e.g., model2.k in package model - title: str -``` - -service1.k: - -```python -import ..model as model # cross-package references - -schema ImageService: - image: model.CatalogItemImage # CatalogItemImage is imported from another package e.g., model2.k in package model - name: str -``` - -#### 相对路径引用 - -我们可以使用 `.` 运算符来实现 KCL 入口文件的相对路径导入。 - -main.k: - -```python -import .model1 # Current directory module -import ..service # Parent directory -import ...root # Parent of parent directory - -s = service.ImageService {} -m = root.Schema {} -``` - -#### 绝对路径引用 - -`import a.b.c.d` 的语义为: - -1. 如果 `kcl.mod` 文件不存在,将当前目录作为包的根路径,并从当前目前查找 `a/b/c/d` 路径 -2. 如果 `kcl.mod` 文件存在,从 `ROOT_PATH/a/b/c/d` 查找,否则抛出一个导入错误 - -根路径 `ROOT_PATH` 的定义为: - -从当前目录或者父级目录中查找 `kcl.mod` 文件对应的目录。 - -```bash -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -main.k: - -```python -import service # `root package` and `kcl.mod` are in the same directory -import mixin # `root package` and `kcl.mod` are in the same directory - -myModel = model.CatalogItem {} -``` - -请注意,对于 KCL 入口文件 `main.k`,不能导入所在文件夹,否则会出现递归导入错误: - -```python -import model # Error: recursively loading -``` - -### 动态参数 - -假设某些字段需要像用户输入一样动态传入,我们可以在模块中定义一个动态参数: - -```python -bankCard = option("bankCard") # Get bankCard through the option function. -``` - -我们可以如下使用 module: - -```bash -kcl employee.k -D bankCard=123 -``` - -目前,支持顶级参数的类型有数字、字符串、布尔、列表和字典。 - -```bash -kcl main.k -D list_key='[1,2,3]' -D dict_key='{"key":"value"}' -``` - -请注意,命令行中引号 `"` 等符号需要使用 `\` 进行转义 - -#### Setting 文件形式的参数 - -此外,它还支持输入一个 YAML 文件作为顶级参数。 - -```yaml -kcl_options: - - key: key_number - value: 1 - - key: key_dict - value: - innerDictKey: innerDictValue - - key: key_list - value: - - 1 - - 2 - - 3 - - key: bankCard - value: 123 -``` - -```bash -kcl -Y setting.yaml employee.k -``` - -此外,setting 文件还支持配置命令行编译参数如下: - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - disable_none: true - strict_range_check: true - debug: 1 - verbose: 1 - sort_keys: true - output: ./stdout.golden - overrides: - - app.image=new_image - path_selector: - - config - package_maps: - k8s: /Users/.kcl/kpm/k8s_1.24 -kcl_options: - - key: image - value: docker.io/kcllang/kcl:latest -``` - -KCL CLI -Y 参数还支持多文件配置,并支持编译参数和顶级参数的单独写入与合并。 - -```bash -kcl -Y compile_setting.yaml option_setting.yaml -``` - -- `compile_setting.yaml` - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - disable_none: true - strict_range_check: true - debug: 1 - verbose: 1 - output: ./stdout.golden -``` - -- `option_setting.yaml` - -```yaml -kcl_options: - - key: image - value: docker.io/kcllang/kcl:latest -``` - -我们可以使用以下指令获取每个参数的含义 - -```bash -kcl --help -``` - -#### Option Functions - -我们可以在 KCL 代码中使用 `option` 获取顶级参数。 - -```python -value = option(key="key", type='str', default="default_value", required=True, help="Set key value") -``` - -参数 - -- **key**: 参数的键。 -- **type**: 要转换的参数类型。 -- **default**: 参数默认值。 -- **required**: 当未提供参数且参数的 required 为 True 是报告错误。 -- **help**: 帮助信息。 - -### 多文件编译 - -除了上面的 KCL 单文件执行之外,我们还可以使用以下命令同时编译多个 KCL 入口文件: - -```bash -kcl main_1.k main_2.k ... main_n.k -``` - -main_1.k - -```python -a = 1 -b = 2 -``` - -main_2.k - -```python -c = 3 -d = 4 -``` - -输出结果为: - -```yaml -a: 1 -b: 2 -c: 3 -d: 4 -``` - -利用**多文件编译**,我们可以组合多个 KCL 文件,而无需使用 import 管理文件。 我们来看一个结合**多文件编译**和 **schema 实例**的例子。 - -model.k - -```python -schema Model: - name: str - labels?: {str:} - annotations?: {str:} - replicas: int - -_model1 = Model { - name = "model1" - labels.key1 = "value1" - labels.key2 = "value2" - annotations.key = "value" - replicas = 2 -} - -_model2 = Model { - name = "model2" - replicas = 3 -} -``` - -backend.k - -```python -import yaml - -schema Backend: - apiVersion: str = "v1" - kind: str = "Deployment" - metadata: {str:} - spec: {str:} = { - minReadySeconds = 0 - paused = False - progressDeadlineSeconds = 600 - replicas = 1 - revisionHistoryLimit = 10 - selector = {} - } - -_backends = [Backend { - metadata.name = model.name - metadata.labels = model.labels - metadata.annotations = model.annotations - spec.selector.matchLabels: model.labels - spec.replicas = model.replicas -} for model in Model.instances()] # Schema Model is defined in model.k -print("---\n".join([yaml.encode(_b, ignore_private=True) for _b in _backends])) -``` - -命令为: - -```bash -kcl model.k backend.k -``` - -输出为: - -```yaml -apiVersion: v1 -kind: Deployment -metadata: - name: model1 - labels: - key1: value1 - key2: value2 - annotations: - key: value -spec: - minReadySeconds: 0 - paused: false - progressDeadlineSeconds: 600 - replicas: 2 - revisionHistoryLimit: 10 - selector: - matchLabels: - key1: value1 - key2: value2 ---- -apiVersion: v1 -kind: Deployment -metadata: - name: model2 -spec: - minReadySeconds: 0 - paused: false - progressDeadlineSeconds: 600 - replicas: 3 - revisionHistoryLimit: 10 - selector: {} -``` - -### KCL 变量查询 - -我们可以在 KCL CLI 使用 `-S|--path-selector` 参数从 KCL 模型中查询一个或多个值。 - -变量查询形式如下: - -`var.name` - -#### 示例 - -Code structure: - -```bash -. -├── kcl.mod -└── main.k - └── pkg - └── model.k -``` - -pkg/model.k: - -```python -schema Person: - name: str - age: int - -var = Person { - name = "Alice" - age = 18 -} -``` - -main.k - -```python -import pkg - -var = pkg.Person { - name = "Bob" - age = 10 -} -``` - -命令为: - -```bash -kcl main.k -S var -``` - -输出结果为: - -```yaml -var: - name: Bob ---- -var: - name: Alice - age: 18 -``` - -### KCL 变量修改 - -除了变量查询,KCL 还允许我们通过 KCL CLI 的 `-O|--overrides` 参数直接修改配置模型中的值。 - -变量修改参数的使用与变量查询类似,参数包含三部分,如 `pkg`、`identifier`、`attribute` 和 `override_value` . - -```bash -kcl main.k -O override_spec -``` - -- `override_spec`: 表示需要修改的配置模型字段和值的统一表示 - -```txt -override_spec: [[pkgpath] ":"] identifier ("=" value | "-") -``` - -- `pkgpath`: 表示需要修改标识符的包路径,通常为 `a.b.c` 的形式,对于 main 包,`pkgpath` 表示为 `__main__`, 可省略,省略不写时表示 main 包 -- `identifier`: 表示需要修改配置的标识符,通常为 `a.b.c` 的形式 -- `value`: 表示需要修改配置的值,可以是任意合法的 KCL 表达式,比如数字/字符串字面值,list/dict/schema 表达式等 -- `=`: 表示修改identifier的值 - - 当 identifier 存在时,修改已有 identifier的值为 value - - 当 identifier 不存在时,添加 identifier属性,并将其值设置为 value -- `-`: 表示删除 identifier属性 - - 当 identifier 存在时,直接进行删除 - - 当 identifier 不存在时,对配置不作任何修改 - -请注意,当 `identifier` 出现多次时,修改/删除全部 `identifier` 的值 - -此外,在 KCL 中还提供了 API 用于变量查询和修改,详见 [API 文档](../xlang-api/go-api.md) - -#### 示例 - -##### 修改示例 - -KCL 代码: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -``` - -命令为: - -```bash -kcl main.k -O :person.name=Bob -O :person.age=10 -``` - -输出结果为: - -```yaml -person: - name: Bob - age: 10 -``` - -此外,当我们使用 KCL CLI `-d` 参数时,KCL 文件将同时修改为以下内容 - -```bash -kcl main.k -O :person.name=Bob -O :person.age=10 -d -``` - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Bob" - age = 10 -} -``` - -##### 删除示例 - -KCL 代码: - -```python -schema Config: - x?: int = 1 - y?: str = "s" - -config = Config { - x = 2 -} -``` - -命令为: - -```bash -kcl main.k -O config.x- -``` - -输出结果为: - -```yaml -config: - x: 1 - y: s -``` - -### 总结 - -本页总结了 KCL 语言中的常用功能。 KCL 作为一种新的语言,会根据配置场景的需求,逐步增加功能特性。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/types/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/types/_category_.json deleted file mode 100644 index a8f40915..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/types/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "类型系统", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/types/types.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/types/types.md deleted file mode 100644 index 182ffaf2..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/types/types.md +++ /dev/null @@ -1,1401 +0,0 @@ -# 类型系统 - -本文档描述 KCL 的类型系统,包括: - -- 类型规则 -- 类型检查 -- 类型转换 -- 类型推导 - -## 类型规则 - -### 基础定义 - -#### 断言 - -$S$ 的所有自由变量都定义在 $\Gamma$ 中 - -$$ -\Gamma \vdash S -$$ - -$\Gamma$ 是一个变量的类型声明环境(well-formed environment),如:$x_1:T_1$, ..., $x_n:T_n$ - -$S$ 的断言有三种形式: - -**环境断言** 断言表示 $\Gamma$ 是良构类型 (well-formed type) - -$$ -\Gamma \vdash ◇ -$$ - -**良构类型断言** 在环境 $\Gamma$ 下,$nat$ 是类型表达式 - -$$ -\Gamma \vdash nat -$$ - -**类型判断断言** 在环境 $\Gamma$ 下,$E$ 具有类型 $T$ - -$$ -\Gamma \vdash E: T -$$ - -#### 推理规则 - -表示法 - -$$ -\frac{\Gamma \vdash S_1, ..., \Gamma \vdash S_n}{\Gamma \vdash S} -$$ - -推理规则中的 $u$, $v$, $w$ 用于表示变量,$i$, $j$, $k$ 用于表示整数,$a$, $b$ 用于表示浮点数,$s$ 用于表示字符串,$c$ 代表常量(整数、浮点数、字符串、布尔)的字面值, $f$ 用于表示函数, $T$, $S$, $U$ 用于表示类型。 - -## 环境规则 - -Env ⌀ - -$$ -\frac{}{⌀ \vdash ◇ } -$$ - -## 类型定义 - -Type Bool - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash boolean} -$$ - -Type Int - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash integer} -$$ - -Type Float - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash float} -$$ - -Type String - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash string} -$$ - -Type Literal - -$$ -\frac{ c \in \{boolean, integer, float, string\}}{\Gamma \vdash literalof(c)} -$$ - -Type List - -$$ -\frac{\Gamma \vdash T \ T \neq Void}{\Gamma \vdash listof(T) } -$$ - -Type Dict - -$$ -\frac{\Gamma \vdash T_1 \ \Gamma \vdash T_2\ T_1 \neq Void \ \ T_2 \neq Void}{\Gamma \vdash dictof(T_k=T_1, T_v=T_2)} -$$ - -Type Struct - -$$ -\frac{\Gamma \vdash T_{1} \ ... \ \Gamma \vdash T_{n} \ \ T_i \neq Void \ K_1 \neq K_n}{\Gamma \vdash structof(K_1 : T_{1}, ... , K_n : T_{n})} -$$ - -Type Union - -$$ -\frac{\Gamma \vdash T_1 \ ... \ \Gamma \vdash T_n \ \ T_i \neq Void}{\Gamma \vdash unionof(T_1, ..., T_n)} -$$ - -Type None - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash None} -$$ - -Type Undefined - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Undefined} -$$ - -Type Void - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Void} -$$ - -Type Any - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Any} -$$ - -Type Nothing - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Nothing} -$$ - -## 类型判断规则 - -### Operand Expr - -Exp Truth - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash true: boolean} -$$ - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash false: boolean} -$$ - -Exp Int - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash int: integer} -$$ - -Exp Flt - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash flt: float} -$$ - -Exp Str - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash str: string} -$$ - -Exp None - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash none: none} -$$ - -Exp Undefined - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash undefined: undefined} -$$ - -Expr ListExp - -$$ -\frac{\Gamma \vdash E_1: T_1 \ E_2: T_2 \ ... \ E_n: T_n}{\Gamma \vdash [E_1, E_2, ..., E_n]: listof \ sup(T_1, T_2, ..., T_n)} -$$ - -Expr ListComp - -$$ -\frac{\Gamma \vdash E_1: T_1 \ \Gamma \vdash v: T \ \Gamma \vdash E_2: listof \ T \ \Gamma \vdash E_3: boolean}{\Gamma \vdash [E_1 \ for \ v \ in \ E_2 \ if \ E_3]: listof(T_1) } -$$ - -Expr DictExp - -$$ -\frac{\Gamma \vdash E_{k1}: T_{k1} \ \Gamma \vdash E_{v1}: T_{v1} \ ... \ \Gamma \vdash E_{kn}: T_{kN} \ \Gamma \vdash E_{vn}: T_{vN}}{\Gamma \vdash \{E_{k1}: E_{v1}, ..., E_{{kn}}: E_{vn}\}: dictof(T_{k}=sup(T_{k1}, T_{k2}, ... T_{kn}), \ T_{v}=sup(T_{v1}, T_{v2}, ..., T_{vn}))} -$$ - -Expr DictComp - -$$ -\frac{\Gamma \vdash E_1: T_{rki} \ \Gamma \vdash E_2: T_{rvi} \ \Gamma \vdash v_1: T_k \ \Gamma \vdash v_2: T_v \ \Gamma \vdash E_3: dictof(T_{k}, \ T_{v}) \ \Gamma \vdash E_4: boolean}{\Gamma \vdash \{E_1:E_2 \ for \ (v_1, v_2) \ in \ E_3 \ if \ E_4\}: dictof(T_{k}=sup(T_{rk1}, T_{rk2}, ..., T_{rkn}), T_{v}=sup(T_{rv1}, T_{rv2}, ..., T_{rvn})) } -$$ - -Expr StructExpr - -$$ -\frac{\Gamma \vdash E_{1}: T_{1} \ ... \ \Gamma \vdash E_{n}: T_{n} \ K_1 \neq K_n}{\Gamma \vdash \{K_{1} = E_{1}, ..., K_{{n}} = E_{n}\}: structof(K_1 : T_{1}, ... , K_n : T_{n})} -$$ - -Literal 类型是基础类型的值类型,Union 类型是类型的组合类型,Void、Any、Nothing 是特殊的类型指代,本身没有直接的值表达式对应关系。 - -### Primary Expr - -Expr Index - -$$ -\frac{\Gamma \vdash E: listof(T) \ \Gamma \vdash Index: integer}{\Gamma \vdash E[Index]: T} -$$ - -Expr Call - -$$ -\frac{\Gamma \vdash E_1: T_1 \rightarrow T_2 \ \Gamma \vdash E_2: T_1}{\Gamma \vdash E_1 \ (E_2): T_2} -$$ - -Expr List Selector - -$$ -\frac{\Gamma \vdash E: listof(T) \ \Gamma \vdash Index: integer}{\Gamma \vdash E.[Index]: T} -$$ - -Expr Dict Selector - -$$ -\frac{\Gamma \vdash E: dictof(T_k = T_1, T_v=T_2) \ \Gamma \vdash S_1: string \ ... \ \Gamma \vdash S_n: string}{\Gamma \vdash E.\{S_1, ..., S_n\}: dictof(T_k = T_1, T_v=T_2)} -$$ - -Expr Struct Selector - -$$ -\frac{\Gamma \vdash E: structof(K_1 : T_{1}, ... , K_n : T_{n}) \ \Gamma \vdash K_i: string}{\Gamma \vdash E.K_i: T_{i}} -$$ - -### Unary Expr - -Expr + - -$$ -\frac{\Gamma \vdash E: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash \ +E: T} -$$ - -Expr - - -$$ -\frac{\Gamma \vdash E: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash \ -E: T} -$$ - -Expr ~ - -$$ -\frac{\Gamma \vdash E: integer}{\Gamma \vdash \ ~E: integer} -$$ - -Expr not - -$$ -\frac{\Gamma \vdash E: boolean}{\Gamma \vdash \ not \ E: boolean} -$$ - -### Binary Expr - -算数运算符 - -Expr op, op $\in$ {-, /, %, \*\*, //} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash E_1 \ op \ E_2: T} -$$ - -Expr + - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, float, string, listof(T_1)\}}{\Gamma \vdash E_1 \ + \ E_2: T} -$$ - -Expr \* - -$$ -\frac{\Gamma \vdash E_1: T_1 \ \ \ \Gamma \vdash E_2: T_2 \ \ \ \ (T_1==T_2 \in \{integer, float\}) \ or \ (T_1 == interger \ and \ T_2 \ \in \ \{string, listof(T_3)\}) \ or \ (T_2 == interger \ and \ T_1 \ \in \ \{string, listof(T_3)\})} {\Gamma \vdash E_1 \ * \ E_2: T} -$$ - -示例 - -Expr % - -$$ -\frac{\Gamma \vdash E_1: interger \ \ \ \Gamma \vdash E_2: integer}{\Gamma \vdash E_1 \ \% \ E_2: interger} -$$ - -逻辑运算符 - -Expr op, op $\in$ \{or, and\} - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ op \ E_2: boolean} -$$ - -示例 - -Expr and - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ and \ E_2: boolean} -$$ - -比较运算符 - -Expr op, op $\in$ \{==, !=, <, >, <=, >=\} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T}{\Gamma \vdash E_1 \ op \ E_2: boolean} -$$ - -示例 - -Expr > - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ > \ E_2: boolean} -$$ - -位运算符 - -Expr op, op $\in$ {&, ^, ~, <<, >>} - -$$ -\frac{\Gamma \vdash E_1: integer \ \ \ \Gamma \vdash E_2: integer}{\Gamma \vdash E_1 \ op \ E_2: integer} -$$ - -Expr | - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, listof(T_1), dictof(T_k, T_v), structof(K_1=T_1, ..., K_n=T_n)\}}{\Gamma \vdash E_1 \ | \ E_2: T} -$$ - -成员运算符 - -Expr op, op $\in$ {in, not in} - -$$ -\frac{\Gamma \vdash E_1: string \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{dictof, structof\}}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -Expr op, op $\in$ {in, not in} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: listof(S), T \sqsubseteq S}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -身份运算符 - -Expr op $\in$ {is, is not} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -### IF Expr - -Expr If - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: T \ \ \ \Gamma \vdash E_3: T}{\Gamma \vdash if \ E_1 \ then \ E_2 \ else \ E_3: T} -$$ - -### Stmt - -Stmt If - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash S_1: Void \ \ \ \Gamma \vdash S_2: Void}{\Gamma \vdash if \ E_1 \ then \ S_1 \ else \ S_2: Void} -$$ - -Stmt Assign - -$$ -\frac{\Gamma \vdash id: T_0 \ \ \ \Gamma \vdash T_1 \ \ \ \Gamma \vdash E: T_2}{\Gamma \vdash id: T_1 \ = \ E : Void} -$$ - -Type Alias - -$$ -\frac{\Gamma \vdash id: T_0 \ \ \ \Gamma \vdash T_1}{\Gamma \vdash type \ id \ = \ T_1 : Void} -$$ - -## Union - -### Union 规则 - -List Union - -$$ -\frac{\Gamma \vdash \ listof(T) \ \ \ \Gamma \vdash \ listof(S)}{\Gamma \vdash \ listof(unionof(T, S))} -$$ - -Dict Union - -$$ -\frac{\Gamma \vdash \ dictof(T_1, T_2) \ \ \ \Gamma \vdash \ dictof(S_1, S_2)}{\Gamma \vdash \ dictof(unionof(T_1, S_1), unionof(T_2, S_2))} -$$ - -Struct Union - -给定两个结构体 $structof(K_{1}: T_{1}, ..., K_{n}: T_{n}),structof(H_{1}: S_{1}, ..., H_{m}: S_{n})$ - -定义他们的 union 类型: - -$$ -structof(J_{1}: U_{1}, ..., J_{p}: U_{n}) = structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \bigcup structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) -$$ - -例如: - -$$ -structof() \ \bigcup \ structof(H_{1}: T_{1}, ..., H_{m}: T_{n}) = structof(H_{1}: T_{1}, ..., H_{m}: T_{n}) -$$ - -$$ -structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \ \bigcup \ structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) = structof(K_1: T_1) :: (structof(K_{2}: T_{2}, ..., K_{n}: T_{n}) \ \bigcup \ structof(H_{1}: S_{1}, ..., H_{m}: S_{n})) -$$ - -其中把 "::" 表示把一个对偶加入到一个结构的操作,定义如下: - -$$ -structof(K_{1}: T_{1}) :: structof() = structof(K_{1}: T_{1}) -$$ - -$$ -structof(K_{1}: T_{1}) :: structof(K_{1}: T_{1}', ..., K_n: T_{n}) = structof(K_{1}: union\_op(T_{1}, T_{1}'), ..., K_{n}: T_{n}) -$$ - -$$ -structof(K_{1}: T_{1}) :: structof(K_{2}: T_{2}, ..., K_n: T_{n}) = structof(K_{2}: T_2) :: structof(K_{1}: T_1) :: structof(K_{3}: T_3, ..., K_{n}: T_{n}) -$$ - -基于此,两个 Struct 的 union 定义为: - -$$ -\frac{\Gamma \vdash structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \ \Gamma \vdash structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) \ structof(J_{1}: U_{1}, ..., J_{p}: U_{n}) = structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \bigcup structof(H_{1}: S_{1}, ..., H_{m}: S_{n})}{\Gamma \vdash structof(J_{1}: U_{1}, ..., J_{p}: U_{n}))} -$$ - -其中 $union\_op(T_1, T_2)$ 表示对相同 $K_i$ 的不同类型的判断操作: - -- 当 $T_1$ 与 $T_2$ 有偏序关系时, 如果 $T_1 \sqsubseteq T_2$ 时,返回 $T_2$,否则返回 $T_1$,即取最小上界 -- 当 $T_1$ 与 $T_2$ 不存在偏序关系时,有三种可选的处理逻辑: - - 结构体 union 失败,返回 type_error - - 返回后者的类型,此处为 $T_2$ - - 返回类型 $unionof(T_1, T_2)$ - -此处需要根据实际需求选择适当的处理方式。 - -结构体继承可以看做一种特殊的 union,整体逻辑与 union 相似,但在 $union\_op(T_1, T_2)$ 中对相同 $K_i$ 的不同类型的判断操作如下: - -- 当 $T_1$ 与 $T_2$ 有偏序关系且 $T_1 \sqsubseteq T_2$ 时,返回 $T_1$,即仅当 $T_1$ 是 $T_2$ 的下界时以下界 $T_1$ 为准 -- 否则返回 type_error - -通过这样的继承设计可以实现分层的、自下而上逐层收缩的类型定义。 - -## Operation - -KCL 支持对结构体属性进行如 `p op E` 形式的操作。 即对给定结构体 $A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})$, 对结构体中的路径 `p` 以 `E` 的值进行指定的操作(如 union,assign,insert 等)。 - -定义如下更新操作: - -$$ -\frac{{\Gamma\vdash A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})}  {\Gamma\vdash p \in (K_{1}, ..., K_{n})} \ {\Gamma\vdash e:T}   k \neq k_1, ..., k \neq k_n} -{ A \{p \ op \ e\}:\{K_1:T_1, ..., K_n:T_n\}∪\{p:T\}} -$$ - -即对路径 $p$ 进行操作本质上是对两个结构体的一种 union,对同名属性类型 union 时的规则根据情况而定。例如路径 $p$ 是一个可用作字段名的标识符 $p=k_1$,并且结构体 A 中字段名也是 $k_1$,它的类型为 $T_1$,并且表达式 $e$ 的类型也为 $T_1$ ,那么 - -$$ -\frac{{\Gamma\vdash A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})}  {\Gamma\vdash p = K_{1}} \ {\Gamma\vdash e:T_1}   k \neq k_1, ..., k \neq k_n} -{ A \{p \ op \ e\}:\{K_1:T_1, ..., K_n:T_n\}} -$$ - -注意: - -- 此处表达式 $e$ 的类型 $T_1$ 同原先同名属性 $K_1$ 的具有相同的类型。可根据实际情况需要适当放松,如 $e$ 的类型 $\sqsubseteq T_1$ 即可。 -- 对于多层结构体嵌套的操作,递归的使用以上规则即可。 - -## 类型偏序 - -### 基础类型 - -$$ -Type \ T \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ T -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Bool \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Int \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Float \sqsubseteq Type \ Any -$$ - -$$ -Type \ Int \sqsubseteq Type \ Float -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ String \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Literal \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ List \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Dict \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Struct \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ None \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Void \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Any -$$ - -### 字面值类型 - -$$ -Type \ Literal(Bool) \sqsubseteq Type \ Bool -$$ - -$$ -Type \ Literal(Int) \sqsubseteq Type \ Int -$$ - -$$ -Type \ Literal(Float) \sqsubseteq Type \ Float -$$ - -$$ -Type \ Literal(String) \sqsubseteq Type \ String -$$ - -### 联合类型 - -$$ -Type \ X \sqsubseteq Type \ Union(X, Y) -$$ - -### 自反 - -$$ -Type \ X \sqsubseteq Type \ X -$$ - -示例 - -$$ -Type \ Bool \sqsubseteq Type \ Bool -$$ - -$$ -Type \ Int \sqsubseteq Type \ Int -$$ - -$$ -Type \ Float \sqsubseteq Type \ Float -$$ - -$$ -Type \ String \sqsubseteq Type \ String -$$ - -$$ -Type \ List \sqsubseteq Type \ List -$$ - -$$ -Type \ Dict \sqsubseteq Type \ Dict -$$ - -$$ -Type \ Struct \sqsubseteq Type \ Struct -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Nothing -$$ - -$$ -Type \ Any \sqsubseteq Type \ Any -$$ - -$$ -Type \ Union(Type Int, Type Bool) \sqsubseteq Type \ Union(Type Int, Type Bool) -$$ - -### 传递 - -$$ -Type \ X \sqsubseteq Type \ Z \ if \ Type \ X \sqsubseteq Type \ Y \ and \ Type \ Y \sqsubseteq \ Type \ Z -$$ - -### 包含 - -$$ -Type \ List(T_1) \sqsubseteq Type \ List(T_2) \ if \ T_1 \sqsubseteq T_2 -$$ - -$$ -Type \ Dict(T_{k1}, T_{v1}) \sqsubseteq Type \ Dict(T_{k2}, T_{v2}) \ if \ T_{k1} \sqsubseteq T_{k2} \ and \ T_{v1} \sqsubseteq T_{v1} -$$ - -$$ -Type \ Structure(K_1: T_{a1}, K_2: T_{a2}, ..., K_n: T_{an}) \sqsubseteq Type \ Structure(K_1: T_{b1}, K_2: T_{b2}, ..., K_n: T_{bn}) \ if \ T_{a1} \sqsubseteq T_{b1} \ and \ T_{a2} \sqsubseteq T_{b2} \ and \ ... \ and \ T_{an} \sqsubseteq T_{bn} -$$ - -### 继承 - -$$ -Type \ Struct \ A \sqsubseteq Type \ Struct \ B \ if \ A \ inherits \ B -$$ - -### None - -$$ -Type \ None \sqsubseteq Type \ X, X \notin \{Type \ Nothing, \ Type \ Void\} -$$ - -### Undefined - -$$ -Type \ Undefined \sqsubseteq Type \ X, X \notin \{Type \ Nothing, \ Type \ Void\} -$$ - -## 相等性 - -交换律 - -$$ -Type \ Union(X, Y) == Type \ Union(Y, X) -$$ - -示例 - -$$ -Type \ Union(Int, Bool) == Type \ Union(Bool, Int) -$$ - -结合律 - -$$ -Type \ Union(Union(X, Y), Z) == Type \ Union(X, Union(Y, Z)) -$$ - -示例 - -$$ -Type \ Union(Union(Int, String), Bool) == Type \ Union(Int, Union(String, Bool)) -$$ - -幂等性 - -$$ -Type \ Union(X, X) == Type \ X -$$ - -示例 - -$$ -Type \ Union(Int, Int) == Type \ Int -$$ - -偏序推导 - -$$ -Type \ Union(X, Y) == Type \ Y \ if \ X \sqsubseteq Y -$$ - -示例 - -假设 Struct A 继承 Struct B - -$$ -Type \ Union(A, B) == Type \ B -$$ - -幂等性是偏序自反的一个特例 - -### List - -$$ -Type \ List(X) == Type \ List(Y) \ if \ X == Y -$$ - -### Dict - -$$ -Type \ Dict(T_k, T_v) == Type \ Dict(S_k, S_v) \ if \ T_k == S_k \ and \ T_v == S_v -$$ - -### Struct - -$$ -Type \ Struct(K_1: T_{1}, K_2: T_{2}, ..., K_n: T_{n}) == Type \ Struct(K_1: S_{1}, K_2: S_{2}, ..., K_n: S_{n}) \ if \ T_{1} == S_{1} \ and \ ... \ and \ T_{n} == S_{n} -$$ - -### 偏序检查 - -$$ -Type \ X == Type \ Y \ if \ Type \ X \sqsubseteq Type \ Y \ and \ Type \ Y \sqsubseteq \ Type \ X -$$ - -## 基础方法 - -- sup(t1: T, t2: T) -> T: 根据类型偏序计算两类型 t1, t2 的最小上界。需要动态创建 union type。 -- typeEqual(t1: T, t2: T) -> bool: 比较两类型 t1, t2 是否相等。 -- typeToString(t: T) -> string: 自顶向下递归解析并转化类型成对应的字符串类型。 - -### Sup Function - -- 暂不考虑类型参数,条件类型等特性 -- 使用一个有序集合存储 UnionType 的所有类型 -- 使用一个全局的 Map 根据 UnionType 的名称存储产生的所有 UnionType -- 根据偏序关系计算类型之间的包含关系 - -```go -// The Sup function returns the minimum supremum of all types in an array of types -func Sup(types: T[]) -> T { - typeOf(types, removeSubTypes=true) -} - -// Build a sup type from types [T1, T2, ... , Tn] -func typeOf(types: T[], removeSubTypes: bool = false) -> T { - assert isNotNullOrEmpty(types) - // 1. Initialize an ordered set to store the type array - typeSet: Set[T] = {} - // 2. Add the type array to the ordered set for sorting by the type id and de-duplication - addTypesToTypeSet(typeSet, types) - // 3. Remove sub types according to partial order relation rules e.g. sub schema types - if removeSubTypes { - removeSubTypes(typeSet) - } - if len(typeSet) == 1 { - // If the typeSet has only one type, return it - return typeSet[0] - } - // 4. Get or set the union type from the global union type map - id := getIdentifierFromTypeSet(typeSet) - unionType := globalUnionTypeMap.get(id) - if !unionType { - unionType = createUnionType(typeSet) // Build a new union type - globalUnionTypeMap.set(id, unionType) - } - return unionType -} - -// Add many types into the type set -func addTypesToTypeSet(typeSet: Set[T], types: T[]) -> void { - for type in types { - addTypeToTypeSet(typeSet, type) - } -} - -// Add one type into the type set -func addTypeToTypeSet(typeSet: Set[T], type: T) -> void { - if isUnion(type) { - return addTypesToTypeSet(typeSet, toUnionOf(type).types) - } - // Ignore the void type check - if !isVoid(type) { - // De-duplication according to the type of id - typeSet.add(type) - } -} - -func removeSubTypes(types: Set[T]) -> void { - for source in types { - for target in types { - if !typeEqual(source, target) { - // If the two types have an inheritance relationship, the base class is retained, or if the two types have a partial order relationship according to the relation table. - if (isPartialOrderRelatedTo(source, target)) { - types.remove(source) - } - } - } - } -} - -// isPartialOrderRelatedTo function Determine whether two types have a partial order relationship `source \sqsubseteq target` -// according to the partial order relationship table and rules -func isPartialOrderRelatedTo(source: T, target: T) -> bool { - assert isNotNullOrEmpty(source) - assert isNotNullOrEmpty(target) - if isNoneOrUndefined(source) and !isNothing(target) and !isVoid(target) { - return true - } - if isAny(target) { - return true - } - if typeEqual(source, target) { - return true - } - if isUnion(target) and source in target.types { - return true - } - // Literal Type - if (isStringLiteral(source) and isString(target)) or \ - (isBooleanLiteral(source) and isBool(target)) or \ - (isIntLiteral(source) and isInt(target)) or \ - (isFloatLiteral(source) and isFloat(target)) { - return true - } - if isInt(source) and isFloat(target) { - return true - } - if isList(source) and isList(target) { - return isPartialOrderRelatedTo(toListOf(source).eleType, toListOf(target).eleType - } - if isDict(source) and isDict(target) { - return isPartialOrderRelatedTo(toDictOf(source).keyType, toDictOf(target).keyType) and isPartialOrderRelatedTo(toDictOf(source).valueType, toDictOf(target).valueType) - } - if isStruct(source) and isStruct(target) { - if isTypeDerivedFrom(source, target) { - return true - } - // Empty Object - if len(target.keys) == 0 { - return true - } - if any([key Not in source.keys for key in target.keys]) { - return false - } - for key, sourceType in (source.keys, source.types) { - targetType = getKeyType(target, key) ? getKeyType(target, key) : anyTypeOf() - if !isPartialOrderRelatedTo(sourceType, targetType) { - return false - } - } - return true - } - return false -} -``` - -## 类型检查 - -### 类型检查器 - -类型检查器通过语法制导翻译的方式,自顶向下遍历语法树,并根据上下文有关的**定型规则**来判定程序构造是否为良类型程序。 - -类型检查器依赖类型规则,类型环境 $\Gamma$ 的信息记入符号表。对类型表达式采用抽象语法,如 listof(T)。类型检查失败时产生 type_error,并根据语法上下文产生错误信息。 - -### 基础方法 - -1. isUpperBound(t1, t2): supUnify(t1, t2) == t2 -2. supUnify(t1, t2): - -- 对于基础类型,根据偏序关系计算 sup(t1, t2) -- 对于 list、 dict、 Struct, 递归地对其中元素的类型进行 supUnify -- 不存在偏序关系时,返回 Nothing - -### 检查逻辑 - -#### Operand Expr - -$D \to id: T$ - -``` -env.addtype(id.entry, T.type) -``` - -$T \to boolean$ - -``` -T.type = boolean -``` - -$T \to integer$ - -``` -T.type = integer -``` - -$T \to float$ - -``` -T.type = float -``` - -$T \to string$ - -``` -T.type = string -``` - -$T \to c, \ c \in \{boolean, integer, float, string\}$ - -``` -T.type = literalof(c) -``` - -$T \to None$ - -``` -T.type = None -``` - -$T \to Undefined$ - -``` -T.type = Undefined -``` - -$T \to \ [T_1]$ - -``` -T.type = listof (T1.type) -``` - -$T \to { \{T_1: T_2\} }$ - -``` -T.type = dictof (T1.type: T2.type) -``` - -$T \to { \{N_1: T_1, N2: T_2, ..., N_n: T_n\} }$ - -``` -T.type = structof (N1: T1.type, N2: T2.type, ..., Nn: Tn.type) -``` - -$E \to id$ - -``` -E.type = env.lookup(id.entry) -``` - -$E \to [E_1, E_2, ..., E_n]$ - -``` -func listExpr(E) { - supe = sup([e.type for e in E]]) - E.type = listof(type) -} -``` - -$E \to [E_1 \ for \ E_2 \ in \ E_3 \ if \ E_4]$ - -``` -func listComp(E) { - if !typeEqual(E4.type, boolean) { - raise type_error - } - if !isUpperBound(listof(Any), E3.type) { - raise type_error(E) - } - if !isUpperBound(E3.type, E2.type) { - raise type_error(E) - } - E.type = listof(E1.type) -} -``` - -$E \to \{E_{k1}: E_{v1}, ..., E_{kn}: E_{vn}\}$ - -``` -func dictExpr(E) { - supk := sup([e.type for e in E.keys()]]) - supv := sup([e.type for e in E.values()]]) - E.type = dictof(supk, supv) -} -``` - -$E \to \{E_1:E_2 \ for \ (E_3, E_4) \ in \ E_5 \ if \ E_6\}$ - -``` -func dictComp(E) { - if !typeEqual(E6.type, boolean) { - raise type_error(E) - } - if !isUpperBound(dictof(Any, Any), E5.type) { - raise type_error(E) - } - if !isUpperBound(E5.type, dictof(E3.type, E4.type)) { - raise type_error(E) - } - E.type = dictof(E1.type, E2.type) -} -``` - -$E \to \{E_{k1}: E_{v1}, ..., E_{kn}: E_{vn}\}$ - -``` -func dictExpr(E) { - supk := sup(Ek1, ..., Ekn) - supv = sup(Ev1, ..., Evn) - E.type = dictof(supk, supv) -} -``` - -$E \to \{N_{1} = E_{1}, ..., N_{{n}} = E_{n}\}$ - -``` -func structExpr(E) { - Struct = structof() - for n, e in E { - Struct.add(n, e.type) - } - E.type = Struct -} -``` - -#### Primary Expr - -$E \to E_1[E_2]$ - -``` -func sliceSuffix(E) { - if !isUpperBound(listof(Any), E.E1.type) { - raise type_error(E) - } - if typeEqual(E.E2.type, integer) { - raise type_error(E) - } - E.type = E.E1.type.eleType -} -``` - -$E \to E_1(E_2)$ - -``` -func callSuffix(E) { - if !typeEqual(E.E1.type, func) { - raise type_error(E) - } - if !isUpperBound(listof(E.E1.arguType), E.E2.type) { - raise type_error(E) - } - E.type = E.E1.returnType -} -``` - -#### Unary Expr - -根据每条双目运算符的推理规则推导,以 '+' 为例 - -$E \to + E_1$ - -``` -func Plus(E) { - if !typeEqual(E.E1.type, [integer, float]) { - raise type_error(E) - } - E.type = E.E1.type -} -``` - -#### Binary Expr - -根据每条双目运算符的推理规则推导,以 '%' 为例 - -$E \to E_1 \ % \ E_2$ - -``` -func Mod(E) { - if !(typeEqual(E.E1.type, [integer, float]) && typeEqual(E.E2.type, [integer, float])) { - raise type_error(E) - } - E.type = E.E1.type -} -``` - -#### IF Binary Expr - -$E \to if E_1 \ then \ E_2 else \ E_3$ - -``` -func ifExpr(E) { - if !typeEqual(E.type, boolean) { - raise type_error(E) - } - if !typeEqual(E_2.type, E_3.type) { - raise type_error(E) - } - E.type = E_2.type -} -``` - -#### Stmt - -$S \to if \ E \ then \ S_1 \ else \ S_2$ - -``` -func ifStmt(S) { - if !typeEqual(S.E.type, boolean) { - raise type_error(E) - } - if !typeEqual(S.S1.type, S.S2.type) { - raise type_error(E) - } - S.type = S.S1.type -} -``` - -$S \to id: T = E$ - -$S \to id = T E$ - -``` -func assignStmt(S) { - tpe := env.lookup(id.entry) - if tpe != nil && tpe != S.T { - raise type_error(E) - } - if isUpperBound(tpe, E.type) { - raise type_error(E) - } - env.addtype(id.entry, T.type) -} -``` - -## 类型转换 - -### 基础定义 - -通过语法制导翻译的方式,根据运算符特征,对参与运算的值类型进行自动类型转换 - -### 转换规则 - -$E \to E_1 \ op \ E_2, , op \in \{+, -, *, /, \%, **, //\}$ - -``` -func binOp(E) { - if E.E1.type == integer and E.E2.type == integer { - E.type = integer - } else if E.E1.type == integer and E.E2.type == float { - E.type = float - } else if E.E1.type == float and E.E2.type == integer { - E.type = float - } else if E.E1.type == float and E.E2.type == float { - E.type = float - } -} -``` - -## 类型推导 - -### 基础定义 - -- 在类型信息不完全的情况下类型规则推导、重建类型 -- 自底向上推导并重建数程序中的数据结构类型,如基础类型,list, dict, Struct - -### 基础方法 - -1. typeOf(expr, subst): 输入为表达式和代换规则集合,返回 expr 的类型和新的代换规则集合 -2. unifier(t1, t2, subst, expr) 用 t1=t2 尝试代换,如果代换成功(未出现且无冲突),则将 t1=t2 加入 subst 并返回 subst。否则报错已出现或有冲突。 - -### 推导逻辑 - -$E \to id = E_1$ - -``` -func assignExpr(E, subst) { - return unifier(E.id.type, E.E_1.type, subst, E) -} -``` - -$unifier(t1, t2, subst, expr) \rightarrow subst$ - -``` -func unifier(t1, t2, subst, expr) { - t1 = applySubstToTypeEquation(t1, subst) - t2 = applySubstToTypeEquation(t2, subst) - - if t1 == t2 { - return subst - } - - if isTypeVar(t1) { - if isNoOccur(t1, t2) { - addTypeEquationToSubst(subst, t1, t2) - return subst - } else { - raise occurrence_violation_error(t1, t2, expr) - } - } - - if isTypeVar(t2) { - if isNoOccur(t2, t1) { - addTypeEquationToSubst(subst, t2, t1) - return subst - } else { - raise occurrence_violation_error(t2, t1, expr) - } - } - - if isList(t1) and isList(t2) { - return unifier(toListOf(t1).eleType, toListOf(t2).eleType, subst, expr) - } - if isDict(t1) and isDict(t2) { - dict1of := toDictOf(t1) - dict2of := toDictOf(t2) - subst = unifier(dict1of.keyType, dict2of.keyType, subst, expr) - subst = unifier(dict1of.valueType, dict2of.valueType, subst, expr) - return subst - } - if isStruct(t1) and isStruct(t2) { - Struct1of := tostructof(t1) - Struct2of := tostructof(t2) - for key, _ in Struct1of { - subst = unifier(t1[key].type, t2[key].type, subst, expr) - } - return subst - } - - raise unification_error(t1, t2, expr) -} - -func applySubstToTypeEquation(t, subst) { - // walks through the type t, replacing each type variable by its binding in the substitution -σ. If a variable is Not bound in the substitution, then it is left unchanged. - if isBasicType(t) { - return t - } - if isList(t) { - return listOf(applySubstToTypeEquation(toListOf(t).eleType, subst)) - } - if isDict(t) { - dictof := toDictOf(t) - kT := applySubstToTypeEquation(dictof.keyType, subst) - vT := applySubstToTypeEquation(dictof.valueType, subst) - return dictOf(kT, vT) - } - if isStruct(t) { - structof := tostructof(t) - s := structof() - for key, type in Struct1of { - kT := applySubstToTypeEquation(type, subst) - s.add(key, kT) - } - return s - } - if hasTypeVar(t) { - for tvar in t.vars { - if tvar in subst { - *tvar = subst[tvar] - } - } - } - return t -} - -func addTypeEquationToSubst(subst, tvar, t) { - // takes the substitution σ and adds the equation tv = t to it - for _, t in subst { - for tvar in t.vars { - tmp := applyOneSubst(tsvar, tvar, t) - *tvar = tmp - } - } - subst.add(tvar, t) -} - -func applyOneSubst(t0, tvar, t1) { - // substituting t1 for every occurrence of tv in t0. - if isBasicType(t0) { - return t0 - } - if isList(t0) { - return listOf(applyOneSubst(toListOf(t).eleType, tvar, t1)) - } - if isDict(t0) { - dictof := toDictOf(t) - kT := applyOneSubst(dictof.keyType, tvar, t1) - vT := applyOneSubst(dictof.valueType, tvar, t1) - return dictOf(kT, vT) - } - if isStruct(t0) { - structof := tostructof(t) - s := structof() - for key, type in Struct1of { - kT := applyOneSubst(type, tvar, t1) - s.add(key, kT) - } - return s - } - if t0 == tvar { - return t1 - } - return t0 -} - -func isNoOccur(tvar, t) { - // No variable bound in the substitution occurs in any of the right-hand sides of the substitution. - if isBasicType(t) { - return true - } - if isList(t) { - return isNoOccur(tvar, toListOf(t).eleType) - } - if isDict(t) { - dictof := toDictOf(t) - return isNoOccur(tvar, dictof.keyType) and isNoOccur(tvar, dictof.valueType) - } - if isStruct(t) { - structof := tostructof(t) - noOccur := true - for _, type in structof { - noOccur = noOccur and isNoOccur(tvar, type) - } - return noOccur - } - return tvar != t -} -``` - -### 示例 - -#### 正常推导 - -``` -T : { - a = 1 - b = "2" - c = a * 2 - d = { - d0 = [a, c] - } -} - -x: T = { - a = 10 -} -``` - -#### Occurrence Violation Error - -``` -T = { - a = a -} -``` - -#### Type Unification Error - -``` -T : { - a = 1 -} - -T : { - a = "1" -} -``` - -## Reference - -- [https://en.wikipedia.org/wiki/Type_system](https://en.wikipedia.org/wiki/Type_system) -- Pierce, Benjamin C. (2002). Types and Programming Languages. MIT Press. -- [https://www.cs.cornell.edu/courses/cs4110/2010fa/](https://www.cs.cornell.edu/courses/cs4110/2010fa/) -- [https://www.typescriptlang.org/docs/handbook/basic-types.html](https://www.typescriptlang.org/docs/handbook/basic-types.html) -- [https://www.typescriptlang.org/docs/handbook/advanced-types.html](https://www.typescriptlang.org/docs/handbook/advanced-types.html) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/_category_.json deleted file mode 100644 index 53e27fd4..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "模块系统", - "position": 2 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/base64.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/base64.md deleted file mode 100644 index 0db738f0..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/base64.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: "base64" -linkTitle: "base64" -type: "docs" -description: base64 编码解码 -weight: 100 ---- - -## encode - -`encode(value: str, encoding: str = "utf-8") -> str` - -使用注册的编码器对字符串 `value` 进行编码。 - -## decode - -`decode(value: str, encoding: str = "utf-8") -> str` - -使用注册的编码器对字符串 `value` 进行解码。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/builtin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/builtin.md deleted file mode 100644 index 44085174..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/builtin.md +++ /dev/null @@ -1,401 +0,0 @@ ---- -title: "builtin" -sidebar_position: 1 ---- - -KCL 提供了一个内置系统模块的列表,这些模块是自动加载的,无需提供任何模块名称即可直接使用。例如,`print` 就是一个广泛使用的内置模块提供的函数。 - -## 类型转换函数 - -KCL的 `bool`、`int`、`float`、`str`、`list`、`dict`等类型有内置同名的转换函数。其中 `int` 不仅仅可以用于截断浮点数,也可以用来将字符串转化为整数(解析时为10进制,也可以制定其他值)。 - -下面是类型相关函数常见的用法: - -```py -b1 = bool(1) # true -b2 = bool(1.5) # true -b3 = bool("true") # true -b4 = bool("") # false -b5 = bool([]) # false -b6 = bool({}) # false - -i1 = int("11") # 11 -i2 = int("11", base=8) # 9 -i3 = int("11", base=2) # 3 - -f1 = float(1) # 1.0 -f2 = float("1.5") # 1.5 - -s1 = str(1) # 1 - -l1 = list([1, 2, 3]) -``` - -## String 类型成员函数 - -参考 [String 文档](/docs/reference/lang/spec/datatypes) - -## print - -`print(*args:any, end:str='\n')` - -内置的打印函数,提供不同类型的可变参数打印,默认在结尾添加一个换行符号。以下上常见的用法: - -```python -print("hello KCL") -print() -print(None, end=':') -print(None) -print(True) -print(False) -print(123) -print(123.0) -print('abc ${123}') -print("abc ${456}") -print([1,'a', True]) -print(1,'a', True) -print({}) -print({a: 123}) -``` - -输出格式如下: - -```shell -hello KCL - -None:None -True -False -123 -123.0 -abc 123 -abc 456 -[1, 'a', True] -1 a True -{} -{'a': 123} -``` - -如果不希望在默认换行时,可以通过 `end=''` 命名参数重新指定结尾的字符串。 - -## multiplyof - -`multiplyof(a:int, b:int) -> bool` - -判断整数 `a` 是否为 `b` 的整数倍,返回布尔值: - -```python -print(multiplyof(2, 1)) # True -print(multiplyof(1, 2)) # False -print(multiplyof(0, 1)) # True -print(multiplyof(0, 2)) # True -print(multiplyof(1, 0)) # Error -``` - -`0` 是任何数的倍数。但是 `b` 不能为 `0`,否则将抛出异常。 - -## isunique - -`isunique(list: [any]) -> bool` - -判断数组中是否存在重复的元素,返回布尔值: - -```python -print(isunique([])) # True -print(isunique([1])) # True -print(isunique([1, 2])) # True - -print(isunique([1, 1])) # False -print(isunique([1, 1.0])) # False -print(isunique([1.1, 1.1])) # False - -print(isunique(['abc', "abc"])) # False -print(isunique(['abc', "a${'bc'}"])) # False -``` - -需要注意的是整数和浮点数会忽略类型差异,根据值是否相等判断。 - -## len - -`len(x: str | [any] | {:}) -> int` - -返回字符串、列表和数组的长度: - -```python -print(len([])) # 0 -print(len({})) # 0 - -print(len([1])) # 1 -print(len({abc:123})) # 1 - -print("abc") # 3 -``` - -注:不支持对 `schema` 对象计算长度。 - -## abs - -`abs(x: number) -> number` - -计算 `x` 的绝对值。 - -## all_true - -`all_true(x:str|[]|{:}) -> bool` - -判断列表或字典类全部元素为真,用法如下: - -```python -print(all_true([])) # True -print(all_true({})) # True - -print(all_true([True])) # True -print(all_true([1])) # True - -print(all_true([True, False])) # False -print(all_true([True, None])) # False -``` - -当列表为空时返回真。 - - - -## any_true - -`any_true(x:str|[]|{:}) -> bool` - -判断可迭代对象中至少有一个元素为真,用法如下: - -```python -print(any_true([])) # False -print(any_true([1])) # True -``` - -## bin - -`bin(x:number) -> str` - -返回整数的二进制表示的字符串,用法如下: - -```python -print(bin(8)) # 0b1000 -``` - -## hex - -`hex(number)` - -返回整数的十六进制表示的字符串,用法如下: - -```python -print(hex(18)) # 0x12 -``` - -## oct - -`oct(number)` - -返回整数的八进制表示的字符串,用法如下: - -```python -print(oct(10)) # 0o12 -``` - -## option - -`option(key:str, type:str='', required=False, default=None, help="") -> any` - -获取命令行参数输入的值。 - -## ord - -`ord(c) -> int` - -获取字符的 Unicode 码点值,用法如下: - -```python -print(ord('A')) # 65 -print(ord('B')) # 66 -print(ord('C')) # 67 -``` - -## sorted - -`sorted(x: []) -> []` - -返回排序后的列表,用法如下: - -```python -_a = [] -_b = [2, 1] - -_c = sorted(_a) -_d = sorted(_b) - -print(_a) # [] -print(_b) # [2, 1] -print(_c) # [] -print(_d) # [1, 2] -``` - -## range - -`range(start:int, end:int, step=1) -> [int]` - -产生迭代列表,用法如下: - -```python -print(range(1,5)) # [1, 2, 3, 4] -print(range(1,5, 2)) # [1, 3] -print(range(5, 1, -1)) # [5, 4, 3, 2] -``` - -## min - -`min(x:[number]) -> number` - -返回列表中最小的元素,用法如下: - -```python -print(min([1,2])) # 1 -print(min([2,1])) # 1 -``` - - - -## max - -`max(x:[number]) -> number` - -返回列表中最大的元素,用法如下: - -```python -print(max([1,2])) # 2 -print(max([2,1])) # 2 -``` - -## sum - -`sum(x:[number], init_value=0) -> number` - -返回列表中全部元素的和,用法如下: - -``` -print(sum([1,2])) # 3 -print(sum([2,1], 1000)) # 1003 -``` - -## pow - -`pow(x: number, y: number, z: number = None) -> number` - -计算 `x**y`,如果 `z` 非空则计算 `(x**y)%z`,支持整数和浮点数。 - -下面的常见的用法: - -```python -print(pow(2,3)) # 8 -print(pow(2, 3, 5)) # 8%5 == 3 - -print(pow(2, 0.5)) # 1.414 -``` - -## round - -`round(number: int|float, ndigits:int|None) -> float | int` - -返回 `number` 的四舍五入近似值。如果 `ndigits` 非 `None` 则返回浮点数并保留指定位数的小数(不能为负数),否则返回整数结构。 - -下面是常用的用法: - -```python -print(round(1)) # 1 -print(round(1.4)) # 1 -print(round(1.5)) # 2 - -print(round(1.5555, 1)) # 1.6 -print(round(1.5555, 2)) # 1.56 - -print(round(1.5555)) # 2 -print(round(1.5555, 0)) # 2.0 -``` - -需要注意的是,`ndigits` 为 `None` 和 `0` 的区别是前缀返回 `int` 类型、后者返回 `float` 类型。 - -## typeof - -`typeof(x: any, full_name: bool = False) -> str` - -输出 `x` 在运算时的类型。当 `full_name` 参数设置为 `True` 时,将返回 `pkg.schema` 形式的包前缀。 - -下面是常见的用法: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person{} -t3 = typeof(_x1) - -_x2 = pkg.Person{} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# 输出 -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -## zip - -`zip(*args: str|list|dict)` - -用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。 - -下面是常见的用法: - -```py -a = zip([0, 1, 2], [3, 4, 5]) -b = zip([0, 1], [3, 4, 5]) -c = zip([0, 1, 2], [3, 4, 5, 6]) - -# 输出 -# a: -# - - 0 -# - 3 -# - - 1 -# - 4 -# - - 2 -# - 5 -# b: -# - - 0 -# - 3 -# - - 1 -# - 4 -# c: -# - - 0 -# - 3 -# - - 1 -# - 4 -# - - 2 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/crypto.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/crypto.md deleted file mode 100644 index cef03352..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/crypto.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "crypto" -linkTitle: "crypto" -type: "docs" -description: crypto 包 - 提供 SHA 相关的哈希函数 -weight: 100 ---- - -## md5 - -`md5(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `MD5` 算法对字符串 `value` 进行加密。 - -## sha1 - -`sha1(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA1` 算法对字符串 `value` 进行加密。 - -## sha224 - -`sha224(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA224` 算法对字符串 `value` 进行加密。 - -## sha256 - -`sha256(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA256` 算法对字符串 `value` 进行加密。 - -## sha384 - -`sha384(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA384` 算法对字符串 `value` 进行加密。 - -## sha512 - -`sha512(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA512` 算法对字符串 `value` 进行加密。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/datetime.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/datetime.md deleted file mode 100644 index 66cb4bca..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/datetime.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: "datetime" -linkTitle: "datetime" -type: "docs" -description: datetime 包 - 时间处理 -weight: 100 ---- - -## time - -`ticks() -> float` - -返回从 1970 年 1 月 1 日 0 时 0 分 0 秒(Epoch)开始到当前时间经过的秒数。如果系统时钟能提供更精确的时间,则秒数后可能会有小数部分。 - -## date - -`date() -> str` - -返回以 `%Y-%m-%d %H:%M:%S` 格式表示的时间。 - -## now - -`now() -> str` - -返回当地时间,例如 `'Sat Jun 06 16:26:11 1998'`。 - -## today - -`today() -> str` - -返回以 `%Y-%m-%d %H:%M:%S.%{ticks}` 格式表示的时间。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/index.md deleted file mode 100644 index c1f4b4a0..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# 系统模块 - -KCL 通过系统模块、用户模块和插件模块提供工程化的扩展能力。本节介绍系统模块的基本概念,插件模块可以参考插件系统。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/json.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/json.md deleted file mode 100644 index b19bdc88..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/json.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: "json" -linkTitle: "json" -type: "docs" -description: JSON 编码解码 -weight: 100 ---- - -## encode - -``` -encode( - data: any, - sort_keys: bool = False, - indent: int = None, - ignore_private: bool = False, - ignore_none: bool = False -) -> str -``` - -将 KCL 对象 `data` 序列化为 JSON 格式的字符串。 - -## decode - -`decode(value: str) -> any` - -反序列化 `value`(一个包含 JSON 格式文档的字符串实例)为一个 KCL 对象。 - -## dump_to_file - -``` -dump_to_file( - data: any, - filename: str, - ignore_private: bool = False, - ignore_none: bool = False -) -> None -``` - -将 KCL 对象 `data` 序列化为 JSON 格式的字符串,并将其写入文件 `filename` 中。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/manifests.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/manifests.md deleted file mode 100644 index 5c54e9c7..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/manifests.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: "manifests" -linkTitle: "manifests" -type: "docs" -description: manifests system module -weight: 100 ---- - -## yaml_stream - -```python -yaml_stream(values: [any], opts: {str:} = { - sort_keys = False - ignore_private = True - ignore_none = False - sep = "---" -}) -``` - -这个函数的功能是将 KCL 对象列表序列化为带 `---` 分隔符的样式 YAML 输出,它具有两个参数: - -- `values` - 一个 KCL 对象列表 -- `opts` - YAML 序列化选项 - - `sort_keys`:是否按属性名称的字典序对序列化结果进行排序(默认为 `False`)。 - - `ignore_private`:是否忽略名称以 `_` 开头的属性序列化输出(默认为 `True`)。 - - `ignore_none`:是否忽略值为 `None` 的属性(默认为 `False`)。 - - `sep`:在多个 YAML 文档之间选择怎样的分隔符(默认为 `"---"`)。 - -下面我们通过一个例子来说明: - -```python -# 使用 `import` 关键词导入 `manifests` 模块 -import manifests - -# `Deployment` schema 定义 -schema Deployment: - apiVersion: str = "v1" - kind: str = "Deployment" - metadata: {str:} = { - name = "deploy" - } - spec: {str:} = { - replica = 2 - } - -# `Service` schema 定义 -schema Service: - apiVersion: str = "v1" - kind: str = "Service" - metadata: {str:} = { - name = "svc" - } - spec: {str:} = {} - -# 定义两个 `Deployment` 资源 -deployments = [Deployment {}, Deployment {}] -# 定义两个 `Service` 资源 -services = [Service {}, Service {}] -# 将它们放入 KCL 列表,并调用 `manifests.yaml_stream` 函数。 -manifests.yaml_stream(deployments + services) -``` - -首先我们通过 `import` 关键字导入 `manifests` 模块并定义 2 个 Deployment 以及 2 个 Service 资源,当我们想以 YAML stream 并以 `---` 作为分隔符的格式依次输出这 4 个资源时,我们可以将它们合并为一个 KCL 列表并作为 `manifests.yaml_stream` 函数的 `values` 形参进行传入 (如无特殊需求,opts 参数一般使用默认值即可),最终得到 YAML 输出为: - -```yaml -apiVersion: v1 -kind: Deployment -metadata: - name: deploy -spec: - replica: 2 ---- -apiVersion: v1 -kind: Deployment -metadata: - name: deploy -spec: - replica: 2 ---- -apiVersion: v1 -kind: Service -metadata: - name: svc ---- -apiVersion: v1 -kind: Service -metadata: - name: svc -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/math.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/math.md deleted file mode 100644 index 3b2ff0cc..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/math.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: "math" -linkTitle: "math" -type: "docs" -description: math 包 - 数学函数 -weight: 100 ---- - -## ceil - -`ceil(x) -> int` - -返回 `x` 向上取整得到的整数,这是大于等于 `x` 的最小整数。 - -## factorial - -`factorial(x) -> int` - -返回 `x` 的阶乘(即 `x!`),如果 `x` 是负数或者不是整数,则会引发一个错误。 - -## floor - -`floor(x) -> int` - -返回 `x` 向下取整得到的整数,这是小于等于 `x` 的最大整数。 - -## gcd - -`gcd(a: int, b: int) -> int` - -返回 `x` 和 `y` 的最大公约数。 - -## isfinite - -`isfinite(x) -> bool` - -如果 `x` 既不是无穷大也不是 `NaN` 返回 `True`,否则返回 `False`。 - -## isinf - -`isinf(x) -> bool` - -如果 `x` 是正无穷或负无穷返回 `True`,否则返回 `False`。 - -## isnan - -`isnan(x) -> bool` - -如果 `x` 是 `NaN` 返回 `True`,否则返回 `False`。 - -## modf - -`modf(x) -> List[float, float]` - -返回 `x` 的整数和小数部分,两个结果均与 `x` 的正负号相同,并且均为浮点数。 - -## exp - -`exp(x) -> float` - -返回以 `e` 为底数, `x` 的幂。 - -## expm1 - -`expm1(x) -> float` - -返回 `e` 的 `x` 次方减去 1,该函数能够避免由于直接计算 `exp(x) - 1` 而引起的精度损失。 - -## log - -`log(x, base=2.71828182845904523536028747135266250) -> float` - -返回以 `e` 为底数,`x` 的对数。 - -## log1p - -`log1p(x) -> float` - -返回以 `e` 为底数,`1 + x` 的自然对数,该函数能够在 `x` 靠近 0 时精确计算结果。 - -## log2 - -`log2(x) -> float` - -返回 `x` 的以 2 为底的对数。 - -## log10 - -`log10(x) -> float` - -返回 `x` 的以 10 为底的对数。 - -## pow - -`pow(x, y) -> float` - -返回 `x` 的 `y` 次幂(即 `x` 的 `y` 次方)。 - -## sqrt - -`sqrt(x) -> float` - -返回 `x` 的平方根。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/net.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/net.md deleted file mode 100644 index 1050d16d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/net.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: "net" -linkTitle: "net" -type: "docs" -description: net 包 - 网络IP处理 -weight: 100 ---- - -## split_host_port - -`split_host_port(ip_end_point: str) -> List[str]` - -从 `ip_end_point` 分离出 `host` 和 `port`。 - -## join_host_port - -`join_host_port(host, port) -> str` - -合并 `host` 和 `port`。 - -## fqdn - -`fqdn(name: str = '') -> str` - -返回完全限定域名(FQDN)。 - -## parse_IP - -`parse_IP(ip) -> str` - -将 `ip` 解析为真实的 IP 地址。 - -## to_IP4 - -`to_IP4(ip) -> str` - -获取 `ip` 的 IPv4 表示形式。 - -## to_IP16 - -`to_IP16(ip) -> int` - -获取 `ip` 的 IPv6 表示形式。 - -## IP_string - -`IP_string(ip: str | int) -> str` - -返回 IP 字符串。 - -## is_IPv4 - -`is_IPv4(ip: str) -> bool` - -判断 `ip` 是否为 IPv4。 - -## is_IP - -`is_IP(ip: str) -> bool` - -判断 `ip` 是否为有效的 IP 地址。 - -## is_loopback_IP - -`is_loopback_IP(ip: str) -> bool` - -判断 `ip` 是否为回环地址。 - -## is_multicast_IP - -`is_multicast_IP(ip: str) -> bool` - -判断 `ip` 是否为组播地址。 - -## is_interface_local_multicast_IP - -`is_interface_local_multicast_IP(ip: str) -> bool` - -判断 `ip` 是否为接口、本地和组播地址。 - -## is_link_local_multicast_IP - -`is_link_local_multicast_IP(ip: str) -> bool` - -判断 `ip` 是否为链路本地和组播地址。 - -## is_link_local_unicast_IP - -`is_link_local_unicast_IP(ip: str) -> bool` - -判断 `ip` 是否为链路本地和单播地址。 - -## is_global_unicast_IP - -`is_global_unicast_IP(ip: str) -> bool` - -判断 `ip` 是否为全局单播地址。 - -## is_unspecified_IP - -`is_unspecified_IP(ip: str) -> bool` - -判断 `ip` 是否为 `unspecified` 地址。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/overview.md deleted file mode 100644 index aa3eaeb3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/overview.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -sidebar_position: 0 ---- - -# 概览 - -KCL 是面向配置的编程语言,通过内置模块、KCL 模块和插件模块提供工程化的扩展能力。 - -![](/img/docs/reference/lang/model/kcl-module.png) - -用户代码中不用导入直接使用 builtin 的函数(比如用 `len` 计算列表的长度、通过 `typeof` 获取值的类型等),而对于字符串等基础类型也提供了一些内置方法(比如转化字符串的大小写等方法)。对于相对复杂的通用工作则通过标准库提供,比如通过 import 导入 `math` 库就可以使用相关的数学函数,可以通过导入 `regex` 库使用正则表达式库。而针对 KCL 代码也可以组织为模块,比如 Konfig 大库中将基础设施和各种标准的应用抽象为模块供上层用户使用。此外还可以通过 Plugin 机制,采用 Python 为 KCL 开发插件,比如目前有 meta 插件可以通过网络查询中心配置信息,`app-context` 插件则可以用于获取当前应用的上下文信息从而简化代码的编写。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/regex.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/regex.md deleted file mode 100644 index e7b0c25c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/regex.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "regex" -linkTitle: "regex" -type: "docs" -description: regex 包 - 正则表达式 -weight: 100 ---- - -## replace - -`replace(string: str, pattern: str, replace: str, count=0) -> str` - -替换字符串 `string`中最左边、不重叠并且匹配模式 `pattern` 的部分替换为指定的字符串 `replace`,并返回替换后的字符串 - -## match - -`match(string: str, pattern: str) -> bool` - -尝试在字符串开头应用模式 `pattern`,找到了任何匹配项则返回 `True`,返回 `False` 表示没有找到匹配项 - -## compile - -`compile(pattern: str) -> bool` - -编译正则表达式模式 `pattern`,并返回一个布尔值,表示该模式是否有效 - -## findall - -`findall(string: str, pattern: str) -> List[str]` - -查找 `pattern` 在 `string` 中的所有非重叠匹配,并以字符串列表的形式返回 - -## search - -`search(string: str, pattern: str) -> bool` - -扫描字符串 `string` 以查找与模式匹配的项,如果找到任何匹配项,则返回布尔值 `True`,否则返回 `False` - -## split - -`split(string: str, pattern: str, maxsplit=0) -> List[str]` - -返回一个由字符串内单词组成的列表,使用 `pattern` 作为分隔字符串,最多进行 `maxsplit` 次拆分 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/units.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/units.md deleted file mode 100644 index 8c862d0e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/units.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: "units" -linkTitle: "units" -type: "docs" -description: units 包 - 单位处理 -weight: 100 ---- - -## 单位的常量 - -- 定点数: `n`, `u`, `m`, `k`, `K`, `G`, `T` 和 `P`. -- 2 的幂: `Ki`, `Mi`, `Gi`, `Ti` 和 `Pi`. - -## 函数列表 - -- `to_n(num: int) -> str` - 将 int 转换为以 `n` 作为后缀的字符串 -- `to_u(num: int) -> str` - 将 int 转换为以 `u` 作为后缀的字符串 -- `to_m(num: int) -> str` - 将 int 转换为以 `m` 作为后缀的字符串 -- `to_K(num: int) -> str` - 将 int 转换为以 `K` 作为后缀的字符串 -- `to_M(num: int) -> str` - 将 int 转换为以 `M` 作为后缀的字符串 -- `to_G(num: int) -> str` - 将 int 转换为以 `G` 作为后缀的字符串 -- `to_T(num: int) -> str` - 将 int 转换为以 `T` 作为后缀的字符串 -- `to_P(num: int) -> str` - 将 int 转换为以 `P` 作为后缀的字符串 -- `to_Ki(num: int) -> str` - 将 int 转换为以 `Ki` 作为后缀的字符串 -- `to_Mi(num: int) -> str` - 将 int 转换为以 `Mi` 作为后缀的字符串 -- `to_Gi(num: int) -> str` - 将 int 转换为以 `Gi` 作为后缀的字符串 -- `to_Ti(num: int) -> str` - 将 int 转换为以 `Ti` 作为后缀的字符串 -- `to_Pi(num: int) -> str` - 将 int 转换为以 `Pi` 作为后缀的字符串 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/yaml.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/yaml.md deleted file mode 100644 index e0faf129..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/model/yaml.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: "yaml" -linkTitle: "yaml" -type: "docs" -description: yaml 编码解码 -weight: 300 ---- - -## encode - -``` -encode( - data: any, - sort_keys: bool = False, - ignore_private: bool = False, - ignore_none: bool = False -) -> str -``` - -将 KCL 对象 `data` 序列化为 YAML 格式的字符串。 - -## decode - -`decode(value: str) -> any` - -反序列化 `value`(一个包含 YAML 格式文档的字符串实例)为一个 KCL 对象。 - -## dump_to_file - -``` -dump_to_file( - data: any, - filename: str, - ignore_private: bool = False, - ignore_none: bool = False -) -> None -``` - -将 KCL 对象 `data` 序列化为 YAML 格式的字符串,并将其写入文件 `filename` 中。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/_category_.json deleted file mode 100644 index edfe989e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "包管理", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/1.init.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/1.init.md deleted file mode 100644 index 0bfc0303..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/1.init.md +++ /dev/null @@ -1,45 +0,0 @@ -# kpm init - -初始化一个 kcl 包。 - -## 使用 - -```shell -kpm init [options][package_name] -``` - -## 介绍 - -`kpm init` 会在当前目录初始化一个 kcl 包。如果没有提供包名,会使用当前目录的名字作为包名。 - -如果提供了包名,会在当前目录下创建一个以包名命名的子目录,并在该目录下初始化 kcl 包。 - -`kpm init` 会在包目录下创建 `kcl.mod`、`kcl.mod.lock` 和 `main.k`。 - -## 选线 - -### --help, -h - -显示帮助信息。 - -## 示例 - -### 初始化当前目录为 kcl 包 - -```shell -# 创建一个目录 -$ mkdir my_package - -# 进入目录 -$ cd my_package - -# 初始化当前目录为 kcl 包 -$ kpm init -``` - -### 初始化一个名为 my_package 的 kcl 包 - -```shell -# 初始化一个名为 my_package 的 kcl 包 -kpm init my_package -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/10.help.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/10.help.md deleted file mode 100644 index 0fd9fa3a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/10.help.md +++ /dev/null @@ -1,21 +0,0 @@ -# kpm help - -输出 kpm 命令的帮助信息。 - -## 使用 - -```shell -kpm help -``` - -## 介绍 - -`kpm help` 会输出 kpm 命令的帮助信息。 - -## 示例 - -使用 `kpm help` 输出 kpm 命令的帮助信息。 - -```shell -kpm help -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/2.add.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/2.add.md deleted file mode 100644 index 09fd5d46..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/2.add.md +++ /dev/null @@ -1,53 +0,0 @@ -# kpm add - -添加一个依赖到 kcl 包。 - -## 使用 - -```shell -kpm add [options][package_reference] -``` - -## 介绍 - -`kpm add` 会添加一个依赖到 kcl 包。依赖可以来自 git 仓库,或者 kcl registry。 - -`package_reference` 是一个 kcl 包引用,格式为 `package_name:version`。 - -## 选项 - -### --git - -指定依赖来自 git 仓库的 git url。 - -### --tag - -指定依赖来自 git 仓库的 tag。 - -### --help, -h - -显示帮助信息。 - -## 示例 - -### 添加一个来自 kcl registry 的依赖 - -添加一个名为 `k8s` 的依赖,版本为最新版本。 - -```shell -kpm add k8s -``` - -添加一个名为 `k8s` 的依赖,版本为 `v1.27.2`。 - -```shell -kpm add k8s:v1.27.2 -``` - -### 添加一个来自 git 仓库的依赖 - -添加一个来自 git 仓库的 kcl 包依赖,tag 为 v0.1.0 - -```shell -kpm add --git https://github.com/awesome-kusion/konfig.git --tag v0.1.0 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/3.pkg.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/3.pkg.md deleted file mode 100644 index fd708d03..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/3.pkg.md +++ /dev/null @@ -1,33 +0,0 @@ -# kpm pkg - -打包一个 kcl 包。 - -## 使用 - -```shell -kpm pkg [options] -``` - -## 介绍 - -`kpm pkg` 会打包一个 kcl 包为 `*.tar`。 - -选项 `--target` 用于指定打包后的 `*.tar` 文件路径。 - -## 选项 - -### --target - -指定打包后的 `*.tar` 文件路径。 - -### --help, -h - -显示帮助信息。 - -## 示例 - -### 打包当前 kcl 包为 `*.tar` - -```shell -kpm pkg --target /Users/my_package_tar -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/4.metadata.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/4.metadata.md deleted file mode 100644 index 199ebd2e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/4.metadata.md +++ /dev/null @@ -1,41 +0,0 @@ -# kpm metadata - -打印 kcl 包的元数据。 - -## 使用 - -```shell -kpm metadata [options] -``` - -## 介绍 - -`kpm metadata` 会打印 kcl 包的元数据。元数据包括包的依赖信息。 - -`--update` 选项用于自动下载缺失的依赖包。 - -## 选项 - -### --update - -自动下载缺失的依赖包。 - -### --help, -h - -展示 `kpm metadata` 命令的帮助信息。 - -## 示例 - -### 打印 kcl 包的元数据 - -打印 kcl 包的元数据。 - -```shell -kpm metadata -``` - -打印 kcl 包的元数据,并自动下载缺失的依赖包。 - -```shell -kpm metadata --update -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/5.run.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/5.run.md deleted file mode 100644 index eee83e08..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/5.run.md +++ /dev/null @@ -1,69 +0,0 @@ -# kpm run - -编译一个 kcl 包。 - -## 使用 - -```shell -kpm run [options][package_source] -``` - -## 介绍 - -`kpm run` 会编译一个 kcl 包。 - -## 选项 - -### --input - -指定包的入口文件路径。 - -### --tag - -指定 oci url 的包的 tag。 - -### --vendor - -`--vendor` 选项会将依赖包移动到当前包,并自动下载缺失的依赖包。 - -### --kcl_args - -`--kcl_args` 描述了传递给 kcl 编译器的参数。 - -### --help, -h - -展示 `kpm run` 命令的帮助信息。 - -## 示例 - -### 编译当前 kcl 包 - -在 kcl 包目录下,`kpm run` 可以用于编译当前 kcl 包。 - -```shell -kpm run -``` - -### 编译一个 kcl 包 tar 文件 - -`kpm run` 可以用于编译一个 kcl 包 tar 文件。 - -```shell -kpm run /Users/demo/my_package.tar -``` - -### 编译一个 kcl 包来自 oci url - -`kpm run` 可以用于编译一个 kcl 包从 oci url。 - -```shell -kpm run --tag 0.0.1 oci://localhost:5001/test/my_package -``` - -### 编译一个 kcl 包来自 oci ref - -`kpm run` 可以用于编译一个 kcl 包从 oci ref。 - -```shell -kpm run test/my_package:0.0.1 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/6.login.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/6.login.md deleted file mode 100644 index 9055d8fb..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/6.login.md +++ /dev/null @@ -1,68 +0,0 @@ -# kpm login - -登陆 kpm registry. - -## 使用 - -```shell -kpm login [options][kpm_registry] -``` - -## 介绍 - -`kpm login` 将会登陆 kpm registry。 - -## 选项 - -### --username, -u - -指定 kpm registry 的用户名。 - -### --password, -p - -指定 kpm registry 的密码。 - -### --help, -h - -展示 `kpm login` 命令的帮助信息。 - -## 示例 - -### 登陆到 kpm registry, 通过参数输入用户名和密码 - -```shell -kpm login -u -p -``` - -期望输出为 - -```shell -Login succeeded -``` - -### 登陆到 kpm registry, 通过参数输入用户名,密码通过交互式输入 - -```shell -kpm login -u -``` - -期望输出为 - -```shell -Password: -Login succeeded -``` - -### 登陆到 kpm registry, 用户名和密码通过交互式输入 - -```shell -kpm login -``` - -期望输出为 - -```shell -Username: -Password: -Login succeeded -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/7.logout.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/7.logout.md deleted file mode 100644 index 65dd317e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/7.logout.md +++ /dev/null @@ -1,27 +0,0 @@ -# kpm logout - -从 kpm registry 登出。 - -## 使用 - -```shell -kpm logout [options][kpm_registry] -``` - -## 介绍 - -`kpm logout` 会从 kpm registry 登出。 - -## 选项 - -### --help, -h - -展示 `kpm logout` 命令的帮助信息。 - -## 示例 - -### 从 kpm registry 登出 - -```shell -kpm logout -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/8.push.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/8.push.md deleted file mode 100644 index 53c2e520..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/8.push.md +++ /dev/null @@ -1,46 +0,0 @@ -# kpm push - -上传一个 kcl 包到 kpm registry。 - -## 使用 - -```shell -kpm push [options][kpm_registry] -``` - -## 介绍 - -`kpm push` 将会上传一个 kcl 包到 kpm registry。 - -## 选项 - -### --tar_path - -指定上传的 `*.tar` 文件路径。 - -### --help, -h - -展示 `kpm push` 命令的帮助信息。 - -## 示例 - -### 上传当前 kcl 包到 kpm registry - -你可以在 kcl 包的根目录下使用 `kpm push` 命令上传一个 kcl 包到 kpm registry。 - -```shell -# 创建一个 kcl 包 -$ kpm init -# 进入 kcl 包目录 -$ cd -# 上传 kcl 包到 kpm registry -$ kpm push -``` - -### 上传一个 `*.tar` 文件到 kpm registry - -你也可以使用 `kpm push` 命令上传一个 `*.tar` 文件到 kpm registry。 - -```shell -kpm push --tar_path -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/9.pull.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/9.pull.md deleted file mode 100644 index cec49291..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/9.pull.md +++ /dev/null @@ -1,41 +0,0 @@ -# kpm pull - -下载 kcl 包从 kpm registry。 - -## 使用 - -```shell -kpm pull [options][package_source] -``` - -## 介绍 - -`kpm pull` 会从 kpm registry 下载 kcl 包。 - -## 选项 - -### --tag - -使用 oci url 下载包时, 指定要下载的 kcl 包的 tag。 - -### --help, -h - -展示 `kpm pull` 命令的帮助信息。 - -## 示例 - -### 从 kpm registry 下载 kcl 包 - -你可以使用 `kpm pull` 命令从 默认的 kpm registry 下载 kcl 包。 - -```shell -kpm pull : -``` - -### 下载 kcl 包通过 oci url - -你可以使用 `kpm pull` 命令从一个 oci url 下载 kcl 包。 - -```shell -kpm pull --tag -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/_category_.json deleted file mode 100644 index abcc956a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "命令参考", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/index.md deleted file mode 100644 index e3025db9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/package-management/command-reference/index.md +++ /dev/null @@ -1,36 +0,0 @@ -# kpm - -kpm 命令。 - -## 使用 - -```shell -kpm [arguments]... -``` - -## 介绍 - -`kpm` 是 kcl 包管理工具。它用于分发和管理 kcl 包。 - -## 选项 - -### --help, -h - -展示 `kpm` 命令的帮助信息。 - -### --version, -v - -展示 `kpm` 命令的版本信息。 - -## 子命令 - -- [kpm init](./1.init.md) - 初始化一个 kcl 包 -- [kpm add](./2.add.md) - 添加一个依赖到 kcl 包 -- [kpm pkg](./3.pkg.md) - 打包一个 kcl 包为 `*.tar` -- [kpm metadata](./4.metadata.md) - 打印一个 kcl 包的元数据 -- [kpm run](./5.run.md) - 编译一个 kcl 包为 yaml 并运行 -- [kpm login](./6.login.md) - 登录到一个 kcl registry -- [kpm logout](./7.logout.md) - 登出一个 kcl registry -- [kpm push](./8.push.md) - 上传一个 kcl 包到一个 registry -- [kpm pull](./9.pull.md) - 下载一个 kcl 包从一个 registry -- [kpm help](./10.help.md) - 打印 kpm 命令的帮助信息 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/plugin/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/plugin/_category_.json deleted file mode 100644 index 645deb88..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/plugin/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "插件系统", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/plugin/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/plugin/index.md deleted file mode 100644 index e2fe86d6..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/plugin/index.md +++ /dev/null @@ -1 +0,0 @@ -# 插件系统 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/plugin/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/plugin/overview.md deleted file mode 100644 index b3cc9469..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/plugin/overview.md +++ /dev/null @@ -1,183 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 简介 - -KCL 是声明式配置策略语言,对于不方便通过配置直接描述的复杂的业务逻辑可以通过通用的编程语言开发 KCL 插件对语言进行扩展。KCL 支持通过通用语言开发插件,KCL 程序导入插件中的函数。KCL 通过插件运行时和辅助的命令行工具提供插件支持。KCL 插件框架支持多种不同的通用语言开发插件,这里我们以 Python 为例简单说明插件的使用。 - -插件的 Git 仓库: [https://github.com/kcl-lang/kcl-plugin](https://github.com/kcl-lang/kcl-plugin) - -## 0. 前置依赖 - -使用 KCL Python 插件需要您的 `PATH` 中存在 `Python3.7+`。 - -## 1. 你好插件 - -KCL 插件在 KCL 的 `plugins` 子目录(通常安装在 `$HOME/.kcl/plugins` 目录),或者通过 `$KCL_PLUGINS_ROOT` 环境变量设置(环境变量优先级更高)。此外,`plugins` 插件目录还可以放在执行 KCL 命令的 `pwd` 路径或者父路径中。对于插件开发人员,插件都在 Git 仓库管理: [https://github.com/kcl-lang/kcl-plugin](https://github.com/kcl-lang/kcl-plugin) ,可以将插件仓库克隆到该目录进行开发。 - -输入 `kcl-plugin info` 命令查看查看插件目录(将其中的 `/Users/kcl_user` 替换成本地的 `$HOME` 路径): - -```shell -$ kcl-plugin info -# plugin_root: /Users/kcl_user/.kcl/plugins -``` - -通过 `kcl-plugin list` 子命令查看插件列表: - -```shell -$ kcl-plugin list -hello: hello doc - 0.0.1 -``` - -其中 `hello` 是 KCL 内置的示例插件(不要修改改插件)。 - -在 KCL 代码中,可以通过 `kcl_plugin.hello` 导入 `hello` 插件。`main.k` 代码如下: - -```python -import kcl_plugin.hello - -name = "kcl" -three = hello.add(1,2) -``` - -输出结果如下: - -```shell -$ python3 -m kclvm main.k -name: kcl -three: 3 -``` - -## 2. `kcl-plugin` 辅助命令 - -`kcl-plugin` 是提供的插件辅助工具,命令行帮助如下: - -```shell -$ kcl-plugin -usage: kcl-plugin [-h] {list,info,init,gendoc,test} ... -positional arguments: - {list,info,init,gendoc,test} - kcl plugin sub commands - list list all plugins - info show plugin document - init init a new plugin - gendoc gen all plugins document - test test plugin -optional arguments: - -h, --help show this help message and exit -``` - -其中 `list` 子命令用于查看插件列表;`info` 用户查看插件目录和每个插件的信息;`init` 可以用户初始化新插件;`gendoc` 更新全部插件的 API 文档;`test` 测试指定的插件。 - -## 3. 插件信息和文档 - -输入 `kcl-plugin info hello` 查看 `hello` 插件信息: - -```shell -$ kcl-plugin info hello -{ - "name": "hello", - "describe": "hello doc", - "long_describe": "long describe", - "version": "0.0.1", - "method": { - "add": "add two numbers, and return result", - "foo": "no doc", - "list_append": "no doc", - "say_hello": "no doc", - "tolower": "no doc", - "update_dict": "no doc" - } -} -``` - -插件的信息主要包含插件的名字和版本信息,插件提供的函数信息。该信息和插件目录中自动生成的 `api.md` 文件是一致的(插件 API 变化时通过 `kcl-plugin gendoc` 为全部的插件重新生成 `api.md` 文件)。 - -## 4. 插件的目录结构 - -插件的目录结构如下(将其中的 `/Users/kcl_user` 替换成本地的 `$HOME` 路径): - -```shell -$ tree /Users/kcl_user/.kcl/plugins/ -/Users/kcl_user/.kcl/plugins/ -├── _examples -├── _test -└── hello - ├── api.md - ├── plugin.py - └── plugin_test.py -$ -``` - -其中 `_examples` 目录下是插件的示例代码,`_test` 目录下是插件的 KCL 测试代码,其他以字母开头的目录是普通的插件(目录中同时包含 `plugin.py` 和 `plugin_test.py` 文件)。 - -KCL 的插件是有一个独立的纯 Python 代码文件实现,并且插件相互之间不能直接调用。插件的内容如下: - -```shell -$ cat ./hello/plugin.py -# Copyright 2020 The KCL Authors. All rights reserved. -INFO = { - 'name': 'hello', - 'describe': 'hello doc', - 'long_describe': 'long describe', - 'version': '0.0.1', -} -def add(a: int, b: int) -> int: - """add two numbers, and return result""" - return a + b -... -``` - -其中 `INFO` 指明了插件的名字、概要说明、详细说明和版本信息。而所有名字以字母开头的函数是插件给 KCL 提供的函数,因此 KCL 中可以直接调用 `add` 函数。 - -## 5. 创建一个插件 - -通过 `kcl-plugin init` 命令可以创建一个插件示例: - -``` -$ kcl-plugin init hi -$ kcl-plugin list -hello: hello doc - 0.0.1 -hi: hi doc - 0.0.1 -``` - -`kcl-plugin init` 命令会以内置的模板构造一个新的插件,然后通过 `kcl-plugin list` 命令可以查看到新创建的插件。 - -## 6. 插件的删除 - -KCL 插件在 KCL 的 `plugins` 子目录(通常安装在 `$HOME/.kcl/plugins` 目录)。 -可以通过命令 `kcl-plugin info` 查询插件安装目录。 - -```shell -$ kcl-plugin info -/Users/kcl_user/.kcl/plugins/ -$ tree /Users/kcl_user/.kcl/plugins/ -/Users/kcl_user/.kcl/plugins/ -├── _examples -├── _test -└── hello -- 删除这个目录就可以删除 hello plugin - ├── api.md - ├── plugin.py - └── plugin_test.py -$ -``` - -## 7. 插件的测试 - -插件是独立的纯 Python 文件实现,插件目录下有个 `plugin_test.py` 文件是插件的单元测试文件(基于 pytest 测试框架)。此外在 `_test` 目录下放置的是 KCL 文件的插件集成测试。`plugin_test.py` 单元测试是必须的,`_test` 目录下的 KCL 集成测试可以根据情况添加。 - -可以通过 `kcl-plugin test` 执行插件的单元测试: - -```shell -$ kcl-plugin test hello -============================= test session starts ============================== -platform darwin -- Python 3.7.6+, pytest-5.3.5, py-1.9.0, pluggy-0.13.1 -rootdir: /Users/kcl_user -collected 5 items -.kcl/plugins/hello/plugin_test.py ..... [100%] -============================== 5 passed in 0.03s =============================== -$ -``` - -集成测试可以通过在 `_test` 目录下执行 `python3 -m pytest` 命令进行测试。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/_category_.json deleted file mode 100644 index e26f646c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "多语言", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/go-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/go-api.md deleted file mode 100644 index 2a978250..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/go-api.md +++ /dev/null @@ -1,665 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Go API - -```go -import kcl "kcl-lang.io/kcl-go" -``` - -## KCL Go SDK - -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ kcl files │ │ KCL-Go-API │ │ KCLResultList │ -│ ┌───────────┐ │ │ │ │ │ -│ │ 1.k │ │ │ │ │ │ -│ └───────────┘ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ ┌───────────┐ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.Get("a.b.c") │ -│ │ 2.k │ │ │ │ Run(path) │ │ │ └───────────┘ │ └───────────────┘ -│ └───────────┘ │────┐ │ └───────────┘ │ │ │ -│ ┌───────────┐ │ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ │ 3.k │ │ │ │ │ │ │ KCLResult │──┼────────▶│x.Get("k", &v) │ -│ └───────────┘ │ │ │ │ │ └───────────┘ │ └───────────────┘ -│ ┌───────────┐ │ ├───▶│ ┌───────────┐ │──────────▶│ │ -│ │setting.yml│ │ │ │ │RunFiles() │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ └───────────┘ │ │ │ └───────────┘ │ │ │ KCLResult │──┼────────▶│x.JSONString() │ -└─────────────────┘ │ │ │ │ └───────────┘ │ └───────────────┘ - │ │ │ │ │ -┌─────────────────┐ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ Options │ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.YAMLString() │ -│WithOptions │ │ │ │MustRun() │ │ │ └───────────┘ │ └───────────────┘ -│WithOverrides │────┘ │ └───────────┘ │ │ │ -│WithWorkDir │ │ │ │ │ -│WithDisableNone │ │ │ │ │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ -``` - -
Example -

- -```go -{ - const k_code = ` -name = "kcl" -age = 1 - -two = 2 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {} -x1 = Person { - age = 101 -} -` - - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First().YAMLString() - fmt.Println(yaml) - - fmt.Println("----") - - result := kcl.MustRun("./testdata/main.k").First() - fmt.Println(result.JSONString()) - - fmt.Println("----") - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - - fmt.Println("----") - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x1", &person)) -} -``` - -

-
- -## Index - -- [Go API](#go-api) - - [KCL Go SDK](#kcl-go-sdk) - - [Index](#index) - - [Constants](#constants) - - [func FormatCode](#func-formatcode) - - [func FormatPath](#func-formatpath) - - [func InitKclvmPath](#func-initkclvmpath) - - [func InitKclvmRuntime](#func-initkclvmruntime) - - [func LintPath](#func-lintpath) - - [func ListDepFiles](#func-listdepfiles) - - [func ListDownStreamFiles](#func-listdownstreamfiles) - - [func ListUpStreamFiles](#func-listupstreamfiles) - - [func OverrideFile](#func-overridefile) - - [func ValidateCode](#func-validatecode) - - [type KCLResult](#type-kclresult) - - [type KCLResultList](#type-kclresultlist) - - [func MustRun](#func-mustrun) - - [func Run](#func-run) - - [func RunFiles](#func-runfiles) - - [type KclType](#type-kcltype) - - [func GetSchemaType](#func-getschematype) - - [type ListDepFilesOption](#type-listdepfilesoption) - - [type ListDepsOptions](#type-listdepsoptions) - - [type Option](#type-option) - - [func WithCode](#func-withcode) - - [func WithDisableNone](#func-withdisablenone) - - [func WithKFilenames](#func-withkfilenames) - - [func WithOptions](#func-withoptions) - - [func WithOverrides](#func-withoverrides) - - [func WithPrintOverridesAST](#func-withprintoverridesast) - - [func WithSettings](#func-withsettings) - - [func WithSortKeys](#func-withsortkeys) - - [func WithWorkDir](#func-withworkdir) - - [type ValidateOptions](#type-validateoptions) - -## Constants - -KclvmAbiVersion is the current kclvm ABI version. - -```go -const KclvmAbiVersion = scripts.KclvmAbiVersion -``` - -## func [FormatCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L110) - -```go -func FormatCode(code interface{}) ([]byte, error) -``` - -FormatCode returns the formatted code. - -
Example -

- -```go -{ - out, err := kcl.FormatCode(`a = 1+2`) - if err != nil { - log.Fatal(err) - } - fmt.Println(string(out)) - -} -``` - -``` -a = 1 + 2 -``` - -

-
- -## func [FormatPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L122) - -```go -func FormatPath(path string) (changedPaths []string, err error) -``` - -FormatPath formats files from the given path path: if path is \`.\` or empty string, all KCL files in current directory will be formatted, not recursively if path is \`path/file.k\`, the specified KCL file will be formatted if path is \`path/to/dir\`, all KCL files in the specified dir will be formatted, not recursively if path is \`path/to/dir/...\`, all KCL files in the specified dir will be formatted recursively - -the returned changedPaths are the changed file paths \(relative path\) - -
Example -

- -```go -{ - changedPaths, err := kcl.FormatPath("testdata/fmt") - if err != nil { - log.Fatal(err) - } - fmt.Println(changedPaths) -} -``` - -

-
- -## func [InitKclvmPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L54) - -```go -func InitKclvmPath(kclvmRoot string) -``` - -InitKclvmPath init kclvm path. - -## func [InitKclvmRuntime](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L59) - -```go -func InitKclvmRuntime(n int) -``` - -InitKclvmRuntime init kclvm process. - -## func [LintPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L142) - -```go -func LintPath(paths []string) (results []string, err error) -``` - -LintPath lint files from the given path - -
Example -

- -```go -{ - - results, err := kcl.LintPath([]string{"testdata/lint/import.k"}) - if err != nil { - log.Fatal(err) - } - for _, s := range results { - fmt.Println(s) - } - -} -``` - -``` -Module 'a' is reimported multiple times -Module 'a' imported but unused -``` - -

-
- -## func [ListDepFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L127) - -```go -func ListDepFiles(workDir string, opt *ListDepFilesOption) (files []string, err error) -``` - -ListDepFiles return the depend files from the given path - -## func [ListDownStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L137) - -```go -func ListDownStreamFiles(workDir string, opt *ListDepsOptions) ([]string, error) -``` - -ListDownStreamFiles return a list of downstream depend files from the given changed path list. - -## func [ListUpStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L132) - -```go -func ListUpStreamFiles(workDir string, opt *ListDepsOptions) (deps []string, err error) -``` - -ListUpStreamFiles return a list of upstream depend files from the given path list - -## func [OverrideFile](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L154) - -```go -func OverrideFile(file string, specs, importPaths []string) (bool, error) -``` - -OverrideFile rewrites a file with override spec file: string. The File that need to be overridden specs: \[\]string. List of specs that need to be overridden. - -``` -Each spec string satisfies the form: := or :- -When the pkgpath is '__main__', it can be omitted. -``` - -importPaths. List of import statements that need to be added - -## func [ValidateCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L159) - -```go -func ValidateCode(data, code string, opt *ValidateOptions) (ok bool, err error) -``` - -ValidateCode validate data match code - -## type [KCLResult](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L47) - -```go -type KCLResult = kcl.KCLResult -``` - -
Example -

- -```go -{ - const k_code = ` -name = "kcl" -age = 1 - -two = 2 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {name = "kcl-go"} -x1 = Person {age = 101} -` - - result := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First() - - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - -} -``` - -``` -x0.name: kcl-go -x1.age: 101 -``` - -

-
- -
Example ('et_struct) -

- -```go -{ - const k_code = ` -schema Person: - name: str = "kcl" - age: int = 1 - X: int = 2 - -x = { - "a": Person {age = 101} - "b": 123 -} -` - - result := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First() - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x.a", &person)) - fmt.Printf("person: %+v\n", person) - -} -``` - -``` -person: &{Name:kcl Age:101} -person: {Name:kcl Age:101} -``` - -

-
- -## type [KCLResultList](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L48) - -```go -type KCLResultList = kcl.KCLResultList -``` - -### func [MustRun](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L64) - -```go -func MustRun(path string, opts ...Option) *KCLResultList -``` - -MustRun is like Run but panics if return any error. - -
Example -

- -```go -{ - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(`name = "kcl"`)).First().YAMLString() - fmt.Println(yaml) - -} -``` - -``` -name: kcl -``` - -

-
- -
Example (Raw Yaml) -

- -```go -{ - const code = ` -b = 1 -a = 2 -` - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(code)).GetRawYamlResult() - fmt.Println(yaml) - - yaml_sorted := kcl.MustRun("testdata/main.k", kcl.WithCode(code), kcl.WithSortKeys(true)).GetRawYamlResult() - fmt.Println(yaml_sorted) - -} -``` - -``` -b: 1 -a: 2 -a: 2 -b: 1 -``` - -

-
- -
Example (Schema Type) -

- -```go -{ - const code = ` -schema Person: - name: str = "" - -x = Person() -` - json := kcl.MustRun("testdata/main.k", kcl.WithCode(code)).First().JSONString() - fmt.Println(json) - -} -``` - -``` -{ - "x": { - "name": "" - } -} -``` - -

-
- -
Example (Settings) -

- -```go -{ - yaml := kcl.MustRun("./testdata/app0/kcl.yaml").First().YAMLString() - fmt.Println(yaml) -} -``` - -

-
- -### func [Run](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L69) - -```go -func Run(path string, opts ...Option) (*KCLResultList, error) -``` - -Run evaluates the KCL program with path and opts, then returns the object list. - -
Example (Get Field) -

- -```go -{ - - x, err := kcl.Run("./testdata/app0/kcl.yaml") - assert(err == nil, err) - - fmt.Println(x.First().Get("deploy_topology.1.zone")) - -} -``` - -``` -R000A -``` - -

-
- -### func [RunFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L74) - -```go -func RunFiles(paths []string, opts ...Option) (*KCLResultList, error) -``` - -RunFiles evaluates the KCL program with multi file path and opts, then returns the object list. - -
Example -

- -```go -{ - result, _ := kcl.RunFiles([]string{"./testdata/app0/kcl.yaml"}) - fmt.Println(result.First().YAMLString()) -} -``` - -

-
- -## type [KclType](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L50) - -```go -type KclType = kcl.KclType -``` - -### func [GetSchemaType](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L176) - -```go -func GetSchemaType(file, code, schemaName string) ([]*KclType, error) -``` - -GetSchemaType returns schema types from a kcl file or code. - -file: string - -``` -The kcl filename -``` - -code: string - -``` -The kcl code string -``` - -schema_name: string - -``` -The schema name got, when the schema name is empty, all schemas are returned. -``` - -## type [ListDepFilesOption](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L45) - -```go -type ListDepFilesOption = list.Option -``` - -## type [ListDepsOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L44) - -```go -type ListDepsOptions = list.DepOptions -``` - -## type [Option](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L43) - -```go -type Option = kcl.Option -``` - -### func [WithCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L79) - -```go -func WithCode(codes ...string) Option -``` - -WithCode returns a Option which hold a kcl source code list. - -### func [WithDisableNone](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L97) - -```go -func WithDisableNone(disableNone bool) Option -``` - -WithDisableNone returns a Option which hold a disable none switch. - -### func [WithKFilenames](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L82) - -```go -func WithKFilenames(filenames ...string) Option -``` - -WithKFilenames returns a Option which hold a filenames list. - -### func [WithOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L85) - -```go -func WithOptions(key_value_list ...string) Option -``` - -WithOptions returns a Option which hold a key=value pair list for option function. - -
Example -

- -```go -{ - const code = ` -name = option("name") -age = option("age") -` - x, err := kcl.Run("hello.k", kcl.WithCode(code), - kcl.WithOptions("name=kcl", "age=1"), - ) - if err != nil { - log.Fatal(err) - } - - fmt.Println(x.First().YAMLString()) - -} -``` - -``` -age: 1 -name: kcl -``` - -

-
- -### func [WithOverrides](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L88) - -```go -func WithOverrides(override_list ...string) Option -``` - -WithOverrides returns a Option which hold a override list. - -### func [WithPrintOverridesAST](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L100) - -```go -func WithPrintOverridesAST(printOverridesAST bool) Option -``` - -WithPrintOverridesAST returns a Option which hold a printOverridesAST switch. - -### func [WithSettings](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L91) - -```go -func WithSettings(filename string) Option -``` - -WithSettings returns a Option which hold a settings file. - -### func [WithSortKeys](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L105) - -```go -func WithSortKeys(sortKeys bool) Option -``` - -WithSortKeys returns a Option which hold a sortKeys switch. - -### func [WithWorkDir](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L94) - -```go -func WithWorkDir(workDir string) Option -``` - -WithWorkDir returns a Option which hold a work dir. - -## type [ValidateOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L46) - -```go -type ValidateOptions = validate.ValidateOptions -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/index.md deleted file mode 100644 index ea02d458..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/index.md +++ /dev/null @@ -1 +0,0 @@ -# 多语言 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/java-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/java-api.md deleted file mode 100644 index 1cea9e49..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/java-api.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Java API - -目前 KCL Java SDK 还处于早期预览版本,后续 KCL 团队会持续更新并提供更丰富的功能,更多信息请参阅:[https://github.com/kcl-lang/kcl-java](https://github.com/kcl-lang/kcl-java)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/overview.md deleted file mode 100644 index 29c8680d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/overview.md +++ /dev/null @@ -1,295 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 简介 - -KCL 语言提供 C/Rust/Go/Python/Java 等通用编程语言接口,相关语言正在开发完整中。 - -## C/Rust 语言 - -KCL 核心采用 Rust 语言开发,对外导出 C 语言 API 供 Go/Python/Java 等高级语言包装和集成。 - -## Go 语言 - -Go 语言是通过 CGO 包装 KCL 提供的 C-API,同时提供更深度的定制特性以满足上层工具的需求。 - -### API 抽象模型 - -Go 语言 API 的抽象模型如下图: - -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ kcl files │ │ KCL-Go-API │ │ KCLResultList │ -│ ┌───────────┐ │ │ │ │ │ -│ │ 1.k │ │ │ │ │ │ -│ └───────────┘ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ ┌───────────┐ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.Get("a.b.c") │ -│ │ 2.k │ │ │ │ Run(path) │ │ │ └───────────┘ │ └───────────────┘ -│ └───────────┘ │────┐ │ └───────────┘ │ │ │ -│ ┌───────────┐ │ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ │ 3.k │ │ │ │ │ │ │ KCLResult │──┼────────▶│x.Get("k", &v) │ -│ └───────────┘ │ │ │ │ │ └───────────┘ │ └───────────────┘ -│ ┌───────────┐ │ ├───▶│ ┌───────────┐ │──────────▶│ │ -│ │setting.yml│ │ │ │ │RunFiles() │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ └───────────┘ │ │ │ └───────────┘ │ │ │ KCLResult │──┼────────▶│x.JSONString() │ -└─────────────────┘ │ │ │ │ └───────────┘ │ └───────────────┘ - │ │ │ │ │ -┌─────────────────┐ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ Options │ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.YAMLString() │ -│WithOptions │ │ │ │MustRun() │ │ │ └───────────┘ │ └───────────────┘ -│WithOverrides │────┘ │ └───────────┘ │ │ │ -│WithWorkDir │ │ │ │ │ -│WithDisableNone │ │ │ │ │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ -``` - -其中输入的文件包含 KCL 文件和 `setting.yml` 配置文件,`Options` 可以用于指定额外的参数和工作目录等信息。“KCL-Go-API”部分是提供的 KCL 执行函数,执行函数根据输入文件和额外的参数执行 KCL 程序,最终输出 `KCLResultList` 结果。`KCLResultList` 是一个 `KCLResult` 构成的列表,每个 `KCLResult` 对应一个生成的配置文件或 `map[string]interface{}`。 - -### 例子 - -```go -package main - -import ( - "fmt" - - kcl "kcl-lang.io/kcl-go" -) - - -func main() { - const k_code = ` -name = "kcl" -age = 1 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person{} -x1 = Person{age:101} -` - - result := kcl.MustRun("hello.k", kcl.WithCode(k_code)).First() - fmt.Println(result.YAMLString()) - - fmt.Println("----") - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - - fmt.Println("----") - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x1", &person)) -} -``` - -输出结果: - -```yaml -age: 1 -name: kcl -x0: - age: 1 - name: kcl -x1: - age: 101 - name: kcl - ----- -x0.name: kcl -x1.age: 101 ----- -person: &{Name:kcl Age:101} -``` - -## REST-API - -KCL 提供的 C-API 并没有 REST-API,REST-API 是通过 Protobuf 定义,最终由上层的 Go-SDK 提供实现。 - -### 启动 REST 服务 - -通过以下方式可以启动 RestAPI 服务: - -```shell -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -然后可以通过 POST 协议请求服务: - -```shell -$ curl -X POST http://127.0.0.1:2021/api:protorpc/BuiltinService.Ping --data '{}' -{ - "error": "", - "result": {} -} -``` - -其中 POST 请求和返回的 JSON 数据和 Protobuf 定义的结构保持一致。 - -### `BuiltinService` 服务 - -其中 `/api:protorpc/BuiltinService.Ping` 路径表示 `BuiltinService` 服务的 `Ping` 方法。 - -完整的 `BuiltinService` 由 Protobuf 定义: - -```protobuf -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} -``` - -其中 `Ping` 方法可以验证服务是否正常,`ListMethod` 方法可以查询提供的全部服务和函数列表。 - -### `KclvmService` 服务 - -`KclvmService` 服务是和 KCL 功能相关的服务。用法和 `BuiltinService` 服务一样。 - -比如有以下的 `Person` 结构定义: - -```python -schema Person: - key: str - - check: - "value" in key # 'key' is required and 'key' must contain "value" -``` - -然后希望通过 `Person` 来校验以下的 JSON 数据: - -```json -{ "key": "value" } -``` - -可以通过 `KclvmService` 服务的 `ValidateCode` 方法完成。参考 `ValidateCode` 方法的 `ValidateCode_Args` 参数结构: - -```protobuf -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} -``` - -根据 `ValidateCode_Args` 参数结构构造 POST 请求需要的 JSON 数据,其中包含 `Person` 定义和要校验的 JSON 数据: - -```json -{ - "code": "\nschema Person:\n key: str\n\n check:\n \"value\" in key # 'key' is required and 'key' must contain \"value\"\n", - "data": "{\"key\": \"value\"}" -} -``` - -将该 JSON 数据保存到 `vet-hello.json` 文件,然后通过以下命令进行校验: - -```shell -$ curl -X POST \ - http://127.0.0.1:2021/api:protorpc/KclvmService.ValidateCode \ - -H "accept: application/json" \ - --data @./vet-hello.json -{ - "error": "", - "result": { - "success": true - } -} -``` - -说明校验成功。 - -## Python 语言 - -使用 Python SDK 要求您本地具备高于 3.7.3 的 Python 版本和 pip 包管理工具,可以通过如下命令进行安装并获得帮助信息 - -```bash -python3 -m pip install kclvm --user && python3 -m kclvm --help -``` - -### 命令行工具 - -编写名为 `main.k` 的 KCL 文件: - -```python -name = "kcl" -age = 1 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {} -x1 = Person { - age = 101 -} -``` - -执行如下命令并获得输出: - -```shell -$ python3 -m kclvm hello.k -name: kcl -age: 1 -x0: - name: kcl - age: 1 -x1: - name: kcl - age: 101 -``` - -### API - -此外,我们还可以通过 Python 代码实现对 KCL 文件的执行 - -编写名为 `main.py` 的 python 文件: - -```python -import kclvm.program.exec as kclvm_exec -import kclvm.vm.planner as planner - -print(planner.plan(kclvm_exec.Run(["hello.k"]).filter_by_path_selector())) -``` - -执行如下命令并获得输出: - -```shell -$ python3 main.py -name: kcl -age: 1 -x0: - name: kcl - age: 1 -x1: - name: kcl - age: 101 -``` - -可以看出通过命令行工具和 API 可以获得同样的输出。 - -目前 KCL Python SDK 还处于早期预览版本,后续 KCL 团队会持续更新并提供更丰富的功能,更多信息请参阅:[https://github.com/kcl-lang/kcl-py](https://github.com/kcl-lang/kcl-py) - -## 其它语言 - -用户也可以基于 C-API 和 RestAPI 包装其它语言的 SDK。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/python-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/python-api.md deleted file mode 100644 index ad3ad867..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/python-api.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Python API - -目前 KCL Python SDK 还处于早期预览版本,后续 KCL 团队会持续更新并提供更丰富的功能,更多信息请参阅:[https://github.com/kcl-lang/kcl-py](https://github.com/kcl-lang/kcl-py)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/rest-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/rest-api.md deleted file mode 100644 index 74a9bf4c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/xlang-api/rest-api.md +++ /dev/null @@ -1,455 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Rest API - -## 1. 启动 REST 服务 - -通过以下方式可以启动 RestAPI 服务: - -```shell -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -或者 - -```shell -go install kcl-lang.io/kcl-go/cmds/kcl-go@main -kcl-go rest-server -``` - -然后可以通过 POST 协议请求服务: - -```shell -curl -X POST http://127.0.0.1:2021/api:protorpc/BuiltinService.Ping --data '{}' -``` - -期望输出为 - -```shell -{ - "error": "", - "result": {} -} -``` - -其中 POST 请求和返回的 JSON 数据和 Protobuf 定义的结构保持一致。 - -## 2. `BuiltinService` 服务 - -其中 `/api:protorpc/BuiltinService.Ping` 路径表示 `BuiltinService` 服务的 `Ping` 方法。 - -完整的 `BuiltinService` 由 Protobuf 定义: - -```protobuf -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} -``` - -其中 `Ping` 方法可以验证服务是否正常,`ListMethod` 方法可以查询提供的全部服务和函数列表。 - -## 3. `KclvmService` 服务 - -`KclvmService` 服务是和 KCL 功能相关的服务。用法和 `BuiltinService` 服务一样。 - -比如有以下的 `Person` 结构定义: - -```python -schema Person: - key: str - - check: - "value" in key # 'key' is required and 'key' must contain "value" -``` - -然后希望通过 `Person` 来校验以下的 JSON 数据: - -```json -{ "key": "value" } -``` - -可以通过 `KclvmService` 服务的 `ValidateCode` 方法完成。参考 `ValidateCode` 方法的 `ValidateCode_Args` 参数结构: - -```protobuf -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} -``` - -根据 `ValidateCode_Args` 参数结构构造 POST 请求需要的 JSON 数据,其中包含 `Person` 定义和要校验的 JSON 数据: - -```json -{ - "code": "\nschema Person:\n key: str\n\n check:\n \"value\" in key # 'key' is required and 'key' must contain \"value\"\n", - "data": "{\"key\": \"value\"}" -} -``` - -将该 JSON 数据保存到 `vet-hello.json` 文件,然后通过以下命令进行校验: - -```shell -curl -X POST \ - http://127.0.0.1:2021/api:protorpc/KclvmService.ValidateCode \ - -H "accept: application/json" \ - --data @./vet-hello.json -``` - -如果看到输出 - -```json -{ - "error": "", - "result": { - "success": true - } -} -``` - -说明校验成功。 - -## 4. 完整的 Protobuf 服务定义 - -跨语言的 API 通过 Protobuf 定义([https://github.com/kcl-lang/kcl-go/blob/main/pkg/spec/gpyrpc/gpyrpc.proto](https://github.com/kcl-lang/kcl-go/blob/main/pkg/spec/gpyrpc/gpyrpc.proto)): - -```protobuf -// Copyright 2023 The KCL Authors. All rights reserved. -// -// This file defines the request parameters and return structure of the KCL RPC server. -// We can use the following command to start a KCL RPC server. - -syntax = "proto3"; - -package gpyrpc; - -import "google/protobuf/any.proto"; -import "google/protobuf/descriptor.proto"; - -// ---------------------------------------------------------------------------- - -// kcl main.k -D name=value -message CmdArgSpec { - string name = 1; - string value = 2; -} - -// kcl main.k -O pkgpath:path.to.field=field_value -message CmdOverrideSpec { - string pkgpath = 1; - string field_path = 2; - string field_value = 3; - string action = 4; -} - -// ---------------------------------------------------------------------------- -// gpyrpc request/response/error types -// ---------------------------------------------------------------------------- - -message RestResponse { - google.protobuf.Any result = 1; - string error = 2; - KclError kcl_err = 3; -} - -message KclError { - string ewcode = 1; // See kclvm/kcl/error/kcl_err_msg.py - string name = 2; - string msg = 3; - repeated KclErrorInfo error_infos = 4; -} - -message KclErrorInfo { - string err_level = 1; - string arg_msg = 2; - string filename = 3; - string src_code = 4; - string line_no = 5; - string col_no = 6; -} - -// ---------------------------------------------------------------------------- -// service requset/response -// ---------------------------------------------------------------------------- - -// gpyrpc.BuiltinService -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -// gpyrpc.KclvmService -service KclvmService { - rpc Ping(Ping_Args) returns(Ping_Result); - - rpc ExecProgram(ExecProgram_Args) returns(ExecProgram_Result); - - rpc FormatCode(FormatCode_Args) returns(FormatCode_Result); - rpc FormatPath(FormatPath_Args) returns(FormatPath_Result); - rpc LintPath(LintPath_Args) returns(LintPath_Result); - rpc OverrideFile(OverrideFile_Args) returns (OverrideFile_Result); - - rpc GetSchemaType(GetSchemaType_Args) returns(GetSchemaType_Result); - rpc GetSchemaTypeMapping(GetSchemaTypeMapping_Args) returns(GetSchemaTypeMapping_Result); - rpc ValidateCode(ValidateCode_Args) returns(ValidateCode_Result); - - rpc ListDepFiles(ListDepFiles_Args) returns(ListDepFiles_Result); - rpc LoadSettingsFiles(LoadSettingsFiles_Args) returns(LoadSettingsFiles_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} - -message ParseFile_AST_Args { - string filename = 1; - string source_code = 2; -} -message ParseFile_AST_Result { - string ast_json = 1; // json value - KclError kcl_err = 2; -} - -message ParseProgram_AST_Args { - repeated string k_filename_list = 1; -} -message ParseProgram_AST_Result { - string ast_json = 1; // json value - KclError kcl_err = 2; -} - -message ExecProgram_Args { - string work_dir = 1; - - repeated string k_filename_list = 2; - repeated string k_code_list = 3; - - repeated CmdArgSpec args = 4; - repeated CmdOverrideSpec overrides = 5; - - bool disable_yaml_result = 6; - - bool print_override_ast = 7; - - // -r --strict-range-check - bool strict_range_check = 8; - - // -n --disable-none - bool disable_none = 9; - // -v --verbose - int32 verbose = 10; - - // -d --debug - int32 debug = 11; - - // yaml/json: sort keys - bool sort_keys = 12; - // include schema type path in JSON/YAML result - bool include_schema_type_path = 13; -} -message ExecProgram_Result { - string json_result = 1; - string yaml_result = 2; - - string escaped_time = 101; -} - -message ResetPlugin_Args { - string plugin_root = 1; -} -message ResetPlugin_Result { - // empty -} - -message FormatCode_Args { - string source = 1; -} - -message FormatCode_Result { - bytes formatted = 1; -} - -message FormatPath_Args { - string path = 1; -} - -message FormatPath_Result { - repeated string changed_paths = 1; -} - -message LintPath_Args { - repeated string paths = 1; -} - -message LintPath_Result { - repeated string results = 1; -} - -message OverrideFile_Args { - string file = 1; - repeated string specs = 2; - repeated string import_paths = 3; -} - -message OverrideFile_Result { - bool result = 1; -} - -message EvalCode_Args { - string code = 1; -} -message EvalCode_Result { - string json_result = 2; -} - -message ResolveCode_Args { - string code = 1; -} - -message ResolveCode_Result { - bool success = 1; -} - -message GetSchemaType_Args { - string file = 1; - string code = 2; - string schema_name = 3; -} -message GetSchemaType_Result { - repeated KclType schema_type_list = 1; -} - -message GetSchemaTypeMapping_Args { - string file = 1; - string code = 2; - string schema_name = 3; -} -message GetSchemaTypeMapping_Result { - map schema_type_mapping = 1; -} - -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} - -message ValidateCode_Result { - bool success = 1; - string err_message = 2; -} - -message Position { - int64 line = 1; - int64 column = 2; - string filename = 3; -} - -message ListDepFiles_Args { - string work_dir = 1; - bool use_abs_path = 2; - bool include_all = 3; - bool use_fast_parser = 4; -} - -message ListDepFiles_Result { - string pkgroot = 1; - string pkgpath = 2; - repeated string files = 3; -} - -// --------------------------------------------------------------------------------- -// LoadSettingsFiles API -// Input work dir and setting files and return the merged kcl singleton config. -// --------------------------------------------------------------------------------- - -message LoadSettingsFiles_Args { - string work_dir = 1; - repeated string files = 2; -} - -message LoadSettingsFiles_Result { - CliConfig kcl_cli_configs = 1; - repeated KeyValuePair kcl_options = 2; -} - -message CliConfig { - repeated string files = 1; - string output = 2; - repeated string overrides = 3; - repeated string path_selector = 4; - bool strict_range_check = 5; - bool disable_none = 6; - int64 verbose = 7; - bool debug = 8; -} - -message KeyValuePair { - string key = 1; - string value = 2; -} - -// ---------------------------------------------------------------------------- -// JSON Schema Lit -// ---------------------------------------------------------------------------- - -message KclType { - string type = 1; // schema, dict, list, str, int, float, bool, any, union, number_multiplier - repeated KclType union_types = 2 ; // union types - string default = 3; // default value - - string schema_name = 4; // schema name - string schema_doc = 5; // schema doc - map properties = 6; // schema properties - repeated string required = 7; // required schema properties, [property_name1, property_name2] - - KclType key = 8; // dict key type - KclType item = 9; // dict/list item type - - int32 line = 10; - - repeated Decorator decorators = 11; // schema decorators -} - -message Decorator { - string name = 1; - repeated string arguments = 2; - map keywords = 3; -} - -// ---------------------------------------------------------------------------- -// END -// ---------------------------------------------------------------------------- -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/Ide/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/Ide/_category_.json deleted file mode 100644 index fcdc7f10..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/Ide/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "集成开发环境", - "position": 2 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/Ide/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/Ide/index.md deleted file mode 100644 index 2ba6e5b4..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/Ide/index.md +++ /dev/null @@ -1,6 +0,0 @@ -# IDE - -我们为 KCL 提供了两种简单的 IDE 插件。您可以通过以下链接获得更多帮助信息: - -- IntelliJ 插件: https://github.com/kcl-lang/intellij-kcl -- VSCode 插件: https://github.com/kcl-lang/vscode-kcl diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/_category_.json deleted file mode 100644 index 5170334a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "工具", - "position": 3 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/_category_.json deleted file mode 100644 index 8fac9ad8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "命令行工具", - "position": 1 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/index.md deleted file mode 100644 index f754b5ca..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# 命令行工具 - -KCL 提供了 IDE 插件、丰富的语言工具和 OpenAPI 工具。通过这些工具,可以提供一整套解决方案,包括配置语言、模型界面、自动化工具和最佳实践。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/_category_.json deleted file mode 100644 index b22440b7..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KCL 语言工具", - "position": 2 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/docgen.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/docgen.md deleted file mode 100644 index 37b660ed..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/docgen.md +++ /dev/null @@ -1,313 +0,0 @@ ---- -sidebar_position: 5 ---- - -# 文档生成工具 - -KCL 命令行工具支持从 KCL 源码中一键提取模型文档,并支持丰富的输出格式:JSON,YAML 和 Markdown 等。本文介绍 KCL 语言的文档规范,举例说明如何使用 KCL 文档生成工具提取文档,并展示新增本地化语言文档的流程。 - -## 1. KCL 语言的文档规范 - -KCL文件的文档主要包含如下两个部分: - -- 当前 KCL Moudle 的文档:对当前 KCL 文件的说明 -- KCL 文件内包含的所有 Schema 的文档:对当前 Schema 的说明,其中包含 Schema 描述、Schema 各属性的描述、Examples 三部分,具体格式如下: - -1. Schema 描述 - -```python -"""这是Schema一个简短的描述信息 -""" -``` - -2. Schema 各属性的描述:包含属性描述、属性类型、默认值、是否可选 - -```python -""" -Attributes ----------- -x : type, default is a, optional. - Description of parameter `x`. -y : type, default is b, required. - Description of parameter `y`. -""" -``` - -其中,使用 `----------` 表示 `Attributes` 为一个标题(`-` 符号长度与标题长度保持一致),属性名称与属性类型用冒号 `:` 分隔,属性的说明另起一行并增加缩进进行书写。属性的默认值说明跟在属性类型之后使用逗号 `,` 分隔,书写为 `default is {默认值}` 形式,此外需要说明属性是否为可选/必选,对于可选属性在默认值之后书写 `optional`,对于必选属性在默认值之后书写 `required`。 - -3. Examples - -```python -""" -Examples --------- -val = Schema { - name = "Alice" - age = 18 -} -""" -``` - -此外,KCL 文档字符串语法应采用 [re-structured text (reST)](https://docutils.sourceforge.io/rst.html) 语法子集,并使用 [Sphinx](https://www.sphinx-doc.org/en/master/) 渲染呈现。 - -## 2. 从 KCL 源码生成文档 - -使用 kcl-doc generate 命令,从用户指定的文件或目录中提取文档,并输出到指定目录。 - -1. 参数说明 - -``` -usage: kcl-doc generate [-h] [--format YAML] [-o OUTPUT] [--r] - [--i18n-locale LOCALE] [--repo-url REPO_URL] - [files [files ...]] - -positional arguments: - files KCL file paths. If there's more than one files to - generate, separate them by space - -optional arguments: - -h, --help show this help message and exit - --format YAML Doc file format, support YAML, JSON and MARKDOWN. - Defaults to MARKDOWN - -o OUTPUT, --output-path OUTPUT - Specify the output directory. Defaults to ./kcl_doc - --r, -R, --recursive Search directory recursively - --i18n-locale LOCALE I18n locale, e.g.: zh, zh_cn, en, en_AS. Defaults to - en - --repo-url REPO_URL The source code repository url. It will be displayed in - the generated doc to link to the source code. -``` - -2. 从指定的一个或多个文件中提取文档,并输出到指定目录 - -```text -kcl-doc generate your_config.k your_another_config.k -o your_docs_output_dir -``` - -3. 从指定目录内,递归地查找 KCL 源码文件,并提取文档 - -```text -kcl-doc generate your_config_dir -r -o your_docs_output_dir -``` - -4. 在生成文档时,指定源码仓库地址。一经指定,生成的文档中将包含指向源码文件的链接 - -```text -kcl-doc generate your_config.k -o your_docs_output_dir --repo-url https://url/to/source_code -``` - -## 3. 新增本地化语言的文档 - -如前所示,默认情况下,文档生成工具提取的文档以源码 docstring 的内容为准,因而文档的语言随 docstring 编写语言而定。如果需要为源文件新增本地化语言的文档,则可以遵循按如下步骤: - -1. 初始化 i18n 配置文件。该步骤基于指定的 KCL 源码文件,生成相应的 i18n 配置文件,文件格式可选 JSON/YAML,默认为 YAML. 输出的配置文件名称将以指定的目标本地化方言结尾 - -```text -kcl-doc init-i18n your_config.k --format JSON --i18n-locale your_target_locale -``` - -2. 手动修改上述生成的 i18n 配置文件,使用目标语言修改配置中的 doc 字段 - -3. 基于修改后的 i18n 配置,生成本地化语言的文档。工具将查找指定目标语言的 i18n 配置文件,并转化为最终的文档 - -```text -kcl-doc generate your_config_dir --i18n-locale your_target_locale --format Markdown -``` - -接下来,通过一个小例子演示新增本地化语言文档的过程。 - -3.1 准备 KCL 源码文件,例如 server.k: - - ```python - schema Server: - """Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - - Attributes - ---------- - workloadType : str, default is "Deployment", required - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - name : str, required - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - labels : {str:str}, optional - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - - Examples - ---------------------- - myCustomApp = AppConfiguration { - name = "componentName" - } - """ - - workloadType: str = "Deployment" - name: str - labels?: {str: str} - ``` - -3.2 从 server.k 得到初始化的 i18n 配置文件,例如希望为其增加中文文档,指定生成的配置文件格式为 YAML - - ```text - kcl-doc init-i18n server.k --format YAML --i18n-locale zh_cn - ``` - - 该命令将在当前目录下创建 kcl_doc 目录,并生成 i18n 配置文件 kcl_doc/i18n_server_zh_cn.yaml,其内容如下: - - ```yaml - name: server - relative_path: ./server.k - schemas: - - name: Server - doc: | - Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - attributes: - - name: workloadType - doc: | - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - default_value: '"Deployment"' - is_optional: false - - name: name - doc: | - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: false - default_value: '' - - name: labels - doc: | - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - type: - type_str: '{str: str}' - type_category: DICT - dict_type: - key_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - value_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: true - default_value: '' - examples: | - myCustomApp = AppConfiguration { - name = "componentName" - } - doc: '' - source_code_url: '' - ``` - -3.3 修改初始化得到的 i18n 配置,将其中的 doc 字段修改为中文的描述,修改后的配置如下: - - ```yaml - name: server - relative_path: ./server.k - schemas: - - name: Server - doc: | - Server 模型定义了采用 Kubernetes 最佳实践的持续运行的服务的通用配置接口 - attributes: - - name: workloadType - doc: | - workloadType 属性定义了服务的类型,是服务级别的属性。合法的取值有:Deployment, CafeDeployment. - 另请查看:k8s/core/v1/workload_metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - default_value: '"Deployment"' - is_optional: false - - name: name - doc: | - name 为服务的名称,是服务级别的属性。 - 另请查看:k8s/core/v1/metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: false - default_value: '' - - name: labels - doc: | - labels 为服务的标签,是服务级别的属性。 - 另请查看:k8s/core/v1/metadata.k. - type: - type_str: '{str: str}' - type_category: DICT - dict_type: - key_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - value_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: true - default_value: '' - examples: | - myCustomApp = AppConfiguration { - name = "componentName" - } - doc: '' - source_code_url: '' - ``` - -3.4 基于修改后的 i18n 配置,生成本地化语言的文档,执行如下命令,将输出中文的文档 kcl_doc/doc_server_zh_cn.md,命令及生成的文档内容如下: - - ```text - kcl-doc generate server.k --i18n-locale zh_cn --format Markdown - ``` - - ~~~markdown - # server - ## Schema Server - Server 模型定义了采用 Kubernetes 最佳实践的持续运行的服务的通用配置接口 - - ### Attributes - |Name and Description|Type|Default Value|Required| - |--------------------|----|-------------|--------| - |**workloadType**
workloadType 属性定义了服务的类型,是服务级别的属性。合法的取值有:Deployment, CafeDeployment.
另请查看:k8s/core/v1/workload_metadata.k.|str|"Deployment"|**required**| - |**name**
name 为服务的名称,是服务级别的属性。
另请查看:k8s/core/v1/metadata.k.|str|Undefined|**required**| - |**labels**
labels 为服务的标签,是服务级别的属性。
另请查看:k8s/core/v1/metadata.k.|{str: str}|Undefined|optional| - ### Examples - ``` - myCustomApp = AppConfiguration { - name = "componentName" - } - ``` - - - - ~~~ - -## 4. 附录 - -### 1. 常见的 reST 概念 - -对于 reST 格式的文档,段落和缩进很重要,新段落用空白行标记,缩进即为表示输出中的缩进。可以使用如下方式表示字体样式: - -- \*斜体\* -- \*\*粗体\*\* -- \`\`等宽字体\`\` - -参考 [reST 文档](https://docutils.sourceforge.io/rst.html)获得更多帮助。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/fmt.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/fmt.md deleted file mode 100644 index 11199215..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/fmt.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -sidebar_position: 2 ---- - -# 格式化代码 - -KCL 支持通过内置的命令行工具一键格式化多个 KCL 文件文档。本文展示 KCL 编码风格和 KCL 格式化工具的使用方式。 - -## KCL 编码风格 - -KCL 格式化对文件的修改样式具体见 KCL 编码风格:[Style Guide for KCL Code](/docs/reference/lang/spec/codestyle) - -## 使用方式 - -- 单文件格式化 - -```text -kcl-fmt your_config.k -``` - -- 文件夹内多文件格式化 - -```text -kcl-fmt your_config_path -R -``` - -- 命令行参数 - - `-R|--recursive` 设置是否递归遍历子文件夹 - - `-w|--fmt-output` 设置是否输出到标准输出流,不加 `-w` 表示原地格式化 KCL 文件 - -## 格式化文件效果展示 - -- 格式化前 - -```py -import math -mixin DeploymentMixin: - service:str ="my-service" -schema DeploymentBase: - name: str - image : str -schema Deployment[replicas] ( DeploymentBase ) : - mixin[DeploymentMixin] - replicas : int = replicas - command: [str ] - labels: {str: str} -deploy = Deployment(replicas = 3){} -``` - -- 格式化后 - -```py -import math - -mixin DeploymentMixin: - service: str = "my-service" - -schema DeploymentBase: - name: str - image: str - -schema Deployment[replicas](DeploymentBase): - mixin [DeploymentMixin] - replicas: int = replicas - command: [str] - labels: {str:str} - -deploy = Deployment(replicas=3) {} - -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/index.md deleted file mode 100644 index 51f69ee6..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# KCL 语言工具 - -KCL 不仅提供了 kcl 命令编译和执行配置程序,还提供了 fmt、lint、test、vet、docgen 等配套的辅助工具。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/lint.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/lint.md deleted file mode 100644 index 7a66d3b3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/lint.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Lint 检查代码风格 - -KCL 支持通过内置的命令行工具对 KCL 代码进行检查,并支持多种输出格式。本文档展示 KCL Lint 工具的使用方式。 - -## 示例 - -### 工程结构 - -```text -. -└── Test - └── kcl.mod - └── a.k - └── b.k - └── dir - └── c.k - └── test.k -``` - -`a.k`,`b.k`,`c.k`,`test.k` 为测试的 kcl 文件。 - -命令: - -```shell -kcl-lint your_config.k -``` - -或 - -```shell -kcl-lint your_config_path -``` - -### CLI 参数 - -```shell -USAGE: - kcl-lint [OPTIONS] [--] [input]... - -ARGS: - ... Sets the input file to use - -OPTIONS: - --emit_warning Emit warning message - -h, --help Print help information - -v, --verbose Print test information verbosely - -Y, --setting ... Sets the input file to use -``` - -- input: 需要检查的单个 `.k` 文件路径或路径目录下的所有 `.k` 文件,支持绝对路径或当前目录的相对路径 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/overview.md deleted file mode 100644 index 4fa606dc..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/overview.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 概览 - -KCL 工具链是 KCL 语言的工具集合,旨在提升 KCL 的批量迁移、编写、编译和测试的效率。 - -| 类别 | 工具名称 | 说明 | -| ---------- | ---------------------- | --------------------------------------------------------- | -| 主工具集 | **kcl** | kcl 命令行工具提供对基于 KCL 语言的配置编写、编译和运行。 | -| | kcl-test | 即将提供 | -| | kcl-fmt | kcl-fmt 工具提供对 KCL 代码的格式化 | -| | kcl-lint | kcl-lint 工具提供对 KCL 代码的 lint 检查和自动修复 | -| | kcl-doc | kcl-doc 工具提供对 KCL 代码的文档解析和生成 | -| | kcl-vet | 使用 KCL 代码校验诸如 JSON 和 YAML 的数据格式 | -| ide 插件集 | IntelliJ IDEA KCL 插件 | 提供 IntelliJ IDEA 平台的 KCL 编写、编译辅助 | -| | VS Code KCL 插件 | 提供 VS Code 平台的 KCL 编写、编译辅助 | - -## KCL 工具 - -### 命令行参数 - -```shell -USAGE: - kcl [OPTIONS] [--] [input]... - -Arguments: - [input]... Specify the input files to run - -Options: - -o, --output - Specify the YAML output file path - -Y, --setting ... - Specify the input setting file - -v, --verbose... - Print test information verbosely - -n, --disable_none - Disable dumping None values - -r, --strict_range_check - Do perform strict numeric range checks - -d, --debug - Run in debug mode (for developers only) - -k, --sort_keys - Sort result keys - -D, --argument ... - Specify the top-level argument - -S, --path_selector ... - Specify the path selector - -O, --overrides ... - Specify the configuration override path and value - --target - Specify the target type - -E, --external ... - Mapping of package name and path where the package is located - -h, --help - Print help -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/test.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/test.md deleted file mode 100644 index f8707ff9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/test.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 5 ---- - -# 测试工具 - -即将到来! diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/vet.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/vet.md deleted file mode 100644 index 2c70ce91..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/kcl/vet.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Validation 校验代码 - -## 简介 - -KCL 支持通过内置的 `kcl-vet` 命令行工具提供了基本的配置数据校验能力,可以编写 KCL schema 对输入的 JSON/YAML 格式文件进行类型以及数值的校验。 - -## 使用方式 - -假设有 data.json 文件,代码如下: - -```json -{ - "name": "Alice", - "age": 18, - "message": "This is Alice", - "data": { - "id": 1, - "value": "value1" - }, - "labels": { - "key": "value" - }, - "hc": [1, 2, 3] -} -``` - -构造 schema.k 校验文件,内容如下: - -```py -schema User: - name: str - age: int - message?: str - data: Data - labels: {str:} - hc: [int] - - check: - age > 10 - -schema Data: - id: int - value: str -``` - -在目录下执行如下命令 - -```shell -$ kcl-vet data.json schema.k -``` - -## 指定校验的 schema - -当校验的 KCL 文件中存在多个 schema 定义时,kcl-vet 工具会默认取第一个 schema 定义进行校验,如果需要指定校验的 schema,可以使用 `-d|--schema` 参数 - -```shell -$ kcl-vet data.json schema.k -d User -``` - -## 命令行参数 - -```shell -$ kcl-vet -h -USAGE: - kcl-vet [OPTIONS] [ARGS] - -ARGS: - Validation data file - KCL file - -OPTIONS: - -d, --schema - Iterate through subdirectories recursively - - --format - Validation data file format, support YAML and JSON, default is JSON - - -h, --help - Print help information - - -n, --attribute_name - The attribute name for the data loading -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/openapi/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/openapi/_category_.json deleted file mode 100644 index 5df621d8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/openapi/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "OpenAPI 工具", - "position": 3 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/openapi/crd-to-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/openapi/crd-to-kcl.md deleted file mode 100644 index 5b6f070c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/openapi/crd-to-kcl.md +++ /dev/null @@ -1,118 +0,0 @@ -# CRD to KCL - -命令 - -```shell -kcl-openapi generate model --crd -f ${your_CRD.yaml} -t ${the_kcl_files_output_dir} --skip-validation -``` - -# 示例 - -- 输入文件:test_crontab_CRD.yaml: - -```yaml -# Deprecated in v1.16 in favor of apiextensions.k8s.io/v1 -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - # name must match the spec fields below, and be in the form: . - name: crontabs.stable.example.com -spec: - # group name to use for REST API: /apis// - group: stable.example.com - # list of versions supported by this CustomResourceDefinition - versions: - - name: v1 - # Each version can be enabled/disabled by Served flag. - served: true - # One and only one version must be marked as the storage version. - storage: true - # either Namespaced or Cluster - scope: Namespaced - names: - # plural name to be used in the URL: /apis/// - plural: crontabs - # singular name to be used as an alias on the CLI and for display - singular: crontab - # kind is normally the CamelCased singular type. Your resource manifests use this. - kind: CronTab - # shortNames allow shorter string to match your resource on the CLI - shortNames: - - ct - preserveUnknownFields: false - validation: - openAPIV3Schema: - type: object - properties: - spec: - type: object - properties: - cronSpec: - type: string - image: - type: string - replicas: - type: integer -``` - -- 命令 - -```shell -kcl-openapi generate model -f test_crontab_CRD.yaml -t ~/ --skip-validation --crd -``` - -- 输出文件: ~/models/stable_example_com_v1_cron_tab.k - -```python -""" -This file was generated by the KCL auto-gen tool. DO NOT EDIT. -Editing this file might prove futile when you re-run the KCL auto-gen generate command. -""" -import kusion_kubernetes.apimachinery.apis - - -schema CronTab: - """stable example com v1 cron tab - - Attributes - ---------- - apiVersion : str, default is "stable.example.com/v1", required - APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - kind : str, default is "CronTab", required - Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - metadata : apis.ObjectMeta, default is Undefined, optional - metadata - spec : StableExampleComV1CronTabSpec, default is Undefined, optional - spec - """ - - - apiVersion: "stable.example.com/v1" = "stable.example.com/v1" - - kind: "CronTab" = "CronTab" - - metadata?: apis.ObjectMeta - - spec?: StableExampleComV1CronTabSpec - - -schema StableExampleComV1CronTabSpec: - """stable example com v1 cron tab spec - - Attributes - ---------- - cronSpec : str, default is Undefined, optional - cron spec - image : str, default is Undefined, optional - image - replicas : int, default is Undefined, optional - replicas - """ - - - cronSpec?: str - - image?: str - - replicas?: int -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/openapi/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/openapi/index.md deleted file mode 100644 index 0654db2a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/openapi/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# OpenAPI Tools - -kcl-openapi 工具支持将通过 OpenAPI 规范描述的模型转换为 KCL 配置策略语言,除了能直接转换 OpenAPI 描述文件之外,还可以从 Kubernetes CRD 中提取并转换为 KCL schema. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/openapi/openapi-to-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/openapi/openapi-to-kcl.md deleted file mode 100644 index 6d9f8e54..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/openapi/openapi-to-kcl.md +++ /dev/null @@ -1,64 +0,0 @@ -# OpenAPI to KCL - -命令 - -```shell -kcl-openapi generate model -f ${your_open_api_spec.yaml} -t ${the_kcl_files_output_dir} -``` - -示例: - -- 输入文件:test_open_api_spec.yaml: - -```yaml -definitions: - v1.TestInt: - type: object - properties: - name: - type: string - format: int-or-string - required: - - name - x-kcl-type: - import: - package: v1.test_int - alias: test_int - type: TestInt -swagger: "2.0" -info: - title: KCL - version: v0.0.2 -paths: {} -``` - -- 命令: - -```shell -kcl-openapi generate model -f test_open_api_spec.yaml -t ~/ -``` - -- 输出:~/models/v1/test_int.k - -```python -""" -This is the test_int module in v1 package. -This file was generated by the KCL auto-gen tool. DO NOT EDIT. -Editing this file might prove futile when you re-run the KCL auto-gen generate command. -""" - - -schema TestInt: - """v1 test int - - Attributes - ---------- - name : int | str, default is Undefined, required - name - """ - - - name: int | str - - -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/openapi/quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/openapi/quick-start.md deleted file mode 100644 index 3d6a125d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/openapi/quick-start.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 快速开始 - -## 1. 安装 KCLOpenAPI 工具 - -目前有多种安装方式可选: - -- [通过 go install 安装](#11-通过-go-install-安装) -- [通过 curl|sh 安装(仅限 MacOS & Linux)](#12-通过-curlsh-安装(仅限-MacOS--Linux)) -- [下载发布包](#13-下载发布包) - -## 1.1 通过 go install 安装 - -```shell -go install kcl-lang.io/kcl-openapi@latest -``` - -## 1.2 通过 curl|sh 安装(仅限 MacOS & Linux) - -```shell -curl -fsSL https://kcl-lang.io/script/install-kcl-openapi.sh | /bin/bash -``` - -## 1.3 下载发布包 - -```shell -# 1. 下载二进制程序 -# https://github.com/kcl-lang/kcl-openapi/releases - -# 2. 解压发布包,并将命令添加至 PATH -export PATH=":$PATH" -``` - -## 1.4 验证安装结果 - -```shell -➜ kcl-openapi -v -kcl-openapi 0.5.0 -``` - -## 2. 生成 KCL 文件 - -- [将 OpenAPI 描述文件转换为 KCL](../openapi/openapi-to-kcl.md) -- [将 Kubernetes CRD 转换为 KCL](../openapi/crd-to-kcl.md) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/openapi/spec.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/openapi/spec.md deleted file mode 100644 index aee9fc92..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/cli/openapi/spec.md +++ /dev/null @@ -1,424 +0,0 @@ -# KCL OpenAPI 规范 - -[OpenAPI](https://www.openapis.org/) 允许 API 提供方规范地描述 API 操作和模型,并基于它生成自动化工具和特定语言的客户端。 - -## KCL OpenAPI 文件结构 - -依据 OpenAPI 3.0 规范,OpenAPI 文件中应至少包含 openapi、components、 info、paths 四种根节点对象,KCL OpenAPI 聚焦于其中模型定义的部分,即 OpenAPI 文件中的 `definitions`,而描述操作的 Restful API 部分(即 OpenAPI 文件中的 `paths`)则不属于 KCL OpenAPI 定义的范畴。 -​ - -注:除以上列出的节点外,OpenAPI 官方规范还支持 servers、security、tags、externalDocs 四种可选的根节点,但都不是 KCL OpenAPI 所关心的,因此用户无需填写这部分内容,即使填写了也不会产生任何影响。 -​ - -| OpenAPI 顶层对象 | 类型 | 含义 | KCL OpenAPI 工具支持情况 | -| ---------------- | ----------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | -| swagger | string | openapi 版本信息 | 必填项,目前支持 openapi 2.0,即合法取值为 "2.0" | -| definitions | Definition Object | 模型定义 | 必填项 | -| info | Info Object | 当前 API 文件的元数据信息,例如标题、描述信息、版本、开源协议等 | 必填项,定义当前 OpenAPI 文件的基本信息,不会输出到 KCL 代码,但可用于 Swagger-UI 工具可视化展示 | - -为方便初学者快速理解,下面给出一个典型的 KCL OpenAPI 文件(截取自 swagger example [Petstore](https://petstore.swagger.io/))应包含的节点图示。KCL OpenAPI 工具重点关注其中的 definitions 节点,可以看到文件中定义了两个模型(Pet 和 Category),并且 Pet 模型中包含三个属性(name、id、category) - -## KCL schema - -KCL 中使用 schema 结构来定义配置数据的“类型”,关于 KCL schema,可参考文档:传送门 -在 definitions 节点下新增 definition 元素,即可定义 KCL schema. -示例: -下例在 KCL 代码中定义了 Pet、Category 两个 schema,同样地,其对应的 OpenAPI 也在 definitions 节点下包含这两个模型的描述。 - -```python -# KCL schema: -schema Pet: - name: str - id?: int - category?: Category - -schema Category: - name?: str - -# 对应的 OpenAPI 描述 -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "id": { - "type": "integer", - "format": "int64" - }, - "category": { - "$ref": "#/definitions/Category" - } - }, - "required": [ - "name" - ] - }, - "Category": { - "type": "object", - "properties": { - "name": { - "type": "string" - } - } - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -``` - -### schema 名称 - -在 KCL 中,schema 名称紧跟在 schema 关键字后声明,在 OpenAPI 中,模型的名称通过 definition 元素的 key 来定义。 - -### schema 类型 - -KCL schema 在 OpenAPI 中的类型为 "object". 例如上例中 "Pet" 的 "type" 值应为 "object". - -### schema 属性 - -KCL schema 中可以定义若干属性,属性的声明一般包含如下几部分: - -- 属性注解:可选,以 @ 开头,例如 @deprecated 注解表示属性被废弃 -- 属性名称:必须 -- 属性 optional 修饰符(?):可选,带问号表示当前属性为可选属性,可以不被赋值。反之,不带问号表示必填属性 -- 属性类型:必须,可以是基本数据类型,也可以是 schema 类型, 或者是前述两种类型的并集 -- 属性默认值:非必须 - -它们与 OpenAPI 规范的对应关系如下: - -| KCL schema 属性元素 | OpenAPI 元素 | -| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- | -| 属性注解 | 暂不支持,计划扩展一个 deprecate 字段用于描述 deprecated 注解 | | -| 属性名称 | properties 节点下,每个属性的 key 即为属性名称 | -| 属性 optional 修饰符(?) | 模型节点下,通过 required 字段列出该模型的所有必填属性的名称,未被列出的属性即为 optional | -| 属性类型 | 属性节点下,设置 type + format 可以标识属性的基本类型,如果是 schema 类型则用 $ref 字段表示,类型 union 则由扩展字段 x-kcl-types 来标识,此外,属性节点的 enum、pattern 也可以用于表示 KCL 类型。 | -| KCL-OpenAPI 关于类型的对照关系,详见“基本数据类型”小节 | | -| 属性默认值 | 属性节点下,设置 default 字段即可为属性设置默认值 | - -示例: -下例中 Pet 模型包含了 2 个属性:name(string 类型,必填属性,无注解,无默认值)、id(int64 类型,无注解,非必填,默认值为 -1) - -```python -# KCL schema Pet,包含两个属性 name 和 id -schema Pet: - name: str - id?: int = -1 - -# 对应的 OpenAPI 文档 -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - "id": { - "type": "integer", - "format": "int64", - "default": -1 - } - }, - "required": [ - "name" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### schema 索引签名 - -KCL schema 允许定义索引签名,用于定义属性名不固定的 dict,起到静态模板的作用。具体来说,KCL schema 索引签名包含如下几个元素: - -- 索引签名中 key 的类型:在方括号中声明,必须是基础类型 -- 索引签名中 value 的类型:在冒号后声明,可以是任意合法的 KCL 类型 -- 索引签名中的省略符:在方括号中,key 类型之前声明,使用"..."表示。如果带有该符号,表示该索引签名只用于约束未在 schema 中定义的属性;否则,表示 schema 中所有已定义和未定义属性都收到该索引签名的约束。 -- 索引签名中 key 的别名:在方括号中,紧随左方括号之后声明,使用名称 + 冒号表示,该别名可用于按名称引用索引签名 -- 索引签名的默认值:可以为索引签名设置默认值 - -在 OpenAPI 中,可以借助在模型节点的 `additionalProperties` 字段描述某些 key 为 string 的索引签名。但对于 KCL 索引签名中非 string 类型的 dict key、索引签名 key 的 check 校验,在 OpenAPI 规范没有对等的描述。它们与 OpenAPI 规范的对应关系如下: - -| KCL 索引签名元素 | OpenAPI 元素 | -| ----------------------- | ---------------------------------------------------------------------- | -| 索引签名中 key 的类型 | OpenAPI 仅支持 key 为 string 类型,无法自定义 | -| 索引签名中 value 的类型 | 模型节点的下 additionalProperties 下的 "type" 字段 | -| 索引签名中的省略符 | OpenAPI 中表示索引签名时,只能表示 KCL 中带有省略符的情况 | -| 索引签名中 key 的别名 | OpenAPI 中不支持为索引签名定义 key 别名,(预计通过扩展支持:x-alias) | -| 索引签名的默认值 | 目前不支持 | - -示例:下例中的 KCL schema Pet,包含两个预定义的属性 name 和 id,除此之外,还允许使用该 schema 的配置额外地赋值其他 key 为 string 类型,value 为 bool 类型的属性: - -```python -# KCL schema Pet,包含两个预定义的属性 name 和 id,允许额外给 key 为 string、value 为 bool 的属性赋值 -schema Pet: - name: str - id?: int - [...str]: bool - -# 对应的 OpenAPI 描述 -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - "id": { - "type": "integer", - "format": "int64", - } - }, - "additionalProperties": { - "type": "bool" - }, - "required": [ - "name" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### schema 继承关系 - -### 内联 schema - -OpenAPI 支持嵌套地定义 schema,但 KCL 目前暂不支持 schema 的内联。OpenAPI 中内联定义的 schema 将被转换为 KCL 中带名称的 schema,其名称的命名规则为:在该内联 schema 的上层 schema 名称的基础上,增加相应的后缀。在拼接后缀时,根据定义了该内联 schema 的外层 OpenAPI 元素类型,后缀内容如下: - -| OpenAPI 文档中定义内联 schema 的元素 | KCL schema 名称拼接规则 | -| ------------------------------------ | ------------------------------ | -| 某属性节点 | 增加该属性节点的名称为后缀 | -| AdditionalProperties 节点 | 增加"AdditionalProperties"后缀 | - -注:KCL 未来也可能会支持内联 schema,届时再更新这部分转换规则 -示例 1:下例中的模型 Deployment 包含有 kind、spec 两个属性,其中 deploymentSpec 属性的 schema 通过内联的方式定义: - -```python -# OpenAPI 文档 -{ - "definitions": { - "Deployment": { - "type": "object", - "properties": { - "kind": { - "type": "string", - }, - "spec": { - "type": "object", - "properties": { - "replicas": { - "type": "integer", - "format": "int64" - } - } - } - }, - "required": [ - "kind", - "spec" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -# 转换为 KCL Schema 如下: -schema Deployment: - kind: str - spec: DeploymentSpec - -schema DeploymentSpec: - replicas?: int -``` - -示例 2:下例中的模型 Person 中除固定属性 name 外,还允许包含额外的属性(additionalProperties),并且这部分额外属性的属性值的 schema 通过内联的方式定义: - -```python -# OpenAPI 文档 -{ - "definitions": { - "Person": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - }, - "required": [ - "name", - "spec" - ], - "additionalProperties": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "description": { - "type": "string" - } - }, - "required": [ - "name" - ] - }, - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -# 转换为 KCL Schema 如下: -schema Person: - name: str - [...str]: [PersonAdditionalProperties] - -schema PersonAdditionalProperties: - name: str - description?: str -``` - -## KCL 文档 - -KCL doc 规范请参考:[传送门](../kcl/docgen.md) -KCL 文档包含 module 文档、schema 文档两类,其中 schema 文档可以由 OpenAPI 转换得到。KCL schema 文档包含: - -- schema 描述信息:位于 schema 声明之后、schema 属性声明之前,是对 schema 的总体介绍 -- schema 属性信息:位于 shcema 描述信息之后,以 Attributes + 分割线分隔 -- schema 附加信息:位于 schema 属性信息之后,以 See Also + 分割线分隔 -- schema 示例信息:位于 schema 附加信息之后,以 Examples + 分割线分隔 - -它们与 OpenAPI 规范的对应关系如下: - -| KCL 文档元素 | OpenAPI 元素 | -| --------------- | ---------------------------------------------------- | -| schema 描述信息 | definitions 节点下,每个模型节点的 description 字段 | -| schema 属性信息 | properties 节点下,每个属性节点的 description 字段 | -| schema 附加信息 | definitions 节点下,每个模型节点的 externalDocs 字段 | -| schema 示例信息 | definitions 节点下,每个模型节点的 example 字段 | - -示例: -下例中为 Pet 模型定义了其 schema 描述文档 "The schema Pet definition";Pet 的两个属性 "name" 和 "id" 也分别定义了其属性文档 "The name of the pet" 及 "The id of the pet";Pet 的附加信息为 "Find more info here. [https://petstore.swagger.io/](https://petstore.swagger.io/)";此外,Pet 模型还提供了模型实例的示例写法。 - -```python -# KCL schema Pet,采用规范的 KCL 文档格式 -schema Pet: - """The schema Pet definition - - Attributes - ---------- - name : str, default is Undefined, required - The name of the pet - id : int, default is -1, optional - The age of the pet - - See Also - -------- - Find more info here. https://petstore.swagger.io/ - - Examples - -------- - pet = Pet { - name = "doggie" - id = 123 - } - """ - name: str - id?: int = -1 - -# 对应的 OpenAPI 文档 -{ - "definitions": { - "Pet": { - "description": "The schema Pet definition", - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "The name of the pet" - }, - "id": { - "type": "integer", - "format": "int64", - "default": -1, - "description": "The age of the pet" - } - }, - "required": [ - "name" - ], - "externalDocs": { - "description": "Find more info here", - "url": "https://petstore.swagger.io/" - }, - "example": { - "name": "doggie", - "id": 123 - } - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -​ - -## 基本数据类型 - -| JSON Schema type | swagger type | KCL type | comment | -| ---------------- | --------------------------- | --------------- | --------------------------------------------------------------------------- | -| boolean | boolean | bool | | -| number | number | float | | -| | number format double | **unsupported** | | -| | number format float | float | | -| integer | integer | int (32) | | -| | integer format int64 | **unsupported** | | -| | integer format int32 | int (32) | | -| string | string | str | | -| | string format byte | str | | -| | string format int-or-string | int | str | -| | string format binay | str | | -| | string format date | unsupported | As defined by full-date - [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) | -| | string format date-time | unsupported | As defined by date-time - [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) | -| | string format password | unsupported | for swagger: A hint to UIs to obscure input. | -| | datetime | datetime | | - -## Reference - -- openapi spec 2.0:[https://swagger.io/specification/v2/](https://swagger.io/specification/v2/) -- openapi spec 3.0:[https://spec.openapis.org/oas/v3.1.0](https://spec.openapis.org/oas/v3.1.0) -- openapi spec 3.0(swagger 版本):[https://swagger.io/specification/](https://swagger.io/specification/) -- openapi spec 2.0 #SchemaObject:[https://swagger.io/specification/v2/#schemaObject](https://swagger.io/specification/v2/#schemaObject) -- go swagger:[https://goswagger.io/use/models/schemas.html](https://goswagger.io/use/models/schemas.html) -- swagger data models:[https://swagger.io/docs/specification/data-models/](https://swagger.io/docs/specification/data-models/) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/concepts/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/concepts/_category_.json deleted file mode 100644 index d3ae7a0a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/concepts/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "核心概念", - "position": 5 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/concepts/concepts.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/concepts/concepts.md deleted file mode 100644 index e2034db2..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/concepts/concepts.md +++ /dev/null @@ -1,3 +0,0 @@ -# 核心概念 - -学习更多关于 KCL 核心概念。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/concepts/package-and-module.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/concepts/package-and-module.md deleted file mode 100644 index fbde28f3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/concepts/package-and-module.md +++ /dev/null @@ -1,156 +0,0 @@ -# 模块和包 - -本节主要介绍如何组织 KCL 中的文件。 - -## 概述 - -在一个**module**中,KCL 按**package**进行组织文件。package 可以在 module 内定义,也可以通过 KCL 包管理器 `kpm` 从外部导入。在后一种情况下,KCL 在专用位置中维护包的副本。 - -## Module - -KCL 模块按目录层次结构布置配置。它包含了确定 KCL 配置结果所需的一切。此目录的根标记为包含 `kcl.mod` 目录。此目录的内容大多由 kcl 工具(如 `kpm` 等)管理。从这个意义上讲,`kcl.mod` 类似于 `.git` 目录,标记着仓库的根目录,但它的内容主要由 git 工具管理。此外,KCL 模块是文件组织的最大单位,具有所有 KCL 文件和依赖项的固定位置。 - -> 注意: 使用 KCL 模块(例如 `kcl.mod`)是可选的,但如果您想使用语义版本管理、分发、共享和重用代码,则需要使用它。 - -### 创建一个 module - -可以通过在模块根目录中运行以下命令来创建模块: - -```bash -kpm init [module name] -``` - -模块名在需要在模块内导入另一个模块的包时是**必需的**。也可以通过手动设置 `kcl.mod` 文件来创建模块。 - -## Package - -在 KCL 中,一个包通常由包含 KCL 文件的“文件夹”组成。这个文件夹可以是实际的磁盘物理路径,也可以由多个 KCL 文件(通常是主包)组成。不同的包通过不同的包路径(如 `kubernetes.core.v1`)唯一地定位。 - -在同一个模块内,可以通过相对或绝对路径的 import 语句互相导入不同的包。在 KCL 解析过程中,相对 import 将被替换为绝对 import,并通过包路径找到相应的 KCL 代码。 - -### 相对导入路径 - -我们可以使用 `.` 运算符来实现 KCL 入口文件的相对路径导入。 - -main.k: - -```python -import .model1 # Current directory module -import ..service # Parent directory -import ...root # Parent of parent directory - -s = service.ImageService {} -m = root.Schema {} -``` - -### 绝对导入路径 - -KCL 语句`import a.b.c.d` 的语义是: - -1. 如果 `kcl.mod` 不存在,则将当前目录视为包根目录,并从当前目录搜索路径 `a/b/c/d`。 -2. 如果当前目录搜索失败,则从根路径 `ROOT_PATH/a/b/c/d` 搜索,否则引发导入错误。 - -根路径 `ROOT_PATH` 的定义是相对于 `kcl.mod` 文件的目录。 - -代码结构: - -```bash -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -### 内置包 - -KCL 有一系列内置包,例如 `math`,`regex` 等。要使用内置包,直接导入并使用其限定标识符调用函数。例如, - -```python -import regex - -image = "nginx:1.14.2" -is_match = regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$") - -``` - -输出的 YAML 为 - -```yaml -image: nginx:1.14.2 -is_match: true -``` - -### 插件包 - - - -KCL 还有一系列插件包,例如 `hello`,`project_context` 等。要使用插件包,需要用 `kcl_plugin.` 包路径前缀导入,并使用其限定标识符调用函数。例如, - -```python -import kcl_plugin.hello - -result = hello.add(1, 1) -``` - -输出的 YAML 为 - -```yaml -result: 2 -``` - -### 主包 - -在 KCL 中,主包的组成通常由编译器参数确定。这是因为KCL模式和约束可以在包中的文件中分隔,甚至可以在目录中组织,考虑将配置写入和维护在隔离块中的便利性。 - -#### 属于主包的文件 - -用户可以使用KCL命令行决定使用哪些配置和约束,例如, - -```bash -kcl file1.k file2.k -``` - -因此,主包包含两个名为 `file1.k` 和 `file2.k` 的 KCL 文件。 - -如果 KCL 被告知为特定目录加载文件,例如: - -```bash -kcl ./path/to/package -``` - -它将只查找 `.k` 后缀的 KCL 文件,并忽略 `_` 或 `_test.k` 前缀的 KCL 文件合并到主包中。此外,如果 `./path/to/package` 包含 `kcl.yaml` 文件,则 `kcl.yaml` 文件将被忽略。 - -此外,我们可以通过配置命令行编译设置文件(例如 `kcl.yaml`)来设置主包文件,如下所示: - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k -``` - -```bash -kcl -Y kcl.yaml -``` - -> 注意:如果没有为 KCL 指定任何输入文件,KCL 将从命令行执行路径查找默认的 `kcl.yaml` 文件读取输入文件。此外,如果我们告诉KCL输入文件和编译设置文件,KCL将把用户输入的输入文件作为最终值。 - -```bash -# 无论`kcl.yaml` 中是否配置 `files` 字段,输入文件的最终值为["file1.k", "file2.k"] -kcl -Y kcl.yaml file1.k file2.k -``` - -## kcl.mod 和 kcl.yaml 异同 - -首先,在 KCL 中,`kcl.mod` 和 `kcl.yaml` 都是可选的。它们之间的区别在于 `kcl.mod` 确定包路径的根路径以及 KCL 模块是否具有分发和重用要求,而 `kcl.yaml` 确定主包的 KCL 文件组成。 - -其次,对于仅用于外部使用的 kcl module,`kcl.yaml` 是可选的,但 `kcl.mod` 是必需的,因为 `kcl.mod` 需要声明 KCL 版本,模块版本,依赖关系和其他信息。 - -最后,对于 KCL IDE 插件,它需要知道主包信息才能形成完整的编译过程,因此它需要根据光标位置自动查找主包组成,因为没有人可以通过 KCL 命令行指定这些信息。一般的查询逻辑是查找 `kcl.yaml` 的存在性。如果找到了,主包由 `kcl.yaml` 中的文件属性组成,如果找不到,主包由当前文件组成。KCL IDE 插件会有选择地了解 `kcl.mod` 文件。当 `kcl.mod` 文件存在时,IDE 插件会读取所有包路径及其在外部依赖项中的实际路径的相应信息。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/getting-started/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/getting-started/_category_.json deleted file mode 100644 index c826d665..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/getting-started/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "快速开始", - "position": 1 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/getting-started/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/getting-started/index.md deleted file mode 100644 index 5d58acf6..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/getting-started/index.md +++ /dev/null @@ -1 +0,0 @@ -# 快速开始 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/getting-started/intro.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/getting-started/intro.md deleted file mode 100644 index aaa364e3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/getting-started/intro.md +++ /dev/null @@ -1,199 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 简介 - -## KCL 是什么? - -[KCL](https://github.com/kcl-lang/kcl) 是一个开源的基于约束的记录及函数语言。KCL 通过成熟的编程语言技术和实践来改进对大量繁杂配置比如云原生 Kubernetes 配置场景的编写,致力于构建围绕配置的更好的模块化、扩展性和稳定性,更简单的逻辑编写,以及更简单的自动化和生态工具集成。 - -## 为什么使用 KCL? - -KCL 期望通过更现代化的声明式配置语言在 Kubernetes 资源管理解决如下问题: - -- 通过**代码抽象**等手段屏蔽基础设施和平台的细节,降低研发者负担 -- **编辑**和**校验**已有的存量配置或模版 -- 通过配置语言无副作用地管理跨团队的大规模配置数据,提升团队协作效率 - - 用**生产级高性能编程语言**以**编写代码**的方式提升配置的灵活度,比如条件语句、循环、函数、包管理等特性提升配置重用的能力 - - 在代码层面提升**配置语义验证**的能力,比如字段可选/必选、类型、范围等配置检查能力 - - 提供**配置分块编写、组合和抽象的能力**,比如结构定义、结构继承、约束定义等能力 - - 通过**多语言 SDK**,**KCL 语言插件**等手段提升其**自动化**集成能力 - -您可以将 KCL 用于 - -- 生成静态配置数据如 JSON, YAML 等 -- 使用 schema 对配置数据进行建模并减少配置数据中的样板文件 -- 为配置数据定义带有规则约束的 schema 并对数据进行自动验证 -- 无副作用地组织、简化、统一和管理庞大的配置 -- 通过分块编写配置数据可扩展地管理庞大的配置 -- 与 [KusionStack](https://kusionstack.io) 一起,用作平台工程语言来交付现代应用程序 - -除了语言自身,KCL 还提供了许多额外的工具如格式化,测试、文档、包管理等工具帮助您使用、理解和检查编写的配置或策略;通过 VS Code 等 IDE 插件和 Playground 降低配置编写、分享的成本;通过 Rust, Go, 和 Python 多语言 SDK 自动化地管理和执行配置。 - -![](/img/docs/user_docs/intro/kcl-overview.png) - -此外,KCL 是一种现代高级领域编程语言,并且它是一种编译静态的强类型语言。KCL 为开发人员提供了通过记录和函数语言设计将**配置(config)**、**建模抽象(schema)**、**逻辑(lambda)**和**策略(rule)**作为核心能力。 - -![](/img/docs/user_docs/intro/kcl-concepts.png) - -KCL 试图提供独立于运行时的可编程性,不在本地提供线程和IO等系统功能,但支持云本地操作场景的功能,并试图为解决领域问题并提供稳定、安全、低噪声、低副作用、易于自动化和易于管理的编程支持。 - -总之,KCL 具备如下特点: - -- **简单易用**:源于 Python、Golang 等高级语言,采纳函数式编程语言特性,低副作用 -- **设计良好**:独立的 Spec 驱动的语法、语义、运行时和系统库设计 -- **快速建模**:以 [Schema](https://kcl-lang.io/docs/reference/lang/tour#schema) 为中心的配置类型及模块化抽象 -- **功能完备**:基于 [Config](https://kcl-lang.io/docs/reference/lang/tour#config-operations)、[Schema](https://kcl-lang.io/docs/reference/lang/tour#schema)、[Lambda](https://kcl-lang.io/docs/reference/lang/tour#function)、[Rule](https://kcl-lang.io/docs/reference/lang/tour#rule) 的配置及其模型、逻辑和策略编写 -- **可靠稳定**:依赖[静态类型系统](https://kcl-lang.io/docs/reference/lang/tour/#type-system)、[约束](https://kcl-lang.io/docs/reference/lang/tour/#validation)和[自定义规则](https://kcl-lang.io/docs/reference/lang/tour#rule)的配置稳定性 -- **强可扩展**:通过独立配置块[自动合并机制](https://kcl-lang.io/docs/reference/lang/tour/#-operators-1)保证配置编写的高可扩展性 -- **易自动化**:[CRUD APIs](https://kcl-lang.io/docs/reference/lang/tour/#kcl-cli-variable-override),[多语言 SDK](https://kcl-lang.io/docs/reference/xlang-api/overview),[语言插件](https://github.com/kcl-lang/kcl-plugin) 构成的梯度自动化方案 -- **极致性能**:使用 Rust & C,[LLVM](https://llvm.org/) 实现,支持编译到本地代码和 [WASM](https://webassembly.org/) 的高性能编译时和运行时 -- **API 亲和**:原生支持 [OpenAPI](https://github.com/kcl-lang/kcl-openapi)、 Kubernetes CRD, Kubernetes YAML 等 API 生态规范 -- **开发友好**:[语言工具](https://kcl-lang.io/docs/tools/cli/kcl/) (Format,Lint,Test,Vet,Doc 等)、 [IDE 插件](https://github.com/kcl-lang/vscode-kcl) 构建良好的研发体验 -- **安全可控**:面向领域,不原生提供线程、IO 等系统级功能,低噪音,低安全风险,易维护,易治理 -- **多语言 SDK**:[Go](https://kcl-lang.io/docs/reference/xlang-api/go-api),[Python](https://kcl-lang.io/docs/reference/xlang-api/python-api),[Java](https://kcl-lang.io/docs/reference/xlang-api/java-api) 和 [REST API](https://kcl-lang.io/docs/reference/xlang-api/rest-api) 满足不同场景和应用使用需求 -- **生态集成**:通过 [Kustomize KCL 插件](https://github.com/kcl-lang/kustomize-kcl), [Helm KCL 插件](https://github.com/kcl-lang/helm-kcl) 或者 [KPT KCL SDK](https://github.com/kcl-lang/kpt-kcl-sdk) 直接编辑或校验资源 -- **生产可用**:广泛应用在蚂蚁集团平台工程及自动化的生产环境实践中 - -虽然 KCL 不是通用语言,但它有相应的应用场景。开发人员可以通过 KCL 编写**config**、**schema**、**function**和**rule**,其中 config 用于定义数据,schema 用于描述数据的模型定义,rule 用于验证数据,schema 和 rule 还可以组合使用模型和约束来充分描述数据。此外,还可以使用 KCL 中的 lambda 纯函数来组织数据代码,封装通用代码,并在需要时直接调用它。 - -KCL 配置通常遵循如下模式: - -$$ -k = (T) v -$$ - -其中,$k$ 是属性名称,$v$ 是属性值,$T$ 是类型注解。由于 KCL 具有类型推导的能力,因此 $T$ 通常可以省略。 - -下面是一个用 KCL 生成 kubernetes 资源的例子 - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = name -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -我们可以使用上述 KCL 代码生成一个 Kubernetes YAML 配置 - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## 如何选择 - -目前社区已经进行了大量的尝试来改进其配置技术,主要可分为三类: - -- 用于模板、修补和验证的基于低级数据格式的工具,使用外部工具来增强重用和验证。 -- 领域特定语言(DSL)和配置语言(CL),以增强语言能力。 -- 基于通用语言(GPL)的解决方案,使用 GPL 的云开发工具包(CDK)或框架来定义配置。 - -简单的选择答案: - -- 如果您需要编写结构化的静态的 K-V,或使用 Kubernetes 原生的技术工具,建议选择 YAML。 -- 如果您希望引入编程语言便利性以消除文本(如 YAML、JSON) 模板,有良好的可读性,或者你已是 Terraform 的用户,建议选择 HCL。 -- 如果您希望引入类型功能提升稳定性,维护可扩展的配置文件,建议选择 CUE。 -- 如果您希望以现代语言方式编写复杂类型和建模,维护可扩展的配置文件,原生的纯函数和策略,和生产级的性能和自动化,建议直接选择 KCL 或将 KCL 用于对已有配置手段或工具进行增强。 - -### vs. YAML/JSON - -YAML/JSON 适用于小型配置场景。对于需要频繁修改的大型云原生配置场景,它们更适合 KCL。所涉及的主要区别是配置数据抽象和部署之间的区别: - -使用 KCL 进行配置的优点是:对于静态数据,抽象一层的优点意味着整个系统具有部署灵活性。不同的配置环境、租户和运行时可能对静态数据有不同的要求,甚至不同的组织可能有不同的规范和产品要求。KCL 可用于公开最需要的和经常修改的配置。 - -### vs. Jsonnet/GCL - -GCL 是一种用 Python 实现的声明式配置语言,它提供了支持模板抽象的必要语言功能。然而 GCL 编译器本身是用Python编写的,且语言本身是解释执行的。对于大型模板实例(如 kubernetes 模型),性能较差。 - -Jsonnet 是一种用 C++ 实现的数据模板语言,适用于应用程序和工具开发人员,可以生成配置数据并通过代码组织、简化和管理大型配置,而不会产生副作用。 - -Jsonnet 和 GCL 非常擅长减少样板。它们都可以使用代码生成配置,就像工程师只需要编写高级 GPL 代码,而不是手动编写容易出错且难以理解的服务器二进制代码一样。Jsonnet 减少了 GCL 的一些复杂性,但在很大程度上属于同一类别。两者都有许多运行时错误,类型检查和约束能力不足。 - -### vs. HCL - -HCL 是一种 Go 实现的结构化配置语言。HCL 的原生语法受到 libucl 和 nginx 配置的启发。它用于创建一种对人类和机器友好的结构化配置语言,作为 [Terraform 语言](https://www.terraform.io/language)主要用于 DevOps工具、服务器配置和资源配置等。 - -HCL 的用户界面不能通过 Terraform 提供者 Schema 定义直接感知。此外,在编写复杂对象和必需/可选字段定义时,用户界面很麻烦。动态参数受变量的条件字段约束。资源本身的约束需要由提供程序模式定义,或者与 Sentinel/Rego 和其他策略语言相结合。语言本身的完整性不能自我封闭,其实现方法也不统一。 - -### vs. CUE - -CUE 可以通过结构、无继承和其他特性用作建模,当模型定义之间没有冲突时可以实现高度抽象。因为 CUE 在运行时执行所有约束检查,所以它在大规模配置建模场景中可能存在性能瓶颈。CUE 将类型和值组合为一个概念,并通过各种语法简化了约束的编写。例如,不需要泛型类型和枚举,求和类型和空值合并是一回事。CUE 支持配置合并,但它是完全幂等的。它可能无法满足复杂的多租户和多环境配置场景的要求。对于复杂的循环和约束场景,编写起来很复杂,编写需要精确配置修改或者 Patch 的场景也很麻烦。 - -对于 KCL,建模是通过 KCL Schema 进行的,通过语言级工程和一些面向对象的特性(如单一继承、Mixin 复用)可以实现高模型抽象。KCL 是一种静态编译语言,用于大规模建模场景是运行时开销较低 (性能更高,更低的内存消耗)。KCL 提供了更丰富的检查声明性约束语法,这使得配置和策略编写更加容易。对于一些配置字段组合约束,它更容易编写(与 CUE 相比,KCL 提供了更多的 if-guard 组合约束、all/any/map/filter 表达式和其他集合约束编写方法,这使得编写更容易)。 - -### vs. Dhall - -Dhall 是一种可编程配置语言,它组合了 JSON、函数、类型和 imports 导入等功能, 本身风格偏向函数式,如果您学过 Haskell 等函数式风格语言,可能会对它感到熟悉的。相比于 Dhall, KCL 也提供了类似功能的组合,提供给用户配置可编程和抽象的能力,不过 KCL 在建模、约束检查、自动化等方面做了更多的改进,同时能够通过包管理手段进行模型共享。此外,KCL 的语法语义更贴近于面向对象语言,在一定程度上会比纯函数式风格接受程度更高。 - -### vs. Nickel - -Nickel 是一种简单的配置语言。它的目的是自动生成静态配置文件,本质上是带有函数和类型的 JSON。 - -KCL 和 Nickel 都有类似的渐进式类型系统(静态+动态)、合并策略、函数和约束定义。不同之处在于 KCL 是一种类似 Python 的语言,而 Nickel 是一种类似 JSON 的语言。此外,KCL 提供了 schema 关键字来区分配置定义和配置数据,以避免混合使用。 - -### vs. Starlark - -Starlark 主要用作 Bazel 的配置语言并且是 Python 的一种方言。它没有类型,并且禁止递归。 - -KCL 一定程度上也可以看作 Python 的变种,但是它极大地增强了静态类型和配置扩展性相关的设计,并且是一个编译型语言,这与 Starlark 有着本质的不同。 - -### vs. Kustomize - -Kustomize 的核心功能是其文件级覆盖功能。但是它存在多个覆盖链的问题,因为找到特定属性值的语句不能保证它是最终值,因为其他地方出现的另一个特定值可以覆盖它。对于复杂的场景,Kustomsize 文件的继承链的检索通常不如 KCL 代码的继承链检索方便,需要仔细考虑指定的配置文件覆盖顺序。此外,Kustomize 无法解决 YAML 配置编写、约束验证、模型抽象和开发等问题,更适合于简单的配置场景。 - -在 KCL 中,配置合并操作可以对代码中的每个配置属性进行细粒度处理,合并策略可以灵活设置,而不限于整体资源,配置之间的依赖关系可以通过KCL的import语句进行静态分析。 - -### vs. Helm - -Helm 的概念源于操作系统的包管理机制。它是一个基于模板化 YAML 文件的包管理工具,支持包中资源的执行和管理。 - -KCL 自然提供了 Helm 功能的超集,因此您可以直接使用 KCL 作为替代。对于采用 Helm 的用户,KCL 中的堆栈编译结果可以打包并以 Helm 格式使用,通过 kpm 包管理工具进行分发复用。此外,我们还可以直接使用 Helm-KCL 插件直接对已有的 Helm Charts 进行无侵入的可编程扩展。 - -### vs. CDK - -用CDK的高级语言编写可以很好地集成到应用程序项目中,这实际上是客户端运行时的一部分。对于KCL,由KCL编写的外部配置和策略与客户端运行时分离。 - -通用语言通常远远超出了需要解决的问题,例如安全问腿、能力边界问题(启动本地线程、访问IO、网络、代码无限循环和其他安全风险)。例如,在音乐领域,有专门的音符来表达音乐,这便于学习和交流,它不能用一般语言表达清楚。 - -此外,由于通用语言风格多样,需要统一维护、管理和自动化。通用语言通常用于编写客户端运行时,它是服务器运行时的延续,不适合编写独立于运行时的配置,被编译成二进制文件,并最终从进程开始运行。此外,GPL 稳定性和可扩展性不易控制。然而,KCL 配置语言通常用于编写数据,将数据与简单逻辑相结合,它描述了预期的最终结果,然后由编译器或引擎使用,既具备丰富的编程抽象能力,又具备方便的数据处理方式。 - -### vs. OPA/Rego - -Rego 起源于逻辑编程,它基于 Datalog,是一种受限制的 Prolog 形式,而 KCL 基于静态类型结构,具备部分 OOP 特性。Rego 类型化特征结构的设计是为了解决 Prolog 在人类语言编码应用中的缺点,将 Datalog 变量用于编程本质上是约束验证任务,Datalog 是一种优秀的查询语言。但对于约束强制执行,它有点麻烦,因为实际上首先需要查询要应用约束的值才能进行校验。 - -此外,KCL 的方法更易于找到规范化、简化、面向人类易读,面向运行时性能优良的约束和校验表示,具备静态类型,并且它更适合于从 OpenAPI 生成或者创建 OpenAPI。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/getting-started/kcl-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/getting-started/kcl-quick-start.md deleted file mode 100644 index 8d75e878..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/getting-started/kcl-quick-start.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -sidebar_position: 3 ---- - -# KCL 语言速览 - -KCL 是一个面相云原生配置策略领域的编程语言。KCL 设计之初受 Python3 启发,同时吸收了声明式、OOP 编程范式的设计理念,是一种专用于配置策略定义、校验的静态强类型的面相配置和策略场景的语言。本节我们将快速展示 KCL 语言的基本特性。 - -## 1. Hello KCL - -学习新语言的最佳途径是自己亲手写几个小程序,配置语言也是如此。KCL 作为一种配置策略语言,我们可以像写配置一样写 KCL 程序。 - -下面是一个简单的 `hello.k` 程序: - -```python -hello = "KCL" -``` - -将 `hello` 属性设置为 `"KCL"` 字符串。然后将代码保存到 `hello.k` 文件中。 - -如何执行这个程序取决于具体的开发环境,我们先假设本地的 macOS 或者是 Linux 系统已经安装了 `kcl` 命令(或者通过 `docker run --rm -it kcllang/kcl` 进入 Docker 环境测试)。然后在文件所在的目录命令行输入以下命令执行: - -```shell -kcl hello.k -``` - -输出为 - -```yaml -hello: KCL -``` - -命令行执行的效果如图所示: - -![](/img/docs/user_docs/getting-started/hello.gif) - -输出的是 YAML 格式的配置数据。这个程序虽然简单,但是我们可以通过执行 KCL 配置程序到输出结果验证了开发环境和 `kcl` 命令行的基本用法。 - -## 2. 再复杂一点的配置 - -常见的配置数据除了的普通的 key-value 对,还有嵌套的字典和列表类型,同时 value 基础类型除了字符串还有布尔和数值等类型。下面是更为复杂一点的 `server.k` 配置: - -```python -# This is a KCL document - -title = "KCL Example" - -owner = { - name = "The KCL Authors" - data = "2020-01-02T03:04:05" -} - -database = { - enabled = True - ports = [8000, 8001, 8002] - data = [["delta", "phi"], [3.14]] - temp_targets = {cpu = 79.5, case = 72.0} -} - -servers = [ - {ip = "10.0.0.1", role = "frontend"} - {ip = "10.0.0.2", role = "backend"} -] -``` - -其中 `#` 开头的表示行注释。`owner` 的 value 是一个字典,字典的面值通过 `{}` 方式包含的内容,字典内部的 key-value 和 `hello = "KCL"` 例子的写法类似。`database` 则是另一个字典,其中字典属性的 value 出现了布尔 `True`、列表 `[]` 和 `{}` 字典,其中列表和字典中还出现了数值类型的 value。 最后一个 `servers` 属性则是一个列表,列表内部嵌套着字典(字典和列表以及后续将要讲到的 `schema` 都可以相互嵌套)。 - -该配置输出的 YAML 结果如下: - -```yaml -$ kcl server.k -title: KCL Example -owner: - name: The KCL Authors - data: '2020-01-02T03:04:05' -database: - enabled: true - ports: - - 8000 - - 8001 - - 8002 - data: - - - delta - - phi - - - 3.14 - temp_targets: - cpu: 79.5 - case: 72.0 -servers: -- ip: 10.0.0.1 - role: frontend -- ip: 10.0.0.2 - role: backend -``` - -## 3. schema 定义配置的结构 - -KCL 通过 `schema` 语法结构为有着固定属性结构和默认值行为的属性提供抽象支持。 - -比如上面例子的中 `database` 的配置一般是用默认值即可。这样我们可以通过为数据库的默认配置定义一个结构: - -```python -schema DatabaseConfig: - enabled: bool = True - ports: [int] = [8000, 8001, 8002] - data: [[str|float]] = [["delta", "phi"], [3.14]] - temp_targets: {str: float} = {cpu = 79.5, case = 72.0} -``` - -`enabled` 是布尔类型;`ports` 为整数列表类型;`data` 为列表的列表,内层的列表元素是字符串或者浮点数类型;`temp_targets` 则是一个字典类型,字典的属性值是浮点数类型。并且 `DatabaseConfig` 的每个属性都定义了默认值。 - -然后通过 `database = DatabaseConfig {}` 就可以产生和默认值相同属性的结构。用户也可以修改默认值: - -```python -database = DatabaseConfig { - ports = [2020, 2021] -} -``` - -`schema DatabaseConfig` 不仅仅为属性提供了默认值,还为属性添加了类型信息。因此,如果用户不小心写错属性值类型的话,KCL 将会给出友好的错误提示,比如下面的例子将 `ports` 错误地写成了浮点数类型: - -```python -database = DatabaseConfig { - ports = [1.2, 1.3] -} -``` - -执行时将产生类似以下的错误(显示的文件路径和本地环境有关): - -```shell -kcl server.k -``` - -输出为 - -```shell -error[E2G22]: TypeError - --> /path/to/server.k:8:5 - | -8 | ports = [1.2, 1.3] - | ^ expected [int], got [float(1.2)|float(1.3)] - | - - --> /path/to/server.k:3:5 - | -3 | ports: [int] = [8000, 8001, 8002] - | ^ variable is defined here, its type is [int], but got [float(1.2)|float(1.3)] - | -``` - -类似地我们可以用以下的代码封装 `servers` 部分的属性: - -```python -schema ServerConfig: - ip: str - role: "frontend" | "backend" - -servers = [ - ServerConfig {ip = "10.0.0.1", role = "frontend"} - ServerConfig {ip = "10.0.0.2", role = "backend"} -] -``` - -其中 `ServerConfig` 的 `ip` 是字符串类型,并没有给出默认值。用户在生成 `ServerConfig` 类型的属性时必须手工添加 `ip` 属性的值,否则 KCL 将会报出缺少必填属性的错误。`role` 属性是 `"frontend" | "backend"` 枚举字符串类型。 - -此外,`schema` 还可以结合 `check`、`mixin`、可选属性、继承和扩展模块实现更为复杂的配置和策略数据的抽象,细节可以参考手册部分的文档。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/_category_.json deleted file mode 100644 index 1fdf894e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "用户手册", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/automation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/automation.md deleted file mode 100644 index 83eb6446..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/automation.md +++ /dev/null @@ -1,205 +0,0 @@ ---- -title: "自动化" -sidebar_position: 6 ---- - -## 简介 - -在 KCL 中提供了很多自动化相关的能力,主要包括工具和多语言 API。 通过 `package_identifier : key_identifier`的模式支持对任意配置键值的索引,从而完成对任意键值的增删改查。比如下图所示修改某个应用配置的镜像内容,可以直接执行如下指令修改镜像,修改前后的 diff 如下图所示。 - -![](/img/blog/2022-09-15-declarative-config-overview/14-kcl-image-update.png) - -此外,KCL 的自动化能力也可以被集成到 CI/CD 中。 - -![](/img/blog/2022-09-15-declarative-config-overview/15-kcl-automation.png) - -## 使用 KCL 进行自动化 - -### 0. 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. 获得示例 - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/automation -``` - -我们可以执行如下命令显示配置 - -```bash -cat main.k -``` - -输出为 - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "app" - replicas = 1 - labels.key = "value" -} -``` - -我们可以执行如下命令输出配置 - -```bash -kcl main.k -``` - -输出为 - -```yaml -app: - name: app - replicas: 1 - labels: - app: app - key: value -``` - -### 2. 使用 KCL CLI 进行自动化 - -KCL 允许使用通过 CLI `-O|--overrides` 参数修改配置模型中的值,这个参数通常由三个部分组成: 包名 `pkg`, 配置标识符 `identifier`, 配置属性 `attribute` 和覆盖值 `override_value` - -```bash -kcl main.k -O override_spec -``` - -- `override_spec`: 表示需要修改的配置模型字段和值的统一表示 - -```bash -override_spec: [[pkgpath] ":"] identifier ("=" value | "-") -``` - -- `pkgpath`: 表示需要修改标识符的包路径,通常为 `a.b.c` 的形式,对于 main 包,`pkgpath` 表示为 `__main__`, 可省略,省略不写时表示 main 包 -- `identifier`: 表示需要修改配置的标识符,通常为 `a.b.c` 的形式 -- `value`: 表示需要修改配置的值,可以是任意合法的 KCL 表达式,比如数字/字符串字面值,`list`/`dict`/`schema` 表达式等 -- `=`: 表示修改identifier的值 -- `-`: 表示删除 identifier 属性 - -请注意,当 `identifier` 多次出现时,修改/删除全部 `identifier` 的值 - -#### 修改配置 - -执行如下命令可以更新应用名称: - -```bash -kcl main.k -O app.name='new_app' -``` - -输出为 - -```yaml -app: - name: new_app - replicas: 1 - labels: - app: new_app - key: value -``` - -可以看出 `app` 的 `name` 属性的值被修改为了 `new_app` - -此外,当我们使用 KCL CLI `-d` 参数时,KCL 文件将同时修改为以下内容 - -```bash -kcl main.k -O app.name='new_app' -d -``` - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "new_app" - replicas = 1 - labels: {key = "value"} -} -``` - -#### 删除配置 - -执行如下命令可以删除 `labels` 中的 `key` 字段 - -```bash -kcl main.k -O app.labels.key- -``` - -输出为: - -```yaml -app: - name: app - replicas: 1 - labels: - app: app -``` - -执行如下命令 - -```bash -kcl main.k -O config.x- -``` - -输出结果为: - -```yaml -config: - x: 1 - y: s -``` - -### 3. 使用 KCL API 进行自动化 - -此外,我们还可以通过[多语言 API](/docs/reference/xlang-api/overview) 自动修改配置属性 - -以 RestAPI 为例 - -执行如下命令启动 RestAPI 服务端 - -```bash -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -通过如下命令 POST 命令请求配置修改服务 - -```bash -curl -X POST http://127.0.0.1:2021/api:protorpc/KclvmService.OverrideFile -H 'content-type: accept/json' -d '{ - "file": "main.k", - "specs": ["app.name=\"nginx\""] -}' -``` - -服务调用完成后,`main.k` 会被修改为如下形式: - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "nginx" - replicas = 1 - labels: { - "key" = "value" - } -} -``` - -## 小结 - -该文档介绍了KCL的自动化功能,包括工具和多语言 API。它支持对任何配置的键值进行索引,允许添加、删除、修改和查询任何键值。它也可以集成到 CI/CD 中。本文档提供了一个使用 KCL 自动化配置管理的示例,包括使用 KCL CLI/API 覆盖和删除配置。更多信息请参阅[此处](/docs/reference/lang/tour#KCL-cli-variable-Override)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/ci-integration/_2-gitlab-ci.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/ci-integration/_2-gitlab-ci.md deleted file mode 100644 index 5ec96ce9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/ci-integration/_2-gitlab-ci.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -id: gitlab-ci -sidebar_label: Gitlab CI ---- - -Coming Soon - -## Introduction - -## How to - -## Summary diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/gitops/1-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/gitops/1-quick-start.md deleted file mode 100644 index 673064c4..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/gitops/1-quick-start.md +++ /dev/null @@ -1,145 +0,0 @@ ---- -id: gitops-quick-start -sidebar_label: 快速开始 ---- - -# 快速开始 - -## 简介 - -### 什么是 GitOps - -GitOps 是一种实现持续交付的现代方式。它的核心思想是拥有一个包含环境和应用程序配置的 Git 存储库。通过更改应用存储库中的文件,可以自动部署应用程序。应用 GitOps 的好处包括: - -- 提高生产力,持续交付可以加快部署时间。 -- 降低开发人员部署的障碍。通过推送代码而不是容器配置,开发人员可以在不知道其内部实现的情况下轻松部署 Kubernetes 集群和应用。 -- 追踪变更记录。使用 Git 管理配置使每一项更改都具有可跟踪性,从而增强审计跟踪。 - -### 将 KCL 与 ArgoCD 一起使用 - -将 [KCL](https://github.com/kcl-lang/kcl) 与 [ArgoCD](https://github.com/argoproj/argo-cd) 等 GitOps 工具一起使用具有如下好处: - -- 通过 KCL 语言的[抽象能力](/docs/user_docs/guides/abstraction)和可编程能力可以帮助我们**简化复杂的 Kubernetes 部署配置文件**,降低手动编写 YAML 文件的错误率,消除多余的配置模版,提升多环境多租户的配置扩展能力,同时提高配置的可读性和可维护性。 -- KCL 允许开发人员以声明式的方式定义应用程序所需的资源,通过将 KCL 和 ArgoCD 相结合可以帮助我们更好地实现**基础设施即代码(IaC)**,提高部署效率,简化应用程序的配置管理。 -- ArgoCD 可以**自动化**地实现应用程序的连续部署,并提供友好的可视化界面。 - -使用 GitOps,开发人员和运维团队可以通过分别修改应用和配置代码来管理应用程序的部署,GitOps 工具链将自动同步对配置的更改,从而实现持续部署并确保一致性。如果出现问题,可以使用 GitOps 工具链快速回滚。 - -## 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -## 快速开始 - -### 1. 获取示例 - -首先,我们执行 git 命令获得用例 - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/gitops -``` - -我们可以运行以下命令来显示配置 - -```bash -cat config/main.k -``` - -The output is - -```python -import .app - -config = app.App { - name = "kcl-guestbook-ui" - containers.guestbook = { - image = "gcr.io/heptio-images/ks-guestbook-demo:0.2" - ports = [{containerPort = 80}] - } - service.ports = [{ port = 80 }] - service.type = "LoadBalancer" -} -``` - -在上述代码中,我们定义使用 `App` schema 定义了应用的配置,其中我们配置了一个镜像为 `gcr.io/heptio-images/ks-guestbook-demo:0.2` 容器,并启用了 `80` 端口。 - -### 2. 安装 Kubernetes 和 GitOps 工具 - -#### 配置 Kubernetes 集群和 ArgoCD 控制器 - -- 安装 [K3d](https://github.com/k3d-io/k3d) 并创建一个集群 - -```bash -k3d cluster create mycluster -``` - -> 注意:你可以在此方案中使用其他方式创建您自己的 Kubernetes 集群,如 kind, minikube 等。 - -- 安装 [ArgoCD](https://github.com/argoproj/argo-cd/releases/). - -```bash -kubectl create namespace argocd -kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml -``` - -- 安装 ArgoCD KCL 插件 - -```bash -kubectl apply -f ./install/kcl-cmp.yaml && kubectl -n argocd patch deploy/argocd-repo-server -p "$(cat ./install/patch-argocd-repo-server.yaml)" -``` - -- 通过 `kubectl get` 命令查看 argocd 控制器容器是否初始化完成进入运行(Running)状态。 - -```bash -kubectl get pod -n argocd -l app.kubernetes.io/name=argocd-repo-server -``` - -- 通过如下命令打开 ArgoCD UI - -```bash -kubectl port-forward svc/argocd-server -n argocd 8080:443 -``` - -- 打开浏览器 `https://localhost:8080` 输入用户名 "admin" 和密码登陆 ArgoCD UI,密码可以通过如下命令得到: - -```bash -kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d -``` - -#### 安装 ArgoCD 客户端工具 - -- 安装 [ArgoCD 客户端工具](https://github.com/argoproj/argo-cd/releases) - -- 使用用户名 "admin" 和刚才得到的密码登陆 - -```bash -argocd login localhost:8080 -``` - -通过如下命令创建一个 ArgoCD KCL 应用 - -```bash -argocd app create guestbook \ ---repo https://github.com/kcl-lang/kcl-lang.io \ ---path examples/gitops/config \ ---dest-namespace default \ ---dest-server https://kubernetes.default.svc \ ---config-management-plugin kcl-v1.0 -``` - -如果创建成功,您可以看到如下输出: - -```bash -application 'guestbook' created -``` - -> 如果您使用的是私有存储库,则在执行 create 命令之前,需要使用私钥凭据配置专用私有存储库访问权限。请参阅[这里](https://argo-cd.readthedocs.io/en/stable/user-guide/private-repositories/)以获取更多详细信息。 - -通过 ArgoCD UI,您可以看到创建的应用程序尚未同步,您可以手动进行配置同步或设置为自动同步。 - -![](/img/docs/user_docs/guides/gitops/argocd-kcl-app.jpg) - -有关同步策略的更多信息,可以请参阅[这里](https://argo-cd.readthedocs.io/en/stable/user-guide/sync-options/) - -![](/img/docs/user_docs/guides/gitops/argocd-kcl-app-dashboard.jpg) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/index.md deleted file mode 100644 index c0613d42..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/index.md +++ /dev/null @@ -1 +0,0 @@ -# 用户手册 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/1-overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/1-overview.md deleted file mode 100644 index ce7b13cb..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/1-overview.md +++ /dev/null @@ -1,3 +0,0 @@ -# 简介 - -KCL 通过包管理工具 [kpm](https://github.com/kcl-lang/kpm) 对 KCL 包进行管理。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/2-installation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/2-installation.md deleted file mode 100644 index 7b0892a5..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/2-installation.md +++ /dev/null @@ -1,53 +0,0 @@ -# 安装 - -## 安装 `kpm` - -kpm 将调用 `KCL`编译器来编译 KCL 程序。在使用 `kpm` 之前,您需要确保 `KCL` 编译器已经成功安装,您可以参照[如何安装 KCL 编译器](https://kcl-lang.io/docs/user_docs/getting-started/install)。 - -### 使用 `go install` 安装 `kpm` - -您可以使用 go install 命令安装 kpm。 - -```shell -go install kcl-lang.io/kpm@latest -``` - -### 从 Github release 页面手动安装 `kpm` - -您可以从 [kpm Github Release](https://github.com/kcl-lang/kpm/releases) 中获取 `kpm` ,并将 `kpm` 的二进制文件路径设置到环境变量 PATH 中。 - -```shell -# KPM_INSTALLATION_PATH 是 `kpm` 二进制文件的所在目录. -export PATH=$KPM_INSTALLATION_PATH:$PATH -``` - -请使用以下命令以确保您成功安装了`kpm`。 - -```shell -kpm --help -``` - -如果你看到以下输出信息,那么你已经成功安装了`kpm`,可以继续执行下一步操作。 - -```shell -NAME: - kpm - kpm is a kcl package manager - -USAGE: - kpm [arguments]... - -COMMANDS: - init initialize new module in current directory - add add new dependency - pkg package a kcl package into tar - metadata output the resolved dependencies of a package - run compile kcl package. - login login to a registry - logout logout from a registry - push push kcl package to OCI registry. - pull pull kcl package from OCI registry. - help, h Shows a list of commands or help for one command - -GLOBAL OPTIONS: - --help, -h show help -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/3-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/3-quick-start.md deleted file mode 100644 index 455987c8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/3-quick-start.md +++ /dev/null @@ -1,108 +0,0 @@ -# 快速开始 - -## 1. 初始化一个空的 KCL 包 - -使用 `kpm init` 命令创建一个名为 `my_package` 的 kcl 程序包, 并且在我们创建完成一个名为 `my_package` 的包后,我们需要通过命令 `cd my_package` 进入这个包来进行后续的操作。 - -```shell -kpm init my_package && cd my_package -``` - -![kpm_init](/img/docs/user_docs/guides/package-management/gifs/kpm_init.gif) - -`kpm` 将会在执行`kpm init my_package`命令的目录下创建两个默认的配置文件 `kcl.mod` 和 `kcl.mod.lock`。 - -```shell -- my_package - |- kcl.mod - |- kcl.mod.lock - |- # 你可以直接在这个目录下写你的kcl程序。 -``` - -`kcl.mod.lock` 是 `kpm` 用来固定依赖版本的文件,是自动生成的,请不要人工修改这个文件。 - -`kpm` 将会为这个新包创建一个默认的 `kcl.mod`。如下所示: - -```shell -[package] -name = "my_package" -edition = "0.0.1" -version = "0.0.1" -``` - -## 2. 为 KCL 包添加依赖 - -然后,您可以通过 `kpm add` 命令来为您当前的库添加一个外部依赖。 - -如下面的命令所示,为当前包添加一个版本号为 `1.27.2` 并且名为 `k8s` 的依赖包。 - -```shell -kpm add k8s:1.27.2 -``` - -![kpm_add_k8s](/img/docs/user_docs/guides/package-management/gifs/kpm_add_k8s.gif) - -`kpm` 会为您将依赖添加到 kcl.mod 文件中. - -```shell -[package] -name = "my_package" -edition = "0.0.1" -version = "0.0.1" - -[dependencies] -k8s = "1.27.2" # The dependency 'k8s' with version '1.27.2' -``` - -## 编写一个程序使用包 `konfig` 中的内容 - -在当前包中创建 `main.k`。 - -```shell -- my_package - |- kcl.mod - |- kcl.mod.lock - |- main.k # Your KCL program. -``` - -并且将下面的内容写入 `main.k` 文件中。 - -```kcl -# 导入并使用外部依赖 `k8s` 包中的内容。 -import k8s.api.core.v1 as k8core - -k8core.Pod { - metadata.name = "web-app" - spec.containers = [{ - name = "main-container" - image = "nginx" - ports = [{containerPort = 80}] - }] -} - -``` - -## 3. 运行 KCL 代码 - -你可以使用 kpm 编译刚才编写的 `main.k` 文件, 得到编译后的结果。 - -```shell -kpm run -``` - -输出为 - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: web-app -spec: - containers: - - image: nginx - name: main-container - ports: - - containerPort: 80 -``` - -![kpm_run](/img/docs/user_docs/guides/package-management/gifs/kpm_run.gif) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md deleted file mode 100644 index 23dd53a5..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md +++ /dev/null @@ -1,73 +0,0 @@ -# 发布 KCL 包到 ghcr.io - -本文将指导您如何使用 kcl 包管理将您的 kcl 包推送到发布到 OCI Registry 中。kcl 包管理默认使用 [ghcr.io](https://ghcr.io) 作为 OCI Registry, 您可以通过修改 kcl 包管理配置文件来更改默认的 OCI Registry。关于如何修改 kcl 包管理配置文件的信息,请参阅 [kcl oci registry](https://github.com/kcl-lang/kpm/blob/main/docs/kpm_oci-zh.md#kpm-registry) - -下面是一个简单的步骤,指导您如何使用 kcl 包管理将您的 kcl 包推送到 ghcr.io。 - -## 步骤 1:安装 KCL CLI - -首先,您需要在您的计算机上安装 KCL CLI。您可以按照 [KCL CLI 安装文档](https://kcl-lang.io/zh-CN/docs/user_docs/getting-started/install)中的说明进行操作。 - -## 步骤 2:创建一个 ghcr.io 令牌 - -如果您使用默认的 OCI Registry, 要将 kcl 包推送到 ghcr.io,您需要创建一个用于身份验证的令牌。您可以参考以下文档。 - -- [创建 ghcr.io token](https://docs.github.com/zh/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic) - -## 步骤 3:登录 ghcr.io - -在安装了 kcl 包管理并创建了 ghcr.io 令牌后,您需要使用 kcl 包管理登录 ghcr.io。您可以使用以下命令进行操作: - -```shell -kcl registry login -u -p ghcr.io -``` - -其中 `` 是您的 GitHub 用户名,`` 是您在步骤 2 中创建的令牌。 - -关于如何使用 kcl 包管理登录 ghcr.io 的更多信息,请参阅 [kcl registry login](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/login)。 - -## 步骤 4:推送您的 kcl 包 - -现在,您可以使用 kcl 包管理将您的 kcl 包推送到 ghcr.io。 - -### 1. 一个合法的 kcl 包 - -首先,您需要确保您推送的内容是符合一个 kcl 包的规范,即必须包含合法的 kcl.mod 和 kcl.mod.lock 文件。 - -如果您不知道如何得到一个合法的 `kcl.mod` 和 `kcl.mod.lock`。您可以使用 `kcl mod init` 命令。 - -```shell -# 创建一个名为 my_package 的 kcl 包 -kcl mod init my_package -``` - -`kcl mod init my_package` 命令将会为您创建一个新的 kcl 包 `my_package`, 并为这个包创建 `kcl.mod` 和 `kcl.mod.lock` 文件。 - -如果您已经有了一个包含 kcl 文件的目录 `exist_kcl_package`,您可以使用以下命令将其转换为一个 kcl 包,并为其创建合法的 `kcl.mod` 和 `kcl.mod.lock`。 - -```shell -# 在 exist_kcl_package 目录下 -$ pwd -/home/user/exist_kcl_package - -# 执行 kcl 包管理init 命令来创建 kcl.mod 和 kcl.mod.lock -$ kcl mod init -``` - -关于如何使用 kcl 包管理init 的更多信息,请参阅 [kcl mod init](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/init)。 - -### 2. 推送 kcl 包 - -您可以在 `kcl` 包的根目录下使用以下命令进行操作: - -```shell -# 在 exist_kcl_package 包的根目录下 -$ pwd -/home/user/exist_kcl_package - -# 推送 kcl 包到默认的 OCI Registry -$ kcl mod push -``` - -完成上述步骤后,您就成功地将您的 kcl 包推送到了默认的 OCI Registry 中。 -关于如何使用 kcl mod push 的更多信息,请参阅 [kcl mod push](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/push)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md deleted file mode 100644 index 9bb9f1cc..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md +++ /dev/null @@ -1,65 +0,0 @@ -# 发布 KCL 包到 docker.io - -本文将指导您如何使用 kcl 包管理将您的 kcl 包推送到发布到 docker.io 中。 - -## 步骤 1:安装 KCL CLI - -首先,您需要在您的计算机上安装 KCL CLI。您可以按照 [KCL CLI 安装文档](https://kcl-lang.io/zh-CN/docs/user_docs/getting-started/install)中的说明进行操作。 - -## 步骤 2:创建一个 docker.io 账户 - -您需要创建一个 docker.io 账户以支持您的 kcl 包的推送。 - -## 步骤 3:登录 docker.io - -您可以直接使用 docker.io 的账户名和密码登录。 - -```shell -kcl registry login -u -p docker.io -``` - -其中 `` 是您的 docker.io 用户名,`` 是您 docker.io 账户的密码。 - -关于如何使用 KCL CLI 登录 docker.io 的更多信息,请参阅 [kcl registry login](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/login)。 - -## 步骤 4:推送您的 kcl 包 - -现在,您可以使用 KCL CLI 将您的 kcl 包推送到 docker.io。 - -### 1. 一个合法的 kcl 包 - -首先,您需要确保您推送的内容是符合一个 kcl 包的规范,即必须包含合法的 kcl.mod 和 kcl.mod.lock 文件。 - -如果您不知道如何得到一个合法的 `kcl.mod` 和 `kcl.mod.lock`。您可以使用 `kcl mod init` 命令。 - -例如:创建一个名为 my_package 的 kcl 包 - -```shell -# 创建一个名为 my_package 的 kcl 包 -kcl mod init my_package -``` - -`kcl mod init my_package` 命令将会为您创建一个新的 kcl 包 `my_package`, 并为这个包创建 `kcl.mod` 和 `kcl.mod.lock` 文件。 - -如果您已经有了一个包含 kcl 文件的目录 `exist_kcl_package`,您可以使用以下命令将其转换为一个 kcl 包,并为其创建合法的 `kcl.mod` 和 `kcl.mod.lock`。 - -在 `exist_kcl_package` 目录下执行: - -```shell -kcl mod init -``` - -关于如何使用 kpm init 的更多信息,请参阅 [kcl mod init](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/init)。 - -### 2. 推送 kcl 包 - -您可以在 `kcl` 包的根目录下使用以下命令进行操作: - -在 `exist_kcl_package` 包的根目录下, 执行 - -```shell -kcl mod push oci://docker.io//exist_kcl_package -``` - -完成上述步骤后,您就成功地将您的 kcl 包 `exist_kcl_package` 推送到了 docker.io 中。 -关于如何使用 kcl mod push 的更多信息,请参阅 [kcl mod push](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/push)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/4-how-to/6-push_github_action.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/4-how-to/6-push_github_action.md deleted file mode 100644 index 2f18b66f..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/4-how-to/6-push_github_action.md +++ /dev/null @@ -1,83 +0,0 @@ -# 如何在 github action 中使用 kcl 包管理发布您的 KCL 包 - -本文将指导您如何在 GitHub Action 中使用 kcl 包管理将您的 kcl 包推送到发布到 ghcr.io 中。 - -## 步骤 1:安装 KCL CLI - -首先,您需要在您的计算机上安装 KCL CLI。您可以按照 [KCL CLI 安装文档](https://kcl-lang.io/zh-CN/docs/user_docs/getting-started/install)中的说明进行操作。 - -## 步骤 2:创建一个 GitHub 账号 - -如果您已经有 GitHub 帐号了,您可以选择跳过这一步 - -[注册新的一个 GitHub 账号](https://docs.github.com/zh/get-started/signing-up-for-github/signing-up-for-a-new-github-account) - -## 步骤 3: 为您的 KCL 包创建一个 GitHub 仓库并进行相关配置 - -### 1. 为您的 KCL 程序包准备仓库 - -您需要为您的 KCL 程序包准备一个 GitHub 仓库。 - -[创建一个 GitHub 仓库](https://docs.github.com/zh/get-started/quickstart/create-a-repo) - -在这个仓库中添加您的 KCL 程序,以仓库 https://github.com/awesome-kusion/catalog.git 为例, - -```bash -├── .github -│ └── workflows -│ └── push.yaml # github action 文件 -├── LICENSE -├── README.md -├── kcl.mod # kcl.mod 将当前仓库内容定义为一个 kcl 包 -├── kcl.mod.lock # kcl.mod.lock 是 kcl 包管理工具自动生成的文件 -└── main.k # 您的 KCL 程序 -``` - -### 2. 为您的仓库设置 OCI Registry,账户和密码 - -以 docker.io 为例,您可以为您的仓库设置 secrets `REG`, `REG_ACCOUNT` 和 `REG_TOKEN`。`REG` 的值为 `docker.io`,`REG_ACCOUNT` 的值为您的 docker.io 账户, `REG_TOKEN` 为您的 `docker.io` 登录密码。 - -[为仓库添加 secrets](https://docs.github.com/zh/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) - -如果您使用 `ghcr.io` 作为 `Registry`, 您需要使用 GitHub token 作为 secrets。 - -[创建一个 GitHub Token](https://docs.github.com/zh/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#personal-access-tokens-classic) - -## 步骤 4: 将您的 KCL 包添加到仓库中并编写 github action workflow - -为这个仓库添加 github action 文件 `.github/workflows/push.yml`,内容如下: - -```yaml -name: KPM Push Workflow - -on: - push: - branches: - - main - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Set up Go 1.21 - uses: actions/setup-go@v2 - with: - go-version: 1.21 - - - name: Install KCL CLI - run: go install kcl-lang.io/cli/cmd/kcl@latest - - - name: Login and Push - env: - # 通过环境变量指定 OCI Registry 和账户 - KPM_REG: ${{ secrets.REG }} - KPM_REPO: ${{ secrets.REG_ACCOUNT }} - # kcl registry login 时使用 secrets.REG_TOKEN - run: kcl registry login -u ${{ secrets.REG_ACCOUNT }} -p ${{ secrets.REG_TOKEN }} ${{ secrets.REG }} && kcl mod push - - - name: Run KCL project from oci registry - run: kcl run oci://${{ secrets.REG }}/${{ secrets.REG_ACCOUNT }}/catalog --tag 0.0.1 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/4-how-to/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/4-how-to/_category_.json deleted file mode 100644 index 370cb4e9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/4-how-to/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "如何使用", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/_category_.json deleted file mode 100644 index d1600bfd..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/package-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "包管理", - "position": 7 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/secret-management/1-vault.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/secret-management/1-vault.md deleted file mode 100644 index f070a784..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/secret-management/1-vault.md +++ /dev/null @@ -1,142 +0,0 @@ ---- -id: vault -sidebar_label: Vault ---- - -# Vault - -## 简介 - -This guide will show you that KCL solves the secret management problem by integrating [Vault](https://developer.hashicorp.com/vault) and [Vals](https://github.com/helmfile/vals). - -## 先决条件 - -- Install [KCL](/docs/user_docs/getting-started/install) -- Prepare a [Kubernetes Cluster](https://kubernetes.io/) -- Install [Vault](https://developer.hashicorp.com/vault/downloads) -- Install [Vals](https://github.com/helmfile/vals) - -## 具体步骤 - -### 1. 获得示例 - -We put the application source code and infrastructure deployment code in different repos, which can be maintained by different roles to achieve the separation of concerns. - -- Get the application code - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/secret-management/vault -``` - -- Show the config - -```shell -cat main.k -``` - -The output is - -```python -# Secret Management using Vault and Vals - -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" - annotations: { - "secret-store": "vault" - # Valid format: - # "ref+vault://PATH/TO/KV_BACKEND#/KEY" - "foo": "ref+vault://secret/foo#/foo" - "bar": "ref+vault://secret/bar#/bar" - } -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -The main.k file extends the configuration of the Nginx application and customizes annotations. Among them, the value of annotation `foo` and `bar` follow secret reference format (`ref+vault://PATH/TO/KV_BACKEND#/KEY`): - -- `ref+vault`: indicates that this is a secret reference, and the external storage service is `Vault`. -- `PATH/TO/KV_BACKEND`: specifies the path where a secret is stored. -- `KEY`: specifies the key to reading secret. - -The complete format is concatenated using a style similar to URI expressions, which can retrieve a secret stored externally. - -### 2. 预存敏感信息 - -Start the Vault Server - -```shell -vault server -dev -export VAULT_ADDR='http://127.0.0.1:8200' -# Note: Replace with your token -export VAULT_TOKEN=yourtoken -``` - -After Vault is started in development mode and unpacked, secrets are pre-stored, and the path and keys are consistent with `main.k`: - -```shell -vault kv put secret/foo foo=foo -vault kv put secret/bar bar=bar -``` - -### 3. 部署配置 - -Using the following command to apply the deployment manifest. - -```shell -kcl main.k | vals eval -f - | kubectl apply -f - -``` - -The expect output is - -```shell -deployment.apps/nginx created -``` - -### 4. 验证敏感信息 - -Next, verify that the secrets have been retrieved from Vault and replace the values of annotations of Nginx: - -- Verify the `foo` annotation - -```shell -kubectl get deploy nginx -o yaml | grep 'foo:' -``` - -The output is - -```yaml -foo: foo -``` - -- Verify the `bar` annotation - -```shell -kubectl get deploy nginx -o yaml | grep 'bar:' -``` - -The output is - -```yaml -bar: bar -``` - -So far, we have retrieved the secrets hosted in `Vault` and put them into use. - -## 小结 - -This guide introduces how KCL solves the secret management by integrating Vault and Vals. By following these steps, we can retrieve the secrets hosted in Vault and utilize them. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/validation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/validation.md deleted file mode 100644 index 2368ec22..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/validation.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: "校验" -sidebar_position: 2 ---- - -## 简介 - -验证是校验数据是否准确、可靠并满足某些要求或限制的过程,包括检查数据的完整性、一致性、准确性和相关性。进行数据验证是为了确保数据符合其预期目的,并能有效使用。 - -我们可以使用 KCL 及其校验工具手动或自动进行数据验证,以确保数据的一致性。 - -## 使用 KCL 校验数据 - -除了使用 KCL 代码生成 JSON/YAML 等配置格式,KCL 还支持对 JSON/YAML 数据进行格式校验。作为一种配置语言,KCL 在验证方面几乎涵盖了 OpenAPI 的所有功能。在 KCL 中可以通过一个结构定义来约束配置数据,同时支持通过 check 块自定义约束规则,在 schema 中书写校验表达式对 schema 定义的属性进行校验和约束。通过 check 表达式可以非常清晰简单地校验输入的 JSON/YAML 是否满足相应的 schema 结构定义与 check 约束。 - -### 0. 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. 获得示例 - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/validation -``` - -我们可以执行如下命令显示配置 - -```bash -cat schema.k -``` - -输出为 - -```python -schema User: - name: str - age: int - message?: str - data: Data - labels: {str:} - hc: [int] - - check: - age > 10, "age must > 10" - -schema Data: - id: int - value: str -``` - -在 schema 中,我们可以使用 `check` 关键字来编写每个 schema 属性的验证规则。`check` 块中的每一行都对应于一个条件表达式。当满足条件时,验证成功。条件表达式后面可以跟 `, "报错信息"`,以指示检查失败时要给用户显示的消息。 - -综上所述,KCL Schema 中支持的校验类型为: - -| 校验类型 | 使用方法 | -| -------- | ---------------------------------------------------------- | -| 范围校验 | 使用 `<`, `>` 等比较运算符 | -| 正则校验 | 使用 `regex` 系统库中的 `match` 等方法 | -| 长度校验 | 使用 `len` 内置函数,可以求 `list/dict/str` 类型的变量长度 | -| 枚举校验 | 使用字面值联合类型 | -| 非空校验 | 使用 schema 的可选/必选属性 | -| 条件校验 | 使用 check if 条件表达式 | - -### 2. 验证数据 - -新建一个名为 `data.json` 的 JSON 配置文件: - -```json -{ - "name": "Alice", - "age": 18, - "message": "This is Alice", - "data": { - "id": 1, - "value": "value1" - }, - "labels": { - "key": "value" - }, - "hc": [1, 2, 3] -} -``` - -执行如下命令获得校验结果 - -```bash -kcl-vet data.json schema.k -``` - -## 小结 - -KCL 是一种配置语言,通过其结构定义和用户定义的约束规则来支持数据验证。KCL Schema 中支持的验证类型包括范围、正则表达式、长度、枚举、可选/必需和条件。并且可以使用 KCL 验证工具或在此基础上构建的可视化产品来验证数据。 - -## 未来计划 - -KCL 校验能力的提升将逐渐围绕"静态化"方面展开工作,即在编译时,结合形式化验证的能力直接分析得出数据是否满足约束条件、约束条件是否冲突等结论,并且可以通过 IDE 实时透出约束错误,而无需在运行时发现错误。 - -我们还期望 KCL Schema 和约束可以作为一个包来管理(这个包只有 KCL 文件)。例如,Kubernetes 模型和约束可以开箱即用。用户可以生成配置或验证现有配置,并且可以通过 KCL 继承简单地扩展用户想要的模型和约束。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md deleted file mode 100644 index 5ebfe83c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: "从 Kubernetes 迁移" -sidebar_position: 1 ---- - -## 简介 - -KCL 对 Kubernetes 配置提供了许多开箱即用的支持,通过 KCL 工具,我们可以将 Kubernetes Schema 和 配置集成到 KCL 中,本节内容将介绍如何使用 KCL 对 Kubernetes 进行集成 - -### 1. Kubernetes OpenAPI Spec - -从 Kubernetes 1.4 开始,引入了对 OpenAPI 规范(在捐赠给 Open API Initiative 之前称为 swagger 2.0)的 alpha 支持,API 描述遵循 [OpenAPI 规范 2.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md),从 Kubernetes 1.5 开始,Kubernetes 能够直接从[源码自动地提取模型并生成 OpenAPI 规范](https://github.com/kubernetes/kube-openapi),自动化地保证了规范和文档与操作/模型的更新完全同步。 - -此外,Kubernetes CRD 使用 [OpenAPI v3.0 validation](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation) 来描述(除内置属性 apiVersion、kind、metadata 之外的)自定义 schema,在 CR 的创建和更新阶段,APIServer 会使用这个 schema 对 CR 的内容进行校验。 - -### 2. KCL OpenAPI 支持 - -KCLOpenAPI 工具支持从 OpenAPI/CRD 定义提取并生成 KCL schema. 在 KCLOpenAPI Spec 中明确定义了 OpenAPI 规范与 KCL 语言之间的映射关系。 - -### 3. 从 Kubernetes 模型迁移到 KCL - -#### 3.1 基于 kusion_models 编写配置 - -我们为你提供了一个开箱即用的 `kusion_models` 包,让你可以快速开始。其中包含一个精心设计的前端模型,称为[服务器模型](https://github.com/KusionStack/konfig/blob/main/base/pkg/kusion_models/kube/frontend/server.k)(Server schema)。你可以通过初始化 `Server schema` 来声明其配置。有关模式及其属性的说明和用法,请参阅 [Server schema 文档](https://kusionstack.io/docs/reference/model/kusion_models/kube/frontend/doc_server)。 - -#### 3.2 创建自定义的 models 前端模型 - -现有的 `kusion_models` 模型可能无法满足你的特定业务需求,那么你也可以设计自定义前端模型包。 您可基于预先生成的 Kubernetes KCL 包自定义您的前端模型。您还可以仿照`kube2kcl` 工具的模式,开发自定义脚本,完成配置数据的迁移。 - -##### 3.2.1 获取 Kubernetes KCL 模型 - -我们提供了预生成的各版本[Kubernetes KCL模型](https://github.com/orgs/KusionStack/packages/container/package/k8s),您可以在项目下执行 `kpm add k8s:` 来获得它。有关 kpm 使用的详细信息,请参考 [kpm快速入门指南](https://github.com/kcl-lang/kpm#quick-start)。 - -或者,如果您需要自己生成这些包,请参考[从 Kubernetes OpenAPI 文件生成 KCL 包](https://github.com/kcl-lang/kcl-openapi/blob/main/docs/generate_from_k8s_spec.md)。 - -##### 3.2.2 编写自定义前端模型 - -由于 Kubernetes 内置模型较为原子化和复杂,我们推荐以 Kubernetes 原生模型作为后端输出的模型,对其进一步抽象,而向用户暴露一份更为友好和简单的前端模型界面,具体您可参照 Konfig 仓库中 [kusion_models Server](https://github.com/KusionStack/konfig/blob/main/base/pkg/kusion_models/kube/frontend/server.k) 模型的设计方式进行。 - -##### 3.2.3 迁移配置数据 - -对于存量的 Kubernetes 配置数据,您可以仿照 kube2Kcl 工具的做法,编写自定义的转换脚本,进行一键迁移。Kusion 后续将提供该脚本的编写脚手架和编写指南。 - -### 4. 从 Kubernetes CRD 迁移 - -如果您的项目中使用了 CRD,也可以采用类似的模式,生成 CRD 对应的 KCL schema,并基于该 schema 声明 CR。 - -- 从 CRD 生成 KCL Schema - - ``` - kcl-openapi generate model --crd --skip-validation -f your_crd.yaml - ``` - -- 使用 KCL 声明 CR - - 使用 KCL 声明 CR 的模式与声明 Kubernetes 内置模型配置的模式相同,在此不做赘述。 - -## 小结 - -本节介绍了如何使用 kcl-openapi 工具将 OpenAPI 规范映射到 KCL 语言特性,此外提供了将 KCL 与 OpenAPI 和 Kubernetes CRD 一起使用的快速入门指南帮助从 Kubernetes 进行迁移或集成。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md deleted file mode 100644 index e674c946..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md +++ /dev/null @@ -1,249 +0,0 @@ ---- -title: "使用 KCL 生成并管理 Kubernetes 资源配置" -sidebar_position: 2 ---- - -## 简介 - -当我们管理 Kubernetes 资源清单时,我们常常会手写维护,或者使用 Helm 和 Kustomize 等工具来维护我们 YAML 配置或者配置模版,然后通过 kubectl 和 helm 命令行等工具将资源下发到集群。但是作为一个 "YAML 工程师" 每天维护 YAML 配置无疑是琐碎且无聊的,并且容易出错。 - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: ... # Omit -spec: - selector: - matchlabels: - cell: RZ00A - replicas: 2 - template: - metadata: ... # Omit - spec: - tolerations: - - effect: NoSchedules - key: is-over-quota - operator: Equal - value: 'true' - containers: - - name: test-app - image: images.example/app:v1 # Wrong ident - resources: - limits: - cpu: 2 # Wrong type. The type of cpu should be str - memory: 4Gi - # Field missing: ephemeral-storage - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: is-over-quota - operator: In - values: - - 'true' -``` - -- YAML 中的结构化数据是无类型的,缺乏验证方法,无法立即检查所有数据的有效性 -- YAML 编程能力欠佳,容易写出不正确的缩进,也没有逻辑判断等常见代码组织方式,容易写出大量重复配置,难以维护 -- Kubernetes 设计是复杂的,用户很难理解所有细节,比如上面配置中的 `toleration` 和 `affinity` 字段,如果用户不理解调度逻辑,它可能被错误地省略掉或者多余的添加 - -因此,KCL 期望在 Kubernetes YAML 资源管理解决如下问题: - -- 用**生产级高性能编程语言**以**编写代码**的方式提升配置的灵活度,比如条件语句、循环、函数、包管理等特性提升配置重用的能力 -- 在代码层面提升**配置语义验证**的能力,比如字段可选/必选、类型、范围等配置检查能力 -- 提供**配置分块编写、组合和抽象的能力**,比如结构定义、结构继承、约束定义等能力 - -## 先决条件 - -首先可以在 [KCL 快速开始](/docs/user_docs/getting-started/kcl-quick-start) 根据指导下载并安装 KCL,然后准备一个 [Kubernetes](https://kubernetes.io/) 环境 - -## 快速开始 - -### 1. 生成 Kubernetes 资源 - -我们可以编写如下 KCL 代码并命名为 main.k ,KCL 受 Python 启发,基础语法十分接近 Python, 比较容易学习和上手, 配置模式写法很简单,`k [: T] = v`, 其中 `k` 表示配置的属性名称; `v` 表示配置的属性值; `: T` 表示一个可选的类型注解。 - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -上述 KCL 代码中我们分别声明了一个 Kubernetes Deployment 资源的 `apiVersion`、`kind`、`metadata` 和 `spec` 等变量,并分别赋值了相应的内容,特别地,我们将 `metadata.labels` 字段分别重用在 `spec.selector.matchLabels` 和 `spec.template.metadata.labels` 字段。可以看出,相比于 YAML,KCL 定义的数据结构更加紧凑,而且可以通过定义局部变量实现配置重用。 - -我们可以执行如下命令行得到一个 Kubernetes YAML 文件 - -```bash -kcl main.k -``` - -输出为: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -当然我们可以将 KCL 工具与 kubectl 等工具结合使用,让我们执行如下命令并看看效果 - -```shell -kcl main.k | kubectl apply -f - -``` - -输出为 - -```shell -deployment.apps/nginx-deployment configured -``` - -可以从命令行的结果看出与我们使用直接使用 YAML 配置和 kubectl apply 的一个 Deployment 体验完全一致 - -通过 kubectl 检查部署状态 - -```shell -kubectl get deploy -``` - -输出为 - -```shell -NAME READY UP-TO-DATE AVAILABLE AGE -nginx-deployment 3/3 3 3 15s -``` - -### 2. 编写代码管理 Kubernetes 资源 - -对于 Kubernetes 资源发布时,我们常常会遇到配置参数需要动态指定的场景,比如不同的环境需要设置不同的 `image` 字段值生成不同环境的资源。对于这种场景,我们可以通过 KCL 的条件语句和 `option` 函数动态地接收外部参数。我们可以在上述例子的基础上根据不同的环境调整配置参数,比如对于如下代码,我们编写了一个条件语句并输入一个名为 `env` 的动态参数 - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" if option("env") == "prod" else "${metadata.name}:latest" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -使用 KCL 命令行 `-D` 标记接收一个外部设置的动态参数: - -```bash -kcl main.k -D env=prod -``` - -输出为: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -上述代码片段中的 `image = metadata.name + ":1.14.2" if option("env") == "prod" else metadata.name + ":latest"` 意思为:当动态参数 `env` 的值被设置为 `prod` 时,image 字段值为 `nginx:1.14.2`, 否则为 `nginx:latest`,因此我们可以根据需要为 env 设置为不同的值获得不同内容的 Kubernetes 资源。 - -并且 KCL 支持将 option 函数动态参数维护在配置文件中,比如编写下面展示的 `kcl.yaml` 文件 - -```yaml -kcl_options: - - key: env - value: prod -``` - -使用如下命令行也可以得到同样的 YAML 输出,以简化 KCL 动态参数的输入过程 - -```bash -kcl main.k -Y kcl.yaml -``` - -输出为: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## 小结 - -KCL 可以用于生成和管理 Kubernetes 资源,解决管理 YAML 配置的局限性,例如缺乏验证方法和较弱的编程能力等,并可以通过条件语句和 option 函数动态接收外部参数,从而能够根据不同的环境调整配置参数。此外,KCL 可以与 kubectl 等其他工具一起使用将配置一键生效到集群。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md deleted file mode 100644 index 5fe97d05..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: "Kubectl KCL 插件" -sidebar_position: 1 ---- - -## 简介 - -[Kubectl](https://kubernetes.io/docs/reference/kubectl/) is a command line tool for communicating with a Kubernetes cluster's control plane, using the Kubernetes API. You can use the `Kubectl-KCL-Plugin` to - -- Edit the YAML configuration in a hook way to separate data and logic for the Kubernetes manifests management. -- For multi-environment and multi-tenant scenarios, you can maintain these configurations gracefully rather than simply copy and paste. -- Validate all KRM resources using the KCL schema. - -## 前置条件 - -- Install [Kubectl](https://github.com/kubernetes/kubectl) -- Install [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) - -## 快速开始 - -Let’s write a KCL function which add annotation `managed-by=krm-kcl` only to `Deployment` resources in the helm chart. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/kubectl-kcl.git/ -cd ./kubectl-kcl/examples/ -``` - -### 2. Test and Run - -Run the KCL code via the `Kubectl KCL Plugin`. - -```bash -kubectl kcl run -f ./kcl-run.yaml -``` - -The output yaml is - -```yaml -apiVersion: config.kubernetes.io/v1 -kind: ResourceList -items: - - apiVersion: apps/v1 - kind: Deployment - metadata: - annotations: - managed-by: krm-kcl - labels: - app: nginx - name: nginx-deployment - spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - image: "nginx:1.14.2" - name: nginx - ports: - - containerPort: 80 - - apiVersion: v1 - kind: Service - metadata: - name: test - spec: - ports: - - port: 80 - protocol: TCP - targetPort: 9376 - selector: - app: MyApp -functionConfig: - # kcl-fn-config.yaml - apiVersion: krm.kcl.dev/v1alpha1 - kind: KCLRun - metadata: - # EDIT THE SOURCE! - # This should be your KCL code which preloads the `ResourceList` to `option("resource_list") - spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "krm-kcl"}} for resource in option("resource_list").items] -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md deleted file mode 100644 index 271f08e8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: "Helm KCL 插件" -sidebar_position: 2 ---- - -## 简介 - -[Helm](https://github.com/helm/helm) 是一个管理 Charts 的工具。Charts 是预配置的 Kubernetes 资源的包。您可以使用 `Helm-KCL-Plugin` 来完成以下操作: - -- 以 hook 的方式编辑 Helm charts,将数据和逻辑分离以便更好地管理 Kubernetes manifests -- 对于多环境和多租户方案,可以优雅地维护这些配置,而不仅仅是简单地复制和粘贴 -- 使用 KCL 模式验证所有 KRM 资源 - -## 先决条件 - -- 安装 [Helm](https://github.com/helm/helm) -- 安装 [Helm KCL 插件](https://github.com/kcl-lang/helm-kcl) - -## 快速开始 - -让我们编写一个仅向 `Deployment` 资源添加 annotation `managed-by=helm-kcl-plugin` 的 KCL 函数 - -### 1. 获取示例 - -```bash -git clone https://github.com/kcl-lang/helm-kcl.git/ -cd ./helm-kcl/examples/workload-charts-with-kcl -``` - -### 2. 测试和运行 - -通过 `Helm KCL Plugin` 运行KCL代码。 - -```bash -helm kcl template --file ./kcl-run.yaml -``` - -输出的YAML为 - -```yaml -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: workload - app.kubernetes.io/version: 0.1.0 - helm.sh/chart: workload-0.1.0 - name: workload -spec: - ports: - - name: www - port: 80 - protocol: TCP - targetPort: 80 - selector: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - type: ClusterIP ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: workload - app.kubernetes.io/version: 0.1.0 - helm.sh/chart: workload-0.1.0 - name: workload - annotations: - managed-by: helm-kcl-plugin -spec: - selector: - matchLabels: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - template: - metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - spec: - containers: - - image: nginx:alpine - name: frontend -``` - -## KCL 开发指南 - -以下是您可以在 KCL 代码中执行的操作: - -- 从 `option("resource_list")` 读取资源。`option("resource_list")` 符合 [KRM 函数规范](https://kpt.dev/book/05-developing-functions/01-functions-specification)。 你可以从 `option("resource_list")["items"]` 读取输入资源,并从 `option("resource_list")["functionConfig"]` 读取 `functionConfig`。 -- 返回输出资源的 KPM 列表。 -- 使用 `assert {condition},{error_message}` 返回错误消息。 - -## 更多文档和示例 - -- [Helm KCL 插件](https://github.com/kcl-lang/helm-kcl) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md deleted file mode 100644 index 4f1c8c56..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -title: "Kustomize KCL 插件" -sidebar_position: 3 ---- - -## 简介 - -[Kustomize](https://github.com/kubernetes-sigs/kustomize) 允许自定义用于多种目的原始的、无模板的 YAML 文件,同时保留原始 YAML 不变和可用。 - -KCL 可用于创建函数,以改变和/或验证 Kubernetes 资源模型(KRM)的 YAML 输入/输出格式,并且我们提供 Kustomize KCL 函数来简化函数编写过程。 - -## 先决条件 - -- 安装 [kustomize](https://github.com/kubernetes-sigs/kustomize) - -## 快速开始 - -让我们编写一个仅向 Deployment 资源添加 annotation `managed-by=kustomize-kcl` 的 KCL 函数 - -### 1. 获取示例 - -```bash -git clone https://github.com/kcl-lang/kustomize-kcl.git -cd ./kustomize-kcl/examples/set-annotation/ -``` - -### 2. 测试和运行 - -```bash -kustomize fn run ./local-resource/ --dry-run -``` - -输出的YAML为 - -```yaml -apiVersion: krm.kcl.dev/v1alpha1 -kind: KCLRun -metadata: - name: set-annotation - annotations: - config.kubernetes.io/function: | - container: - image: docker.io/kcllang/kustomize-kcl:v0.2.0 - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml -# EDIT THE SOURCE! -# This should be your KCL code which preloads the `ResourceList` to `option("resource_list") -spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "kustomize-kcl"}} for resource in option("resource_list").items] ---- -apiVersion: v1 -kind: Service -metadata: - name: test - annotations: - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml -spec: - selector: - app: MyApp - ports: - - protocol: TCP - port: 80 - targetPort: 9376 ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx - annotations: - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml - managed-by: kustomize-kcl -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## KCL 开发指南 - -以下是可以使用 KCL 执行的操作: - -- 从 `option("resource_list")` 读取资源。`option("resource_list")` 符合 [KRM 函数规范](https://kpt.dev/book/05-developing-functions/01-functions-specification)。 你可以从 `option("resource_list")["items"]` 读取输入资源,并从 `option("resource_list")["functionConfig"]` 读取 `functionConfig`。 -- 返回输出资源的 KPM 列表。 -- 使用 `assert {condition},{error_message}` 返回错误消息。 - -## 更多文档和示例 - -- [Kustomize KCL 插件](https://github.com/kcl-lang/kustomize-kcl) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md deleted file mode 100644 index 1981ae3d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: "KPT KCL SDK" -sidebar_position: 4 ---- - -## 简介 - -[kpt](https://github.com/GoogleContainerTools/kpt) 是一个以包为中心的工具链,可实现配置原地编辑、自动化和交付,通过将声明性配置作为数据进行操作,从而简化 Kubernetes 平台和 KRM 驱动的基础设施(例如,Config Connector、Crossplane)的大规模管理,以实现 Kubernetes 配置编辑的自动化包括转换和验证。 - -KCL 可用于创建函数来转换和/或验证 YAML Kubernetes 资源模型 (KRM) 输入/输出格式,但我们提供 KPT KCL SDK 来简化函数编写过程。 - -## 先决条件 - -- 安装 [kpt](https://github.com/GoogleContainerTools/kpt) -- 安装 [Docker](https://www.docker.com/) - -## 快速开始 - -让我们编写一个仅向 Deployment 资源添加 annotation `managed-by=kpt` 的 KCL 函数 - -### 1. 获取示例 - -```bash -git clone https://github.com/kcl-lang/kpt-kcl-sdk.git/ -cd ./kpt-kcl-sdk/get-started/set-annotation -``` - -### 2. 显示 KRM - -```bash -kpt pkg tree -``` - -输出为 - -```bash -set-annotation -├── [kcl-fn-config.yaml] KCLRun set-annotation -└── data - ├── [resources.yaml] Deployment nginx-deployment - └── [resources.yaml] Service test -``` - -### 3. 显示和更新 KCL `FunctionConfig` - -```bash -cat ./kcl-fn-config.yaml -``` - -输出为 - -```yaml -# kcl-fn-config.yaml -apiVersion: krm.kcl.dev/v1alpha1 -kind: KCLRun -metadata: # kpt-merge: /set-annotation - name: set-annotation -spec: - # 编辑此源代码 - # 您在此的 KCL 代码将 `ResourceList` 预加载到 `option("resource_list")` - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "kpt"}} for resource in option("resource_list").items] -``` - -### 4. 测试和运行 - -通过 kpt 运行 KCL 代码 - -```bash -kpt fn eval ./data -i docker.io/kcllang/kpt-kcl:v0.2.0 --fn-config kcl-fn-config.yaml - -# 验证 annotation 是否添加到 `Deployment` 资源并且其他资源 `Service` 没有这个 annotation。 -cat ./data/resources.yaml | grep annotations -A1 -B0 -``` - -输出为 - -```bash - annotations: - managed-by: kpt -``` - -可以看出,我们确实成功添加了 `managed-by=kpt` 标签 - -## 更多文档和示例 - -- [KPT KCL SDK](https://github.com/kcl-lang/kpt-kcl-sdk) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-konfig/1-overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-konfig/1-overview.md deleted file mode 100644 index b112e946..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-konfig/1-overview.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -id: overview -sidebar_label: 概述 ---- - -# Konfig 概述 - -在 KCL 中推荐通过**配置库**的方式统一管理所有的配置清单和模型库,即不仅存放抽象模型本身的 KCL 定义,还存放各种类型的配置清单,比如应用的运维配置、策略配置等。配置大库推荐托管在各类 VCS 系统中,以方便做配置的回滚和漂移检查。配置大库的最佳实践代号为 Konfig,仓库托管在 [Github](https://github.com/KusionStack/konfig)。 - -⚡️ 配置大库主要包括: - -- KCL 模块声明文件(kcl.mod) -- KCL 领域模型库 (Kubernetes, Prometheus 等) -- 各类配置清单目录 (应用运维配置等) -- 配置构建和测试脚本 (Makefile,Github CI 文件等) - -之所以用一个统一的仓库管理全部的 KCL 配置代码,是由于不同代码包的研发主体不同,会引发出包管理和版本管理的问题。将业务配置代码、基础配置代码在一个统一仓库中,代码间的版本依赖管理会比较简单,通过定位唯一代码库的目录及文件即可,可以将配置代码统一管理,便于查找、修改、维护。 - -下面是配置大库(Konfig)的架构图: - -![](/img/docs/user_docs/guides/konfig/konfig-arch.png) - -Konfig 提供给用户开箱即用、高度抽象的配置界面,模型库最初朴素的出发点就是改善 YAML 用户的效率和体验,我们希望通过将代码更繁杂的模型抽象封装到统一的模型中,从而简化用户侧配置代码的编写。Konfig 由以下部分组成: - -- **核心模型**: - - **前端模型**:前端模型即「用户界面」,包含平台侧暴露给用户的所有可配置属性,其中省略了一些重复的、可推导的配置,抽象出必要属性暴露给用户,具有用户友好的特性,比如 server.k。 - - **后端模型**:后端模型是「模型实现」,是让前端模型属性生效的模型,主要包含前端模型实例的渲染逻辑,后端模型中可借助 KCL 编写校验和逻辑判断等以提高配置代码复用性和健壮性,对用户不感知,比如 server_backend.k -- **领域模型**:是不包含任何实现逻辑和抽象的模型,往往由工具转换生成,无需修改,和真正生效的 YAML 属性一一对应,底层模型需要经过进一步抽象,一般不直接被用户使用。比如,kusion_kubernetes 是 Kubernetes 场景的底层模型库。 - -此外,核心模型内部通过前端模型和后端模型两层抽象简化前端用户的配置代码,底层模型则是通过 KCL OpenAPI 工具自动生成。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-konfig/2-structure.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-konfig/2-structure.md deleted file mode 100644 index cc54087e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-konfig/2-structure.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -id: structure -sidebar_label: 工程结构 ---- - -# Konfig 工程结构 - -本文主要解释 Konfig 配置大库的目录和代码结构 - -## 整体结构 - -```bash -. -├── .github # CI 脚本 -├── Makefile # 通过 Makefile 封装常用命令 -├── README.md # 配置大库说明 -├── appops # 应用运维目录,用来放置所有应用的 KCL 运维配置 -│ ├── clickhouse-operator -│ ├── code-city -│ ├── guestbook -│ ├── http-echo -│ └── nginx-example -├── base # 模型库 -│ ├── examples # 样例代码 -│ │ ├── monitoring # 监控配置样例 -│ │ ├── native # Kubernetes 资源配置样例 -│ │ ├── provider # 基础资源配置样例 -│ │ └── server # 云原生应用运维配置模型样例 -│ └── pkg -│ ├── kusion_kubernetes # Kubernetes 底层模型库 -│ ├── kusion_models # 核心模型库 -│ ├── kusion_prometheus # Prometheus 底层模型库 -│ └── kusion_provider # 基础资源 底层模型库 -└── kcl.mod # 大库配置文件,通常用来标识大库根目录位置以及大库所需依赖 -``` - -## 核心模型库结构 - -核心模型库一般命名为 kusion_models,主要包含前端模型、后端模型、Mixin、渲染器等,目录结构为: - -```bash -├── commons # 基础资源核心模型库 -├── kube # 云原生资源核心模型库 -│ ├── backend # 后端模型 -│ ├── frontend # 前端模型 -│ │ ├── common # 通用前端模型 -│ │ ├── configmap # ConfigMap 前端模型 -│ │ ├── container # 容器前端模型 -│ │ ├── ingress # Ingress 前端模型 -│ │ ├── resource # 资源规格前端模型 -│ │ ├── secret # Secret 前端模型 -│ │ ├── service # Service 前端模型 -│ │ ├── sidecar # Sidecar 容器前端模型 -│ │ ├── strategy # 策略前端模型 -│ │ ├── volume # Volume 前端模型 -│ │ └── server.k # 云原生应用运维前端模型 -│ ├── metadata # 应用运维的元数据模型 -│ ├── mixins # 统一放置可复用的 Mixin -│ ├── render # 渲染器,把前后端模型联系在一起的桥梁 -│ ├── templates # 静态配置 -│ └── utils # 工具方法 -└── metadata # 通用元数据模型 -``` - -## Project 和 Stack 结构 - -![](/img/docs/user_docs/concepts/project-stack.png) - -Project 和 Stack 是用于组织 Konfig 的逻辑隔离概念。 - -### Project - -任何包含文件 "project.yaml" 的文件夹都将被视为一个 Project,"project.yaml" 用于描述此 Project 的元数据,如 "name" 和 "tenant" 等。项目必须具有明确的业务语义,用户可以将应用程序或运维场景映射到项目。 - -### Stack - -与Project一样,包含文件 "stack.yaml" 的任何文件夹都将被视为一个 Stack,"stack.yaml" 用于描述此 Stack 的元数据。Stack 是一组 KCL 文件,表示可以单独配置和部署的最小操作单元,它通常代表 CI/CD 过程中的不同阶段。 - -### Project 与 Stack 之间的关系 - -一个 Project 包含一个或多个 Stack,Stack 必须属于且只能属于一个 Project。用户可以根据自己的需要解释 Project 和 Stack 的含义,并灵活组织 Konfig 结构。根据我们的经验,我们提供以下示例作为最佳实践: - -```bash -├── README.md # Project 介绍文件 -├── base # 各环境通用配置 -│ └── base.k # 通用 KCL 配置 -├── dev # 环境特有配置 -│ ├── ci-test # 测试目录 -│ │ ├── settings.yaml # 测试数据 -│ │ └── stdout.golden.yaml # 测试期望结果 -│ ├── kcl.yaml # 多文件编译配置,是 KCL 编译的入口 -│ ├── main.k # 当前环境 KCL 配置 -│ └── stack.yaml # Stack 配置文件 -└── project.yaml # Project 配置文件 -``` - -Project 通常表示一个应用程序,Stack 表示该应用程序的不同环境的配置,例如 dev、pre 和 prod 等。通用配置可以存储在该 Project 下的 "base" 目录中。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-konfig/3-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-konfig/3-quick-start.md deleted file mode 100644 index 92c9849d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-konfig/3-quick-start.md +++ /dev/null @@ -1,198 +0,0 @@ ---- -id: guide -sidebar_label: 快速开始 ---- - -# 简介 - -本篇指南向你展示,如何使用 KCL 语言与其相对应的 CLI 工具,完成一个运行在 Kubernetes 中的 Long-Running 应用的部署,我们将组织配置的单位叫做应用(Application),描述应用部署和运维细节的配置集合叫做应用服务(Server),它本质上是通过 KCL 定义的运维模型。 - -要将一个运行在 Kubernetes 中的应用完全部署起来,一般需要下发多个 Kubernetes 资源,本次演示的样例涉及以下 Kubernetes 资源: - -- 命名空间(Namespace) -- 无状态工作负载(Deployment) -- 服务(Service) - -> 不清楚相关概念的,可以前往 Kubernetes 官方网站,查看相关说明: - -- [Learn Kubernetes Basics](https://kubernetes.io/docs/tutorials/kubernetes-basics/) -- [Namespace](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/) -- [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) -- [Service](https://kubernetes.io/docs/concepts/services-networking/service/) - -## 准备工作 - -在开始之前,我们需要做以下准备工作: - -1. 安装 KCL, 详情信息请参阅[下载和安装](/docs/user_docs/getting-started/install)。 - -2. 下载开源 Konfig 大库,仓库地址: [https://github.com/KusionStack/konfig.git](https://github.com/KusionStack/konfig.git) - -```shell -git clone https://github.com/KusionStack/konfig.git && cd konfig -``` - -## 快速开始 - -### 1. 配置编译 - -Konfig 的编程语言是 KCL,不是 Kubernetes 认识的 JSON/YAML,因此还需要编译得到最终输出。 - -进入到项目的 Stack 目录(`appops/nginx-example/dev`)并执行编译: - -```bash -cd appops/nginx-example/dev && kcl -Y kcl.yaml -D __konfig_output_format__=raw -``` - -可以获得如下 YAML 输出: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-exampledev - namespace: nginx-example -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - template: - metadata: - labels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - spec: - containers: - - image: nginx:1.7.8 - name: main - ports: - - containerPort: 80 - protocol: TCP - resources: - limits: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi - requests: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi ---- -apiVersion: v1 -kind: Namespace -metadata: - name: nginx-example ---- -apiVersion: v1 -kind: Service -metadata: - name: nginx-example - namespace: nginx-example -spec: - ports: - - nodePort: 30201 - port: 80 - targetPort: 80 - selector: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - type: NodePort -``` - -完成编译,可以看到 3 个资源: - -- 一个 name 为 nginx-exampledev 的 Deployment -- 一个 name 为 nginx-example 的 Namespace -- 一个 name 为 nginx-example 的 Service - -以上就完成了配置生效,后续可以使用 `kubectl apply` 等命令下发并检查资源的实际状态,本文不在赘述。 - -### 2. 配置修改 - -Server 模型中的 image 属性用于声明应用的业务容器镜像,我们可以修改 base/main.k 中的 image 的值进行镜像修改或升级: - -```diff -14c14 -< image = "nginx:1.7.8" ---- -> image = "nginx:latest" -``` - -重新编译配置代码可以获得修改后的 YAML 输出: - -```shell -kcl -Y kcl.yaml -D __konfig_output_format__=raw -``` - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-exampledev - namespace: nginx-example -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - template: - metadata: - labels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - spec: - containers: - - image: nginx:latest - name: main - ports: - - containerPort: 80 - protocol: TCP - resources: - limits: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi - requests: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi ---- -apiVersion: v1 -kind: Namespace -metadata: - name: nginx-example ---- -apiVersion: v1 -kind: Service -metadata: - name: nginx-example - namespace: nginx-example -spec: - ports: - - nodePort: 30201 - port: 80 - targetPort: 80 - selector: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - type: NodePort -``` - -## 小结 - -本文主要介绍了如何使用 KCL 语言与其相对应的 Konfig 库,完成一个运行在 Kubernetes 中的 Long-Running 应用的部署。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-konfig/4-best-practice.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-konfig/4-best-practice.md deleted file mode 100644 index c4bf4b08..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-konfig/4-best-practice.md +++ /dev/null @@ -1,271 +0,0 @@ ---- -id: practice -sidebar_label: 最佳实践 ---- - -# 最佳实践 - -本文档旨在讲解新的业务模型接入 Konfig 大库以及 KCL 代码模型设计与编写的最佳实践,新业务模型一般采用前-后端模型分离的最佳实践进行设计与抽象,区分前端模型和后端模型的直接目的是将「用户界面」和「模型实现」进行分离,实现用户友好的简单的配置界面以及自动化配置增删改查接口。 - -## 工作流程 - -![](/img/docs/user_docs/guides/konfig/workflow.png) - -1. 首先使用 KCL OpenAPI 工具生成下游所需配置的 KCL 模型代码,对于 Kubernetes 模型;可以根据 CRD 或者 Swagger Model 生成,对于其他场景,可以使用 Terraform provider schema、Java Class 或者 Go Struct 生成相应 KCL Schema (建设中),作为后端模型并存放在 "基础配置代码" 中; -2. 使用 KCL 开发工具(包括 KCL 编译器、KCL format,doc,lint,test 等工具和 IDE 插件等),根据业务语义抽象前端模型; -3. 依据 Project & Stack 方式在 Konfig 仓库中组织用户侧配置代码(主要是对前端模型的实例化),Konfig 会自动根据 project.yaml 和 stack.yaml 文件进行测试; -4. 最后编译 KCL 代码生成 YAML,通过测试后,利用 CI/CD 流程完成配置的 diff 与分发。 - -## 模型结构 - -正如 web 应用会提供友好的用户界面,而在应用的后端对用户输入进行进一步推演得到最终落库的数据,类似地,使用 KCL 进行模型设计时同样遵循前后端分离的逻辑。此外当下游所需的数据内容发生变化时,我们仅需修改用户配置数据到后端模型的渲染/逻辑即可,从而避免了大规模修改用户配置的情况。以应用服务的 sidecar 配置为例,直接暴露给用户的只有 `user_sidecar_feature_gates`,而最终交给下游处理的数据中,则应是把 `user_sidecar_feature_gates` 作为 `sidecars` 配置的一部分包装起来的结果。比如如下代码: - -```python -# 用户可配的: -user_sidecar_feature_gates: str - -# 下游能处理的: -sidecars = [ - { - name = "sidecar_name" # sidecars 参数的额外模版参数,用户不需要进行配置 - feature_gates = user_sidecar_feature_gates - } -] -``` - -## Konfig 建模的一些最佳实践 - -### 使用一个属性代替配置模板 - -对于一些后端模型所需要填写的配置字段往往是大而全的设计,需要用户主动输入较为复杂的配置模版,并且不同用户对于该字段的填写内容基本一致,比如在下面示出的超卖逻辑的配置就需要用户填写大量的模板数据,心智成本较高。 - -对于此类常用复杂的模板一个简单的最佳实践是在前端模型中抽象为一个简单的 bool 类型的变量 overQuota,让用户做选择题而不是填空题,比如当 overQuota 变量为 True 时,后端模型才会渲染这个复杂逻辑。 - -- 前端模型属性 `overQuota` - -```python -overQuota: bool -``` - -- 后端模型 YAML 输出 - -```yaml -spec: - template: - spec: - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: k8s/is-over-quota - operator: In - values: - - "true" -``` - -此外也可以根据具体的业务场景设计不同的模版名称来填空,比如如下所示的代码设计一个属性 template 来辅助用户做模版的选择而不是直接填入模板内容。合法的 template 值可以为 "success_ratio" 或者 "service_cost", 当后端模型扩展更多的模版时,前端代码无需作出任何修改,仅需在后端模型中适配相应模板逻辑即可。 - -```python -schema SLI: - template: str = "success_ratio" -``` - -此外,尽量不采用复杂的结构直接作为前端模型属性,避免用户使用该模型时需要借助过多的 KCL 语法特性(比如解包、循环等特性)或者书写很多临时变量完成该结构的实例化。 - -### 使用字面值类型和联合类型 - -在上述小节提到了可以使用一个字符串属性表示不同的模板名称,更进一步地是可以使用字面值类型表述 template 可选的内容,比如可以进行如下改进。 - -```python -schema SLI: - template: "success_ratio" | "service_cost" = "success_ratio" -``` - -其中 template 的类型为两个字符串类型的联合,表示 template 只能为 "success_ratio" 或者 "service_cost",当用户填写了其他字符串的值时,KCL 编译器会进行报错。 - -除了对字面值类型使用联合类型外,KCL 还支持对复杂类型如 schema 类型的联合。对于这种后端 oneof 配置的支持,KCL 内置了复合结构的联合类型进行支持。比如我们可以针对多种种场景定义自己的 SLI 前端类型:CustomSliDataSource,PQLSLIDataSource 和 StackSLIDataSource。 - -```python -schema CustomSLIDataSource: - customPluginUrl: str - -schema PQLSLIDataSource: - total?: str - error?: str - success?: str - cost?: str - count?: str - -schema StackSLIDataSource: - stack: str - groupBy?: str - metric?: str - -# Simplify type definitions using type aliases -type DataSource = CustomSLIDataSource | PQLSLIDataSource | StackSLIDataSource - -schema DataConfiguration: - sources: {str: DataSource} -``` - -这样前端模型设计的好处是编译器可以静态地检查出用户书写的类型只能是某一种类型,如果直接使用后端模型无法从模型上直接获得不同类型 type 与需要填写字段的映射关系。 - -此外,前端模型的整体设计上也应该考虑横向扩展性,尽可能地采用联合类型,充分利用代码化的优势,避免对接不同后端或者后端模型发生改变时带来不必要的大量代码前端代码与用户代码重构与修改。此外,对于其他 GPL 语言中常用的工厂模式,在 KCL 中也可以使用联合类型代替,比如想要根据某个字符串内容获得某个类型的构造函数,可以直接使用联合类型进行优化。 - -KCL 中书写工厂模式 - -```python -schema DataA: - id?: int = 1 - value?: str = "value" - -schema DataB: - name?: str = "DataB" - -_dataFactory: {str:} = { - DataA = DataA - DataB = DataB -} -dataA = _dataFactory["DataA"]() -dataB = _dataFactory["DataB"]() -``` - -使用联合类型替换工厂模式 - -```python -schema DataA: - id?: int = 1 - value?: str = "value" - -schema DataB: - name?: str = "DataB" - -# 直接使用联合类型即可 -dataA: DataA | DataB = DataA() -dataB: DataA | DataB = DataB() -``` - -### 列表/数组属性字典化 - -为了便于作配置的原地修改或者程序自动化查询修改,尽量将列表/数组属性定义为字典类型方便索引,因为在大部分配置场景对于复杂结构的列表类型,列表的索引 0, 1, 2, ..., n 不具备任何业务含义,列表中元素的顺序对该列表配置无任何影响,此时采用字典类型而不是列表类型更方便数据的查询与修改。首先以一个简单例子举例: - -```python -schema Person: - name: str - age: int - -schema House: - persons: [Person] - -house = House { - persons = [ - Person { - name = "Alice" - age = 18 - } - Person { - name = "Bob" - age = 10 - } - ] -} -``` - -比如在上述例子中,想要查询 name 为 "Alice" 的年龄 age, 就需要在 house.persons 这个列表中作遍历才能很查询到 Alice 的 age。而将 persons 定义为如下代码所示的字典,不仅从代码上看起来更加简洁,并且可以通过 house.persons.Alice.age 直接获得 Alice 的 age,并且整个配置的信息完整且无冗余信息。 - -```python -schema Person: - age: int - -schema House: - persons: {str: Person} # 将 persons 定义为字典而不是数组 - -house = House { - persons = { - Alice = Person { age = 18 } - Bob = Person { age = 10 } - } -} -``` - -### 为模型书写校验表达式 - -对于前端模型,往往需要对用户填写的字段进行校验,此时可以使用 KCL 的 check 表达式与 KCL 的内置函数/语法/系统库进行配合对字段进行校验。对于前端模型的校验尽可能直接书写在前端模型的定义中进行校验前置,避免错误传递到后端模型中发生意想不到的错误。 - -使用 all/any 表达式与 check 表达式进行校验 - -```python -import regex - -schema ConfigMap: - name: str - data: {str:str} - configMounts?: [ConfigMount] - - check: - all k in data { - regex.match(k, r"[A-Za-z0-9_.-]*") - }, "a valid config key must consist of alphanumeric characters, '-', '_' or '.'" - -schema ConfigMount: - containerName: str - mountPath: str - subPath?: str - - check: - ":" not in mountPath, "mount path must not contain ':'" -``` - -### 使用数值单位类型 - -KCL 中带单位的数字具有一个内置的类型 units.NumberMultiplier, 不允许进行任意四则运算。 - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -x0: NumberMultiplier = 1M # Ok -x1: NumberMultiplier = x0 # Ok -x2 = x0 + x1 # Error: unsupported operand type(s) for +: 'number_multiplier(1M)' and 'number_multiplier(1M)' -``` - -可以使用 `int()/float()` 函数和 `str()` 函数将数字单位类型转换为整数类型或者字符串类型,产生的字符串保留原有数字单位类型的单位。 - -```python -a: int = int(1Ki) # 1024 -b: str = str(1Mi) # "1Mi" -``` - -对于在 Konfig 中的 Kubernetes Resource 资源相关的定义均可使用数值单位类型进行书写 - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -schema Resource: - cpu?: NumberMultiplier | int = 1 - memory?: NumberMultiplier = 1024Mi - disk?: NumberMultiplier = 10Gi - epchygontee?: int -``` - -### 前端模型实例的自动化修改 - -在 KCL,可以通过命令行和 API 界面实现对前端模型实例的自动化修改,比如想要修改某个应用(Konfig Stack Path: appops/nginx-example/dev)配置的镜像内容,可以直接执行如下指令修改镜像 - -```python -kcl -Y kcl.yaml ci-test/settings.yaml -o ci-test/stdout.golden.yaml -d -O :appConfiguration.image=\"test-image-v1\" -``` - -更多与自动化相关的使用文档请参考 [自动化](/docs/user_docs/guides/automation) 一节 - -### 为模型添加代码注释 - -为便于用户理解以及模型文档自动生成,需要对定义的模型编写注释,注释内容一般包括模型的解释,模型字段的解释,类型,默认值,使用样例等。详细的 KCL Schema 代码注释编写规范以及模型文档自动生成可以参考 [KCL 文档规范](/docs/tools/cli/kcl/docgen) - -## 后端模型 - -后端模型是「模型实现」,主要包括将前端模型映射为后端模型的逻辑代码。当编写完成前端模型后,我们可以使用前端模型 Schema 新建前端模型的实例 instance 并编写相应的后端映射/渲染代码将这些前端 instance 转换为后端模型,并且利用 KCL 多文件编译和 `Schema.instances()` 函数可以做到前端代码和后端代码的高度解耦,用户仅需关心前端的配置而不感知模型复杂的校验、逻辑判断等代码。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-kusion/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-kusion/index.md deleted file mode 100644 index 2906ab83..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-kusion/index.md +++ /dev/null @@ -1,15 +0,0 @@ -# KusionStack - -**KusionStack 是开源的云原生可编程技术栈!** - -KusionStack 是一个可编程、高灵活性的应用交付及运维技术栈,灵感源于融合(Fusion)一词,旨在帮助企业构建的应用运维配置管理平面及 DevOps 生态。 - -1. 融合**专有云**,**混合云**,**多云**混合场景 -2. 融合以**云原生技术**为主,同时采用**多种平台技术**的混合平台技术选型 -3. 融合**多项目**、**多团队**、**多角色**、**多租户**、**多环境**的企业级诉求 - -基于 Platform as Code (平台服务即代码)理念,研发者可以快速收敛围绕**应用运维生命周期**的全量配置定义,面向**混合技术体系及云环境**,完成从应用运维研发到上线的**端到端工作流程**,真正做到**一处编写,随处交付**。 - -![](/img/docs/user_docs/intro/kusion-stack-1.png) - -更多文档请参考: [https://kusionstack.io/](https://kusionstack.io/) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/support/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/support/_category_.json deleted file mode 100644 index d670513b..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/support/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "常见问答", - "position": 6 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/support/faq-cli.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/support/faq-cli.md deleted file mode 100644 index 035c021c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/support/faq-cli.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -sidebar_position: 4 ---- - -# 命令行工具 - -## 1. Konfig 大库应用目录下的 settings.yaml 文件的作用是什么? - -KCL 中 settings.yaml 文件表示 KCL 命令行工具的配置参数文件,可以将编译的配置放入其中进行调用比如需要编译的文件,需要输入的 option 动态参数 `-d`,是否需要忽略掉空值 None `-n` 等配置。 - -比如对于如下的命令行运行参数 - -```shell -kcl main.k -D key=value -n -r -``` - -就可以使用如下的命令行参数和 settings.yaml 配置文件代替 - -```shell -kcl -Y settings.yaml -``` - -settings.yaml - -```yaml -kcl_cli_configs: - files: - - main.k - disable_none: true - strict_range_check: true -kcl_options: - - key: key - value: value -``` - -- `kcl_cli_configs` 表示可以配置的编译参数,`file` 用于配置编译的 KCL 文件,`disable_none` 表示是否使用 `-n` 参数,`strict_range_check` 表示是否使用 `-r` 参数。 -- `kcl_options` 表示可以配置的动态参数,`key` 表示动态参数的名称,`value` 表示动态参数的值 - -注意:settings.yaml 的文件名称可替换,只要其中的配置结构满足规定即可 - -## 2. 如何传入动态参数?如何在代码中获取命令行传入的动态参数? - -KCL 支持多种方式传入动态参数 - -- `-D`: 使用 KCL 命令行的-D 参数可以直接传入动态参数,支持基本数据类型 str/int/float/bool, 以及结构数据类型 list/dict - -```shell -kcl main.k -D env-type=TEST -D deploy-topology='[{"cluster":"my-cluster","idc":"my-idc","replicas":2,"workspace":"my-idc","zone":"my-zone"}]' -``` - -- `-Y`: 使用 KCL 命令行的-Y 参数可以间接通过配置文件传入动态参数: - -```yaml -kcl_options: - - key: env-type - value: TEST - - key: deploy-topology - value: - - cluster: my-cluster - idc: my-idc - replicas: 2 - workspace: my-workspace - zone: my-zone -``` - -在代码中使用内置的 option 函数获取即可 - -```python -env = option("env-type") -deploy_topology = option("deploy-topology") -``` - -输出 YAML - -```yaml -env: TEST -deploy_topology: - - cluster: my-cluster - idc: my-idc - replicas: 2 - workspace: my-workspace - zone: my-zone -``` - -## 3. 如何使用 kcl 的多文件编译特性? - -- 使用 KCL 命令行工具直接书写多文件编译 - -```shell -kcl file1.k file2.k file3.k -``` - -- 在配置文件中配置并配合 KCL 命令行工具参数 `-Y` 使用 - -settings.yaml - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - - file3.k -``` - -```shell -kcl -Y settings.yaml -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/support/faq-install.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/support/faq-install.md deleted file mode 100644 index 1c98f224..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/support/faq-install.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -sidebar_position: 5 ---- - -# 安装问题 - -## MacOS 提示无法打开 "kcl",因为 Apple 无法检查其是否包含恶意软件 - -MacOS 提示无法打开 "kcl",因为 Apple 无法检查其是否包含恶意软件。这个错误是因为 macOS 操作系统中的 Gatekeeper 安全功能阻止了应用程序的运行。要解决此问题,请按照以下步骤操作: - -打开"系统偏好设置"并点击"安全性与隐私"。 在"通用"选项卡中,您将看到一个消息:"kcl" 已被阻止。单击"仍要打开"。 或者,你可以单击"打开任何方式"以打开你的应用程序。(可能需要使用管理员权限来打开应用程序。) - -如果不想在每次打开应用程序时都执行这些步骤,则可以的应用程序添加到白名单中,以便在不受阻止的情况下运行。要将您的应用程序添加到白名单中,请执行以下操作: - -打开终端并输入以下命令: - -```shell -xattr -rd com.apple.quarantine /path/to/kcl -``` - -其中,/path/to/kcl 是 kcl 应用程序的完整路径。运行命令后,应用程序将被添加到白名单中,Gatekeeper 将不再阻止其运行。 - -## 在 Windows/Linux/MacOS 平台上抱 program not found 或者 run linker failed 错误 - -请确保如下依赖在您的 PATH 中 - -- MacOS: `clang` -- Linux: `gcc` -- Windows: `cl.exe` (可以通过安装 MSVC 获得) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/support/faq-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/support/faq-kcl.md deleted file mode 100644 index 8330dfd6..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/support/faq-kcl.md +++ /dev/null @@ -1,2355 +0,0 @@ ---- -sidebar_position: 2 ---- - -# KCL 语法 - -## 1. 如何用 KCL 写一个简单的 key-value 对配置 - -创建一个名为 `config.k` 的文件 - -```python -cpu = 256 -memory = 512 -image = "nginx:1.14.2" -service = "my-service" -``` - -上述 KCL 代码中,定义了 4 个变量 `cpu` 和 `memory` 被声明为整数类型,并且它们的值分别为 `256` 和 `512`,而 `image` 和 `service` 是字符串类型,它们的值分别为 `image` 和 `service` - -使用如下命令可以将上述 KCL 文件编译为 YAML 进行输出 - -``` -kcl config.k -``` - -得到的 YAML 输出为: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -如果想要输出到文件,可以使用 `-o|--output` 参数: - -``` -kcl config.k -o config.yaml -``` - -## 2. KCL 中有哪些基本的数据类型? - -KCL 目前的基本数值类型和值包含: - -- 整数类型 `int` - - 举例: 十进制正整数 `1`, 十进制负整数 `-1`, 十六进制整数 `0x10`, 八进制整数 `0o10`, 二进制整数 `0b10` -- 浮点数类型 `float` - - 举例: 正浮点数 `1.10`, `1.0`, 负浮点数 `-35.59`, `-90.`, 科学记数法浮点数 `32.3e+18`, `70.2E-12` -- 布尔类型 `bool` - - 举例: 真值 `True`, 假值 `False` -- 字符串类型 `str` - 使用引号 `'`, `"` 标记 - - 举例: 双引号字符串 `"string"`, `"""string"""`, 单引号字符串 `'string'`, `'''string'''` -- 列表类型 `list` - 使用 `[`, `]` 标记 - - 举例: 空列表 `[]`, 字符串列表 `["string1", "string2", "string3"]` -- 字典类型 `dict` - 使用 `{`, `}` 标记 - - 举例: 空字典 `{}`, 键值均为字符串类型的字典 `{"key1": "value1", "key2": "value2"}` -- 结构类型 `schema` - 使用关键字 `schema` 定义,并使用相应的 schema 名称进行实例化 -- 空值类型 `None` - 用于表示一个变量的值为空,与输出 YAML 的 `null` 值对应 -- 未定义值类型 `Undefined` - 用于表示一个变量未被赋值,值为 `Undefined` 的变量不会被输出到 YAML 中 - -```python -schema Person: - name: str - age: int - -alice = Person { - name = "Alice" - age = 18 -} -bob = Person { - name = "Bob" - age = 10 -} -``` - -注意: 所有 KCL 类型的变量均可赋值为空值 `None` 和未定义的值 `Undefined` - -## 3. 有些 KCL 变量名带 `_` 下划线前缀表示什么?和不带 `_` 下划线前缀的区别是什么?分别适合什么场景下使用? - -KCL 中带下划线前缀的变量表示一个**隐藏**的,**可变**的变量,**隐藏**表示带下划线前缀的变量不会被输出到 YAML 当中,包括包级别的下划线前缀变量和 schema 当中的下划线前缀变量。**可变**表示带下划线前缀的变量可被多次重复赋值,不带下划线前缀的变量被赋值后不可变。 - -带 `_` 下划线前缀的变量与不带 `_` 下划线前缀变量的区别是: 不带 `_` 下划线前缀变量默认是导出到 YAML 当中的,并且具有强不可变性;带 `_` 下划线前缀变量是不导出的,可变的。 - -```python -name = 'Foo' # 导出变量,不可变变量 -name = 'Bar' # 错误:导出变量只能设置一次 -``` - -```python -_name = 'Foo' # 隐藏变量,可变变量 -_name = 'Bar' - -schema Person: - _name: str # hidden and mutable -``` - -## 4. 如何向 dict 中添加元素? - -可以使用 union 运算符 `|`, 或者 dict 解包运算符 `**` 来向 dict 中添加一个元素,并且可以使用 `in`,`not in` 等关键字判断 dict 变量当中是否包含某一个键值 - -```python -_left = {key: {key1 = "value1"}, intKey = 1} # 注意使用 = 表示覆盖 -_right = {key: {key2 = "value2"}, intKey = 2} -dataUnion = _left | _right # {"key": {"key1": "value1", "key2": "value2"}, "intKey": 2} -dataUnpack = {**_left, **_right} # {"key": {"key1": "value1", "key2": "value2"}, "intKey": 2} -``` - -输出 YAML 为: - -```yaml -dataUnion: - key: - key1: value1 - key2: value2 - intKey: 2 -dataUnpack: - key: - key1: value1 - key2: value2 - intKey: 2 -``` - -此外还可以使用 `字符串插值` 或者字符串 `format` 成员函数特性向 kcl dict 添加变量键值对 - -```python -dictKey1 = "key1" -dictKey2 = "key2" -data = { - "${dictKey1}" = "value1" - "{}".format(dictKey2) = "value2" -} -``` - -输出 YAML 为: - -```yaml -dictKey1: key1 -dictKey2: key2 -data: - key1: value1 - key2: value2 -``` - -## 5. 如何修改 dict 中的元素? - -我们可以使用 union 运算符 `|`, 或者解包运算符 `**` 修改 dict 当中的元素 - -```python -_data = {key = "value"} # {"key": "value"} -_data = _data | {key = "override_value1"} # {"key": "override_value1"} -_data = {**_data, **{key = "override_value2"}} # {"key": "override_value2"} -``` - -如果想要删除 dict 中某个键为 `key` 的值,可以使用解包运算符 `**{key = Undefined}` 或者合并运算符 `| {key = Undefined}` 进行覆盖,覆盖后 key 的值为 Undefined,不会进行 YAML 输出。 - -## 6. 如何向 list 中添加元素? - -在 list 中添加元素有两种方式: - -- 使用 `+`, `+=` 和 slice 切片连接组装 list 变量达到向 list 中添加元素的目的 - -```python -_args = ["a", "b", "c"] -_args += ["end"] # 在list尾部添加元素"end", ["a", "b", "c", "end"] -_args = _args[:2] + ["x"] + _args[2:] # 在list索引为2的地方插入元素"x", ["a", "b", "x", "c", "end"] -_args = ["start"] + _args # 在list头部添加元素"start", ["start", "a", "b", "x", "c", "end"] -``` - -- 使用 `*` 解包运算符连接合并 list - -```python -_args = ["a", "b", "c"] -_args = [*_args, "end"] # 在list尾部添加元素"end", ["a", "b", "c", "end"] -_args = ["start", *_args] # 在list头部添加元素"start", ["start", "a", "b", "c", "end"] -``` - -注意:当接连的变量为 `None/Undefined` 时,使用 `+` 可能会发生错误,这时使用 list 解包运算符 `*` 或者使用 `or` 运算符取 list 的默认值可以避免空值判断 - -```python -data1 = [1, 2, 3] -data2 = None -data3 = [*data1, *data2] # Right [1, 2, 3] -data4 = data1 + data2 or [] # Right [1, 2, 3], 使用 or 取 data2 的默认值为 [], 当 data2 为 None/Undefined 时,取空列表 [] 进行计算 -data5 = data1 + data2 # Error: can only concatenate list (not "NoneType") to list -``` - -## 7. 如何修改/删除 list 中的元素? - -修改 list 中的元素分为两种方式: - -- 直接修改 list 某个索引处的值,使用 slice 切片 - -```python -_index = 1 -_args = ["a", "b", "c"] -_args = _args[:index] + ["x"] + _args[index+1:] # 修改list索引为1的元素为"x", ["a", "x", "c"] -``` - -- 根据某个条件修改 list 当中的元素,使用 list comprehension 列表推导式 - -```python -_args = ["a", "b", "c"] -_args = ["x" if a == "b" else a for a in _args] # 将list当中值为"b"的值都修改为"x", ["a", "x", "c"] -``` - -删除 list 中的元素分为两种方式: - -- 使用 list for 推导表达式中 if 过滤条件 -- 使用 filter 表达式对 list 进行元素过滤 - -比如想要删除一个列表 `[1, 2, 3, 4, 5]` 中大于 2 的数字,则在 KCL 中可以写为: - -```python -originList = [1, 2, 3, 4, 5] -oneWayDeleteListItem = [item for item in originList if item <= 2] -anotherWayDeleteListItem = filter item in originList { - item <= 2 -} -``` - -输出如下结果 - -```yaml -originList: - - 1 - - 2 - - 3 - - 4 - - 5 -oneWayDeleteListItem: - - 1 - - 2 -anotherWayDeleteListItem: - - 1 - - 2 -``` - -## 8. 怎样写 for 循环?怎样理解和使用 list comprehension 列表推导式 和 dict comprehension 字典推导式 ? - -KCL 目前仅支持函数式/声明式的推导式 for 循环方式,可以按照如下方式遍历 dict 和 list 变量: - -list 推导式具体形式为(其中推导式两边使用方括号 `[]`): - -```txt -[expression for expr in sequence1 - if condition1 - for expr2 in sequence2 - if condition2 - for expr3 in sequence3 ... - if condition3 - for exprN in sequenceN - if conditionN] -``` - -dict 推导式具体形式为(其中推导式两边使用花括号 `{}`): - -```txt -{expression for expr in sequence1 - if condition1 - for expr2 in sequence2 - if condition2 - for expr3 in sequence3 ... - if condition3 - for exprN in sequenceN - if conditionN} -``` - -上述推导式中的 `if` 表示过滤条件,满足条件的表达式 `expr` 才会生成到新的 list 或 dict 中 - -list 推导式举例: - -```python -_listData = [1, 2, 3, 4, 5, 6] -_listData = [l * 2 for l in _listData] # _listData中所有元素都乘以2,[2, 4, 6, 8, 10, 12] -_listData = [l for l in _listData if l % 4 == 0] # 筛选出_listData中可以被4整除的所有元素,[4, 8, 12] -_listData = [l + 100 if l % 8 == 0 else l for l in _listData] # 遍历_listData, 当其中的元素可以被8整除时,将该元素加100,否则保持不变, [4, 108, 12] -``` - -注意上述代码中第 3 行和第 4 行两个 `if` 的区别: - -- 第一个 `if` 表示 list 变量 `_listData` 本身的推导式过滤条件,后不能跟 `else`,满足该过滤条件的元素会继续放在该列表中,不满足条件的元素被剔除,有可能会使列表长度发生变化 -- 第二个 `if` 表示 list 迭代变量 `l` 的选择条件,表示 `if-else` 三元表达式,后必须跟 `else`,不论是否满足该条件,产生的元素仍然在该列表中,列表长度不变 - -dict 推导式举例: - -```python -_dictData = {key1 = "value1", key2 = "value2"} -_dictData = {k = _dictData[k] for k in _dictData if k == "key1" and _dictData[k] == "value1"} # 将_dictData中key为"key1", value为"value1"的元素筛选出来, {"key1": "value1"} -``` - -使用推导式获得 dict 所有 key: - -```python -dictData = {key1 = "value1", key2 = "value2"} -dictDataKeys = [k for k in _dictData] # ["key1", "key2"] -``` - -使用推导式对 dict 按照 key 的字典序升序进行排序: - -```python -dictData = {key3 = "value3", key2 = "value2", key1 = "value1"} # {'key3': 'value3', 'key2': 'value2', 'key1': 'value1'} -dictSortedData = {k = dictData[k] for k in sorted(dictData)} # {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'} -``` - -多级推导式举例: - -```python -array1 = [1, 2, 3] -array2 = [4, 5, 6] -data = [a1 + a2 for a1 in array1 for a2 in array2] # [5, 6, 7, 6, 7, 8, 7, 8, 9] len(data) == len(array1) * len(array2) -``` - -双变量循环(for 推导表达式支持 list 的索引迭代以及 dict 的 value 迭代,可以简化 list/dict 迭代过程代码书写): - -- list - -```python -data = [1000, 2000, 3000] -# 单变量循环 -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# 双变量循环 -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# 使用_忽略循环变量 -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -- dict - -```python -data = {key1 = "value1", key2 = "value2"} -# 单变量循环 -dataKeys1 = [k for k in data] # ["key1", "key2"] -dataValues1 = [data[k] for k in data] # ["value1", "value2"] -# 双变量循环 -dataKeys2 = [k for k, v in data] # ["key1", "key2"] -dataValues2 = [v for k, v in data] # ["value1", "value2"] -dataFilter = {k = v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# 使用_忽略循环变量 -dataKeys3 = [k for k, _ in data] # ["key1", "key2"] -dataValues3 = [v for _, v in data] # ["value1", "value2"] -``` - -## 9. 怎样写 if 条件语句? - -KCL 支持两种方式书写 if 条件语句: - -- if-elif-else 块语句,其中 elif 和 else 块均可省略,并且 elif 块可以使用多次 - -```python -success = True -_result = "failed" -if success: - _result = "success" -``` - -```python -success = True -if success: - _result = "success" -else: - _result = "failed" -``` - -```python -_result = 0 -if condition == "one": - _result = 1 -elif condition == "two": - _result = 2 -elif condition == "three": - _result = 3 -else: - _result = 4 -``` - -- 条件表达式 ` if else `, 类似于 C 语言当中的 ` ? : ` 三元表达式 - -```python -success = True -_result = "success" if success else "failed" -``` - -注意:在书写 if-elif-else 块语句时注意书写 if 条件后的冒号 `:` 以及保持缩进的统一 - -除此之外,还可以在 list 或者 dict 结构中直接书写条件表达式(不同的是,在结构中书写的 if 表达式中需要书写的值而不是语句): - -- list - -```python -env = "prod" -data = [ - "env_value" - ":" - if env == "prod": - "prod" # 书写需要添加到 data 中的值,而不是语句 - else: - "other_prod" -] # ["env_value", ":", "prod"] -``` - -- dict - -```python -env = "prod" -config = { - if env == "prod": - MY_PROD_ENV = "prod_value" # 书写需要添加到 config 中的键-值对,而不是语句 - else: - OTHER_ENV = "other_value" -} # {"MY_PROD_ENV": "prod_value"} -``` - -## 10. 怎样表达 "与" "或" "非" 等逻辑运算? - -在 KCL 中,使用 `and` 表示"逻辑与", 使用 `or` 表示"逻辑或", 使用 `not` 表示"非", 与 C 语言当中的 `&&`, `||` 和 `~` 语义一致; - -```python -done = True -col == 0 -if done and (col == 0 or col == 3): - ok = 1 -``` - -对于整数的"按位与", "按位或"和"按位异或",在 KCL 中使用 `&`, `|` 和 `^` 运算符表示, 与 C 语言当中的 `&`, `|` 和 `^` 语义一致; - -```python -value = 0x22 -bitmask = 0x0f - -assert (value & bitmask) == 0x02 -assert (value & ~bitmask) == 0x20 -assert (value | bitmask) == 0x2f -assert (value ^ bitmask) == 0x2d -``` - -"逻辑或" `or` 的妙用:当需要书写诸如 `A if A else B` 类似的模式时,可以使用 `A or B` 进行简化,比如如下代码: - -```python -value = [0] -default = [1] -x0 = value if value else default -x1 = value or default # 使用 value or default 代替 value if value else default -``` - -## 11. 如何判断变量是否为 None/Undefined、字符串/dict/list 是否为空? - -请注意,在 if 表达式的条件判断中,`False`、`None`、`Undefined`、数字 `0`、空列表 `[]`、空字典 `{}` 和空字符串 `""`, `''`, `""""""`, `''''''` 都被视为值为 `假` 的表达式。 - -比如判断一个字符串变量 `strData` 既不为 `None/Undefined` 也不为空字符串时(字符串长度大于 0),就可以简单的使用如下表达式: - -```python -strData = "value" -if strData: - isEmptyStr = False -``` - -空字典和空列表判断举例: - -```python -_emptyList = [] -_emptyDict = {} -isEmptyList = False if _emptyList else True -isEmptyDict = False if _emptyDict else True -``` - -YAML 输出为: - -```yaml -isEmptyList: true -isEmptyDict: true -``` - -或者使用布尔函数 `bool` 进行判断 - -```python -_emptyList = [] -_emptyDict = {} -isEmptyList = bool(_emptyList) -isEmptyDict = bool(_emptyDict) -``` - -## 12. 字符串怎样拼接、怎样格式化字符串、怎样检查字符串前缀、后缀?怎样替换字符串内容? - -- KCL 中可以使用 `+` 运算符连接两个字符串 - -```python -data1 = "string1" + "string2" # "string1string2" -data2 = "string1" + " " + "string2" # "string1 string2" -``` - -- KCL 中目前存在两种格式化字符串的方式: - - 字符串变量的 format 方法 `"{}".format()` - - 字符串插值 `${}` - -```python -hello = "hello" -a = "{} world".format(hello) -b = "${hello} world" -``` - -注意,如果想在 `"{}".format()` 中单独使用 `{` 字符或者 `}`, 则需要使用 `{{` 和 `}}` 分别对 `{` 和 `}` 进行转义,比如转义一个 JSON 字符串如下代码: - -```python -data = "value" -jsonData = '{{"key": "{}"}}'.format(data) -``` - -输出 YAML 为: - -```yaml -data: value -jsonData: '{"key": "value"}' -``` - -注意,如果想在 `${}` 插值字符串中单独使用 `$` 字符,则需要使用 `$$` 对 `$` 进行转义 - -```python -world = "world" -a = "hello {}".format(world) # "hello world" -b = "hello ${world}" # "hello world" -c = "$$hello ${world}$$" # "$hello world$" -c2 = "$" + "hello ${world}" + "$" # "$hello world$" -``` - -输出 YAML 为: - -```yaml -world: world -a: hello world -b: hello world -c: $hello world$ -c2: $hello world$ -``` - -- KCL 中使用字符串的 `startswith` 和 `endswith` 方法检查字符串的前缀和后缀 - -```python -data = "length" -isEndsWith = data.endswith("th") # True -isStartsWith = "length".startswith('len') # True -``` - -- KCL 中使用字符串的 replace 方法或者 regex.replace 函数替换字符串的内容 - -```python -import regex -data1 = "length".replace("len", "xxx") # 使用"xxx"替换"len", "xxxgth" -data2 = regex.replace("abc123", r"\D", "0") # 替换"abc123"中的所有非数字为"0", "000123" -``` - -其中,`r"\D"` 表示不需要使用 `\\` 转义 `\D` 中的反斜杠 `\`,多用于正则表达式字符串中 - -此外,我们可以在字符串格式化表达式中插入索引占位符或者关键字占位符用于格式化多个字符串 - -- 索引占位符 - -```python -x = '{2} {1} {0}'.format('directions', 'the', 'Read') -y = '{0} {0} {0}'.format('string') -``` - -输出为: - -```yaml -x: Read the directions -y: string string string -``` - -- 关键字占位符 - -```python -x = 'a: {a}, b: {b}, c: {c}'.format(a = 1, b = 'Two', c = 12.3) -``` - -输出为: - -```yaml -x: "a: 1, b: Two, c: 12.3" -``` - -## 13. 字符串中使用单引号和双引号的区别是什么? - -KCL 单引号和双引号字符串几乎没有区别。唯一的区别是,不需要在单引号字符串中使用 `\"` 转义双引号 `"`,不需要在双引号字符串中使用 `\'` 转义单引号引号 `'`。 - -```python -singleQuotedString = 'This is my book named "foo"' # Don’t need to escape double quotes in single quoted strings. -doubleQuotedString = "This is my book named 'foo'" # Don’t need to escape single quotes in double quoted strings. -``` - -此外在 KCL 中,使用三个单引号或者三个双引号组成的长字符串,无需在其中对单引号或者三引号进行转义 (除字符串首尾),比如如下例子: - -```python -longStrWithQuote0 = """Double quotes in long strings "(not at the beginning and end)""" -longStrWithQuote1 = '''Double quotes in long strings "(not at the beginning and end)''' -longStrWithQuote2 = """Single quotes in long strings '(not at the beginning and end)""" -longStrWithQuote3 = '''Single quotes in long strings '(not at the beginning and end)''' -``` - -输出 YAML: - -```yaml -longStrWithQuote0: Double quotes in long strings "(not at the beginning and end) -longStrWithQuote1: Double quotes in long strings "(not at the beginning and end) -longStrWithQuote2: Single quotes in long strings '(not at the beginning and end) -longStrWithQuote3: Single quotes in long strings '(not at the beginning and end) -``` - -## 14. 如何编写跨行的长字符串? - -KCL 中可以使用单引号字符串 + 换行符 `\n` 或者三引号字符串书写一个多行字符串,并且可以借助续行符 `\` 优化 KCL 字符串的形式,比如对于如下代码中的三个多行字符串变量,它们的制是相同的: - -```python -string1 = "The first line\nThe second line\nThe third line\n" -string2 = """The first line -The second line -The third line -""" -string3 = """\ -The first line -The second line -The third line -""" # 推荐使用 string3 长字符串的书写形式 -``` - -输出 YAML 为: - -```yaml -string1: | - The first line - The second line - The third line -string2: | - The first line - The second line - The third line -string3: | - The first line - The second line - The third line -``` - -## 15. 如何使用正则表达式? - -通过在 KCL 中导入正则表达式库 `import regex` 即可使用正则表达式,其中包含了如下函数: - -- **match**: 正则表达式匹配函数,根据正则表达式对输入字符串进行匹配,返回 bool 类型表示是否匹配成功 -- **split**: 正则表达式分割函数,根据正则表达式分割字符串,返回分割字串的列表 -- **replace**: 正则表达式替换函数,替换字符串中所有满足正则表达式的子串,返回被替换的字符串 -- **compile**: 正则表达式编译函数,返回 bool 类型表示是否是一个合法的正则表达式 -- **search**: 正则表达式搜索函数,搜索所有满足正则表达式的子串,返回子串的列表 - -使用举例: - -```python -import regex - -regex_source = "Apple,Google,Baidu,Xiaomi" -regex_split = regex.split(regex_source, ",") -regex_replace = regex.replace(regex_source, ",", "|") -regex_compile = regex.compile("$^") -regex_search = regex.search("aaaa", "a") -regex_find_all = regex.findall("aaaa", "a") -regex_result = regex.match("192.168.0.1", "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$") # 判断是否是一个IP字符串 -regex_result_false = regex.match("192.168.0,1", "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$") # 判断是否是一个IP字符串 -``` - -输出 YAML: - -```yaml -regex_source: Apple,Google,Baidu,Xiaomi -regex_split: - - Apple - - Google - - Baidu - - Xiaomi -regex_replace: Apple|Google|Baidu|Xiaomi -regex_compile: true -regex_search: true -regex_find_all: - - a - - a - - a - - a -regex_result: true -regex_result_false: false -``` - -对于比较长的正则表达式,还可以使用 r-string 忽略 `\` 符号的转义简化正则表达式字符串的书写: - -```python -import regex - -isIp = regex.match("192.168.0.1", r"^(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)$") # 判断是否是一个IP字符串 -``` - -更多举例: - -```python -import regex - -schema Resource: - cpu: str = "1" - memory: str = "1024Mi" - disk: str = "10Gi" - check: - regex.match(cpu, r"^([+-]?[0-9.]+)([m]*[-+]?[0-9]*)$"), "cpu must match specific regular expression" - regex.match(memory, r"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"), "memory must match specific regular expression" - regex.match(disk, r"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"), "disk must match specific regular expression" -``` - -```python -import regex - -schema Env: - name: str - value?: str - check: - len(name) <= 63, "a valid env name must be no more than 63 characters" - regex.match(name, r"[A-Za-z_][A-Za-z0-9_]*"), "a valid env name must start with alphabetic character or '_', followed by a string of alphanumeric characters or '_'" -``` - -## 16. KCL 当中的 schema 是什么含义? - -schema 是 KCL 中一种语言元素,用于定义配置数据的类型,像 C 语言中的 struct 或者 Java 中的 class 一样,在其中可以定义属性,每种属性具有相应的类型。 - -## 17. 如何声明 schema? - -KCL 中使用 schema 关键字可以定义一个结构,在其中可以申明 schema 的各个属性 - -```python -# 一个Person结构,其中具有属性字符串类型的firstName, 字符串类型的lastName, 整数类型的age -schema Person: - firstName: str - lastName: str - # age属性的默认值为0 - age: int = 0 -``` - -一个复杂例子: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels: {str:str} -``` - -在上面的代码中,`cpu` 和 `memory` 被定义为整数 int 类型;`name`,`image` 和 `service` 是字符串 str 类型; `command` 是字符串类型的列表; labels 是字典类型,其键类型和值类型均为字符串。 - -## 18. 如何为 schema 属性添加 "不可变"、"必选" 约束? - -KCL 中使用 `?` 运算符定义一个 schema 的"可选"约束,schema 属性默认都是"必选"的 - -```python -# 一个Person结构,其中具有属性字符串类型的firstName, 字符串类型的lastName, 整数类型的age -schema Person: - firstName?: str # firstName是一个可选属性,可以赋值为None/Undefined - lastName?: str # age是一个可选属性,可以赋值为None/Undefined - # age属性的默认值为0 - age: int = 18 # age是一个必选属性,不能赋值为None/Undefined,并且是一个不可变属性 - age = 10 # Error, age是一个不可变的属性 -``` - -## 19. 如何为 schema 中的属性编写校验规则? - -在 schema 定义当中可以使用 check 关键字编写 schema 属性的校验规则, 如下所示,check 代码块中的每一行都对应一个条件表达式,当满足条件时校验成功,当不满足条件时校验失败。条件表达式后可跟 `, "check error message"` 表示当校验失败时需要显示的信息 - -```python -import regex - -schema Sample: - foo: str # Required, 不能为None/Undefined, 且类型必须为str - bar: int # Required, 不能为None/Undefined, 且类型必须为int - fooList: [int] # Required, 不能为None/Undefined, 且类型必须为int列表 - color: "Red" | "Yellow" | "Blue" # Required, 字面值联合类型,且必须为"Red", "Yellow", "Blue"中的一个,枚举作用 - id?: int # Optional,可以留空,类型必须为int - - check: - bar >= 0 # bar必须大于等于0 - bar < 100 # bar必须小于100 - len(fooList) > 0 # fooList不能为None/Undefined,并且长度必须大于0 - len(fooList) < 100 # fooList不能为None/Undefined,并且长度必须小于100 - regex.match(foo, "^The.*Foo$") # regex 正则表达式匹配 - bar in range(100) # range, bar范围只能为1到99 - bar in [2, 4, 6, 8] # enum, bar只能取2, 4, 6, 8 - bar % 2 == 0 # bar必须为2的倍数 - all foo in fooList { - foo > 1 - } # fooList中的所有元素必须大于1 - any foo in fooList { - foo > 10 - } # fooList中至少有一个元素必须大于10 - abs(id) > 10 if id # check if 表达式,当 id 不为空时,id的绝对值必须大于10 -``` - -此外,上述 check 当中比较表达式还可以简写为: - -```python -0 <= bar < 100 -0 < len(fooList) < 100 -``` - -综上所述,KCL Schema 中支持的校验类型为: - -| 校验类型 | 使用方法 | -| -------- | ---------------------------------------------------------- | -| 范围校验 | 使用 `<`, `>` 等比较运算符 | -| 正则校验 | 使用 `regex` 系统库中的 `match` 等方法 | -| 长度校验 | 使用 `len` 内置函数,可以求 `list/dict/str` 类型的变量长度 | -| 枚举校验 | 使用字面值联合类型 | -| 非空校验 | 使用 schema 的可选/必选属性 | -| 条件校验 | 使用 check if 条件表达式 | - -## 20. 如何为 schema 及其属性添加文档注释? - -一个完整的 schema 属性注释使用三引号字符串表示,其中的结构如下所示: - -```python -schema Person: - """The schema person definition - - Attributes - ---------- - name : str - The name of the person - age : int - The age of the person - - See Also - -------- - Son: - Sub-schema Son of the schema Person. - - Examples - -------- - person = Person { - name = "Alice" - age = 18 - } - """ - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -``` - -## 21. 如何基于 schema 编写配置?多个配置之间如何复用公共的配置? - -在 schema 实例化的过程中可以使用解包运算符 `**` 对公共的配置进行展开 - -```python -schema Boy: - name: str - age: int - hc: int - -schema Girl: - name: str - age: int - hc: int - -config = { - age = 18 - hc = 10 -} - -boy = Boy { - **config - name = "Bob" -} -girl = Girl { - **config - name = "Alice" -} -``` - -输出 YAML 为: - -```yaml -config: - age: 18 - hc: 10 -boy: - name: Bob - age: 18 - hc: 10 -girl: - name: Alice - age: 18 - hc: 10 -``` - -## 22. 基于 schema 编写配置时如何覆盖 schema 属性的默认值? - -在定义 schema 后,可以使用 schema 名称实例化相应的配置,使用 `:` 运算符对 schema 默认值进行 union, 使用 `=` 对 schema 默认值进行覆盖。对于 int/float/bool/str 类型的 schema 属性,union 和覆盖的效果相同; 对于 list/dict/schema 类型的 schema 属性,union 和覆盖的效果不同; - -```python -schema Meta: - labels: {str:str} = {"key1" = "value1"} - annotations: {str:str} = {"key1" = "value1"} - -meta = Meta { - labels: {"key2": "value2"} - annotations = {"key2" = "value2"} -} -``` - -输出 YAML 为: - -```yaml -meta: - labels: - key1: value1 - key2: value2 - annotations: - key2: value2 -``` - -## 23. 如何通过继承来复用 schema 定义? - -可以在 schema 定义处声明 schema 需要继承的 schema 名称: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 - -# An employee **is** a person, and has some additional information. -schema Employee(Person): - bankCard: int - nationality: str - -employee = Employee { - firstName = "Bob" - lastName = "Green" - age = 18 - bankCard = 123456 - nationality = "China" -} -``` - -输出 YAML 为: - -```yaml -employee: - firstName: Bob - lastName: Green - age: 18 - bankCard: 123456 - nationality: China -``` - -注意: KCL 只允许 schema 单继承 - -## 24. 如何通过组合复用 schema 逻辑? - -可以使用 KCL schema mixin 复用 schema 逻辑,mixin 一般被用于 schema 内部属性的分离数据,和数据映射等功能,可以使 KCL 代码更具模块化和声明性。注意不同的 mixin 之间的混入属性不建议定义依赖关系,会使得 mixin 使用方式复杂,一般一个 mixin 中作不超过三个属性混入即可。 - -```python -schema Person: - mixin [FullNameMixin, UpperMixin] - - firstName: str - lastName: str - fullName: str - upper: str - -schema FullNameMixin: - fullName = "{} {}".format(firstName, lastName) - -schema UpperMixin: - upper = fullName.upper() - -person = Person { - firstName = "John" - lastName = "Doe" -} -``` - -输出 YAML 为: - -```yaml -person: - firstName: John - lastName: Doe - fullName: John Doe - upper: JOHN DOE -``` - -## 25. 如何导入其他 KCL 文件? - -通过 import 关键字可以导入其他 KCL 文件,KCL 配置文件被组织为模块。单个 KCL 文件被视为一个模块,目录被视为一个包,作为一个特殊的模块。import 关键字支持相对路径导入和绝对路径导入两种方式 - -比如对于如下目录结构: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ │── service1.k - │ └── service2.k - └── mixin - └── mixin1.k -``` - -对于 `main.k`, 相对路径导入和绝对路径导入分别可以表示为: - -```python -import service # 绝对路径导入, 根目录为kcl.mod所在的路径 -import mixin # 绝对路径导入, 根目录为kcl.mod所在的路径 - -import .model1 # 相对路径导入, 当前目录模块 -import ..service # 相对路径导入, 父目录 -import ...root # 相对路径导入, 父目录的父目录 -``` - -注意,对于 KCL 的入口文件 `main.k`, 其不能导入自身所在的文件夹,否则会发生循环导入错误: - -```python -import model # Error: recursively loading -``` - -## 26. 什么情况下可以省略 import ? - -除了 main 包当中的同一文件夹下的 KCL 可以相互引用而不需通过 import 相互引用,比如对于如下目录结构: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ │── service1.k - │ └── service2.k - └── mixin - └── mixin1.k -``` - -当 main.k 作为 KCL 命令行入口文件时, model 文件夹中的 main.k, model1.k 和 model2.k 中的变量不能相互引用,需要通过 import 导入,但是 service 文件夹中的 service1.k 和 service2.k 当中的变量可以互相引用,忽略 import - -service1.k - -```python -schema BaseService: - name: str - namespace: str -``` - -service2.k - -```python -schema Service(BaseService): - id: str -``` - -## 27. 有一行代码太长了,如何在语法正确的情况下优雅地换行? - -在 KCL 中可以使用续行符 `\` 进行换行, 并且在字符串中也可以使用 `\` 表示续行 - -长字符串连接续行举例: - -```python -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " -``` - -推导表达式续行举例: - -```python -data = [1, 2, 3, 4] -dataNew = [ - d + 2 \ - for d in data \ - if d % 2 == 0 -] -``` - -if 表达式续行举例: - -```python -condition = 1 -data1 = 1 \ - if condition \ - else 2 -data2 = 2 \ -if condition \ -else 1 -``` - -三引号字符串内部续行举例: - -```python -longString = """\ -The first line\ -The continue second line\ -""" -``` - -注意: 使用续行符 `\` 的同时缩进的保持, 如下所示: - -错误用例: - -```python -data1 = [ - 1, 2, - 3, 4 \ -] # Error, 需要保持右方括号]的缩进 - -data2 = [ - 1, 2, - 3, 4 -] # Error, 需要数字1和3的缩进统一 -``` - -正确用例: - -```python -data1 = [ - 1, 2, - 3, 4 -] # Right, 带缩进的列表定义 - -data2 = [ \ - 1, 2, \ - 3, 4 \ -] # Right, 使用续行符的列表定义, 实际效果是单行列表 - -data3 = [ \ - 1, 2, \ - 3, 4 \ -] # Right, 使用续行符的列表定义, 无需保持缩进, 实际效果是单行列表 -``` - -## 28. \*_, _ 这些符号是什么意思? - -- `**`, `*` 出现在 dict/list 外部时分别表示乘方运算符和乘法运算符 - -```python -data1 = 2 ** 4 # 2的4次方等于16 -data2 = 2 * 3 # 2乘以3等于6 -``` - -- `**`, `*` 出现在 dict/list 内部时表示解包运算符,经常用于 list/dict 的解包和合并, 与 Python 当中的解包运算符用法相同 - -dict 的解包: - -```python -data = {"key1" = "value1"} -dataUnpack = {**data, "key2" = "value2"} # 将data解包合并入dataUnpack中, {"key1": "value1", "key2": "value2"} -``` - -list 的解包: - -```python -data = [1, 2, 3] -dataUnpack = [*data, 4, 5, 6] # 将data解包合并入dataUnpack中, [1, 2, 3, 4, 5, 6] -``` - -## 29. 如何取 list/dict/schema 的子元素 - -在 KCL 中可以使用 select 表达式或者 subscript 表达式取 list/dict/schema 的子元素 - -- 对于 list 类型,可以使用 `[]` 取列表中的某一个元素或者某一些元素 - -```python -data = [1, 2, 3] # 定义一个整数类型的数组 -theFirstItem = data[0] # 取数组中索引为0的元素,即第一个元素 1 -theSecondItem = data[1] # 取数组中索引为1的元素,即第一个元素 2 -``` - -注意:索引的取值不能超出列表的长度,否则会发生错误,可以使用 `len` 函数获得数组的长度 - -```python -data = [1, 2, 3] -dataLength = len(data) # 数组长度为3 -item = data[3] # 发生数组索引越界错误 -``` - -此外,还可以使用负数索引倒序获得列表中的元素 - -```python -data = [1, 2, 3] -item1 = data[-1] # 取数组中索引为-1的元素,即最后一个元素 3 -item2 = data[-2] # 取数组中索引为-2的元素,即倒数第二个元素 2 -``` - -综上,列表索引的取值范围为 `[-len, len - 1]` - -当想要取得列表的一部分时,可以在 `[]` 中使用切片表达式,其具体语法为 `[<列表开始索引>:<列表终止索引>:<列表遍历步长>]`,注意索引开始终止的取值区间为 `左闭右开[<列表开始索引>, <列表终止索引>)`,注意三个参数均可省略不写 - -```python -data = [1, 2, 3, 4, 5] -dataSlice0 = data[1:2] # 取列表中索引开始为 1, 终止索引为 2 的元素集合 [2] -dataSlice1 = data[1:3] # 取列表中索引开始为 1, 终止索引为 3 的元素集合 [2, 3] -dataSlice2 = data[1:] # 取列表中索引开始为 1, 终止索引为 最后一个索引 的元素集合 [2, 3, 4, 5] -dataSlice3 = data[:3] # 取列表中索引开始为 第一个索引, 终止索引为 3 的元素集合 [1, 2, 3] -dataSlice4 = data[::2] # 取列表中索引开始为 第一个索引, 终止索引为 最后一个索引 的元素集合(步长为2) [1, 3, 5] -dataSlice5 = data[::-1] # 反转一个列表,[5, 4, 3, 2, 1] -dataSlice6 = data[2:1] # 当开始,终止,步长三个参数组合不满足条件时返回空列表 [] - -``` - -- 对于 dict/schema 类型,可以使用 `[]` 和 `.` 两种方式取 dict/schema 中的子元素 - -```python -data = {key1: "value1", key2: "value2"} -data1 = data["key1"] # "value1" -data2 = data.key1 # "value1" -data3 = data["key2"] # "value2" -data4 = data.key2 # "value2" -``` - -```python -schema Person: - name: str = "Alice" - age: int = 18 - -person = Person {} -name1 = person.name # "Alice" -name2 = person["name"] # "Alice" -age1 = person.age # 18 -age2 = person.age # 18 -``` - -当键值在 dict 中不存在时,返回未定义值 `Undefined` - -```python -data = {key1 = "value1", key2 = "value2"} -data1 = data["not_exist_key"] # Undefined -data2 = data.not_exist_key # Undefined -``` - -可以使用 `in` 关键字判断某个键值是否在 dict/schema 中存在 - -```python -data = {key1 = "value1", key2 = "value2"} -exist1 = "key1" in data # True -exist2 = "not_exist_key" in data # False -``` - -当键值中存在 `.` 时或者需要运行时取一个键值变量对应的值时,只能使用 `[]` 方式,如无特殊情况,使用 `.` 即可: - -```python -name = "key1" -data = {key1 = "value1", key2 = "value2", "contains.dot" = "value3"} -data1 = data[name] # "value1" -data2 = data["contains.dot"] # "value3" -# 注意这样子是不对的 data3 = data.contains.dot -``` - -注意:上述取子元素的运算符不能对非 list/dict/schema 集合类型的值进行操作,比如整数,空值等。 - -```python -data = 1 -data1 = 1[0] # error -``` - -```python -data = None -data1 = None[0] # error -``` - -在取集合类型的子元素时往往要进行非空或者长度判断: - -```python -data = [] -item = data[0] if data else None -``` - -可以使用非空判断符 `?` 添加在 `[]`, `.` 的前面表示进行 if 非空判断,当不满足条件时返回 None,比如上述代码可以简化为: - -```python -data = [] -item1 = data?[0] # 当data为空时,返回空值 None -item2 = data?[0] or 1 # 当data为空时,返回空值 None, 如果不想返回 None, 还可与 or 运算符连用返回其他默认值 -``` - -使用 `?` 可以进行递归调用, 避免复杂繁琐的非空判断 - -```python -data = {key1.key2.key3 = []} -item = data?.key1?.key2?.key3?[0] -``` - -## 30. 如何在 KCL 代码中判断变量的类型 - -KCL typeof built-in 函数可以在该函数执行时立即返回一个变量的类型(字符串表示)用于类型断言 - -用法举例: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person{} -t3 = typeof(_x1) - -_x2 = pkg.Person{} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# 输出 -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -## 31. 关键字和 KCL 变量名冲突了可以怎么解决? - -对于与关键字冲突的标识符,可以在标识符前添加 `$` 前缀用于定义一个关键字标识符,比如如下代码中使用了 `if`, `else` 等关键字作为标识符并且可以得到相应的 YAML 输出 - -```python -$if = 1 -$else = "s" - -schema Data: - $filter: str = "filter" - -data = Data {} -``` - -输出 YAML: - -```yaml -data: - filter: filter -if: 1 -else: s -``` - -注意:在非关键字标识符前添加 `$` 前缀的效果与不添加相同 - -```python -_a = 1 -$_a = 2 # 等效于 `_a = 2` -``` - -## 32. KCL 的内置类型是 KCL 的关键字吗?是否可用于变量的定义 - -KCL 的内置类型包括 `int`, `float`, `bool` 和 `str` 四种类型,它们不是 KCL 的关键字,可用于变量的定义,比如如下代码: - -```py -int = 1 -str = 2 -``` - -输出 YAML 为: - -```yaml -int: 1 -str: 2 -``` - -注意:如无特殊需求,不建议变量的名称取这些内置类型,因为在有些语言当中,它们作为关键字存在 - -## 33. 如何在 KCL 中实现类似 Enum 枚举的功能 - -有两种方式可以在 KCL 中实现 Enum 枚举的方式 - -- (推荐)使用**字面值类型**的**联合类型** - -```python -schema Person: - name: str - gender: "Male" | "Female" - -person = Person { - name = "Alice" - gender = "Male" # gender 只能为 "Male" 或者 "Female" -} -``` - -一个复杂例子 - -```python -schema Config: - colors: ["Red" | "Yellow" | "Blue"] # colors 是一个枚举数组 - -config = Config { - colors = [ - "Red" - "Blue" - ] -} -``` - -- 使用 schema 的 check 表达式 - -```python -schema Person: - name: str - gender: "Male" | "Female" - - check: - gender in ["Male", "Female"] - -person = Person { - name = "Alice" - gender = "Male" # gender 只能为 "Male" 或者 "Female" -} -``` - -## 34. 如何求字典 dict 的长度 - -在 KCL 中可以使用 `len` 内置函数直接求 dict 的长度 - -```python -len1 = len({k1: "v1"}) # 1 -len2 = len({k1: "v1", k2: "v2"}) # 2 -varDict = {k1 = 1, k2 = 2, k3 = 3} -len3 = len(varDict) # 3 -``` - -此外,使用 `len` 函数还可以求 `str` 和 `list` 类型长度 - -```python -len1 = len("hello") # 5 -len2 = len([1, 2, 3]) # 3 -``` - -## 35. 如何在 KCL 中编写带条件的配置 - -在 KCL 中,除了支持在顶级的语句中书写 `if-elif-else` 条件表达式以外,还支持在 KCL 复杂结构(list/dict/schema)中书写条件表达式,支持带条件的配置书写。 - -```python -x = 1 -# List 结构中的 if 条件语句 -dataList = [ - if x == 1: 1 -] -# Dict 结构中的 if 条件语句 -dataDict = { - if x == 1: key1 = "value1" # 可以同一行书写 - elif x == 2: - key2 = "value2" # 可以跨行书写 -} -# Schema 结构中的 if 条件语句 -schema Config: - id?: int -env = "prod" -dataSchema = Config { - if env == "prod": - id = 1 - elif env == "pre": - id = 2 - elif env == "test": - id = 3 -} -``` - -## 36. KCL 中的 == 运算符会作深度比较嘛? - -KCL 中的 `==` 运算符 - -- 对于基本类型 `int`, `float`, `bool`, `str` 的变量是直接比较它们的值是否相等 -- 对于复合类型 `list`, `dict`, `schema` 的变量会深度递归地比较其中的子元素是否相等 - - `list` 类型深度递归递归比较每个索引的值以及长度 - - `dict`/`schema` 类型深度递归比较每个属性的值(与属性出现的顺序无关) - -```python -print([1, 2] == [1, 2]) # True -print([[0, 1], 1] == [[0, 1], 1]) # True -print({k1 = 1, k2 = 2} == {k2 = 2, k1 = 1}) # True - -print([1, 2] == [1, 2, 3]) # False -print({k1 = 1, k2 = 2, k3 = 3} == {k2 = 2, k1 = 1}) # False -``` - -## 37. 如何对 KCL 中已有的配置块进行修改 - -在 KCL 中,存在三种**属性运算符** `=`、`+=`、`:`,可以用来对已有配置块进行修改,并且可以使用**解包运算符** `**` 等"继承"一个配置块的所有属性字段和值。 - -- `=` 属性运算符表示覆盖,使用 `=` 运算符可以对属性进行有优先级的覆盖/删除,(如果是用 `Undefined` 覆盖则表示删除) -- `+=` 属性运算符表示添加,一般用于对 list 类型的属性添加子元素,`+=` 属性运算符后跟的操作数类型也只能为 list 类型 -- `:` 属性运算符表示幂等合并,当值发生冲突时进行报错,不冲突时进行合并 - -### 覆盖属性运算符= - -最常使用的属性运算符是 `=`,表示一个属性的赋值,多次对同一个属性进行使用时表示覆盖,对于 `{}` 外的全局变量或者 `{}` 内的属性均表示使用值覆盖这个全局变量或者属性 - -```python -data = { # 定义一个字典类型的变量 data - a = 1 # 使用 = 在 data 中声明一个值为 1 的属性 a - b = 2 # 使用 = 在 data 中声明一个值为 1 的属性 b -} # 最终 data 的值为 {"a": 1, "b": 1} -``` - -在 schema 实例化处也可以使用覆盖属性运算符实现对 schema 默认值的覆盖效果,一般在创建新的 schema 实例时如无特殊的需求,一般使用 `=` 即可 - -```python -schema Person: - name: str = "Alice" # schema Person 的 name 属性具有默认值 "Alice" - age: int = 18 # schema Person 的 age 属性具有默认值 18 - -bob = Person { - name = "Bob" # "Bob" -> "Alice", 属性 name 的值 "Bob" 的值会覆盖 schema Person name 属性的默认值 "Alice" - age = 10 # 10 -> 18, 属性 age 的值 10 的值会覆盖 schema Person age 属性的默认值 18 -} # 最终 bob 的值为 {"name": "Bob", age: 10} -``` - -### 插入属性运算符 += - -插入属性运算符表示对一个属性的值进行原地添加,比如向一个 list 类型的属性添加新的元素 - -```python -data = { - args = ["kcl"] # 使用 = 在 data 中声明一个值为 ["kcl"] 的属性 args - args += ["-Y", "settings.yaml"] # 使用 += 运算符向属性 args 中添加两个元素"-Y", "settings.yaml" -} # 最终 data 的值为 {"args": ["kcl", "-Y", "settings.yaml"]} -``` - -### 合并属性运算符: - -合并属性运算符表示对一个属性的不同配置块值进行幂等的合并,当需要合并的值发生冲突时进行报错,多用于复杂配置合并场景 - -```python -data = { - labels: {key1: "value1"} # 定义一个 labels, 它的类型为 dict, 值为 {"key1": "value1"} - labels: {key2: "value2"} # 使用 : 将 labels 不同的配置值进行合并 -} # 最终 data 的值为 {"labels": {"key1": "value1", "key2": "value2"}} -``` - -合并属性运算符属于幂等运算符,需要合并的配置块的书写顺序不影响其最终结果,比如上述例子中的两个 `labels` 属性也可以调换顺序书写 - -```python -data = { # 同一个属性 labels 的合并书写顺序不影响最终结果 - labels: {key2: "value2"} # 定义一个 labels, 它的类型为 dict, 值为 {"key2": "value2"} - labels: {key1: "value1"} # 使用 : 将 labels 不同的配置值进行合并 -} # 最终 data 的值为 {"labels": {"key1": "value1", "key2": "value2"}} -``` - -注意:合并属性运算符会对合并的值进行冲突检查,当需要合并的配置值发生冲突时进行报错 - -```python -data = { - a: 1 # a 的值为 1 - a: 2 # Error: a 的值 2 不能与 a 的值 1 进行合并,因为其结果存在冲突,且合并是不可交换的 -} -``` - -```python -data = { - labels: {key: "value"} - labels: {key: "override_value"} # Error: 两个 labels 的 key 属性的值 "value" 和 "override_value" 是冲突的,不可合并 -} -``` - -合并运算符对不同类型的使用方式不同 - -- 不同类型的属性不能进行合并 -- 当属性为 int/float/str/bool 等基本类型时,运算符会判断需要合并的值是否相等,不相等时发生合并冲突错误 - -```python -data = { - a: 1 - a: 1 # Ok - a: 2 # Error -} -``` - -- 当属性为 list 类型时 - - 当需要合并的两个 list 长度不相等时,发生合并冲突错误 - - 当需要合并的两个 list 长度相等时,按照索引递归地合并 list 当中的每一个元素 - -```python -data = { - args: ["kcl"] - args: ["-Y", "settings.yaml"] # Error: 两个 args 属性的长度不相同,不能进行合并 - env: [{key1: "value1"}] - env: [{key2: "value2"}] # Ok: 最终 env 属性的值为 [{"key1": "value1"}, {"key2": "value2"}] -} -``` - -- 当属性为 dict/schema 类型时,按照 key 递归地合并 dict/schema 当中的每一个元素 - -```python -data = { - labels: {key1: "value1"} - labels: {key2: "value2"} - labels: {key3: "value3"} -} # 最终 data 的值为 {"labels": {"key1": "value1", "key2": "value2", "key3": "value3"}} -``` - -- 任意类型的属性与 None/Undefined 合并的结果都是其自身 - -```python -data = { - args: ["kcl"] - args: None # Ok - args: Undefined #Ok -} # 最终 data 的值为 {"args": ["kcl"]} -``` - -支持顶级变量使用 `:` 属性声明与合并(仍然可使用 `config = Config {}` 的方式声明一个配置块) - -```python -schema Config: - id: int - value: str - -config: Config { - id: 1 -} -config: Config { - value: "1" -} -""" -此处定义了两个 Config 配置块,使用 : 运算符将可以两个配置块合并在一起,其合并的等效代码如下: -config: Config { - id: 1 - value: "1" -} -""" -``` - -综上所述,合并属性运算符 `:` 的使用场景主要为复杂数据结构 list/dict/schema 的合并操作,一般情况如无特殊需求使用 `=` 和 `+=` 两种属性运算符即可,因此属性运算符的最佳实践如下 - -- 对于基本类型,采用 `=` 运算符 -- 对于 list 类型,一般采用 `=` 和 `+=` 运算符,使用 `=` 表示完全覆盖 list 属性,使用 `+=` 表示向 list 中添加元素 -- 对于 dict/schema 类型,一般采用 `:` 运算符 - -此外,当已经存在一个配置时,可以使用解包运算符 `**` 获得此配置的所有字段值并对其中的字段使用不同属性运算符进行修改,并获得一个新的配置 - -```python -configBase = { - intKey = 1 # 一个 int 类型的属性 - floatKey = 1.0 # 一个 float 类型的属性 - listKey = [0] # 一个 list 类型的属性 - dictKey = {key1: "value1"} # 一个 dict 类型的属性 -} -configNew = { - **configBase # 将 configBase 解包内联到 configNew 中 - intKey = 0 # 使用 覆盖属性运算符 = 将 intKey 属性覆盖为 1 - floatKey = Undefined # 使用 覆盖属性运算符 = 删除 floatKey 属性 - listKey += [1] # 使用 添加属性运算符 += 为 listKey 属性尾部添加一个属性 1 - dictKey: {key2: "value2"} # 使用 合并属性运算符 : 为 dictKey 属性扩展一个键-值对 -} -``` - -输出的 YAML 结果为: - -```yaml -configBase: - intKey: 1 - floatKey: 1.0 - listKey: - - 0 - dictKey: - key1: value1 -configNew: - intKey: 0 - listKey: - - 0 - - 1 - dictKey: - key1: value1 - key2: value2 -``` - -或者可以使用 `|` 运算符对两个配置块合并: - -```python -configBase = { - intKey = 1 # 一个 int 类型的属性 - floatKey = 1.0 # 一个 float 类型的属性 - listKey = [0] # 一个 list 类型的属性 - dictKey = {key1: "value1"} # 一个 dict 类型的属性 -} -configNew = configBase | { # 使用 | 进行合并 - intKey = 0 # 使用 覆盖属性运算符 = 将 intKey 属性覆盖为 1 - floatKey = Undefined # 使用 覆盖属性运算符 = 删除 floatKey 属性 - listKey += [1] # 使用 添加属性运算符 += 为 listKey 属性尾部添加一个属性 1 - dictKey: {key2: "value2"} # 使用 合并属性运算符 : 为 dictKey 属性扩展一个键-值对 -} -``` - -输出的 YAML 结果为: - -```yaml -configBase: - intKey: 1 - floatKey: 1.0 - listKey: - - 0 - dictKey: - key1: value1 -configNew: - intKey: 0 - listKey: - - 0 - - 1 - dictKey: - key1: value1 - key2: value2 -``` - -### KCL 发生 conflicting values on the attribute 'attr' between {value1} and {value2} 错误的解决方式 - -当 KCL 发生类似 conflicting values on the attribute 'attr' between {value1} and {value2} 错误时,一般是合并属性运算符 `:` 的使用问题,表明 `value1` 和 `value2` 配置进行合并时在属性 `attr` 处发生了冲突错误。一般情况将 value2 的 attr 属性修改为其他属性运算符即可,使用 `=` 表示覆盖,使用 `+=` 表示添加 - -比如对于如下代码: - -```python -data = {k: 1} | {k: 2} # Error: conflicting values on the attribute 'k' between {'k': 1} and {'k': 2} -``` - -则可以使用 `=` 属性运算符修改为如下形式 - -```python -data = {k: 1} | {k = 2} # Ok: the value 2 will override the value 1 through the `=` operator -``` - -## 38. KCL 中如何同时遍历多个元素 - -KCL 中可以使用 for 推导表达式遍历多个元素 - -- 举例 1: 使用 for 进行 2 维元素遍历 - -```python -dimension1 = [1, 2, 3] # dimension1 列表的长度是 3 -dimension2 = [1, 2, 3] # dimension2 列表的长度是 3 -matrix = [x + y for x in dimension1 for y in dimension2] # matrix 列表的长度是 9 = 3 * 3 -``` - -输出结果如下: - -```yaml -dimension1: - - 1 - - 2 - - 3 -dimension2: - - 1 - - 2 - - 3 -matrix: - - 2 - - 3 - - 4 - - 3 - - 4 - - 5 - - 4 - - 5 - - 6 -``` - -- 举例 2: 使用 for 循环配合 zip 内置函数按照索引一一对应对多个列表进行遍历 - -```python -dimension1 = [1, 2, 3] # dimension1 列表的长度是 3 -dimension2 = [1, 2, 3] # dimension2 列表的长度是 3 -dimension3 = [d[0] + d[1] for d in zip(dimension1, dimension2)] # dimension3 列表的长度是 3 -``` - -输出结果如下: - -```yaml -dimension1: - - 1 - - 2 - - 3 -dimension2: - - 1 - - 2 - - 3 -dimension3: - - 2 - - 4 - - 6 -``` - -## 39. KCL 中如何为 option 函数设定默认值 - -在 KCL 中,当 option 属性的值为 None/Undefined 空时,可以使用逻辑或 `or` 直接指定一个默认值 - -```python -value = option("key") or "default_value" # 当 key 的值存在时,取 option("key") 的值,否则取 "default_value" -``` - -或者使用 option 函数的 default 参数 - -```python -value = option("key", default="default_value") # 当 key 的值存在时,取 option("key") 的值,否则取 "default_value" -``` - -## 40. KCL 中 schema 怎么检查多个属性不能同时为空或同时设置 - -在 KCL 中,对于 schema 的单个属性不能为空可以使用属性非空标记 - -```python -schema Person: - name: str # required. name 不能为空 - age: int # required. age 不能为空 - id?: int # optional. id 可以留空 -``` - -而对于需要检查 schema 属性不能同时为空或者只能有一者为空的情况时,需要借助 schema check 表达式进行书写,下面以同一个 schema Config 的两个属性 a, b 为例进行说明 - -- Config 的 a, b 属性不能同时为空 - -```python -schema Config: - a?: str - b?: str - - check: - a or b, "a属性和b属性不能同时为空" -``` - -- Config 的 a, b 属性只能有一个为空或者都为空(不能同时存在或不为空) - -```python -schema Config: - a?: str - b?: str - - check: - not a or not b, "a属性和b属性不能同时填写" -``` - -## 41. KCL 中 import 了某个文件但是找不到其同目录下其他 KCL 文件定义的 schema 可能是什么原因 - -可能是与使用 import 仅导入了这个文件夹的这一个文件导致,在 KCL 中,import 支持导入整个文件夹,也支持导入某一个文件夹下的的某一个 KCL 文件,比如对于如下目录结构 - -``` -. -├── kcl.mod -├── main.k -└── pkg - ├── pkg1.k - ├── pkg2.k - └── pkg3.k -``` - -在根目录下存在入口文件 main.k,可以在 main.k 中书写如下代码导入整个 pkg 文件夹,此时 pkg 文件夹下的所有 schema 定义互相可见 - -```python -import pkg -``` - -还可以书写如下代码导入单个文件 pkg/pkg1.k,此时 pkg1.k 不能找到其他文件即 pkg2.k/pkg3.k 下的 schema 定义 - -```python -import pkg.pkg1 -``` - -## 42. KCL 中的缩进是如何处理的? - -在 KCL 中,在出现冒号 `:`、中括号对 `[]` 以及大括号对 `{}` 时,一般需要使用换行 + 缩进,同一缩进级的缩进空格数需要保持一致,一个缩进级一般采用 4 个空格表示 - -- 冒号 `:` 后跟换行 + 缩进 - -```python -"""if 语句中的缩进""" -_a = 1 -_b = 1 -if _a >= 1: # 冒号后跟换行+缩进 - if _a > 8: - _b = 2 - elif a > 6: - _b = 3 - -"""schema 定义中的缩进""" -schema Person: # 冒号后跟换行+缩进 - name: str - age: int -``` - -- 中括号对 `[]` 后跟换行 + 缩进 - -```python -data = [ # 左中括号 [ 后跟换行+缩进 - 1 - 2 - 3 -] # 右中括号 ] 前取消缩进 -``` - -```python -data = [ # 左中括号 [ 后跟换行+缩进 - i * 2 for i in range(5) -] # 右中括号 ] 前取消缩进 -``` - -- 大括号对 `{}` 后跟换行 + 缩进 - -```python -data = { # 左大括号 { 后跟换行+缩进 - k1 = "v1" - k2 = "v2" -} # 右大括号 } 前取消缩进 -``` - -```python -data = { # 左大括号 { 后跟换行+缩进 - str(i): i * 2 for i in range(5) -} # 右大括号 } 前取消缩进 -``` - -## 43. 如何为 KCL 代码编写简单的测试? - -KCL 目前的版本还不支持内部程序调试,可以使用 assert 语句以及 print 函数实现数据的断言和打印查看 - -```python -a = 1 -print("The value of a is", a) -assert a == 1 -``` - -此外,还可以借助 kcl-test 测试工具编写 KCL 内部编写测试用例 - -假设有 hello.k 文件,代码如下: - -```python -schema Person: - name: str = "kcl" - age: int = 1 - -hello = Person { - name = "hello kcl" - age = 102 -} -``` - -构造 hello_test.k 测试文件,内容如下: - -```python -schema TestPerson: - a = Person{} - assert a.name == 'kcl' - -schema TestPerson_age: - a = Person{} - assert a.age == 1 - -schema TestPerson_ok: - a = Person{} - assert a.name == "kcl" - assert a.age == 1 -``` - -然后在目录下执行 kcl-test 命令: - -``` -$ kcl-test -ok /pkg/to/app [365.154142ms] -$ -``` - -## 44. KCL 中如何定义函数或定义方法? - -schema 结构在一定程度上充当了函数的功能,并且这个函数具有多个输入参数和多个输出参数的能力,比如如下代码可以实现一个斐波那契数列的功能: - -```python -schema Fib: - n: int - value: int = 1 if n <= 2 else (Fib {n: n - 1}).value + (Fib {n: n - 2}).value - -fib8 = (Fib {n: 8}).value -``` - -输出结果为: - -```yaml -fib8: 21 -``` - -一个合并列表为字典的 schema 函数 - -```python -schema UnionAll[data, n]: - _?: [] = data - value?: {:} = ((UnionAll(data=data, n=n - 1) {}).value | data[n] if n > 0 else data[0]) if data else {} - -schema MergeList[data]: - """Union一个列表中的所有元素返回合并字典 - - [{"key1": "value1"}, {"key2": "value2"}, {"key3": "value3"}] -> {"key1": "value1", "key2": "value2", "key3": "value3"} - """ - _?: [] = data - value?: {:} = (UnionAll(data=data, n=len(data) - 1) {}).value if data else {} -``` - -此外,KCL 支持使用 `lambda` 关键字定义一个函数: - -```python -func = lambda x: int, y: int -> int { - x + y -} -a = func(1, 1) # 2 -``` - -lambda 函数具有如下特性: - -- lambda 函数将最后一个表达式的值作为函数的返回值,空函数体返回 None。 -- 返回值类型注解可以省略,返回值类型为最后一个表达式值的类型 -- 函数体中没有与顺序无关的特性,所有的表达式都是按顺序执行的 - -```python -_func = lambda x: int, y: int -> int { - x + y -} # 使用 lambda 表达式定义一个函数 -_func = lambda x: int, y: int -> int { - x - y -} # Ok -_func = lambda x: int, y: int -> str { - str(x + y) -} # Error (int, int) -> str can't be assigned to (int, int) -> int -``` - -lambda 函数对象不能参与任何计算,只能在赋值语句和调用语句中使用。 - -```python -func = lambda x: int, y: int -> int { - x + y -} -x = func + 1 # Error: unsupported operand type(s) for +: 'function' and 'int(1)' -``` - -```python -a = 1 -func = lambda x: int { - x + a -} -funcOther = lambda f, para: int { - f(para) -} -r = funcOther(func, 1) # 2 -``` - -输出为: - -```python -a: 1 -r: 2 -``` - -可以定义一个匿名函数并直接调用 - -```python -result = (lambda x, y { - z = 2 * x - z + y -})(1, 1) # 3 -``` - -可以在 for 循环使用使用匿名函数 - -```python -result = [(lambda x, y { - x + y -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 3, 3, 4] -``` - -可以在 KCL schema 中定义并使用函数 - -```python -_funcOutOfSchema = lambda x: int, y: int { - x + y -} -schema Data: - _funcInSchema = lambda x: int, y: int { - x + y - } - id0: int = _funcOutOfSchema(1, 1) - id1: int = _funcInSchema(1, 1) - id2: int = (lambda x: int, y: int { - x + y - })(1, 1) -``` - -输出 YAML 为: - -```yaml -data: - id0: 2 - id1: 2 - id2: 2 -``` - -## 45. 为什么变量赋值为枚举类型(字面值联合类型)时会报错 - -在 KCL 中,被定义为字面值联合类型的属性,在赋值时仅允许接收一个字面值或者同为字面值联合类型的变量,比如如下代码是正确的: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -data = Data { - color = "Red" # Ok, 赋值为 "Red"、"Yellow" 和 "Blue" 均可 -} -``` - -然而以下代码是错误的: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -_color = "Red" - -data = Data { - color = _color # Error: expect str(Red)|str(Yellow)|str(Blue), got str -} -``` - -这是因为没有为变量 `_color` 申明一个类型,它会被 KCL 编译器推导为 `str` 字符串类型,因此当一个 “较大” 的类型 `str` 赋值为一个 “较小” 的类型时 `"Red" | "Yellow" | "Blue"` 会报错,一个解决方式是为 `_color` 变量声明一个类型,以下代码是正确的: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -_color: "Red" | "Yellow" | "Blue" = "Red" - -data = Data { - color = _color # Ok -} -``` - -进一步地,我们可以使用类型别名来简化枚举(字面值联合类型的书写),比如如下代码: - -```python -type Color = "Red" | "Yellow" | "Blue" # 定义一个类型别名,可以在不同的地方重复使用,降低代码书写量 - -schema Data: - color: Color - -_color: Color = "Red" - -data = Data { - color = _color # Ok -} -``` - -## 46. 过程式的 for 循环 - -KCL 中为何不支持过程式的 for 循环! - -KCL 提供了推导表达式以及 all/any/map/filter 表达式等用于对一个集合元素进行处理,满足大部分需求,提供过程式的 for 循环体从目前场景看需求暂时不强烈,因此暂未提供过程式的 for 循环支持 - -此外,KCL 中虽然没有支持过程式的 for 循环,但是可以通过 for 循环和 lambda 函数“构造”相应的过程式 for 循环 - -```python -result = [(lambda x: int, y: int -> int { - # 在其中书写过程式的 for 循环逻辑 - z = x + y - x * 2 -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 2, 4, 4] -``` - -## 47. 默认变量不可变 - -KCL 变量不可变性是指 KCL 顶层结构中的非下划线 `_` 开头的导出变量初始化后不能被改变。 - -```python -schema Person: - name: str - age: int - -a = 1 # a会输出到YAML中,一旦赋值不可修改 -_b = 1 # _b变量以下划线开头命名,不会输出到YAML中, 可多次赋值修改 -_b = 2 -alice = Person { - name = "Alice" - age = 18 -} -``` - -规定变量不可变的方式分为两类: - -- schema 外的非下划线顶层变量 - -```python -a = 1 # 不可变导出变量 -_b = 2 # 可变非导出变量 -``` - -## 48. 在 KCL 中存在类似 Go `interface{}`/`any` 或者 Java `Object` 的类型嘛? - -在 KCL 中,我们可以使用 `any` 类型注解来定义一个变量存储任意类型比如整数、字符串、schema 结构等数据。比如如下例子: - -```python -schema Data: - id: int = 1 - -var_list: [any] = [1, "12", Data {}] -``` - -输出 YAML 为: - -```yaml -var_list: - - 1 - - "12" - - id: 1 -``` - -此外,我们可以使用 `typeof` 函数来判断 KCL 变量的类型: - -```python -schema Data1: - id: int = 1 - -schema Data2: - name: str = "name" - -data_list: [any] = [Data1 {}, Data2 {}] -data_type_list: [str] = [typeof(data) for data in data_list] -``` - -输出 YAML 为: - -```yaml -data_list: - - id: 1 - - name: name -data_type_list: - - Data1 - - Data2 -``` - -## 49. 如何通过编写 KCL 插件进行扩展? - -KCL 插件在 KCL 的 plugins 子目录(通常安装在 `$HOME/.kcl/plugins` 目录),或者通过 `$KCL_PLUGINS_ROOT` 环境变量设置(环境变量优先级更高)。对于插件开发人员,插件都在 [Git 仓库](https://github.com/kcl-lang/kcl-plugin)管理,可以将插件仓库克隆到该目录进行开发。 - -KCL 内置了 kcl-plugin 脚手架命令用于辅助用户使用 Python 语言编写 KCL 插件,以便在 KCL 文件当中调用相应的插件对 KCL 语言本身进行增强,比如访问网络,读写 IO,CMDB 查询和加密解密等功能。 - -``` -usage: kcl-plugin [-h] {list,init,info,gendoc,test} ... - -positional arguments: - {list,init,info,gendoc,test} - kcl plugin sub commands - list list all plugins - init init a new plugin - info show plugin document - gendoc gen all plugins document - test test plugin - -optional arguments: - -h, --help show this help message and exit -``` - -比如想要开发一个名为 io 插件,就可以使用如下命令成功新建一个 io 插件 - -``` -kcl-plugin init io -``` - -然后可以使用如下命令获得 plugin 的根路径并 cd 到相应的 io 插件目录进行开发 - -``` -kcl-plugin info -``` - -比如想要开发一个读文件的函数 read_file,就可以在 `$plugin_root/io` 的 `plugin.py` 中进行 python 代码编写: - -```python -# Copyright 2020 The KCL Authors. All rights reserved. - -import pathlib - -INFO = { - 'name': 'io', - 'describe': 'my io plugin description test', - 'long_describe': 'my io plugin long description test', - 'version': '0.0.1', -} - - -def read_file(file: str) -> str: - """Read string from file""" - return pathlib.Path(file).read_text() - -``` - -另外可以在 `plugin_test.py` 中编写相应的测试函数,也可以直接编写如下所示 KCL 文件进行测试: - -```python -import kcl_plugin.io - -text = io.read_file('test.txt') -``` - -还可以使用 info 命令查看 io 插件的信息 - -``` -kcl-plugin info io -``` - -``` -{ - "name": "io", - "describe": "my io plugin description test", - "long_describe": "my io plugin long description test", - "version": "0.0.1", - "method": { - "read_file": "Read string from file" - } -} -``` - -最后将编写测试完成的插件在 `kcl_plugins` 仓库提 MR 合并即可 - -## 50. 如何在 KCL 中进行基本类型转换 - -可以使用`int()`, `float()`和`str()` 这些内置的方法来进行 `int`, `float` 和 `str` 之间的基本类型转换. - -``` -_t = 1 - -t_str: str = str(_t) # 输出的 t_str 为一个字符串 "t_str: '1'" -t_int: int = int(t_str) # 输出的 t_int 为一个整型 "t_int: 1" -t_float: float = float(t_str) # 输出的 t_float 为一个浮点型 "t_float: 1.0" -``` - -如果您想查看更多详细的关于KCL类型系统和类型转换的内容,您可以查阅 [KCL 内置类型](https://kcl-lang.io/docs/reference/lang/tour#built-in-types) 和 [KCL 类型系统](https://kcl-lang.io/docs/reference/lang/tour#type-system)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/support/faq-yaml.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/support/faq-yaml.md deleted file mode 100644 index 4dd12c00..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/support/faq-yaml.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -sidebar_position: 3 ---- - -# YAML 语法 - -## 1. YAML 字符串使用单引号和双引号的区别是什么? - -- YAML 双引号字符串是唯一能够表达任意字符串的样式,通过使用 `\` 转义字符,比如使用 `\"` 转义双引号 `"`,使用 `\\` 转义反斜杠 `\`,并且可以使用单个反斜杠 `\` 作为双引号字符串的续行符 -- YAML 单引号字符串与 YAML 双引号字符串不同的是可以自由地使用 `\` 和 `"` 而不需要转义,但是使用两个单引号 `''` 转义单引号 `'` 字符 - -比如对于如下的例子,三个字符串变量的内容是相同的 - -```yaml -string1: 'here '' s to "quotes"' -string2: 'here''s to "quotes"' -string3: here's to "quotes" -``` - -因此,KCL 输出 YAML 字符串的策略是当字符串内容出现单引号时,优先输出无引号字符串或双引号字符串,其他情况输出单引号字符串以避免理解上的负担。 - -更多细节可参考: [YAML 规范 v1.2](https://yaml.org/spec/1.2.1/) - -## 2. YAML 中出现的 | - + > 等符号是什么含义? - -在使用 KCL 多行字符串(使用三引号括起来的字符串),输出的 YAML 经常会携带一些特殊的记号,如 `|`,`-`,`+` 和 `>` 等,这些记号通常为 YAML 多行字符串的表示方法,比如对于如下 KCL 代码: - -```python -data = """This is a KCL multi line string (the first line) -This is a KCL multi line string (the second line) -This is a KCL multi line string (the third line) - - -""" -var = 1 -``` - -输出 YAML 为: - -```yaml -data: |+ - This is a KCL multi line string (the first line) - This is a KCL multi line string (the second line) - This is a KCL multi line string (the third line) - - -var: 1 -``` - -- `|` 表示**块字符串样式**,用于表示一个多行字符串,其中的所有换行符都表示字符串真实的换行; -- `>` 表示**块折叠样式**,在其中所有的换行符将被空格替换; -- `+` 和 `-` 用于控制在字符串末尾使用换行符的情况。默认情况为字符串末尾保留单个换行符,如果要删除所有换行符,可以在样式指示符 `|` 或 `>` 后面放置一个 `-` 来完成,如果要保留末尾的换行符,则需要在 `|` 或 `>` 后面放置一个 `+` - -更多细节可参考: [YAML 多行字符串](https://yaml-multiline.info/) 和 [YAML 规范 v1.2](https://yaml.org/spec/1.2.1/) - -## 3. YAML 中在 | - + > 等符号之后出现的数字是什么含义? - -数字表示 YAML 当中的**显式缩进指示符**。对于 YAML 中的长字符串,YAML 通常第一个非空行确定字符串的缩进级别,而当第一个非空行前面具有非前导字符时,比如换行符,YAML 要求必须使用**显式缩进指示符**来指定内容的缩进级别,比如 `|2` 和 `|1` 等 - -比如对于如下 KCL 代码: - -```python -longStringStartWithNewline = """ -This is the second line -This is the third line -""" - -``` - -```yaml -longStringStartWithNewline: |2 - - This is the second line - This is the third line -``` - -如果不需要长字符串开头的空行或换行符,则可以以如下两种方式进行 KCL 长字符串书写 - -- 长字符串从第 1 行开始书写 - -```python -longString = """This is the second line -This is the third line -""" -``` - -- 使用续行符 - -```python -longString = """\ -This is the second line -This is the third line -""" -``` - -以上两种方式输出的 YAML 均为: - -```yaml -longString: | - This is the second line - This is the third line -``` - -更多细节可参考: [YAML 规范 v1.2](https://yaml.org/spec/1.2.1/) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/support/support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/support/support.md deleted file mode 100644 index 648ee5a3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/support/support.md +++ /dev/null @@ -1,3 +0,0 @@ -# 常见问答 - -KCL 安装、使用过程中遇到的常见问题,包括基本概念解释、KCL 语法、KCL 语言设计、命令行工具和 YAML 等常见问题。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6.json deleted file mode 100644 index a9e8bfe5..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "sidebar.user_docs.category.Get Started": { - "message": "快速开始" - }, - "sidebar.user_docs.category.Introduction": { - "message": "简介" - }, - "sidebar.user_docs.category.User Guide": { - "message": "用户手册" - }, - "sidebar.user_docs.guides.category.Automation": { - "message": "自动化" - }, - "sidebar.user_docs.category.Configuration": { - "message": "配置" - }, - "sidebar.user_docs.category.Data Integration": { - "message": "数据集成" - }, - "sidebar.user_docs.category.Package Management": { - "message": "包管理工具" - }, - "sidebar.user_docs.category.How to": { - "message": "如何使用" - }, - "sidebar.user_docs.category.Schema Definition": { - "message": "模型定义" - }, - "sidebar.user_docs.category.Validation": { - "message": "验证" - }, - "sidebar.user_docs.category.Concepts": { - "message": "核心概念" - }, - "sidebar.user_docs.category.FAQ": { - "message": "常见问答" - }, - "sidebar.reference.category.Tutorial": { - "message": "教程" - }, - "sidebar.reference.category.Code Lab": { - "message": "代码实验室" - }, - "sidebar.reference.category.Spec": { - "message": "语言规范" - }, - "sidebar.reference.category.Errors and Warnings": { - "message": "错误与警告" - }, - "sidebar.reference.category.Types": { - "message": "类型系统" - }, - "sidebar.reference.category.System Package": { - "message": "系统模块" - }, - "sidebar.reference.category.Plugin System": { - "message": "插件系统" - }, - "sidebar.reference.category.Multi-Language": { - "message": "多语言集成" - }, - "sidebar.reference.category.Cheat Sheet": { - "message": "备忘表" - }, - "sidebar.reference.category.Package Management": { - "message": "包管理工具" - }, - "sidebar.reference.category.Command Reference": { - "message": "命令参考" - }, - "sidebar.reference.category.Advanced-Concepts": { - "message": "进阶概念" - }, - "sidebar.reference.category.Best-Practices": { - "message": "最佳实践" - }, - "sidebar.tools.category.Command Line Tools": { - "message": "命令行工具" - }, - "sidebar.tools.category.KCL Tools": { - "message": "语言工具" - }, - "sidebar.tools.category.OpenAPI Tools": { - "message": "OpenAPI 工具" - }, - "sidebar.community.category.Community": { - "message": "简介" - }, - "sidebar.community.category.Types": { - "message": "类型系统" - }, - "sidebar.community.category.Contribution Guide": { - "message": "贡献指南" - }, - "sidebar.community.category.Release Policy": { - "message": "发布策略" - }, - "sidebar.docs.category.GitOps": { - "message": "GitOps", - "description": "The label for category GitOps in sidebar docs" - }, - "sidebar.docs.category.CI Integration": { - "message": "CI 集成", - "description": "The label for category CI Integration in sidebar docs" - }, - "sidebar.user_docs.category.GitOps": { - "message": "GitOps", - "description": "The label for category GitOps in sidebar user_docs" - }, - "sidebar.user_docs.category.CI Integration": { - "message": "CI 集成", - "description": "The label for category CI Integration in sidebar user_docs" - }, - "sidebar.docs.category.Mutate or Validate Kubernetes Manifests": { - "message": "编辑或验证 Kubernetes 资源", - "description": "The label for category Mutate or Validate Kubernetes Manifests in sidebar docs" - }, - "sidebar.user_docs.category.Mutate or Validate Kubernetes Manifests": { - "message": "编辑或验证 Kubernetes 资源", - "description": "The label for category Mutate or Validate Kubernetes Manifests in sidebar user_docs" - }, - "sidebar.docs.category.Secret Management": { - "message": "敏感信息管理", - "description": "The label for category Secret Management in sidebar docs" - }, - "sidebar.user_docs.category.Secret Management": { - "message": "敏感信息管理", - "description": "The label for category Secret Management in sidebar user_docs" - } -} \ No newline at end of file diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/_category_.json deleted file mode 100644 index f763b5c8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "社区", - "position": 5 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/contribute/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/contribute/_category_.json deleted file mode 100644 index 131bb8e3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/contribute/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "贡献指南", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/contribute/contribute-code.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/contribute/contribute-code.md deleted file mode 100644 index 8e8392fe..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/contribute/contribute-code.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -sidebar_position: 2 ---- - -# 如何贡献代码? - -欢迎参与 KCL 共建贡献完善代码、完善代码文档和测试,同时也欢迎通过 Issue 提供反馈。本文主要针对修改和完善已有的代码,如果是希望增加 KCL 语言特性请通过 KEP 流程提交。 - -## 1. 代码和注释中的错别字 - -如果只是修改代码和注释中的错别字,不涉及代码逻辑的调整,那么可以直接在 Github 克隆仓库后直接修改并提交 PR。需要注意的是尽量保持代码风格一致。 - -## 2. 如何贡献 KCL 代码 - -- 先确保本地测试环境正常 -- 修改代码并补充测试 -- 本地测试通过后提交 PR - -## 3. 如何贡献 VS Code 插件代码 - -请参考 VS Code 插件仓库的相关文档 - -## 4. 开发流程相关代码 - -欢迎通过 Issue 和讨论组讨论。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/contribute/contribute-docs.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/contribute/contribute-docs.md deleted file mode 100644 index 7b846680..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/contribute/contribute-docs.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 如何贡献文档? - -本文主要针对已有的文档做局部修改。如果是投稿博客文章、添加新的文档或者调整文档目录结构请先联系团队成员。 - -KCL 文档分为用户指南、开发文档、内部文档、参考手册和博客文章等,他们的区别如下: - -- 用户指南:对应使用文档,是让用户以最小的代价快速使用 KCL 工具完整工作,不要涉及太多的内部原理和实现 -- 开发文档:内部是怎么实现的,主要针对希望了解 KCL 原理和参与贡献和开发的同学 -- 内部文档:针对企业用户的一些内部场景定制的文档 -- 参考手册:KCL 语言、工具和 IDE 等全部特性的文档,内容覆盖最广但比较琐碎 -- 博客文章:没有特别的限制,可以是针对某些具体的场景、某些技术点或者是整体发展展望等分享文章 - -在贡献不同类型的文档时,最好能够结合上面的定位对不同的内容做一些适当的裁剪,给读者最佳体验。 - -## 1. 基本规范 - -- 除标题外,内部小标题尽量带编号,便于阅读 -- 工具自动输出的文档需要由到源代码的链接,小标题可以不带编号 -- 尽量不要贴大段的代码(30行以内),代码最好给出文字解释和对应的参考链接 -- 有图有真相,但是不推荐过度复杂的架构图 -- 内部链接:采用 `/docs/user_docs/getting-started/intro` 绝对路径形式 - -**标点和空格** - -- 在中文的文档中优先使用中文的标点 -- 中文和英文之间需要增加 1 个空格 -- 中文和数字之间需要增加 1 个空格 -- 中文使用全角标点,标点前后均不添加空格 -- 英文内容使用半角标点,标点后面加 1 个空格 -- 链接前后需要保留一个空格,但是段落开头和中文全角标点附近不用添加空格。 - -**图片和资源文件名** - -- 文件名和目录名只能用数字、英文字母、下划线 `_` 和减号 `-` 组成 -- 当前文档的图片放在当前目录的 images 目录下 -- 矢量图片可以通过 [drawio 离线版](https://github.com/jgraph/drawio-desktop/releases) 绘制(并同时提交源文件),以 200% 分辨率导出 png 格式图片 - -## 2. 使用文档内容的基本模式 - -每个使用文档可以看作是一个相对完整的分享或博客文章(参考手册不再此类)。使用文档遵循以下模式组织内容: - -1. 概览:本文希望解决什么问题,达到什么效果,可以先放最终效果截图 -1. 依赖的环境:需要安装什么工具,并给出相关链接 -1. 引入本文构建资源的关系图或架构图 - - 需要用到的 Konfig 模型,给出模型参考页面链接,以及对应的上游原始模型的文档链接 -1. 具体的操作步骤 - - 尽量确保最小化代码,甚至可以刻意隐藏一些干扰代码,同时给出完整代码对应的链接 - - 列出每个步骤命令的概要输出信息,并配以文字描述 -1. 给出测试方式 - - 尽量采用社区通用的方式(比如kube、curl命令、或浏览器)测试 - - 给出测试结果的截图(和开头呼应) -1. 总结和展望 - - 简单回顾当前操作的流程,以及一些可以展开的地方(可以给出一些链接) - -## 3. 测试和提交 PR - -先克隆文档仓库,本地通过 `npm run start` 和 `npm run build` 命令测试查看效果,确保可以正常浏览后提交 PR 即可。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/contribute/contribute.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/contribute/contribute.md deleted file mode 100644 index 692df6ab..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/contribute/contribute.md +++ /dev/null @@ -1 +0,0 @@ -# 贡献指南 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/contribute/git-guideline.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/contribute/git-guideline.md deleted file mode 100644 index c475057d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/contribute/git-guideline.md +++ /dev/null @@ -1,132 +0,0 @@ -# Git 提交指南 - -本文介绍了 Git 提交变更时需要注意的事项,如果拒绝接受本文的内容会导致提交的变更无法被接受。 - -## 1. 关于 issue - -在提交一个 issue 之前,请先查阅已经关闭的 issue ,也许在关闭的 issue 中已经存在合适的解决方案。 - -如果没有找到合适的方案,我们提供了4种模版在创建 issue 的时候使用。 - -- Bug Report : 发现了一个 Bug,可以通过 Bug Report 模版创建 issue 与我们联系。 -- Enhancement : 开发者对工具进行了增强,可以通过 Enhancement 模版创建 issue 来介绍增加的内容。 -- Feature Request : 在使用的过程中想要为工具增加某些新的特性或者功能,可以通过 Feature Request 模版创建 issue 来描述新特性。 -- Ask a Question : 如果有任何的疑问,可以通过 Ask a Question 模版来创建一个 issue 与我们联系。 - -在选择合适的模版后,只需要填写模版上的要求填写的内容即可。如果在创建 issue 的时候发现没有模版,或者模版内容为空,可以通过微信群,钉钉群或者邮件向我们反馈这个问题。 - -## 2. 关于 Git 分支 - -要向 kcl-lang 贡献代码,您必须拥有一个 GitHub 帐户,以便您可以将代码推送到您自己的分支并创建拉取请求。我们推荐参考 [Angular 规范](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines) 为您自己的分支命名。 -推荐的格式如下: - -``` -{type}-{a_short_description} -``` - -分支名称主要包括两个字段,并通过 “-” 分割。其中: - -- {type} : 当前分支内容的类型。 -- {a_short_description}: 一个简短的描述,介绍这个分支的主要内容。 - -e.g. 张三首先 Fork 仓库到自己账户下,然后创建对应名称 `zhangsan:fix-output-fmt-bug` 的分支(冒号之前是张三的账号),用于修复输出格式化 bug。 - -## 3. 关于 Git Commit - -我们参考 [Commitizen](https://github.com/commitizen/cz-cli) 书写 Commit Message。 - -``` -注: 如果直接使用 Commitizen 生成 Commit Message,需要注意因为 Commitizen -是开发人员管理 commit 的工具,与项目本身无关联,因此由 Commitizen 生成的中间产物 -(如: node_modules 文件目录)可能没有在项目 .gitignore 文件中。 - -您可以 git add {filename} 选择要提交的文件而忽视中间产物。 -或者您可以向 .gitignore 文件中添加如下内容而自动忽视中间产物: -# commitizen -package.json -package-lock.json -node_modules/* -``` - -如果手动编写 Commit Message,我们也建议采用 [Commitizen](https://github.com/commitizen/cz-cli) 的 commit message 格式。 - -``` -{type} ( {component_or_file} ) {a_short_description} - {a_longer_description} - BREAKING CHANGE: {breaking_change_description}. - {linked issue} -``` - -其中主要包括6个字段: - -- {type} : 当前 commit 对应的分支的类型。 -- {component_or_file}: 当前 commit 改动的模块或者文件的名称。 -- {a_short_description}: 简短的描述介绍 commit 中的内容。 -- {a_longer_description}: 详细的描述用来介绍 commit 中的内容。 -- {breaking_change_description}: 如果 commit 中包含破环兼容性的改动,需要对兼容性改动产生的影响进行介绍。 -- {linked issue}: 与当前这个 commit 关联的 issue。 - -其中 {breaking_change_description} 和 {linked issue} 如果 commit 中不包含破坏兼容性的改动和关联的 issue,可以省略。 - -e.g. 张三在分支 `zhangsan:fix-output-fmt-bug` 中创建的 commit。 - -``` - - fix(kcl-printer): fix an output format bug in kcl-printer - - There is an output format bug in kcl-printer because ..., - So, The calling of method "XXX" is replaced by "HHHH"..., - ... - - -- 如果没有破坏兼容性的改动和关联的 issue 可以省略下面内容。 - - BREAKING CHANGE: This change maybe cause ....... - - fix #123 - -``` - -## 4. 关于 pull request - -在提交一个 PR 之前,可能需要优先考虑以下几个问题: - -- 请先查阅已经关闭的 PR ,也许在已经关闭的 PR 中,可能存在已经完成的解决方案。 -- 我们建议在提交变更之前,提交一个对应的 issue 描述变更中将要解决的问题,并将变更对应的 PR 与 issue 关联。 -- 在向我们提交 PR 之后,请签署 [Contributor License Agreement (CLA)](#cla) ,如果拒绝签署,我们将无法接受 PR。 -- 请确保每次改动都创建了一个新的分支,并根据上文中提到的规范为分支命名。 -- 一次 PR 请不要超过两个 commit ,请将多余的 commit 通过 squash 压缩,并根据上文中提到的规范,编写 commit message 。 -- 我们提供了 [PR 模版](https://github.com/kcl-lang/.github/blob/main/.github/PULL_REQUEST_TEMPLATE.md),只需要添加模版中要求的内容即可,如果在创建PR时发现没有模版或者模版内容为空,可以通过微信群,钉钉群或者邮件向我们反馈这个问题。 - -我们建议PR的标题与分支名、commit message 风格保持一致: - -``` -{type} ( {component_name_or_file_name} ) :{a_short_description} -``` - -e.g. 张三为分支`fix/zhangsan/fix_output_fmt_bug`创建的PR名称。 - -``` -fix(kcl-printer): fix an output format bug in kcl-printer. -``` - -## 5. 目前 type 支持的类型 - -参考[Angular 规范](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines),type 支持类型的类型如下: - -``` -- feat: -- 添加了新的功能特性。 -- fix: -- 进行了 Bug 的修复。 -- docs: -- 进行了文档部分的修改。 -- style: -- 对代码格式的修改,并不影响代码的功能,如:删除多余空格,代码缩进等。 -- refactor: -- 在不改变代码功能的基础上对代码进行了的重构。 -- perf: -- 对代码进行了性能优化。 -- test: -- 添加或者调整已有的测试用例。 -- build: -- 对构建系统或者外部依赖库进行了调整。 -- ci: -- 调整了 CI 的配置文件或者脚本。 -- chore: -- 对源代码和测试文件之外其他部分的调整。 -- revert: -- 对 commit 进行回滚。 -``` - -## 6. Contributor License Agreement (CLA) - -在第一次向我们提交 PR 之后,在 PR 中的 CLA 检查将会失败并提示签署 CLA。您可以通过自己的账户之间在 PR 回复 "I have read the CLA Document and I hereby sign the CLA" 表示同意签署 CLA,然后手动重启失败的 CLA 检查 Action 即可。当 PR 被成功合并之后将会被锁定不能再修改。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/intro/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/intro/_category_.json deleted file mode 100644 index e4cb1869..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/intro/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "简介", - "position": 1 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/intro/intro.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/intro/intro.md deleted file mode 100644 index af94bc33..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/intro/intro.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 社区 - -欢迎来到 KCL 开源社区,每个人的参与都是所有开源项目健康成长的动力!有很多方法可以参与开源。每个人都可以通过提交PR(Pull Request)来创建问题或修复 bug、改进文档或修改代码, - -可以查看[社区](https://github.com/kcl-lang/community)并加入我们。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/intro/license.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/intro/license.md deleted file mode 100644 index fe1db435..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/intro/license.md +++ /dev/null @@ -1,211 +0,0 @@ ---- -sidebar_position: 99 ---- - -# 许可 - -KCL 使用 [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0): - -``` - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2023 The KCL Authors. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/intro/support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/intro/support.md deleted file mode 100644 index 70ecd7e8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/intro/support.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 寻求帮助 - -KCL拥有一个由众多爱好者组成的开发者和用户社区。在此页面上,我们列出了您可以参与的KCL相关社区;有关其他在线和离线学习材料,请参阅本节的其他页面。 - -在加入 KCL 社区之前,请阅读[贡献者条款](https://www.contributor-covenant.org/version/2/0/code_of_conduct/),所有社区成员都需要遵守这些条款。 - -## 讨论 - -- 在 Github 上提交问题 -- 在 Github 讨论组中交流 -- 通过官方网站、Github、Twitter、微信和其他帐户获取 KCL 最新状态。可以查看[社区](https://github.com/kcl-lang/community)并加入我们。 - -## 新功能 - -请尽量避免提交新功能的拉取请求,我们可能已经有人在处理这些功能,或者这个功能已经是我们未来计划的一部分。总之,请在提交新功能之前与我们联系! diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/release-policy/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/release-policy/_category_.json deleted file mode 100644 index bf01a053..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/release-policy/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "发布策略", - "position": 3 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/release-policy/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/release-policy/index.md deleted file mode 100644 index a4a0bc3d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/release-policy/index.md +++ /dev/null @@ -1 +0,0 @@ -# 发布策略 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/release-policy/kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/release-policy/kcl.md deleted file mode 100644 index 0f9115b8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/release-policy/kcl.md +++ /dev/null @@ -1,39 +0,0 @@ -# KCL 发布策略 - -KCL 开发团队采用 [语义化版本](https://semver.org/lang/zh-CN/) 来简化管理。版本格式:主版本号.次版本号.修订号。版本号递增规则如下:主版本号对应不兼容的 API 修改,次版本号对应向下兼容的功能性新增,修订号对应向下兼容的问题修正。总体目标是每一个半月发布一个特性增强的次要版本,根据需要不定期发布其他版本的修订。 - -KCL 项目版本发布策略如下: - -- 主版本号:当进行重大的架构调整或者加入重大的新功能时,需要提升主版本号。对于 KCL 项目来说,目前的主版本号为 0。 -- 次版本号:当添加的功能和特性有较大的变化时,提升次版本号。目前的次版本号为 5,2023 年度会相继发布 0.5, 0.6, 0.7 版本。 -- 修订号:通过修复漏洞或者改进性能来更新程序时,会提升修订号,修订号从 0 开始计数以此加 1。 -- 发布周期:在未达到 v1.0.0 版本之前,计划每隔 3 个月发布一个新的次要版本。在此期间,需要持续收集用户反馈,并进行必要的修复和改进。 -- 发布流程:在发布新版本之前,需要进行严格的测试和审核,确保新版本的质量。封板并测试完成后,会在 Github 上发布新版本的源代码,二进制和镜像,并提供详细的文档和使用指南。 -- 版本支持:我们将对最新的版本提供长期支持,包括漏洞修复和安全更新。对于旧版本,我们将提供有限的支持,仅在必要时进行修复。 - -## 发布流程与规则 - -- 特性开发:main 分支主干开发,分支发布,block 用户使用的问题和严重的 bug, 安全隐患,高优先级解决,尽可能保持在一周内收敛,高于一般的功能研发。 -- 迭代周期:我们的迭代周期通常为 3 个月,即每 3 个月发布一个新的次要版本。 -- 版本规划:发版前两周产出 alpha 版本,前一周产出 beta 版本,alpha 版本仍可进行特性合并,beta 版本只合并错误修复,最终产出正式版本并打 tag 作为长期保存的 release 分支。 -- 发版计划:在每个发布周期开始时制定详细的发版计划(Github Milestone),包括发布日期、版本号、功能列表和测试计划等。需要尽可能地遵守发版计划,确保按时发布新版本。 -- 发布前测试:在发布新版本之前,需要进行全面的测试,包括单元测试、集成测试,模糊测试,压测,用户验收测试等。只有经过测试并无问题后,我们才会发布新版本。 -- 版本回滚:如果在发布后发现了严重的问题,需要立即回滚版本,并尽快修复问题。并通过邮件、社交媒体等渠道及时通知用户,并提供解决方案。 -- 发布文档:需要在发布时提供详细的文档,包括发布说明、更新日志、API 文档和使用指南等,帮助用户了解和使用新版本。在 KCL 中,我们统一在 KCL 网站进行维护。 -- 版本兼容性:在发布新版本时,需要尽可能保持兼容性,以确保用户无需进行过多的修改和适应。KCL 还没有达到 v1,暂时没有兼容性保证。KCL 的目标是尽可能少地进行重大更改,不应轻率地考虑对语言的更改,为了语言自身更好地演进和发展,一般认为更改具有重大好处时才会进行(较好地解决了目标场景的问题或者提升了绝大用户的使用体验)。对于可能引入兼容性问题的功能或变更,提供相应的提示和解决方案,同时会提供逐步升级的指南或提供自动迁移的工具,以帮助用户平滑地迁移到新版本。 - -## 发布组件 - -![](/img/docs/community/release-policy/kcl-components.png) - -每次版本发布时,KCL 相关所有组件保持一个依赖同一个 KCL 核心主要版本,整体采用树形结构组织依赖顺序发布并进行回归测试,直到发布测试完成,尽力避免三角依赖,禁止循环依赖。 - -## 一个 Feature 的生命周期 - -- 设计方案/文档:通过 Issue 回答清楚这个 feature 的动机是什么,它解决什么问题以及目标是什么,用户需求和用户故事是怎样的;这个 feature 做什么,如何做,难度怎样,需要多长时间,依赖项,需要做什么测试等。(Tips: 大的设计尽量拆分成小的设计,通过权衡和广泛的调研找到一个简单且可持续的解决方案,并且具备一定得到可扩展以适应未来的业务或技术变化,通过持续讨论和方案评审确定最终设计)。 -- 编写代码:通过高频小改动进行迭代、持续沟通和协作,提前设计单元测试、集成测试和 benchmark 等测试用例,确保编写代码 100% 测试覆盖,注释完整和逻辑清晰,并通过 Demo 演示持续收集反馈。 -- 文档撰写:在 [KCL 网站](https://kcl-lang.io) 中更新用户文档。 -- 测试和反馈:在发布功能之前,让一些同行/用户通过**随循文档**而不是口述来尝试和测试这些新功能。接收反馈并改进。 -- 发布和公告:撰写 Release Note, PR 文章,场景和新特性解读等以及渠道宣发等。 - -> 注:以上所有信息全是公开的,需要透出给所有社区研发者进行参与、讨论和贡献。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/release-policy/roadmap.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/release-policy/roadmap.md deleted file mode 100644 index 2f0ee86a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/community/release-policy/roadmap.md +++ /dev/null @@ -1,3 +0,0 @@ -# 路线规划 - -![](/img/docs/community/release-policy/roadmap.jpg) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/_category_.json deleted file mode 100644 index 1910abe4..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "参考手册", - "position": 5 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/cheatsheets/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/cheatsheets/_category_.json deleted file mode 100644 index 7839b7a2..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/cheatsheets/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "备忘录", - "position": 10 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/cheatsheets/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/cheatsheets/index.md deleted file mode 100644 index 6bfb2e4c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/cheatsheets/index.md +++ /dev/null @@ -1,5 +0,0 @@ -# KCL 备忘录 - -![](/img/docs/reference/cheatsheets/cheatsheet.png) - -[Download PDF](https://github.com/kcl-lang/kcl-lang.io/blob/main/cheatsheet/cheatsheet.pdf) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/index.md deleted file mode 100644 index 9fd0c276..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/index.md +++ /dev/null @@ -1 +0,0 @@ -# 学习 KCL diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/_category_.json deleted file mode 100644 index 6066c82b..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KCL", - "position": 1 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/codelab/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/codelab/_category_.json deleted file mode 100644 index c0133443..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/codelab/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "代码实验室", - "position": 2 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/codelab/collaborative.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/codelab/collaborative.md deleted file mode 100644 index 883f4853..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/codelab/collaborative.md +++ /dev/null @@ -1,345 +0,0 @@ ---- -title: "使用配置操作分块编写配置" -linkTitle: "使用配置操作分块编写配置" -type: "docs" -weight: 2 -description: 使用配置操作分块编写配置 -sidebar_position: 3 ---- - -## 1. Introduction - -KCL 是一种简单易用的配置语言,用户可以简单地编写可重复使用的配置代码。 - -在这个教程中,我们将学习如何使用 KCL 配置操作(config operation)功能以协同的方式编写配置。 - -### 本节将会学习 - -1. 定义 schema 并组织项目目录。 -2. 通过KCL的配置操作功能创建多个环境配置。 -3. 配置编译参数和测试。 - -## 2. 定义 Schema 和 组织项目目录 - -### Schema 定义 - -假设我们想定义具有某些属性的服务器配置,我们可以通过创建一个 `server.k` 文件来创建一个简单的配置,我们可以填写以下代码来定义服务器配置的可重用模式: - -```python -import units - -type Unit = units.NumberMultiplier - -schema Server: - replicas: int = 1 - image: str - resource: Resource = {} - mainContainer: Main = {} - labels?: {str:str} - annotations?: {str:str} - -schema Main: - name: str = "main" - command?: [str] - args?: [str] - ports?: [Port] - -schema Resource: - cpu?: int = 1 - memory?: Unit = 1024Mi - disk?: Unit = 10Gi - -schema Port: - name?: str - protocol: "HTTP" | "TCP" - port: 80 | 443 - targetPort: int - - check: - targetPort > 1024, "targetPort must be larger than 1024" -``` - -在上面的代码中,我们定义了一个名为 Server 的 schema,该 schema 表示用户将要编写的配置类型,其中包含一些基本类型属性(例如`replicas`、`image` 等)和一些复合类型属性(例如 `resource`、`main` 等)。除了一些在 [schema codelab](./schema.md)中提到的基本类型之外,我们可以看到上面的代码中有两种类型 `Unit` 和 `units.NumberMultiplier`。其中,`units.NumberMultiplier` 表示 KCL 数字单位类型,意味着可以在 KCL 数字后添加自然单位或二进制单位,例如 `1K` 表示 `1000`,`1Ki` 表示 `1024`。 `Unit` 是 `units.NumberMultiplier` 的类型别名,用于简化类型注释的编写。 - -### 项目目录 - -为了完成协同的配置的开发,我们首先需要一个配置项目,其中包含测试应用程序的配置以及不同环境的差异化配置,因此我们正在创建以下项目目录: - -``` -. -├── appops -│ └── test_app -│ ├── base -│ │ └── base.k -│ ├── dev -│ │ ├── ci-test -│ │ │ └── stdout.golden.yaml -│ │ ├── kcl.yaml -│ │ └── main.k -│ └── prod -│ ├── ci-test -│ │ └── stdout.golden.yaml -│ ├── kcl.yaml -│ └── main.k -├── kcl.mod -└── pkg - └── sever.k -``` - -该项目目录主要包含三个部分: - -- `kcl.mod`:用于标识KCL项目的根目录的文件。 -- `pkg`:不同应用程序配置所共用的 `Server Schema` 结构。 -- `appops`:不同应用程序的 Server 配置,目前仅包含一个名为 `test_app` 的应用程序。 - - `base`:供所有环境使用的应用程序通用配置。 - - `dev`:供开发环境使用的应用程序配置。 - - `prod`:供生产环境使用的应用程序配置。 - -后续章节将会介绍`base.k`、`main.k`、`kcl.yaml` 和 `ci-test/stdout.golden.yaml` 的含义。 - -## 3. 通过 KCL 配置操作功能创建多个环境配置 - -### 创建基线配置 - -在组织好项目目录和基本的服务器配置模型之后,我们可以编写用户应用程序的配置。我们可以创建自己的测试应用程序文件夹 `test_app`,并将其放置在应用程序配置文件夹 `appops` 中。 - -对于应用程序的配置,我们通常将其分为基本配置和多个环境的差异化配置并进行合并。通过 KCL 的配置合并功能,我们可以轻松实现这一点。假设我们有开发环境和生产环境的两个配置,我们可以创建三个文件夹:`base`、`dev` 和 `prod` 分别存储基线、开发环境和生产环境的配置。首先,我们编写 `base/base.k` 的配置: - -```python -import pkg - -server: pkg.Server { - # 设置镜像的值为 "nginx:1.14.2" - image = "nginx:1.14.2" - # 添加 app label - labels.app = "test_app" - # 添加一个mainContainer配置,它的端口是 [{protocol = "HTTP", port = 80, targetPort = 1100}] - mainContainer.ports = [{ - protocol = "HTTP" - port = 80 - targetPort = 1100 - }] -} -``` - -正如上述代码中所示,我们使用 `import` 关键字在 `base.k` 中导入放置在 `pkg` 下的 `Server` schema,并使用它实例化一个名为`server` 的配置,在其中将 `image` 属性设置为 `"nginx:1.14.2"`,并添加一个带有值为 `test_app` 的标签 `app`。此外,我们还在 `ports` 属性中添加了主容器 `mainContainer` 的配置,其值为 `[{protocol = "HTTP", port = 80, targetPort = 1100}]`。 - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k -``` - -输出: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2 - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app -``` - -当前,我们已经有了一个基线配置。 - -### 创建多重环境配置 - -接下来我们将配置一个差异化的多环境配置。首先假设我们想在开发环境中使用自己的临时镜像 `nginx:1.14.2-dev`,然后使用它来覆盖基准中的服务器配置,我们可以在 `dev/main.k` 中编写以下配置: - -```python -import pkg - -server: pkg.Server { - # 覆盖 base 配置中的声明的镜像 - image = "nginx:1.14.2-dev" -} -``` - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -输出: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app -``` - -可以看出输出的 YAML 文件的 `image` 字段被覆盖为 `nginx:1.14.2-dev`。假设我们还想将一个具有键为 `env`,值为 `dev` 的标签添加到 `dev` 环境中,我们将以下代码添加到 `dev/main.k` 中: - -```python -import pkg - -server: pkg.Server { - # 覆盖 base 配置中的声明的镜像 - image = "nginx:1.14.2-dev" - # 将新标签 env 合并到 base 标签中 - labels.env = "dev" -} -``` - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app - env: dev -``` - -可以看到输出的 YAML 文件的 `labels` 字段中有两个标签。 - -此外,我们还可以使用 `+=` 运算符将新值添加到列表类型属性中,例如在基准环境中的 `mainContainer.ports` 配置,继续修改 `dev/main.k` 中的代码: - -```python -import pkg - -server: pkg.Server { - # 覆盖 base 配置中的声明的镜像 - image = "nginx:1.14.2-dev" - # 将新标签 env 合并到 base 标签中 - labels.env = "dev" - # 在 base ports配置中添加一个 port - mainContainer.ports += [{ - protocol = "TCP" - port = 443 - targetPort = 1100 - }] -} -``` - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -输出: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - - protocol: TCP - port: 443 - targetPort: 1100 - labels: - app: test_app - env: dev -``` - -使用相同的方法,我们可以构建生产配置,在 `dev/main.k` 文件中编写代码,并为其添加标签。 - -```python -import pkg - -server: pkg.Server { - # 将新标签 env 合并到 base 标签中 - labels.env = "prod" -} -``` - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k appops/test_app/prod/main.k -``` - -输出: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2 - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app - env: prod -``` - -## 4. 配置编译参数和测试 - -在前面的章节中,我们通过代码构建了一个多环境配置。可以看出不同环境的 KCL 命令行编译参数相似,因此我们可以将这些编译参数配置到一个文件中,并将其输入到 KCL 命令行中进行调用。请将以下代码配置在 `dev/kcl.yaml`中: - -```yaml -kcl_cli_configs: - files: - - ../base/base.k - - main.k - output: ./ci-test/stdout.golden.yaml -``` - -然后我们可以使用以下命令在开发环境中编译配置: - -```bash -cd appops/test_app/dev && kcl -Y ./kcl.yaml -``` - -此外,我们已经在 `dev/kcl.yaml` 中配置了 `output` 字段,以将 YAML 输出到文件,以便进行后续配置分发或测试。您可以通过遍历每个环境中的 `kcl.yaml` 构建,并将其与 `./ci-test/stdout.golden.yaml` 进行比较,可以验证应用程序的配置是否符合预期。 - -## 5. 最后 - -恭喜! - -我们已经完成了关于 KCL 的第三课。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/codelab/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/codelab/index.md deleted file mode 100644 index 123c0878..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/codelab/index.md +++ /dev/null @@ -1 +0,0 @@ -# 代码实验室 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/codelab/schema.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/codelab/schema.md deleted file mode 100644 index 434e1f5c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/codelab/schema.md +++ /dev/null @@ -1,814 +0,0 @@ ---- -title: "使用 KCL Schema 编写复杂配置" -linkTitle: "使用 KCL Schema 编写复杂配置" -type: "docs" -weight: 2 -description: 使用 KCL Schema 编写复杂配置 -sidebar_position: 2 ---- - -## 1. 介绍 - -KCL 是一种简单易用的配置语言,用户可以简单地编写可重用的配置代码。 - -在本节教程中,我们将学习如何使用 KCL 编写定制配置,这样我们就可以定义一个架构并以协作方式编写配置。 - -### 本节将会学习 - -1. 定义一个简单的 schema -2. 为 schema 字段设置默认的不可变值 -3. 基于简单的 schema 创建配置 -4. 在 schema 中编写复杂的逻辑 -5. 通过 schema 的组合创建新的 schema -6. 使用 dict/map 创建具有深度嵌套 schema 的配置 -7. 通过 schema 继承创建新的 schema -8. 通过多个 mixin schema 创建新的 schema -9. 声明 schema 验证规则 -10. 配置 schema 的输出布局 -11. 共享和重用 schema - -## 2. 编写简单的 Schema - -假设我们希望定义一个具有特定属性的工作负载,我们可以通过创建一个 `my_config.k` 文件来创建一个简单的配置。我们可以按以下方式填写下面的代码,定义一个可重复使用的部署配置的 schema: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels: {str:str} -``` - -在上述代码中,`cpu` 和 `memory` 被定义为 int 值;`name`、`image` 和 `service` 是字符串;`command` 是由字符串构成的列表;`labels` 是字典类型,其键和值的类型均为字符串。 - -另外,每个属性都**必须**被赋予非 None 值作为 schema 实例,除非它被标记问号 **?** 而作为可选参数。 - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels?: {str:str} # labels 是一个可选的参数 -``` - -当存在继承关系时: - -- 如果在基 schema 中该属性为可选(optional)参数,则在子 schema 中它应该是可选的(optional)或必需的(required)。 -- 如果在基 schema 中该属性为必需(required)属性,则在子 schema 中它需要是必需的(required)。 - -## 3. Enhance Schema as Needed - -Suppose we need to set default values to service and replica, we can make them as below: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str = "my-service" # defaulting - replica: int = 1 # defaulting - command: [str] - labels?: {str:str} # labels is an optional attribute -``` - -And then we can set the service type annotation as the string literal type to make it immutable: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: "my-service" = "my-service" - replica: int = 1 - command: [str] - labels?: {str:str} -``` - -In the schema, type hint is a `must`, for example we can define cpu as `cpu: int`. - -Specially, we can define a string-interface dict as `{str:}`, and in case we want to define an object or interface, just define as `{:}`. - -## 4. 基于简单 Schema 创建配置 - -现在我们有了一个简单的 schema 定义,我们可以用它来定义配置: - -```python -nginx = Deployment { - name = "my-nginx" - cpu = 256 - memory = 512 - image = "nginx:1.14.2" - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python - kcl my_config.k -``` - -标准输出: - -```yaml -nginx: - name: my-nginx - cpu: 256 - memory: 512 - image: nginx:1.14.2 - service: my-service - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -> 有关集合数据类型和块的更多详细信息,请查看手册和规范。 - -此外,**配置选择器表达式**(config selector expressions)可以用于初始化 schema 实例,我们可以忽略配置表达式中行末的逗号。 - -```python -nginx = Deployment { - name = "my-nginx" - cpu = 256 - memory = 512 - image = "nginx:1.14.2" - command = ["nginx"] # 忽略行尾的逗号 - labels.run = "my-nginx" # schema 中的字典变量可以使用选择器表达式 - labels.env = "pre-prod" # schema 中的字典变量可以使用选择器表达式 -} -``` - -## 5. 在 Schema 中编写更为复杂的逻辑 - -假设我们有一些schema逻辑,我们可以将它包装进 schema 中: - -```python -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - image: str - service: "my-service" = "my-service" - replica: int = 1 - command: [str] - labels?: {str:str} - - _cpu = 2048 - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 -``` - -现在,我们可以通过创建 schema 实例来定义配置,并将优先级作为参数传递给模式: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl my_config.k -``` - -标准输出: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - image: nginx:1.14.2 - service: my-service - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 6. 通过 Schema 组合创建新 Schema - -现在我们想要定义一个详细的 schema,包括服务(service)和卷(volumes),我们可以按以下方式进行操作: - -```python -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - volumes?: [Volume] - image: str - service?: Service - replica: int = 1 - command: [str] - labels?: {str:str} - - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 - -schema Port: - name: str - protocol: str - port: int - targetPort: int - -schema Service: - name: "my-service" = "my-service" - ports: [Port] - -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -在这种情况下,Deployment 由 Service 和一系列 Volume 组成,而 Service 又由一系列 Port 组成。 - -## 7. 使用 dict/map 创建具有深度嵌套 schema 的配置 - -现在我们有一个新的 Deployment schema,但我们可能会注意到,它包含多层嵌套的结构,在复杂的结构定义中,这是非常常见的,我们通常必须编写命令式组装代码来生成最终结构。 - -使用 KCL,我们可以使用简单的字典声明创建配置,并具有完整的 schema 初始化和验证功能。例如,我们可以按照以下方式使用新的 Deployment schema简单地配置 nginx: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl my_config.k -``` - -标准输出: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -请注意,我们用于定义 Deployment 配置的字典必须与 schema 定义对齐,否则我们将会得到一个错误。例如,假设我们将服务端口的类型定义错误如下: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = [80] # 错误的数据类型,试图将 List 分配给 int - targetPort = 9376 - }] -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl my_config.k -``` - -标准错误输出: - -``` -The type got is inconsistent with the type expected: expect int, got [int(80)] -``` - -## 8. 声明 Schema 验证规则 - -现在我们已经看到了一个复杂的 schema,在其中每个字段都有一个类型提示,以使其更加不容错(error-prone)。 - -但是这还不够好,我们希望为我们的 schema 支持更多的增强验证,以便尽快发现 schema 和配置中的代码错误。许多验证规则,如 None 类型检查、范围检查、值检查、长度检查、正则表达式匹配、枚举检查已经被添加或陆续添加进来。以下是一段代码示例: - -```python -import regex - -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - volumes?: [Volume] - image: str - service?: Service - replica: int = 1 - command: [str] - labels?: {str:str} - - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 - - check: - multiplyof(cpu, 256), "cpu must be a multiplier of 256" - regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$"), "image name should be like 'nginx:1.14.2'" - 1 <= replica < 100, "replica should be in range (1, 100)" - len(labels) >= 2 if labels, "the length of labels should be large or equal to 2" - "env" in labels, "'env' must be in labels" - len(command) > 0, "the command list should be non-empty" - -schema Port: - name: str - protocol: str - port: int - targetPort: int - - check: - port in [80, 443], "we can only expose 80 and 443 port" - protocol in ["HTTP", "TCP"], "protocol must be either HTTP or TCP" - 1024 < targetPort, "targetPort must be larger than 1024" - -schema Service: - name: "my-service" = "my-service" - ports: [Port] - - check: - len(ports) > 0, "ports list must be non-empty" - -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -由于schema定义的属性默认是**必需的**(required),因此可以省略判断变量不能为 None/Undefined 的验证。 - -```python -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -现在我们可以基于新的 schema 编写配置,并及时暴露配置错误。例如,使用以下无效的配置: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1142" # 镜像值不匹配正则表达式 - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -每个字段都是类型有效的,但镜像名无效。 - -运行 KCL,我们将看到如下错误信息: - -KCL 命令: - -```python -kcl my_config.k -``` - -标准错误输出: - -``` -Schema check is failed to check condition: regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$"), "image name should be like 'nginx:1.14.2'" -``` - -> KCL 的验证功能涵盖了 Openapi 定义的验证,因此我们可以通过 KCL 编写任何 API 验证。 - -## 9. 通过 Schema 继承创建新 Schema - -现在,我们拥有了一个稳定的部署 schema 定义,可以用它来声明配置。 - -通常,部署 schema 将被用于多个场景中。我们可以直接使用 schema 在不同的用例中声明配置(见上文的部分),或者我们可以通过继承生成一个更具体的 schema 定义。 - -例如,我们可以使用部署 schema 作为基础,来定义 nginx 的基本 schema,并在每个场景中扩展定义。在这种情况下,我们定义了一些常用的属性。请注意,我们使用“final”关键字将名称标记为不可变,以防止被覆盖。 - -```python -schema Nginx(Deployment): - """ A base nginx schema """ - name: "my-nginx" = "my-nginx" - image: str = "nginx:1.14.2" - replica: int = 3 - command: [str] = ["nginx"] - -schema NginxProd(Nginx): - """ A prod nginx schema with stable configurations """ - volumes: [Volume] = [{ - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - """ A volume mapped to host path """ - service: Service = { - ports = [{ - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] - } - """ An 80 port to target backend server """ -``` - -现在我们有了一些 nginx 的静态配置。建议将我们认为是静态的配置声明在那里,并将更多的动态配置放在下面: - -```python -nginx = Nginx { - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -```python -nginx = NginxProd { - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -现在,我们只需要通过运行时标签值 “prod” 来简单定义 不那么静态的 nginx 生产环境配置。 - -实际上,在某些复杂情况下,我们可以将所有配置分为基本配置、业务配置和环境配置定义,并基于此实现团队成员之间的协作。 - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl prod_config.k -``` - -标准输出: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 3 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 10. Create New Schema by Multiple Protocol and Mixin Schemas Inheritance - -现在,我们可以通过 Deployment schema 完成服务器配置的声明。 - -然而,通常实际情况更为复杂,部署可能有各种可选变量附件。 - -例如,我们想要在现有 schema 中支持声明持久卷,作为可重用的 Kubernetes schema。在这种情况下,我们可以通过以下 `mixin` 和 `protocal` 进行包装: - -```python -import k8spkg.api.core.v1 - -protocol PVCProtocol: - pvc?: {str:} - -mixin PersistentVolumeClaimMixin for PVCProtocol: - """ - PersistentVolumeClaim (PVC) sample: - Link: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims - """ - - # Mix in a new attribute `kubernetesPVC` - kubernetesPVC?: v1.PersistentVolumeClaim - - if pvc: - kubernetesPVC = v1.PersistentVolumeClaim { - metadata.name = pvc.name - metadata.labels = pvc.labels - spec = { - accessModes = pvc.accessModes - resources = pvc.resources - storageClassName = pvc.storageClassName - } - } -``` - -有了 PersistentVolumeClaimMixin,我们使用清晰的用户界面(user interface)定义了一个 PVC schema,并使用 Kubernetes PVC 作为实现。然后,我们可以使用 Deployment schema 和 PVC mixin schema 定义一个 server schema。 - -```python -schema Server(Deployment): - mixin [PersistentVolumeClaimMixin] - pvc?: {str:} - """ pvc user interface data defined by PersistentVolumeClaimMixin """ -``` - -在 Server schema 中,Deployment schema 是基础 schema,而 PersistentVolumeClaimMixin 是一个可选附加项,其用户界面数据为`pvc?:{str:}`。 - -请注意,mixin 通常用于向宿主 schema 添加新属性,或修改宿主 schema 的现有属性。因此,mixin 可以使用宿主 schema 中的属性。由于其被设计为可重用,因此我们需要一个额外的协议来限制 mixin 中宿主 schema 中属性的名称和类型。 - -现在,如果我们想要使用 PVC 进行部署,只需声明用户界面: - -```python -server = Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] - pvc = { - name = "my_pvc" - accessModes = ["ReadWriteOnce"] - resources.requests.storage = "8Gi" - storageClassName = "slow" - } -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl server.k -``` - -标准输出: - -```yaml -server: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod - pvc: - name: my_pvc - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 8Gi - storageClassName: slow ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: my_pvc -spec: - accessModes: - - ReadWriteOnce - storageClassName: slow - resources: - requests: - storage: 8Gi -``` - -如果我们不需要持久卷,只需删除 pvc 配置块。 - -## 11. 共享和重用 Schema - -可以通过导入来共享 Server schema,我们只需要将代码与 KCL 一起打包即可。 - -```python -import pkg - -server = pkg.Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -另一个关于共享代码的技巧是:在同一包下的模块不需要相互导入。 - -假设我们在 pkg 中有如下 models: - -``` -pkg/ - - deploy.k - - server.k - - pvc.k -``` - -在 `server.k` 中,我们可以只使用 `deploy.k` 中的 Deployment schema 和 `pvc.k` 中的 pvc schema 而无需导入: - -```python -# 无需 import -schema Server(Deployment): - mixin [PersistentVolumeClaimMixin] - pvc?: {str:} - """ pvc user interface data defined by PersistentVolumeClaimMixin """ -``` - -然后用户必须导入 pkg 才能作为一个整体使用它: - -```python -import pkg - -server = pkg.Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [pkg.Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } - service.ports = [pkg.Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -运行 KCL 命令: - -```python -kcl pkg_server.k -``` - -Output: - -```yaml -server: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 12. 最后 - -恭喜! - -我们已经完成了 KCL 的第二节课。我们使用 KCL 来替换我们的 key-value 文本文件,以便获得更好的可编程性。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/codelab/simple.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/codelab/simple.md deleted file mode 100644 index 32ad2612..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/codelab/simple.md +++ /dev/null @@ -1,495 +0,0 @@ ---- -title: "使用 KCL 编写简单配置" -linkTitle: "使用 KCL 编写简单配置" -type: "docs" -weight: 2 -description: 使用 KCL 编写简单配置 -sidebar_position: 1 ---- - -## 1. 介绍 - -KCL 是一种简单易用的配置语言,用户可以简单地编写可重用的配置代码。 - -在这个第一个教程中,我们将学习如何使用 KCL 编写一个简单的配置。 - -学习这个代码实验只需要基本的编程知识,如果你有 Python 经验,将会更容易上手。 - -### 本节将会学习 - -1. 用一种可编程的方式编写简单的 key-value 配置 -2. 使用 KCL 编写简单的逻辑 -3. 使用 KCL 编写集合(collections) -4. 使用 KCL 代码进行测试和调试 -5. 在 KCL 代码中使用内置(built-in)支持 -6. 共享和重用 KCL 代码 -7. 使用动态输入参数编写配置 - -## 2. 编写Key-Value键值对 - -通过创建 `my_config.k` 来生成一个简单的配置,我们可以填充下面的代码,并且不需要严格的格式描述部署的配置。 - -```python -cpu = 256 -memory = 512 -image = "nginx:1.14.2" -service = "my-service" -``` - -在上述代码中,cpu 和 memory 被声明为 int 类型的值,而 image 和 service 被声明为字符串字面值。 - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -KCL 命令: - -```bash -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -可导出变量(exported variable)默认情况下是不可变的,一旦声明,就不能在其他地方修改它。 - -## 3. 编写简单逻辑 - -有时候我们想在配置中编写一些逻辑,那么我们就可以使用: - -- 以 `_` 开头的非导出可变变量(mutable and non-exported variable) -- if-else 语句 - -非导出变量表示它不会出现在输出的 YAML 中,且它可以被多次赋值。 - -这是一个示例,显示如何根据条件调整资源。 - -KCL 命令: - -```python -kcl my_config.k -``` - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -image = "nginx:1.14.2" -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -```python -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -.. 注意:: -KCL 对运算符和字符串成员函数有丰富的支持,请阅读手册和规范以了解更多细节。 - -## 4. 编写集合 - -我们可以使用集合来表示复杂的数据类型。已支持的集合类型有: - -- list -- dict - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -command = ["nginx"] # 列表 -labels = {run = "my-nginx"} # a dict -image = "nginx:1.14.2" -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -KCL 命令: - -```bash -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx -image: nginx:1.14.2 -service: my-service -``` - -> 有关集合数据类型和成员函数的更多信息,请查阅手册和规范。 - -## 5. 在集合中添加元素 - -我们可以将逻辑表达式、推导式、切片、联合类型等特性组合起来,动态地将元素添加到集合中。 - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 -_env = "pre-prod" - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -_command = ["nginx"] # 列表 -_command = _command + ["-f", "file"] # 使用 + 运算符将元素附加到命令中以连接两个列表 -command = [c.lower() for c in _command] # # 将列表中的每个元素转为小写 -_labels = { - run = "my-nginx" - if _env: - env = _env # 当 _env 不是 None/Undefined 或为空时使用 if 表达式添加一个字典键值对 -} # 字典 -labels = _labels -image = "nginx:1.14.2" -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -```python -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 256 -memory: 512 -command: - - nginx - - -f - - file -labels: - run: my-nginx -image: nginx:1.14.2 -service: my-service -``` - -## 6. 编写断言 - -为了使代码可测试且健壮,我们可以使用断言(assertions)验证配置数据。 - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -command = ["nginx"] # 列表 -labels = {run = "my-nginx"} # 字典 -image = "nginx:1.14.2" -service = "my-service" -assert "env" in labels, "env label is a must" -assert cpu >= 256, "cpu cannot be less than 256" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -```bash -kcl my_config.k -``` - -标准错误输出: - -```bash -Assertion failure: env label is a must. -``` - -将 env:pre-prod 对添加到标签中后,我们将得到如下输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 7. 使用方便的内置支持 - -更重要的是,我们可以使用内置函数来帮助我们调试或简化编码。 - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -_name = "nginx" -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # 列表 -labels = { - run = "my-{}".format(_name) - env = "pre-prod" -} # a dict -image = "{}:1.14.2".format(_name) # 字符串格式 -service = "my-service" - -# debugging -print(labels) # 通过打印调式 - -# test -assert len(labels) > 0, "labels can't be empty" # 使用 len() 得到列表长度 -assert "env" in labels, "env label is a must" -assert cpu >= 256, "cpu cannot be less than 256" -``` - -此示例展示了我们如何使用 `format()`、`len()`、`print()` 函数来帮助自定义配置。 - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -KCL 命令: - -```bash -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -run: my-nginx -env: pre-prod -``` - -注意:更多的内置函数和模块可以在 spec/module 目录中查看。 - -## 8. 重用另一个模块的变量 - -为了使我们的代码得到良好的组织,我们可以将代码简单地分为 `my_config.k` 和 `my_config_test.k` 两个文件。 - -在 `my_config.k` 中定义配置数据: - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 -_name = "nginx" - -# 可导出变量 -cpu = _cpu -memory = _cpu * 2 -command = [_name] # 列表 -labels = { - run = "my-{}".format(_name) - env = "pre-prod" -} # a dict -image = "{}:1.14.2".format(_name) # 字符串格式 -service = "my-service" -``` - -而测试代码定义在 `my_config_test.k` 中,我们可以在其中导入 `my_config.k`: - -```python -import my_config - -# debugging -print(my_config.labels) # 通过打印调试 - -# test -assert len(my_config.labels) > 0, "labels can't be empty" # 使用 len() 得到列表长度 -assert "env" in my_config.labels, "env label is a must" -assert my_config.cpu >= 256, "cpu cannot be less than256" -``` - -## 9. 配置输入参数 - -有时我们需要获得通过从最终用户或平台动态获取的外部输入参数。 - -在这种情况下,我们可以按需传递 `priority` 和 `env` 参数: - -- 通过参数传递: `-D priority=1 -D env=pre-prod` -- 可以在 KCL 代码中使用 `option` 关键字获取这些值 - -```python -_priority = option("priority") # 非导出可变变量 -_env = option("env") # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -_name = "nginx" -# 可导出变量 -cpu = _cpu -memory = _cpu * 2 -command = [_name] # 列表 -labels = { - run = "my-{}".format(_name) - env = _env -} # a dict -image = "{}:1.14.2".format(_name) # 字符串格式 -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -```bash -kcl my_config.k -D priority=2 -D env=pre-prod -``` - -标准输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 10. 使用 Dict 简化逻辑表达式 - -当我们需要编写复杂的逻辑时,可以使用dict来简化逻辑的编写。 - -```python -_priority = option("priority") # 非导出可变变量 -_env = option("env") # 非导出可变变量 -_priorityCpuMap = { - "1" = 256 - "2" = 512 - "3" = 1024 -} -# 使用字典简化逻辑,默认值为2048 -_cpu = _priorityCpuMap[_priority] or 2048 -_name = "nginx" -# 可导出变量 -cpu = _cpu -memory = _cpu * 2 -command = [_name] # 列表 -labels = { - run = "my-{}".format(_name) - env = _env -} # a dict -image = "{}:1.14.2".format(_name) # 字符串格式 -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -KCL 命令: - -```bash -kcl my_config.k -D priority=2 -D env=pre-prod -``` - -标准输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 11. 最后 - -恭喜! - -我们已经完成了关于 KCL 的第一课程,我们使用 KCL 来替换我们的键值文本文件,以获得更好的编程支持。 - -建议立即查看架构代码实验,以了解如何使用 KCL `schema` 机制协作编写高级配置。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/error/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/error/_category_.json deleted file mode 100644 index 4f285ced..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/error/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "错误与警告", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/error/_error.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/error/_error.md deleted file mode 100644 index a2f192b8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/error/_error.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: "错误检查" -linkTitle: "错误检查" -type: "docs" -weight: 1 -description: KCL 语言规范 ---- - -When errors happen, developers should be able to detect the error and abort -execution. Thus, KCL introduce the `assert` syntax. - -In the previous topic of `schema` syntax. Errors can also be raised when a -schema is violated. - -## Syntax - -The syntax of the `assert` statement is the following. - -``` -assert_stmt: 'assert' test [',' test] -``` - -In the basic form, an `assert` statement evaluates an expression. If the -expression is evaluated to `False`, the assertion is failed, and an error -should be reported. - -In the extended form, an error message can be provided. The error message is -another expression. It is only evaluated when the expression to be evaluated -is evaluated to `False`. The evaluation result of the error message is printed -when reporting the error. - -The following is an example: - -```py -a = 1 -b = 3 -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -``` - -## The Implementation - -When an error happens, no matter it is caused by the `assert` or the `schema` syntax, -the virtual machine should exit with an exit code greater than `0`. - -The virtual machine may choose to dump the back trace information, and it is strongly -recommended to implement it. - -In practice, KCL can dump back trace by default, and an argument can be introduced -to disable it. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/error/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/error/index.md deleted file mode 100644 index e4f702ec..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/error/index.md +++ /dev/null @@ -1 +0,0 @@ -# 错误与警告 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/index.md deleted file mode 100644 index 66fd3dde..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/index.md +++ /dev/null @@ -1 +0,0 @@ -# KCL diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/_category_.json deleted file mode 100644 index c088e386..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "规范", - "position": 3 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/codestyle.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/codestyle.md deleted file mode 100644 index dd40925e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/codestyle.md +++ /dev/null @@ -1,608 +0,0 @@ ---- -title: "Code Style" -linkTitle: "Code Style" -type: "docs" -weight: 2 -description: Code Style ---- - -## Introduction - -This document gives the KCL code style conventions. Good code style can play a vital role in the development and maintenance of the project. We can learn the KCL code style by referring to the full text of the description and sample codes, and use KCL format and lint tools to help coding. - -## Source File Encoding - -KCL file encoding should always use **UTF-8**. - -## Code Layout - -### Indentation - -Use **4 spaces** per indentation level such as in the schema statement and if statement. - -```python -schema PersonA: - name: str # non-recommended - age: int - -schema PersonB: - name: str # recommended - age: int - -if True: - a = 1 # recommended -elif True: - b = 2 # non-recommended -else: - c = 3 # non-recommended -``` - -The closing brace/bracket/parenthesis on multiline constructs should line up under **first character** of the line that starts the multiline construct, as in: - -```python -# valid and recommended -my_list = [ - 1, 2, 3, - 4, 5, 6, -] -``` - -```python -# invalid -my_list = [ - 1, 2, 3, - 4, 5, 6, - ] -``` - -### Tabs or Spaces - -- Spaces are the preferred indentation method. -- Tabs should be used solely to remain consistent with code that is already indented with tabs. - -KCL disallows mixing the use of tabs and spaces for indentation and an error will be reported during the compile time. - -### Blank Lines - -- Surround top-level schema definitions with one blank line. -- Keep at most one blank line between two statements and remove redundant blank lines. -- Remove extra blank characters at the end of the line -- Remove extra blank characters in a blank line. -- There is no blank line in the header of the file, start writing from the first line. -- Only one blank line will be left at the end of the KCL file. - -```python -# Remove blank lines in the file header -a = 1 # Remove white space at the end of the line -# Keep at most one blank line between two statements - -b = 2 -# Only leave one blank line at the end of the file - -``` - -### Inline Expressions - -Write indentation of KCL `if`, `elif`, `else` and other conditions on different lines. - -```python -if True: print("") # non-recommended - -if True: # recommended - print("") -``` - -### Line Break and Continuation lines - -- For long expressions, use the line continuation symbol `\` and keep the left end of multiple expressions aligned. -- The 4-space rule is optional for continuation lines. - -```python -anotherString = "Too long expression " + \ - "Too long expression " # non-recommended - -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " # recommended -``` - -### When to Use Trailing Commas - -- Always use trailing commas. - -### Maximum Line Length - -- The general recommendation is **80 characters** but not absolute. - -### Symbol Break White Space - -Try to keep the spaces between different symbols, but not too many, usually one is good. - -```python -a = 1 # recommended -b = 1 + 2 # non-recommended -``` - -### Whitespace in Expressions and Statements - -Avoid extraneous whitespace in the following situations: - -- The parentheses `()`, brackets `[]` and braces `{}` in the expression have no spaces inside. - -```python -a = (1 + 2) # recommended -b = ( 1 + 2 ) # non-recommended - -c = [1, 2, 3] # recommended -d = [ 1, 2, 3 ] # non-recommended - -e = {key = "value"} # recommended -f = { key = "value" } # non-recommended -``` - -```python -spam(ham[1], {eggs = 2}) # recommended -spam( ham[ 1 ], { eggs = 2 } ) # non-recommended -``` - -- Between a trailing comma and a following close parenthesis. - -```python -foo = [0,] # recommended -bar = [0, ] # non-recommended -``` - -- Immediately before the open parenthesis that starts the argument list of a function call. - -```python -print(1) # recommended -print (1) # non-recommended -``` - -- Immediately before the open parenthesis that starts indexing or slicing. - -```python -dct = {key = "value"} -lst = [1, 2, 3] - -a = dct['key'] # recommended -b = dct ['key'] # non-recommended - -c = lst[0] # recommended -d = lst [1] # non-recommended -``` - -- More than one space around an assignment `=` (or other) operator to align it with another. - -```python -# recommended: -x = 1 -y = 2 -long_variable = 3 -``` - -```python -# non-recommended: -x = 1 -y = 2 -long_variable = 3 -``` - -- Always surround these binary operators with a single space on either side: assignment (`=`), augmented assignment (`+=`, `-=`, etc.), comparisons (`==`, `<`, `>`, `!=`, `<=`, `>=`, `in`, `not in`, `is`, `is not`), booleans (`and`, `or`, `not`). - -```python -# recommended: -i = i + 1 -submitted += 1 -x = x * 2 - 1 -hypot2 = x * x + y * y -c = (a + b) * (a - b) -``` - -```python -# non-recommended: -i = i+1 -submitted+=1 -x = x*2 - 1 -hypot2 = x*x + y*y -c = (a+b) * (a-b) -``` - -- Break one blank line between different statements e.g., import, schema and expression statements. - -```python -import math -import net - -schema Person: - name: str - -person = Person { - name = "Alice" -} -``` - -- Compound statements (multiple statements on the same line) are generally discouraged - -```python -# recommended: -if foo == 'blah': - do_blah_thing() -do_one() -do_two() -do_three() -``` - -```python -# non-recommended: -if foo == 'blah': do_blah_thing() -do_one(); do_two(); do_three() -``` - -## Naming Conventions - -### Naming Styles - -The following naming styles are commonly distinguished: - -- `b` (single lowercase letter) -- `B` (single uppercase letter) -- `lowercase` -- `lower_case_with_underscores` -- `UPPERCASE` -- `UPPER_CASE_WITH_UNDERSCORES` -- `CapitalizedWords` (capitalize all letters of the acronym in `CapitalizedWords` e.g., `HTTPServer`.) -- `mixedCase` (differs from `CapitalizedWords` by initial lowercase character) -- `Capitalized_Words_With_Underscores` (ugly and non-recommended) - -### Names to Avoid - -Never use the characters 'l' (lowercase letter el), 'O' (uppercase letter oh), or 'I' (uppercase letter eye) as single-character variable names. - -### Package and Module Names - -Package and module names should have short, all-lowercase names. - -### Schema Names - -Schema names should normally use the `CapWords` convention. - -### Constants - -Constants are usually defined on a module level and written in all capital letters with underscores separating words such as `MAX_OVERFLOW` and `TOTAL`. - -## Import - -- Imports should usually be on separate lines. -- Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants. -- Imports should be grouped in the following order and we should put a blank line between each group of imports. - 1. Standard library imports. - 2. Related third party plugin imports. - 3. Local application/library specific imports. -- Use an alias when we import a package name with a relatively long path. -- Leave only one space between the Import keyword and the package name. - -```python -import net # recommended -import math # non-recommended - -import ..pkg.internal_pkg as alias_pkg # recommended -``` - -## Comments - -- Comments should be complete sentences. The first word should be capitalized unless it is an identifier that begins with a lower-case letter (never alter the case of identifiers!). -- Block comments generally consist of one or more paragraphs built out of complete sentences, with each sentence ending in a period. -- Use two spaces after a sentence-ending period in multi-sentence comments, except after the final sentence. - -### Block Comments - -Block comments generally apply to some (or all) code that follows them, and are indented to the same level as that code. Each line of a block comment starts with a `#` and **a single space**(unless it is indented text inside the comment). - -Paragraphs inside a block comment are separated by a line containing a single `#`. - -```python -# This is a block comment -a = 1 -``` - -### Inline Comments - -Use inline comments sparingly. - -An inline comment is a comment on the same line as a statement. Inline comments should be separated by **at least two spaces** from the statement. They should start with a `#` and **a single space**. - -```python -a = 1 # This is an inline comment -``` - -### Documentation Strings - -Write doc strings for all public schema and schema attributes. - -```python -schema Person: - """ - Person schema doc string - """ - - name: str = "Alice" -``` - -## String - -- Single-quoted strings and double-quoted strings are the same in KCL. -- Use double-quoted string with lowercase prefix -- For triple-quoted strings, always use double quote characters to be consistent with the docstring convention. -- When a string contains single or double quote characters, use the other one to avoid backslashes in the string. - -```python -strC = "'123'" # recommended -strD = "\"123\"" # non-recommended -``` - -## Number - -- Use lowercase for the prefix of non-decimal numbers, and use uppercase for the number itself. - -```python -foo = 0xAB # recommended -bar = 0Xab # non-recommended -``` - -## Operators - -### Binary Operators - -- Leave only one space before and after the assignment `=`. -- Leave only one space before and after the binary operator in the expression. - -```python -a = 1 # recommended -b=2 # non-recommended -c= 3 # non-recommended -d =4 # non-recommended - -_value = (1 + 2 * 3) # recommended -_value = (1+2*3) # non-recommended -``` - -### Unary Operators - -- There is only no space after unary operators e.g., `~`, `+` and `-`. - -```python -_value = 1 + -2 * ~3 # recommended -_value = 1+ - 2 * ~ 3 # non-recommended -``` - -- There is no space after `**` and `*` in the dict/list deduction expressions and argument expressions. - -```python -_list = [1, 2, 3] -_list = [*_list, [4, 5 ,6]] # recommended -_list = [* _list, [4, 5 ,6]] # non-recommended - -_dict = {**{k = "v"}, **{k = "v"}} # recommended -_dict = {** {k = "v"}, ** {k = "v"}} # non-recommended -``` - -- Use `is not` operator rather than `not ... is`. - -```python -# recommended: -if foo is not None: - a = 1 -``` - -```python -# non-recommended: -if not foo is None: - a = 1 -``` - -## Dict - -- There is no space before the colon `:` at the instantiation of KCL dict and schema config, and a space after the colon `:`. - -```python -d1 = {labels: {k1 = "v1"}} # recommended -d2 = {labels : {k1 = "v1"}} # non-recommended -d3 = {labels :{k1 = "v1"}} # non-recommended -``` - -- Always surround the override attribute operator `=` and the insert attribute operator `+=` with a single space on either sid. - -```python -d1 = {key = "value"} # recommended -d2 = {key= "value"} # non-recommended -d3 = {key ="value"} # non-recommended -``` - -```python -d1 = {key += [0, 1, 2]} # recommended -d2 = {key+= [0, 1, 2]} # non-recommended -d3 = {key +=[0, 1, 2]} # non-recommended -``` - -- Remove all commas at the end of the line in the KCL multiline dict because the end commas of each line are optional. - -```python -d = { - key1 = "value1" - key2 = "value2" - key3 = "value3" - key4 = "value4" -} -``` - -## List - -- Keep only **one space** after the comma `,` separating elements in the list - -```python -a = [1, 2, 3] # recommended -b = [1,2,3] # non-recommended -``` - -- Keep only **one space** before and after the comprehension expression token `for` and `in` in the dict and list. - -```python -a = [i for i in range(10)] # recommended -b = [i for i in range(10)] # non-recommended -``` - -## Slice - -- Keep the same number of spaces before and after the colon `:` of the list slice. - -```python -l = [1, 2, 3] -a = l[0:2] # recommended -b = l[0 : 2] # non-recommended -c = l[0: 2] # non-recommended - -d = l[0 + 0 : 1 + 1] # recommended -e = l[0 + 0:1 + 1] # non-recommended -``` - -## Schema - -- Leave only one space before and after the schema attribute assignment `=`. -- Always add a doc string to a schema, which is a good programming habit. - -```python -schema Person: - """ - Schema doc string - """ - name: str = "Alice" # recommended - age : int=12 # non-recommended - -person = Person {} -``` - -- Keep **no spaces** around the schema inheritance operator `()` - -```python -schema Base: - name: str - -schema Person(Base): # recommended - age: int - -schema Schema ( Base ): # non-recommended - age: int -``` - -- Keep **only one space** between the brackets and the schema name of the config at schema instantiation. - -```python -schema Base: - name: str - -schema Person(Base): - age: int - -personA = Person{} # non-recommended -personB = Person {} # recommended -``` - -- Keep **only one space** between the **mixin** keyword and the following `[]` operator - -```python -schema NameMixin: - name: str = "name" - -schema Person: - mixin [NameMixin] # non-recommended - age: int - -schema Parent: - mixin [NameMixin] # recommended - age: int -``` - -### Attribute Annotations - -- Annotations for schema attributes should have a single space after the colon `:` and no space before the colon `:`. - -```python -# recommended: -schema Person: - name: str # No space before the colon `:` - age: int = 18 # Spaces around assignment`=` -``` - -```python -# non-recommended: -schema Person: - codeA:int # No space after the colon `:` - codeB : int # Space before the colon `:` - name: str="Alice" # No spaces around assignment`=` -``` - -- There are no spaces around the colon `:` in the dict type annotation. - -```python -schema Person: - labels: {str:str} # recommended - keyValues: {str : str} # non-recommended -``` - -### Arguments - -- There are no spaces around the assignment `=` in the function/schema/decorator keyword arguments (kwargs). - -```python -schema Person[nameVar]: - # Decorator kwargs - @deprecated(strict=False) # recommended - name: str = nameVar - - @deprecated(strict = False) # non-recommended - age: int - -# Schema kwargs -personA = Person(nameVar="Alice") {} # recommended -personB = Person(nameVar = "Bob") {} # non-recommended - -# Function kwargs -print("", end='') # recommended -print("", end = '') # non-recommended -``` - -## Keywords - -- Only one space is usually reserved around the keyword, such as `schema`, `mixin`, `is` and `not`, etc. - -```python -schema NameMixin: - check: - name not None - -schema Person: - """ - Person schema definition - """ - mixin [NameMixin] - - name: str = "Alice" - age: int - -person = Person { - age = 18 -} -``` - -## Function - -- There are no spaces around the function/package select operator `.` -- There are no spaces between the function name and the parentheses `()`. - -```python -import math - -print(math.log(10)) # recommended -print( math . log (10)) # non-recommended -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/error.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/error.md deleted file mode 100644 index 2a58b553..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/error.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: "Errors" -linkTitle: "Errors" -type: "docs" -weight: 2 -description: Errors ---- - -When errors happen, developers should be able to detect the error and abort -execution. Thus, KCL introduce the `assert` syntax. - -In the previous topic of `schema` syntax. Errors can also be raised when a -schema is violated. - -## Syntax - -The syntax of the `assert` statement is the following. - -```bnf -assert_stmt: 'assert' test ['if' test] [',' test] -``` - -In the basic form, an `assert` statement evaluates an expression. If the -expression is evaluated to `False`, the assertion is failed, and an error -should be reported. - -In the extended form, an error message can be provided. The error message is -another expression. It is only evaluated when the expression to be evaluated -is evaluated to `False`. The evaluation result of the error message is printed -when reporting the error. - -The following is an example: - -```python -a = 1 -b = 3 -condition = False -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -# if condition is True, then assert `a == b`, if failed, the message "error message" will be printed. -assert a == b if condition, "error message" -``` - -## The Implementation - -When an error happens, no matter it is caused by the `assert` or the `schema` syntax, -the virtual machine should exit with an exit code greater than `0`. - -The virtual machine may choose to dump the back trace information, and it is strongly recommended to implement it. - -In practice, KCL can dump back trace by default, and an argument can be introduced to disable it. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/expressions.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/expressions.md deleted file mode 100644 index b52c10f3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/expressions.md +++ /dev/null @@ -1,915 +0,0 @@ ---- -title: "Expressions" -linkTitle: "Expressions" -type: "docs" -weight: 2 -description: Expressions ---- - -## Syntax - -In KCL, an expression specifies the computation of a value. - -The syntax is the following: - -```bnf -expression: test ("," test)* -test: if_expr | primary_expr | unary_expr | binary_expr -``` - -KCL expressions consist of `if` expression, `primary` expression, `unary` expression, and `binary` expression. - -### Primary Expressions - -Primary expressions are the operands for unary and binary expressions. - -Operands are self-delimiting. An **operand** may be followed by any number of selector dot, a function call, or slice suffixes, to form a primary expression. The grammar uses `expression`, where a multiple-component expression is allowed, and `test` where it accepts an expression of only a single component. - -Syntax: - -```bnf -primary_expr: operand | primary_expr select_suffix | primary_expr call_suffix | primary_expr subscript_suffix -``` - -### Operands - -Operand denotes the elementary value in an expression. An operand may be an identifier, a literal, or a parenthesized expression. - -Syntax: - -```bnf -operand: operand_name | number | string | "True" | "False" | "None" | "Undefined" | list_expr | list_comp | dict_expr | dict_comp | "(" expression ")" -operand_name: identifier | qualified_identifier -``` - -### Identifiers - -In KCL, an identifier is a name, may with selectors, that identifies a value. - -Syntax: - -```bnf -identifier: NAME -``` - -Examples: - -```python -x -a -_b -``` - -Use the `$` character prefix to define keyword identifiers. - -```python -$if = 1 -$else = "s" -``` - -Please note: whether the non-keyword identifier is prefixed with `$` has the same effect. - -```python -_a = 1 -$_a = 2 # equal to `_a = 2` -``` - -To simplify the definition of the qualified identifier, such as 'pkg.type', we additionally define `qualified_identifier`: - -Syntax: - -```bnf -qualified_identifier: identifier "." identifier -``` - -Examples: - -```python -pkg.a -``` - -The package name in qualified_identifier must be imported. - -### Basic Literals - -Basic literals supported in KCL are `int`, `float`, `string` and `bool` including `True` and `False`. Evaluation of basic literal yields a value of the given type with the given value. - -Syntax: - -```bnf -operand: number | string | "True" | "False" | "None" | "Undefined" -``` - -Examples: - -```python -1 -2.3 -"abc" -True -False -None -Undefined -``` - -See more details about **data type** spec. - -### Parenthesized Expressions - -An expression enclosed in parentheses yields the result of that expression. - -Syntax: - -```bnf -operand: '(' expression ')' -``` - -Examples: - -```python -x = (1 + 2) * (3 + 4) # 21 -``` - -### Dictionary Expressions - -A dictionary expression is a comma-separated immutable list of colon-separated key/value expression pairs, enclosed in curly brackets, and it yields a new dictionary object. An optional comma may follow the final pair. - -```bnf -config_expr: '{' config_entries '}' -config_entries: config_entry [config_entry*] -config_comp: '{' (config_entry comp_clause+) '}' -config_entry: expr (':' | '=' | '+=') expr | double_star_expr | if_entry -double_star_expr: "**" expression -if_entry: - 'if' expr ';' if_entry_exec_block - ('elif' expr ':' if_entry_exec_block)* - ('else' ':' if_entry_exec_block)? -NEWLINE: '/r?/n' -``` - -Examples: - -```python -{} -{"one": 1} -{"one": 1, "two": 2} -``` - -The key and value expressions are evaluated in left-to-right order. Evaluation fails if the same key is used multiple times. - -Only hashable values may be used as the keys of a dictionary. This includes all built-in types except dictionaries, and lists. - -We can ignore the comma `,` at the end of the line for writing dict key-value pairs in multiple lines: - -```python -data = { - "key1" = "value1" # Ignore the comma ',' at the end of line - "key2" = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -We can ignore the key quotation marks when we writing simple literals on the key. - -```python -data = { - key1 = "value1" # Ignore the comma ',' at the end of line - key2 = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -In addition, the **config selector expressions** can be used to init a schema instance. - -```python -person = { - base.count = 2 - base.value = "value" - labels.key = "value" -} # {"base": {"count": 2, "value": "value"}, "labels": {"key": "value"}} -``` - -We can **merge** dict using the dict unpacking operator `**` like this: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = {**_part1, **_part2} # {"a: "b", "c": "d"} -``` - -We can use `if expressions` to dynamically add elements to the dict element, elements that meet the conditions are added to the dict, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = { - key1 = "value1" - if a == 1: key2 = "value2" - if a > 0: key3 = "value3" - if a < 0: key4 = "value4" -} # {"key1": "value1", "key2": "value2", "key3": "value3"} -``` - -```python -a = 1 # 1 -data1 = { - key1 = "value1" - if a == 1: - key2 = "value2" - elif a > 0: - key3 = "value3" - else: - key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -data2 = { - key1 = "value1" - if a == 1: key2 = "value2" - elif a > 0: key3 = "value3" - else: key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -``` - -### List Expressions - -A list expression is a comma-separated immutable list of element expressions, enclosed in square brackets, and it yields a new list. An optional comma may follow the last element expression. - -```bnf -list_expr: '[' [list_item [',']] ']' -list_item: test | "*" primary_expr | if_expr -``` - -Element expressions are evaluated in left-to-right order. - -Examples: - -```python -[] # [], empty list -[1] # [1], a 1-element list -[1, 2, 3] # [1, 2, 3], a 3-element list -``` - -We can use `if expressions` to dynamically add elements to the list element, elements that meet the conditions are added to the list, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = [ - 1 - if a == 1: 2 - if a > 0: 3 - if a < 0: 4 -] # [1, 2, 3] -``` - -```python -a = 1 # 1 -data1 = [ - 1 - if a == 1: - 2 - elif a == 2: - 3 - else: - 3 -] # [1, 2] -data2 = [ - 1 - if a == 1: 2 - elif a == 2: 2 - else: 3 -] # [1, 2] -``` - -### Comprehensions - -A comprehension constructs a new list or dictionary value by looping over one or more iterables and evaluating a body expression that produces successive elements of the result. - -Syntax: - -```bnf -list_comp: '[' list_item comp_clause+ ']' . -dict_comp: '{' entry comp_clause+ '}' . - -comp_clause: 'for' loop_variables [","] 'in' test ['if' test] -loop_variables: primary_expr (',' primary_expr)* -``` - -A list comprehension consists of a single expression followed by one or more clauses, the first of which must be a `for` clause. Each `for` clause resembles a `for` statement, and specifies an iterable operand and a set of variables to be assigned by successive values of the iterable. An `if` cause resembles an `if` statement, and specifies a condition that must be met for the body expression to be evaluated. A sequence of `for` and `if` clauses acts like a nested sequence of `for` and `if` statements. - -Examples: - -```python -[x * x for x in range(5)] # [0, 1, 4, 9, 16] -[x * x for x in range(5) if x % 2 == 0] # [0, 4, 16] -[[x, y] for x in range(5) \ - if x % 2 == 0 \ - for y in range(5) \ - if y > x] # [[0, 1], [0, 2], [0, 3], [0, 4], [2, 3], [2, 4]] -``` - -Besides, we can use two variables in the list comprehension, the first variable denotes the list index and the second variable denotes the list item. - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use `_` to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -A dict comprehension resembles a list comprehension, but its body is a pair of expressions, key: value, separated by a colon, and its result is a dictionary containing the key/value pairs for which the body expression was evaluated. Evaluation fails if the value of any key is un-hashable. - -Besides, we can use two variables in the dict comprehension, the first variable denotes the dict key and the second variable denotes the dict value of the key. - -```python -data = {"key1" = "value1", "key2" = "value2"} -# Single variable loop -dataKeys1 = {k: k for k in data} # {"key1": "key1", "key2": "key2"} -dataValues1 = {k: data[k] for k in data} # {"key1": "value1", "key2": "value2"} -# Double variable loop -dataKeys2 = {k: k for k, v in data} # {"key1": "key1", "key2": "key2"} -dataValues2 = {v: v for k, v in data} # {"value1": "value1", "value2": "value2"} -dataFilter = {k: v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use `_` to ignore loop variables -dataKeys3 = {k: k for k, _ in data} # {"key1": "key1", "key2": "key2"} -dataValues3 = {v: v for _, v in data} # {"value1": "value1", "value2": "value2"} -``` - -As with a `for` loop, the loop variables may exploit compound assignment: - -```python -[x * y + z for [x, y], z in [[[2, 3], 5], [["o", 2], "!"]]] # [11, 'oo!'] -``` - -KCL does not accept an un-parenthesized list as the operand of a for clause: - -```python -[x * x for x in 1, 2, 3] # parse error: unexpected comma -``` - -Comprehensions defines a new lexical block, so assignments to loop variables have no effect on variables of the same name in an enclosing block: - -```python -x = 1 -_ = [x for x in [2]] # new variable x is local to the comprehension -print(x) # 1 -``` - -The operand of a comprehension's first clause (always a for) is resolved in the lexical block enclosing the comprehension. In the examples below, identifiers referring to the outer variable named x have been distinguished by subscript. - -```python -x0 = [1, 2, 3] -[x * x for x in x0] # [1, 4, 9] -[x * x for x in x0 if x % 2 == 0] # [4] -``` - -All subsequent for and if expressions are resolved within the comprehension's lexical block, as in this rather obscure example: - -```python -x0 = [[1, 2], [3, 4], [5, 6]] -[x * x for x in x0 for x in x if x % 2 == 0] # [4, 16, 36] -``` - -which would be more clearly rewritten as: - -```python -x = [[1, 2], [3, 4], [5, 6]] -[z * z for y in x for z in y if z % 2 == 0] # [4, 16, 36] -``` - -### Conditional Expressions - -A conditional expression has the form `a if cond else b`. It first evaluates the condition `cond`. If it's true, it evaluates `a` and yields its value; otherwise it yields the value of `b`. - -Syntax: - -```bnf -if_expr: test "if" test "else" test -``` - -Examples: - -```python -x = True if enabled else False # if enabled is -``` - -### Unary Expressions - -In KCL, supported unary operators are `+`, `-`, `~`, and `not`. - -Syntax: - -```bnf -unary_expr: ("+" | "-" | "~") primary_expr - | "not" test -``` - -Usage: - -```bnf -+ number unary positive (int, float) -- number unary negation (int, float) -~ number unary bitwise inversion (int) -not x logical negation (any type) -``` - -The `+` and `-` operators may be applied to any number (int or float) and return the number. -The `not` operator returns the negation of the truth value of its operand. - -Examples: - -```python -~1 # -2 -~-1 # 0 -~0 # -1 -not True # False -not 0 # True -``` - -### Binary Expressions - -In KCL, binary expressions consist of `comparisons`, `logical operations`, `arithmetic operations` and `membership tests`. - -Syntax: - -```bnf -binary_expr: test bin_op test -bin_op: 'or' - | 'and' - | '==' | '!=' | '<' | '>' | '<=' | '>=' - | 'in' | 'not' 'in' - | '|' - | '^' - | '&' - | '-' | '+' - | '*' | '%' | '/' | '//' - | '<<' | '>>' -``` - -#### Logical Operations - -The `or` and `and` operators yield the logical disjunction and conjunction of their arguments, which need not be Booleans. - -The expression `x or y` yields the value of `x` if its truth value is `True`, or the value of `y` otherwise. - -```python -False or False # False -False or True # True -True or True # True -1 or "hello" # 1 -``` - -Similarly, `x` and `y` yields the value of `x` if its truth value is `False`, or the value of `y` otherwise. - -```python -False and False # False -False and True # False -True and True # True -1 and "hello" # "hello" -``` - -These operators use "short circuit" evaluation, so the second expression is not evaluated if the value of the first expression has already determined the result, allowing constructions like these: - -```python -x and x[0] == 1 # x[0] is not evaluated if x is empty -len(x) == 0 or x[0] == "" -not x or not x[0] -``` - -#### Comparisons - -The `==` operator reports whether its operands are equal; the `!=` operator is its negation. - -The operators `<`, `>`, `<=`, and `>=` perform an ordered comparison of their operands. It is an error to apply these operators to operands of unequal type, unless one of the operands is an `int` and the other is a `float`. Of the built-in types, only the following support ordered comparison, using the ordering relation shown: - -```bnf -NoneType # None <= None -bool # False < True -int # mathematical -float # as defined by IEEE 754 -string # lexicographical -list # lexicographical -``` - -Comparison of floating-point values follows the IEEE 754 standard, which breaks several mathematical identities. For example, if `x` is a `NaN` value, the comparisons `x < y`, `x == y`, and `x > y` all yield false for all values of `y`. - -The remaining built-in types support only equality comparisons. Values of type `dict` and `schema` compare equal if their elements compare equal, and values of type function or `builtin_function_or_method` are equal only to themselves. - -```bnf -dict # equal contents -schema # equal exported-attributes -function # identity -builtin_function_or_method # identity -``` - -#### Arithmetic Operations - -The following table summarizes the binary arithmetic operations available for built-in types: - -```bnf -Arithmetic (int or float; result has type float unless both operands have type int) - number + number # addition - number - number # subtraction - number * number # multiplication - number / number # real division (result is always a float) - number // number # floored division - number % number # remainder of floored division - number ^ number # bitwise XOR - number << number # bitwise left shift - number >> number # bitwise right shift - -Concatenation - string + string - list + list - -Repetition (string/list) - int * sequence - sequence * int - -Union - int | int - list | list - dict | dict - schema | schema - schema | dict -basictype | basictype -``` - -The operands of the arithmetic operators `+`, `-`, `*`, `//`, and `%` must both be numbers (`int` or `float`) but need not have the same type. The type of the result has type `int` only if both operands have that type. The result of real division / always has type `float`. - -The `+` operator may be applied to non-numeric operands of the same type, such as two lists, or two strings, in which case it computes the concatenation of the two operands and yields a new value of the same type. - -```python -"Hello, " + "world" # "Hello, world" -[1, 2] + [3, 4] # [1, 2, 3, 4] -``` - -The `*` operator may be applied to an integer n and a value of type `string`, `list`, in which case it yields a new value of the same sequence type consisting of n repetitions of the original sequence. The order of the operands is immaterial. Negative values of n behave like zero. - -```python -'mur' * 2 # 'murmur' -3 * range(3) # [0, 1, 2, 0, 1, 2, 0, 1, 2] -``` - -The `&` operator requires two operands of the same type, such as `int`. For integers, it yields the bitwise intersection (AND) of its operands. - -The `|` operator likewise computes bitwise, unions basic types and unions collection and schema data, such as **list**, **dict** and **schema**. - -Computing bitwise examples: - -```python -0x12345678 | 0xFF # 0x123456FF -``` - -Unioning basic types examples: - -```python -schema x: - a: int | str # attribute a could be a int or string -``` - -A union type is used to define a schema attribute type. See more details in **schema** spec. -Supported types in a union type are `int`, `str`, `float`, `bool`, `list` and `dict`. - -Unioning collection and schema data: - -- Unioning List. Overwrite the list expression on the right side of the operator `|` to the list variable on the left side of the operator one by one according to the **index**. - -```python -_a = [1, 2, 3] -_b = [4, 5, 6, 7] -x = _a | _b # [4, 5, 6, 7] 4 -> 1; 5 -> 2; 6 -> 3; 7 -> None -``` - -Unioning to the specific index or all elements is still under discussion. - -- Unioning Dict. Union the dict expression on the right side of the operator `|` one by one to the dict variable on the left side of the operator according to the **key** - -```python -_a = {key1 = "value1"} -_b = {key1 = "overwrite", key2 = "value2"} -_c = _a | _b # {"key1": "overwrite", "key2": "value2"} -``` - -The union of collection and schema is a new one whose attributes are unioning b to a, preserving the order of the attributes of the operands, left before right. - -Unioning to the specific key or all keys is still under discussion. - -- Unioning Schema. - -The union operation for schema is similar to dict. - -Schema union could be done as: - -```bnf -schema Person: - firstName: str - lastName: str - -_a = Person { - firstName = "John" -} -_b = {lastName = "Doe"} -_a = _a | _b # {"firstName": "John", "lastName": "Doe"} -``` - -Unioning to a specific attribute is still under discussion. Unioning to all attributes is not applicable to schema instances. - -See **selector expression** in **expression** spec for more details. - -The `^` operator accepts operands of `int`. For integers, it yields the bitwise XOR (exclusive OR) of its operands. - -The `<<` and `>>` operators require operands of `int` type both. They shift the first operand to the left or right by the number of bits given by the second operand. It is a dynamic error if the second operand is negative. Implementations may impose a limit on the second operand of a left shift. - -```python -0x12345678 & 0xFF # 0x00000078 -0b01011101 ^ 0b110101101 # 0b111110000 -0b01011101 >> 2 # 0b010111 -0b01011101 << 2 # 0b0101110100 -``` - -#### Membership Tests - -Usage: - -```bnf - any in sequence (list, dict, schema, string) - any not in sequence -``` - -The `in` operator reports whether its first operand is a member of its second operand, which must be a list, dict, schema, or string. The `not in` operator is its negation. Both return a Boolean. - -The meaning of membership varies by the type of the second operand: the members of a list are its elements; the members of a dict are its keys; the members of a string are all its substrings. - -```python -1 in [1, 2, 3] # True - -d = {"one" = 1, "two" = 2} -"one" in d # True -"three" in d # False -1 in d # False -[] in d # False - -"nasty" in "dynasty" # True -"a" in "banana" # True -"f" not in "way" # True - -d = data {one = 1, two = 2} # data is a schema with attributes one and two -"one" in d # True -"three" in d # False -``` - -### Function Invocations - -KCL allows calling built-in functions and functions from built-in and system modules. Whether KCL allows defining new functions is under discussion. - -Syntax: - -```bnf -call_suffix: "(" [arguments [","]] ")" -arguments: argument ("," argument)* -argument: test | identifier "=" test | "*" test | "**" test -``` - -To call a function, the basic way is shown as the following code excerpt: - -```python -print("An argument") - -import math -# 2 powers 3 is 8. -a = math.pow(2, 3) -``` - -As you can see, arguments are separated with `,`. Arguments can only be passed in this way. KCL supports positional arguments and key-value arguments. - -Note that: - -- Some functions have parameters with default values. -- Some functions accept variadic arguments. - -When an argument is not supplied for a parameter without a default value, -an error will be reported. - -### Selector Expressions - -A selector expression selects the attribute or method of the value. - -#### Select Attributes - -Syntax: - -```bnf -select_suffix: ["?"] "." identifier -``` - -KCL provides a wealth of ways to identify or filter attributes. - -x.y - -- schema: it denotes the attribute value of a schema `x` identified by `y` -- package: it denotes the identifier of a package `x` identified by `y` - -Examples: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -name = person.name # "Alice" -age = person.age # 18 -``` - -x?.y - -If the x if None/Undefined or empty(empty list or dict), just return None, otherwise behave as x.y. - -Examples - -```python -noneData = None -data?.name # None - -emptyDict = {} -emptyDict?.name # None - -emptyList = [] -emptyList?[0] # None -``` - -As a supplementary of the `selector` expression in KCL code, the KCL compiler needs to provide corresponding identifying and filtering features through the command line and api form. - -#### Select Methods - -Syntax: - -```bnf -select_suffix: "." identifier -``` - -A `identifier` identifies method belongs to the built-in types `string`, `list`, `dict`, and `schema`. - -- A selector expression fails if the value does not have an attribute of the specified name. -- A selector expression that selects a method typically appears within a call expression, as in these examples: - -Examples: - -```python -["able", "baker", "charlie"].index("baker") # 1 -"banana".count("a") # 3 -"banana".reverse() # error: string has no .reverse field or method -Person.instances() # all instances of schema Person -``` - -But when not called immediately, the selector expression evaluates to a bound method, that is, a method coupled to a specific receiver value. A bound method can be called like an ordinary function, without a receiver argument: - -```bnf -f = "banana".count -f # -f("a") # 3 -f("n") # 2 -``` - -### Index Expressions - -An index expression `a[i]` yields the `i` th element of an indexable type such as a string or list. The index `i` must be an `int` value in the range `-n` ≤ `i` < `n`, where `n` is `len(a)`; any other index results in an error. - -Syntax: - -```bnf -subscript_suffix: "[" [test] "]" -``` - -A valid negative index `i` behaves like the non-negative index `n+i`, allowing for convenient indexing relative to the end of the sequence. - -```python -"abc"[0] # "a" -"abc"[1] # "b" -"abc"[-1] # "c" - -["zero", "one", "two"][0] # "zero" -["zero", "one", "two"][1] # "one" -["zero", "one", "two"][-1] # "two" -``` - -An index expression `d[key]` may also be applied to a dictionary `d`, to obtain the value associated with the specified key. It returns `Undefined` if the dictionary contains no such key. - -An index expression appearing on the left side of an assignment causes the specified list or dictionary element to be updated: - -```python -a = range(3) # a == [0, 1, 2] -b = a[2] # 2 - - -``` - -It is a dynamic error to attempt to update an element of an immutable type, such as a list or string, or a frozen value of a mutable type. - -### Slice Expressions - -A slice expression `a[start:stop:stride]` yields a new value containing a sub-sequence of `a`, which must be a string, or list. - -```bnf -subscript_suffix: "[" [test] [":" [test] [":" [test]]] "]" -``` - -Each of the `start`, `stop`, and `stride` operands is optional; if present, and not `None`, each must be an integer. -The `stride` value defaults to 1. If the stride is not specified, the colon preceding it may be omitted too. It is an error to specify a stride of zero. - -Conceptually, these operands specify a sequence of values `i` starting at start and successively adding `stride` until `i` reaches or passes `stop`. The result consists of the concatenation of values of `a[i]` for which `i` is valid.` - -The effective start and stop indices are computed from the three operands as follows. Let `n` be the length of the sequence. - -**If the stride is positive**: If the `start` operand was omitted, it defaults to -infinity. If the `end` operand was omitted, it defaults to +infinity. For either operand, if a negative value was supplied, `n` is added to it. The `start` and `end` values are then "clamped" to the nearest value in the range 0 to `n`, inclusive. - -**If the stride is negative**: If the `start` operand was omitted, it defaults to +infinity. If the `end` operand was omitted, it defaults to -infinity. For either operand, if a negative value was supplied, `n` is added to it. The `start` and `end` values are then "clamped" to the nearest value in the range -1 to `n`-1, inclusive. - -```python -"abc"[1:] # "bc" (remove first element) -"abc"[:-1] # "ab" (remove last element) -"abc"[1:-1] # "b" (remove first and last element) -"banana"[1::2] # "aaa" (select alternate elements starting at index 1) -"banana"[4::-2] # "nnb" (select alternate elements in reverse, starting at index 4) -``` - -It's not allowed to define a slice expression as a left value in KCL. -Cause list and string are immutable, re-slicing can directly operate to operand to ensure better performance. - -#### Quantifier Expressions - -Quantifier expressions act on collection: list or dict, generally used to obtain a certain result after processing the collection, mainly in the following four forms: - -```bnf -quant_expr: quant_op [ identifier ',' ] identifier 'in' quant_target '{' expr ['if' expr] '}' -quant_target: string | identifier | list_expr |list_comp | dict_expr | dict_comp -quant_op: 'all' | 'any' | 'filter' | 'map' -``` - -- **all** - - Used to detect that all elements in the collection satisfy the given logical expression, and return a boolean value as the result. - - Only when all elements in the collection satisfy the expression true, the `all` expression is true, otherwise it is false. - - If the original collection is empty, return true. - - Supports short-circuiting of logical expressions during expression execution. -- **any** - - Used to detect that at least one element in the collection satisfies the given logical expression, and returns a boolean value as the result. - - When at least one element in the collection satisfies the expression true, the `any` expression is true, otherwise it is false. - - If the original collection is empty, return false. - - Supports short-circuiting of logical expressions during expression execution. -- **map** - - Generate a new **list** by mapping the elements in the original collection. - - The length of the new list is exactly the same as the original collection. -- **filter** - - By logically judging and filtering the elements in the original collection, and returning the filtered sub-collection. - - Only when the element judges the expression to be true, it is added to the sub-collection. - - The type (list, dict and schema) of the new collection is exactly the same as the original collection, and the length range is `[0, len(original-collection)]`. - -**all** and **any** expression sample codes: - -```python -schema Config: - volumes: [{str:}] - services: [{str:}] - - check: - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - }, "invalid cluster ip" - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } -``` - -**map** and **filter** expression sample codes: - -```python -a = map e in [{name = "1", value = 1}, {name = "2", value = 2}] { - {name = e.name, value = int(e.value) ** 2} -} # [{"name": "1", value: 1}, {"name": "2", "value": 4}] - -b = map k, v in {a = "foo", b = "bar"} { v } # ["foo", "bar"] - -c = filter e in [{name = "1", value = 1}, {name = "2", value = 2}] { - int(e.value) > 1 -} # [{"name": "2", "value": 2}] - -d = filter _, v in {a = "foo", b = "bar"} { - v == "foo" -} # {"a": "foo"} -``` - -Please pay attention to distinguish the difference between any expression and any type. When `any` is used in type annotations, it means that the value of the variable is arbitrary, while the any expression means that one of the elements in a set satisfies the condition. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/index.md deleted file mode 100644 index c3ecc162..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/index.md +++ /dev/null @@ -1 +0,0 @@ -# KCL 语言规范 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/kcl-spec.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/kcl-spec.md deleted file mode 100644 index 63a9d6e7..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/kcl-spec.md +++ /dev/null @@ -1,343 +0,0 @@ ---- -title: "KCL Spec" -linkTitle: "KCL Spec" -type: "docs" -weight: 2 -description: KCL Spec ---- - -## Lexical rules - -### Keywords and reserved words - -The following are the keywords of the KCL: - -```python -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -The following are reserved words for the KCL: - -```python -pass return validate rule flow -def del raise except try -finally while from with yield -global nonlocal struct class final -``` - -### Line comment - -```python -# a comment -``` - -### Operators - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != = -+= -= *= **= /= //= %= -<<= >>= &= ^= -``` - -### Delimiters - -```python -( ) [ ] { } -, : . ; @ -``` - -### Operator precedence - -The following list of operators is ordered from **highest to lowest**: - -| Operator | Description | -| -------------------------------------------------------------------------------- | -------------------------------------------------------- | -| `**` | Exponentiation (highest priority) | -| `+x` `-x` `~x` | Positive, negative, bitwise NOT | -| `*` `/` `%` `//` | Multiplication, division, floor division and remainder | -| `+` `-` | Addition and subtraction | -| `<<` `>>` | Left and right shifts | -| `&` | Bitwise AND | -| `^` | Bitwise XOR | -| \| | Bitwise OR | -| `in`, `not in`, `is`, `is not`, `<`, `<=`, `>`, `>=`, `!=`, `==` | Comparisons, including membership and identity operators | -| `not` | Boolean NOT | -| `and` | Boolean AND | -| `or` | Boolean OR | -| `if – else` | Conditional expression = | -| `=`, `+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `=`, `^=`, `\*\*=`, `//=`, `<<=`, `>>=` | Assign | - -## Grammar - -KCL uses Python's [LarkParser](https://lark-parser.readthedocs.io/en/latest/) tool to describe the grammar, and the specification rules are as follows: - -```bnf -//////////// KCL grammar //////////// -start: (NEWLINE | statement)* - -statement: simple_stmt | compound_stmt -simple_stmt: (assign_stmt | unification_stmt | expr_stmt | assert_stmt | import_stmt | type_alias_stmt) NEWLINE -compound_stmt: if_stmt | schema_stmt | rule_stmt - -//////////// import_stmt //////////// -import_stmt: IMPORT dot_name (AS NAME)? -dot_name: (leading_dots identifier) | identifier -leading_dots: DOT+ - -/////////// assert_stmt //////////// -assert_stmt: ASSERT simple_expr (IF simple_expr)? (COMMA test)? - -//////////// if_stmt //////////// -if_stmt: IF test COLON execution_block (ELIF test COLON execution_block)* (ELSE COLON execution_block)? -execution_block: if_simple_stmt | NEWLINE _INDENT schema_init_stmt+ _DEDENT -if_simple_stmt: (simple_assign_stmt | unification_stmt | expr_stmt | assert_stmt) NEWLINE - -//////////// assign_stmt //////////// -assign_stmt: identifier [COLON type] (ASSIGN identifier)* ASSIGN test - | identifier (COMP_PLUS | COMP_MINUS | COMP_MULTIPLY | COMP_DOUBLE_STAR | COMP_DIVIDE - | COMP_DOUBLE_DIVIDE | COMP_MOD | COMP_AND | COMP_OR | COMP_XOR | COMP_SHIFT_LEFT - | COMP_SHIFT_RIGHT) test - -simple_assign_stmt: identifier ASSIGN test - | identifier (COMP_PLUS | COMP_MINUS | COMP_MULTIPLY | COMP_DOUBLE_STAR | COMP_DIVIDE - | COMP_DOUBLE_DIVIDE | COMP_MOD | COMP_AND | COMP_OR | COMP_XOR | COMP_SHIFT_LEFT - | COMP_SHIFT_RIGHT) test - -//////////// unification_stmt //////////// -unification_stmt: identifier COLON schema_expr - -//////////// schema_stmt //////////// -schema_stmt: [decorators] (SCHEMA|MIXIN|PROTOCOL) NAME [LEFT_BRACKETS [schema_arguments] RIGHT_BRACKETS] [LEFT_PARENTHESES identifier (COMMA identifier)* RIGHT_PARENTHESES] [for_host] COLON NEWLINE [schema_body] -schema_arguments: schema_argument (COMMA schema_argument)* -schema_argument: NAME [COLON type] [ASSIGN test] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt|schema_init_stmt|schema_index_signature)* [check_block] _DEDENT -schema_attribute_stmt: attribute_stmt NEWLINE -attribute_stmt: [decorators] identifier [QUESTION] COLON type [(ASSIGN|COMP_OR) test] -schema_init_stmt: if_simple_stmt | if_stmt -schema_index_signature: LEFT_BRACKETS [NAME COLON] [ELLIPSIS] basic_type RIGHT_BRACKETS COLON type [ASSIGN test] NEWLINE - -//////////// rule_stmt //////////// -rule_stmt: [decorators] RULE NAME [LEFT_BRACKETS [schema_arguments] RIGHT_BRACKETS] [LEFT_PARENTHESES identifier (COMMA identifier)* RIGHT_PARENTHESES] [for_host] COLON NEWLINE [rule_body] -rule_body: _INDENT (string NEWLINE)* check_expr+ _DEDENT - -for_host: FOR identifier - -/////////// decorators //////////// -decorators: (AT decorator_expr NEWLINE)+ -decorator_expr: identifier [call_suffix] - -//////////// type //////////// -type: type_element (OR type_element)* -type_element: schema_type | basic_type | compound_type | literal_type -schema_type: identifier -basic_type: STRING_TYPE | INT_TYPE | FLOAT_TYPE | BOOL_TYPE | ANY_TYPE -compound_type: list_type | dict_type -list_type: LEFT_BRACKETS (type)? RIGHT_BRACKETS -dict_type: LEFT_BRACE (type)? COLON (type)? RIGHT_BRACE -literal_type: string | number | TRUE | FALSE | NONE - -//////////// type alias //////////// -type_alias_stmt: TYPE NAME ASSIGN type - -//////////// check_stmt //////////// -check_block: CHECK COLON NEWLINE _INDENT check_expr+ _DEDENT -check_expr: simple_expr [IF simple_expr] [COMMA primary_expr] NEWLINE - -//////////// mixin_stmt //////////// -mixin_stmt: MIXIN LEFT_BRACKETS [mixins | multiline_mixins] RIGHT_BRACKETS NEWLINE -multiline_mixins: NEWLINE _INDENT mixins NEWLINE _DEDENT -mixins: identifier (COMMA (NEWLINE mixins | identifier))* - - -//////////// expression_stmt //////////// -expr_stmt: testlist_expr -testlist_expr: test (COMMA test)* -test: if_expr | simple_expr -if_expr: simple_expr IF simple_expr ELSE test - -simple_expr: unary_expr | binary_expr | primary_expr - -unary_expr: un_op simple_expr -binary_expr: simple_expr bin_op simple_expr - -bin_op: L_OR | L_AND - | OR | XOR | AND - | SHIFT_LEFT | SHIFT_RIGHT - | PLUS | MINUS | MULTIPLY | DIVIDE | MOD | DOUBLE_DIVIDE - | DOUBLE_STAR - | EQUAL_TO | NOT_EQUAL_TO - | LESS_THAN | GREATER_THAN | LESS_THAN_OR_EQUAL_TO | GREATER_THAN_OR_EQUAL_TO - | IN | L_NOT IN | IS | IS L_NOT | L_NOT | AS -un_op: L_NOT | PLUS | MINUS | NOT - -primary_expr: identifier call_suffix | operand | primary_expr select_suffix | primary_expr call_suffix | primary_expr slice_suffix -operand: identifier | number | string | constant | quant_expr | list_expr | list_comp | config_expr | dict_comp | schema_expr | lambda_expr | LEFT_PARENTHESES test RIGHT_PARENTHESES -select_suffix: [QUESTION] DOT NAME -call_suffix: LEFT_PARENTHESES [arguments [COMMA]] RIGHT_PARENTHESES -slice_suffix: [QUESTION] LEFT_BRACKETS (test | [test] COLON [test] [COLON [test]]) RIGHT_BRACKETS -arguments: argument (COMMA argument)* -argument: test | NAME ASSIGN test | MULTIPLY test | DOUBLE_STAR test - - -//////////// operand //////////// -identifier: NAME (DOT NAME)* -quant_expr: quant_op [ identifier COMMA ] identifier IN quant_target LEFT_BRACE (simple_expr [IF simple_expr] | NEWLINE _INDENT simple_expr [IF simple_expr] NEWLINE _DEDENT)? RIGHT_BRACE -quant_target: string | identifier | list_expr | list_comp | config_expr | dict_comp -quant_op: ALL | ANY | FILTER | MAP -list_expr: LEFT_BRACKETS [list_items | NEWLINE [_INDENT list_items _DEDENT]] RIGHT_BRACKETS -list_items: list_item ((COMMA [NEWLINE] | [NEWLINE]) list_item)* [COMMA] [NEWLINE] -list_item: test | star_expr | if_item -list_comp: LEFT_BRACKETS (list_item comp_clause+ | NEWLINE _INDENT list_item comp_clause+ _DEDENT) RIGHT_BRACKETS -dict_comp: LEFT_BRACE (entry comp_clause+ | NEWLINE _INDENT entry comp_clause+ _DEDENT) RIGHT_BRACE -entry: test (COLON | ASSIGN | COMP_PLUS) test -comp_clause: FOR loop_variables [COMMA] IN simple_expr [NEWLINE] [IF test [NEWLINE]] -if_entry: IF test COLON if_entry_exec_block (ELIF test COLON if_entry_exec_block)* (ELSE COLON if_entry_exec_block)? -if_entry_exec_block: (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry) [NEWLINE] | NEWLINE _INDENT (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry) ((COMMA [NEWLINE] | [NEWLINE]) (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry))* [COMMA] [NEWLINE] _DEDENT -if_item: IF test COLON if_item_exec_block (ELIF test COLON if_item_exec_block)* (ELSE COLON if_item_exec_block)? -if_item_exec_block: list_item [NEWLINE] | NEWLINE _INDENT list_item ((COMMA [NEWLINE] | NEWLINE) list_item)* [COMMA] [NEWLINE] _DEDENT - -star_expr: MULTIPLY test -double_star_expr: DOUBLE_STAR test -loop_variables: primary_expr (COMMA primary_expr)* -schema_expr: identifier (LEFT_PARENTHESES [arguments] RIGHT_PARENTHESES)? config_expr -config_expr: LEFT_BRACE [config_entries | NEWLINE [_INDENT config_entries _DEDENT]] RIGHT_BRACE -config_entries: config_entry ((COMMA [NEWLINE] | [NEWLINE]) config_entry)* [COMMA] [NEWLINE] -config_entry: test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry - -//////////// lambda_expr //////////// -lambda_expr: LAMBDA [schema_arguments] [RIGHT_ARROW type] LEFT_BRACE [expr_stmt | NEWLINE _INDENT schema_init_stmt+ _DEDENT] RIGHT_BRACE - -//////////// misc //////////// -number: DEC_NUMBER [multiplier] | HEX_NUMBER | BIN_NUMBER | OCT_NUMBER | FLOAT_NUMBER -multiplier: SI_N_L | SI_U_L | SI_M_L | SI_K_L | SI_K | SI_M | SI_G | SI_T | SI_P - | SI_K_IEC | SI_M_IEC | SI_G_IEC | SI_T_IEC | SI_P_IEC -string: STRING | LONG_STRING -constant : TRUE | FALSE | NONE | UNDEFINED -// Tokens - -ASSIGN: "=" -COLON: ":" -SEMI_COLON: ";" -COMMA: "," -QUESTION: "?" -ELLIPSIS: "..." -RIGHT_ARROW: "->" -LEFT_PARENTHESES: "(" -RIGHT_PARENTHESES: ")" -LEFT_BRACKETS: "[" -RIGHT_BRACKETS: "]" -LEFT_BRACE: "{" -RIGHT_BRACE: "}" -PLUS: "+" -MINUS: "-" -MULTIPLY: "*" -DIVIDE: "/" -MOD: "%" -DOT: "." -AND: "&" -OR: "|" -XOR: "^" -NOT: "~" -LESS_THAN: "<" -GREATER_THAN: ">" -EQUAL_TO: "==" -NOT_EQUAL_TO: "!=" -GREATER_THAN_OR_EQUAL_TO: ">=" -LESS_THAN_OR_EQUAL_TO: "<=" -DOUBLE_STAR: "**" -DOUBLE_DIVIDE: "//" -SHIFT_LEFT: "<<" -SHIFT_RIGHT: ">>" -AT: "@" - -COMP_PLUS: "+=" -COMP_MINUS: "-=" -COMP_MULTIPLY: "*=" -COMP_DIVIDE: "/=" -COMP_MOD: "%=" -COMP_AND: "&=" -COMP_OR: "|=" -COMP_XOR: "^=" -COMP_DOUBLE_STAR: "**=" -COMP_DOUBLE_DIVIDE: "//=" -COMP_SHIFT_LEFT: "<<=" -COMP_SHIFT_RIGHT: ">>=" - -// Special tokens -IMPORT: "import" -AS: "as" -RULE: "rule" -SCHEMA: "schema" -MIXIN: "mixin" -PROTOCOL: "protocol" -CHECK: "check" -FOR: "for" -ASSERT: "assert" -IF: "if" -ELIF: "elif" -ELSE: "else" -L_OR: "or" -L_AND: "and" -L_NOT: "not" -IN: "in" -IS: "is" -LAMBDA: "lambda" -ALL: "all" -ANY: "any" -FILTER: "filter" -MAP: "map" -TYPE: "type" - -ANY_TYPE: "any" -STRING_TYPE: "str" -INT_TYPE: "int" -FLOAT_TYPE: "float" -BOOL_TYPE: "bool" - -// Constant tokens -TRUE: "True" -FALSE: "False" -NONE: "None" -UNDEFINED: "Undefined" - -// Binary prefix -SI_N_L: "n" -SI_U_L: "u" -SI_M_L: "m" -SI_K_L: "k" -SI_K: "K" -SI_M: "M" -SI_G: "G" -SI_T: "T" -SI_P: "P" -SI_K_IEC: "Ki" -SI_M_IEC: "Mi" -SI_G_IEC: "Gi" -SI_T_IEC: "Ti" -SI_P_IEC: "Pi" -IEC: "i" - -NAME: /\$?[a-zA-Z_]\w*/ -COMMENT: /#[^\n]*/ -NEWLINE: ( /\r?\n[\t ]*/ | COMMENT )+ - -STRING: /r?("(?!"").*?(? **note** -> -> Any character except the ASCII space, tab (`\t`) and formfeed (`\f`) is considered a none-space character. - -- A line ending in a backslash cannot carry a comment (, which will be introduced shortly afterwards). -- A backslash does not continue a comment. -- A backslash does not continue a token except for string literals (i.e., tokens other than string literals cannot be split across physical lines using a backslash). -- A backslash is illegal elsewhere on a line outside a string literal. - -### Implicit Line Joining - -Expressions in parentheses, square brackets or curly braces can be split over more than one physical line without using backslashes. - -- Implicitly continued lines can carry comments. -- The indentation of the continuation lines is not important. -- Blank continuation lines are allowed. -- There is no `NEWLINE` token between implicit continuation lines. -- Implicitly continued lines can also occur within triple-quoted strings (see below); in that case they cannot carry comments. - -### Blank Lines - -### Indentation - -### Comments - -Starting with a `#` character that is not part of a string literal is a comment. A comment ends at the end of the physical line. - -A comment signifies the end of the logical line unless the implicit line joining rules are invoked. - -Comments are ignored by the syntax. - -### Identifiers and Keywords - -Identifiers (also referred to as names) are described by the following lexical definitions. - -Within the ASCII range (from `U+0001` to `U+007F`), the valid characters for identifiers are the uppercase and lowercase letters `A` through `Z`, the underscore `_` and, except for the first character, the digits `0` through `9`. - -Identifiers are unlimited in length. The case is significant. - -### Keywords - -The following identifiers are used as reserved words, or keywords of the language, and cannot be used as ordinary identifiers. They must be spelled exactly as written here: - -```python -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -The following tokens are not used, but they are reserved as possible future keywords: - -```python -pass return validate rule flow -def del raise except try -finally while from with yield -global nonlocal struct class final -``` - -### Literals - -Literals are notations for constant values of some built-in types. - -### String Literals - -String literals are described by the following lexical definitions: - -``` -stringliteral ::= [stringprefix](shortstring | longstring) -stringprefix ::= "r" | "R" -shortstring ::= "'" shortstringitem* "'" | '"' shortstringitem* '"' -longstring ::= "'''" longstringitem* "'''" | '"""' longstringitem* '"""' -shortstringitem ::= shortstringchar | stringescapeseq -longstringitem ::= longstringchar | stringescapeseq -shortstringchar ::= -longstringchar ::= -stringescapeseq ::= "\" -``` - -Multiple adjacent string or bytes literals (delimited by whitespace),possibly using different quoting conventions, are allowed, and their meaning is the same as their concatenation. - -### Numeric Literals - -There are two types of numeric literals: integers and floating-point numbers. - -Integer literals are described by the following lexical definitions: - -``` -integer ::= decinteger | bininteger | octinteger | hexinteger -decinteger ::= nonzerodigit (["_"] digit)* | "0"+ (["_"] "0")* -bininteger ::= "0" ("b" | "B") (["_"] bindigit)+ -octinteger ::= "0" ("o" | "O") (["_"] octdigit)+ -hexinteger ::= "0" ("x" | "X") (["_"] hexdigit)+ -nonzerodigit ::= "1"..."9" -digit ::= "0"..."9" -bindigit ::= "0" | "1" -octdigit ::= "0"..."7" -hexdigit ::= digit | "a"..."f" | "A"..."F" -``` - -Floating-point literals are described by the following lexical definitions: - -``` -floatnumber ::= pointfloat | exponentfloat -pointfloat ::= [digitpart] fraction | digitpart "." -exponentfloat ::= (digitpart | pointfloat) exponent -digitpart ::= digit (["_"] digit)* -fraction ::= "." digitpart -exponent ::= ("e" | "E") ["+" | "-"] digitpart -``` - -## Operators and Delimiters - -### Operators - -The following tokens are operators: - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != @ -``` - -### Delimiters - -The following tokens serve as delimiters in the grammar: - -```python -( ) [ ] { } -, : . ; = += --= *= **= /= //= %= -<<= >>= &= |= ^= -``` - -The period can also occur in floating-point literals. - -The following printing ASCII characters have special meaning as part of other tokens or are otherwise significant to the lexical analyzer: - -``` -' " # \ -``` - -The following printing ASCII characters are not used in KCL. Their occurrence outside string literals and comments is an unconditional error: - -``` -? ` -``` - -## Reference - -Since the lexical conventions of KCL is very similar to that of Python, we use the following document as the reference when writing this chapter. - -- [https://docs.python.org/3/reference/lexical_analysis.html](https://docs.python.org/3/reference/lexical_analysis.html) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/modules.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/modules.md deleted file mode 100644 index f8608619..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/modules.md +++ /dev/null @@ -1,621 +0,0 @@ ---- -title: "Modules" -linkTitle: "Modules" -type: "docs" -weight: 2 -description: Modules ---- - -## Modules and the Import System - -KCL code is organized in **modules**. For code in one module to access the code defined in another module, a process called **importing** must be used. - -Importing is undertaken at compile-time in KCL. The advantage is to have static checking enabled. - -A regular KCL module is a file on the file system. It is required to have a `.k` suffix. - -## Packages - -To help manage modules and provide a naming hierarchy, KCL has the concept of packages. In KCL, a package maps to exactly a file system directory, and a regular module maps to a file. - -Files directly under a package are considered parts of the package, instead of individual regular modules. - -Packages can have sub-packages. - -Packages are special modules: - -- All packages in KCL are modules. -- A single-file module can never be a package. - -All modules have a name. - -Sub package names are separated from their parent package name by dots. - -To summary, a regular KCL module is a `.k` file, and a package is a directory on the file system. All `.k` files directly under the directory are included in the package, other files are ignored. If the directory has subdirectories, they become sub-packages as long as there are `.k` files underneath. - -### Intra-Package Name Space Sharing - -Inside a package, all `.k` files are considered parts of the package, instead of regular modules. Code in these files share a single name space and can access names defined in other files, without explicitly granted. - -### Package Initialization - -A package can have the initialization code. The code must exist in only one of the `.k` files under this package. The interpreter guarantees that the initialization code is executed after all definitions. - -## Searching - -The searching begins when an `import` statement is used to import a module. - -### Module Cache - -In KCL, only standard system modules are cached. When a cached module is imported, the cached version is used. In other words, KCL runtime would not create another copy of the standard system module in memory. - -However, other modules are uncached. Importing a module multiple time would create multiple instances of the module. - -### Module Names - -An `import` statement specifies the name of the module to import. The syntax is: - -``` -import [as ] -``` - -The rule to search with the module name is very simple: - -- **Step 1**: Searches the module name from the **standard system modules**, then **plugins modules**. - - See **standard system modules** and **plugins modules** for more details. If matched, the module is imported. Otherwise, continue to **Step 2**. -- **Step 2**. Whether a module name starts with a `.` is checked. If yes, the name is a so-called relative pathname, and we go to **Step 5**. Otherwise, continue to **Step 3**. -- **Step 3**: If the module name does not start with any `.`, then the compiler searches the nearest `root path` directory from this directory to the parent, and find the module according to the name just from the `root path`. If no `root path` is found, find the module according to the name from the folder the `.k` file including this `import` statement exists. - - **root path**: the directory contains a `kcl.mod` file. If matched, the module is imported. Otherwise, continue to **Step 4**. -- **Step 4**: Then the compiler checks if the name is the name of any library module that requires explicit loading. If matched, the library module is imported. Otherwise, continue to **Step 6**. -- **Step 5**. For relative importing, find the module according to the name from the folder the `.k` file including this `import` statement exists. Interpret leading dots using the following rule: -- One dot: Ignore. -- Tow or more dots: Suppose there are `n` leading dots, then the searching starts at `n - 1` levels above this folder. If matched, the module is imported. Otherwise, continue to **Step 6**. -- **Step 6**. Module not found, report an error. - -Do case-sensitive search when the operating system allows. If case-sensitive search is not allowed, search directories before regular files. - -In KCL, the `from <> import <>` is unsupported, and relative import is performed with the `import <>` syntax. - -### Uniqueness of Module - -Each module has a unique location path in its scope, so that a module or package could be located with a unique location path, such as `a.b.c`. - -Searching by location path should be supported by the kcl compiler, which needs to provide corresponding searching features through the command line and api form. - -## Standard System Packages - -KCL supports a few standard system modules. The following is the full list of these standard system modules: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PackageMember
datetimetoday
now
ticks
date
mathceil
exp
expm1
factorial
floor
gcd
isfinite
isinf
isnan
log
log1p
log2
log10
modf
pow
sqrt
regexreplace
match
compile
findall
search
split
unitsn
u
m
k
K
M
G
T
P
Ki
Mi
Gi
Ti
Pi
to_n
to_u
to_m
to_K
to_M
to_G
to_T
to_P
to_Ki
to_Mi
to_Gi
to_Ti
to_Pi
jsonencode
decode
dump_to_file
yamlencode
decode
dump_to_file
netsplit_host_port
join_host_port
fqdn
parse_IP
to_IP4
to_IP16
IP_string
is_IPv4
is_IP
is_loopback_IP
is_multicast_IP
is_interface_local_multicast_IP
is_link_local_multicast_IP
is_link_local_unicast_IP
is_global_unicast_IP
is_unspecified_IP
base64encode
decode
cryptomd5
sha1
sha224
sha256
sha384
sha512
- -- datetime - - ticks() -> float - Return the current time in seconds since the Epoch. Fractions of a second may be present if the system clock provides them. - - date() -> str - return the `%Y-%m-%d %H:%M:%S` format date. - - now() -> str - return the local time. e.g. `'Sat Jun 06 16:26:11 1998'` - - today() -> str - return the `%Y-%m-%d %H:%M:%S.%{ticks}` format date. -- math - - ceil(x) -> int - Return the ceiling of x as an Integral. This is the smallest integer >= x. - - factorial(x) -> int - Return x!. Raise a error if x is negative or non-integral. - - floor(x) -> int - Return the floor of x as an Integral. This is the largest integer <= x. - - gcd(a: int, b: int) -> int - Return the greatest common divisor of x and y - - isfinite(x) -> bool - Return True if x is neither an infinity nor a NaN, and False otherwise. - - isinf(x) -> bool - Return True if x is a positive or negative infinity, and False otherwise. - - isnan(x) -> bool - Return True if x is a NaN (not a number), and False otherwise. - - modf(x) -> Listfloat, float] - Return the fractional and integer parts of x. Both results carry the sign of x and are floats. - - exp(x) -> float - Return e raised to the power of x. - - expm1(x) -> float - Return exp(x)-1. This function avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small x. - - log(x, base=2.71828182845904523536028747135266250) -> float - Return the logarithm of x to the base e. - - log1p(x) -> float - Return the natural logarithm of 1+x (base e). The result is computed in a way which is accurate for x near zero. - - log2(x) -> float - Return the base 2 logarithm of x. - - log10(x) -> float - Return the base 10 logarithm of x. - - pow(x, y) -> float - Return x\*\*y (x to the power of y). - - sqrt(x) -> float - Return the square root of x. -- regex - - replace(string: str, pattern: str, replace: str, count=0) -> str - Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement. - - match(string: str, pattern: str) -> bool - Try to apply the pattern at the start of the string, returning a bool value True if any match was found, or False if no match was found. - - compile(pattern: str) -> bool - Compile a regular expression pattern, returning a bool value denoting whether the pattern is valid. - - findall(string: str, pattern: str) -> List[str] - Return a list of all non-overlapping matches in the string. - - search(string: str, pattern: str) -> bool - Scan through string looking for a match to the pattern, returning a bool value True if any match was found, or False if no match was found. - - split(string: str, pattern: str, maxsplit=0) -> List[str] - Scan through string looking for a match to the pattern, returning a Match object, or None if no match was found. -- units - - Unit constants - - Fixed point: `n`, `u`, `m`, `k`, `K`, `G`, `T` and `P`. - - Power of 2: `Ki`, `Mi`, `Gi`, `Ti` and `Pi`. - - Functions - - to_n(num: int) -> str - Int literal to string with `n` suffix - - to_u(num: int) -> str - Int literal to string with `u` suffix - - to_m(num: int) -> str - Int literal to string with `m` suffix - - to_K(num: int) -> str - Int literal to string with `K` suffix - - to_M(num: int) -> str - Int literal to string with `M` suffix - - to_G(num: int) -> str - Int literal to string with `G` suffix - - to_T(num: int) -> str - Int literal to string with `T` suffix - - to_P(num: int) -> str - Int literal to string with `P` suffix - - to_Ki(num: int) -> str - Int literal to string with `Ki` suffix - - to_Mi(num: int) -> str - Int literal to string with `Mi` suffix - - to_Gi(num: int) -> str - Int literal to string with `Gi` suffix - - to_Ti(num: int) -> str - Int literal to string with `Ti` suffix - - to_Pi(num: int) -> str - Int literal to string with `Pi` suffix -- json - - encode(data: any, sort_keys: bool = False, indent: int = None, ignore_private: bool = False, ignore_none: bool = False) -> str - Serialize a KCL object `data` to a JSON formatted str. - - decode(value: str) -> any - Deserialize `value` (a string instance containing a JSON document) to a KCL object. - - dump_to_file(data: any, filename: str, ignore_private: bool = False, ignore_none: bool = False) -> None - Serialize a KCL object `data` to a JSON formatted str and write it into the file `filename`. -- yaml - - encode(data: any, sort_keys: bool = False, ignore_private: bool = False, ignore_none: bool = False) -> str - Serialize a KCL object `data` to a YAML formatted str. - - decode(value: str) -> any - Deserialize `value` (a string instance containing a YAML document) to a KCL object. - - dump_to_file(data: any, filename: str, ignore_private: bool = False, ignore_none: bool = False) -> None - Serialize a KCL object `data` to a YAML formatted str and write it into the file `filename`. -- net - - split_host_port(ip_end_point: str) -> List[str] - Split the 'host' and 'port' from the ip end point. - - join_host_port(host, port) -> str - Merge the 'host' and 'port'. - - fqdn(name: str = '') -> str - Return Fully Qualified Domain Name (FQDN). - - parse_IP(ip) -> str - Parse 'ip' to a real IP address - - to_IP4(ip) -> str - Get the IP4 form of 'ip'. - - to_IP16(ip) -> int - Get the IP16 form of 'ip'. - - IP_string(ip: str | int) -> str - Get the IP string. - - is_IPv4(ip: str) -> bool - Whether 'ip' is a IPv4 one. - - is_IP(ip: str) -> bool - Whether ip is a valid ip address. - - is_loopback_IP(ip: str) -> bool - Whether 'ip' is a loopback one. - - is_multicast_IP(ip: str) -> bool - Whether 'ip' is a multicast one. - - is_interface_local_multicast_IP(ip: str) -> bool - Whether 'ip' is a interface, local and multicast one. - - is_link_local_multicast_IP(ip: str) -> bool - Whether 'ip' is a link local and multicast one. - - is_link_local_unicast_IP(ip: str) -> bool - Whether 'ip' is a link local and unicast one. - - is_global_unicast_IP(ip: str) -> bool - Whether 'ip' is a global and unicast one. - - is_unspecified_IP(ip: str) -> bool - Whether 'ip' is a unspecified one. -- base64 - - encode(value: str, encoding: str = "utf-8") -> str - Encode the string `value` using the codec registered for encoding. - - decode(value: str, encoding: str = "utf-8") -> str - Decode the string `value` using the codec registered for encoding. -- crypto - - md5(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `MD5` and the codec registered for encoding. - - sha1(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA1` and the codec registered for encoding. - - sha224(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA224` and the codec registered for encoding. - - sha256(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA256` and the codec registered for encoding. - - sha384(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA384` and the codec registered for encoding. - - sha512(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA512` and the codec registered for encoding. -- manifests - - `yaml_stream(values: [any], opts: {str:} = {sort_keys = False, ignore_private = True, ignore_none = False, sep = "---"}`. This function is used to serialize the KCL object list into YAML output with the `---` separator - -### The Built-in System Package - -KCL provides a list of built-in system modules, which are loaded automatically and can be directly used without providing any module name. For example, `print` is a widely used built-in module. - -The following is the full list of these built-in system modules: - -- print() - - The print function. -- multiplyof(a, b) - - Check if the modular result of a and b is 0 -- isunique(inval) - - Check if a list has duplicated elements -- len(inval) - Return the length of a value -- abs(x) - Return the absolute value of the argument. -- all(iterable) - Return True if bool(x) is True for all values x in the iterable. If the iterable is empty, return True. -- any(iterable) - Return True if bool(x) is True for any x in the iterable. If the iterable is empty, return False. -- bin(number) - Return the binary representation of an integer. -- hex(number) - Return the hexadecimal representation of an integer. -- oct(number) - Return the octal representation of an integer. -- ord(c) -> int - Return the Unicode code point for a one-character string. -- sorted(iterable) - Return a new list containing all items from the iterable in ascending order. A custom key function can be supplied to customize the sort order, and the reverse flag can be set to request the result in descending order. -- range(start, end, step=1) - Return the range of a value with start, end and step parameter. -- min(iterable) - With a single iterable argument, return its smallest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the smallest argument. -- max(iterable) - With a single iterable argument, return its biggest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the largest argument. -- sum(iterable, start) - Return the sum of a 'start' value (default: 0) plus an iterable of numbers. When the iterable is empty, return the start value. This function is intended specifically for use with numeric values and may reject non-numeric types. -- pow(x, y, z) - Equivalent to `x**y` (with two arguments) or `x**y % z` (with three arguments). Some types, such as ints, are able to use a more efficient algorithm when invoked using the three argument form. -- round(number, ndigits) - Round a number to a given precision in decimal digits. The return value is an integer if ndigits is omitted or None. Otherwise the return value has the same type as the number. ndigits may be negative. -- typeof(x: any, \*, full_name: bool = False) -> str - Return the type of the value 'x' at runtime. When the 'full_name' is 'True', return the full package type name such as `pkg.schema`. - -### Plugin Modules - -KCL compiler needs to provide the ability to dynamically expand and load plugin modules without modifying the compiler itself. KCL compiler needs to support flexible pluggable module extension mechanism, so that KCL users can use more abundant built-in function capabilities to simplify writing. - -KCL compiler needs to ensure the stability and safety of the expansion mechanism, without affecting the core of the compiler. - -Searching extended plugin module is performed after the standard system module. The standard system module has a higher priority in naming. If it exists a standard or built-in system module with the same name, the extended plugin module will be ignored. - -Importing and using the extended plugin module should be consistent with the standard or built-in system module. - -### Replacing Standard System Packages - -Replacing standard system modules is not allowed. - -## Examples - -We show more module features through an example. - -Suppose we have the following directories and files: - -``` - . - ├── mod1.k - ├── mod2.k - ├── pkg1 - │   ├── def1.k - │   ├── def2.k - │   └── def3init.k - └── pkg2 - ├── file2.k - └── subpkg3 - └── file3.k -``` - -From the structure we can see that `pkg1` and `pkg2` are two packages, `subpkg3` is a subpackage of `pkg2`, and `mod1.k` and `mod2.k` are regular modules. - -### Importing a Standard System Package - -The following statement can import the standard system module `math` - -```python -import math -``` - -This is the only way to import a standard system module. After importing a standard system module, functions, variables and schemas defined in it can be used. For example, the following statement uses the `log10` function -defined in `math` - -```python -a = math.log10(100) # a is 2 after computation. -``` - -### Importing a Regular Module - -In `mod1.k`, we can import `mod2` using one of the following syntaxes. - -```python -import mod2 -``` - -```python -import .mod2 -``` - -The difference is that in the first syntax, the KCL compiler will first try to check if `mod2` matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where `mod1.k` resists in, like what the second statement does. - -Suppose in `mod2.k` there is a definition of a variable:: - -```python -a = 100 -``` - -After importing `mod2`, we can access `a` in `mod1.k` using the following syntax - -```python -b = mod2.a -``` - -### Importing a Package - -In `mod1.k`, we can import `pkg1` using one of the following syntaxes. - -```python -import pkg1 -``` - -```python -import .pkg1 -``` - -The difference is that in the first syntax, the KCL compiler will first try to check if `pkg1` matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where `mod1.k` resists in, like what the second statement does. - -We can use similar statements to import `pkg2`. Note that importing `pkg2` will not import `subpkg3`. - -The name of the package is the name of the imported module. - -Suppose in `file2.k` that is inside `pkg2` there is a definition to variable `foo` - -```python -foo = 100 -``` - -This variable can be used in `mod1.k` after importing `pkg2` like the following - -```python -bar = pkg2.foo -``` - -### Importing a Subpackage - -To import `subpkg3` from `mod1.k`, one of the following statements can be used. - -```python -import pkg2.subpkg3 -``` - -```python -import .pkg2.subpkg3 -``` - -The behaviors of these statements are identical. - -The name of the subpackage is the name of the imported module. - -Suppose in `file3.k` that is inside `subpkg3` there is a definition to variable `foo` - -```python -foo = 100 -``` - -This variable can be used in `mod1.k` after importing `subpkg3` like the following - -```python -bar = subpkg3.foo -``` - -### Relative Importing - -Relative importing is useful when there is code trying to import modules that does not exist recursively inside the current directory. - -For example, the following statements, if written in `file3.k`, can be used to import `pkg2`, `pkg1` and `mod2` respectively. - -```python -import ...pkg2 # Go two levels up then import pkg2 -import ...pkg1 # Go two levels up then import pkg1 -import ...mod2 # Go two levels up then import mod2 -``` - -### Importing from a Root Path - -Suppose we have a `kcl.mod` file in the directory to mark it as a root path, then we have the following files: - -``` - . - |── kcl.mod - ├── mod1.k - ├── mod2.k - ├── pkg1 - │   ├── def1.k - │   ├── def2.k - │   └── def3init.k - └── pkg2 - ├── file2.k - └── subpkg3 - └── file3.k -``` - -In `pkg1` `def1.k`, we can import `pkg2.subpkg3` `file3` using the following syntaxes. - -```python -import pkg2.subpkg3.file3 -``` - -Importing from the root path is very convenient when the code is trying to import modules from a directory needs to look up multiple directories above this directory. At also, it is helpful to organize a large number of files in a root directory. - -### Importing a Module Inside a Package - -Note that `subpkg3` is only implemented with one file `file3.k`. The file can be regarded as a regular module and imported directly. - -In `mod1.k`, the importing statement would be:: - -```python -import pkg2.subpkg3.file3 -``` - -Different from importing `subpkg3`, now the name of the module is `file3`. We can access the variable `foo` defined in this module with the following -statement - -```python -bar = file3.foo -``` - -### Precedence of Importing - -When an import statement specifies a package to import, the virtual machine first looks for a directory named according to the import statement in the file system. - -If such a directory is not found, the virtual machine looks for a single file module. - -For example, when the statement `import a.b.c` appears, the virtual machine first looks for the directory `a/b/c` from the directory of the current file. If `a/b/c` is not found, the virtual machine looks for a file named `a/b/c.k`. If the file is also absent, an error is reported. - -### Package Implemented with Multiple Files - -Package `pkg1` is implemented with multiple KCL files. - -Multiple files can be used to define variables, schemas and functions, and they can access names defined in other files of this package. - -For example, suppose `def1.k` defines a variable `foo`, `def2.k` defines `bar`, and `def3init.k` defines a variable `baz`, when `pkg1` is imported by `mod1.k`, all these variable can be used - -```python -import pkg1 -a = pkg1.foo + pkg1.bar + pkg1.baz -``` - -Inside a module, names defined in a file can be accessed in another file without further importing. For example, suppose `bar` in `def2.k` would invoke `foo` defined in `def1.k`, it can directly use `foo` like the following - -```python -bar = foo + 1 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/schema.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/schema.md deleted file mode 100644 index c3d09f65..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/schema.md +++ /dev/null @@ -1,916 +0,0 @@ ---- -title: "Schema" -linkTitle: "Schema" -type: "docs" -weight: 2 -description: Schema ---- - -## Syntax - -### Schema Definition - -A schema is a language element to define a type of configuration data. - -To define a schema, the syntax is the following: - -```bnf -schema_stmt: [decorators] "schema" ["relaxed"] identifier ["[" [arguments] "]"] ["(" operand_name ")"] ":" NEWLINE [schema_body] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt | schema_index_signature | statement)* [check_block] _DEDENT -``` - -Attributes could be defined in a schema, the syntax is the following: - -```bnf -schema_attribute_stmt: [decorators] identifier ["?"] ":" type [(ASSIGN | augassign) test] NEWLINE -``` - -Index signature could be defined in a schema, the syntax is the following: - -```bnf -schema_index_signature: LEFT_BRACKETS [NAME COLON] [ELLIPSIS] basic_type RIGHT_BRACKETS COLON type [ASSIGN test] NEWLINE -``` - -Once defined, an attribute must have a valid type: - -```bnf -type: type_element ("|" type_element)* -type_element: schema_type | basic_type | list_type | dict_type -schema_type: operand_name -basic_type: "str" | "int" | "float" | "bool" -list_type: "[" (type)? "]" -dict_type: "{" (type)? COLON (type)? "}" -``` - -The followings are some basic examples: - -```python -# A person has a first name, a last name and an age. -schema person: - firstName: str - lastName: str - # fullName is generated by firstName and lastName - fullName: str = firstName + ' ' + lastName - # The default value of age is 0 - age: int = 0 - -# An employee IS a person, and has some additional information. -schema employee(person): - bankCard: int - nationality: str - -# A company has a name and many employees. -schema company: - name: str - employees: [employee] -``` - -More complex schema definitions will be elaborated after other concepts are -introduced. - -#### Optional Attribute - -Each attribute **must** be assigned with a not-None value as a schema instance unless it is modified by a question mark as an optional attribute. - -Examples: - -```bnf -schema employee(person): - bankCard?: int # bankCard is an optional attribute - nationality?: str # # nationality is an optional attribute -``` - -When there is an inheritance relationship: - -- If the attribute is optional in the base schema, it could be optional or required in the sub-schema. -- If the attribute is required in the base schema, it must be required in the sub-schema. - -### Configuration Definition - -A configuration is structured data stored in a dict-like structure. In KCL, we have introduced -the configuration definition syntax as a variant of dict definition syntax. - -```bnf -schema_expr: operand_name ("(" [arguments] ")")? dict_expr -``` - -As can be seen, apart from having an identifier as schema type, a configuration definition -is just an ordinary dict definition, and each key in the dict matches an attribute in the schema. - -To simplify configuration, schema attribute key is much easier to define as: - -- schema attribute key can be unquoted. When the attribute key has the same name as a variable, it must be quoted as a normal dict to avoid naming conflict. -- schema attribute key can be defined nested through `select expression`, such as `a.b.c`. - -The comma at the end of each line can be omitted. - -For example, we can define a `person` named `John Doe` using the following statement: - -```python -johnDoe = person { - # In the result, 'lastName' appears later than 'firstName', according the schema - lastName = 'Doe' - firstName = 'John' - # If we don't specify the 'age', the default value 0 is used. - # 'age': 20 -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' - 'age': 0 -} -``` - -Compared to the ordinary dict definition, a configuration definition has the following features: - -- Each attribute defined in the schema (or one of the schemas) could be configured, and config data has higher priority than the default value. -- When an attribute defined in the schema (or one of the schemas) is not configured in the configuration definition statement, and it has a default value, the default value is used. -- Unless the schema (or one of the schemas) is a **relaxed schema**, no more attributes can be defined. -- The quotation marks of dict key can be omitted. -- The comma at the end of each line can be omitted. -- Cases of **inheritance** will be discussed separately. - -For attributes of list, dict and schema types, the config data is added by **union** instead of reassignment. For instance: - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name = { - firstNam = "John" - lastName = "default" - } - -JohnDoe = Person { - name.lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' -} -``` - -#### Attribute Identify - -Each key identifier in the configuration expr identifies an element or a range of elements in a schema. The key identifier may consist of multiple attribute identifiers, and each attribute may be a basic type value, a list, a dict or schema. For example, the key identifier 'a.b.c' identifies the element 'c' in the 'A' schema: - -```python - -schema C: - c: int - -schema B: - b: C - -schema A: - a: B - -A { - a.b.c: 5 -} -``` - -To make the key identifier usage rules as clear as possible, we define the way of identifying with complex data types as follows. - -##### List - -Suppose we have a list attribute a. - -Identify an element in a: - -```python -a[0] # the first element -a[3] # the 4th element -a[-1] # the last element -a[-2] # the penultimate element -``` - -Identify a range of elements in the list: - -```python -a[2:5] # a slice of the third, 4th, and 5th elements -a[:5] # a slice of the first to 5th elements -``` - -#### Attribute Operator - -Once we identified the element(s), we can declare operation on it. It follows the pattern of `identifier op E`. - -#### Union - -Pattern: `identifier : E` - -The value of the expression `E` will be unioned into the element value. - -Examples: - -```python -a = A { - # union {d:4} into the element b.c, suppose c is a schema with an int type attribute d. - b.c : { - d : 4 - } -} -``` - -See 'union' in `expressions` spec for more details. - -#### Override - -Pattern: `identifier = E` - -The value of the expression `E` will override the element value. - -Examples: - -```python -a = A { - # override {c:4} to the element b, suppose b is a schema with an int type attribute c. - b = { - c: 4 - } -} -``` - -Unlike union, the override operation will reassign the element with a brand new value. -For basic type value, `union` and `override` have equivalent effects. - -Note: - -- Especially, we can "delete" its content by overriding the element to `Undefined`, such as `{ a = Undefined }`. - -#### Insert - -Pattern: `identifier += E` -Insert only works for list type `identifier`. - -List `E` will be inserted just after the specified index of the list `identifier`, and the following elements after the index will be automatically shifted. - -Examples: - -```python -a = A { - # insert {c:4} to the end position(just after index=1), suppose b is a list of schema with an int type attribute c. - b += { - c: 4 - } -} -``` - -If no index is specified, the last index will be used. - -The type of 'E' must be compatible with the type of list. See `types` for more details. - -#### Index Signature - -Index signatures can be defined in the KCL schema, and it means that the key-value constraints of the index signature can be used to construct a dict with the schema type, or additional checks can be added to the relaxed schema attributes to enhance the KCL type and semantic checks. - -- Use the form `[{attr_alias}: {key_type}]: {value_type}` to define an index signature in the schema, and `{attr_alias}` can be omitted. - -```python -schema Map: - """ - Map is a relaxed schema with a key of str type and a value of str type - """ - [str]: str # `{attr_alias}` can be omitted. - -data = Map { - key1 = "value1" - key2 = "value2" -} -``` - -- Mandatory all attributes of the schema key and value types - -```python -schema Person: - name: str - age: int # error, conflicts with the index signature definition `[str]: str` - [str]: str # The values of all attributes of the schema can only be strings -``` - -- Mandatory all attribute key and value types are defined in the schema, which is equivalent to restricting all attribute types except the relaxed attributes. - -```python -schema Person: - name: str - age: int - [...str]: str # Except for the `name` and `age` attributes, the key type of all other attributes of the schema must be `str`, and the value type must also be `str`. -``` - -- Define the index signature attribute alias and use it with the check block. - -```python -schema Data: - [dataName: str]: str - check: - dataName in ["Alice", "Bob", "John"] - -data = Data { - Alice = "10" - Bob = "12" - Jonn = "8" # error Jonn not in ["Alice", "Bob", "John"] -} -``` - -```python -import regex - -schema DataMap: - [attr: str]: str - check: - regex.match(attr, r'^[-._a-zA-Z0-9]+$') - -data = DataMap { - key1 = "value1" - "foo.bar" = "value2" # check error -} -``` - -### Schema Context - -The schema definition space can be regarded as a separate function context. - -Init statement could be defined inside the schema, the syntax is the following: - -```bnf -statement: small_stmt NEWLINE | if_stmt -``` - -The following is an example: - -```python -schema Person: - firstName: str = "John" - lastName: str - # fullName is generated by firstName and lastName in a separate init statement - fullName: str = firstName + ' ' + lastName - -JohnDoe = Person { - lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' -} -``` - -If statement, expr statement and assert statement are supported as a schema init -statement. See more in statement spec. - -- The attributes must be defined first, including inherited ones, and then used in the init statement. -- Statements in the schema context will be executed sequentially. -- The value of attributes referenced in the init statement will be evaluated at runtime. - See the **Configuration Definition** section for the assignment rules of non-referenced attributes. For example, `"fullName"` in Person is generated by `"firstName"` and `"lastName"` evaluated at runtime, in which firstName is 'John', and lastName is "Doe". - -The immutability of attributes in the schema context follows the same rules as the immutability of global variables: - -```python -schema Person: - age: int = 1 # Immutable attribute - _name: str = "Alice" # Mutable attribute - - age = 10 # Error - _name = "Bob" # Ok -``` - -#### Arguments - -Schema context can also have arguments. The following is an example. - -```python -schema Person[separator]: - firstName: str = "John" - lastName: str - fullName: str = firstName + separator + lastName - -JohnDoe = Person('_') { - lastName = "Doe" -} -``` - -The example is similar to the previous one, except that the separator character used in -the `"fullName"` member is passed in as an argument. The way to perform a schema generation -when the schema has an initialization function with arguments is demonstrated in the code. - -### Check Block - -Optionally, a check block can be added to a schema definition to allow -additional checking to be performed. - -The syntax is the following: - -```bnf -check_block: "check" ":" NEWLINE _INDENT check_expr+ _DEDENT -check_expr: test (IF test)? [":" primary_expr] NEWLINE -``` - -In terms of grammatical definition, a check block consists of a list of conditional expressions. The following is an example: - -```python -schema employee(person): - bankCard: int - gender: str - - check: - len(str(bankCard)) == 16 - gender in ['male', 'female'], "The gender {} is unsupported".format(gender) -``` - -The ability of KCL check expressions covers the abilities that can be defined by OpenAPI spec and is aligned with the ability of logical expressions. We consider further aligning the syntax with `CEL` spec. -Whether to support `lambda expressions` is still under discussion. - -Summary: - -- A check block consists of one or more logical **expressions**. -- When defining a configuration, the expressions in the check block are evaluated - in any order. If any of the expression is `False`, an error is reported. -- A custom error message can be provided after an expression. - -### Specifying Types - -Optionally, the type of any member of a schema can be specified. As previous examples have shown. - -A member can be of a basic type, such as a string (`str`), a floating-point number (`float`), a fixed-point number (`int`) or a boolean number (`bool`). - -A member can also be of a dictionary generated from another schema. In such a case, the name of the other schema is used as the type name. - -A member can also be a list or an ordinary dict: - -- A list with unspecified type of elements is `[]`. -- A list with elements of type `t` is `[t]`. Here `t` is another type. -- A dict with keys of type `kt` and values of type `vt` is `{kt:vt}`. -- `kt`, `vt` or both of them can be missing, like a list with unspecified type of elements. - -The followings are some more examples: - -- A list of lists of strings: `[[str]]`. -- A dict of keys with the type string and unspecified value types: `{str:}`. - -A member can be a **union type** defined by `|`, such as `a | b`, which means the type of the member could be a or b. - -A union type can include types of `int`, `str`, `float`, `bool`, `list` and `dict` and support type nesting e.g. `{str:str|int}` and `[[int|str]|str|float]`, etc. - -Examples: - -```python -schema x: - p: int | str # p could be defined as a int or string -``` - -### Immutability - -KCL pursues strict immutability of schema attributes. It's generally followed the rules: - -- For the attributes of the basic type, such as string, int and float, it's allowed to be reassigned - through the init statement in **schema context** or by the **configuration definition**. -- For the attributes of list, dict and schema type, it's allowed to be reassigned only by the init statement in **schema context**. The content of it is allowed to be operated in **schema context** or by the **configuration definition**. -- Any other attempt to reassign or modify schema attribute will report an error. - -#### Assign by Value - -When using a schema variable to assign the value to another variable, we can only get a deep copy of its value, not a pointer or reference. That is, modifying the assigned value will not change the assigned schema variable. - -```python -schema Person: - name: str - -person = { - name = "Alice" -} -personCopy = person # 'personCopy' is a deep copy of 'person' and modifying 'personCopy' will not affect 'person' -``` - -### Union Operator - -For list, dict and schema, we can union delta to existing data. For example: - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name = { - firstName = "John" - } - - # union a schema and a dict - name: Name { - lastName = "Doe" - } - -person = Person {} -``` - -The result is a **dict**: - -```python -{ - 'person': { - 'name': { - 'firstName': 'Jhon', - 'lastName': 'Doe' - } - } -} -``` - -### Other Operators - -Except for `assignment` and `union assignment`, it's not support other operators on schema type data. -Report an error if trying to use other operators on schema type data. - -### Deprecated - -The schema attribute can be marked as deprecated once it's considered invalid. - -```python -schema Person: - @deprecated(version="1.1.0", reason="use fullName instead", strict=True) - name: str - ... # Omitted contents - -person = Person { - # report an error on configing a deprecated attribute - name = "name" -} -``` - -- Deprecated attributes cannot be configured under any circumstances. Report an error or warning once the attribute is assigned. -- Define the expired version of the attribute through **version**, and define the reason for the attribute expired through **reason**. -- When strict is true, the attribute assignment will cause an error, otherwise it will report a warning and ignore the attribute assignment. - -### Composition - -The composition is a common way to define complex structures. KCL provides simplified means for the configuration definition of combined structures. - -Assuming we have the following schemas, which is defined by a combination of multiple schemas. - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name - age: int - -schema Group: - name: str - persons: [Person] -``` - -To config a group: - -```python -group = Group { - name = "group" - persons = [{ - name = { - firstName = "John" - lastName = "Doe" - } - age = 24 - }] -} -``` - -- Top-level schema name is required to config a schema. -- The schema of the attributes in the schema can be omitted. - -Multi-level nested schemas will make the configuration verbose. KCL supports defining attributes in the schema through `selector expression`. The selector form is **x.y.z**, see the following example: - -```python -group = Group { - name = "group" - persons = [{ - name.firstName = "John" - name.lastName = "Doe" - age = 24 - }] -} -``` - -- Selector can be used to represent attribute in a schema - -### Inheritance - -Inheritance is an effective means to define a hierarchical structure definition, and KCL supports limited **single inheritance** of the schema. - -```python -schema Person: - firstName: str - lastName: str - -# schema Scholar inherits schema Person -schema Scholar(Person): - fullName: str = firstName + '_' + lastName - subject: str - -JohnDoe = Scholar { - firstName = "John", - lastName = "Doe", - subject = "CS" -} -``` - -The result is a **dict**: - -```python -{ - 'JohnDoe': { - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' - 'subject': 'CS' - } -} -``` - -Each schema can be treated as a separated function context. Statements, including attribute statements and init statements, in the context of schemas will be evaluated from base schema to subschema according to the inheritance order. Each schema context is evaluated only once sequentially. The same goes for expressions in the check block. In the example, firstName and lastName are configured in the context of Person schema, and fullName is formed by splicing firstName and lastName in the context of Scholar schema. - -The default value can be modified in each schema. Value defined in **Configuration Definition** has a higher priority than the default value. Attributes with default values in any schema context ​​will eventually be unioned by configuration data. References to attributes in the schema context statements will use the value with unioned configuration data on evaluating at runtime. For example: - -```python -schema a: - x = 1 - y = x * 2 - -schema b(a): - x = 2 - -v = a { - x = 3 -} - -``` - -The result is a **dict**: - -```python -{ - 'v': { - 'x': 3 - 'y': 6 - } -} -``` - -Notes: - -- Report an error if inheriting more than one base schema. -- The type of the base schema attribute cannot be modified in the subschema. -- Report an error if inheriting a **mixin**. -- Report an error when a circular dependency occurs. - -Limitations: - -Since inheritance will derive some complex demands, we are cautious about these complex demands. There are still some restrictions on inheritance, and it's still under discussion. - -- KCL provides limited and deterministic polymorphism support, more complex and flexible polymorphism support, such as **self**, **super** keywords, are temporarily not included in the schema definition. -- Currently, KCL only supports the polymorphism of the inherited attributes of the schema, and does not support the polymorphism of the expressions in the check block. -- For the case of multiple levels of schema inheritance, the schema arguments can only be passed to the last level of sub-schema. - -### Mixin - -In addition to **composition** and **inheritance**, KCL supports declarative reuse of schema code through the **mixin** mechanism. To use a mixin, we only need to declare the **mixin** in the schema definition. - -The **mixin** syntax is the following: - -```bnf -//////////// mixin_stmt //////////// -mixin_stmt: "mixin" "[" [mixins | multiline_mixins] "]" "\n" -multiline_mixins: "\n" _INDENT mixins "\n" _DEDENT -mixins: operand_name ("," ("\n" mixins | operand_name))* -``` - -Here is a simple example: - -```python -schema Person: - mixin [FullNameMixin] - firstName: str = "default" - lastName: str - -schema FullNameMixin: - fullName: str = "{} {}".format(firstName, lastName) - -JohnDoe = Person { - firstName = "John" - lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'JohnDoe': { - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' - } -} -``` - -Multiple mixins can be added to a single schema, and mixins context will be evaluated after the host schema context at runtime. In the inheritance scenario, the mixin context can be regarded as a part of the host schema context, and the overall evaluation of schema context order is not affected. - -Notes: - -- The name of **mixin** schema must end with 'Mixin', otherwise an error will be reported. -- The attributes referenced in the **mixin** must be defined in the **mixin** itself or host schema, otherwise an error will be reported. - -### Protocol - -In addition to schema, an additional type definition method `protocol` is provided in KCL, and its properties are as follows: - -- In a protocol, only attributes and their types can be defined, complex logic and check expressions cannot be written, and mixins cannot be used. -- A protocol can only inherit or refer to other protocols, but cannot inherit or refer to other schemas. - -We can use **protocol** to add an optional host type to the dynamically inserted **mixin**. - -The **mixin** can define its host type through the `for` keyword, and internally it will query the type corresponding to the attribute from the host type. - -```python -protocol DataProtocol: # A mixin host type - data: str - -mixin DataMixin for DataProtocol: # Using the `for` keyword to define a mixin host type - x: int = data # The type of `data` is `str`, which is from `data` of `DataProtocol` -``` - -In `DataMixin`, the `data` attribute is obtained according to the `DataProtocol` host type as `str` type, and then a type error will occur when the value is assigned to `x` of type `int`: - -```python -protocol DataProtocol: - data: str - -mixin DataMixin for DataProtocol: - x: int = data # Error: expect int, got str - x: str = data # Error: can't change schema field type of 'x' from int to str -``` - -Please note that the host type **protocol** can only be used for **mixin** definitions (the suffix name is `Mixin`), otherwise an error will be reported. - -```python -protocol DataProtocol: - data: str - -schema Data for DataProtocol: # Error: only schema mixin can inherit from protocol - x: str = data -``` - -### Schema Context Evaluation - -The schema definition is composed of attribute statements, configuration data, init statements, mixins, and checks. In a separate schema context, the evaluation top-down order is as follows: - -``` -|------------------------------------------| -| attribute defaulting | -|------------------------------------------| -| configuration union | -|------------------------------------------| -| attribute templating | -|------------------------------------------| -| statements in declaration order | -|------------------------------------------| -| mixins in declaration order | -|------------------------------------------| -| check expressions in any order | -|------------------------------------------| -``` - -In the case of schema inheritance, each schema context is evaluated from the base schema in the order of inheritance, and each context is evaluated only once. -Suppose there are schemas a, b, and c, where c inherits b and b inherits a. Schema contexts will be evaluated in top-down order as: - -``` -|-----------------| -| schema a | -|-----------------| -| schema b | -|-----------------| -| schema c | -|-----------------| -``` - -### Members - -Built-in function and members of schema - -- instances() - Return the list of existing instances of a schema. - -### Irrelevant Order Calculation - -The irrelevant order calculation in the schema indicates the reference relationship between the internal attributes of the schema. For example, when we declare an expression of the form `a = b + 1`, the calculation of the value of `a` depends on the calculation of the value of `b`. When the compiler calculate the value of `a` and the value of `a` depends on the value of `b`, the compiler will choose to first calculate the value of `b`, and then calculate the value of a according to the expression `a = b + 1`, which is slightly different from the calculation method of traditional procedural language the difference. - -Since the calculation of values in the schema is based on dependencies, just like a directed acyclic graph traverses each node in the graph according to the order of topological sorting, the order of declaration of attributes in the schema is not so important, so the feature is called the irrelevant order calculation. - -Please note that there can be no circular references between different schema attribute values. - -We can see this feature through the following examples. - -```python -schema Person: - name?: str - age: int = _age - - _age = 10 - - if name == "Son": - _age = 18 - -schema Son(Person): - name: str = "Son" - -person = Person {} -son = Son {} -``` - -The output is - -```yaml -person: - name: null - age: 10 -son: - name: Son - age: 18 -``` - -Besides, we can achieve KCL polymorphism such as - -```python -schema Person: - name?: str - _age: int = _age - - _age = 10 - if name == "Son": - _age = 18 - elif name == "SonConf": - _age = 24 - -schema Son(Person): - name: str = "Son" - -person = Person() {} -son = Son() { - name = "SonConf" -} -``` - -The output is - -```yaml -person: - name: null - age: 10 -son: - name: SonConf - age: 24 -``` - -More examples: - -```python -schema Fib: - n1: int = n - 1 - n2: int = n1 - 1 - n: int - value: int = _value - - if n <= 2: - _value = 1 - else: - _value = (Fib {n = n1}).value + (Fib {n = n2}).value - -fib8 = (Fib {n = 8}).value -``` - -The output is - -```yaml -fib8: 21 -``` - -As in the above examples, we can see that in the schema, we only need to simply specify the dependency between attributes, and the compiler will automatically calculate the value based on the dependency, which can help us save a lot of boilerplate code and reduce configuration difficulty of writing. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/statements.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/statements.md deleted file mode 100644 index b09488b9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/statements.md +++ /dev/null @@ -1,185 +0,0 @@ ---- -title: "Statements" -linkTitle: "Statements" -type: "docs" -weight: 2 -description: Statements ---- - -## Syntax - -In KCL, statements consist of small statements and compound statements. The syntax is the following: - -```bnf -preamble_statement: preamble_small_stmt | preamble_compound_stmt -preamble_small_stmt: (small_stmt | import_stmt) NEWLINE -preamble_compound_stmt: compound_stmt | schema_stmt -statement: small_stmt NEWLINE | compound_stmt -compound_stmt: if_stmt -small_stmt: assign_stmt | expr_stmt | assert_stmt -``` - -The preamble statement is used to define the module level statements, consist of `statement`, `import_stmt`, and `schema_stmt`. The statement is used to define the block level statements, which are used in the `if` statement and `schema` statement. - -### Small Statements - -A small statement is comprised of a single logical line. Multiple statements in one-line are not allowed. - -#### Assignment Statements - -Generally, assign_stmt is divided into assignment and augmented assignment. The syntax is the following: - -```bnf -assign_stmt: target_primary ("=" target_primary)* "=" test | target_primary augassign test -augassign: "+=" | "-=" | "*=" | "**=" | "/=" | "//=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>=" | "or" | "and" -target_primary: identifier | target_primary DOT identifier -``` - -An assignment statement has the form `lhs = rhs`. It evaluates the expression on the right-hand side then assigns its value (or values) to the variable (or variables) on the left-hand side. - -The **target_primary** on the left-hand side is an `identifier` or an `identifier` followed by select dots. - -Note: When using **target_primary** will cause collisions, use **primary_expr** as an alternative. - -Examples: - -```python -k = 1 -a.b = "a.b" -``` - -To keep it simple, the compound target is not supported as **target_primary**. - -The right value of an assignment statement is a conditional expression, which is discussed separately. - -An augmented assignment, which has the form `lhs op= rhs` updates the variable `lhs` by applying a binary arithmetic operator op (one of +, -, \*, /, //, %, &, |, ^, <<, >>) to the previous value of `lhs` and the value of `rhs`. - -The **target_primary** on the left-hand side is the same as assignment statement. Examples: - -```python -_x -= 1 -_filename += ".k" -``` - -There is no concept of in-place modification in KCL. The `augassign` statement will modify a copy of the **target_primary** and assign the copy to **target_primary**. - -In particular, in KCL, the `|=` symbol represents the **union** operation, which is defined as follows: - -- The behavior of the **union** operation needs to be consistent with the behavior of the **configuration definition**. - -See **expressions** spec for more details of union operator in **Arithmetic Operations**. - -#### Expression Statements - -An expression statement evaluates an expression and discards its result. - -Syntax: - -```bnf -expr_stmt: expression -``` - -An expression statement supported in KCL is function invocation expression, which is discussed in **expression** spec. - -```python -print(k) # print a variable -``` - -#### Import Statements - -Import statements are used to **search** and **load** a module, and define a name or names in the local namespace for the scope where the import statement occurs. - -Syntax: - -```bnf -import_stmt: "import" dot_name ("as" NAME)? -dot_name: [leading_dots] identifier (DOT identifier)* -leading_dots: "."+ -``` - -Examples: - -```python -import math # import a built-in module math -import pkg # import pkg -import pkg.foo # import pkg.foo -import pkg.subpkg # import a subpkg in a pkg -import .pkg2.subpkg3 # import a subpkg in a pkg inside of current pkg -import ...pkg2 # Go two levels up then import pkg2 -``` - -See **module** spec for more details of module spec. - -#### Assert Statements - -Assert statements are a convenient way to insert debugging assertions into KCL code. - -The syntax is the following: - -``` -assert_stmt: ASSERT test ("," test)? -``` - -The conditional expression in assert will be evaluated and get a boolean. Report an error if returning a `False`. - -Examples: - -```python -assert: x > 1 # report an error on x <= 1 -``` - -#### Conditional Statements - -KCL allows using conditional statements to control the instructions to -be executed. They are also called the control-flow statements. - -The only type of control-flow syntax is the well-known `if-elif-else` syntax. - -The syntax of the `if-elif-else` statement is the following. - -```bnf -if_stmt: "if" test ":" suite ("elif" test ":" suite)* (ELSE ":" suite)? -suite: small_stmt | NEWLINE _INDENT statement+ _DEDENT -``` - -An `if` or `elif` statement evaluates a given expression. When the expression -is evaluated to `True`, a list of statements following `:` are executed. - -The following is an example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - print("maybe a is negative") -else: - print("a >= 100") -``` - -`if-elif-else` statements can be nested. For example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - if a < 0: - print("a is negative") - print("No matter a is negative or positive, this message is printed") -else: - print("a >= 100") -``` - -#### Schema Statements - -Schema statements are used to define a type of configuration data. The syntax is the following: - -```bnf -schema_stmt: [decorators] "schema" ["relaxed"] identifier ["[" [arguments] "]"] ["(" operand_name ")"] ":" NEWLINE [schema_body] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt | statement)* [check_block] _DEDENT -``` - -See **schema** spec for more details of schema spec. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/types/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/types/_category_.json deleted file mode 100644 index a8f40915..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/types/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "类型系统", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/types/types.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/types/types.md deleted file mode 100644 index 182ffaf2..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/types/types.md +++ /dev/null @@ -1,1401 +0,0 @@ -# 类型系统 - -本文档描述 KCL 的类型系统,包括: - -- 类型规则 -- 类型检查 -- 类型转换 -- 类型推导 - -## 类型规则 - -### 基础定义 - -#### 断言 - -$S$ 的所有自由变量都定义在 $\Gamma$ 中 - -$$ -\Gamma \vdash S -$$ - -$\Gamma$ 是一个变量的类型声明环境(well-formed environment),如:$x_1:T_1$, ..., $x_n:T_n$ - -$S$ 的断言有三种形式: - -**环境断言** 断言表示 $\Gamma$ 是良构类型 (well-formed type) - -$$ -\Gamma \vdash ◇ -$$ - -**良构类型断言** 在环境 $\Gamma$ 下,$nat$ 是类型表达式 - -$$ -\Gamma \vdash nat -$$ - -**类型判断断言** 在环境 $\Gamma$ 下,$E$ 具有类型 $T$ - -$$ -\Gamma \vdash E: T -$$ - -#### 推理规则 - -表示法 - -$$ -\frac{\Gamma \vdash S_1, ..., \Gamma \vdash S_n}{\Gamma \vdash S} -$$ - -推理规则中的 $u$, $v$, $w$ 用于表示变量,$i$, $j$, $k$ 用于表示整数,$a$, $b$ 用于表示浮点数,$s$ 用于表示字符串,$c$ 代表常量(整数、浮点数、字符串、布尔)的字面值, $f$ 用于表示函数, $T$, $S$, $U$ 用于表示类型。 - -## 环境规则 - -Env ⌀ - -$$ -\frac{}{⌀ \vdash ◇ } -$$ - -## 类型定义 - -Type Bool - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash boolean} -$$ - -Type Int - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash integer} -$$ - -Type Float - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash float} -$$ - -Type String - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash string} -$$ - -Type Literal - -$$ -\frac{ c \in \{boolean, integer, float, string\}}{\Gamma \vdash literalof(c)} -$$ - -Type List - -$$ -\frac{\Gamma \vdash T \ T \neq Void}{\Gamma \vdash listof(T) } -$$ - -Type Dict - -$$ -\frac{\Gamma \vdash T_1 \ \Gamma \vdash T_2\ T_1 \neq Void \ \ T_2 \neq Void}{\Gamma \vdash dictof(T_k=T_1, T_v=T_2)} -$$ - -Type Struct - -$$ -\frac{\Gamma \vdash T_{1} \ ... \ \Gamma \vdash T_{n} \ \ T_i \neq Void \ K_1 \neq K_n}{\Gamma \vdash structof(K_1 : T_{1}, ... , K_n : T_{n})} -$$ - -Type Union - -$$ -\frac{\Gamma \vdash T_1 \ ... \ \Gamma \vdash T_n \ \ T_i \neq Void}{\Gamma \vdash unionof(T_1, ..., T_n)} -$$ - -Type None - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash None} -$$ - -Type Undefined - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Undefined} -$$ - -Type Void - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Void} -$$ - -Type Any - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Any} -$$ - -Type Nothing - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Nothing} -$$ - -## 类型判断规则 - -### Operand Expr - -Exp Truth - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash true: boolean} -$$ - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash false: boolean} -$$ - -Exp Int - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash int: integer} -$$ - -Exp Flt - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash flt: float} -$$ - -Exp Str - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash str: string} -$$ - -Exp None - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash none: none} -$$ - -Exp Undefined - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash undefined: undefined} -$$ - -Expr ListExp - -$$ -\frac{\Gamma \vdash E_1: T_1 \ E_2: T_2 \ ... \ E_n: T_n}{\Gamma \vdash [E_1, E_2, ..., E_n]: listof \ sup(T_1, T_2, ..., T_n)} -$$ - -Expr ListComp - -$$ -\frac{\Gamma \vdash E_1: T_1 \ \Gamma \vdash v: T \ \Gamma \vdash E_2: listof \ T \ \Gamma \vdash E_3: boolean}{\Gamma \vdash [E_1 \ for \ v \ in \ E_2 \ if \ E_3]: listof(T_1) } -$$ - -Expr DictExp - -$$ -\frac{\Gamma \vdash E_{k1}: T_{k1} \ \Gamma \vdash E_{v1}: T_{v1} \ ... \ \Gamma \vdash E_{kn}: T_{kN} \ \Gamma \vdash E_{vn}: T_{vN}}{\Gamma \vdash \{E_{k1}: E_{v1}, ..., E_{{kn}}: E_{vn}\}: dictof(T_{k}=sup(T_{k1}, T_{k2}, ... T_{kn}), \ T_{v}=sup(T_{v1}, T_{v2}, ..., T_{vn}))} -$$ - -Expr DictComp - -$$ -\frac{\Gamma \vdash E_1: T_{rki} \ \Gamma \vdash E_2: T_{rvi} \ \Gamma \vdash v_1: T_k \ \Gamma \vdash v_2: T_v \ \Gamma \vdash E_3: dictof(T_{k}, \ T_{v}) \ \Gamma \vdash E_4: boolean}{\Gamma \vdash \{E_1:E_2 \ for \ (v_1, v_2) \ in \ E_3 \ if \ E_4\}: dictof(T_{k}=sup(T_{rk1}, T_{rk2}, ..., T_{rkn}), T_{v}=sup(T_{rv1}, T_{rv2}, ..., T_{rvn})) } -$$ - -Expr StructExpr - -$$ -\frac{\Gamma \vdash E_{1}: T_{1} \ ... \ \Gamma \vdash E_{n}: T_{n} \ K_1 \neq K_n}{\Gamma \vdash \{K_{1} = E_{1}, ..., K_{{n}} = E_{n}\}: structof(K_1 : T_{1}, ... , K_n : T_{n})} -$$ - -Literal 类型是基础类型的值类型,Union 类型是类型的组合类型,Void、Any、Nothing 是特殊的类型指代,本身没有直接的值表达式对应关系。 - -### Primary Expr - -Expr Index - -$$ -\frac{\Gamma \vdash E: listof(T) \ \Gamma \vdash Index: integer}{\Gamma \vdash E[Index]: T} -$$ - -Expr Call - -$$ -\frac{\Gamma \vdash E_1: T_1 \rightarrow T_2 \ \Gamma \vdash E_2: T_1}{\Gamma \vdash E_1 \ (E_2): T_2} -$$ - -Expr List Selector - -$$ -\frac{\Gamma \vdash E: listof(T) \ \Gamma \vdash Index: integer}{\Gamma \vdash E.[Index]: T} -$$ - -Expr Dict Selector - -$$ -\frac{\Gamma \vdash E: dictof(T_k = T_1, T_v=T_2) \ \Gamma \vdash S_1: string \ ... \ \Gamma \vdash S_n: string}{\Gamma \vdash E.\{S_1, ..., S_n\}: dictof(T_k = T_1, T_v=T_2)} -$$ - -Expr Struct Selector - -$$ -\frac{\Gamma \vdash E: structof(K_1 : T_{1}, ... , K_n : T_{n}) \ \Gamma \vdash K_i: string}{\Gamma \vdash E.K_i: T_{i}} -$$ - -### Unary Expr - -Expr + - -$$ -\frac{\Gamma \vdash E: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash \ +E: T} -$$ - -Expr - - -$$ -\frac{\Gamma \vdash E: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash \ -E: T} -$$ - -Expr ~ - -$$ -\frac{\Gamma \vdash E: integer}{\Gamma \vdash \ ~E: integer} -$$ - -Expr not - -$$ -\frac{\Gamma \vdash E: boolean}{\Gamma \vdash \ not \ E: boolean} -$$ - -### Binary Expr - -算数运算符 - -Expr op, op $\in$ {-, /, %, \*\*, //} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash E_1 \ op \ E_2: T} -$$ - -Expr + - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, float, string, listof(T_1)\}}{\Gamma \vdash E_1 \ + \ E_2: T} -$$ - -Expr \* - -$$ -\frac{\Gamma \vdash E_1: T_1 \ \ \ \Gamma \vdash E_2: T_2 \ \ \ \ (T_1==T_2 \in \{integer, float\}) \ or \ (T_1 == interger \ and \ T_2 \ \in \ \{string, listof(T_3)\}) \ or \ (T_2 == interger \ and \ T_1 \ \in \ \{string, listof(T_3)\})} {\Gamma \vdash E_1 \ * \ E_2: T} -$$ - -示例 - -Expr % - -$$ -\frac{\Gamma \vdash E_1: interger \ \ \ \Gamma \vdash E_2: integer}{\Gamma \vdash E_1 \ \% \ E_2: interger} -$$ - -逻辑运算符 - -Expr op, op $\in$ \{or, and\} - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ op \ E_2: boolean} -$$ - -示例 - -Expr and - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ and \ E_2: boolean} -$$ - -比较运算符 - -Expr op, op $\in$ \{==, !=, <, >, <=, >=\} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T}{\Gamma \vdash E_1 \ op \ E_2: boolean} -$$ - -示例 - -Expr > - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ > \ E_2: boolean} -$$ - -位运算符 - -Expr op, op $\in$ {&, ^, ~, <<, >>} - -$$ -\frac{\Gamma \vdash E_1: integer \ \ \ \Gamma \vdash E_2: integer}{\Gamma \vdash E_1 \ op \ E_2: integer} -$$ - -Expr | - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, listof(T_1), dictof(T_k, T_v), structof(K_1=T_1, ..., K_n=T_n)\}}{\Gamma \vdash E_1 \ | \ E_2: T} -$$ - -成员运算符 - -Expr op, op $\in$ {in, not in} - -$$ -\frac{\Gamma \vdash E_1: string \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{dictof, structof\}}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -Expr op, op $\in$ {in, not in} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: listof(S), T \sqsubseteq S}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -身份运算符 - -Expr op $\in$ {is, is not} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -### IF Expr - -Expr If - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: T \ \ \ \Gamma \vdash E_3: T}{\Gamma \vdash if \ E_1 \ then \ E_2 \ else \ E_3: T} -$$ - -### Stmt - -Stmt If - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash S_1: Void \ \ \ \Gamma \vdash S_2: Void}{\Gamma \vdash if \ E_1 \ then \ S_1 \ else \ S_2: Void} -$$ - -Stmt Assign - -$$ -\frac{\Gamma \vdash id: T_0 \ \ \ \Gamma \vdash T_1 \ \ \ \Gamma \vdash E: T_2}{\Gamma \vdash id: T_1 \ = \ E : Void} -$$ - -Type Alias - -$$ -\frac{\Gamma \vdash id: T_0 \ \ \ \Gamma \vdash T_1}{\Gamma \vdash type \ id \ = \ T_1 : Void} -$$ - -## Union - -### Union 规则 - -List Union - -$$ -\frac{\Gamma \vdash \ listof(T) \ \ \ \Gamma \vdash \ listof(S)}{\Gamma \vdash \ listof(unionof(T, S))} -$$ - -Dict Union - -$$ -\frac{\Gamma \vdash \ dictof(T_1, T_2) \ \ \ \Gamma \vdash \ dictof(S_1, S_2)}{\Gamma \vdash \ dictof(unionof(T_1, S_1), unionof(T_2, S_2))} -$$ - -Struct Union - -给定两个结构体 $structof(K_{1}: T_{1}, ..., K_{n}: T_{n}),structof(H_{1}: S_{1}, ..., H_{m}: S_{n})$ - -定义他们的 union 类型: - -$$ -structof(J_{1}: U_{1}, ..., J_{p}: U_{n}) = structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \bigcup structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) -$$ - -例如: - -$$ -structof() \ \bigcup \ structof(H_{1}: T_{1}, ..., H_{m}: T_{n}) = structof(H_{1}: T_{1}, ..., H_{m}: T_{n}) -$$ - -$$ -structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \ \bigcup \ structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) = structof(K_1: T_1) :: (structof(K_{2}: T_{2}, ..., K_{n}: T_{n}) \ \bigcup \ structof(H_{1}: S_{1}, ..., H_{m}: S_{n})) -$$ - -其中把 "::" 表示把一个对偶加入到一个结构的操作,定义如下: - -$$ -structof(K_{1}: T_{1}) :: structof() = structof(K_{1}: T_{1}) -$$ - -$$ -structof(K_{1}: T_{1}) :: structof(K_{1}: T_{1}', ..., K_n: T_{n}) = structof(K_{1}: union\_op(T_{1}, T_{1}'), ..., K_{n}: T_{n}) -$$ - -$$ -structof(K_{1}: T_{1}) :: structof(K_{2}: T_{2}, ..., K_n: T_{n}) = structof(K_{2}: T_2) :: structof(K_{1}: T_1) :: structof(K_{3}: T_3, ..., K_{n}: T_{n}) -$$ - -基于此,两个 Struct 的 union 定义为: - -$$ -\frac{\Gamma \vdash structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \ \Gamma \vdash structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) \ structof(J_{1}: U_{1}, ..., J_{p}: U_{n}) = structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \bigcup structof(H_{1}: S_{1}, ..., H_{m}: S_{n})}{\Gamma \vdash structof(J_{1}: U_{1}, ..., J_{p}: U_{n}))} -$$ - -其中 $union\_op(T_1, T_2)$ 表示对相同 $K_i$ 的不同类型的判断操作: - -- 当 $T_1$ 与 $T_2$ 有偏序关系时, 如果 $T_1 \sqsubseteq T_2$ 时,返回 $T_2$,否则返回 $T_1$,即取最小上界 -- 当 $T_1$ 与 $T_2$ 不存在偏序关系时,有三种可选的处理逻辑: - - 结构体 union 失败,返回 type_error - - 返回后者的类型,此处为 $T_2$ - - 返回类型 $unionof(T_1, T_2)$ - -此处需要根据实际需求选择适当的处理方式。 - -结构体继承可以看做一种特殊的 union,整体逻辑与 union 相似,但在 $union\_op(T_1, T_2)$ 中对相同 $K_i$ 的不同类型的判断操作如下: - -- 当 $T_1$ 与 $T_2$ 有偏序关系且 $T_1 \sqsubseteq T_2$ 时,返回 $T_1$,即仅当 $T_1$ 是 $T_2$ 的下界时以下界 $T_1$ 为准 -- 否则返回 type_error - -通过这样的继承设计可以实现分层的、自下而上逐层收缩的类型定义。 - -## Operation - -KCL 支持对结构体属性进行如 `p op E` 形式的操作。 即对给定结构体 $A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})$, 对结构体中的路径 `p` 以 `E` 的值进行指定的操作(如 union,assign,insert 等)。 - -定义如下更新操作: - -$$ -\frac{{\Gamma\vdash A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})}  {\Gamma\vdash p \in (K_{1}, ..., K_{n})} \ {\Gamma\vdash e:T}   k \neq k_1, ..., k \neq k_n} -{ A \{p \ op \ e\}:\{K_1:T_1, ..., K_n:T_n\}∪\{p:T\}} -$$ - -即对路径 $p$ 进行操作本质上是对两个结构体的一种 union,对同名属性类型 union 时的规则根据情况而定。例如路径 $p$ 是一个可用作字段名的标识符 $p=k_1$,并且结构体 A 中字段名也是 $k_1$,它的类型为 $T_1$,并且表达式 $e$ 的类型也为 $T_1$ ,那么 - -$$ -\frac{{\Gamma\vdash A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})}  {\Gamma\vdash p = K_{1}} \ {\Gamma\vdash e:T_1}   k \neq k_1, ..., k \neq k_n} -{ A \{p \ op \ e\}:\{K_1:T_1, ..., K_n:T_n\}} -$$ - -注意: - -- 此处表达式 $e$ 的类型 $T_1$ 同原先同名属性 $K_1$ 的具有相同的类型。可根据实际情况需要适当放松,如 $e$ 的类型 $\sqsubseteq T_1$ 即可。 -- 对于多层结构体嵌套的操作,递归的使用以上规则即可。 - -## 类型偏序 - -### 基础类型 - -$$ -Type \ T \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ T -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Bool \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Int \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Float \sqsubseteq Type \ Any -$$ - -$$ -Type \ Int \sqsubseteq Type \ Float -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ String \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Literal \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ List \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Dict \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Struct \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ None \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Void \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Any -$$ - -### 字面值类型 - -$$ -Type \ Literal(Bool) \sqsubseteq Type \ Bool -$$ - -$$ -Type \ Literal(Int) \sqsubseteq Type \ Int -$$ - -$$ -Type \ Literal(Float) \sqsubseteq Type \ Float -$$ - -$$ -Type \ Literal(String) \sqsubseteq Type \ String -$$ - -### 联合类型 - -$$ -Type \ X \sqsubseteq Type \ Union(X, Y) -$$ - -### 自反 - -$$ -Type \ X \sqsubseteq Type \ X -$$ - -示例 - -$$ -Type \ Bool \sqsubseteq Type \ Bool -$$ - -$$ -Type \ Int \sqsubseteq Type \ Int -$$ - -$$ -Type \ Float \sqsubseteq Type \ Float -$$ - -$$ -Type \ String \sqsubseteq Type \ String -$$ - -$$ -Type \ List \sqsubseteq Type \ List -$$ - -$$ -Type \ Dict \sqsubseteq Type \ Dict -$$ - -$$ -Type \ Struct \sqsubseteq Type \ Struct -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Nothing -$$ - -$$ -Type \ Any \sqsubseteq Type \ Any -$$ - -$$ -Type \ Union(Type Int, Type Bool) \sqsubseteq Type \ Union(Type Int, Type Bool) -$$ - -### 传递 - -$$ -Type \ X \sqsubseteq Type \ Z \ if \ Type \ X \sqsubseteq Type \ Y \ and \ Type \ Y \sqsubseteq \ Type \ Z -$$ - -### 包含 - -$$ -Type \ List(T_1) \sqsubseteq Type \ List(T_2) \ if \ T_1 \sqsubseteq T_2 -$$ - -$$ -Type \ Dict(T_{k1}, T_{v1}) \sqsubseteq Type \ Dict(T_{k2}, T_{v2}) \ if \ T_{k1} \sqsubseteq T_{k2} \ and \ T_{v1} \sqsubseteq T_{v1} -$$ - -$$ -Type \ Structure(K_1: T_{a1}, K_2: T_{a2}, ..., K_n: T_{an}) \sqsubseteq Type \ Structure(K_1: T_{b1}, K_2: T_{b2}, ..., K_n: T_{bn}) \ if \ T_{a1} \sqsubseteq T_{b1} \ and \ T_{a2} \sqsubseteq T_{b2} \ and \ ... \ and \ T_{an} \sqsubseteq T_{bn} -$$ - -### 继承 - -$$ -Type \ Struct \ A \sqsubseteq Type \ Struct \ B \ if \ A \ inherits \ B -$$ - -### None - -$$ -Type \ None \sqsubseteq Type \ X, X \notin \{Type \ Nothing, \ Type \ Void\} -$$ - -### Undefined - -$$ -Type \ Undefined \sqsubseteq Type \ X, X \notin \{Type \ Nothing, \ Type \ Void\} -$$ - -## 相等性 - -交换律 - -$$ -Type \ Union(X, Y) == Type \ Union(Y, X) -$$ - -示例 - -$$ -Type \ Union(Int, Bool) == Type \ Union(Bool, Int) -$$ - -结合律 - -$$ -Type \ Union(Union(X, Y), Z) == Type \ Union(X, Union(Y, Z)) -$$ - -示例 - -$$ -Type \ Union(Union(Int, String), Bool) == Type \ Union(Int, Union(String, Bool)) -$$ - -幂等性 - -$$ -Type \ Union(X, X) == Type \ X -$$ - -示例 - -$$ -Type \ Union(Int, Int) == Type \ Int -$$ - -偏序推导 - -$$ -Type \ Union(X, Y) == Type \ Y \ if \ X \sqsubseteq Y -$$ - -示例 - -假设 Struct A 继承 Struct B - -$$ -Type \ Union(A, B) == Type \ B -$$ - -幂等性是偏序自反的一个特例 - -### List - -$$ -Type \ List(X) == Type \ List(Y) \ if \ X == Y -$$ - -### Dict - -$$ -Type \ Dict(T_k, T_v) == Type \ Dict(S_k, S_v) \ if \ T_k == S_k \ and \ T_v == S_v -$$ - -### Struct - -$$ -Type \ Struct(K_1: T_{1}, K_2: T_{2}, ..., K_n: T_{n}) == Type \ Struct(K_1: S_{1}, K_2: S_{2}, ..., K_n: S_{n}) \ if \ T_{1} == S_{1} \ and \ ... \ and \ T_{n} == S_{n} -$$ - -### 偏序检查 - -$$ -Type \ X == Type \ Y \ if \ Type \ X \sqsubseteq Type \ Y \ and \ Type \ Y \sqsubseteq \ Type \ X -$$ - -## 基础方法 - -- sup(t1: T, t2: T) -> T: 根据类型偏序计算两类型 t1, t2 的最小上界。需要动态创建 union type。 -- typeEqual(t1: T, t2: T) -> bool: 比较两类型 t1, t2 是否相等。 -- typeToString(t: T) -> string: 自顶向下递归解析并转化类型成对应的字符串类型。 - -### Sup Function - -- 暂不考虑类型参数,条件类型等特性 -- 使用一个有序集合存储 UnionType 的所有类型 -- 使用一个全局的 Map 根据 UnionType 的名称存储产生的所有 UnionType -- 根据偏序关系计算类型之间的包含关系 - -```go -// The Sup function returns the minimum supremum of all types in an array of types -func Sup(types: T[]) -> T { - typeOf(types, removeSubTypes=true) -} - -// Build a sup type from types [T1, T2, ... , Tn] -func typeOf(types: T[], removeSubTypes: bool = false) -> T { - assert isNotNullOrEmpty(types) - // 1. Initialize an ordered set to store the type array - typeSet: Set[T] = {} - // 2. Add the type array to the ordered set for sorting by the type id and de-duplication - addTypesToTypeSet(typeSet, types) - // 3. Remove sub types according to partial order relation rules e.g. sub schema types - if removeSubTypes { - removeSubTypes(typeSet) - } - if len(typeSet) == 1 { - // If the typeSet has only one type, return it - return typeSet[0] - } - // 4. Get or set the union type from the global union type map - id := getIdentifierFromTypeSet(typeSet) - unionType := globalUnionTypeMap.get(id) - if !unionType { - unionType = createUnionType(typeSet) // Build a new union type - globalUnionTypeMap.set(id, unionType) - } - return unionType -} - -// Add many types into the type set -func addTypesToTypeSet(typeSet: Set[T], types: T[]) -> void { - for type in types { - addTypeToTypeSet(typeSet, type) - } -} - -// Add one type into the type set -func addTypeToTypeSet(typeSet: Set[T], type: T) -> void { - if isUnion(type) { - return addTypesToTypeSet(typeSet, toUnionOf(type).types) - } - // Ignore the void type check - if !isVoid(type) { - // De-duplication according to the type of id - typeSet.add(type) - } -} - -func removeSubTypes(types: Set[T]) -> void { - for source in types { - for target in types { - if !typeEqual(source, target) { - // If the two types have an inheritance relationship, the base class is retained, or if the two types have a partial order relationship according to the relation table. - if (isPartialOrderRelatedTo(source, target)) { - types.remove(source) - } - } - } - } -} - -// isPartialOrderRelatedTo function Determine whether two types have a partial order relationship `source \sqsubseteq target` -// according to the partial order relationship table and rules -func isPartialOrderRelatedTo(source: T, target: T) -> bool { - assert isNotNullOrEmpty(source) - assert isNotNullOrEmpty(target) - if isNoneOrUndefined(source) and !isNothing(target) and !isVoid(target) { - return true - } - if isAny(target) { - return true - } - if typeEqual(source, target) { - return true - } - if isUnion(target) and source in target.types { - return true - } - // Literal Type - if (isStringLiteral(source) and isString(target)) or \ - (isBooleanLiteral(source) and isBool(target)) or \ - (isIntLiteral(source) and isInt(target)) or \ - (isFloatLiteral(source) and isFloat(target)) { - return true - } - if isInt(source) and isFloat(target) { - return true - } - if isList(source) and isList(target) { - return isPartialOrderRelatedTo(toListOf(source).eleType, toListOf(target).eleType - } - if isDict(source) and isDict(target) { - return isPartialOrderRelatedTo(toDictOf(source).keyType, toDictOf(target).keyType) and isPartialOrderRelatedTo(toDictOf(source).valueType, toDictOf(target).valueType) - } - if isStruct(source) and isStruct(target) { - if isTypeDerivedFrom(source, target) { - return true - } - // Empty Object - if len(target.keys) == 0 { - return true - } - if any([key Not in source.keys for key in target.keys]) { - return false - } - for key, sourceType in (source.keys, source.types) { - targetType = getKeyType(target, key) ? getKeyType(target, key) : anyTypeOf() - if !isPartialOrderRelatedTo(sourceType, targetType) { - return false - } - } - return true - } - return false -} -``` - -## 类型检查 - -### 类型检查器 - -类型检查器通过语法制导翻译的方式,自顶向下遍历语法树,并根据上下文有关的**定型规则**来判定程序构造是否为良类型程序。 - -类型检查器依赖类型规则,类型环境 $\Gamma$ 的信息记入符号表。对类型表达式采用抽象语法,如 listof(T)。类型检查失败时产生 type_error,并根据语法上下文产生错误信息。 - -### 基础方法 - -1. isUpperBound(t1, t2): supUnify(t1, t2) == t2 -2. supUnify(t1, t2): - -- 对于基础类型,根据偏序关系计算 sup(t1, t2) -- 对于 list、 dict、 Struct, 递归地对其中元素的类型进行 supUnify -- 不存在偏序关系时,返回 Nothing - -### 检查逻辑 - -#### Operand Expr - -$D \to id: T$ - -``` -env.addtype(id.entry, T.type) -``` - -$T \to boolean$ - -``` -T.type = boolean -``` - -$T \to integer$ - -``` -T.type = integer -``` - -$T \to float$ - -``` -T.type = float -``` - -$T \to string$ - -``` -T.type = string -``` - -$T \to c, \ c \in \{boolean, integer, float, string\}$ - -``` -T.type = literalof(c) -``` - -$T \to None$ - -``` -T.type = None -``` - -$T \to Undefined$ - -``` -T.type = Undefined -``` - -$T \to \ [T_1]$ - -``` -T.type = listof (T1.type) -``` - -$T \to { \{T_1: T_2\} }$ - -``` -T.type = dictof (T1.type: T2.type) -``` - -$T \to { \{N_1: T_1, N2: T_2, ..., N_n: T_n\} }$ - -``` -T.type = structof (N1: T1.type, N2: T2.type, ..., Nn: Tn.type) -``` - -$E \to id$ - -``` -E.type = env.lookup(id.entry) -``` - -$E \to [E_1, E_2, ..., E_n]$ - -``` -func listExpr(E) { - supe = sup([e.type for e in E]]) - E.type = listof(type) -} -``` - -$E \to [E_1 \ for \ E_2 \ in \ E_3 \ if \ E_4]$ - -``` -func listComp(E) { - if !typeEqual(E4.type, boolean) { - raise type_error - } - if !isUpperBound(listof(Any), E3.type) { - raise type_error(E) - } - if !isUpperBound(E3.type, E2.type) { - raise type_error(E) - } - E.type = listof(E1.type) -} -``` - -$E \to \{E_{k1}: E_{v1}, ..., E_{kn}: E_{vn}\}$ - -``` -func dictExpr(E) { - supk := sup([e.type for e in E.keys()]]) - supv := sup([e.type for e in E.values()]]) - E.type = dictof(supk, supv) -} -``` - -$E \to \{E_1:E_2 \ for \ (E_3, E_4) \ in \ E_5 \ if \ E_6\}$ - -``` -func dictComp(E) { - if !typeEqual(E6.type, boolean) { - raise type_error(E) - } - if !isUpperBound(dictof(Any, Any), E5.type) { - raise type_error(E) - } - if !isUpperBound(E5.type, dictof(E3.type, E4.type)) { - raise type_error(E) - } - E.type = dictof(E1.type, E2.type) -} -``` - -$E \to \{E_{k1}: E_{v1}, ..., E_{kn}: E_{vn}\}$ - -``` -func dictExpr(E) { - supk := sup(Ek1, ..., Ekn) - supv = sup(Ev1, ..., Evn) - E.type = dictof(supk, supv) -} -``` - -$E \to \{N_{1} = E_{1}, ..., N_{{n}} = E_{n}\}$ - -``` -func structExpr(E) { - Struct = structof() - for n, e in E { - Struct.add(n, e.type) - } - E.type = Struct -} -``` - -#### Primary Expr - -$E \to E_1[E_2]$ - -``` -func sliceSuffix(E) { - if !isUpperBound(listof(Any), E.E1.type) { - raise type_error(E) - } - if typeEqual(E.E2.type, integer) { - raise type_error(E) - } - E.type = E.E1.type.eleType -} -``` - -$E \to E_1(E_2)$ - -``` -func callSuffix(E) { - if !typeEqual(E.E1.type, func) { - raise type_error(E) - } - if !isUpperBound(listof(E.E1.arguType), E.E2.type) { - raise type_error(E) - } - E.type = E.E1.returnType -} -``` - -#### Unary Expr - -根据每条双目运算符的推理规则推导,以 '+' 为例 - -$E \to + E_1$ - -``` -func Plus(E) { - if !typeEqual(E.E1.type, [integer, float]) { - raise type_error(E) - } - E.type = E.E1.type -} -``` - -#### Binary Expr - -根据每条双目运算符的推理规则推导,以 '%' 为例 - -$E \to E_1 \ % \ E_2$ - -``` -func Mod(E) { - if !(typeEqual(E.E1.type, [integer, float]) && typeEqual(E.E2.type, [integer, float])) { - raise type_error(E) - } - E.type = E.E1.type -} -``` - -#### IF Binary Expr - -$E \to if E_1 \ then \ E_2 else \ E_3$ - -``` -func ifExpr(E) { - if !typeEqual(E.type, boolean) { - raise type_error(E) - } - if !typeEqual(E_2.type, E_3.type) { - raise type_error(E) - } - E.type = E_2.type -} -``` - -#### Stmt - -$S \to if \ E \ then \ S_1 \ else \ S_2$ - -``` -func ifStmt(S) { - if !typeEqual(S.E.type, boolean) { - raise type_error(E) - } - if !typeEqual(S.S1.type, S.S2.type) { - raise type_error(E) - } - S.type = S.S1.type -} -``` - -$S \to id: T = E$ - -$S \to id = T E$ - -``` -func assignStmt(S) { - tpe := env.lookup(id.entry) - if tpe != nil && tpe != S.T { - raise type_error(E) - } - if isUpperBound(tpe, E.type) { - raise type_error(E) - } - env.addtype(id.entry, T.type) -} -``` - -## 类型转换 - -### 基础定义 - -通过语法制导翻译的方式,根据运算符特征,对参与运算的值类型进行自动类型转换 - -### 转换规则 - -$E \to E_1 \ op \ E_2, , op \in \{+, -, *, /, \%, **, //\}$ - -``` -func binOp(E) { - if E.E1.type == integer and E.E2.type == integer { - E.type = integer - } else if E.E1.type == integer and E.E2.type == float { - E.type = float - } else if E.E1.type == float and E.E2.type == integer { - E.type = float - } else if E.E1.type == float and E.E2.type == float { - E.type = float - } -} -``` - -## 类型推导 - -### 基础定义 - -- 在类型信息不完全的情况下类型规则推导、重建类型 -- 自底向上推导并重建数程序中的数据结构类型,如基础类型,list, dict, Struct - -### 基础方法 - -1. typeOf(expr, subst): 输入为表达式和代换规则集合,返回 expr 的类型和新的代换规则集合 -2. unifier(t1, t2, subst, expr) 用 t1=t2 尝试代换,如果代换成功(未出现且无冲突),则将 t1=t2 加入 subst 并返回 subst。否则报错已出现或有冲突。 - -### 推导逻辑 - -$E \to id = E_1$ - -``` -func assignExpr(E, subst) { - return unifier(E.id.type, E.E_1.type, subst, E) -} -``` - -$unifier(t1, t2, subst, expr) \rightarrow subst$ - -``` -func unifier(t1, t2, subst, expr) { - t1 = applySubstToTypeEquation(t1, subst) - t2 = applySubstToTypeEquation(t2, subst) - - if t1 == t2 { - return subst - } - - if isTypeVar(t1) { - if isNoOccur(t1, t2) { - addTypeEquationToSubst(subst, t1, t2) - return subst - } else { - raise occurrence_violation_error(t1, t2, expr) - } - } - - if isTypeVar(t2) { - if isNoOccur(t2, t1) { - addTypeEquationToSubst(subst, t2, t1) - return subst - } else { - raise occurrence_violation_error(t2, t1, expr) - } - } - - if isList(t1) and isList(t2) { - return unifier(toListOf(t1).eleType, toListOf(t2).eleType, subst, expr) - } - if isDict(t1) and isDict(t2) { - dict1of := toDictOf(t1) - dict2of := toDictOf(t2) - subst = unifier(dict1of.keyType, dict2of.keyType, subst, expr) - subst = unifier(dict1of.valueType, dict2of.valueType, subst, expr) - return subst - } - if isStruct(t1) and isStruct(t2) { - Struct1of := tostructof(t1) - Struct2of := tostructof(t2) - for key, _ in Struct1of { - subst = unifier(t1[key].type, t2[key].type, subst, expr) - } - return subst - } - - raise unification_error(t1, t2, expr) -} - -func applySubstToTypeEquation(t, subst) { - // walks through the type t, replacing each type variable by its binding in the substitution -σ. If a variable is Not bound in the substitution, then it is left unchanged. - if isBasicType(t) { - return t - } - if isList(t) { - return listOf(applySubstToTypeEquation(toListOf(t).eleType, subst)) - } - if isDict(t) { - dictof := toDictOf(t) - kT := applySubstToTypeEquation(dictof.keyType, subst) - vT := applySubstToTypeEquation(dictof.valueType, subst) - return dictOf(kT, vT) - } - if isStruct(t) { - structof := tostructof(t) - s := structof() - for key, type in Struct1of { - kT := applySubstToTypeEquation(type, subst) - s.add(key, kT) - } - return s - } - if hasTypeVar(t) { - for tvar in t.vars { - if tvar in subst { - *tvar = subst[tvar] - } - } - } - return t -} - -func addTypeEquationToSubst(subst, tvar, t) { - // takes the substitution σ and adds the equation tv = t to it - for _, t in subst { - for tvar in t.vars { - tmp := applyOneSubst(tsvar, tvar, t) - *tvar = tmp - } - } - subst.add(tvar, t) -} - -func applyOneSubst(t0, tvar, t1) { - // substituting t1 for every occurrence of tv in t0. - if isBasicType(t0) { - return t0 - } - if isList(t0) { - return listOf(applyOneSubst(toListOf(t).eleType, tvar, t1)) - } - if isDict(t0) { - dictof := toDictOf(t) - kT := applyOneSubst(dictof.keyType, tvar, t1) - vT := applyOneSubst(dictof.valueType, tvar, t1) - return dictOf(kT, vT) - } - if isStruct(t0) { - structof := tostructof(t) - s := structof() - for key, type in Struct1of { - kT := applyOneSubst(type, tvar, t1) - s.add(key, kT) - } - return s - } - if t0 == tvar { - return t1 - } - return t0 -} - -func isNoOccur(tvar, t) { - // No variable bound in the substitution occurs in any of the right-hand sides of the substitution. - if isBasicType(t) { - return true - } - if isList(t) { - return isNoOccur(tvar, toListOf(t).eleType) - } - if isDict(t) { - dictof := toDictOf(t) - return isNoOccur(tvar, dictof.keyType) and isNoOccur(tvar, dictof.valueType) - } - if isStruct(t) { - structof := tostructof(t) - noOccur := true - for _, type in structof { - noOccur = noOccur and isNoOccur(tvar, type) - } - return noOccur - } - return tvar != t -} -``` - -### 示例 - -#### 正常推导 - -``` -T : { - a = 1 - b = "2" - c = a * 2 - d = { - d0 = [a, c] - } -} - -x: T = { - a = 10 -} -``` - -#### Occurrence Violation Error - -``` -T = { - a = a -} -``` - -#### Type Unification Error - -``` -T : { - a = 1 -} - -T : { - a = "1" -} -``` - -## Reference - -- [https://en.wikipedia.org/wiki/Type_system](https://en.wikipedia.org/wiki/Type_system) -- Pierce, Benjamin C. (2002). Types and Programming Languages. MIT Press. -- [https://www.cs.cornell.edu/courses/cs4110/2010fa/](https://www.cs.cornell.edu/courses/cs4110/2010fa/) -- [https://www.typescriptlang.org/docs/handbook/basic-types.html](https://www.typescriptlang.org/docs/handbook/basic-types.html) -- [https://www.typescriptlang.org/docs/handbook/advanced-types.html](https://www.typescriptlang.org/docs/handbook/advanced-types.html) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/_category_.json deleted file mode 100644 index 53e27fd4..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "模块系统", - "position": 2 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/base64.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/base64.md deleted file mode 100644 index 0db738f0..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/base64.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: "base64" -linkTitle: "base64" -type: "docs" -description: base64 编码解码 -weight: 100 ---- - -## encode - -`encode(value: str, encoding: str = "utf-8") -> str` - -使用注册的编码器对字符串 `value` 进行编码。 - -## decode - -`decode(value: str, encoding: str = "utf-8") -> str` - -使用注册的编码器对字符串 `value` 进行解码。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/builtin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/builtin.md deleted file mode 100644 index 44085174..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/builtin.md +++ /dev/null @@ -1,401 +0,0 @@ ---- -title: "builtin" -sidebar_position: 1 ---- - -KCL 提供了一个内置系统模块的列表,这些模块是自动加载的,无需提供任何模块名称即可直接使用。例如,`print` 就是一个广泛使用的内置模块提供的函数。 - -## 类型转换函数 - -KCL的 `bool`、`int`、`float`、`str`、`list`、`dict`等类型有内置同名的转换函数。其中 `int` 不仅仅可以用于截断浮点数,也可以用来将字符串转化为整数(解析时为10进制,也可以制定其他值)。 - -下面是类型相关函数常见的用法: - -```py -b1 = bool(1) # true -b2 = bool(1.5) # true -b3 = bool("true") # true -b4 = bool("") # false -b5 = bool([]) # false -b6 = bool({}) # false - -i1 = int("11") # 11 -i2 = int("11", base=8) # 9 -i3 = int("11", base=2) # 3 - -f1 = float(1) # 1.0 -f2 = float("1.5") # 1.5 - -s1 = str(1) # 1 - -l1 = list([1, 2, 3]) -``` - -## String 类型成员函数 - -参考 [String 文档](/docs/reference/lang/spec/datatypes) - -## print - -`print(*args:any, end:str='\n')` - -内置的打印函数,提供不同类型的可变参数打印,默认在结尾添加一个换行符号。以下上常见的用法: - -```python -print("hello KCL") -print() -print(None, end=':') -print(None) -print(True) -print(False) -print(123) -print(123.0) -print('abc ${123}') -print("abc ${456}") -print([1,'a', True]) -print(1,'a', True) -print({}) -print({a: 123}) -``` - -输出格式如下: - -```shell -hello KCL - -None:None -True -False -123 -123.0 -abc 123 -abc 456 -[1, 'a', True] -1 a True -{} -{'a': 123} -``` - -如果不希望在默认换行时,可以通过 `end=''` 命名参数重新指定结尾的字符串。 - -## multiplyof - -`multiplyof(a:int, b:int) -> bool` - -判断整数 `a` 是否为 `b` 的整数倍,返回布尔值: - -```python -print(multiplyof(2, 1)) # True -print(multiplyof(1, 2)) # False -print(multiplyof(0, 1)) # True -print(multiplyof(0, 2)) # True -print(multiplyof(1, 0)) # Error -``` - -`0` 是任何数的倍数。但是 `b` 不能为 `0`,否则将抛出异常。 - -## isunique - -`isunique(list: [any]) -> bool` - -判断数组中是否存在重复的元素,返回布尔值: - -```python -print(isunique([])) # True -print(isunique([1])) # True -print(isunique([1, 2])) # True - -print(isunique([1, 1])) # False -print(isunique([1, 1.0])) # False -print(isunique([1.1, 1.1])) # False - -print(isunique(['abc', "abc"])) # False -print(isunique(['abc', "a${'bc'}"])) # False -``` - -需要注意的是整数和浮点数会忽略类型差异,根据值是否相等判断。 - -## len - -`len(x: str | [any] | {:}) -> int` - -返回字符串、列表和数组的长度: - -```python -print(len([])) # 0 -print(len({})) # 0 - -print(len([1])) # 1 -print(len({abc:123})) # 1 - -print("abc") # 3 -``` - -注:不支持对 `schema` 对象计算长度。 - -## abs - -`abs(x: number) -> number` - -计算 `x` 的绝对值。 - -## all_true - -`all_true(x:str|[]|{:}) -> bool` - -判断列表或字典类全部元素为真,用法如下: - -```python -print(all_true([])) # True -print(all_true({})) # True - -print(all_true([True])) # True -print(all_true([1])) # True - -print(all_true([True, False])) # False -print(all_true([True, None])) # False -``` - -当列表为空时返回真。 - - - -## any_true - -`any_true(x:str|[]|{:}) -> bool` - -判断可迭代对象中至少有一个元素为真,用法如下: - -```python -print(any_true([])) # False -print(any_true([1])) # True -``` - -## bin - -`bin(x:number) -> str` - -返回整数的二进制表示的字符串,用法如下: - -```python -print(bin(8)) # 0b1000 -``` - -## hex - -`hex(number)` - -返回整数的十六进制表示的字符串,用法如下: - -```python -print(hex(18)) # 0x12 -``` - -## oct - -`oct(number)` - -返回整数的八进制表示的字符串,用法如下: - -```python -print(oct(10)) # 0o12 -``` - -## option - -`option(key:str, type:str='', required=False, default=None, help="") -> any` - -获取命令行参数输入的值。 - -## ord - -`ord(c) -> int` - -获取字符的 Unicode 码点值,用法如下: - -```python -print(ord('A')) # 65 -print(ord('B')) # 66 -print(ord('C')) # 67 -``` - -## sorted - -`sorted(x: []) -> []` - -返回排序后的列表,用法如下: - -```python -_a = [] -_b = [2, 1] - -_c = sorted(_a) -_d = sorted(_b) - -print(_a) # [] -print(_b) # [2, 1] -print(_c) # [] -print(_d) # [1, 2] -``` - -## range - -`range(start:int, end:int, step=1) -> [int]` - -产生迭代列表,用法如下: - -```python -print(range(1,5)) # [1, 2, 3, 4] -print(range(1,5, 2)) # [1, 3] -print(range(5, 1, -1)) # [5, 4, 3, 2] -``` - -## min - -`min(x:[number]) -> number` - -返回列表中最小的元素,用法如下: - -```python -print(min([1,2])) # 1 -print(min([2,1])) # 1 -``` - - - -## max - -`max(x:[number]) -> number` - -返回列表中最大的元素,用法如下: - -```python -print(max([1,2])) # 2 -print(max([2,1])) # 2 -``` - -## sum - -`sum(x:[number], init_value=0) -> number` - -返回列表中全部元素的和,用法如下: - -``` -print(sum([1,2])) # 3 -print(sum([2,1], 1000)) # 1003 -``` - -## pow - -`pow(x: number, y: number, z: number = None) -> number` - -计算 `x**y`,如果 `z` 非空则计算 `(x**y)%z`,支持整数和浮点数。 - -下面的常见的用法: - -```python -print(pow(2,3)) # 8 -print(pow(2, 3, 5)) # 8%5 == 3 - -print(pow(2, 0.5)) # 1.414 -``` - -## round - -`round(number: int|float, ndigits:int|None) -> float | int` - -返回 `number` 的四舍五入近似值。如果 `ndigits` 非 `None` 则返回浮点数并保留指定位数的小数(不能为负数),否则返回整数结构。 - -下面是常用的用法: - -```python -print(round(1)) # 1 -print(round(1.4)) # 1 -print(round(1.5)) # 2 - -print(round(1.5555, 1)) # 1.6 -print(round(1.5555, 2)) # 1.56 - -print(round(1.5555)) # 2 -print(round(1.5555, 0)) # 2.0 -``` - -需要注意的是,`ndigits` 为 `None` 和 `0` 的区别是前缀返回 `int` 类型、后者返回 `float` 类型。 - -## typeof - -`typeof(x: any, full_name: bool = False) -> str` - -输出 `x` 在运算时的类型。当 `full_name` 参数设置为 `True` 时,将返回 `pkg.schema` 形式的包前缀。 - -下面是常见的用法: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person{} -t3 = typeof(_x1) - -_x2 = pkg.Person{} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# 输出 -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -## zip - -`zip(*args: str|list|dict)` - -用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。 - -下面是常见的用法: - -```py -a = zip([0, 1, 2], [3, 4, 5]) -b = zip([0, 1], [3, 4, 5]) -c = zip([0, 1, 2], [3, 4, 5, 6]) - -# 输出 -# a: -# - - 0 -# - 3 -# - - 1 -# - 4 -# - - 2 -# - 5 -# b: -# - - 0 -# - 3 -# - - 1 -# - 4 -# c: -# - - 0 -# - 3 -# - - 1 -# - 4 -# - - 2 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/crypto.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/crypto.md deleted file mode 100644 index cef03352..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/crypto.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "crypto" -linkTitle: "crypto" -type: "docs" -description: crypto 包 - 提供 SHA 相关的哈希函数 -weight: 100 ---- - -## md5 - -`md5(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `MD5` 算法对字符串 `value` 进行加密。 - -## sha1 - -`sha1(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA1` 算法对字符串 `value` 进行加密。 - -## sha224 - -`sha224(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA224` 算法对字符串 `value` 进行加密。 - -## sha256 - -`sha256(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA256` 算法对字符串 `value` 进行加密。 - -## sha384 - -`sha384(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA384` 算法对字符串 `value` 进行加密。 - -## sha512 - -`sha512(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA512` 算法对字符串 `value` 进行加密。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/index.md deleted file mode 100644 index c1f4b4a0..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# 系统模块 - -KCL 通过系统模块、用户模块和插件模块提供工程化的扩展能力。本节介绍系统模块的基本概念,插件模块可以参考插件系统。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/manifests.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/manifests.md deleted file mode 100644 index 5c54e9c7..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/manifests.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: "manifests" -linkTitle: "manifests" -type: "docs" -description: manifests system module -weight: 100 ---- - -## yaml_stream - -```python -yaml_stream(values: [any], opts: {str:} = { - sort_keys = False - ignore_private = True - ignore_none = False - sep = "---" -}) -``` - -这个函数的功能是将 KCL 对象列表序列化为带 `---` 分隔符的样式 YAML 输出,它具有两个参数: - -- `values` - 一个 KCL 对象列表 -- `opts` - YAML 序列化选项 - - `sort_keys`:是否按属性名称的字典序对序列化结果进行排序(默认为 `False`)。 - - `ignore_private`:是否忽略名称以 `_` 开头的属性序列化输出(默认为 `True`)。 - - `ignore_none`:是否忽略值为 `None` 的属性(默认为 `False`)。 - - `sep`:在多个 YAML 文档之间选择怎样的分隔符(默认为 `"---"`)。 - -下面我们通过一个例子来说明: - -```python -# 使用 `import` 关键词导入 `manifests` 模块 -import manifests - -# `Deployment` schema 定义 -schema Deployment: - apiVersion: str = "v1" - kind: str = "Deployment" - metadata: {str:} = { - name = "deploy" - } - spec: {str:} = { - replica = 2 - } - -# `Service` schema 定义 -schema Service: - apiVersion: str = "v1" - kind: str = "Service" - metadata: {str:} = { - name = "svc" - } - spec: {str:} = {} - -# 定义两个 `Deployment` 资源 -deployments = [Deployment {}, Deployment {}] -# 定义两个 `Service` 资源 -services = [Service {}, Service {}] -# 将它们放入 KCL 列表,并调用 `manifests.yaml_stream` 函数。 -manifests.yaml_stream(deployments + services) -``` - -首先我们通过 `import` 关键字导入 `manifests` 模块并定义 2 个 Deployment 以及 2 个 Service 资源,当我们想以 YAML stream 并以 `---` 作为分隔符的格式依次输出这 4 个资源时,我们可以将它们合并为一个 KCL 列表并作为 `manifests.yaml_stream` 函数的 `values` 形参进行传入 (如无特殊需求,opts 参数一般使用默认值即可),最终得到 YAML 输出为: - -```yaml -apiVersion: v1 -kind: Deployment -metadata: - name: deploy -spec: - replica: 2 ---- -apiVersion: v1 -kind: Deployment -metadata: - name: deploy -spec: - replica: 2 ---- -apiVersion: v1 -kind: Service -metadata: - name: svc ---- -apiVersion: v1 -kind: Service -metadata: - name: svc -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/math.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/math.md deleted file mode 100644 index 3b2ff0cc..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/math.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: "math" -linkTitle: "math" -type: "docs" -description: math 包 - 数学函数 -weight: 100 ---- - -## ceil - -`ceil(x) -> int` - -返回 `x` 向上取整得到的整数,这是大于等于 `x` 的最小整数。 - -## factorial - -`factorial(x) -> int` - -返回 `x` 的阶乘(即 `x!`),如果 `x` 是负数或者不是整数,则会引发一个错误。 - -## floor - -`floor(x) -> int` - -返回 `x` 向下取整得到的整数,这是小于等于 `x` 的最大整数。 - -## gcd - -`gcd(a: int, b: int) -> int` - -返回 `x` 和 `y` 的最大公约数。 - -## isfinite - -`isfinite(x) -> bool` - -如果 `x` 既不是无穷大也不是 `NaN` 返回 `True`,否则返回 `False`。 - -## isinf - -`isinf(x) -> bool` - -如果 `x` 是正无穷或负无穷返回 `True`,否则返回 `False`。 - -## isnan - -`isnan(x) -> bool` - -如果 `x` 是 `NaN` 返回 `True`,否则返回 `False`。 - -## modf - -`modf(x) -> List[float, float]` - -返回 `x` 的整数和小数部分,两个结果均与 `x` 的正负号相同,并且均为浮点数。 - -## exp - -`exp(x) -> float` - -返回以 `e` 为底数, `x` 的幂。 - -## expm1 - -`expm1(x) -> float` - -返回 `e` 的 `x` 次方减去 1,该函数能够避免由于直接计算 `exp(x) - 1` 而引起的精度损失。 - -## log - -`log(x, base=2.71828182845904523536028747135266250) -> float` - -返回以 `e` 为底数,`x` 的对数。 - -## log1p - -`log1p(x) -> float` - -返回以 `e` 为底数,`1 + x` 的自然对数,该函数能够在 `x` 靠近 0 时精确计算结果。 - -## log2 - -`log2(x) -> float` - -返回 `x` 的以 2 为底的对数。 - -## log10 - -`log10(x) -> float` - -返回 `x` 的以 10 为底的对数。 - -## pow - -`pow(x, y) -> float` - -返回 `x` 的 `y` 次幂(即 `x` 的 `y` 次方)。 - -## sqrt - -`sqrt(x) -> float` - -返回 `x` 的平方根。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/net.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/net.md deleted file mode 100644 index 1050d16d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/net.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: "net" -linkTitle: "net" -type: "docs" -description: net 包 - 网络IP处理 -weight: 100 ---- - -## split_host_port - -`split_host_port(ip_end_point: str) -> List[str]` - -从 `ip_end_point` 分离出 `host` 和 `port`。 - -## join_host_port - -`join_host_port(host, port) -> str` - -合并 `host` 和 `port`。 - -## fqdn - -`fqdn(name: str = '') -> str` - -返回完全限定域名(FQDN)。 - -## parse_IP - -`parse_IP(ip) -> str` - -将 `ip` 解析为真实的 IP 地址。 - -## to_IP4 - -`to_IP4(ip) -> str` - -获取 `ip` 的 IPv4 表示形式。 - -## to_IP16 - -`to_IP16(ip) -> int` - -获取 `ip` 的 IPv6 表示形式。 - -## IP_string - -`IP_string(ip: str | int) -> str` - -返回 IP 字符串。 - -## is_IPv4 - -`is_IPv4(ip: str) -> bool` - -判断 `ip` 是否为 IPv4。 - -## is_IP - -`is_IP(ip: str) -> bool` - -判断 `ip` 是否为有效的 IP 地址。 - -## is_loopback_IP - -`is_loopback_IP(ip: str) -> bool` - -判断 `ip` 是否为回环地址。 - -## is_multicast_IP - -`is_multicast_IP(ip: str) -> bool` - -判断 `ip` 是否为组播地址。 - -## is_interface_local_multicast_IP - -`is_interface_local_multicast_IP(ip: str) -> bool` - -判断 `ip` 是否为接口、本地和组播地址。 - -## is_link_local_multicast_IP - -`is_link_local_multicast_IP(ip: str) -> bool` - -判断 `ip` 是否为链路本地和组播地址。 - -## is_link_local_unicast_IP - -`is_link_local_unicast_IP(ip: str) -> bool` - -判断 `ip` 是否为链路本地和单播地址。 - -## is_global_unicast_IP - -`is_global_unicast_IP(ip: str) -> bool` - -判断 `ip` 是否为全局单播地址。 - -## is_unspecified_IP - -`is_unspecified_IP(ip: str) -> bool` - -判断 `ip` 是否为 `unspecified` 地址。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/overview.md deleted file mode 100644 index aa3eaeb3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/overview.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -sidebar_position: 0 ---- - -# 概览 - -KCL 是面向配置的编程语言,通过内置模块、KCL 模块和插件模块提供工程化的扩展能力。 - -![](/img/docs/reference/lang/model/kcl-module.png) - -用户代码中不用导入直接使用 builtin 的函数(比如用 `len` 计算列表的长度、通过 `typeof` 获取值的类型等),而对于字符串等基础类型也提供了一些内置方法(比如转化字符串的大小写等方法)。对于相对复杂的通用工作则通过标准库提供,比如通过 import 导入 `math` 库就可以使用相关的数学函数,可以通过导入 `regex` 库使用正则表达式库。而针对 KCL 代码也可以组织为模块,比如 Konfig 大库中将基础设施和各种标准的应用抽象为模块供上层用户使用。此外还可以通过 Plugin 机制,采用 Python 为 KCL 开发插件,比如目前有 meta 插件可以通过网络查询中心配置信息,`app-context` 插件则可以用于获取当前应用的上下文信息从而简化代码的编写。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/regex.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/regex.md deleted file mode 100644 index e7b0c25c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/regex.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "regex" -linkTitle: "regex" -type: "docs" -description: regex 包 - 正则表达式 -weight: 100 ---- - -## replace - -`replace(string: str, pattern: str, replace: str, count=0) -> str` - -替换字符串 `string`中最左边、不重叠并且匹配模式 `pattern` 的部分替换为指定的字符串 `replace`,并返回替换后的字符串 - -## match - -`match(string: str, pattern: str) -> bool` - -尝试在字符串开头应用模式 `pattern`,找到了任何匹配项则返回 `True`,返回 `False` 表示没有找到匹配项 - -## compile - -`compile(pattern: str) -> bool` - -编译正则表达式模式 `pattern`,并返回一个布尔值,表示该模式是否有效 - -## findall - -`findall(string: str, pattern: str) -> List[str]` - -查找 `pattern` 在 `string` 中的所有非重叠匹配,并以字符串列表的形式返回 - -## search - -`search(string: str, pattern: str) -> bool` - -扫描字符串 `string` 以查找与模式匹配的项,如果找到任何匹配项,则返回布尔值 `True`,否则返回 `False` - -## split - -`split(string: str, pattern: str, maxsplit=0) -> List[str]` - -返回一个由字符串内单词组成的列表,使用 `pattern` 作为分隔字符串,最多进行 `maxsplit` 次拆分 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/units.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/units.md deleted file mode 100644 index 8c862d0e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/units.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: "units" -linkTitle: "units" -type: "docs" -description: units 包 - 单位处理 -weight: 100 ---- - -## 单位的常量 - -- 定点数: `n`, `u`, `m`, `k`, `K`, `G`, `T` 和 `P`. -- 2 的幂: `Ki`, `Mi`, `Gi`, `Ti` 和 `Pi`. - -## 函数列表 - -- `to_n(num: int) -> str` - 将 int 转换为以 `n` 作为后缀的字符串 -- `to_u(num: int) -> str` - 将 int 转换为以 `u` 作为后缀的字符串 -- `to_m(num: int) -> str` - 将 int 转换为以 `m` 作为后缀的字符串 -- `to_K(num: int) -> str` - 将 int 转换为以 `K` 作为后缀的字符串 -- `to_M(num: int) -> str` - 将 int 转换为以 `M` 作为后缀的字符串 -- `to_G(num: int) -> str` - 将 int 转换为以 `G` 作为后缀的字符串 -- `to_T(num: int) -> str` - 将 int 转换为以 `T` 作为后缀的字符串 -- `to_P(num: int) -> str` - 将 int 转换为以 `P` 作为后缀的字符串 -- `to_Ki(num: int) -> str` - 将 int 转换为以 `Ki` 作为后缀的字符串 -- `to_Mi(num: int) -> str` - 将 int 转换为以 `Mi` 作为后缀的字符串 -- `to_Gi(num: int) -> str` - 将 int 转换为以 `Gi` 作为后缀的字符串 -- `to_Ti(num: int) -> str` - 将 int 转换为以 `Ti` 作为后缀的字符串 -- `to_Pi(num: int) -> str` - 将 int 转换为以 `Pi` 作为后缀的字符串 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/_category_.json deleted file mode 100644 index edfe989e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "包管理", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/1.init.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/1.init.md deleted file mode 100644 index 0bfc0303..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/1.init.md +++ /dev/null @@ -1,45 +0,0 @@ -# kpm init - -初始化一个 kcl 包。 - -## 使用 - -```shell -kpm init [options][package_name] -``` - -## 介绍 - -`kpm init` 会在当前目录初始化一个 kcl 包。如果没有提供包名,会使用当前目录的名字作为包名。 - -如果提供了包名,会在当前目录下创建一个以包名命名的子目录,并在该目录下初始化 kcl 包。 - -`kpm init` 会在包目录下创建 `kcl.mod`、`kcl.mod.lock` 和 `main.k`。 - -## 选线 - -### --help, -h - -显示帮助信息。 - -## 示例 - -### 初始化当前目录为 kcl 包 - -```shell -# 创建一个目录 -$ mkdir my_package - -# 进入目录 -$ cd my_package - -# 初始化当前目录为 kcl 包 -$ kpm init -``` - -### 初始化一个名为 my_package 的 kcl 包 - -```shell -# 初始化一个名为 my_package 的 kcl 包 -kpm init my_package -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/10.help.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/10.help.md deleted file mode 100644 index 0fd9fa3a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/10.help.md +++ /dev/null @@ -1,21 +0,0 @@ -# kpm help - -输出 kpm 命令的帮助信息。 - -## 使用 - -```shell -kpm help -``` - -## 介绍 - -`kpm help` 会输出 kpm 命令的帮助信息。 - -## 示例 - -使用 `kpm help` 输出 kpm 命令的帮助信息。 - -```shell -kpm help -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/2.add.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/2.add.md deleted file mode 100644 index 09fd5d46..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/2.add.md +++ /dev/null @@ -1,53 +0,0 @@ -# kpm add - -添加一个依赖到 kcl 包。 - -## 使用 - -```shell -kpm add [options][package_reference] -``` - -## 介绍 - -`kpm add` 会添加一个依赖到 kcl 包。依赖可以来自 git 仓库,或者 kcl registry。 - -`package_reference` 是一个 kcl 包引用,格式为 `package_name:version`。 - -## 选项 - -### --git - -指定依赖来自 git 仓库的 git url。 - -### --tag - -指定依赖来自 git 仓库的 tag。 - -### --help, -h - -显示帮助信息。 - -## 示例 - -### 添加一个来自 kcl registry 的依赖 - -添加一个名为 `k8s` 的依赖,版本为最新版本。 - -```shell -kpm add k8s -``` - -添加一个名为 `k8s` 的依赖,版本为 `v1.27.2`。 - -```shell -kpm add k8s:v1.27.2 -``` - -### 添加一个来自 git 仓库的依赖 - -添加一个来自 git 仓库的 kcl 包依赖,tag 为 v0.1.0 - -```shell -kpm add --git https://github.com/awesome-kusion/konfig.git --tag v0.1.0 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/3.pkg.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/3.pkg.md deleted file mode 100644 index fd708d03..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/3.pkg.md +++ /dev/null @@ -1,33 +0,0 @@ -# kpm pkg - -打包一个 kcl 包。 - -## 使用 - -```shell -kpm pkg [options] -``` - -## 介绍 - -`kpm pkg` 会打包一个 kcl 包为 `*.tar`。 - -选项 `--target` 用于指定打包后的 `*.tar` 文件路径。 - -## 选项 - -### --target - -指定打包后的 `*.tar` 文件路径。 - -### --help, -h - -显示帮助信息。 - -## 示例 - -### 打包当前 kcl 包为 `*.tar` - -```shell -kpm pkg --target /Users/my_package_tar -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/4.metadata.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/4.metadata.md deleted file mode 100644 index 199ebd2e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/4.metadata.md +++ /dev/null @@ -1,41 +0,0 @@ -# kpm metadata - -打印 kcl 包的元数据。 - -## 使用 - -```shell -kpm metadata [options] -``` - -## 介绍 - -`kpm metadata` 会打印 kcl 包的元数据。元数据包括包的依赖信息。 - -`--update` 选项用于自动下载缺失的依赖包。 - -## 选项 - -### --update - -自动下载缺失的依赖包。 - -### --help, -h - -展示 `kpm metadata` 命令的帮助信息。 - -## 示例 - -### 打印 kcl 包的元数据 - -打印 kcl 包的元数据。 - -```shell -kpm metadata -``` - -打印 kcl 包的元数据,并自动下载缺失的依赖包。 - -```shell -kpm metadata --update -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/5.run.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/5.run.md deleted file mode 100644 index eee83e08..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/5.run.md +++ /dev/null @@ -1,69 +0,0 @@ -# kpm run - -编译一个 kcl 包。 - -## 使用 - -```shell -kpm run [options][package_source] -``` - -## 介绍 - -`kpm run` 会编译一个 kcl 包。 - -## 选项 - -### --input - -指定包的入口文件路径。 - -### --tag - -指定 oci url 的包的 tag。 - -### --vendor - -`--vendor` 选项会将依赖包移动到当前包,并自动下载缺失的依赖包。 - -### --kcl_args - -`--kcl_args` 描述了传递给 kcl 编译器的参数。 - -### --help, -h - -展示 `kpm run` 命令的帮助信息。 - -## 示例 - -### 编译当前 kcl 包 - -在 kcl 包目录下,`kpm run` 可以用于编译当前 kcl 包。 - -```shell -kpm run -``` - -### 编译一个 kcl 包 tar 文件 - -`kpm run` 可以用于编译一个 kcl 包 tar 文件。 - -```shell -kpm run /Users/demo/my_package.tar -``` - -### 编译一个 kcl 包来自 oci url - -`kpm run` 可以用于编译一个 kcl 包从 oci url。 - -```shell -kpm run --tag 0.0.1 oci://localhost:5001/test/my_package -``` - -### 编译一个 kcl 包来自 oci ref - -`kpm run` 可以用于编译一个 kcl 包从 oci ref。 - -```shell -kpm run test/my_package:0.0.1 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/6.login.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/6.login.md deleted file mode 100644 index 9055d8fb..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/6.login.md +++ /dev/null @@ -1,68 +0,0 @@ -# kpm login - -登陆 kpm registry. - -## 使用 - -```shell -kpm login [options][kpm_registry] -``` - -## 介绍 - -`kpm login` 将会登陆 kpm registry。 - -## 选项 - -### --username, -u - -指定 kpm registry 的用户名。 - -### --password, -p - -指定 kpm registry 的密码。 - -### --help, -h - -展示 `kpm login` 命令的帮助信息。 - -## 示例 - -### 登陆到 kpm registry, 通过参数输入用户名和密码 - -```shell -kpm login -u -p -``` - -期望输出为 - -```shell -Login succeeded -``` - -### 登陆到 kpm registry, 通过参数输入用户名,密码通过交互式输入 - -```shell -kpm login -u -``` - -期望输出为 - -```shell -Password: -Login succeeded -``` - -### 登陆到 kpm registry, 用户名和密码通过交互式输入 - -```shell -kpm login -``` - -期望输出为 - -```shell -Username: -Password: -Login succeeded -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/7.logout.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/7.logout.md deleted file mode 100644 index 65dd317e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/7.logout.md +++ /dev/null @@ -1,27 +0,0 @@ -# kpm logout - -从 kpm registry 登出。 - -## 使用 - -```shell -kpm logout [options][kpm_registry] -``` - -## 介绍 - -`kpm logout` 会从 kpm registry 登出。 - -## 选项 - -### --help, -h - -展示 `kpm logout` 命令的帮助信息。 - -## 示例 - -### 从 kpm registry 登出 - -```shell -kpm logout -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/8.push.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/8.push.md deleted file mode 100644 index 53c2e520..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/8.push.md +++ /dev/null @@ -1,46 +0,0 @@ -# kpm push - -上传一个 kcl 包到 kpm registry。 - -## 使用 - -```shell -kpm push [options][kpm_registry] -``` - -## 介绍 - -`kpm push` 将会上传一个 kcl 包到 kpm registry。 - -## 选项 - -### --tar_path - -指定上传的 `*.tar` 文件路径。 - -### --help, -h - -展示 `kpm push` 命令的帮助信息。 - -## 示例 - -### 上传当前 kcl 包到 kpm registry - -你可以在 kcl 包的根目录下使用 `kpm push` 命令上传一个 kcl 包到 kpm registry。 - -```shell -# 创建一个 kcl 包 -$ kpm init -# 进入 kcl 包目录 -$ cd -# 上传 kcl 包到 kpm registry -$ kpm push -``` - -### 上传一个 `*.tar` 文件到 kpm registry - -你也可以使用 `kpm push` 命令上传一个 `*.tar` 文件到 kpm registry。 - -```shell -kpm push --tar_path -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/9.pull.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/9.pull.md deleted file mode 100644 index cec49291..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/9.pull.md +++ /dev/null @@ -1,41 +0,0 @@ -# kpm pull - -下载 kcl 包从 kpm registry。 - -## 使用 - -```shell -kpm pull [options][package_source] -``` - -## 介绍 - -`kpm pull` 会从 kpm registry 下载 kcl 包。 - -## 选项 - -### --tag - -使用 oci url 下载包时, 指定要下载的 kcl 包的 tag。 - -### --help, -h - -展示 `kpm pull` 命令的帮助信息。 - -## 示例 - -### 从 kpm registry 下载 kcl 包 - -你可以使用 `kpm pull` 命令从 默认的 kpm registry 下载 kcl 包。 - -```shell -kpm pull : -``` - -### 下载 kcl 包通过 oci url - -你可以使用 `kpm pull` 命令从一个 oci url 下载 kcl 包。 - -```shell -kpm pull --tag -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/_category_.json deleted file mode 100644 index abcc956a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "命令参考", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/index.md deleted file mode 100644 index e3025db9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/package-management/command-reference/index.md +++ /dev/null @@ -1,36 +0,0 @@ -# kpm - -kpm 命令。 - -## 使用 - -```shell -kpm [arguments]... -``` - -## 介绍 - -`kpm` 是 kcl 包管理工具。它用于分发和管理 kcl 包。 - -## 选项 - -### --help, -h - -展示 `kpm` 命令的帮助信息。 - -### --version, -v - -展示 `kpm` 命令的版本信息。 - -## 子命令 - -- [kpm init](./1.init.md) - 初始化一个 kcl 包 -- [kpm add](./2.add.md) - 添加一个依赖到 kcl 包 -- [kpm pkg](./3.pkg.md) - 打包一个 kcl 包为 `*.tar` -- [kpm metadata](./4.metadata.md) - 打印一个 kcl 包的元数据 -- [kpm run](./5.run.md) - 编译一个 kcl 包为 yaml 并运行 -- [kpm login](./6.login.md) - 登录到一个 kcl registry -- [kpm logout](./7.logout.md) - 登出一个 kcl registry -- [kpm push](./8.push.md) - 上传一个 kcl 包到一个 registry -- [kpm pull](./9.pull.md) - 下载一个 kcl 包从一个 registry -- [kpm help](./10.help.md) - 打印 kpm 命令的帮助信息 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/plugin/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/plugin/_category_.json deleted file mode 100644 index 645deb88..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/plugin/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "插件系统", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/plugin/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/plugin/index.md deleted file mode 100644 index e2fe86d6..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/plugin/index.md +++ /dev/null @@ -1 +0,0 @@ -# 插件系统 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/plugin/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/plugin/overview.md deleted file mode 100644 index b3cc9469..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/plugin/overview.md +++ /dev/null @@ -1,183 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 简介 - -KCL 是声明式配置策略语言,对于不方便通过配置直接描述的复杂的业务逻辑可以通过通用的编程语言开发 KCL 插件对语言进行扩展。KCL 支持通过通用语言开发插件,KCL 程序导入插件中的函数。KCL 通过插件运行时和辅助的命令行工具提供插件支持。KCL 插件框架支持多种不同的通用语言开发插件,这里我们以 Python 为例简单说明插件的使用。 - -插件的 Git 仓库: [https://github.com/kcl-lang/kcl-plugin](https://github.com/kcl-lang/kcl-plugin) - -## 0. 前置依赖 - -使用 KCL Python 插件需要您的 `PATH` 中存在 `Python3.7+`。 - -## 1. 你好插件 - -KCL 插件在 KCL 的 `plugins` 子目录(通常安装在 `$HOME/.kcl/plugins` 目录),或者通过 `$KCL_PLUGINS_ROOT` 环境变量设置(环境变量优先级更高)。此外,`plugins` 插件目录还可以放在执行 KCL 命令的 `pwd` 路径或者父路径中。对于插件开发人员,插件都在 Git 仓库管理: [https://github.com/kcl-lang/kcl-plugin](https://github.com/kcl-lang/kcl-plugin) ,可以将插件仓库克隆到该目录进行开发。 - -输入 `kcl-plugin info` 命令查看查看插件目录(将其中的 `/Users/kcl_user` 替换成本地的 `$HOME` 路径): - -```shell -$ kcl-plugin info -# plugin_root: /Users/kcl_user/.kcl/plugins -``` - -通过 `kcl-plugin list` 子命令查看插件列表: - -```shell -$ kcl-plugin list -hello: hello doc - 0.0.1 -``` - -其中 `hello` 是 KCL 内置的示例插件(不要修改改插件)。 - -在 KCL 代码中,可以通过 `kcl_plugin.hello` 导入 `hello` 插件。`main.k` 代码如下: - -```python -import kcl_plugin.hello - -name = "kcl" -three = hello.add(1,2) -``` - -输出结果如下: - -```shell -$ python3 -m kclvm main.k -name: kcl -three: 3 -``` - -## 2. `kcl-plugin` 辅助命令 - -`kcl-plugin` 是提供的插件辅助工具,命令行帮助如下: - -```shell -$ kcl-plugin -usage: kcl-plugin [-h] {list,info,init,gendoc,test} ... -positional arguments: - {list,info,init,gendoc,test} - kcl plugin sub commands - list list all plugins - info show plugin document - init init a new plugin - gendoc gen all plugins document - test test plugin -optional arguments: - -h, --help show this help message and exit -``` - -其中 `list` 子命令用于查看插件列表;`info` 用户查看插件目录和每个插件的信息;`init` 可以用户初始化新插件;`gendoc` 更新全部插件的 API 文档;`test` 测试指定的插件。 - -## 3. 插件信息和文档 - -输入 `kcl-plugin info hello` 查看 `hello` 插件信息: - -```shell -$ kcl-plugin info hello -{ - "name": "hello", - "describe": "hello doc", - "long_describe": "long describe", - "version": "0.0.1", - "method": { - "add": "add two numbers, and return result", - "foo": "no doc", - "list_append": "no doc", - "say_hello": "no doc", - "tolower": "no doc", - "update_dict": "no doc" - } -} -``` - -插件的信息主要包含插件的名字和版本信息,插件提供的函数信息。该信息和插件目录中自动生成的 `api.md` 文件是一致的(插件 API 变化时通过 `kcl-plugin gendoc` 为全部的插件重新生成 `api.md` 文件)。 - -## 4. 插件的目录结构 - -插件的目录结构如下(将其中的 `/Users/kcl_user` 替换成本地的 `$HOME` 路径): - -```shell -$ tree /Users/kcl_user/.kcl/plugins/ -/Users/kcl_user/.kcl/plugins/ -├── _examples -├── _test -└── hello - ├── api.md - ├── plugin.py - └── plugin_test.py -$ -``` - -其中 `_examples` 目录下是插件的示例代码,`_test` 目录下是插件的 KCL 测试代码,其他以字母开头的目录是普通的插件(目录中同时包含 `plugin.py` 和 `plugin_test.py` 文件)。 - -KCL 的插件是有一个独立的纯 Python 代码文件实现,并且插件相互之间不能直接调用。插件的内容如下: - -```shell -$ cat ./hello/plugin.py -# Copyright 2020 The KCL Authors. All rights reserved. -INFO = { - 'name': 'hello', - 'describe': 'hello doc', - 'long_describe': 'long describe', - 'version': '0.0.1', -} -def add(a: int, b: int) -> int: - """add two numbers, and return result""" - return a + b -... -``` - -其中 `INFO` 指明了插件的名字、概要说明、详细说明和版本信息。而所有名字以字母开头的函数是插件给 KCL 提供的函数,因此 KCL 中可以直接调用 `add` 函数。 - -## 5. 创建一个插件 - -通过 `kcl-plugin init` 命令可以创建一个插件示例: - -``` -$ kcl-plugin init hi -$ kcl-plugin list -hello: hello doc - 0.0.1 -hi: hi doc - 0.0.1 -``` - -`kcl-plugin init` 命令会以内置的模板构造一个新的插件,然后通过 `kcl-plugin list` 命令可以查看到新创建的插件。 - -## 6. 插件的删除 - -KCL 插件在 KCL 的 `plugins` 子目录(通常安装在 `$HOME/.kcl/plugins` 目录)。 -可以通过命令 `kcl-plugin info` 查询插件安装目录。 - -```shell -$ kcl-plugin info -/Users/kcl_user/.kcl/plugins/ -$ tree /Users/kcl_user/.kcl/plugins/ -/Users/kcl_user/.kcl/plugins/ -├── _examples -├── _test -└── hello -- 删除这个目录就可以删除 hello plugin - ├── api.md - ├── plugin.py - └── plugin_test.py -$ -``` - -## 7. 插件的测试 - -插件是独立的纯 Python 文件实现,插件目录下有个 `plugin_test.py` 文件是插件的单元测试文件(基于 pytest 测试框架)。此外在 `_test` 目录下放置的是 KCL 文件的插件集成测试。`plugin_test.py` 单元测试是必须的,`_test` 目录下的 KCL 集成测试可以根据情况添加。 - -可以通过 `kcl-plugin test` 执行插件的单元测试: - -```shell -$ kcl-plugin test hello -============================= test session starts ============================== -platform darwin -- Python 3.7.6+, pytest-5.3.5, py-1.9.0, pluggy-0.13.1 -rootdir: /Users/kcl_user -collected 5 items -.kcl/plugins/hello/plugin_test.py ..... [100%] -============================== 5 passed in 0.03s =============================== -$ -``` - -集成测试可以通过在 `_test` 目录下执行 `python3 -m pytest` 命令进行测试。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/plugin/project_context.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/plugin/project_context.md deleted file mode 100644 index 0be02e78..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/plugin/project_context.md +++ /dev/null @@ -1,59 +0,0 @@ -# project_context - -project_context extract base info from project.yaml&stack.yaml - -_version: 0.0.1_ - -## `get_project_current_path` - -return the relative path of first file - -Example: - -```py -import kcl_plugin.project_context as ctx - -path = ctx.get_project_current_path() -print(path) -``` - -## `get_project_input_file` - -return compiling file list - -Example: - -```py -import kcl_plugin.project_context as ctx - -input_file = ctx.get_project_input_file() -print(input_file) -``` - -## `get_project_context` - -return the current project context from project.yaml - -Example: - -```py -import kcl_plugin.project_context as ctx - -project = ctx.get_project_context() -# Get project name -print(project?.name) -``` - -## `get_stack_context` - -return the current stack context from stack.yaml - -Example: - -```py -import kcl_plugin.project_context as ctx - -stack = ctx.get_stack_context() -# Get stack name -print(stack?.name) -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/_category_.json deleted file mode 100644 index e26f646c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "多语言", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/go-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/go-api.md deleted file mode 100644 index 2a978250..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/go-api.md +++ /dev/null @@ -1,665 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Go API - -```go -import kcl "kcl-lang.io/kcl-go" -``` - -## KCL Go SDK - -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ kcl files │ │ KCL-Go-API │ │ KCLResultList │ -│ ┌───────────┐ │ │ │ │ │ -│ │ 1.k │ │ │ │ │ │ -│ └───────────┘ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ ┌───────────┐ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.Get("a.b.c") │ -│ │ 2.k │ │ │ │ Run(path) │ │ │ └───────────┘ │ └───────────────┘ -│ └───────────┘ │────┐ │ └───────────┘ │ │ │ -│ ┌───────────┐ │ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ │ 3.k │ │ │ │ │ │ │ KCLResult │──┼────────▶│x.Get("k", &v) │ -│ └───────────┘ │ │ │ │ │ └───────────┘ │ └───────────────┘ -│ ┌───────────┐ │ ├───▶│ ┌───────────┐ │──────────▶│ │ -│ │setting.yml│ │ │ │ │RunFiles() │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ └───────────┘ │ │ │ └───────────┘ │ │ │ KCLResult │──┼────────▶│x.JSONString() │ -└─────────────────┘ │ │ │ │ └───────────┘ │ └───────────────┘ - │ │ │ │ │ -┌─────────────────┐ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ Options │ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.YAMLString() │ -│WithOptions │ │ │ │MustRun() │ │ │ └───────────┘ │ └───────────────┘ -│WithOverrides │────┘ │ └───────────┘ │ │ │ -│WithWorkDir │ │ │ │ │ -│WithDisableNone │ │ │ │ │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ -``` - -
Example -

- -```go -{ - const k_code = ` -name = "kcl" -age = 1 - -two = 2 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {} -x1 = Person { - age = 101 -} -` - - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First().YAMLString() - fmt.Println(yaml) - - fmt.Println("----") - - result := kcl.MustRun("./testdata/main.k").First() - fmt.Println(result.JSONString()) - - fmt.Println("----") - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - - fmt.Println("----") - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x1", &person)) -} -``` - -

-
- -## Index - -- [Go API](#go-api) - - [KCL Go SDK](#kcl-go-sdk) - - [Index](#index) - - [Constants](#constants) - - [func FormatCode](#func-formatcode) - - [func FormatPath](#func-formatpath) - - [func InitKclvmPath](#func-initkclvmpath) - - [func InitKclvmRuntime](#func-initkclvmruntime) - - [func LintPath](#func-lintpath) - - [func ListDepFiles](#func-listdepfiles) - - [func ListDownStreamFiles](#func-listdownstreamfiles) - - [func ListUpStreamFiles](#func-listupstreamfiles) - - [func OverrideFile](#func-overridefile) - - [func ValidateCode](#func-validatecode) - - [type KCLResult](#type-kclresult) - - [type KCLResultList](#type-kclresultlist) - - [func MustRun](#func-mustrun) - - [func Run](#func-run) - - [func RunFiles](#func-runfiles) - - [type KclType](#type-kcltype) - - [func GetSchemaType](#func-getschematype) - - [type ListDepFilesOption](#type-listdepfilesoption) - - [type ListDepsOptions](#type-listdepsoptions) - - [type Option](#type-option) - - [func WithCode](#func-withcode) - - [func WithDisableNone](#func-withdisablenone) - - [func WithKFilenames](#func-withkfilenames) - - [func WithOptions](#func-withoptions) - - [func WithOverrides](#func-withoverrides) - - [func WithPrintOverridesAST](#func-withprintoverridesast) - - [func WithSettings](#func-withsettings) - - [func WithSortKeys](#func-withsortkeys) - - [func WithWorkDir](#func-withworkdir) - - [type ValidateOptions](#type-validateoptions) - -## Constants - -KclvmAbiVersion is the current kclvm ABI version. - -```go -const KclvmAbiVersion = scripts.KclvmAbiVersion -``` - -## func [FormatCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L110) - -```go -func FormatCode(code interface{}) ([]byte, error) -``` - -FormatCode returns the formatted code. - -
Example -

- -```go -{ - out, err := kcl.FormatCode(`a = 1+2`) - if err != nil { - log.Fatal(err) - } - fmt.Println(string(out)) - -} -``` - -``` -a = 1 + 2 -``` - -

-
- -## func [FormatPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L122) - -```go -func FormatPath(path string) (changedPaths []string, err error) -``` - -FormatPath formats files from the given path path: if path is \`.\` or empty string, all KCL files in current directory will be formatted, not recursively if path is \`path/file.k\`, the specified KCL file will be formatted if path is \`path/to/dir\`, all KCL files in the specified dir will be formatted, not recursively if path is \`path/to/dir/...\`, all KCL files in the specified dir will be formatted recursively - -the returned changedPaths are the changed file paths \(relative path\) - -
Example -

- -```go -{ - changedPaths, err := kcl.FormatPath("testdata/fmt") - if err != nil { - log.Fatal(err) - } - fmt.Println(changedPaths) -} -``` - -

-
- -## func [InitKclvmPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L54) - -```go -func InitKclvmPath(kclvmRoot string) -``` - -InitKclvmPath init kclvm path. - -## func [InitKclvmRuntime](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L59) - -```go -func InitKclvmRuntime(n int) -``` - -InitKclvmRuntime init kclvm process. - -## func [LintPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L142) - -```go -func LintPath(paths []string) (results []string, err error) -``` - -LintPath lint files from the given path - -
Example -

- -```go -{ - - results, err := kcl.LintPath([]string{"testdata/lint/import.k"}) - if err != nil { - log.Fatal(err) - } - for _, s := range results { - fmt.Println(s) - } - -} -``` - -``` -Module 'a' is reimported multiple times -Module 'a' imported but unused -``` - -

-
- -## func [ListDepFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L127) - -```go -func ListDepFiles(workDir string, opt *ListDepFilesOption) (files []string, err error) -``` - -ListDepFiles return the depend files from the given path - -## func [ListDownStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L137) - -```go -func ListDownStreamFiles(workDir string, opt *ListDepsOptions) ([]string, error) -``` - -ListDownStreamFiles return a list of downstream depend files from the given changed path list. - -## func [ListUpStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L132) - -```go -func ListUpStreamFiles(workDir string, opt *ListDepsOptions) (deps []string, err error) -``` - -ListUpStreamFiles return a list of upstream depend files from the given path list - -## func [OverrideFile](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L154) - -```go -func OverrideFile(file string, specs, importPaths []string) (bool, error) -``` - -OverrideFile rewrites a file with override spec file: string. The File that need to be overridden specs: \[\]string. List of specs that need to be overridden. - -``` -Each spec string satisfies the form: := or :- -When the pkgpath is '__main__', it can be omitted. -``` - -importPaths. List of import statements that need to be added - -## func [ValidateCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L159) - -```go -func ValidateCode(data, code string, opt *ValidateOptions) (ok bool, err error) -``` - -ValidateCode validate data match code - -## type [KCLResult](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L47) - -```go -type KCLResult = kcl.KCLResult -``` - -
Example -

- -```go -{ - const k_code = ` -name = "kcl" -age = 1 - -two = 2 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {name = "kcl-go"} -x1 = Person {age = 101} -` - - result := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First() - - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - -} -``` - -``` -x0.name: kcl-go -x1.age: 101 -``` - -

-
- -
Example ('et_struct) -

- -```go -{ - const k_code = ` -schema Person: - name: str = "kcl" - age: int = 1 - X: int = 2 - -x = { - "a": Person {age = 101} - "b": 123 -} -` - - result := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First() - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x.a", &person)) - fmt.Printf("person: %+v\n", person) - -} -``` - -``` -person: &{Name:kcl Age:101} -person: {Name:kcl Age:101} -``` - -

-
- -## type [KCLResultList](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L48) - -```go -type KCLResultList = kcl.KCLResultList -``` - -### func [MustRun](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L64) - -```go -func MustRun(path string, opts ...Option) *KCLResultList -``` - -MustRun is like Run but panics if return any error. - -
Example -

- -```go -{ - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(`name = "kcl"`)).First().YAMLString() - fmt.Println(yaml) - -} -``` - -``` -name: kcl -``` - -

-
- -
Example (Raw Yaml) -

- -```go -{ - const code = ` -b = 1 -a = 2 -` - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(code)).GetRawYamlResult() - fmt.Println(yaml) - - yaml_sorted := kcl.MustRun("testdata/main.k", kcl.WithCode(code), kcl.WithSortKeys(true)).GetRawYamlResult() - fmt.Println(yaml_sorted) - -} -``` - -``` -b: 1 -a: 2 -a: 2 -b: 1 -``` - -

-
- -
Example (Schema Type) -

- -```go -{ - const code = ` -schema Person: - name: str = "" - -x = Person() -` - json := kcl.MustRun("testdata/main.k", kcl.WithCode(code)).First().JSONString() - fmt.Println(json) - -} -``` - -``` -{ - "x": { - "name": "" - } -} -``` - -

-
- -
Example (Settings) -

- -```go -{ - yaml := kcl.MustRun("./testdata/app0/kcl.yaml").First().YAMLString() - fmt.Println(yaml) -} -``` - -

-
- -### func [Run](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L69) - -```go -func Run(path string, opts ...Option) (*KCLResultList, error) -``` - -Run evaluates the KCL program with path and opts, then returns the object list. - -
Example (Get Field) -

- -```go -{ - - x, err := kcl.Run("./testdata/app0/kcl.yaml") - assert(err == nil, err) - - fmt.Println(x.First().Get("deploy_topology.1.zone")) - -} -``` - -``` -R000A -``` - -

-
- -### func [RunFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L74) - -```go -func RunFiles(paths []string, opts ...Option) (*KCLResultList, error) -``` - -RunFiles evaluates the KCL program with multi file path and opts, then returns the object list. - -
Example -

- -```go -{ - result, _ := kcl.RunFiles([]string{"./testdata/app0/kcl.yaml"}) - fmt.Println(result.First().YAMLString()) -} -``` - -

-
- -## type [KclType](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L50) - -```go -type KclType = kcl.KclType -``` - -### func [GetSchemaType](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L176) - -```go -func GetSchemaType(file, code, schemaName string) ([]*KclType, error) -``` - -GetSchemaType returns schema types from a kcl file or code. - -file: string - -``` -The kcl filename -``` - -code: string - -``` -The kcl code string -``` - -schema_name: string - -``` -The schema name got, when the schema name is empty, all schemas are returned. -``` - -## type [ListDepFilesOption](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L45) - -```go -type ListDepFilesOption = list.Option -``` - -## type [ListDepsOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L44) - -```go -type ListDepsOptions = list.DepOptions -``` - -## type [Option](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L43) - -```go -type Option = kcl.Option -``` - -### func [WithCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L79) - -```go -func WithCode(codes ...string) Option -``` - -WithCode returns a Option which hold a kcl source code list. - -### func [WithDisableNone](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L97) - -```go -func WithDisableNone(disableNone bool) Option -``` - -WithDisableNone returns a Option which hold a disable none switch. - -### func [WithKFilenames](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L82) - -```go -func WithKFilenames(filenames ...string) Option -``` - -WithKFilenames returns a Option which hold a filenames list. - -### func [WithOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L85) - -```go -func WithOptions(key_value_list ...string) Option -``` - -WithOptions returns a Option which hold a key=value pair list for option function. - -
Example -

- -```go -{ - const code = ` -name = option("name") -age = option("age") -` - x, err := kcl.Run("hello.k", kcl.WithCode(code), - kcl.WithOptions("name=kcl", "age=1"), - ) - if err != nil { - log.Fatal(err) - } - - fmt.Println(x.First().YAMLString()) - -} -``` - -``` -age: 1 -name: kcl -``` - -

-
- -### func [WithOverrides](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L88) - -```go -func WithOverrides(override_list ...string) Option -``` - -WithOverrides returns a Option which hold a override list. - -### func [WithPrintOverridesAST](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L100) - -```go -func WithPrintOverridesAST(printOverridesAST bool) Option -``` - -WithPrintOverridesAST returns a Option which hold a printOverridesAST switch. - -### func [WithSettings](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L91) - -```go -func WithSettings(filename string) Option -``` - -WithSettings returns a Option which hold a settings file. - -### func [WithSortKeys](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L105) - -```go -func WithSortKeys(sortKeys bool) Option -``` - -WithSortKeys returns a Option which hold a sortKeys switch. - -### func [WithWorkDir](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L94) - -```go -func WithWorkDir(workDir string) Option -``` - -WithWorkDir returns a Option which hold a work dir. - -## type [ValidateOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L46) - -```go -type ValidateOptions = validate.ValidateOptions -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/index.md deleted file mode 100644 index ea02d458..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/index.md +++ /dev/null @@ -1 +0,0 @@ -# 多语言 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/java-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/java-api.md deleted file mode 100644 index 1cea9e49..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/java-api.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Java API - -目前 KCL Java SDK 还处于早期预览版本,后续 KCL 团队会持续更新并提供更丰富的功能,更多信息请参阅:[https://github.com/kcl-lang/kcl-java](https://github.com/kcl-lang/kcl-java)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/overview.md deleted file mode 100644 index 29c8680d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/overview.md +++ /dev/null @@ -1,295 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 简介 - -KCL 语言提供 C/Rust/Go/Python/Java 等通用编程语言接口,相关语言正在开发完整中。 - -## C/Rust 语言 - -KCL 核心采用 Rust 语言开发,对外导出 C 语言 API 供 Go/Python/Java 等高级语言包装和集成。 - -## Go 语言 - -Go 语言是通过 CGO 包装 KCL 提供的 C-API,同时提供更深度的定制特性以满足上层工具的需求。 - -### API 抽象模型 - -Go 语言 API 的抽象模型如下图: - -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ kcl files │ │ KCL-Go-API │ │ KCLResultList │ -│ ┌───────────┐ │ │ │ │ │ -│ │ 1.k │ │ │ │ │ │ -│ └───────────┘ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ ┌───────────┐ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.Get("a.b.c") │ -│ │ 2.k │ │ │ │ Run(path) │ │ │ └───────────┘ │ └───────────────┘ -│ └───────────┘ │────┐ │ └───────────┘ │ │ │ -│ ┌───────────┐ │ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ │ 3.k │ │ │ │ │ │ │ KCLResult │──┼────────▶│x.Get("k", &v) │ -│ └───────────┘ │ │ │ │ │ └───────────┘ │ └───────────────┘ -│ ┌───────────┐ │ ├───▶│ ┌───────────┐ │──────────▶│ │ -│ │setting.yml│ │ │ │ │RunFiles() │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ └───────────┘ │ │ │ └───────────┘ │ │ │ KCLResult │──┼────────▶│x.JSONString() │ -└─────────────────┘ │ │ │ │ └───────────┘ │ └───────────────┘ - │ │ │ │ │ -┌─────────────────┐ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ Options │ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.YAMLString() │ -│WithOptions │ │ │ │MustRun() │ │ │ └───────────┘ │ └───────────────┘ -│WithOverrides │────┘ │ └───────────┘ │ │ │ -│WithWorkDir │ │ │ │ │ -│WithDisableNone │ │ │ │ │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ -``` - -其中输入的文件包含 KCL 文件和 `setting.yml` 配置文件,`Options` 可以用于指定额外的参数和工作目录等信息。“KCL-Go-API”部分是提供的 KCL 执行函数,执行函数根据输入文件和额外的参数执行 KCL 程序,最终输出 `KCLResultList` 结果。`KCLResultList` 是一个 `KCLResult` 构成的列表,每个 `KCLResult` 对应一个生成的配置文件或 `map[string]interface{}`。 - -### 例子 - -```go -package main - -import ( - "fmt" - - kcl "kcl-lang.io/kcl-go" -) - - -func main() { - const k_code = ` -name = "kcl" -age = 1 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person{} -x1 = Person{age:101} -` - - result := kcl.MustRun("hello.k", kcl.WithCode(k_code)).First() - fmt.Println(result.YAMLString()) - - fmt.Println("----") - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - - fmt.Println("----") - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x1", &person)) -} -``` - -输出结果: - -```yaml -age: 1 -name: kcl -x0: - age: 1 - name: kcl -x1: - age: 101 - name: kcl - ----- -x0.name: kcl -x1.age: 101 ----- -person: &{Name:kcl Age:101} -``` - -## REST-API - -KCL 提供的 C-API 并没有 REST-API,REST-API 是通过 Protobuf 定义,最终由上层的 Go-SDK 提供实现。 - -### 启动 REST 服务 - -通过以下方式可以启动 RestAPI 服务: - -```shell -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -然后可以通过 POST 协议请求服务: - -```shell -$ curl -X POST http://127.0.0.1:2021/api:protorpc/BuiltinService.Ping --data '{}' -{ - "error": "", - "result": {} -} -``` - -其中 POST 请求和返回的 JSON 数据和 Protobuf 定义的结构保持一致。 - -### `BuiltinService` 服务 - -其中 `/api:protorpc/BuiltinService.Ping` 路径表示 `BuiltinService` 服务的 `Ping` 方法。 - -完整的 `BuiltinService` 由 Protobuf 定义: - -```protobuf -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} -``` - -其中 `Ping` 方法可以验证服务是否正常,`ListMethod` 方法可以查询提供的全部服务和函数列表。 - -### `KclvmService` 服务 - -`KclvmService` 服务是和 KCL 功能相关的服务。用法和 `BuiltinService` 服务一样。 - -比如有以下的 `Person` 结构定义: - -```python -schema Person: - key: str - - check: - "value" in key # 'key' is required and 'key' must contain "value" -``` - -然后希望通过 `Person` 来校验以下的 JSON 数据: - -```json -{ "key": "value" } -``` - -可以通过 `KclvmService` 服务的 `ValidateCode` 方法完成。参考 `ValidateCode` 方法的 `ValidateCode_Args` 参数结构: - -```protobuf -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} -``` - -根据 `ValidateCode_Args` 参数结构构造 POST 请求需要的 JSON 数据,其中包含 `Person` 定义和要校验的 JSON 数据: - -```json -{ - "code": "\nschema Person:\n key: str\n\n check:\n \"value\" in key # 'key' is required and 'key' must contain \"value\"\n", - "data": "{\"key\": \"value\"}" -} -``` - -将该 JSON 数据保存到 `vet-hello.json` 文件,然后通过以下命令进行校验: - -```shell -$ curl -X POST \ - http://127.0.0.1:2021/api:protorpc/KclvmService.ValidateCode \ - -H "accept: application/json" \ - --data @./vet-hello.json -{ - "error": "", - "result": { - "success": true - } -} -``` - -说明校验成功。 - -## Python 语言 - -使用 Python SDK 要求您本地具备高于 3.7.3 的 Python 版本和 pip 包管理工具,可以通过如下命令进行安装并获得帮助信息 - -```bash -python3 -m pip install kclvm --user && python3 -m kclvm --help -``` - -### 命令行工具 - -编写名为 `main.k` 的 KCL 文件: - -```python -name = "kcl" -age = 1 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {} -x1 = Person { - age = 101 -} -``` - -执行如下命令并获得输出: - -```shell -$ python3 -m kclvm hello.k -name: kcl -age: 1 -x0: - name: kcl - age: 1 -x1: - name: kcl - age: 101 -``` - -### API - -此外,我们还可以通过 Python 代码实现对 KCL 文件的执行 - -编写名为 `main.py` 的 python 文件: - -```python -import kclvm.program.exec as kclvm_exec -import kclvm.vm.planner as planner - -print(planner.plan(kclvm_exec.Run(["hello.k"]).filter_by_path_selector())) -``` - -执行如下命令并获得输出: - -```shell -$ python3 main.py -name: kcl -age: 1 -x0: - name: kcl - age: 1 -x1: - name: kcl - age: 101 -``` - -可以看出通过命令行工具和 API 可以获得同样的输出。 - -目前 KCL Python SDK 还处于早期预览版本,后续 KCL 团队会持续更新并提供更丰富的功能,更多信息请参阅:[https://github.com/kcl-lang/kcl-py](https://github.com/kcl-lang/kcl-py) - -## 其它语言 - -用户也可以基于 C-API 和 RestAPI 包装其它语言的 SDK。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/python-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/python-api.md deleted file mode 100644 index ad3ad867..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/python-api.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Python API - -目前 KCL Python SDK 还处于早期预览版本,后续 KCL 团队会持续更新并提供更丰富的功能,更多信息请参阅:[https://github.com/kcl-lang/kcl-py](https://github.com/kcl-lang/kcl-py)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/rest-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/rest-api.md deleted file mode 100644 index 74a9bf4c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/xlang-api/rest-api.md +++ /dev/null @@ -1,455 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Rest API - -## 1. 启动 REST 服务 - -通过以下方式可以启动 RestAPI 服务: - -```shell -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -或者 - -```shell -go install kcl-lang.io/kcl-go/cmds/kcl-go@main -kcl-go rest-server -``` - -然后可以通过 POST 协议请求服务: - -```shell -curl -X POST http://127.0.0.1:2021/api:protorpc/BuiltinService.Ping --data '{}' -``` - -期望输出为 - -```shell -{ - "error": "", - "result": {} -} -``` - -其中 POST 请求和返回的 JSON 数据和 Protobuf 定义的结构保持一致。 - -## 2. `BuiltinService` 服务 - -其中 `/api:protorpc/BuiltinService.Ping` 路径表示 `BuiltinService` 服务的 `Ping` 方法。 - -完整的 `BuiltinService` 由 Protobuf 定义: - -```protobuf -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} -``` - -其中 `Ping` 方法可以验证服务是否正常,`ListMethod` 方法可以查询提供的全部服务和函数列表。 - -## 3. `KclvmService` 服务 - -`KclvmService` 服务是和 KCL 功能相关的服务。用法和 `BuiltinService` 服务一样。 - -比如有以下的 `Person` 结构定义: - -```python -schema Person: - key: str - - check: - "value" in key # 'key' is required and 'key' must contain "value" -``` - -然后希望通过 `Person` 来校验以下的 JSON 数据: - -```json -{ "key": "value" } -``` - -可以通过 `KclvmService` 服务的 `ValidateCode` 方法完成。参考 `ValidateCode` 方法的 `ValidateCode_Args` 参数结构: - -```protobuf -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} -``` - -根据 `ValidateCode_Args` 参数结构构造 POST 请求需要的 JSON 数据,其中包含 `Person` 定义和要校验的 JSON 数据: - -```json -{ - "code": "\nschema Person:\n key: str\n\n check:\n \"value\" in key # 'key' is required and 'key' must contain \"value\"\n", - "data": "{\"key\": \"value\"}" -} -``` - -将该 JSON 数据保存到 `vet-hello.json` 文件,然后通过以下命令进行校验: - -```shell -curl -X POST \ - http://127.0.0.1:2021/api:protorpc/KclvmService.ValidateCode \ - -H "accept: application/json" \ - --data @./vet-hello.json -``` - -如果看到输出 - -```json -{ - "error": "", - "result": { - "success": true - } -} -``` - -说明校验成功。 - -## 4. 完整的 Protobuf 服务定义 - -跨语言的 API 通过 Protobuf 定义([https://github.com/kcl-lang/kcl-go/blob/main/pkg/spec/gpyrpc/gpyrpc.proto](https://github.com/kcl-lang/kcl-go/blob/main/pkg/spec/gpyrpc/gpyrpc.proto)): - -```protobuf -// Copyright 2023 The KCL Authors. All rights reserved. -// -// This file defines the request parameters and return structure of the KCL RPC server. -// We can use the following command to start a KCL RPC server. - -syntax = "proto3"; - -package gpyrpc; - -import "google/protobuf/any.proto"; -import "google/protobuf/descriptor.proto"; - -// ---------------------------------------------------------------------------- - -// kcl main.k -D name=value -message CmdArgSpec { - string name = 1; - string value = 2; -} - -// kcl main.k -O pkgpath:path.to.field=field_value -message CmdOverrideSpec { - string pkgpath = 1; - string field_path = 2; - string field_value = 3; - string action = 4; -} - -// ---------------------------------------------------------------------------- -// gpyrpc request/response/error types -// ---------------------------------------------------------------------------- - -message RestResponse { - google.protobuf.Any result = 1; - string error = 2; - KclError kcl_err = 3; -} - -message KclError { - string ewcode = 1; // See kclvm/kcl/error/kcl_err_msg.py - string name = 2; - string msg = 3; - repeated KclErrorInfo error_infos = 4; -} - -message KclErrorInfo { - string err_level = 1; - string arg_msg = 2; - string filename = 3; - string src_code = 4; - string line_no = 5; - string col_no = 6; -} - -// ---------------------------------------------------------------------------- -// service requset/response -// ---------------------------------------------------------------------------- - -// gpyrpc.BuiltinService -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -// gpyrpc.KclvmService -service KclvmService { - rpc Ping(Ping_Args) returns(Ping_Result); - - rpc ExecProgram(ExecProgram_Args) returns(ExecProgram_Result); - - rpc FormatCode(FormatCode_Args) returns(FormatCode_Result); - rpc FormatPath(FormatPath_Args) returns(FormatPath_Result); - rpc LintPath(LintPath_Args) returns(LintPath_Result); - rpc OverrideFile(OverrideFile_Args) returns (OverrideFile_Result); - - rpc GetSchemaType(GetSchemaType_Args) returns(GetSchemaType_Result); - rpc GetSchemaTypeMapping(GetSchemaTypeMapping_Args) returns(GetSchemaTypeMapping_Result); - rpc ValidateCode(ValidateCode_Args) returns(ValidateCode_Result); - - rpc ListDepFiles(ListDepFiles_Args) returns(ListDepFiles_Result); - rpc LoadSettingsFiles(LoadSettingsFiles_Args) returns(LoadSettingsFiles_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} - -message ParseFile_AST_Args { - string filename = 1; - string source_code = 2; -} -message ParseFile_AST_Result { - string ast_json = 1; // json value - KclError kcl_err = 2; -} - -message ParseProgram_AST_Args { - repeated string k_filename_list = 1; -} -message ParseProgram_AST_Result { - string ast_json = 1; // json value - KclError kcl_err = 2; -} - -message ExecProgram_Args { - string work_dir = 1; - - repeated string k_filename_list = 2; - repeated string k_code_list = 3; - - repeated CmdArgSpec args = 4; - repeated CmdOverrideSpec overrides = 5; - - bool disable_yaml_result = 6; - - bool print_override_ast = 7; - - // -r --strict-range-check - bool strict_range_check = 8; - - // -n --disable-none - bool disable_none = 9; - // -v --verbose - int32 verbose = 10; - - // -d --debug - int32 debug = 11; - - // yaml/json: sort keys - bool sort_keys = 12; - // include schema type path in JSON/YAML result - bool include_schema_type_path = 13; -} -message ExecProgram_Result { - string json_result = 1; - string yaml_result = 2; - - string escaped_time = 101; -} - -message ResetPlugin_Args { - string plugin_root = 1; -} -message ResetPlugin_Result { - // empty -} - -message FormatCode_Args { - string source = 1; -} - -message FormatCode_Result { - bytes formatted = 1; -} - -message FormatPath_Args { - string path = 1; -} - -message FormatPath_Result { - repeated string changed_paths = 1; -} - -message LintPath_Args { - repeated string paths = 1; -} - -message LintPath_Result { - repeated string results = 1; -} - -message OverrideFile_Args { - string file = 1; - repeated string specs = 2; - repeated string import_paths = 3; -} - -message OverrideFile_Result { - bool result = 1; -} - -message EvalCode_Args { - string code = 1; -} -message EvalCode_Result { - string json_result = 2; -} - -message ResolveCode_Args { - string code = 1; -} - -message ResolveCode_Result { - bool success = 1; -} - -message GetSchemaType_Args { - string file = 1; - string code = 2; - string schema_name = 3; -} -message GetSchemaType_Result { - repeated KclType schema_type_list = 1; -} - -message GetSchemaTypeMapping_Args { - string file = 1; - string code = 2; - string schema_name = 3; -} -message GetSchemaTypeMapping_Result { - map schema_type_mapping = 1; -} - -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} - -message ValidateCode_Result { - bool success = 1; - string err_message = 2; -} - -message Position { - int64 line = 1; - int64 column = 2; - string filename = 3; -} - -message ListDepFiles_Args { - string work_dir = 1; - bool use_abs_path = 2; - bool include_all = 3; - bool use_fast_parser = 4; -} - -message ListDepFiles_Result { - string pkgroot = 1; - string pkgpath = 2; - repeated string files = 3; -} - -// --------------------------------------------------------------------------------- -// LoadSettingsFiles API -// Input work dir and setting files and return the merged kcl singleton config. -// --------------------------------------------------------------------------------- - -message LoadSettingsFiles_Args { - string work_dir = 1; - repeated string files = 2; -} - -message LoadSettingsFiles_Result { - CliConfig kcl_cli_configs = 1; - repeated KeyValuePair kcl_options = 2; -} - -message CliConfig { - repeated string files = 1; - string output = 2; - repeated string overrides = 3; - repeated string path_selector = 4; - bool strict_range_check = 5; - bool disable_none = 6; - int64 verbose = 7; - bool debug = 8; -} - -message KeyValuePair { - string key = 1; - string value = 2; -} - -// ---------------------------------------------------------------------------- -// JSON Schema Lit -// ---------------------------------------------------------------------------- - -message KclType { - string type = 1; // schema, dict, list, str, int, float, bool, any, union, number_multiplier - repeated KclType union_types = 2 ; // union types - string default = 3; // default value - - string schema_name = 4; // schema name - string schema_doc = 5; // schema doc - map properties = 6; // schema properties - repeated string required = 7; // required schema properties, [property_name1, property_name2] - - KclType key = 8; // dict key type - KclType item = 9; // dict/list item type - - int32 line = 10; - - repeated Decorator decorators = 11; // schema decorators -} - -message Decorator { - string name = 1; - repeated string arguments = 2; - map keywords = 3; -} - -// ---------------------------------------------------------------------------- -// END -// ---------------------------------------------------------------------------- -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/Ide/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/Ide/_category_.json deleted file mode 100644 index fcdc7f10..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/Ide/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "集成开发环境", - "position": 2 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/Ide/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/Ide/index.md deleted file mode 100644 index 2ba6e5b4..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/Ide/index.md +++ /dev/null @@ -1,6 +0,0 @@ -# IDE - -我们为 KCL 提供了两种简单的 IDE 插件。您可以通过以下链接获得更多帮助信息: - -- IntelliJ 插件: https://github.com/kcl-lang/intellij-kcl -- VSCode 插件: https://github.com/kcl-lang/vscode-kcl diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/Ide/vs-code.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/Ide/vs-code.md deleted file mode 100644 index e2154f31..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/Ide/vs-code.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Visual Studio Code - -## 快速开始 - -- 1. [安装 KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) 并检查 `kcl` 和 `kcl-language-server` 命令在您的 PATH 中: - - ```bash - which kcl - which kcl-language-server - ``` - -- 2. 安装 [VS Code KCL 插件](https://marketplace.visualstudio.com/items?itemName=kcl.kcl-vscode-extension). 需要您的 VS Code 版本大于 1.50+ -- 3. 重新打开 VS Code 并创建一个 KCL 文件验证 IDE 插件功能 - -## 特性 - -此扩展提供了一些 KCL 编码帮助,包括以下功能: - -- **语法高亮** - ![Highlight](/img/docs/tools/Ide/vs-code/Highlight.png) -- **跳转** - ![Goto Definition](/img/docs/tools/Ide/vs-code/GotoDef.gif) -- **补全** - ![Completion](/img/docs/tools/Ide/vs-code/Completion.gif) -- **大纲** - ![Outline](/img/docs/tools/Ide/vs-code/Outline.gif) -- **悬停** - ![Hover](/img/docs/tools/Ide/vs-code/Hover.gif) -- **诊断** - ![Diagnostics](/img/docs/tools/Ide/vs-code/Diagnostics.gif) - -> 提示:您可以通过安装 [Error Lens 插件](https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens) 来增强诊断效果 - -其他一些有用的功能,如代码重构和智能感知等正在开发中。 - -## 最小依赖 - -我们建议您使用最新版本的 KCL,但此扩展所需的 KCL 最低版本为 v0.4.6。如果您使用的是更早期版本,则此扩展可能无法正常工作。 - -## 已知问题 - -[详见](https://github.com/kcl-lang/kcl/issues/524) - -## 寻求帮助 - -如果扩展没有如您所期望的那样工作,请通过[社区](https://kcl-lang.io/docs/community/intro/support)与我们联系和寻求帮助。 - -## 参与贡献 - -目前 VS Code KCL 插件处于早期版本,我们正在积极改进 VS Code KCL 插件体验,欢迎参考[贡献指南](https://kcl-lang.io/docs/community/contribute) 一起共建! - -## 许可 - -Apache License 2.0 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/_category_.json deleted file mode 100644 index 5170334a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "工具", - "position": 3 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/_category_.json deleted file mode 100644 index 8fac9ad8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "命令行工具", - "position": 1 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/index.md deleted file mode 100644 index f754b5ca..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# 命令行工具 - -KCL 提供了 IDE 插件、丰富的语言工具和 OpenAPI 工具。通过这些工具,可以提供一整套解决方案,包括配置语言、模型界面、自动化工具和最佳实践。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/_category_.json deleted file mode 100644 index b22440b7..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KCL 语言工具", - "position": 2 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/docgen.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/docgen.md deleted file mode 100644 index 37b660ed..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/docgen.md +++ /dev/null @@ -1,313 +0,0 @@ ---- -sidebar_position: 5 ---- - -# 文档生成工具 - -KCL 命令行工具支持从 KCL 源码中一键提取模型文档,并支持丰富的输出格式:JSON,YAML 和 Markdown 等。本文介绍 KCL 语言的文档规范,举例说明如何使用 KCL 文档生成工具提取文档,并展示新增本地化语言文档的流程。 - -## 1. KCL 语言的文档规范 - -KCL文件的文档主要包含如下两个部分: - -- 当前 KCL Moudle 的文档:对当前 KCL 文件的说明 -- KCL 文件内包含的所有 Schema 的文档:对当前 Schema 的说明,其中包含 Schema 描述、Schema 各属性的描述、Examples 三部分,具体格式如下: - -1. Schema 描述 - -```python -"""这是Schema一个简短的描述信息 -""" -``` - -2. Schema 各属性的描述:包含属性描述、属性类型、默认值、是否可选 - -```python -""" -Attributes ----------- -x : type, default is a, optional. - Description of parameter `x`. -y : type, default is b, required. - Description of parameter `y`. -""" -``` - -其中,使用 `----------` 表示 `Attributes` 为一个标题(`-` 符号长度与标题长度保持一致),属性名称与属性类型用冒号 `:` 分隔,属性的说明另起一行并增加缩进进行书写。属性的默认值说明跟在属性类型之后使用逗号 `,` 分隔,书写为 `default is {默认值}` 形式,此外需要说明属性是否为可选/必选,对于可选属性在默认值之后书写 `optional`,对于必选属性在默认值之后书写 `required`。 - -3. Examples - -```python -""" -Examples --------- -val = Schema { - name = "Alice" - age = 18 -} -""" -``` - -此外,KCL 文档字符串语法应采用 [re-structured text (reST)](https://docutils.sourceforge.io/rst.html) 语法子集,并使用 [Sphinx](https://www.sphinx-doc.org/en/master/) 渲染呈现。 - -## 2. 从 KCL 源码生成文档 - -使用 kcl-doc generate 命令,从用户指定的文件或目录中提取文档,并输出到指定目录。 - -1. 参数说明 - -``` -usage: kcl-doc generate [-h] [--format YAML] [-o OUTPUT] [--r] - [--i18n-locale LOCALE] [--repo-url REPO_URL] - [files [files ...]] - -positional arguments: - files KCL file paths. If there's more than one files to - generate, separate them by space - -optional arguments: - -h, --help show this help message and exit - --format YAML Doc file format, support YAML, JSON and MARKDOWN. - Defaults to MARKDOWN - -o OUTPUT, --output-path OUTPUT - Specify the output directory. Defaults to ./kcl_doc - --r, -R, --recursive Search directory recursively - --i18n-locale LOCALE I18n locale, e.g.: zh, zh_cn, en, en_AS. Defaults to - en - --repo-url REPO_URL The source code repository url. It will be displayed in - the generated doc to link to the source code. -``` - -2. 从指定的一个或多个文件中提取文档,并输出到指定目录 - -```text -kcl-doc generate your_config.k your_another_config.k -o your_docs_output_dir -``` - -3. 从指定目录内,递归地查找 KCL 源码文件,并提取文档 - -```text -kcl-doc generate your_config_dir -r -o your_docs_output_dir -``` - -4. 在生成文档时,指定源码仓库地址。一经指定,生成的文档中将包含指向源码文件的链接 - -```text -kcl-doc generate your_config.k -o your_docs_output_dir --repo-url https://url/to/source_code -``` - -## 3. 新增本地化语言的文档 - -如前所示,默认情况下,文档生成工具提取的文档以源码 docstring 的内容为准,因而文档的语言随 docstring 编写语言而定。如果需要为源文件新增本地化语言的文档,则可以遵循按如下步骤: - -1. 初始化 i18n 配置文件。该步骤基于指定的 KCL 源码文件,生成相应的 i18n 配置文件,文件格式可选 JSON/YAML,默认为 YAML. 输出的配置文件名称将以指定的目标本地化方言结尾 - -```text -kcl-doc init-i18n your_config.k --format JSON --i18n-locale your_target_locale -``` - -2. 手动修改上述生成的 i18n 配置文件,使用目标语言修改配置中的 doc 字段 - -3. 基于修改后的 i18n 配置,生成本地化语言的文档。工具将查找指定目标语言的 i18n 配置文件,并转化为最终的文档 - -```text -kcl-doc generate your_config_dir --i18n-locale your_target_locale --format Markdown -``` - -接下来,通过一个小例子演示新增本地化语言文档的过程。 - -3.1 准备 KCL 源码文件,例如 server.k: - - ```python - schema Server: - """Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - - Attributes - ---------- - workloadType : str, default is "Deployment", required - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - name : str, required - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - labels : {str:str}, optional - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - - Examples - ---------------------- - myCustomApp = AppConfiguration { - name = "componentName" - } - """ - - workloadType: str = "Deployment" - name: str - labels?: {str: str} - ``` - -3.2 从 server.k 得到初始化的 i18n 配置文件,例如希望为其增加中文文档,指定生成的配置文件格式为 YAML - - ```text - kcl-doc init-i18n server.k --format YAML --i18n-locale zh_cn - ``` - - 该命令将在当前目录下创建 kcl_doc 目录,并生成 i18n 配置文件 kcl_doc/i18n_server_zh_cn.yaml,其内容如下: - - ```yaml - name: server - relative_path: ./server.k - schemas: - - name: Server - doc: | - Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - attributes: - - name: workloadType - doc: | - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - default_value: '"Deployment"' - is_optional: false - - name: name - doc: | - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: false - default_value: '' - - name: labels - doc: | - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - type: - type_str: '{str: str}' - type_category: DICT - dict_type: - key_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - value_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: true - default_value: '' - examples: | - myCustomApp = AppConfiguration { - name = "componentName" - } - doc: '' - source_code_url: '' - ``` - -3.3 修改初始化得到的 i18n 配置,将其中的 doc 字段修改为中文的描述,修改后的配置如下: - - ```yaml - name: server - relative_path: ./server.k - schemas: - - name: Server - doc: | - Server 模型定义了采用 Kubernetes 最佳实践的持续运行的服务的通用配置接口 - attributes: - - name: workloadType - doc: | - workloadType 属性定义了服务的类型,是服务级别的属性。合法的取值有:Deployment, CafeDeployment. - 另请查看:k8s/core/v1/workload_metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - default_value: '"Deployment"' - is_optional: false - - name: name - doc: | - name 为服务的名称,是服务级别的属性。 - 另请查看:k8s/core/v1/metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: false - default_value: '' - - name: labels - doc: | - labels 为服务的标签,是服务级别的属性。 - 另请查看:k8s/core/v1/metadata.k. - type: - type_str: '{str: str}' - type_category: DICT - dict_type: - key_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - value_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: true - default_value: '' - examples: | - myCustomApp = AppConfiguration { - name = "componentName" - } - doc: '' - source_code_url: '' - ``` - -3.4 基于修改后的 i18n 配置,生成本地化语言的文档,执行如下命令,将输出中文的文档 kcl_doc/doc_server_zh_cn.md,命令及生成的文档内容如下: - - ```text - kcl-doc generate server.k --i18n-locale zh_cn --format Markdown - ``` - - ~~~markdown - # server - ## Schema Server - Server 模型定义了采用 Kubernetes 最佳实践的持续运行的服务的通用配置接口 - - ### Attributes - |Name and Description|Type|Default Value|Required| - |--------------------|----|-------------|--------| - |**workloadType**
workloadType 属性定义了服务的类型,是服务级别的属性。合法的取值有:Deployment, CafeDeployment.
另请查看:k8s/core/v1/workload_metadata.k.|str|"Deployment"|**required**| - |**name**
name 为服务的名称,是服务级别的属性。
另请查看:k8s/core/v1/metadata.k.|str|Undefined|**required**| - |**labels**
labels 为服务的标签,是服务级别的属性。
另请查看:k8s/core/v1/metadata.k.|{str: str}|Undefined|optional| - ### Examples - ``` - myCustomApp = AppConfiguration { - name = "componentName" - } - ``` - - - - ~~~ - -## 4. 附录 - -### 1. 常见的 reST 概念 - -对于 reST 格式的文档,段落和缩进很重要,新段落用空白行标记,缩进即为表示输出中的缩进。可以使用如下方式表示字体样式: - -- \*斜体\* -- \*\*粗体\*\* -- \`\`等宽字体\`\` - -参考 [reST 文档](https://docutils.sourceforge.io/rst.html)获得更多帮助。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/fmt.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/fmt.md deleted file mode 100644 index 11199215..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/fmt.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -sidebar_position: 2 ---- - -# 格式化代码 - -KCL 支持通过内置的命令行工具一键格式化多个 KCL 文件文档。本文展示 KCL 编码风格和 KCL 格式化工具的使用方式。 - -## KCL 编码风格 - -KCL 格式化对文件的修改样式具体见 KCL 编码风格:[Style Guide for KCL Code](/docs/reference/lang/spec/codestyle) - -## 使用方式 - -- 单文件格式化 - -```text -kcl-fmt your_config.k -``` - -- 文件夹内多文件格式化 - -```text -kcl-fmt your_config_path -R -``` - -- 命令行参数 - - `-R|--recursive` 设置是否递归遍历子文件夹 - - `-w|--fmt-output` 设置是否输出到标准输出流,不加 `-w` 表示原地格式化 KCL 文件 - -## 格式化文件效果展示 - -- 格式化前 - -```py -import math -mixin DeploymentMixin: - service:str ="my-service" -schema DeploymentBase: - name: str - image : str -schema Deployment[replicas] ( DeploymentBase ) : - mixin[DeploymentMixin] - replicas : int = replicas - command: [str ] - labels: {str: str} -deploy = Deployment(replicas = 3){} -``` - -- 格式化后 - -```py -import math - -mixin DeploymentMixin: - service: str = "my-service" - -schema DeploymentBase: - name: str - image: str - -schema Deployment[replicas](DeploymentBase): - mixin [DeploymentMixin] - replicas: int = replicas - command: [str] - labels: {str:str} - -deploy = Deployment(replicas=3) {} - -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/index.md deleted file mode 100644 index 51f69ee6..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# KCL 语言工具 - -KCL 不仅提供了 kcl 命令编译和执行配置程序,还提供了 fmt、lint、test、vet、docgen 等配套的辅助工具。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/lint.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/lint.md deleted file mode 100644 index 7a66d3b3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/lint.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Lint 检查代码风格 - -KCL 支持通过内置的命令行工具对 KCL 代码进行检查,并支持多种输出格式。本文档展示 KCL Lint 工具的使用方式。 - -## 示例 - -### 工程结构 - -```text -. -└── Test - └── kcl.mod - └── a.k - └── b.k - └── dir - └── c.k - └── test.k -``` - -`a.k`,`b.k`,`c.k`,`test.k` 为测试的 kcl 文件。 - -命令: - -```shell -kcl-lint your_config.k -``` - -或 - -```shell -kcl-lint your_config_path -``` - -### CLI 参数 - -```shell -USAGE: - kcl-lint [OPTIONS] [--] [input]... - -ARGS: - ... Sets the input file to use - -OPTIONS: - --emit_warning Emit warning message - -h, --help Print help information - -v, --verbose Print test information verbosely - -Y, --setting ... Sets the input file to use -``` - -- input: 需要检查的单个 `.k` 文件路径或路径目录下的所有 `.k` 文件,支持绝对路径或当前目录的相对路径 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/overview.md deleted file mode 100644 index 4fa606dc..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/overview.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 概览 - -KCL 工具链是 KCL 语言的工具集合,旨在提升 KCL 的批量迁移、编写、编译和测试的效率。 - -| 类别 | 工具名称 | 说明 | -| ---------- | ---------------------- | --------------------------------------------------------- | -| 主工具集 | **kcl** | kcl 命令行工具提供对基于 KCL 语言的配置编写、编译和运行。 | -| | kcl-test | 即将提供 | -| | kcl-fmt | kcl-fmt 工具提供对 KCL 代码的格式化 | -| | kcl-lint | kcl-lint 工具提供对 KCL 代码的 lint 检查和自动修复 | -| | kcl-doc | kcl-doc 工具提供对 KCL 代码的文档解析和生成 | -| | kcl-vet | 使用 KCL 代码校验诸如 JSON 和 YAML 的数据格式 | -| ide 插件集 | IntelliJ IDEA KCL 插件 | 提供 IntelliJ IDEA 平台的 KCL 编写、编译辅助 | -| | VS Code KCL 插件 | 提供 VS Code 平台的 KCL 编写、编译辅助 | - -## KCL 工具 - -### 命令行参数 - -```shell -USAGE: - kcl [OPTIONS] [--] [input]... - -Arguments: - [input]... Specify the input files to run - -Options: - -o, --output - Specify the YAML output file path - -Y, --setting ... - Specify the input setting file - -v, --verbose... - Print test information verbosely - -n, --disable_none - Disable dumping None values - -r, --strict_range_check - Do perform strict numeric range checks - -d, --debug - Run in debug mode (for developers only) - -k, --sort_keys - Sort result keys - -D, --argument ... - Specify the top-level argument - -S, --path_selector ... - Specify the path selector - -O, --overrides ... - Specify the configuration override path and value - --target - Specify the target type - -E, --external ... - Mapping of package name and path where the package is located - -h, --help - Print help -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/test.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/test.md deleted file mode 100644 index f8707ff9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/test.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 5 ---- - -# 测试工具 - -即将到来! diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/vet.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/vet.md deleted file mode 100644 index 2c70ce91..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/kcl/vet.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Validation 校验代码 - -## 简介 - -KCL 支持通过内置的 `kcl-vet` 命令行工具提供了基本的配置数据校验能力,可以编写 KCL schema 对输入的 JSON/YAML 格式文件进行类型以及数值的校验。 - -## 使用方式 - -假设有 data.json 文件,代码如下: - -```json -{ - "name": "Alice", - "age": 18, - "message": "This is Alice", - "data": { - "id": 1, - "value": "value1" - }, - "labels": { - "key": "value" - }, - "hc": [1, 2, 3] -} -``` - -构造 schema.k 校验文件,内容如下: - -```py -schema User: - name: str - age: int - message?: str - data: Data - labels: {str:} - hc: [int] - - check: - age > 10 - -schema Data: - id: int - value: str -``` - -在目录下执行如下命令 - -```shell -$ kcl-vet data.json schema.k -``` - -## 指定校验的 schema - -当校验的 KCL 文件中存在多个 schema 定义时,kcl-vet 工具会默认取第一个 schema 定义进行校验,如果需要指定校验的 schema,可以使用 `-d|--schema` 参数 - -```shell -$ kcl-vet data.json schema.k -d User -``` - -## 命令行参数 - -```shell -$ kcl-vet -h -USAGE: - kcl-vet [OPTIONS] [ARGS] - -ARGS: - Validation data file - KCL file - -OPTIONS: - -d, --schema - Iterate through subdirectories recursively - - --format - Validation data file format, support YAML and JSON, default is JSON - - -h, --help - Print help information - - -n, --attribute_name - The attribute name for the data loading -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/openapi/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/openapi/_category_.json deleted file mode 100644 index 5df621d8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/openapi/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "OpenAPI 工具", - "position": 3 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/openapi/crd-to-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/openapi/crd-to-kcl.md deleted file mode 100644 index 5b6f070c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/openapi/crd-to-kcl.md +++ /dev/null @@ -1,118 +0,0 @@ -# CRD to KCL - -命令 - -```shell -kcl-openapi generate model --crd -f ${your_CRD.yaml} -t ${the_kcl_files_output_dir} --skip-validation -``` - -# 示例 - -- 输入文件:test_crontab_CRD.yaml: - -```yaml -# Deprecated in v1.16 in favor of apiextensions.k8s.io/v1 -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - # name must match the spec fields below, and be in the form: . - name: crontabs.stable.example.com -spec: - # group name to use for REST API: /apis// - group: stable.example.com - # list of versions supported by this CustomResourceDefinition - versions: - - name: v1 - # Each version can be enabled/disabled by Served flag. - served: true - # One and only one version must be marked as the storage version. - storage: true - # either Namespaced or Cluster - scope: Namespaced - names: - # plural name to be used in the URL: /apis/// - plural: crontabs - # singular name to be used as an alias on the CLI and for display - singular: crontab - # kind is normally the CamelCased singular type. Your resource manifests use this. - kind: CronTab - # shortNames allow shorter string to match your resource on the CLI - shortNames: - - ct - preserveUnknownFields: false - validation: - openAPIV3Schema: - type: object - properties: - spec: - type: object - properties: - cronSpec: - type: string - image: - type: string - replicas: - type: integer -``` - -- 命令 - -```shell -kcl-openapi generate model -f test_crontab_CRD.yaml -t ~/ --skip-validation --crd -``` - -- 输出文件: ~/models/stable_example_com_v1_cron_tab.k - -```python -""" -This file was generated by the KCL auto-gen tool. DO NOT EDIT. -Editing this file might prove futile when you re-run the KCL auto-gen generate command. -""" -import kusion_kubernetes.apimachinery.apis - - -schema CronTab: - """stable example com v1 cron tab - - Attributes - ---------- - apiVersion : str, default is "stable.example.com/v1", required - APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - kind : str, default is "CronTab", required - Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - metadata : apis.ObjectMeta, default is Undefined, optional - metadata - spec : StableExampleComV1CronTabSpec, default is Undefined, optional - spec - """ - - - apiVersion: "stable.example.com/v1" = "stable.example.com/v1" - - kind: "CronTab" = "CronTab" - - metadata?: apis.ObjectMeta - - spec?: StableExampleComV1CronTabSpec - - -schema StableExampleComV1CronTabSpec: - """stable example com v1 cron tab spec - - Attributes - ---------- - cronSpec : str, default is Undefined, optional - cron spec - image : str, default is Undefined, optional - image - replicas : int, default is Undefined, optional - replicas - """ - - - cronSpec?: str - - image?: str - - replicas?: int -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/openapi/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/openapi/index.md deleted file mode 100644 index 0654db2a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/openapi/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# OpenAPI Tools - -kcl-openapi 工具支持将通过 OpenAPI 规范描述的模型转换为 KCL 配置策略语言,除了能直接转换 OpenAPI 描述文件之外,还可以从 Kubernetes CRD 中提取并转换为 KCL schema. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/openapi/openapi-to-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/openapi/openapi-to-kcl.md deleted file mode 100644 index 6d9f8e54..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/openapi/openapi-to-kcl.md +++ /dev/null @@ -1,64 +0,0 @@ -# OpenAPI to KCL - -命令 - -```shell -kcl-openapi generate model -f ${your_open_api_spec.yaml} -t ${the_kcl_files_output_dir} -``` - -示例: - -- 输入文件:test_open_api_spec.yaml: - -```yaml -definitions: - v1.TestInt: - type: object - properties: - name: - type: string - format: int-or-string - required: - - name - x-kcl-type: - import: - package: v1.test_int - alias: test_int - type: TestInt -swagger: "2.0" -info: - title: KCL - version: v0.0.2 -paths: {} -``` - -- 命令: - -```shell -kcl-openapi generate model -f test_open_api_spec.yaml -t ~/ -``` - -- 输出:~/models/v1/test_int.k - -```python -""" -This is the test_int module in v1 package. -This file was generated by the KCL auto-gen tool. DO NOT EDIT. -Editing this file might prove futile when you re-run the KCL auto-gen generate command. -""" - - -schema TestInt: - """v1 test int - - Attributes - ---------- - name : int | str, default is Undefined, required - name - """ - - - name: int | str - - -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/openapi/quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/openapi/quick-start.md deleted file mode 100644 index 3d6a125d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/openapi/quick-start.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 快速开始 - -## 1. 安装 KCLOpenAPI 工具 - -目前有多种安装方式可选: - -- [通过 go install 安装](#11-通过-go-install-安装) -- [通过 curl|sh 安装(仅限 MacOS & Linux)](#12-通过-curlsh-安装(仅限-MacOS--Linux)) -- [下载发布包](#13-下载发布包) - -## 1.1 通过 go install 安装 - -```shell -go install kcl-lang.io/kcl-openapi@latest -``` - -## 1.2 通过 curl|sh 安装(仅限 MacOS & Linux) - -```shell -curl -fsSL https://kcl-lang.io/script/install-kcl-openapi.sh | /bin/bash -``` - -## 1.3 下载发布包 - -```shell -# 1. 下载二进制程序 -# https://github.com/kcl-lang/kcl-openapi/releases - -# 2. 解压发布包,并将命令添加至 PATH -export PATH=":$PATH" -``` - -## 1.4 验证安装结果 - -```shell -➜ kcl-openapi -v -kcl-openapi 0.5.0 -``` - -## 2. 生成 KCL 文件 - -- [将 OpenAPI 描述文件转换为 KCL](../openapi/openapi-to-kcl.md) -- [将 Kubernetes CRD 转换为 KCL](../openapi/crd-to-kcl.md) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/openapi/spec.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/openapi/spec.md deleted file mode 100644 index aee9fc92..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/cli/openapi/spec.md +++ /dev/null @@ -1,424 +0,0 @@ -# KCL OpenAPI 规范 - -[OpenAPI](https://www.openapis.org/) 允许 API 提供方规范地描述 API 操作和模型,并基于它生成自动化工具和特定语言的客户端。 - -## KCL OpenAPI 文件结构 - -依据 OpenAPI 3.0 规范,OpenAPI 文件中应至少包含 openapi、components、 info、paths 四种根节点对象,KCL OpenAPI 聚焦于其中模型定义的部分,即 OpenAPI 文件中的 `definitions`,而描述操作的 Restful API 部分(即 OpenAPI 文件中的 `paths`)则不属于 KCL OpenAPI 定义的范畴。 -​ - -注:除以上列出的节点外,OpenAPI 官方规范还支持 servers、security、tags、externalDocs 四种可选的根节点,但都不是 KCL OpenAPI 所关心的,因此用户无需填写这部分内容,即使填写了也不会产生任何影响。 -​ - -| OpenAPI 顶层对象 | 类型 | 含义 | KCL OpenAPI 工具支持情况 | -| ---------------- | ----------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | -| swagger | string | openapi 版本信息 | 必填项,目前支持 openapi 2.0,即合法取值为 "2.0" | -| definitions | Definition Object | 模型定义 | 必填项 | -| info | Info Object | 当前 API 文件的元数据信息,例如标题、描述信息、版本、开源协议等 | 必填项,定义当前 OpenAPI 文件的基本信息,不会输出到 KCL 代码,但可用于 Swagger-UI 工具可视化展示 | - -为方便初学者快速理解,下面给出一个典型的 KCL OpenAPI 文件(截取自 swagger example [Petstore](https://petstore.swagger.io/))应包含的节点图示。KCL OpenAPI 工具重点关注其中的 definitions 节点,可以看到文件中定义了两个模型(Pet 和 Category),并且 Pet 模型中包含三个属性(name、id、category) - -## KCL schema - -KCL 中使用 schema 结构来定义配置数据的“类型”,关于 KCL schema,可参考文档:传送门 -在 definitions 节点下新增 definition 元素,即可定义 KCL schema. -示例: -下例在 KCL 代码中定义了 Pet、Category 两个 schema,同样地,其对应的 OpenAPI 也在 definitions 节点下包含这两个模型的描述。 - -```python -# KCL schema: -schema Pet: - name: str - id?: int - category?: Category - -schema Category: - name?: str - -# 对应的 OpenAPI 描述 -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "id": { - "type": "integer", - "format": "int64" - }, - "category": { - "$ref": "#/definitions/Category" - } - }, - "required": [ - "name" - ] - }, - "Category": { - "type": "object", - "properties": { - "name": { - "type": "string" - } - } - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -``` - -### schema 名称 - -在 KCL 中,schema 名称紧跟在 schema 关键字后声明,在 OpenAPI 中,模型的名称通过 definition 元素的 key 来定义。 - -### schema 类型 - -KCL schema 在 OpenAPI 中的类型为 "object". 例如上例中 "Pet" 的 "type" 值应为 "object". - -### schema 属性 - -KCL schema 中可以定义若干属性,属性的声明一般包含如下几部分: - -- 属性注解:可选,以 @ 开头,例如 @deprecated 注解表示属性被废弃 -- 属性名称:必须 -- 属性 optional 修饰符(?):可选,带问号表示当前属性为可选属性,可以不被赋值。反之,不带问号表示必填属性 -- 属性类型:必须,可以是基本数据类型,也可以是 schema 类型, 或者是前述两种类型的并集 -- 属性默认值:非必须 - -它们与 OpenAPI 规范的对应关系如下: - -| KCL schema 属性元素 | OpenAPI 元素 | -| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- | -| 属性注解 | 暂不支持,计划扩展一个 deprecate 字段用于描述 deprecated 注解 | | -| 属性名称 | properties 节点下,每个属性的 key 即为属性名称 | -| 属性 optional 修饰符(?) | 模型节点下,通过 required 字段列出该模型的所有必填属性的名称,未被列出的属性即为 optional | -| 属性类型 | 属性节点下,设置 type + format 可以标识属性的基本类型,如果是 schema 类型则用 $ref 字段表示,类型 union 则由扩展字段 x-kcl-types 来标识,此外,属性节点的 enum、pattern 也可以用于表示 KCL 类型。 | -| KCL-OpenAPI 关于类型的对照关系,详见“基本数据类型”小节 | | -| 属性默认值 | 属性节点下,设置 default 字段即可为属性设置默认值 | - -示例: -下例中 Pet 模型包含了 2 个属性:name(string 类型,必填属性,无注解,无默认值)、id(int64 类型,无注解,非必填,默认值为 -1) - -```python -# KCL schema Pet,包含两个属性 name 和 id -schema Pet: - name: str - id?: int = -1 - -# 对应的 OpenAPI 文档 -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - "id": { - "type": "integer", - "format": "int64", - "default": -1 - } - }, - "required": [ - "name" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### schema 索引签名 - -KCL schema 允许定义索引签名,用于定义属性名不固定的 dict,起到静态模板的作用。具体来说,KCL schema 索引签名包含如下几个元素: - -- 索引签名中 key 的类型:在方括号中声明,必须是基础类型 -- 索引签名中 value 的类型:在冒号后声明,可以是任意合法的 KCL 类型 -- 索引签名中的省略符:在方括号中,key 类型之前声明,使用"..."表示。如果带有该符号,表示该索引签名只用于约束未在 schema 中定义的属性;否则,表示 schema 中所有已定义和未定义属性都收到该索引签名的约束。 -- 索引签名中 key 的别名:在方括号中,紧随左方括号之后声明,使用名称 + 冒号表示,该别名可用于按名称引用索引签名 -- 索引签名的默认值:可以为索引签名设置默认值 - -在 OpenAPI 中,可以借助在模型节点的 `additionalProperties` 字段描述某些 key 为 string 的索引签名。但对于 KCL 索引签名中非 string 类型的 dict key、索引签名 key 的 check 校验,在 OpenAPI 规范没有对等的描述。它们与 OpenAPI 规范的对应关系如下: - -| KCL 索引签名元素 | OpenAPI 元素 | -| ----------------------- | ---------------------------------------------------------------------- | -| 索引签名中 key 的类型 | OpenAPI 仅支持 key 为 string 类型,无法自定义 | -| 索引签名中 value 的类型 | 模型节点的下 additionalProperties 下的 "type" 字段 | -| 索引签名中的省略符 | OpenAPI 中表示索引签名时,只能表示 KCL 中带有省略符的情况 | -| 索引签名中 key 的别名 | OpenAPI 中不支持为索引签名定义 key 别名,(预计通过扩展支持:x-alias) | -| 索引签名的默认值 | 目前不支持 | - -示例:下例中的 KCL schema Pet,包含两个预定义的属性 name 和 id,除此之外,还允许使用该 schema 的配置额外地赋值其他 key 为 string 类型,value 为 bool 类型的属性: - -```python -# KCL schema Pet,包含两个预定义的属性 name 和 id,允许额外给 key 为 string、value 为 bool 的属性赋值 -schema Pet: - name: str - id?: int - [...str]: bool - -# 对应的 OpenAPI 描述 -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - "id": { - "type": "integer", - "format": "int64", - } - }, - "additionalProperties": { - "type": "bool" - }, - "required": [ - "name" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### schema 继承关系 - -### 内联 schema - -OpenAPI 支持嵌套地定义 schema,但 KCL 目前暂不支持 schema 的内联。OpenAPI 中内联定义的 schema 将被转换为 KCL 中带名称的 schema,其名称的命名规则为:在该内联 schema 的上层 schema 名称的基础上,增加相应的后缀。在拼接后缀时,根据定义了该内联 schema 的外层 OpenAPI 元素类型,后缀内容如下: - -| OpenAPI 文档中定义内联 schema 的元素 | KCL schema 名称拼接规则 | -| ------------------------------------ | ------------------------------ | -| 某属性节点 | 增加该属性节点的名称为后缀 | -| AdditionalProperties 节点 | 增加"AdditionalProperties"后缀 | - -注:KCL 未来也可能会支持内联 schema,届时再更新这部分转换规则 -示例 1:下例中的模型 Deployment 包含有 kind、spec 两个属性,其中 deploymentSpec 属性的 schema 通过内联的方式定义: - -```python -# OpenAPI 文档 -{ - "definitions": { - "Deployment": { - "type": "object", - "properties": { - "kind": { - "type": "string", - }, - "spec": { - "type": "object", - "properties": { - "replicas": { - "type": "integer", - "format": "int64" - } - } - } - }, - "required": [ - "kind", - "spec" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -# 转换为 KCL Schema 如下: -schema Deployment: - kind: str - spec: DeploymentSpec - -schema DeploymentSpec: - replicas?: int -``` - -示例 2:下例中的模型 Person 中除固定属性 name 外,还允许包含额外的属性(additionalProperties),并且这部分额外属性的属性值的 schema 通过内联的方式定义: - -```python -# OpenAPI 文档 -{ - "definitions": { - "Person": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - }, - "required": [ - "name", - "spec" - ], - "additionalProperties": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "description": { - "type": "string" - } - }, - "required": [ - "name" - ] - }, - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -# 转换为 KCL Schema 如下: -schema Person: - name: str - [...str]: [PersonAdditionalProperties] - -schema PersonAdditionalProperties: - name: str - description?: str -``` - -## KCL 文档 - -KCL doc 规范请参考:[传送门](../kcl/docgen.md) -KCL 文档包含 module 文档、schema 文档两类,其中 schema 文档可以由 OpenAPI 转换得到。KCL schema 文档包含: - -- schema 描述信息:位于 schema 声明之后、schema 属性声明之前,是对 schema 的总体介绍 -- schema 属性信息:位于 shcema 描述信息之后,以 Attributes + 分割线分隔 -- schema 附加信息:位于 schema 属性信息之后,以 See Also + 分割线分隔 -- schema 示例信息:位于 schema 附加信息之后,以 Examples + 分割线分隔 - -它们与 OpenAPI 规范的对应关系如下: - -| KCL 文档元素 | OpenAPI 元素 | -| --------------- | ---------------------------------------------------- | -| schema 描述信息 | definitions 节点下,每个模型节点的 description 字段 | -| schema 属性信息 | properties 节点下,每个属性节点的 description 字段 | -| schema 附加信息 | definitions 节点下,每个模型节点的 externalDocs 字段 | -| schema 示例信息 | definitions 节点下,每个模型节点的 example 字段 | - -示例: -下例中为 Pet 模型定义了其 schema 描述文档 "The schema Pet definition";Pet 的两个属性 "name" 和 "id" 也分别定义了其属性文档 "The name of the pet" 及 "The id of the pet";Pet 的附加信息为 "Find more info here. [https://petstore.swagger.io/](https://petstore.swagger.io/)";此外,Pet 模型还提供了模型实例的示例写法。 - -```python -# KCL schema Pet,采用规范的 KCL 文档格式 -schema Pet: - """The schema Pet definition - - Attributes - ---------- - name : str, default is Undefined, required - The name of the pet - id : int, default is -1, optional - The age of the pet - - See Also - -------- - Find more info here. https://petstore.swagger.io/ - - Examples - -------- - pet = Pet { - name = "doggie" - id = 123 - } - """ - name: str - id?: int = -1 - -# 对应的 OpenAPI 文档 -{ - "definitions": { - "Pet": { - "description": "The schema Pet definition", - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "The name of the pet" - }, - "id": { - "type": "integer", - "format": "int64", - "default": -1, - "description": "The age of the pet" - } - }, - "required": [ - "name" - ], - "externalDocs": { - "description": "Find more info here", - "url": "https://petstore.swagger.io/" - }, - "example": { - "name": "doggie", - "id": 123 - } - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -​ - -## 基本数据类型 - -| JSON Schema type | swagger type | KCL type | comment | -| ---------------- | --------------------------- | --------------- | --------------------------------------------------------------------------- | -| boolean | boolean | bool | | -| number | number | float | | -| | number format double | **unsupported** | | -| | number format float | float | | -| integer | integer | int (32) | | -| | integer format int64 | **unsupported** | | -| | integer format int32 | int (32) | | -| string | string | str | | -| | string format byte | str | | -| | string format int-or-string | int | str | -| | string format binay | str | | -| | string format date | unsupported | As defined by full-date - [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) | -| | string format date-time | unsupported | As defined by date-time - [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) | -| | string format password | unsupported | for swagger: A hint to UIs to obscure input. | -| | datetime | datetime | | - -## Reference - -- openapi spec 2.0:[https://swagger.io/specification/v2/](https://swagger.io/specification/v2/) -- openapi spec 3.0:[https://spec.openapis.org/oas/v3.1.0](https://spec.openapis.org/oas/v3.1.0) -- openapi spec 3.0(swagger 版本):[https://swagger.io/specification/](https://swagger.io/specification/) -- openapi spec 2.0 #SchemaObject:[https://swagger.io/specification/v2/#schemaObject](https://swagger.io/specification/v2/#schemaObject) -- go swagger:[https://goswagger.io/use/models/schemas.html](https://goswagger.io/use/models/schemas.html) -- swagger data models:[https://swagger.io/docs/specification/data-models/](https://swagger.io/docs/specification/data-models/) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/concepts/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/concepts/_category_.json deleted file mode 100644 index d3ae7a0a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/concepts/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "核心概念", - "position": 5 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/concepts/concepts.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/concepts/concepts.md deleted file mode 100644 index e2034db2..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/concepts/concepts.md +++ /dev/null @@ -1,3 +0,0 @@ -# 核心概念 - -学习更多关于 KCL 核心概念。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/concepts/package-and-module.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/concepts/package-and-module.md deleted file mode 100644 index fbde28f3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/concepts/package-and-module.md +++ /dev/null @@ -1,156 +0,0 @@ -# 模块和包 - -本节主要介绍如何组织 KCL 中的文件。 - -## 概述 - -在一个**module**中,KCL 按**package**进行组织文件。package 可以在 module 内定义,也可以通过 KCL 包管理器 `kpm` 从外部导入。在后一种情况下,KCL 在专用位置中维护包的副本。 - -## Module - -KCL 模块按目录层次结构布置配置。它包含了确定 KCL 配置结果所需的一切。此目录的根标记为包含 `kcl.mod` 目录。此目录的内容大多由 kcl 工具(如 `kpm` 等)管理。从这个意义上讲,`kcl.mod` 类似于 `.git` 目录,标记着仓库的根目录,但它的内容主要由 git 工具管理。此外,KCL 模块是文件组织的最大单位,具有所有 KCL 文件和依赖项的固定位置。 - -> 注意: 使用 KCL 模块(例如 `kcl.mod`)是可选的,但如果您想使用语义版本管理、分发、共享和重用代码,则需要使用它。 - -### 创建一个 module - -可以通过在模块根目录中运行以下命令来创建模块: - -```bash -kpm init [module name] -``` - -模块名在需要在模块内导入另一个模块的包时是**必需的**。也可以通过手动设置 `kcl.mod` 文件来创建模块。 - -## Package - -在 KCL 中,一个包通常由包含 KCL 文件的“文件夹”组成。这个文件夹可以是实际的磁盘物理路径,也可以由多个 KCL 文件(通常是主包)组成。不同的包通过不同的包路径(如 `kubernetes.core.v1`)唯一地定位。 - -在同一个模块内,可以通过相对或绝对路径的 import 语句互相导入不同的包。在 KCL 解析过程中,相对 import 将被替换为绝对 import,并通过包路径找到相应的 KCL 代码。 - -### 相对导入路径 - -我们可以使用 `.` 运算符来实现 KCL 入口文件的相对路径导入。 - -main.k: - -```python -import .model1 # Current directory module -import ..service # Parent directory -import ...root # Parent of parent directory - -s = service.ImageService {} -m = root.Schema {} -``` - -### 绝对导入路径 - -KCL 语句`import a.b.c.d` 的语义是: - -1. 如果 `kcl.mod` 不存在,则将当前目录视为包根目录,并从当前目录搜索路径 `a/b/c/d`。 -2. 如果当前目录搜索失败,则从根路径 `ROOT_PATH/a/b/c/d` 搜索,否则引发导入错误。 - -根路径 `ROOT_PATH` 的定义是相对于 `kcl.mod` 文件的目录。 - -代码结构: - -```bash -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -### 内置包 - -KCL 有一系列内置包,例如 `math`,`regex` 等。要使用内置包,直接导入并使用其限定标识符调用函数。例如, - -```python -import regex - -image = "nginx:1.14.2" -is_match = regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$") - -``` - -输出的 YAML 为 - -```yaml -image: nginx:1.14.2 -is_match: true -``` - -### 插件包 - - - -KCL 还有一系列插件包,例如 `hello`,`project_context` 等。要使用插件包,需要用 `kcl_plugin.` 包路径前缀导入,并使用其限定标识符调用函数。例如, - -```python -import kcl_plugin.hello - -result = hello.add(1, 1) -``` - -输出的 YAML 为 - -```yaml -result: 2 -``` - -### 主包 - -在 KCL 中,主包的组成通常由编译器参数确定。这是因为KCL模式和约束可以在包中的文件中分隔,甚至可以在目录中组织,考虑将配置写入和维护在隔离块中的便利性。 - -#### 属于主包的文件 - -用户可以使用KCL命令行决定使用哪些配置和约束,例如, - -```bash -kcl file1.k file2.k -``` - -因此,主包包含两个名为 `file1.k` 和 `file2.k` 的 KCL 文件。 - -如果 KCL 被告知为特定目录加载文件,例如: - -```bash -kcl ./path/to/package -``` - -它将只查找 `.k` 后缀的 KCL 文件,并忽略 `_` 或 `_test.k` 前缀的 KCL 文件合并到主包中。此外,如果 `./path/to/package` 包含 `kcl.yaml` 文件,则 `kcl.yaml` 文件将被忽略。 - -此外,我们可以通过配置命令行编译设置文件(例如 `kcl.yaml`)来设置主包文件,如下所示: - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k -``` - -```bash -kcl -Y kcl.yaml -``` - -> 注意:如果没有为 KCL 指定任何输入文件,KCL 将从命令行执行路径查找默认的 `kcl.yaml` 文件读取输入文件。此外,如果我们告诉KCL输入文件和编译设置文件,KCL将把用户输入的输入文件作为最终值。 - -```bash -# 无论`kcl.yaml` 中是否配置 `files` 字段,输入文件的最终值为["file1.k", "file2.k"] -kcl -Y kcl.yaml file1.k file2.k -``` - -## kcl.mod 和 kcl.yaml 异同 - -首先,在 KCL 中,`kcl.mod` 和 `kcl.yaml` 都是可选的。它们之间的区别在于 `kcl.mod` 确定包路径的根路径以及 KCL 模块是否具有分发和重用要求,而 `kcl.yaml` 确定主包的 KCL 文件组成。 - -其次,对于仅用于外部使用的 kcl module,`kcl.yaml` 是可选的,但 `kcl.mod` 是必需的,因为 `kcl.mod` 需要声明 KCL 版本,模块版本,依赖关系和其他信息。 - -最后,对于 KCL IDE 插件,它需要知道主包信息才能形成完整的编译过程,因此它需要根据光标位置自动查找主包组成,因为没有人可以通过 KCL 命令行指定这些信息。一般的查询逻辑是查找 `kcl.yaml` 的存在性。如果找到了,主包由 `kcl.yaml` 中的文件属性组成,如果找不到,主包由当前文件组成。KCL IDE 插件会有选择地了解 `kcl.mod` 文件。当 `kcl.mod` 文件存在时,IDE 插件会读取所有包路径及其在外部依赖项中的实际路径的相应信息。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/getting-started/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/getting-started/_category_.json deleted file mode 100644 index c826d665..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/getting-started/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "快速开始", - "position": 1 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/getting-started/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/getting-started/index.md deleted file mode 100644 index 5d58acf6..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/getting-started/index.md +++ /dev/null @@ -1 +0,0 @@ -# 快速开始 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/getting-started/install.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/getting-started/install.md deleted file mode 100644 index a6945527..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/getting-started/install.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -sidebar_position: 2 ---- - -# 安装 - -## 1. 安装 KCL - -### 二进制下载 - -KCL 的每个版本都包含各种操作系统和体系结构。这些二进制版本可以从 [Github](https://github.com/kcl-lang/kcl/releases/) 或者 [Gitee](https://gitee.com/kusionstack/kcl/releases) 手动下载并安装,下载完成后将 `{install-location}/kclvm/bin` 添加到环境变量 PATH 中。 - -> ⚠️ 如果您不能成功访问 Github, 也可以访问 Gitee 获得二进制进行安装 - -#### MacOS & Linux - -```bash -export PATH=$PATH:{install-location}/kclvm/bin -``` - -#### Windows - -```powershell -$env:PATH += ";{install-location}\kclvm\bin;" -``` - -### 使用脚本安装最新版本 - -#### MacOS - -将 KCL darwin 最新版本安装到 /usr/local/kclvm/bin - -```bash -curl -fsSL https://kcl-lang.io/script/install.sh | /bin/bash -``` - -#### Linux - -将 KCL linux 最新版本安装到 /usr/local/kclvm/bin - -```bash -wget -q https://kcl-lang.io/script/install.sh -O - | /bin/bash -``` - -#### Windows - -将 KCL windows 最新版本安装到 $Env:SystemDrive\kclvm\bin,并将该目录添加到用户 PATH 环境变量中。 - -```bash -powershell -Command "iwr -useb https://kcl-lang.io/script/install.ps1 | iex" -``` - -### Homebrew (MacOS) - -- 安装 - -```bash -brew install kcl-lang/tap/kcl -``` - -- 升级 - -```bash -brew upgrade kcl-lang/tap/kcl -``` - -- 卸载 - -```bash -brew uninstall kcl-lang/tap/kcl -``` - -### Scoop (Windows) - -首先安装 [Scoop](https://scoop.sh/), 然后通过如下命令安装 `kcl`: - -```bash -scoop bucket add kcl-lang https://github.com/kcl-lang/scoop-bucket.git -scoop install kcl-lang/kcl -``` - -### 使用 Go 安装 - -通过 `Go` 命令安装 (Go 要求 1.18+) - -```bash -go install kcl-lang.io/kcl-go/cmds/kcl-go@main -``` - -添加一个 kcl 命令的别名 (可选) - -```bash -alias kcl='kcl-go run' -``` - -> 注意:`kcl-go` 并不依赖是否安装了 `kcl`,但如果 PATH 中存在 `kcl`,`kcl-go` 将优先使用 `PATH` 中的 `kcl`。 - -### 使用 Docker 镜像安装 - -- 基本命令 - -```bash -docker run --rm -it kcllang/kcl -``` - -- 更新镜像 - -```bash -docker pull kcllang/kcl -``` - -### 注意 - -可以执行运行如下命令确保 KCL 已经正确安装 - -```bash -kcl -V -``` - -如果安装成功,输出可能为如下形式 (不同版本结果可能稍微不同): - -```bash -Version: {kcl version} -Platform: {your platform} -GitCommit: {git commit} -``` - -对于上述所有安装方式, 如果您想使用 [KCL Python 插件](/docs/reference/plugin/overview), 需要确保您已经安装了 Python 3.7+ 并将 python3 命令添加到您的 PATH 中。 - -## 2. 安装 KCL IDE 插件 - -### VS Code - -KCL 为 VS Code 本地版本提供了插件支持,并提供了高亮、自动补全、跳转、悬停、大纲等功能。您可以[点击这里](/docs/tools/Ide/vs-code)进行安装。 - -![Completion](/img/docs/tools/Ide/vs-code/Completion.gif) - -### NeoVim - -参见[此处](https://github.com/kcl-lang/kcl.nvim)配置 KCL 语言服务器并启用它。 - -![kcl.nvim](/img/docs/tools/Ide/neovim/overview.png) - -### IntelliJ IDEA - -从[这里](https://github.com/kcl-lang/intellij-kcl/releases)下载发行版,在 IntelliJ IDEA 中,点击 Preference -> plugins -> install Plugin from Disk... -> 选择 kcl-idea-plugin zip -> 重启 IDE。此插件需要 IntelliJ IDEA 2020.2+ - -![intellij](/img/docs/tools/Ide/intellij/overview.png) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/getting-started/intro.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/getting-started/intro.md deleted file mode 100644 index aaa364e3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/getting-started/intro.md +++ /dev/null @@ -1,199 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 简介 - -## KCL 是什么? - -[KCL](https://github.com/kcl-lang/kcl) 是一个开源的基于约束的记录及函数语言。KCL 通过成熟的编程语言技术和实践来改进对大量繁杂配置比如云原生 Kubernetes 配置场景的编写,致力于构建围绕配置的更好的模块化、扩展性和稳定性,更简单的逻辑编写,以及更简单的自动化和生态工具集成。 - -## 为什么使用 KCL? - -KCL 期望通过更现代化的声明式配置语言在 Kubernetes 资源管理解决如下问题: - -- 通过**代码抽象**等手段屏蔽基础设施和平台的细节,降低研发者负担 -- **编辑**和**校验**已有的存量配置或模版 -- 通过配置语言无副作用地管理跨团队的大规模配置数据,提升团队协作效率 - - 用**生产级高性能编程语言**以**编写代码**的方式提升配置的灵活度,比如条件语句、循环、函数、包管理等特性提升配置重用的能力 - - 在代码层面提升**配置语义验证**的能力,比如字段可选/必选、类型、范围等配置检查能力 - - 提供**配置分块编写、组合和抽象的能力**,比如结构定义、结构继承、约束定义等能力 - - 通过**多语言 SDK**,**KCL 语言插件**等手段提升其**自动化**集成能力 - -您可以将 KCL 用于 - -- 生成静态配置数据如 JSON, YAML 等 -- 使用 schema 对配置数据进行建模并减少配置数据中的样板文件 -- 为配置数据定义带有规则约束的 schema 并对数据进行自动验证 -- 无副作用地组织、简化、统一和管理庞大的配置 -- 通过分块编写配置数据可扩展地管理庞大的配置 -- 与 [KusionStack](https://kusionstack.io) 一起,用作平台工程语言来交付现代应用程序 - -除了语言自身,KCL 还提供了许多额外的工具如格式化,测试、文档、包管理等工具帮助您使用、理解和检查编写的配置或策略;通过 VS Code 等 IDE 插件和 Playground 降低配置编写、分享的成本;通过 Rust, Go, 和 Python 多语言 SDK 自动化地管理和执行配置。 - -![](/img/docs/user_docs/intro/kcl-overview.png) - -此外,KCL 是一种现代高级领域编程语言,并且它是一种编译静态的强类型语言。KCL 为开发人员提供了通过记录和函数语言设计将**配置(config)**、**建模抽象(schema)**、**逻辑(lambda)**和**策略(rule)**作为核心能力。 - -![](/img/docs/user_docs/intro/kcl-concepts.png) - -KCL 试图提供独立于运行时的可编程性,不在本地提供线程和IO等系统功能,但支持云本地操作场景的功能,并试图为解决领域问题并提供稳定、安全、低噪声、低副作用、易于自动化和易于管理的编程支持。 - -总之,KCL 具备如下特点: - -- **简单易用**:源于 Python、Golang 等高级语言,采纳函数式编程语言特性,低副作用 -- **设计良好**:独立的 Spec 驱动的语法、语义、运行时和系统库设计 -- **快速建模**:以 [Schema](https://kcl-lang.io/docs/reference/lang/tour#schema) 为中心的配置类型及模块化抽象 -- **功能完备**:基于 [Config](https://kcl-lang.io/docs/reference/lang/tour#config-operations)、[Schema](https://kcl-lang.io/docs/reference/lang/tour#schema)、[Lambda](https://kcl-lang.io/docs/reference/lang/tour#function)、[Rule](https://kcl-lang.io/docs/reference/lang/tour#rule) 的配置及其模型、逻辑和策略编写 -- **可靠稳定**:依赖[静态类型系统](https://kcl-lang.io/docs/reference/lang/tour/#type-system)、[约束](https://kcl-lang.io/docs/reference/lang/tour/#validation)和[自定义规则](https://kcl-lang.io/docs/reference/lang/tour#rule)的配置稳定性 -- **强可扩展**:通过独立配置块[自动合并机制](https://kcl-lang.io/docs/reference/lang/tour/#-operators-1)保证配置编写的高可扩展性 -- **易自动化**:[CRUD APIs](https://kcl-lang.io/docs/reference/lang/tour/#kcl-cli-variable-override),[多语言 SDK](https://kcl-lang.io/docs/reference/xlang-api/overview),[语言插件](https://github.com/kcl-lang/kcl-plugin) 构成的梯度自动化方案 -- **极致性能**:使用 Rust & C,[LLVM](https://llvm.org/) 实现,支持编译到本地代码和 [WASM](https://webassembly.org/) 的高性能编译时和运行时 -- **API 亲和**:原生支持 [OpenAPI](https://github.com/kcl-lang/kcl-openapi)、 Kubernetes CRD, Kubernetes YAML 等 API 生态规范 -- **开发友好**:[语言工具](https://kcl-lang.io/docs/tools/cli/kcl/) (Format,Lint,Test,Vet,Doc 等)、 [IDE 插件](https://github.com/kcl-lang/vscode-kcl) 构建良好的研发体验 -- **安全可控**:面向领域,不原生提供线程、IO 等系统级功能,低噪音,低安全风险,易维护,易治理 -- **多语言 SDK**:[Go](https://kcl-lang.io/docs/reference/xlang-api/go-api),[Python](https://kcl-lang.io/docs/reference/xlang-api/python-api),[Java](https://kcl-lang.io/docs/reference/xlang-api/java-api) 和 [REST API](https://kcl-lang.io/docs/reference/xlang-api/rest-api) 满足不同场景和应用使用需求 -- **生态集成**:通过 [Kustomize KCL 插件](https://github.com/kcl-lang/kustomize-kcl), [Helm KCL 插件](https://github.com/kcl-lang/helm-kcl) 或者 [KPT KCL SDK](https://github.com/kcl-lang/kpt-kcl-sdk) 直接编辑或校验资源 -- **生产可用**:广泛应用在蚂蚁集团平台工程及自动化的生产环境实践中 - -虽然 KCL 不是通用语言,但它有相应的应用场景。开发人员可以通过 KCL 编写**config**、**schema**、**function**和**rule**,其中 config 用于定义数据,schema 用于描述数据的模型定义,rule 用于验证数据,schema 和 rule 还可以组合使用模型和约束来充分描述数据。此外,还可以使用 KCL 中的 lambda 纯函数来组织数据代码,封装通用代码,并在需要时直接调用它。 - -KCL 配置通常遵循如下模式: - -$$ -k = (T) v -$$ - -其中,$k$ 是属性名称,$v$ 是属性值,$T$ 是类型注解。由于 KCL 具有类型推导的能力,因此 $T$ 通常可以省略。 - -下面是一个用 KCL 生成 kubernetes 资源的例子 - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = name -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -我们可以使用上述 KCL 代码生成一个 Kubernetes YAML 配置 - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## 如何选择 - -目前社区已经进行了大量的尝试来改进其配置技术,主要可分为三类: - -- 用于模板、修补和验证的基于低级数据格式的工具,使用外部工具来增强重用和验证。 -- 领域特定语言(DSL)和配置语言(CL),以增强语言能力。 -- 基于通用语言(GPL)的解决方案,使用 GPL 的云开发工具包(CDK)或框架来定义配置。 - -简单的选择答案: - -- 如果您需要编写结构化的静态的 K-V,或使用 Kubernetes 原生的技术工具,建议选择 YAML。 -- 如果您希望引入编程语言便利性以消除文本(如 YAML、JSON) 模板,有良好的可读性,或者你已是 Terraform 的用户,建议选择 HCL。 -- 如果您希望引入类型功能提升稳定性,维护可扩展的配置文件,建议选择 CUE。 -- 如果您希望以现代语言方式编写复杂类型和建模,维护可扩展的配置文件,原生的纯函数和策略,和生产级的性能和自动化,建议直接选择 KCL 或将 KCL 用于对已有配置手段或工具进行增强。 - -### vs. YAML/JSON - -YAML/JSON 适用于小型配置场景。对于需要频繁修改的大型云原生配置场景,它们更适合 KCL。所涉及的主要区别是配置数据抽象和部署之间的区别: - -使用 KCL 进行配置的优点是:对于静态数据,抽象一层的优点意味着整个系统具有部署灵活性。不同的配置环境、租户和运行时可能对静态数据有不同的要求,甚至不同的组织可能有不同的规范和产品要求。KCL 可用于公开最需要的和经常修改的配置。 - -### vs. Jsonnet/GCL - -GCL 是一种用 Python 实现的声明式配置语言,它提供了支持模板抽象的必要语言功能。然而 GCL 编译器本身是用Python编写的,且语言本身是解释执行的。对于大型模板实例(如 kubernetes 模型),性能较差。 - -Jsonnet 是一种用 C++ 实现的数据模板语言,适用于应用程序和工具开发人员,可以生成配置数据并通过代码组织、简化和管理大型配置,而不会产生副作用。 - -Jsonnet 和 GCL 非常擅长减少样板。它们都可以使用代码生成配置,就像工程师只需要编写高级 GPL 代码,而不是手动编写容易出错且难以理解的服务器二进制代码一样。Jsonnet 减少了 GCL 的一些复杂性,但在很大程度上属于同一类别。两者都有许多运行时错误,类型检查和约束能力不足。 - -### vs. HCL - -HCL 是一种 Go 实现的结构化配置语言。HCL 的原生语法受到 libucl 和 nginx 配置的启发。它用于创建一种对人类和机器友好的结构化配置语言,作为 [Terraform 语言](https://www.terraform.io/language)主要用于 DevOps工具、服务器配置和资源配置等。 - -HCL 的用户界面不能通过 Terraform 提供者 Schema 定义直接感知。此外,在编写复杂对象和必需/可选字段定义时,用户界面很麻烦。动态参数受变量的条件字段约束。资源本身的约束需要由提供程序模式定义,或者与 Sentinel/Rego 和其他策略语言相结合。语言本身的完整性不能自我封闭,其实现方法也不统一。 - -### vs. CUE - -CUE 可以通过结构、无继承和其他特性用作建模,当模型定义之间没有冲突时可以实现高度抽象。因为 CUE 在运行时执行所有约束检查,所以它在大规模配置建模场景中可能存在性能瓶颈。CUE 将类型和值组合为一个概念,并通过各种语法简化了约束的编写。例如,不需要泛型类型和枚举,求和类型和空值合并是一回事。CUE 支持配置合并,但它是完全幂等的。它可能无法满足复杂的多租户和多环境配置场景的要求。对于复杂的循环和约束场景,编写起来很复杂,编写需要精确配置修改或者 Patch 的场景也很麻烦。 - -对于 KCL,建模是通过 KCL Schema 进行的,通过语言级工程和一些面向对象的特性(如单一继承、Mixin 复用)可以实现高模型抽象。KCL 是一种静态编译语言,用于大规模建模场景是运行时开销较低 (性能更高,更低的内存消耗)。KCL 提供了更丰富的检查声明性约束语法,这使得配置和策略编写更加容易。对于一些配置字段组合约束,它更容易编写(与 CUE 相比,KCL 提供了更多的 if-guard 组合约束、all/any/map/filter 表达式和其他集合约束编写方法,这使得编写更容易)。 - -### vs. Dhall - -Dhall 是一种可编程配置语言,它组合了 JSON、函数、类型和 imports 导入等功能, 本身风格偏向函数式,如果您学过 Haskell 等函数式风格语言,可能会对它感到熟悉的。相比于 Dhall, KCL 也提供了类似功能的组合,提供给用户配置可编程和抽象的能力,不过 KCL 在建模、约束检查、自动化等方面做了更多的改进,同时能够通过包管理手段进行模型共享。此外,KCL 的语法语义更贴近于面向对象语言,在一定程度上会比纯函数式风格接受程度更高。 - -### vs. Nickel - -Nickel 是一种简单的配置语言。它的目的是自动生成静态配置文件,本质上是带有函数和类型的 JSON。 - -KCL 和 Nickel 都有类似的渐进式类型系统(静态+动态)、合并策略、函数和约束定义。不同之处在于 KCL 是一种类似 Python 的语言,而 Nickel 是一种类似 JSON 的语言。此外,KCL 提供了 schema 关键字来区分配置定义和配置数据,以避免混合使用。 - -### vs. Starlark - -Starlark 主要用作 Bazel 的配置语言并且是 Python 的一种方言。它没有类型,并且禁止递归。 - -KCL 一定程度上也可以看作 Python 的变种,但是它极大地增强了静态类型和配置扩展性相关的设计,并且是一个编译型语言,这与 Starlark 有着本质的不同。 - -### vs. Kustomize - -Kustomize 的核心功能是其文件级覆盖功能。但是它存在多个覆盖链的问题,因为找到特定属性值的语句不能保证它是最终值,因为其他地方出现的另一个特定值可以覆盖它。对于复杂的场景,Kustomsize 文件的继承链的检索通常不如 KCL 代码的继承链检索方便,需要仔细考虑指定的配置文件覆盖顺序。此外,Kustomize 无法解决 YAML 配置编写、约束验证、模型抽象和开发等问题,更适合于简单的配置场景。 - -在 KCL 中,配置合并操作可以对代码中的每个配置属性进行细粒度处理,合并策略可以灵活设置,而不限于整体资源,配置之间的依赖关系可以通过KCL的import语句进行静态分析。 - -### vs. Helm - -Helm 的概念源于操作系统的包管理机制。它是一个基于模板化 YAML 文件的包管理工具,支持包中资源的执行和管理。 - -KCL 自然提供了 Helm 功能的超集,因此您可以直接使用 KCL 作为替代。对于采用 Helm 的用户,KCL 中的堆栈编译结果可以打包并以 Helm 格式使用,通过 kpm 包管理工具进行分发复用。此外,我们还可以直接使用 Helm-KCL 插件直接对已有的 Helm Charts 进行无侵入的可编程扩展。 - -### vs. CDK - -用CDK的高级语言编写可以很好地集成到应用程序项目中,这实际上是客户端运行时的一部分。对于KCL,由KCL编写的外部配置和策略与客户端运行时分离。 - -通用语言通常远远超出了需要解决的问题,例如安全问腿、能力边界问题(启动本地线程、访问IO、网络、代码无限循环和其他安全风险)。例如,在音乐领域,有专门的音符来表达音乐,这便于学习和交流,它不能用一般语言表达清楚。 - -此外,由于通用语言风格多样,需要统一维护、管理和自动化。通用语言通常用于编写客户端运行时,它是服务器运行时的延续,不适合编写独立于运行时的配置,被编译成二进制文件,并最终从进程开始运行。此外,GPL 稳定性和可扩展性不易控制。然而,KCL 配置语言通常用于编写数据,将数据与简单逻辑相结合,它描述了预期的最终结果,然后由编译器或引擎使用,既具备丰富的编程抽象能力,又具备方便的数据处理方式。 - -### vs. OPA/Rego - -Rego 起源于逻辑编程,它基于 Datalog,是一种受限制的 Prolog 形式,而 KCL 基于静态类型结构,具备部分 OOP 特性。Rego 类型化特征结构的设计是为了解决 Prolog 在人类语言编码应用中的缺点,将 Datalog 变量用于编程本质上是约束验证任务,Datalog 是一种优秀的查询语言。但对于约束强制执行,它有点麻烦,因为实际上首先需要查询要应用约束的值才能进行校验。 - -此外,KCL 的方法更易于找到规范化、简化、面向人类易读,面向运行时性能优良的约束和校验表示,具备静态类型,并且它更适合于从 OpenAPI 生成或者创建 OpenAPI。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/getting-started/kcl-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/getting-started/kcl-quick-start.md deleted file mode 100644 index 8d75e878..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/getting-started/kcl-quick-start.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -sidebar_position: 3 ---- - -# KCL 语言速览 - -KCL 是一个面相云原生配置策略领域的编程语言。KCL 设计之初受 Python3 启发,同时吸收了声明式、OOP 编程范式的设计理念,是一种专用于配置策略定义、校验的静态强类型的面相配置和策略场景的语言。本节我们将快速展示 KCL 语言的基本特性。 - -## 1. Hello KCL - -学习新语言的最佳途径是自己亲手写几个小程序,配置语言也是如此。KCL 作为一种配置策略语言,我们可以像写配置一样写 KCL 程序。 - -下面是一个简单的 `hello.k` 程序: - -```python -hello = "KCL" -``` - -将 `hello` 属性设置为 `"KCL"` 字符串。然后将代码保存到 `hello.k` 文件中。 - -如何执行这个程序取决于具体的开发环境,我们先假设本地的 macOS 或者是 Linux 系统已经安装了 `kcl` 命令(或者通过 `docker run --rm -it kcllang/kcl` 进入 Docker 环境测试)。然后在文件所在的目录命令行输入以下命令执行: - -```shell -kcl hello.k -``` - -输出为 - -```yaml -hello: KCL -``` - -命令行执行的效果如图所示: - -![](/img/docs/user_docs/getting-started/hello.gif) - -输出的是 YAML 格式的配置数据。这个程序虽然简单,但是我们可以通过执行 KCL 配置程序到输出结果验证了开发环境和 `kcl` 命令行的基本用法。 - -## 2. 再复杂一点的配置 - -常见的配置数据除了的普通的 key-value 对,还有嵌套的字典和列表类型,同时 value 基础类型除了字符串还有布尔和数值等类型。下面是更为复杂一点的 `server.k` 配置: - -```python -# This is a KCL document - -title = "KCL Example" - -owner = { - name = "The KCL Authors" - data = "2020-01-02T03:04:05" -} - -database = { - enabled = True - ports = [8000, 8001, 8002] - data = [["delta", "phi"], [3.14]] - temp_targets = {cpu = 79.5, case = 72.0} -} - -servers = [ - {ip = "10.0.0.1", role = "frontend"} - {ip = "10.0.0.2", role = "backend"} -] -``` - -其中 `#` 开头的表示行注释。`owner` 的 value 是一个字典,字典的面值通过 `{}` 方式包含的内容,字典内部的 key-value 和 `hello = "KCL"` 例子的写法类似。`database` 则是另一个字典,其中字典属性的 value 出现了布尔 `True`、列表 `[]` 和 `{}` 字典,其中列表和字典中还出现了数值类型的 value。 最后一个 `servers` 属性则是一个列表,列表内部嵌套着字典(字典和列表以及后续将要讲到的 `schema` 都可以相互嵌套)。 - -该配置输出的 YAML 结果如下: - -```yaml -$ kcl server.k -title: KCL Example -owner: - name: The KCL Authors - data: '2020-01-02T03:04:05' -database: - enabled: true - ports: - - 8000 - - 8001 - - 8002 - data: - - - delta - - phi - - - 3.14 - temp_targets: - cpu: 79.5 - case: 72.0 -servers: -- ip: 10.0.0.1 - role: frontend -- ip: 10.0.0.2 - role: backend -``` - -## 3. schema 定义配置的结构 - -KCL 通过 `schema` 语法结构为有着固定属性结构和默认值行为的属性提供抽象支持。 - -比如上面例子的中 `database` 的配置一般是用默认值即可。这样我们可以通过为数据库的默认配置定义一个结构: - -```python -schema DatabaseConfig: - enabled: bool = True - ports: [int] = [8000, 8001, 8002] - data: [[str|float]] = [["delta", "phi"], [3.14]] - temp_targets: {str: float} = {cpu = 79.5, case = 72.0} -``` - -`enabled` 是布尔类型;`ports` 为整数列表类型;`data` 为列表的列表,内层的列表元素是字符串或者浮点数类型;`temp_targets` 则是一个字典类型,字典的属性值是浮点数类型。并且 `DatabaseConfig` 的每个属性都定义了默认值。 - -然后通过 `database = DatabaseConfig {}` 就可以产生和默认值相同属性的结构。用户也可以修改默认值: - -```python -database = DatabaseConfig { - ports = [2020, 2021] -} -``` - -`schema DatabaseConfig` 不仅仅为属性提供了默认值,还为属性添加了类型信息。因此,如果用户不小心写错属性值类型的话,KCL 将会给出友好的错误提示,比如下面的例子将 `ports` 错误地写成了浮点数类型: - -```python -database = DatabaseConfig { - ports = [1.2, 1.3] -} -``` - -执行时将产生类似以下的错误(显示的文件路径和本地环境有关): - -```shell -kcl server.k -``` - -输出为 - -```shell -error[E2G22]: TypeError - --> /path/to/server.k:8:5 - | -8 | ports = [1.2, 1.3] - | ^ expected [int], got [float(1.2)|float(1.3)] - | - - --> /path/to/server.k:3:5 - | -3 | ports: [int] = [8000, 8001, 8002] - | ^ variable is defined here, its type is [int], but got [float(1.2)|float(1.3)] - | -``` - -类似地我们可以用以下的代码封装 `servers` 部分的属性: - -```python -schema ServerConfig: - ip: str - role: "frontend" | "backend" - -servers = [ - ServerConfig {ip = "10.0.0.1", role = "frontend"} - ServerConfig {ip = "10.0.0.2", role = "backend"} -] -``` - -其中 `ServerConfig` 的 `ip` 是字符串类型,并没有给出默认值。用户在生成 `ServerConfig` 类型的属性时必须手工添加 `ip` 属性的值,否则 KCL 将会报出缺少必填属性的错误。`role` 属性是 `"frontend" | "backend"` 枚举字符串类型。 - -此外,`schema` 还可以结合 `check`、`mixin`、可选属性、继承和扩展模块实现更为复杂的配置和策略数据的抽象,细节可以参考手册部分的文档。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/_category_.json deleted file mode 100644 index 1fdf894e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "用户手册", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/abstraction.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/abstraction.md deleted file mode 100644 index da590317..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/abstraction.md +++ /dev/null @@ -1,149 +0,0 @@ ---- -title: "抽象" -sidebar_position: 3 ---- - -## 什么是抽象 - -抽象是指一个实体的简化表示,它允许隐藏特定的具体细节,同时向程序员提供最相关的信息。每一个抽象都是为满足特定需求而定制的,并且可以极大地提高给定实体的可用性。在 KCL 的上下文中,抽象可以使代码更容易理解和维护,同时也可以简化用户界面。 - -需要注意的是,代码抽象并不是为了减少代码大小,而是为了提高代码的可维护性和可扩展性。在抽象代码的过程中,应考虑可重用性、可读性和可扩展性等因素,并根据需要对代码进行不断优化。 - -良好的抽象可以提供如下价值 - -1. 提供不同的焦点,不同角色和场景关注点分离。 -2. 屏蔽较低级别的细节,避免潜在的错误。 -3. 提升用户界面和自动化友好性。 - -KCL 自身可能不会评估用户定义模型抽象的合理性,但它提供了技术解决方案来帮助用户构建抽象。 - -## 使用 KCL 进行抽象 - -现在,让我们将 Docker Compose 和 Kubernetes 资源抽象为应用程序配置 - -`Docker Compose` 是一个用于定义和运行多容器 Docker 应用程序的工具。使用 Docker Compose,您可以在一个文件中定义应用程序的服务、网络和卷,然后使用它作为一个单元启动和停止应用程序。Docker Compose 通过处理网络、存储和其他基础设施问题的细节,简化了运行复杂的多容器应用程序的过程。 - -Kubernetes 清单是定义 Kubernete 对象(如 Pods、Deployments 和 Services)的 YAML 文件。清单提供了一种声明性的方法来定义应用程序的所需状态,包括副本数量、要使用的镜像和网络配置。Kubernetes 使用清单来创建和管理部署和运行应用程序所需的资源。 - -以下是一些参考资料,可以帮助了解更多关于 Docker Compose 和 Kubernetes 相关的信息: - -- [Docker Compose 文档](https://docs.docker.com/compose/) -- [Kubernetes 对象文档](https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/) - -以应用程序为中心的开发使开发人员能够专注于其工作负载的体系结构,而不是目标环境、基础设施或平台中的技术栈。我们用 `App` 结构定义了应用程序模型,然后使用 KCL CLI 将其翻译到多个平台,例如不同版本的 `Docker Compose` 或 `Kubernetes`。该应用程序模型旨在通过只需定义一个跨多个平台工作的 KCL 文件来减少开发人员的工作量和认知负荷。现在,让我们学习如何做到这一点。 - -### 0. 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. 获取示例 - -首先,我们执行 git 命令获得用例 - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/abstraction -``` - -我们可以运行以下命令来显示配置。 - -```bash -cat main.k -``` - -输出为 - -```python -import .app - -app.App { - name = "app" - containers.nginx = { - image = "nginx" - ports = [{containerPort = 80}] - } - service.ports = [{ port = 80 }] -} -``` - -在上面的代码中,我们使用 `App` schema 定义了一个配置,其中我们配置了一个 `nginx` 容器,并开启 `80` 端口配置。 - -此外,KCL 允许开发人员以声明式的方式定义应用程序所需的资源,并允许生成特定于平台的配置文件,如 `docker_compose.yaml` 或 Kubernetes `manifests.yaml` 文件。接下来,让我们生成相应的配置。 - -### 2. 将应用配置转换为 Docker Compose 配置 - -如果我们想将应用程序配置转换为 Docker Compose 配置,我们可以简单地运行如下命令: - -```shell -kcl main.k docker_compose_render.k -``` - -输出为 - -```yaml -services: - app: - image: nginx - ports: - - published: 80 - target: 80 - protocol: TCP -``` - -### 3. 将应用配置转换为 Kubernetes Deployment and Service 资源清单 - -如果我们想将应用程序配置转换为 Kubernetes 清单,我们可以简单地运行如下命令: - -```shell -kcl main.k kubernetes_render.k -``` - -输出为 - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: app - labels: - app: app -spec: - replicas: 1 - selector: - matchLabels: - app: app - template: - metadata: - labels: - app: app - spec: - containers: - - name: nginx - image: nginx - ports: - - protocol: TCP - containerPort: 80 ---- -apiVersion: v1 -kind: Service -metadata: - name: app - labels: - app: app -spec: - selector: - app: app - ports: - - port: 80 - protocol: TCP -``` - -如果您想了解有关应用程序模型的更多信息,可以参考[此处](https://github.com/kcl-lang/kcl-lang.io/tree/main/examples/abstraction). - -## 小结 - -通过使用 KCL,我们能够分离模型的抽象和实现细节,允许将抽象模型映射到各种基础设施或平台。这是通过不同实现之间的灵活切换和 KCL 组合编译来实现的,以屏蔽配置差异,减轻认知负担。 - -## 更多信息 - -除了手动维护配置外,我们还可以使用 KCL API 将**自动配置更改能力**集成到我们的应用程序中。有关 KCL 自动化能力的相关说明,请参阅[此处](/docs/user_docs/guides/automation)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/automation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/automation.md deleted file mode 100644 index 83eb6446..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/automation.md +++ /dev/null @@ -1,205 +0,0 @@ ---- -title: "自动化" -sidebar_position: 6 ---- - -## 简介 - -在 KCL 中提供了很多自动化相关的能力,主要包括工具和多语言 API。 通过 `package_identifier : key_identifier`的模式支持对任意配置键值的索引,从而完成对任意键值的增删改查。比如下图所示修改某个应用配置的镜像内容,可以直接执行如下指令修改镜像,修改前后的 diff 如下图所示。 - -![](/img/blog/2022-09-15-declarative-config-overview/14-kcl-image-update.png) - -此外,KCL 的自动化能力也可以被集成到 CI/CD 中。 - -![](/img/blog/2022-09-15-declarative-config-overview/15-kcl-automation.png) - -## 使用 KCL 进行自动化 - -### 0. 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. 获得示例 - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/automation -``` - -我们可以执行如下命令显示配置 - -```bash -cat main.k -``` - -输出为 - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "app" - replicas = 1 - labels.key = "value" -} -``` - -我们可以执行如下命令输出配置 - -```bash -kcl main.k -``` - -输出为 - -```yaml -app: - name: app - replicas: 1 - labels: - app: app - key: value -``` - -### 2. 使用 KCL CLI 进行自动化 - -KCL 允许使用通过 CLI `-O|--overrides` 参数修改配置模型中的值,这个参数通常由三个部分组成: 包名 `pkg`, 配置标识符 `identifier`, 配置属性 `attribute` 和覆盖值 `override_value` - -```bash -kcl main.k -O override_spec -``` - -- `override_spec`: 表示需要修改的配置模型字段和值的统一表示 - -```bash -override_spec: [[pkgpath] ":"] identifier ("=" value | "-") -``` - -- `pkgpath`: 表示需要修改标识符的包路径,通常为 `a.b.c` 的形式,对于 main 包,`pkgpath` 表示为 `__main__`, 可省略,省略不写时表示 main 包 -- `identifier`: 表示需要修改配置的标识符,通常为 `a.b.c` 的形式 -- `value`: 表示需要修改配置的值,可以是任意合法的 KCL 表达式,比如数字/字符串字面值,`list`/`dict`/`schema` 表达式等 -- `=`: 表示修改identifier的值 -- `-`: 表示删除 identifier 属性 - -请注意,当 `identifier` 多次出现时,修改/删除全部 `identifier` 的值 - -#### 修改配置 - -执行如下命令可以更新应用名称: - -```bash -kcl main.k -O app.name='new_app' -``` - -输出为 - -```yaml -app: - name: new_app - replicas: 1 - labels: - app: new_app - key: value -``` - -可以看出 `app` 的 `name` 属性的值被修改为了 `new_app` - -此外,当我们使用 KCL CLI `-d` 参数时,KCL 文件将同时修改为以下内容 - -```bash -kcl main.k -O app.name='new_app' -d -``` - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "new_app" - replicas = 1 - labels: {key = "value"} -} -``` - -#### 删除配置 - -执行如下命令可以删除 `labels` 中的 `key` 字段 - -```bash -kcl main.k -O app.labels.key- -``` - -输出为: - -```yaml -app: - name: app - replicas: 1 - labels: - app: app -``` - -执行如下命令 - -```bash -kcl main.k -O config.x- -``` - -输出结果为: - -```yaml -config: - x: 1 - y: s -``` - -### 3. 使用 KCL API 进行自动化 - -此外,我们还可以通过[多语言 API](/docs/reference/xlang-api/overview) 自动修改配置属性 - -以 RestAPI 为例 - -执行如下命令启动 RestAPI 服务端 - -```bash -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -通过如下命令 POST 命令请求配置修改服务 - -```bash -curl -X POST http://127.0.0.1:2021/api:protorpc/KclvmService.OverrideFile -H 'content-type: accept/json' -d '{ - "file": "main.k", - "specs": ["app.name=\"nginx\""] -}' -``` - -服务调用完成后,`main.k` 会被修改为如下形式: - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "nginx" - replicas = 1 - labels: { - "key" = "value" - } -} -``` - -## 小结 - -该文档介绍了KCL的自动化功能,包括工具和多语言 API。它支持对任何配置的键值进行索引,允许添加、删除、修改和查询任何键值。它也可以集成到 CI/CD 中。本文档提供了一个使用 KCL 自动化配置管理的示例,包括使用 KCL CLI/API 覆盖和删除配置。更多信息请参阅[此处](/docs/reference/lang/tour#KCL-cli-variable-Override)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/ci-integration/1-github-actions.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/ci-integration/1-github-actions.md deleted file mode 100644 index b93fdec9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/ci-integration/1-github-actions.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -id: github-actions -sidebar_label: Github Actions ---- - -# Github Actions 集成 - -## 简介 - -在 GitOps 章节,我们介绍了如何将 KCL 与 GitOps 进行集成。在本文中,我们将继续提供 KCL 和 CI 集成的示例方案,希望通过使用容器、用于生成的持续集成 (CI) 和用于持续部署 (CD) 的 GitOps 来实现端到端应用程序开发流程。在此方案中,我们使用一个 Flask 应用和 Github Actions 将用作示例。 - -> 注意:你可以在此方案中使用任何容器化应用以及不同的 CI 系统如 Gitlab CI,Jenkins CI 等。 - -整体工作流程如下: - -- 应用代码开发并提交到提交到 GitHub 存储库 -- GitHub Actions 从应用代码生成容器镜像,并将容器镜像推送到 docker.io 容器注册表 -- GitHub Actions 根据 docker.io 容器注册表中容器镜像的版本号并同步更新 KCL 清单部署文件 - -## 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -## 具体步骤 - -### 1. 获得示例 - -我们将业务源码和部署清单放在不同仓库,可以分不同角色进行分别维护,实现关注点分离。 - -- 获得业务源码 - -```shell -git clone https://github.com/kcl-lang/flask-demo.git/ -cd flask-demo -``` - -这是一个使用 Python 编写的 Web 应用,我们可以使用应用目录的 `Dockerfile` 来生成这个应用的容器镜像,同时可以通过 Github CI 自动构建 `flask_demo` 镜像,CI 配置如下 - -```yaml -# This is a basic workflow to help you get started with Actions - -name: CI - -# Controls when the workflow will run -on: - # Triggers the workflow on push or pull request events but only for the main branch - push: - branches: [main] - pull_request: - branches: [main] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "build" - build: - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - - - name: Docker Login - uses: docker/login-action@v1.10.0 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - logout: true - - # Runs a set of commands using the runners shell - - name: build image - run: | - make image - docker tag flask_demo:latest ${{ secrets.DOCKER_USERNAME }}/flask_demo:${{ github.sha }} - docker push ${{ secrets.DOCKER_USERNAME }}/flask_demo:${{ github.sha }} - - # Trigger KCL manifest - - name: Trigger CI - uses: InformaticsMatters/trigger-ci-action@1.0.1 - with: - ci-owner: kcl-lang - ci-repository: flask-demo-kcl-manifests - ci-ref: refs/heads/main - ci-user: kcl-bot - ci-user-token: ${{ secrets.DEPLOY_ACCESS_TOKEN }} - ci-name: CI - ci-inputs: >- - image=${{ secrets.DOCKER_USERNAME }}/flask_demo - sha-tag=${{ github.sha }} -``` - -我们需要源码仓库的工作流自动触发部署清单仓库中的工作流,此时需要创建具有 Github CI 操作权限的 `secrets.DEPLOY_ACCESS_TOKEN` 以及 Docker Hub 镜像推送的账号信息 `secrets.DOCKER_USERNAME` 和 `secrets.DOCKER_PASSWORD`, 这些可以在 Github 仓库的 `Secrets and variables` 设置中进行配置,如下图所示 - -![](/img/docs/user_docs/guides/ci-integration/github-secrets.png) - -### 2. 提交应用代码 - -flask-demo 仓库提交代码后,Github 会自动构建容器镜像,并将制品推送到 Docker hub 中,会再触发 flask-demo-kcl-manifests 仓库的 Action,[通过 KCL 自动化 API](/docs/user_docs/guides/automation) 修改部署清单仓库中的镜像地址。现在让我们为 flask-demo 仓库创建一个提交,我们可以看到代码提交后触发业务仓库 Github CI 流程 - -![](/img/docs/user_docs/guides/ci-integration/app-ci.png) - -### 3. 配置自动更新 - -当业务仓库 Github CI 流程执行完成后,会自动在存放 KCL 资源配置的仓库触发一个 CI 自动更新配置并提交到 flask-demo-kcl-manifests main 分支,commit 信息如下 - -![](/img/docs/user_docs/guides/ci-integration/image-auto-update.png) - -- 我们可以获得部署清单源码进行编译验证 - -```shell -git clone https://github.com/kcl-lang/flask-demo-kcl-manifests.git/ -cd flask-demo-kcl-manifests -git checkout main && git pull && kcl -``` - -输出 YAML 为 - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - replicas: 1 - selector: - matchLabels: - app: flask_demo - template: - metadata: - labels: - app: flask_demo - spec: - containers: - - name: flask_demo - image: "kcllang/flask_demo:6428cff4309afc8c1c40ad180bb9cfd82546be3e" - ports: - - protocol: TCP - containerPort: 5000 ---- -apiVersion: v1 -kind: Service -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - type: NodePort - selector: - app: flask_demo - ports: - - port: 5000 - protocol: TCP - targetPort: 5000 -``` - -从上述配置可以看出资源的镜像确实自动更新为了新构建的镜像内容。此外,我们还可以使用 Argo CD KCL 插件 自动从 Git 存储库同步或从中拉取数据并将应用部署到 Kubernetes 集群。 - -## 小结 - -通过将 KCL 和 Github CI 集成,我们能够将任意的业务代码的产出容器化镜像进行自动化修改并部署配置,以实现端到端应用程序开发流程并提升研发部署效率。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/ci-integration/_2-gitlab-ci.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/ci-integration/_2-gitlab-ci.md deleted file mode 100644 index 5ec96ce9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/ci-integration/_2-gitlab-ci.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -id: gitlab-ci -sidebar_label: Gitlab CI ---- - -Coming Soon - -## Introduction - -## How to - -## Summary diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/configuration.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/configuration.md deleted file mode 100644 index 127505c9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/configuration.md +++ /dev/null @@ -1,129 +0,0 @@ ---- -title: "配置" -sidebar_position: 1 ---- - -## 简介 - -配置是软件系统的一个重要方面,由于不断发展的业务需求、基础设施需求和其他因素,这些系统会不断发生变化。通常,快速改变这些系统的行为可能具有挑战性,尤其是当这样做需要昂贵且耗时的重建和重新部署过程时。在这种情况下,仅仅对业务代码进行更改可能是不够的。幸运的是,配置提供了一种低开销的方式来修改系统功能。 - -我们可以根据需要将静态配置存储在 JSON 或 YAML 等文件中。此外,配置也可以存储在高级语言中,从而实现更灵活的配置。这种语言可以进行编码、呈现和静态配置。KCL 是一种提供此类功能的配置语言。开发人员可以编写 KCL 代码来生成JSON/YAML 和其他配置。 - -## 使用 KCL 编写配置代码 - -KCL 的核心特性是其**建模**和**约束**能力,KCL 核心功能基本围绕 KCL 这个两个核心特性展开,对于代码而言(包括配置代码)都存在对配置数据约束的需求,比如类型约束、配置字段必选/可选约束、范围约束、不可变性约束等,这也是 KCL 致力于解决的核心问题之一。 - -现在我们已经了解了 KCL 的基本功能,让我们探索如何使用它来生成配置。 - -### 0. 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. 获取示例 - -首先,执行如下命令获取示例 - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/configuration -``` - -我们可以执行如下命令显示配置代码 - -```shell -cat nginx.k -``` - -输出为: - -```python -schema Nginx: - """Schema for Nginx configuration files""" - http: Http - -schema Http: - server: Server - -schema Server: - listen: int | str # The attribute `listen` can be int type or a string type. - location?: Location # Optional, but must be non-empty when specified - -schema Location: - root: str - index: str - -nginx = Nginx { - http.server = { - listen = 80 - location = { - root = "/var/www/html" - index = "index.html" - } - } -} -``` - -### 2. 使用 KCL 生成 YAML - -执行如下命令: - -```bash -kcl nginx.k -``` - -我们可以获得如下 YAML 输出 - -```yaml -nginx: - http: - server: - listen: 80 - location: - root: /var/www/html - index: index.html -``` - -### 3. 为配置添加动态参数 - -此外,我们可以通过 KCL 内置函数 `option` 动态接收外部参数。例如,对于下面的 KCL 文件(db.k),我们可以使用命令行 `-D` 标志来接收外部动态参数。 - -```python -env: str = option("env") or "dev" # The attribute `env` has a default value "den" -database: str = option("database") -hosts = { - dev = "postgres.dev" - stage = "postgres.stage" - prod = "postgres.prod" -} -dbConfig = { - host = hosts[env] - database = database - port = "2023" - conn = "postgres://${host}:${port}/${database}" -} -``` - -```bash -# Use the `-D` flag to input external parameters. -kcl db.k -D database="foo" -``` - -输出为 - -```yaml -env: dev -database: foo -hosts: - dev: postgres.dev - stage: postgres.stage - prod: postgres.prod -dbConfig: - host: postgres.dev - database: foo - port: "2023" - conn: "postgres://postgres.dev:2023/foo" -``` - -## 小结 - -通过使用KCL,我们可以生成更低低级别的数据配置。此外啊,我们通过 `-D` 标志设置动态参数以满足不同的场景需求。有关更多 KCL 的功能和教程,请参阅[此处](/docs/reference/lang/tour)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/data-integration.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/data-integration.md deleted file mode 100644 index 89511b2e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/data-integration.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: "数据集成" -sidebar_position: 4 ---- - -## 简介 - -在 KCL 中,不仅可以将 KCL 编写的配置代码编译输出为 YAML 格式的数据,还可以将 JSON/YAML 等数据直接嵌入到 KCL 语言当中。 - -## 使用 KCL 进行数据集成 - -### 0. 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. 获得示例 - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/data-integration -``` - -### 2. YAML 集成 - -我们可以运行以下命令来显示 KCL YAML 集成配置。 - -```bash -cat yaml.k -``` - -```python -import yaml - -schema Server: - ports: [int] - -server: Server = yaml.decode("""\ -ports: -- 80 -- 8080 -""") -server_yaml = yaml.encode({ - ports = [80, 8080] -}) -``` - -在上述代码中,我们通过 KCL 内置的 `yaml` 模块以及其中的 `yaml.decode` 直接完成 YAML 数据的集成,并且使用 `Server` schema 对集成的 YAML 数据直接进行校验。此外,我们可以使用 `yaml.encode` 完成 YAML 数据的序列化。 - -我们通过如下命令可以获得配置输出: - -```shell -kcl yaml.k -``` - -输出为 - -```yaml -server: - ports: - - 80 - - 8080 -server_yaml: | - ports: - - 80 - - 8080 -``` - -### 3. JSON 集成 - -同样的,对于 JSON 数据,我们可以使用 `json.encode` 和 `json.decode` 函数以同样的方式进行数据集成。 - -我们可以运行以下命令来显示 KCL JSON 集成配置。 - -```bash -cat json.k -``` - -```python -import json - -schema Server: - ports: [int] - -server: Server = json.decode('{"ports": [80, 8080]}') -server_json = json.encode({ - ports = [80, 8080] -}) -``` - -执行命令输出为: - -```shell -kcl json.k -``` - -```yaml -server: - ports: - - 80 - - 8080 -server_json: '{"ports": [80, 8080]}' -``` - -## 小结 - -本文介绍了如何在 KCL 中进行数据集成,使用 KCL 内置的 yaml 和 json 包将 YAML 和 JSON 数据直接集成到 KCL 语言中,并使用相应的解码和编码功能对其进行验证和序列化。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/gitops/1-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/gitops/1-quick-start.md deleted file mode 100644 index 673064c4..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/gitops/1-quick-start.md +++ /dev/null @@ -1,145 +0,0 @@ ---- -id: gitops-quick-start -sidebar_label: 快速开始 ---- - -# 快速开始 - -## 简介 - -### 什么是 GitOps - -GitOps 是一种实现持续交付的现代方式。它的核心思想是拥有一个包含环境和应用程序配置的 Git 存储库。通过更改应用存储库中的文件,可以自动部署应用程序。应用 GitOps 的好处包括: - -- 提高生产力,持续交付可以加快部署时间。 -- 降低开发人员部署的障碍。通过推送代码而不是容器配置,开发人员可以在不知道其内部实现的情况下轻松部署 Kubernetes 集群和应用。 -- 追踪变更记录。使用 Git 管理配置使每一项更改都具有可跟踪性,从而增强审计跟踪。 - -### 将 KCL 与 ArgoCD 一起使用 - -将 [KCL](https://github.com/kcl-lang/kcl) 与 [ArgoCD](https://github.com/argoproj/argo-cd) 等 GitOps 工具一起使用具有如下好处: - -- 通过 KCL 语言的[抽象能力](/docs/user_docs/guides/abstraction)和可编程能力可以帮助我们**简化复杂的 Kubernetes 部署配置文件**,降低手动编写 YAML 文件的错误率,消除多余的配置模版,提升多环境多租户的配置扩展能力,同时提高配置的可读性和可维护性。 -- KCL 允许开发人员以声明式的方式定义应用程序所需的资源,通过将 KCL 和 ArgoCD 相结合可以帮助我们更好地实现**基础设施即代码(IaC)**,提高部署效率,简化应用程序的配置管理。 -- ArgoCD 可以**自动化**地实现应用程序的连续部署,并提供友好的可视化界面。 - -使用 GitOps,开发人员和运维团队可以通过分别修改应用和配置代码来管理应用程序的部署,GitOps 工具链将自动同步对配置的更改,从而实现持续部署并确保一致性。如果出现问题,可以使用 GitOps 工具链快速回滚。 - -## 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -## 快速开始 - -### 1. 获取示例 - -首先,我们执行 git 命令获得用例 - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/gitops -``` - -我们可以运行以下命令来显示配置 - -```bash -cat config/main.k -``` - -The output is - -```python -import .app - -config = app.App { - name = "kcl-guestbook-ui" - containers.guestbook = { - image = "gcr.io/heptio-images/ks-guestbook-demo:0.2" - ports = [{containerPort = 80}] - } - service.ports = [{ port = 80 }] - service.type = "LoadBalancer" -} -``` - -在上述代码中,我们定义使用 `App` schema 定义了应用的配置,其中我们配置了一个镜像为 `gcr.io/heptio-images/ks-guestbook-demo:0.2` 容器,并启用了 `80` 端口。 - -### 2. 安装 Kubernetes 和 GitOps 工具 - -#### 配置 Kubernetes 集群和 ArgoCD 控制器 - -- 安装 [K3d](https://github.com/k3d-io/k3d) 并创建一个集群 - -```bash -k3d cluster create mycluster -``` - -> 注意:你可以在此方案中使用其他方式创建您自己的 Kubernetes 集群,如 kind, minikube 等。 - -- 安装 [ArgoCD](https://github.com/argoproj/argo-cd/releases/). - -```bash -kubectl create namespace argocd -kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml -``` - -- 安装 ArgoCD KCL 插件 - -```bash -kubectl apply -f ./install/kcl-cmp.yaml && kubectl -n argocd patch deploy/argocd-repo-server -p "$(cat ./install/patch-argocd-repo-server.yaml)" -``` - -- 通过 `kubectl get` 命令查看 argocd 控制器容器是否初始化完成进入运行(Running)状态。 - -```bash -kubectl get pod -n argocd -l app.kubernetes.io/name=argocd-repo-server -``` - -- 通过如下命令打开 ArgoCD UI - -```bash -kubectl port-forward svc/argocd-server -n argocd 8080:443 -``` - -- 打开浏览器 `https://localhost:8080` 输入用户名 "admin" 和密码登陆 ArgoCD UI,密码可以通过如下命令得到: - -```bash -kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d -``` - -#### 安装 ArgoCD 客户端工具 - -- 安装 [ArgoCD 客户端工具](https://github.com/argoproj/argo-cd/releases) - -- 使用用户名 "admin" 和刚才得到的密码登陆 - -```bash -argocd login localhost:8080 -``` - -通过如下命令创建一个 ArgoCD KCL 应用 - -```bash -argocd app create guestbook \ ---repo https://github.com/kcl-lang/kcl-lang.io \ ---path examples/gitops/config \ ---dest-namespace default \ ---dest-server https://kubernetes.default.svc \ ---config-management-plugin kcl-v1.0 -``` - -如果创建成功,您可以看到如下输出: - -```bash -application 'guestbook' created -``` - -> 如果您使用的是私有存储库,则在执行 create 命令之前,需要使用私钥凭据配置专用私有存储库访问权限。请参阅[这里](https://argo-cd.readthedocs.io/en/stable/user-guide/private-repositories/)以获取更多详细信息。 - -通过 ArgoCD UI,您可以看到创建的应用程序尚未同步,您可以手动进行配置同步或设置为自动同步。 - -![](/img/docs/user_docs/guides/gitops/argocd-kcl-app.jpg) - -有关同步策略的更多信息,可以请参阅[这里](https://argo-cd.readthedocs.io/en/stable/user-guide/sync-options/) - -![](/img/docs/user_docs/guides/gitops/argocd-kcl-app-dashboard.jpg) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/index.md deleted file mode 100644 index c0613d42..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/index.md +++ /dev/null @@ -1 +0,0 @@ -# 用户手册 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/1-overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/1-overview.md deleted file mode 100644 index ce7b13cb..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/1-overview.md +++ /dev/null @@ -1,3 +0,0 @@ -# 简介 - -KCL 通过包管理工具 [kpm](https://github.com/kcl-lang/kpm) 对 KCL 包进行管理。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/2-installation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/2-installation.md deleted file mode 100644 index 7b0892a5..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/2-installation.md +++ /dev/null @@ -1,53 +0,0 @@ -# 安装 - -## 安装 `kpm` - -kpm 将调用 `KCL`编译器来编译 KCL 程序。在使用 `kpm` 之前,您需要确保 `KCL` 编译器已经成功安装,您可以参照[如何安装 KCL 编译器](https://kcl-lang.io/docs/user_docs/getting-started/install)。 - -### 使用 `go install` 安装 `kpm` - -您可以使用 go install 命令安装 kpm。 - -```shell -go install kcl-lang.io/kpm@latest -``` - -### 从 Github release 页面手动安装 `kpm` - -您可以从 [kpm Github Release](https://github.com/kcl-lang/kpm/releases) 中获取 `kpm` ,并将 `kpm` 的二进制文件路径设置到环境变量 PATH 中。 - -```shell -# KPM_INSTALLATION_PATH 是 `kpm` 二进制文件的所在目录. -export PATH=$KPM_INSTALLATION_PATH:$PATH -``` - -请使用以下命令以确保您成功安装了`kpm`。 - -```shell -kpm --help -``` - -如果你看到以下输出信息,那么你已经成功安装了`kpm`,可以继续执行下一步操作。 - -```shell -NAME: - kpm - kpm is a kcl package manager - -USAGE: - kpm [arguments]... - -COMMANDS: - init initialize new module in current directory - add add new dependency - pkg package a kcl package into tar - metadata output the resolved dependencies of a package - run compile kcl package. - login login to a registry - logout logout from a registry - push push kcl package to OCI registry. - pull pull kcl package from OCI registry. - help, h Shows a list of commands or help for one command - -GLOBAL OPTIONS: - --help, -h show help -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/3-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/3-quick-start.md deleted file mode 100644 index 455987c8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/3-quick-start.md +++ /dev/null @@ -1,108 +0,0 @@ -# 快速开始 - -## 1. 初始化一个空的 KCL 包 - -使用 `kpm init` 命令创建一个名为 `my_package` 的 kcl 程序包, 并且在我们创建完成一个名为 `my_package` 的包后,我们需要通过命令 `cd my_package` 进入这个包来进行后续的操作。 - -```shell -kpm init my_package && cd my_package -``` - -![kpm_init](/img/docs/user_docs/guides/package-management/gifs/kpm_init.gif) - -`kpm` 将会在执行`kpm init my_package`命令的目录下创建两个默认的配置文件 `kcl.mod` 和 `kcl.mod.lock`。 - -```shell -- my_package - |- kcl.mod - |- kcl.mod.lock - |- # 你可以直接在这个目录下写你的kcl程序。 -``` - -`kcl.mod.lock` 是 `kpm` 用来固定依赖版本的文件,是自动生成的,请不要人工修改这个文件。 - -`kpm` 将会为这个新包创建一个默认的 `kcl.mod`。如下所示: - -```shell -[package] -name = "my_package" -edition = "0.0.1" -version = "0.0.1" -``` - -## 2. 为 KCL 包添加依赖 - -然后,您可以通过 `kpm add` 命令来为您当前的库添加一个外部依赖。 - -如下面的命令所示,为当前包添加一个版本号为 `1.27.2` 并且名为 `k8s` 的依赖包。 - -```shell -kpm add k8s:1.27.2 -``` - -![kpm_add_k8s](/img/docs/user_docs/guides/package-management/gifs/kpm_add_k8s.gif) - -`kpm` 会为您将依赖添加到 kcl.mod 文件中. - -```shell -[package] -name = "my_package" -edition = "0.0.1" -version = "0.0.1" - -[dependencies] -k8s = "1.27.2" # The dependency 'k8s' with version '1.27.2' -``` - -## 编写一个程序使用包 `konfig` 中的内容 - -在当前包中创建 `main.k`。 - -```shell -- my_package - |- kcl.mod - |- kcl.mod.lock - |- main.k # Your KCL program. -``` - -并且将下面的内容写入 `main.k` 文件中。 - -```kcl -# 导入并使用外部依赖 `k8s` 包中的内容。 -import k8s.api.core.v1 as k8core - -k8core.Pod { - metadata.name = "web-app" - spec.containers = [{ - name = "main-container" - image = "nginx" - ports = [{containerPort = 80}] - }] -} - -``` - -## 3. 运行 KCL 代码 - -你可以使用 kpm 编译刚才编写的 `main.k` 文件, 得到编译后的结果。 - -```shell -kpm run -``` - -输出为 - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: web-app -spec: - containers: - - image: nginx - name: main-container - ports: - - containerPort: 80 -``` - -![kpm_run](/img/docs/user_docs/guides/package-management/gifs/kpm_run.gif) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md deleted file mode 100644 index 23dd53a5..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md +++ /dev/null @@ -1,73 +0,0 @@ -# 发布 KCL 包到 ghcr.io - -本文将指导您如何使用 kcl 包管理将您的 kcl 包推送到发布到 OCI Registry 中。kcl 包管理默认使用 [ghcr.io](https://ghcr.io) 作为 OCI Registry, 您可以通过修改 kcl 包管理配置文件来更改默认的 OCI Registry。关于如何修改 kcl 包管理配置文件的信息,请参阅 [kcl oci registry](https://github.com/kcl-lang/kpm/blob/main/docs/kpm_oci-zh.md#kpm-registry) - -下面是一个简单的步骤,指导您如何使用 kcl 包管理将您的 kcl 包推送到 ghcr.io。 - -## 步骤 1:安装 KCL CLI - -首先,您需要在您的计算机上安装 KCL CLI。您可以按照 [KCL CLI 安装文档](https://kcl-lang.io/zh-CN/docs/user_docs/getting-started/install)中的说明进行操作。 - -## 步骤 2:创建一个 ghcr.io 令牌 - -如果您使用默认的 OCI Registry, 要将 kcl 包推送到 ghcr.io,您需要创建一个用于身份验证的令牌。您可以参考以下文档。 - -- [创建 ghcr.io token](https://docs.github.com/zh/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic) - -## 步骤 3:登录 ghcr.io - -在安装了 kcl 包管理并创建了 ghcr.io 令牌后,您需要使用 kcl 包管理登录 ghcr.io。您可以使用以下命令进行操作: - -```shell -kcl registry login -u -p ghcr.io -``` - -其中 `` 是您的 GitHub 用户名,`` 是您在步骤 2 中创建的令牌。 - -关于如何使用 kcl 包管理登录 ghcr.io 的更多信息,请参阅 [kcl registry login](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/login)。 - -## 步骤 4:推送您的 kcl 包 - -现在,您可以使用 kcl 包管理将您的 kcl 包推送到 ghcr.io。 - -### 1. 一个合法的 kcl 包 - -首先,您需要确保您推送的内容是符合一个 kcl 包的规范,即必须包含合法的 kcl.mod 和 kcl.mod.lock 文件。 - -如果您不知道如何得到一个合法的 `kcl.mod` 和 `kcl.mod.lock`。您可以使用 `kcl mod init` 命令。 - -```shell -# 创建一个名为 my_package 的 kcl 包 -kcl mod init my_package -``` - -`kcl mod init my_package` 命令将会为您创建一个新的 kcl 包 `my_package`, 并为这个包创建 `kcl.mod` 和 `kcl.mod.lock` 文件。 - -如果您已经有了一个包含 kcl 文件的目录 `exist_kcl_package`,您可以使用以下命令将其转换为一个 kcl 包,并为其创建合法的 `kcl.mod` 和 `kcl.mod.lock`。 - -```shell -# 在 exist_kcl_package 目录下 -$ pwd -/home/user/exist_kcl_package - -# 执行 kcl 包管理init 命令来创建 kcl.mod 和 kcl.mod.lock -$ kcl mod init -``` - -关于如何使用 kcl 包管理init 的更多信息,请参阅 [kcl mod init](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/init)。 - -### 2. 推送 kcl 包 - -您可以在 `kcl` 包的根目录下使用以下命令进行操作: - -```shell -# 在 exist_kcl_package 包的根目录下 -$ pwd -/home/user/exist_kcl_package - -# 推送 kcl 包到默认的 OCI Registry -$ kcl mod push -``` - -完成上述步骤后,您就成功地将您的 kcl 包推送到了默认的 OCI Registry 中。 -关于如何使用 kcl mod push 的更多信息,请参阅 [kcl mod push](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/push)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md deleted file mode 100644 index 9bb9f1cc..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md +++ /dev/null @@ -1,65 +0,0 @@ -# 发布 KCL 包到 docker.io - -本文将指导您如何使用 kcl 包管理将您的 kcl 包推送到发布到 docker.io 中。 - -## 步骤 1:安装 KCL CLI - -首先,您需要在您的计算机上安装 KCL CLI。您可以按照 [KCL CLI 安装文档](https://kcl-lang.io/zh-CN/docs/user_docs/getting-started/install)中的说明进行操作。 - -## 步骤 2:创建一个 docker.io 账户 - -您需要创建一个 docker.io 账户以支持您的 kcl 包的推送。 - -## 步骤 3:登录 docker.io - -您可以直接使用 docker.io 的账户名和密码登录。 - -```shell -kcl registry login -u -p docker.io -``` - -其中 `` 是您的 docker.io 用户名,`` 是您 docker.io 账户的密码。 - -关于如何使用 KCL CLI 登录 docker.io 的更多信息,请参阅 [kcl registry login](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/login)。 - -## 步骤 4:推送您的 kcl 包 - -现在,您可以使用 KCL CLI 将您的 kcl 包推送到 docker.io。 - -### 1. 一个合法的 kcl 包 - -首先,您需要确保您推送的内容是符合一个 kcl 包的规范,即必须包含合法的 kcl.mod 和 kcl.mod.lock 文件。 - -如果您不知道如何得到一个合法的 `kcl.mod` 和 `kcl.mod.lock`。您可以使用 `kcl mod init` 命令。 - -例如:创建一个名为 my_package 的 kcl 包 - -```shell -# 创建一个名为 my_package 的 kcl 包 -kcl mod init my_package -``` - -`kcl mod init my_package` 命令将会为您创建一个新的 kcl 包 `my_package`, 并为这个包创建 `kcl.mod` 和 `kcl.mod.lock` 文件。 - -如果您已经有了一个包含 kcl 文件的目录 `exist_kcl_package`,您可以使用以下命令将其转换为一个 kcl 包,并为其创建合法的 `kcl.mod` 和 `kcl.mod.lock`。 - -在 `exist_kcl_package` 目录下执行: - -```shell -kcl mod init -``` - -关于如何使用 kpm init 的更多信息,请参阅 [kcl mod init](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/init)。 - -### 2. 推送 kcl 包 - -您可以在 `kcl` 包的根目录下使用以下命令进行操作: - -在 `exist_kcl_package` 包的根目录下, 执行 - -```shell -kcl mod push oci://docker.io//exist_kcl_package -``` - -完成上述步骤后,您就成功地将您的 kcl 包 `exist_kcl_package` 推送到了 docker.io 中。 -关于如何使用 kcl mod push 的更多信息,请参阅 [kcl mod push](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/push)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/4-how-to/6-push_github_action.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/4-how-to/6-push_github_action.md deleted file mode 100644 index 2f18b66f..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/4-how-to/6-push_github_action.md +++ /dev/null @@ -1,83 +0,0 @@ -# 如何在 github action 中使用 kcl 包管理发布您的 KCL 包 - -本文将指导您如何在 GitHub Action 中使用 kcl 包管理将您的 kcl 包推送到发布到 ghcr.io 中。 - -## 步骤 1:安装 KCL CLI - -首先,您需要在您的计算机上安装 KCL CLI。您可以按照 [KCL CLI 安装文档](https://kcl-lang.io/zh-CN/docs/user_docs/getting-started/install)中的说明进行操作。 - -## 步骤 2:创建一个 GitHub 账号 - -如果您已经有 GitHub 帐号了,您可以选择跳过这一步 - -[注册新的一个 GitHub 账号](https://docs.github.com/zh/get-started/signing-up-for-github/signing-up-for-a-new-github-account) - -## 步骤 3: 为您的 KCL 包创建一个 GitHub 仓库并进行相关配置 - -### 1. 为您的 KCL 程序包准备仓库 - -您需要为您的 KCL 程序包准备一个 GitHub 仓库。 - -[创建一个 GitHub 仓库](https://docs.github.com/zh/get-started/quickstart/create-a-repo) - -在这个仓库中添加您的 KCL 程序,以仓库 https://github.com/awesome-kusion/catalog.git 为例, - -```bash -├── .github -│ └── workflows -│ └── push.yaml # github action 文件 -├── LICENSE -├── README.md -├── kcl.mod # kcl.mod 将当前仓库内容定义为一个 kcl 包 -├── kcl.mod.lock # kcl.mod.lock 是 kcl 包管理工具自动生成的文件 -└── main.k # 您的 KCL 程序 -``` - -### 2. 为您的仓库设置 OCI Registry,账户和密码 - -以 docker.io 为例,您可以为您的仓库设置 secrets `REG`, `REG_ACCOUNT` 和 `REG_TOKEN`。`REG` 的值为 `docker.io`,`REG_ACCOUNT` 的值为您的 docker.io 账户, `REG_TOKEN` 为您的 `docker.io` 登录密码。 - -[为仓库添加 secrets](https://docs.github.com/zh/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) - -如果您使用 `ghcr.io` 作为 `Registry`, 您需要使用 GitHub token 作为 secrets。 - -[创建一个 GitHub Token](https://docs.github.com/zh/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#personal-access-tokens-classic) - -## 步骤 4: 将您的 KCL 包添加到仓库中并编写 github action workflow - -为这个仓库添加 github action 文件 `.github/workflows/push.yml`,内容如下: - -```yaml -name: KPM Push Workflow - -on: - push: - branches: - - main - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Set up Go 1.21 - uses: actions/setup-go@v2 - with: - go-version: 1.21 - - - name: Install KCL CLI - run: go install kcl-lang.io/cli/cmd/kcl@latest - - - name: Login and Push - env: - # 通过环境变量指定 OCI Registry 和账户 - KPM_REG: ${{ secrets.REG }} - KPM_REPO: ${{ secrets.REG_ACCOUNT }} - # kcl registry login 时使用 secrets.REG_TOKEN - run: kcl registry login -u ${{ secrets.REG_ACCOUNT }} -p ${{ secrets.REG_TOKEN }} ${{ secrets.REG }} && kcl mod push - - - name: Run KCL project from oci registry - run: kcl run oci://${{ secrets.REG }}/${{ secrets.REG_ACCOUNT }}/catalog --tag 0.0.1 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/4-how-to/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/4-how-to/_category_.json deleted file mode 100644 index 370cb4e9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/4-how-to/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "如何使用", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/_category_.json deleted file mode 100644 index d1600bfd..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/package-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "包管理", - "position": 7 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/schema-definition.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/schema-definition.md deleted file mode 100644 index 735667b9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/schema-definition.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -title: "模型定义" -sidebar_position: 3 ---- - -## 简介 - -KCL 的核心场景是写配置和校验,因此 KCL 被设计之初的一个核心特性就是**建模**,对应到 KCL 的关键字 `schema`,`schema` 可以被用于定义结构和约束,比如字段的类型,默认值,字段的范围和各种其他约束等内容。此外,使用 KCL schema 定义的结构可以反过来用于验证实现、验证输入(JSON、YAML 等结构化数据)或生成代码(生成多语言结构体、OpenAPI 等)。 - -## 使用 KCL 定义结构和约束 - -### 0. 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. 获得示例 - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/definition -``` - -我们可以执行如下命令显示配置 - -```bash -cat main.k -``` - -输出为 - -```python -import .app_module # A relative path import - -app: app_module.App { - domainType = "Standard" - containerPort = 80 - volumes = [ - { - mountPath = "/tmp" - } - ] - services = [ - { - clusterIP = "None" - $type = "ClusterIP" - } - ] -} -``` - -我们将 `App` 模型放入单独的 `app_module.k` 中,在需要时我们可以在 `main.k` 中使用 `import` 关键字进行模块化管理,比如下面的文件结构 - -``` -. -├── app_module.k -└── main.k -``` - -其中 `app_module.k` 的内容为 - -```python -schema App: - domainType: "Standard" | "Customized" | "Global" - containerPort: int - volumes: [Volume] - services: [Service] - - check: - 1 <= containerPort <= 65535 - -schema Service: - clusterIP: str - $type: str - - check: - clusterIP == "None" if $type == "ClusterIP" - -schema Volume: - container: str = "*" # `container` 的默认值为 "*" - mountPath: str - - check: - mountPath not in ["/", "/boot", "/home", "dev", "/etc", "/root"] -``` - -在上面的文件中。在其中,我们使用 `schema` 关键字定义了三个模型 `App`,`Service` 和 `Volume`。并且 `App` 模型具有四个属性 `domainType`, `containerPort`, `volumes` 和 `services`,其中 - -- `domainType` 的类型为字符串字面值联合类型,与“枚举”类似,这表明 `domainType` 的值只能取 `"Standard"`, `"Customized"` 和 `"Global"` 中的一个 -- `containerPort` 的类型为整数 `int`, 此外我们使用 `check` 关键字定义了其取值范围 1 ~ 65535 -- `services` 的类型为 `Service` 列表类型,`Service`,并且我们用 `?` 标记了它是一个可选属性,这意味着我们可以不为其赋值。 -- `volumes` 的类型为 `Volume` 列表类型,并且我们用 `?` 标记了它是一个可选属性,这意味着我们可以不为其赋值。 - -### 2. 输出配置 - -我们可以使用如下命令行可以获得 `app` 实例的 YAML 输出 - -```shell -kcl main.k -``` - -输出为 - -```yaml -app: - domainType: Standard - containerPort: 80 - volumes: - - container: "*" - mountPath: /tmp - services: - - clusterIP: None - type: ClusterIP -``` - -## 小结 - -KCL 是一种用于定义配置和约束的语言,其核心功能是使用 schema 关键字进行建模,schema 允许定义具有属性、默认值、范围检查和其他约束的结构。使用 KCL schema 定义的结构可以用于验数据或生成代码。该文档演示了如何使用 schema 定义模型,使用 import 导入模型进行模块化管理,并使用 kcl 命令输出已定义结构实例的 YAML 配置。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/secret-management/1-vault.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/secret-management/1-vault.md deleted file mode 100644 index f070a784..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/secret-management/1-vault.md +++ /dev/null @@ -1,142 +0,0 @@ ---- -id: vault -sidebar_label: Vault ---- - -# Vault - -## 简介 - -This guide will show you that KCL solves the secret management problem by integrating [Vault](https://developer.hashicorp.com/vault) and [Vals](https://github.com/helmfile/vals). - -## 先决条件 - -- Install [KCL](/docs/user_docs/getting-started/install) -- Prepare a [Kubernetes Cluster](https://kubernetes.io/) -- Install [Vault](https://developer.hashicorp.com/vault/downloads) -- Install [Vals](https://github.com/helmfile/vals) - -## 具体步骤 - -### 1. 获得示例 - -We put the application source code and infrastructure deployment code in different repos, which can be maintained by different roles to achieve the separation of concerns. - -- Get the application code - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/secret-management/vault -``` - -- Show the config - -```shell -cat main.k -``` - -The output is - -```python -# Secret Management using Vault and Vals - -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" - annotations: { - "secret-store": "vault" - # Valid format: - # "ref+vault://PATH/TO/KV_BACKEND#/KEY" - "foo": "ref+vault://secret/foo#/foo" - "bar": "ref+vault://secret/bar#/bar" - } -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -The main.k file extends the configuration of the Nginx application and customizes annotations. Among them, the value of annotation `foo` and `bar` follow secret reference format (`ref+vault://PATH/TO/KV_BACKEND#/KEY`): - -- `ref+vault`: indicates that this is a secret reference, and the external storage service is `Vault`. -- `PATH/TO/KV_BACKEND`: specifies the path where a secret is stored. -- `KEY`: specifies the key to reading secret. - -The complete format is concatenated using a style similar to URI expressions, which can retrieve a secret stored externally. - -### 2. 预存敏感信息 - -Start the Vault Server - -```shell -vault server -dev -export VAULT_ADDR='http://127.0.0.1:8200' -# Note: Replace with your token -export VAULT_TOKEN=yourtoken -``` - -After Vault is started in development mode and unpacked, secrets are pre-stored, and the path and keys are consistent with `main.k`: - -```shell -vault kv put secret/foo foo=foo -vault kv put secret/bar bar=bar -``` - -### 3. 部署配置 - -Using the following command to apply the deployment manifest. - -```shell -kcl main.k | vals eval -f - | kubectl apply -f - -``` - -The expect output is - -```shell -deployment.apps/nginx created -``` - -### 4. 验证敏感信息 - -Next, verify that the secrets have been retrieved from Vault and replace the values of annotations of Nginx: - -- Verify the `foo` annotation - -```shell -kubectl get deploy nginx -o yaml | grep 'foo:' -``` - -The output is - -```yaml -foo: foo -``` - -- Verify the `bar` annotation - -```shell -kubectl get deploy nginx -o yaml | grep 'bar:' -``` - -The output is - -```yaml -bar: bar -``` - -So far, we have retrieved the secrets hosted in `Vault` and put them into use. - -## 小结 - -This guide introduces how KCL solves the secret management by integrating Vault and Vals. By following these steps, we can retrieve the secrets hosted in Vault and utilize them. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/validation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/validation.md deleted file mode 100644 index 2368ec22..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/validation.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: "校验" -sidebar_position: 2 ---- - -## 简介 - -验证是校验数据是否准确、可靠并满足某些要求或限制的过程,包括检查数据的完整性、一致性、准确性和相关性。进行数据验证是为了确保数据符合其预期目的,并能有效使用。 - -我们可以使用 KCL 及其校验工具手动或自动进行数据验证,以确保数据的一致性。 - -## 使用 KCL 校验数据 - -除了使用 KCL 代码生成 JSON/YAML 等配置格式,KCL 还支持对 JSON/YAML 数据进行格式校验。作为一种配置语言,KCL 在验证方面几乎涵盖了 OpenAPI 的所有功能。在 KCL 中可以通过一个结构定义来约束配置数据,同时支持通过 check 块自定义约束规则,在 schema 中书写校验表达式对 schema 定义的属性进行校验和约束。通过 check 表达式可以非常清晰简单地校验输入的 JSON/YAML 是否满足相应的 schema 结构定义与 check 约束。 - -### 0. 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. 获得示例 - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/validation -``` - -我们可以执行如下命令显示配置 - -```bash -cat schema.k -``` - -输出为 - -```python -schema User: - name: str - age: int - message?: str - data: Data - labels: {str:} - hc: [int] - - check: - age > 10, "age must > 10" - -schema Data: - id: int - value: str -``` - -在 schema 中,我们可以使用 `check` 关键字来编写每个 schema 属性的验证规则。`check` 块中的每一行都对应于一个条件表达式。当满足条件时,验证成功。条件表达式后面可以跟 `, "报错信息"`,以指示检查失败时要给用户显示的消息。 - -综上所述,KCL Schema 中支持的校验类型为: - -| 校验类型 | 使用方法 | -| -------- | ---------------------------------------------------------- | -| 范围校验 | 使用 `<`, `>` 等比较运算符 | -| 正则校验 | 使用 `regex` 系统库中的 `match` 等方法 | -| 长度校验 | 使用 `len` 内置函数,可以求 `list/dict/str` 类型的变量长度 | -| 枚举校验 | 使用字面值联合类型 | -| 非空校验 | 使用 schema 的可选/必选属性 | -| 条件校验 | 使用 check if 条件表达式 | - -### 2. 验证数据 - -新建一个名为 `data.json` 的 JSON 配置文件: - -```json -{ - "name": "Alice", - "age": 18, - "message": "This is Alice", - "data": { - "id": 1, - "value": "value1" - }, - "labels": { - "key": "value" - }, - "hc": [1, 2, 3] -} -``` - -执行如下命令获得校验结果 - -```bash -kcl-vet data.json schema.k -``` - -## 小结 - -KCL 是一种配置语言,通过其结构定义和用户定义的约束规则来支持数据验证。KCL Schema 中支持的验证类型包括范围、正则表达式、长度、枚举、可选/必需和条件。并且可以使用 KCL 验证工具或在此基础上构建的可视化产品来验证数据。 - -## 未来计划 - -KCL 校验能力的提升将逐渐围绕"静态化"方面展开工作,即在编译时,结合形式化验证的能力直接分析得出数据是否满足约束条件、约束条件是否冲突等结论,并且可以通过 IDE 实时透出约束错误,而无需在运行时发现错误。 - -我们还期望 KCL Schema 和约束可以作为一个包来管理(这个包只有 KCL 文件)。例如,Kubernetes 模型和约束可以开箱即用。用户可以生成配置或验证现有配置,并且可以通过 KCL 继承简单地扩展用户想要的模型和约束。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md deleted file mode 100644 index 5ebfe83c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: "从 Kubernetes 迁移" -sidebar_position: 1 ---- - -## 简介 - -KCL 对 Kubernetes 配置提供了许多开箱即用的支持,通过 KCL 工具,我们可以将 Kubernetes Schema 和 配置集成到 KCL 中,本节内容将介绍如何使用 KCL 对 Kubernetes 进行集成 - -### 1. Kubernetes OpenAPI Spec - -从 Kubernetes 1.4 开始,引入了对 OpenAPI 规范(在捐赠给 Open API Initiative 之前称为 swagger 2.0)的 alpha 支持,API 描述遵循 [OpenAPI 规范 2.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md),从 Kubernetes 1.5 开始,Kubernetes 能够直接从[源码自动地提取模型并生成 OpenAPI 规范](https://github.com/kubernetes/kube-openapi),自动化地保证了规范和文档与操作/模型的更新完全同步。 - -此外,Kubernetes CRD 使用 [OpenAPI v3.0 validation](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation) 来描述(除内置属性 apiVersion、kind、metadata 之外的)自定义 schema,在 CR 的创建和更新阶段,APIServer 会使用这个 schema 对 CR 的内容进行校验。 - -### 2. KCL OpenAPI 支持 - -KCLOpenAPI 工具支持从 OpenAPI/CRD 定义提取并生成 KCL schema. 在 KCLOpenAPI Spec 中明确定义了 OpenAPI 规范与 KCL 语言之间的映射关系。 - -### 3. 从 Kubernetes 模型迁移到 KCL - -#### 3.1 基于 kusion_models 编写配置 - -我们为你提供了一个开箱即用的 `kusion_models` 包,让你可以快速开始。其中包含一个精心设计的前端模型,称为[服务器模型](https://github.com/KusionStack/konfig/blob/main/base/pkg/kusion_models/kube/frontend/server.k)(Server schema)。你可以通过初始化 `Server schema` 来声明其配置。有关模式及其属性的说明和用法,请参阅 [Server schema 文档](https://kusionstack.io/docs/reference/model/kusion_models/kube/frontend/doc_server)。 - -#### 3.2 创建自定义的 models 前端模型 - -现有的 `kusion_models` 模型可能无法满足你的特定业务需求,那么你也可以设计自定义前端模型包。 您可基于预先生成的 Kubernetes KCL 包自定义您的前端模型。您还可以仿照`kube2kcl` 工具的模式,开发自定义脚本,完成配置数据的迁移。 - -##### 3.2.1 获取 Kubernetes KCL 模型 - -我们提供了预生成的各版本[Kubernetes KCL模型](https://github.com/orgs/KusionStack/packages/container/package/k8s),您可以在项目下执行 `kpm add k8s:` 来获得它。有关 kpm 使用的详细信息,请参考 [kpm快速入门指南](https://github.com/kcl-lang/kpm#quick-start)。 - -或者,如果您需要自己生成这些包,请参考[从 Kubernetes OpenAPI 文件生成 KCL 包](https://github.com/kcl-lang/kcl-openapi/blob/main/docs/generate_from_k8s_spec.md)。 - -##### 3.2.2 编写自定义前端模型 - -由于 Kubernetes 内置模型较为原子化和复杂,我们推荐以 Kubernetes 原生模型作为后端输出的模型,对其进一步抽象,而向用户暴露一份更为友好和简单的前端模型界面,具体您可参照 Konfig 仓库中 [kusion_models Server](https://github.com/KusionStack/konfig/blob/main/base/pkg/kusion_models/kube/frontend/server.k) 模型的设计方式进行。 - -##### 3.2.3 迁移配置数据 - -对于存量的 Kubernetes 配置数据,您可以仿照 kube2Kcl 工具的做法,编写自定义的转换脚本,进行一键迁移。Kusion 后续将提供该脚本的编写脚手架和编写指南。 - -### 4. 从 Kubernetes CRD 迁移 - -如果您的项目中使用了 CRD,也可以采用类似的模式,生成 CRD 对应的 KCL schema,并基于该 schema 声明 CR。 - -- 从 CRD 生成 KCL Schema - - ``` - kcl-openapi generate model --crd --skip-validation -f your_crd.yaml - ``` - -- 使用 KCL 声明 CR - - 使用 KCL 声明 CR 的模式与声明 Kubernetes 内置模型配置的模式相同,在此不做赘述。 - -## 小结 - -本节介绍了如何使用 kcl-openapi 工具将 OpenAPI 规范映射到 KCL 语言特性,此外提供了将 KCL 与 OpenAPI 和 Kubernetes CRD 一起使用的快速入门指南帮助从 Kubernetes 进行迁移或集成。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md deleted file mode 100644 index e674c946..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md +++ /dev/null @@ -1,249 +0,0 @@ ---- -title: "使用 KCL 生成并管理 Kubernetes 资源配置" -sidebar_position: 2 ---- - -## 简介 - -当我们管理 Kubernetes 资源清单时,我们常常会手写维护,或者使用 Helm 和 Kustomize 等工具来维护我们 YAML 配置或者配置模版,然后通过 kubectl 和 helm 命令行等工具将资源下发到集群。但是作为一个 "YAML 工程师" 每天维护 YAML 配置无疑是琐碎且无聊的,并且容易出错。 - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: ... # Omit -spec: - selector: - matchlabels: - cell: RZ00A - replicas: 2 - template: - metadata: ... # Omit - spec: - tolerations: - - effect: NoSchedules - key: is-over-quota - operator: Equal - value: 'true' - containers: - - name: test-app - image: images.example/app:v1 # Wrong ident - resources: - limits: - cpu: 2 # Wrong type. The type of cpu should be str - memory: 4Gi - # Field missing: ephemeral-storage - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: is-over-quota - operator: In - values: - - 'true' -``` - -- YAML 中的结构化数据是无类型的,缺乏验证方法,无法立即检查所有数据的有效性 -- YAML 编程能力欠佳,容易写出不正确的缩进,也没有逻辑判断等常见代码组织方式,容易写出大量重复配置,难以维护 -- Kubernetes 设计是复杂的,用户很难理解所有细节,比如上面配置中的 `toleration` 和 `affinity` 字段,如果用户不理解调度逻辑,它可能被错误地省略掉或者多余的添加 - -因此,KCL 期望在 Kubernetes YAML 资源管理解决如下问题: - -- 用**生产级高性能编程语言**以**编写代码**的方式提升配置的灵活度,比如条件语句、循环、函数、包管理等特性提升配置重用的能力 -- 在代码层面提升**配置语义验证**的能力,比如字段可选/必选、类型、范围等配置检查能力 -- 提供**配置分块编写、组合和抽象的能力**,比如结构定义、结构继承、约束定义等能力 - -## 先决条件 - -首先可以在 [KCL 快速开始](/docs/user_docs/getting-started/kcl-quick-start) 根据指导下载并安装 KCL,然后准备一个 [Kubernetes](https://kubernetes.io/) 环境 - -## 快速开始 - -### 1. 生成 Kubernetes 资源 - -我们可以编写如下 KCL 代码并命名为 main.k ,KCL 受 Python 启发,基础语法十分接近 Python, 比较容易学习和上手, 配置模式写法很简单,`k [: T] = v`, 其中 `k` 表示配置的属性名称; `v` 表示配置的属性值; `: T` 表示一个可选的类型注解。 - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -上述 KCL 代码中我们分别声明了一个 Kubernetes Deployment 资源的 `apiVersion`、`kind`、`metadata` 和 `spec` 等变量,并分别赋值了相应的内容,特别地,我们将 `metadata.labels` 字段分别重用在 `spec.selector.matchLabels` 和 `spec.template.metadata.labels` 字段。可以看出,相比于 YAML,KCL 定义的数据结构更加紧凑,而且可以通过定义局部变量实现配置重用。 - -我们可以执行如下命令行得到一个 Kubernetes YAML 文件 - -```bash -kcl main.k -``` - -输出为: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -当然我们可以将 KCL 工具与 kubectl 等工具结合使用,让我们执行如下命令并看看效果 - -```shell -kcl main.k | kubectl apply -f - -``` - -输出为 - -```shell -deployment.apps/nginx-deployment configured -``` - -可以从命令行的结果看出与我们使用直接使用 YAML 配置和 kubectl apply 的一个 Deployment 体验完全一致 - -通过 kubectl 检查部署状态 - -```shell -kubectl get deploy -``` - -输出为 - -```shell -NAME READY UP-TO-DATE AVAILABLE AGE -nginx-deployment 3/3 3 3 15s -``` - -### 2. 编写代码管理 Kubernetes 资源 - -对于 Kubernetes 资源发布时,我们常常会遇到配置参数需要动态指定的场景,比如不同的环境需要设置不同的 `image` 字段值生成不同环境的资源。对于这种场景,我们可以通过 KCL 的条件语句和 `option` 函数动态地接收外部参数。我们可以在上述例子的基础上根据不同的环境调整配置参数,比如对于如下代码,我们编写了一个条件语句并输入一个名为 `env` 的动态参数 - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" if option("env") == "prod" else "${metadata.name}:latest" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -使用 KCL 命令行 `-D` 标记接收一个外部设置的动态参数: - -```bash -kcl main.k -D env=prod -``` - -输出为: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -上述代码片段中的 `image = metadata.name + ":1.14.2" if option("env") == "prod" else metadata.name + ":latest"` 意思为:当动态参数 `env` 的值被设置为 `prod` 时,image 字段值为 `nginx:1.14.2`, 否则为 `nginx:latest`,因此我们可以根据需要为 env 设置为不同的值获得不同内容的 Kubernetes 资源。 - -并且 KCL 支持将 option 函数动态参数维护在配置文件中,比如编写下面展示的 `kcl.yaml` 文件 - -```yaml -kcl_options: - - key: env - value: prod -``` - -使用如下命令行也可以得到同样的 YAML 输出,以简化 KCL 动态参数的输入过程 - -```bash -kcl main.k -Y kcl.yaml -``` - -输出为: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## 小结 - -KCL 可以用于生成和管理 Kubernetes 资源,解决管理 YAML 配置的局限性,例如缺乏验证方法和较弱的编程能力等,并可以通过条件语句和 option 函数动态接收外部参数,从而能够根据不同的环境调整配置参数。此外,KCL 可以与 kubectl 等其他工具一起使用将配置一键生效到集群。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md deleted file mode 100644 index 5fe97d05..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: "Kubectl KCL 插件" -sidebar_position: 1 ---- - -## 简介 - -[Kubectl](https://kubernetes.io/docs/reference/kubectl/) is a command line tool for communicating with a Kubernetes cluster's control plane, using the Kubernetes API. You can use the `Kubectl-KCL-Plugin` to - -- Edit the YAML configuration in a hook way to separate data and logic for the Kubernetes manifests management. -- For multi-environment and multi-tenant scenarios, you can maintain these configurations gracefully rather than simply copy and paste. -- Validate all KRM resources using the KCL schema. - -## 前置条件 - -- Install [Kubectl](https://github.com/kubernetes/kubectl) -- Install [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) - -## 快速开始 - -Let’s write a KCL function which add annotation `managed-by=krm-kcl` only to `Deployment` resources in the helm chart. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/kubectl-kcl.git/ -cd ./kubectl-kcl/examples/ -``` - -### 2. Test and Run - -Run the KCL code via the `Kubectl KCL Plugin`. - -```bash -kubectl kcl run -f ./kcl-run.yaml -``` - -The output yaml is - -```yaml -apiVersion: config.kubernetes.io/v1 -kind: ResourceList -items: - - apiVersion: apps/v1 - kind: Deployment - metadata: - annotations: - managed-by: krm-kcl - labels: - app: nginx - name: nginx-deployment - spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - image: "nginx:1.14.2" - name: nginx - ports: - - containerPort: 80 - - apiVersion: v1 - kind: Service - metadata: - name: test - spec: - ports: - - port: 80 - protocol: TCP - targetPort: 9376 - selector: - app: MyApp -functionConfig: - # kcl-fn-config.yaml - apiVersion: krm.kcl.dev/v1alpha1 - kind: KCLRun - metadata: - # EDIT THE SOURCE! - # This should be your KCL code which preloads the `ResourceList` to `option("resource_list") - spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "krm-kcl"}} for resource in option("resource_list").items] -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md deleted file mode 100644 index 271f08e8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: "Helm KCL 插件" -sidebar_position: 2 ---- - -## 简介 - -[Helm](https://github.com/helm/helm) 是一个管理 Charts 的工具。Charts 是预配置的 Kubernetes 资源的包。您可以使用 `Helm-KCL-Plugin` 来完成以下操作: - -- 以 hook 的方式编辑 Helm charts,将数据和逻辑分离以便更好地管理 Kubernetes manifests -- 对于多环境和多租户方案,可以优雅地维护这些配置,而不仅仅是简单地复制和粘贴 -- 使用 KCL 模式验证所有 KRM 资源 - -## 先决条件 - -- 安装 [Helm](https://github.com/helm/helm) -- 安装 [Helm KCL 插件](https://github.com/kcl-lang/helm-kcl) - -## 快速开始 - -让我们编写一个仅向 `Deployment` 资源添加 annotation `managed-by=helm-kcl-plugin` 的 KCL 函数 - -### 1. 获取示例 - -```bash -git clone https://github.com/kcl-lang/helm-kcl.git/ -cd ./helm-kcl/examples/workload-charts-with-kcl -``` - -### 2. 测试和运行 - -通过 `Helm KCL Plugin` 运行KCL代码。 - -```bash -helm kcl template --file ./kcl-run.yaml -``` - -输出的YAML为 - -```yaml -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: workload - app.kubernetes.io/version: 0.1.0 - helm.sh/chart: workload-0.1.0 - name: workload -spec: - ports: - - name: www - port: 80 - protocol: TCP - targetPort: 80 - selector: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - type: ClusterIP ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: workload - app.kubernetes.io/version: 0.1.0 - helm.sh/chart: workload-0.1.0 - name: workload - annotations: - managed-by: helm-kcl-plugin -spec: - selector: - matchLabels: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - template: - metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - spec: - containers: - - image: nginx:alpine - name: frontend -``` - -## KCL 开发指南 - -以下是您可以在 KCL 代码中执行的操作: - -- 从 `option("resource_list")` 读取资源。`option("resource_list")` 符合 [KRM 函数规范](https://kpt.dev/book/05-developing-functions/01-functions-specification)。 你可以从 `option("resource_list")["items"]` 读取输入资源,并从 `option("resource_list")["functionConfig"]` 读取 `functionConfig`。 -- 返回输出资源的 KPM 列表。 -- 使用 `assert {condition},{error_message}` 返回错误消息。 - -## 更多文档和示例 - -- [Helm KCL 插件](https://github.com/kcl-lang/helm-kcl) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md deleted file mode 100644 index 4f1c8c56..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -title: "Kustomize KCL 插件" -sidebar_position: 3 ---- - -## 简介 - -[Kustomize](https://github.com/kubernetes-sigs/kustomize) 允许自定义用于多种目的原始的、无模板的 YAML 文件,同时保留原始 YAML 不变和可用。 - -KCL 可用于创建函数,以改变和/或验证 Kubernetes 资源模型(KRM)的 YAML 输入/输出格式,并且我们提供 Kustomize KCL 函数来简化函数编写过程。 - -## 先决条件 - -- 安装 [kustomize](https://github.com/kubernetes-sigs/kustomize) - -## 快速开始 - -让我们编写一个仅向 Deployment 资源添加 annotation `managed-by=kustomize-kcl` 的 KCL 函数 - -### 1. 获取示例 - -```bash -git clone https://github.com/kcl-lang/kustomize-kcl.git -cd ./kustomize-kcl/examples/set-annotation/ -``` - -### 2. 测试和运行 - -```bash -kustomize fn run ./local-resource/ --dry-run -``` - -输出的YAML为 - -```yaml -apiVersion: krm.kcl.dev/v1alpha1 -kind: KCLRun -metadata: - name: set-annotation - annotations: - config.kubernetes.io/function: | - container: - image: docker.io/kcllang/kustomize-kcl:v0.2.0 - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml -# EDIT THE SOURCE! -# This should be your KCL code which preloads the `ResourceList` to `option("resource_list") -spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "kustomize-kcl"}} for resource in option("resource_list").items] ---- -apiVersion: v1 -kind: Service -metadata: - name: test - annotations: - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml -spec: - selector: - app: MyApp - ports: - - protocol: TCP - port: 80 - targetPort: 9376 ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx - annotations: - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml - managed-by: kustomize-kcl -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## KCL 开发指南 - -以下是可以使用 KCL 执行的操作: - -- 从 `option("resource_list")` 读取资源。`option("resource_list")` 符合 [KRM 函数规范](https://kpt.dev/book/05-developing-functions/01-functions-specification)。 你可以从 `option("resource_list")["items"]` 读取输入资源,并从 `option("resource_list")["functionConfig"]` 读取 `functionConfig`。 -- 返回输出资源的 KPM 列表。 -- 使用 `assert {condition},{error_message}` 返回错误消息。 - -## 更多文档和示例 - -- [Kustomize KCL 插件](https://github.com/kcl-lang/kustomize-kcl) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md deleted file mode 100644 index 1981ae3d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: "KPT KCL SDK" -sidebar_position: 4 ---- - -## 简介 - -[kpt](https://github.com/GoogleContainerTools/kpt) 是一个以包为中心的工具链,可实现配置原地编辑、自动化和交付,通过将声明性配置作为数据进行操作,从而简化 Kubernetes 平台和 KRM 驱动的基础设施(例如,Config Connector、Crossplane)的大规模管理,以实现 Kubernetes 配置编辑的自动化包括转换和验证。 - -KCL 可用于创建函数来转换和/或验证 YAML Kubernetes 资源模型 (KRM) 输入/输出格式,但我们提供 KPT KCL SDK 来简化函数编写过程。 - -## 先决条件 - -- 安装 [kpt](https://github.com/GoogleContainerTools/kpt) -- 安装 [Docker](https://www.docker.com/) - -## 快速开始 - -让我们编写一个仅向 Deployment 资源添加 annotation `managed-by=kpt` 的 KCL 函数 - -### 1. 获取示例 - -```bash -git clone https://github.com/kcl-lang/kpt-kcl-sdk.git/ -cd ./kpt-kcl-sdk/get-started/set-annotation -``` - -### 2. 显示 KRM - -```bash -kpt pkg tree -``` - -输出为 - -```bash -set-annotation -├── [kcl-fn-config.yaml] KCLRun set-annotation -└── data - ├── [resources.yaml] Deployment nginx-deployment - └── [resources.yaml] Service test -``` - -### 3. 显示和更新 KCL `FunctionConfig` - -```bash -cat ./kcl-fn-config.yaml -``` - -输出为 - -```yaml -# kcl-fn-config.yaml -apiVersion: krm.kcl.dev/v1alpha1 -kind: KCLRun -metadata: # kpt-merge: /set-annotation - name: set-annotation -spec: - # 编辑此源代码 - # 您在此的 KCL 代码将 `ResourceList` 预加载到 `option("resource_list")` - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "kpt"}} for resource in option("resource_list").items] -``` - -### 4. 测试和运行 - -通过 kpt 运行 KCL 代码 - -```bash -kpt fn eval ./data -i docker.io/kcllang/kpt-kcl:v0.2.0 --fn-config kcl-fn-config.yaml - -# 验证 annotation 是否添加到 `Deployment` 资源并且其他资源 `Service` 没有这个 annotation。 -cat ./data/resources.yaml | grep annotations -A1 -B0 -``` - -输出为 - -```bash - annotations: - managed-by: kpt -``` - -可以看出,我们确实成功添加了 `managed-by=kpt` 标签 - -## 更多文档和示例 - -- [KPT KCL SDK](https://github.com/kcl-lang/kpt-kcl-sdk) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-konfig/1-overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-konfig/1-overview.md deleted file mode 100644 index b112e946..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-konfig/1-overview.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -id: overview -sidebar_label: 概述 ---- - -# Konfig 概述 - -在 KCL 中推荐通过**配置库**的方式统一管理所有的配置清单和模型库,即不仅存放抽象模型本身的 KCL 定义,还存放各种类型的配置清单,比如应用的运维配置、策略配置等。配置大库推荐托管在各类 VCS 系统中,以方便做配置的回滚和漂移检查。配置大库的最佳实践代号为 Konfig,仓库托管在 [Github](https://github.com/KusionStack/konfig)。 - -⚡️ 配置大库主要包括: - -- KCL 模块声明文件(kcl.mod) -- KCL 领域模型库 (Kubernetes, Prometheus 等) -- 各类配置清单目录 (应用运维配置等) -- 配置构建和测试脚本 (Makefile,Github CI 文件等) - -之所以用一个统一的仓库管理全部的 KCL 配置代码,是由于不同代码包的研发主体不同,会引发出包管理和版本管理的问题。将业务配置代码、基础配置代码在一个统一仓库中,代码间的版本依赖管理会比较简单,通过定位唯一代码库的目录及文件即可,可以将配置代码统一管理,便于查找、修改、维护。 - -下面是配置大库(Konfig)的架构图: - -![](/img/docs/user_docs/guides/konfig/konfig-arch.png) - -Konfig 提供给用户开箱即用、高度抽象的配置界面,模型库最初朴素的出发点就是改善 YAML 用户的效率和体验,我们希望通过将代码更繁杂的模型抽象封装到统一的模型中,从而简化用户侧配置代码的编写。Konfig 由以下部分组成: - -- **核心模型**: - - **前端模型**:前端模型即「用户界面」,包含平台侧暴露给用户的所有可配置属性,其中省略了一些重复的、可推导的配置,抽象出必要属性暴露给用户,具有用户友好的特性,比如 server.k。 - - **后端模型**:后端模型是「模型实现」,是让前端模型属性生效的模型,主要包含前端模型实例的渲染逻辑,后端模型中可借助 KCL 编写校验和逻辑判断等以提高配置代码复用性和健壮性,对用户不感知,比如 server_backend.k -- **领域模型**:是不包含任何实现逻辑和抽象的模型,往往由工具转换生成,无需修改,和真正生效的 YAML 属性一一对应,底层模型需要经过进一步抽象,一般不直接被用户使用。比如,kusion_kubernetes 是 Kubernetes 场景的底层模型库。 - -此外,核心模型内部通过前端模型和后端模型两层抽象简化前端用户的配置代码,底层模型则是通过 KCL OpenAPI 工具自动生成。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-konfig/2-structure.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-konfig/2-structure.md deleted file mode 100644 index cc54087e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-konfig/2-structure.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -id: structure -sidebar_label: 工程结构 ---- - -# Konfig 工程结构 - -本文主要解释 Konfig 配置大库的目录和代码结构 - -## 整体结构 - -```bash -. -├── .github # CI 脚本 -├── Makefile # 通过 Makefile 封装常用命令 -├── README.md # 配置大库说明 -├── appops # 应用运维目录,用来放置所有应用的 KCL 运维配置 -│ ├── clickhouse-operator -│ ├── code-city -│ ├── guestbook -│ ├── http-echo -│ └── nginx-example -├── base # 模型库 -│ ├── examples # 样例代码 -│ │ ├── monitoring # 监控配置样例 -│ │ ├── native # Kubernetes 资源配置样例 -│ │ ├── provider # 基础资源配置样例 -│ │ └── server # 云原生应用运维配置模型样例 -│ └── pkg -│ ├── kusion_kubernetes # Kubernetes 底层模型库 -│ ├── kusion_models # 核心模型库 -│ ├── kusion_prometheus # Prometheus 底层模型库 -│ └── kusion_provider # 基础资源 底层模型库 -└── kcl.mod # 大库配置文件,通常用来标识大库根目录位置以及大库所需依赖 -``` - -## 核心模型库结构 - -核心模型库一般命名为 kusion_models,主要包含前端模型、后端模型、Mixin、渲染器等,目录结构为: - -```bash -├── commons # 基础资源核心模型库 -├── kube # 云原生资源核心模型库 -│ ├── backend # 后端模型 -│ ├── frontend # 前端模型 -│ │ ├── common # 通用前端模型 -│ │ ├── configmap # ConfigMap 前端模型 -│ │ ├── container # 容器前端模型 -│ │ ├── ingress # Ingress 前端模型 -│ │ ├── resource # 资源规格前端模型 -│ │ ├── secret # Secret 前端模型 -│ │ ├── service # Service 前端模型 -│ │ ├── sidecar # Sidecar 容器前端模型 -│ │ ├── strategy # 策略前端模型 -│ │ ├── volume # Volume 前端模型 -│ │ └── server.k # 云原生应用运维前端模型 -│ ├── metadata # 应用运维的元数据模型 -│ ├── mixins # 统一放置可复用的 Mixin -│ ├── render # 渲染器,把前后端模型联系在一起的桥梁 -│ ├── templates # 静态配置 -│ └── utils # 工具方法 -└── metadata # 通用元数据模型 -``` - -## Project 和 Stack 结构 - -![](/img/docs/user_docs/concepts/project-stack.png) - -Project 和 Stack 是用于组织 Konfig 的逻辑隔离概念。 - -### Project - -任何包含文件 "project.yaml" 的文件夹都将被视为一个 Project,"project.yaml" 用于描述此 Project 的元数据,如 "name" 和 "tenant" 等。项目必须具有明确的业务语义,用户可以将应用程序或运维场景映射到项目。 - -### Stack - -与Project一样,包含文件 "stack.yaml" 的任何文件夹都将被视为一个 Stack,"stack.yaml" 用于描述此 Stack 的元数据。Stack 是一组 KCL 文件,表示可以单独配置和部署的最小操作单元,它通常代表 CI/CD 过程中的不同阶段。 - -### Project 与 Stack 之间的关系 - -一个 Project 包含一个或多个 Stack,Stack 必须属于且只能属于一个 Project。用户可以根据自己的需要解释 Project 和 Stack 的含义,并灵活组织 Konfig 结构。根据我们的经验,我们提供以下示例作为最佳实践: - -```bash -├── README.md # Project 介绍文件 -├── base # 各环境通用配置 -│ └── base.k # 通用 KCL 配置 -├── dev # 环境特有配置 -│ ├── ci-test # 测试目录 -│ │ ├── settings.yaml # 测试数据 -│ │ └── stdout.golden.yaml # 测试期望结果 -│ ├── kcl.yaml # 多文件编译配置,是 KCL 编译的入口 -│ ├── main.k # 当前环境 KCL 配置 -│ └── stack.yaml # Stack 配置文件 -└── project.yaml # Project 配置文件 -``` - -Project 通常表示一个应用程序,Stack 表示该应用程序的不同环境的配置,例如 dev、pre 和 prod 等。通用配置可以存储在该 Project 下的 "base" 目录中。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-konfig/3-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-konfig/3-quick-start.md deleted file mode 100644 index 92c9849d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-konfig/3-quick-start.md +++ /dev/null @@ -1,198 +0,0 @@ ---- -id: guide -sidebar_label: 快速开始 ---- - -# 简介 - -本篇指南向你展示,如何使用 KCL 语言与其相对应的 CLI 工具,完成一个运行在 Kubernetes 中的 Long-Running 应用的部署,我们将组织配置的单位叫做应用(Application),描述应用部署和运维细节的配置集合叫做应用服务(Server),它本质上是通过 KCL 定义的运维模型。 - -要将一个运行在 Kubernetes 中的应用完全部署起来,一般需要下发多个 Kubernetes 资源,本次演示的样例涉及以下 Kubernetes 资源: - -- 命名空间(Namespace) -- 无状态工作负载(Deployment) -- 服务(Service) - -> 不清楚相关概念的,可以前往 Kubernetes 官方网站,查看相关说明: - -- [Learn Kubernetes Basics](https://kubernetes.io/docs/tutorials/kubernetes-basics/) -- [Namespace](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/) -- [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) -- [Service](https://kubernetes.io/docs/concepts/services-networking/service/) - -## 准备工作 - -在开始之前,我们需要做以下准备工作: - -1. 安装 KCL, 详情信息请参阅[下载和安装](/docs/user_docs/getting-started/install)。 - -2. 下载开源 Konfig 大库,仓库地址: [https://github.com/KusionStack/konfig.git](https://github.com/KusionStack/konfig.git) - -```shell -git clone https://github.com/KusionStack/konfig.git && cd konfig -``` - -## 快速开始 - -### 1. 配置编译 - -Konfig 的编程语言是 KCL,不是 Kubernetes 认识的 JSON/YAML,因此还需要编译得到最终输出。 - -进入到项目的 Stack 目录(`appops/nginx-example/dev`)并执行编译: - -```bash -cd appops/nginx-example/dev && kcl -Y kcl.yaml -D __konfig_output_format__=raw -``` - -可以获得如下 YAML 输出: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-exampledev - namespace: nginx-example -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - template: - metadata: - labels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - spec: - containers: - - image: nginx:1.7.8 - name: main - ports: - - containerPort: 80 - protocol: TCP - resources: - limits: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi - requests: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi ---- -apiVersion: v1 -kind: Namespace -metadata: - name: nginx-example ---- -apiVersion: v1 -kind: Service -metadata: - name: nginx-example - namespace: nginx-example -spec: - ports: - - nodePort: 30201 - port: 80 - targetPort: 80 - selector: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - type: NodePort -``` - -完成编译,可以看到 3 个资源: - -- 一个 name 为 nginx-exampledev 的 Deployment -- 一个 name 为 nginx-example 的 Namespace -- 一个 name 为 nginx-example 的 Service - -以上就完成了配置生效,后续可以使用 `kubectl apply` 等命令下发并检查资源的实际状态,本文不在赘述。 - -### 2. 配置修改 - -Server 模型中的 image 属性用于声明应用的业务容器镜像,我们可以修改 base/main.k 中的 image 的值进行镜像修改或升级: - -```diff -14c14 -< image = "nginx:1.7.8" ---- -> image = "nginx:latest" -``` - -重新编译配置代码可以获得修改后的 YAML 输出: - -```shell -kcl -Y kcl.yaml -D __konfig_output_format__=raw -``` - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-exampledev - namespace: nginx-example -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - template: - metadata: - labels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - spec: - containers: - - image: nginx:latest - name: main - ports: - - containerPort: 80 - protocol: TCP - resources: - limits: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi - requests: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi ---- -apiVersion: v1 -kind: Namespace -metadata: - name: nginx-example ---- -apiVersion: v1 -kind: Service -metadata: - name: nginx-example - namespace: nginx-example -spec: - ports: - - nodePort: 30201 - port: 80 - targetPort: 80 - selector: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - type: NodePort -``` - -## 小结 - -本文主要介绍了如何使用 KCL 语言与其相对应的 Konfig 库,完成一个运行在 Kubernetes 中的 Long-Running 应用的部署。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-konfig/4-best-practice.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-konfig/4-best-practice.md deleted file mode 100644 index c4bf4b08..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-konfig/4-best-practice.md +++ /dev/null @@ -1,271 +0,0 @@ ---- -id: practice -sidebar_label: 最佳实践 ---- - -# 最佳实践 - -本文档旨在讲解新的业务模型接入 Konfig 大库以及 KCL 代码模型设计与编写的最佳实践,新业务模型一般采用前-后端模型分离的最佳实践进行设计与抽象,区分前端模型和后端模型的直接目的是将「用户界面」和「模型实现」进行分离,实现用户友好的简单的配置界面以及自动化配置增删改查接口。 - -## 工作流程 - -![](/img/docs/user_docs/guides/konfig/workflow.png) - -1. 首先使用 KCL OpenAPI 工具生成下游所需配置的 KCL 模型代码,对于 Kubernetes 模型;可以根据 CRD 或者 Swagger Model 生成,对于其他场景,可以使用 Terraform provider schema、Java Class 或者 Go Struct 生成相应 KCL Schema (建设中),作为后端模型并存放在 "基础配置代码" 中; -2. 使用 KCL 开发工具(包括 KCL 编译器、KCL format,doc,lint,test 等工具和 IDE 插件等),根据业务语义抽象前端模型; -3. 依据 Project & Stack 方式在 Konfig 仓库中组织用户侧配置代码(主要是对前端模型的实例化),Konfig 会自动根据 project.yaml 和 stack.yaml 文件进行测试; -4. 最后编译 KCL 代码生成 YAML,通过测试后,利用 CI/CD 流程完成配置的 diff 与分发。 - -## 模型结构 - -正如 web 应用会提供友好的用户界面,而在应用的后端对用户输入进行进一步推演得到最终落库的数据,类似地,使用 KCL 进行模型设计时同样遵循前后端分离的逻辑。此外当下游所需的数据内容发生变化时,我们仅需修改用户配置数据到后端模型的渲染/逻辑即可,从而避免了大规模修改用户配置的情况。以应用服务的 sidecar 配置为例,直接暴露给用户的只有 `user_sidecar_feature_gates`,而最终交给下游处理的数据中,则应是把 `user_sidecar_feature_gates` 作为 `sidecars` 配置的一部分包装起来的结果。比如如下代码: - -```python -# 用户可配的: -user_sidecar_feature_gates: str - -# 下游能处理的: -sidecars = [ - { - name = "sidecar_name" # sidecars 参数的额外模版参数,用户不需要进行配置 - feature_gates = user_sidecar_feature_gates - } -] -``` - -## Konfig 建模的一些最佳实践 - -### 使用一个属性代替配置模板 - -对于一些后端模型所需要填写的配置字段往往是大而全的设计,需要用户主动输入较为复杂的配置模版,并且不同用户对于该字段的填写内容基本一致,比如在下面示出的超卖逻辑的配置就需要用户填写大量的模板数据,心智成本较高。 - -对于此类常用复杂的模板一个简单的最佳实践是在前端模型中抽象为一个简单的 bool 类型的变量 overQuota,让用户做选择题而不是填空题,比如当 overQuota 变量为 True 时,后端模型才会渲染这个复杂逻辑。 - -- 前端模型属性 `overQuota` - -```python -overQuota: bool -``` - -- 后端模型 YAML 输出 - -```yaml -spec: - template: - spec: - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: k8s/is-over-quota - operator: In - values: - - "true" -``` - -此外也可以根据具体的业务场景设计不同的模版名称来填空,比如如下所示的代码设计一个属性 template 来辅助用户做模版的选择而不是直接填入模板内容。合法的 template 值可以为 "success_ratio" 或者 "service_cost", 当后端模型扩展更多的模版时,前端代码无需作出任何修改,仅需在后端模型中适配相应模板逻辑即可。 - -```python -schema SLI: - template: str = "success_ratio" -``` - -此外,尽量不采用复杂的结构直接作为前端模型属性,避免用户使用该模型时需要借助过多的 KCL 语法特性(比如解包、循环等特性)或者书写很多临时变量完成该结构的实例化。 - -### 使用字面值类型和联合类型 - -在上述小节提到了可以使用一个字符串属性表示不同的模板名称,更进一步地是可以使用字面值类型表述 template 可选的内容,比如可以进行如下改进。 - -```python -schema SLI: - template: "success_ratio" | "service_cost" = "success_ratio" -``` - -其中 template 的类型为两个字符串类型的联合,表示 template 只能为 "success_ratio" 或者 "service_cost",当用户填写了其他字符串的值时,KCL 编译器会进行报错。 - -除了对字面值类型使用联合类型外,KCL 还支持对复杂类型如 schema 类型的联合。对于这种后端 oneof 配置的支持,KCL 内置了复合结构的联合类型进行支持。比如我们可以针对多种种场景定义自己的 SLI 前端类型:CustomSliDataSource,PQLSLIDataSource 和 StackSLIDataSource。 - -```python -schema CustomSLIDataSource: - customPluginUrl: str - -schema PQLSLIDataSource: - total?: str - error?: str - success?: str - cost?: str - count?: str - -schema StackSLIDataSource: - stack: str - groupBy?: str - metric?: str - -# Simplify type definitions using type aliases -type DataSource = CustomSLIDataSource | PQLSLIDataSource | StackSLIDataSource - -schema DataConfiguration: - sources: {str: DataSource} -``` - -这样前端模型设计的好处是编译器可以静态地检查出用户书写的类型只能是某一种类型,如果直接使用后端模型无法从模型上直接获得不同类型 type 与需要填写字段的映射关系。 - -此外,前端模型的整体设计上也应该考虑横向扩展性,尽可能地采用联合类型,充分利用代码化的优势,避免对接不同后端或者后端模型发生改变时带来不必要的大量代码前端代码与用户代码重构与修改。此外,对于其他 GPL 语言中常用的工厂模式,在 KCL 中也可以使用联合类型代替,比如想要根据某个字符串内容获得某个类型的构造函数,可以直接使用联合类型进行优化。 - -KCL 中书写工厂模式 - -```python -schema DataA: - id?: int = 1 - value?: str = "value" - -schema DataB: - name?: str = "DataB" - -_dataFactory: {str:} = { - DataA = DataA - DataB = DataB -} -dataA = _dataFactory["DataA"]() -dataB = _dataFactory["DataB"]() -``` - -使用联合类型替换工厂模式 - -```python -schema DataA: - id?: int = 1 - value?: str = "value" - -schema DataB: - name?: str = "DataB" - -# 直接使用联合类型即可 -dataA: DataA | DataB = DataA() -dataB: DataA | DataB = DataB() -``` - -### 列表/数组属性字典化 - -为了便于作配置的原地修改或者程序自动化查询修改,尽量将列表/数组属性定义为字典类型方便索引,因为在大部分配置场景对于复杂结构的列表类型,列表的索引 0, 1, 2, ..., n 不具备任何业务含义,列表中元素的顺序对该列表配置无任何影响,此时采用字典类型而不是列表类型更方便数据的查询与修改。首先以一个简单例子举例: - -```python -schema Person: - name: str - age: int - -schema House: - persons: [Person] - -house = House { - persons = [ - Person { - name = "Alice" - age = 18 - } - Person { - name = "Bob" - age = 10 - } - ] -} -``` - -比如在上述例子中,想要查询 name 为 "Alice" 的年龄 age, 就需要在 house.persons 这个列表中作遍历才能很查询到 Alice 的 age。而将 persons 定义为如下代码所示的字典,不仅从代码上看起来更加简洁,并且可以通过 house.persons.Alice.age 直接获得 Alice 的 age,并且整个配置的信息完整且无冗余信息。 - -```python -schema Person: - age: int - -schema House: - persons: {str: Person} # 将 persons 定义为字典而不是数组 - -house = House { - persons = { - Alice = Person { age = 18 } - Bob = Person { age = 10 } - } -} -``` - -### 为模型书写校验表达式 - -对于前端模型,往往需要对用户填写的字段进行校验,此时可以使用 KCL 的 check 表达式与 KCL 的内置函数/语法/系统库进行配合对字段进行校验。对于前端模型的校验尽可能直接书写在前端模型的定义中进行校验前置,避免错误传递到后端模型中发生意想不到的错误。 - -使用 all/any 表达式与 check 表达式进行校验 - -```python -import regex - -schema ConfigMap: - name: str - data: {str:str} - configMounts?: [ConfigMount] - - check: - all k in data { - regex.match(k, r"[A-Za-z0-9_.-]*") - }, "a valid config key must consist of alphanumeric characters, '-', '_' or '.'" - -schema ConfigMount: - containerName: str - mountPath: str - subPath?: str - - check: - ":" not in mountPath, "mount path must not contain ':'" -``` - -### 使用数值单位类型 - -KCL 中带单位的数字具有一个内置的类型 units.NumberMultiplier, 不允许进行任意四则运算。 - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -x0: NumberMultiplier = 1M # Ok -x1: NumberMultiplier = x0 # Ok -x2 = x0 + x1 # Error: unsupported operand type(s) for +: 'number_multiplier(1M)' and 'number_multiplier(1M)' -``` - -可以使用 `int()/float()` 函数和 `str()` 函数将数字单位类型转换为整数类型或者字符串类型,产生的字符串保留原有数字单位类型的单位。 - -```python -a: int = int(1Ki) # 1024 -b: str = str(1Mi) # "1Mi" -``` - -对于在 Konfig 中的 Kubernetes Resource 资源相关的定义均可使用数值单位类型进行书写 - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -schema Resource: - cpu?: NumberMultiplier | int = 1 - memory?: NumberMultiplier = 1024Mi - disk?: NumberMultiplier = 10Gi - epchygontee?: int -``` - -### 前端模型实例的自动化修改 - -在 KCL,可以通过命令行和 API 界面实现对前端模型实例的自动化修改,比如想要修改某个应用(Konfig Stack Path: appops/nginx-example/dev)配置的镜像内容,可以直接执行如下指令修改镜像 - -```python -kcl -Y kcl.yaml ci-test/settings.yaml -o ci-test/stdout.golden.yaml -d -O :appConfiguration.image=\"test-image-v1\" -``` - -更多与自动化相关的使用文档请参考 [自动化](/docs/user_docs/guides/automation) 一节 - -### 为模型添加代码注释 - -为便于用户理解以及模型文档自动生成,需要对定义的模型编写注释,注释内容一般包括模型的解释,模型字段的解释,类型,默认值,使用样例等。详细的 KCL Schema 代码注释编写规范以及模型文档自动生成可以参考 [KCL 文档规范](/docs/tools/cli/kcl/docgen) - -## 后端模型 - -后端模型是「模型实现」,主要包括将前端模型映射为后端模型的逻辑代码。当编写完成前端模型后,我们可以使用前端模型 Schema 新建前端模型的实例 instance 并编写相应的后端映射/渲染代码将这些前端 instance 转换为后端模型,并且利用 KCL 多文件编译和 `Schema.instances()` 函数可以做到前端代码和后端代码的高度解耦,用户仅需关心前端的配置而不感知模型复杂的校验、逻辑判断等代码。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-kusion/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-kusion/index.md deleted file mode 100644 index 2906ab83..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-kusion/index.md +++ /dev/null @@ -1,15 +0,0 @@ -# KusionStack - -**KusionStack 是开源的云原生可编程技术栈!** - -KusionStack 是一个可编程、高灵活性的应用交付及运维技术栈,灵感源于融合(Fusion)一词,旨在帮助企业构建的应用运维配置管理平面及 DevOps 生态。 - -1. 融合**专有云**,**混合云**,**多云**混合场景 -2. 融合以**云原生技术**为主,同时采用**多种平台技术**的混合平台技术选型 -3. 融合**多项目**、**多团队**、**多角色**、**多租户**、**多环境**的企业级诉求 - -基于 Platform as Code (平台服务即代码)理念,研发者可以快速收敛围绕**应用运维生命周期**的全量配置定义,面向**混合技术体系及云环境**,完成从应用运维研发到上线的**端到端工作流程**,真正做到**一处编写,随处交付**。 - -![](/img/docs/user_docs/intro/kusion-stack-1.png) - -更多文档请参考: [https://kusionstack.io/](https://kusionstack.io/) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/support/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/support/_category_.json deleted file mode 100644 index d670513b..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/support/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "常见问答", - "position": 6 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/support/faq-cli.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/support/faq-cli.md deleted file mode 100644 index 035c021c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/support/faq-cli.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -sidebar_position: 4 ---- - -# 命令行工具 - -## 1. Konfig 大库应用目录下的 settings.yaml 文件的作用是什么? - -KCL 中 settings.yaml 文件表示 KCL 命令行工具的配置参数文件,可以将编译的配置放入其中进行调用比如需要编译的文件,需要输入的 option 动态参数 `-d`,是否需要忽略掉空值 None `-n` 等配置。 - -比如对于如下的命令行运行参数 - -```shell -kcl main.k -D key=value -n -r -``` - -就可以使用如下的命令行参数和 settings.yaml 配置文件代替 - -```shell -kcl -Y settings.yaml -``` - -settings.yaml - -```yaml -kcl_cli_configs: - files: - - main.k - disable_none: true - strict_range_check: true -kcl_options: - - key: key - value: value -``` - -- `kcl_cli_configs` 表示可以配置的编译参数,`file` 用于配置编译的 KCL 文件,`disable_none` 表示是否使用 `-n` 参数,`strict_range_check` 表示是否使用 `-r` 参数。 -- `kcl_options` 表示可以配置的动态参数,`key` 表示动态参数的名称,`value` 表示动态参数的值 - -注意:settings.yaml 的文件名称可替换,只要其中的配置结构满足规定即可 - -## 2. 如何传入动态参数?如何在代码中获取命令行传入的动态参数? - -KCL 支持多种方式传入动态参数 - -- `-D`: 使用 KCL 命令行的-D 参数可以直接传入动态参数,支持基本数据类型 str/int/float/bool, 以及结构数据类型 list/dict - -```shell -kcl main.k -D env-type=TEST -D deploy-topology='[{"cluster":"my-cluster","idc":"my-idc","replicas":2,"workspace":"my-idc","zone":"my-zone"}]' -``` - -- `-Y`: 使用 KCL 命令行的-Y 参数可以间接通过配置文件传入动态参数: - -```yaml -kcl_options: - - key: env-type - value: TEST - - key: deploy-topology - value: - - cluster: my-cluster - idc: my-idc - replicas: 2 - workspace: my-workspace - zone: my-zone -``` - -在代码中使用内置的 option 函数获取即可 - -```python -env = option("env-type") -deploy_topology = option("deploy-topology") -``` - -输出 YAML - -```yaml -env: TEST -deploy_topology: - - cluster: my-cluster - idc: my-idc - replicas: 2 - workspace: my-workspace - zone: my-zone -``` - -## 3. 如何使用 kcl 的多文件编译特性? - -- 使用 KCL 命令行工具直接书写多文件编译 - -```shell -kcl file1.k file2.k file3.k -``` - -- 在配置文件中配置并配合 KCL 命令行工具参数 `-Y` 使用 - -settings.yaml - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - - file3.k -``` - -```shell -kcl -Y settings.yaml -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/support/faq-install.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/support/faq-install.md deleted file mode 100644 index 1c98f224..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/support/faq-install.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -sidebar_position: 5 ---- - -# 安装问题 - -## MacOS 提示无法打开 "kcl",因为 Apple 无法检查其是否包含恶意软件 - -MacOS 提示无法打开 "kcl",因为 Apple 无法检查其是否包含恶意软件。这个错误是因为 macOS 操作系统中的 Gatekeeper 安全功能阻止了应用程序的运行。要解决此问题,请按照以下步骤操作: - -打开"系统偏好设置"并点击"安全性与隐私"。 在"通用"选项卡中,您将看到一个消息:"kcl" 已被阻止。单击"仍要打开"。 或者,你可以单击"打开任何方式"以打开你的应用程序。(可能需要使用管理员权限来打开应用程序。) - -如果不想在每次打开应用程序时都执行这些步骤,则可以的应用程序添加到白名单中,以便在不受阻止的情况下运行。要将您的应用程序添加到白名单中,请执行以下操作: - -打开终端并输入以下命令: - -```shell -xattr -rd com.apple.quarantine /path/to/kcl -``` - -其中,/path/to/kcl 是 kcl 应用程序的完整路径。运行命令后,应用程序将被添加到白名单中,Gatekeeper 将不再阻止其运行。 - -## 在 Windows/Linux/MacOS 平台上抱 program not found 或者 run linker failed 错误 - -请确保如下依赖在您的 PATH 中 - -- MacOS: `clang` -- Linux: `gcc` -- Windows: `cl.exe` (可以通过安装 MSVC 获得) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/support/faq-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/support/faq-kcl.md deleted file mode 100644 index 8330dfd6..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/support/faq-kcl.md +++ /dev/null @@ -1,2355 +0,0 @@ ---- -sidebar_position: 2 ---- - -# KCL 语法 - -## 1. 如何用 KCL 写一个简单的 key-value 对配置 - -创建一个名为 `config.k` 的文件 - -```python -cpu = 256 -memory = 512 -image = "nginx:1.14.2" -service = "my-service" -``` - -上述 KCL 代码中,定义了 4 个变量 `cpu` 和 `memory` 被声明为整数类型,并且它们的值分别为 `256` 和 `512`,而 `image` 和 `service` 是字符串类型,它们的值分别为 `image` 和 `service` - -使用如下命令可以将上述 KCL 文件编译为 YAML 进行输出 - -``` -kcl config.k -``` - -得到的 YAML 输出为: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -如果想要输出到文件,可以使用 `-o|--output` 参数: - -``` -kcl config.k -o config.yaml -``` - -## 2. KCL 中有哪些基本的数据类型? - -KCL 目前的基本数值类型和值包含: - -- 整数类型 `int` - - 举例: 十进制正整数 `1`, 十进制负整数 `-1`, 十六进制整数 `0x10`, 八进制整数 `0o10`, 二进制整数 `0b10` -- 浮点数类型 `float` - - 举例: 正浮点数 `1.10`, `1.0`, 负浮点数 `-35.59`, `-90.`, 科学记数法浮点数 `32.3e+18`, `70.2E-12` -- 布尔类型 `bool` - - 举例: 真值 `True`, 假值 `False` -- 字符串类型 `str` - 使用引号 `'`, `"` 标记 - - 举例: 双引号字符串 `"string"`, `"""string"""`, 单引号字符串 `'string'`, `'''string'''` -- 列表类型 `list` - 使用 `[`, `]` 标记 - - 举例: 空列表 `[]`, 字符串列表 `["string1", "string2", "string3"]` -- 字典类型 `dict` - 使用 `{`, `}` 标记 - - 举例: 空字典 `{}`, 键值均为字符串类型的字典 `{"key1": "value1", "key2": "value2"}` -- 结构类型 `schema` - 使用关键字 `schema` 定义,并使用相应的 schema 名称进行实例化 -- 空值类型 `None` - 用于表示一个变量的值为空,与输出 YAML 的 `null` 值对应 -- 未定义值类型 `Undefined` - 用于表示一个变量未被赋值,值为 `Undefined` 的变量不会被输出到 YAML 中 - -```python -schema Person: - name: str - age: int - -alice = Person { - name = "Alice" - age = 18 -} -bob = Person { - name = "Bob" - age = 10 -} -``` - -注意: 所有 KCL 类型的变量均可赋值为空值 `None` 和未定义的值 `Undefined` - -## 3. 有些 KCL 变量名带 `_` 下划线前缀表示什么?和不带 `_` 下划线前缀的区别是什么?分别适合什么场景下使用? - -KCL 中带下划线前缀的变量表示一个**隐藏**的,**可变**的变量,**隐藏**表示带下划线前缀的变量不会被输出到 YAML 当中,包括包级别的下划线前缀变量和 schema 当中的下划线前缀变量。**可变**表示带下划线前缀的变量可被多次重复赋值,不带下划线前缀的变量被赋值后不可变。 - -带 `_` 下划线前缀的变量与不带 `_` 下划线前缀变量的区别是: 不带 `_` 下划线前缀变量默认是导出到 YAML 当中的,并且具有强不可变性;带 `_` 下划线前缀变量是不导出的,可变的。 - -```python -name = 'Foo' # 导出变量,不可变变量 -name = 'Bar' # 错误:导出变量只能设置一次 -``` - -```python -_name = 'Foo' # 隐藏变量,可变变量 -_name = 'Bar' - -schema Person: - _name: str # hidden and mutable -``` - -## 4. 如何向 dict 中添加元素? - -可以使用 union 运算符 `|`, 或者 dict 解包运算符 `**` 来向 dict 中添加一个元素,并且可以使用 `in`,`not in` 等关键字判断 dict 变量当中是否包含某一个键值 - -```python -_left = {key: {key1 = "value1"}, intKey = 1} # 注意使用 = 表示覆盖 -_right = {key: {key2 = "value2"}, intKey = 2} -dataUnion = _left | _right # {"key": {"key1": "value1", "key2": "value2"}, "intKey": 2} -dataUnpack = {**_left, **_right} # {"key": {"key1": "value1", "key2": "value2"}, "intKey": 2} -``` - -输出 YAML 为: - -```yaml -dataUnion: - key: - key1: value1 - key2: value2 - intKey: 2 -dataUnpack: - key: - key1: value1 - key2: value2 - intKey: 2 -``` - -此外还可以使用 `字符串插值` 或者字符串 `format` 成员函数特性向 kcl dict 添加变量键值对 - -```python -dictKey1 = "key1" -dictKey2 = "key2" -data = { - "${dictKey1}" = "value1" - "{}".format(dictKey2) = "value2" -} -``` - -输出 YAML 为: - -```yaml -dictKey1: key1 -dictKey2: key2 -data: - key1: value1 - key2: value2 -``` - -## 5. 如何修改 dict 中的元素? - -我们可以使用 union 运算符 `|`, 或者解包运算符 `**` 修改 dict 当中的元素 - -```python -_data = {key = "value"} # {"key": "value"} -_data = _data | {key = "override_value1"} # {"key": "override_value1"} -_data = {**_data, **{key = "override_value2"}} # {"key": "override_value2"} -``` - -如果想要删除 dict 中某个键为 `key` 的值,可以使用解包运算符 `**{key = Undefined}` 或者合并运算符 `| {key = Undefined}` 进行覆盖,覆盖后 key 的值为 Undefined,不会进行 YAML 输出。 - -## 6. 如何向 list 中添加元素? - -在 list 中添加元素有两种方式: - -- 使用 `+`, `+=` 和 slice 切片连接组装 list 变量达到向 list 中添加元素的目的 - -```python -_args = ["a", "b", "c"] -_args += ["end"] # 在list尾部添加元素"end", ["a", "b", "c", "end"] -_args = _args[:2] + ["x"] + _args[2:] # 在list索引为2的地方插入元素"x", ["a", "b", "x", "c", "end"] -_args = ["start"] + _args # 在list头部添加元素"start", ["start", "a", "b", "x", "c", "end"] -``` - -- 使用 `*` 解包运算符连接合并 list - -```python -_args = ["a", "b", "c"] -_args = [*_args, "end"] # 在list尾部添加元素"end", ["a", "b", "c", "end"] -_args = ["start", *_args] # 在list头部添加元素"start", ["start", "a", "b", "c", "end"] -``` - -注意:当接连的变量为 `None/Undefined` 时,使用 `+` 可能会发生错误,这时使用 list 解包运算符 `*` 或者使用 `or` 运算符取 list 的默认值可以避免空值判断 - -```python -data1 = [1, 2, 3] -data2 = None -data3 = [*data1, *data2] # Right [1, 2, 3] -data4 = data1 + data2 or [] # Right [1, 2, 3], 使用 or 取 data2 的默认值为 [], 当 data2 为 None/Undefined 时,取空列表 [] 进行计算 -data5 = data1 + data2 # Error: can only concatenate list (not "NoneType") to list -``` - -## 7. 如何修改/删除 list 中的元素? - -修改 list 中的元素分为两种方式: - -- 直接修改 list 某个索引处的值,使用 slice 切片 - -```python -_index = 1 -_args = ["a", "b", "c"] -_args = _args[:index] + ["x"] + _args[index+1:] # 修改list索引为1的元素为"x", ["a", "x", "c"] -``` - -- 根据某个条件修改 list 当中的元素,使用 list comprehension 列表推导式 - -```python -_args = ["a", "b", "c"] -_args = ["x" if a == "b" else a for a in _args] # 将list当中值为"b"的值都修改为"x", ["a", "x", "c"] -``` - -删除 list 中的元素分为两种方式: - -- 使用 list for 推导表达式中 if 过滤条件 -- 使用 filter 表达式对 list 进行元素过滤 - -比如想要删除一个列表 `[1, 2, 3, 4, 5]` 中大于 2 的数字,则在 KCL 中可以写为: - -```python -originList = [1, 2, 3, 4, 5] -oneWayDeleteListItem = [item for item in originList if item <= 2] -anotherWayDeleteListItem = filter item in originList { - item <= 2 -} -``` - -输出如下结果 - -```yaml -originList: - - 1 - - 2 - - 3 - - 4 - - 5 -oneWayDeleteListItem: - - 1 - - 2 -anotherWayDeleteListItem: - - 1 - - 2 -``` - -## 8. 怎样写 for 循环?怎样理解和使用 list comprehension 列表推导式 和 dict comprehension 字典推导式 ? - -KCL 目前仅支持函数式/声明式的推导式 for 循环方式,可以按照如下方式遍历 dict 和 list 变量: - -list 推导式具体形式为(其中推导式两边使用方括号 `[]`): - -```txt -[expression for expr in sequence1 - if condition1 - for expr2 in sequence2 - if condition2 - for expr3 in sequence3 ... - if condition3 - for exprN in sequenceN - if conditionN] -``` - -dict 推导式具体形式为(其中推导式两边使用花括号 `{}`): - -```txt -{expression for expr in sequence1 - if condition1 - for expr2 in sequence2 - if condition2 - for expr3 in sequence3 ... - if condition3 - for exprN in sequenceN - if conditionN} -``` - -上述推导式中的 `if` 表示过滤条件,满足条件的表达式 `expr` 才会生成到新的 list 或 dict 中 - -list 推导式举例: - -```python -_listData = [1, 2, 3, 4, 5, 6] -_listData = [l * 2 for l in _listData] # _listData中所有元素都乘以2,[2, 4, 6, 8, 10, 12] -_listData = [l for l in _listData if l % 4 == 0] # 筛选出_listData中可以被4整除的所有元素,[4, 8, 12] -_listData = [l + 100 if l % 8 == 0 else l for l in _listData] # 遍历_listData, 当其中的元素可以被8整除时,将该元素加100,否则保持不变, [4, 108, 12] -``` - -注意上述代码中第 3 行和第 4 行两个 `if` 的区别: - -- 第一个 `if` 表示 list 变量 `_listData` 本身的推导式过滤条件,后不能跟 `else`,满足该过滤条件的元素会继续放在该列表中,不满足条件的元素被剔除,有可能会使列表长度发生变化 -- 第二个 `if` 表示 list 迭代变量 `l` 的选择条件,表示 `if-else` 三元表达式,后必须跟 `else`,不论是否满足该条件,产生的元素仍然在该列表中,列表长度不变 - -dict 推导式举例: - -```python -_dictData = {key1 = "value1", key2 = "value2"} -_dictData = {k = _dictData[k] for k in _dictData if k == "key1" and _dictData[k] == "value1"} # 将_dictData中key为"key1", value为"value1"的元素筛选出来, {"key1": "value1"} -``` - -使用推导式获得 dict 所有 key: - -```python -dictData = {key1 = "value1", key2 = "value2"} -dictDataKeys = [k for k in _dictData] # ["key1", "key2"] -``` - -使用推导式对 dict 按照 key 的字典序升序进行排序: - -```python -dictData = {key3 = "value3", key2 = "value2", key1 = "value1"} # {'key3': 'value3', 'key2': 'value2', 'key1': 'value1'} -dictSortedData = {k = dictData[k] for k in sorted(dictData)} # {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'} -``` - -多级推导式举例: - -```python -array1 = [1, 2, 3] -array2 = [4, 5, 6] -data = [a1 + a2 for a1 in array1 for a2 in array2] # [5, 6, 7, 6, 7, 8, 7, 8, 9] len(data) == len(array1) * len(array2) -``` - -双变量循环(for 推导表达式支持 list 的索引迭代以及 dict 的 value 迭代,可以简化 list/dict 迭代过程代码书写): - -- list - -```python -data = [1000, 2000, 3000] -# 单变量循环 -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# 双变量循环 -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# 使用_忽略循环变量 -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -- dict - -```python -data = {key1 = "value1", key2 = "value2"} -# 单变量循环 -dataKeys1 = [k for k in data] # ["key1", "key2"] -dataValues1 = [data[k] for k in data] # ["value1", "value2"] -# 双变量循环 -dataKeys2 = [k for k, v in data] # ["key1", "key2"] -dataValues2 = [v for k, v in data] # ["value1", "value2"] -dataFilter = {k = v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# 使用_忽略循环变量 -dataKeys3 = [k for k, _ in data] # ["key1", "key2"] -dataValues3 = [v for _, v in data] # ["value1", "value2"] -``` - -## 9. 怎样写 if 条件语句? - -KCL 支持两种方式书写 if 条件语句: - -- if-elif-else 块语句,其中 elif 和 else 块均可省略,并且 elif 块可以使用多次 - -```python -success = True -_result = "failed" -if success: - _result = "success" -``` - -```python -success = True -if success: - _result = "success" -else: - _result = "failed" -``` - -```python -_result = 0 -if condition == "one": - _result = 1 -elif condition == "two": - _result = 2 -elif condition == "three": - _result = 3 -else: - _result = 4 -``` - -- 条件表达式 ` if else `, 类似于 C 语言当中的 ` ? : ` 三元表达式 - -```python -success = True -_result = "success" if success else "failed" -``` - -注意:在书写 if-elif-else 块语句时注意书写 if 条件后的冒号 `:` 以及保持缩进的统一 - -除此之外,还可以在 list 或者 dict 结构中直接书写条件表达式(不同的是,在结构中书写的 if 表达式中需要书写的值而不是语句): - -- list - -```python -env = "prod" -data = [ - "env_value" - ":" - if env == "prod": - "prod" # 书写需要添加到 data 中的值,而不是语句 - else: - "other_prod" -] # ["env_value", ":", "prod"] -``` - -- dict - -```python -env = "prod" -config = { - if env == "prod": - MY_PROD_ENV = "prod_value" # 书写需要添加到 config 中的键-值对,而不是语句 - else: - OTHER_ENV = "other_value" -} # {"MY_PROD_ENV": "prod_value"} -``` - -## 10. 怎样表达 "与" "或" "非" 等逻辑运算? - -在 KCL 中,使用 `and` 表示"逻辑与", 使用 `or` 表示"逻辑或", 使用 `not` 表示"非", 与 C 语言当中的 `&&`, `||` 和 `~` 语义一致; - -```python -done = True -col == 0 -if done and (col == 0 or col == 3): - ok = 1 -``` - -对于整数的"按位与", "按位或"和"按位异或",在 KCL 中使用 `&`, `|` 和 `^` 运算符表示, 与 C 语言当中的 `&`, `|` 和 `^` 语义一致; - -```python -value = 0x22 -bitmask = 0x0f - -assert (value & bitmask) == 0x02 -assert (value & ~bitmask) == 0x20 -assert (value | bitmask) == 0x2f -assert (value ^ bitmask) == 0x2d -``` - -"逻辑或" `or` 的妙用:当需要书写诸如 `A if A else B` 类似的模式时,可以使用 `A or B` 进行简化,比如如下代码: - -```python -value = [0] -default = [1] -x0 = value if value else default -x1 = value or default # 使用 value or default 代替 value if value else default -``` - -## 11. 如何判断变量是否为 None/Undefined、字符串/dict/list 是否为空? - -请注意,在 if 表达式的条件判断中,`False`、`None`、`Undefined`、数字 `0`、空列表 `[]`、空字典 `{}` 和空字符串 `""`, `''`, `""""""`, `''''''` 都被视为值为 `假` 的表达式。 - -比如判断一个字符串变量 `strData` 既不为 `None/Undefined` 也不为空字符串时(字符串长度大于 0),就可以简单的使用如下表达式: - -```python -strData = "value" -if strData: - isEmptyStr = False -``` - -空字典和空列表判断举例: - -```python -_emptyList = [] -_emptyDict = {} -isEmptyList = False if _emptyList else True -isEmptyDict = False if _emptyDict else True -``` - -YAML 输出为: - -```yaml -isEmptyList: true -isEmptyDict: true -``` - -或者使用布尔函数 `bool` 进行判断 - -```python -_emptyList = [] -_emptyDict = {} -isEmptyList = bool(_emptyList) -isEmptyDict = bool(_emptyDict) -``` - -## 12. 字符串怎样拼接、怎样格式化字符串、怎样检查字符串前缀、后缀?怎样替换字符串内容? - -- KCL 中可以使用 `+` 运算符连接两个字符串 - -```python -data1 = "string1" + "string2" # "string1string2" -data2 = "string1" + " " + "string2" # "string1 string2" -``` - -- KCL 中目前存在两种格式化字符串的方式: - - 字符串变量的 format 方法 `"{}".format()` - - 字符串插值 `${}` - -```python -hello = "hello" -a = "{} world".format(hello) -b = "${hello} world" -``` - -注意,如果想在 `"{}".format()` 中单独使用 `{` 字符或者 `}`, 则需要使用 `{{` 和 `}}` 分别对 `{` 和 `}` 进行转义,比如转义一个 JSON 字符串如下代码: - -```python -data = "value" -jsonData = '{{"key": "{}"}}'.format(data) -``` - -输出 YAML 为: - -```yaml -data: value -jsonData: '{"key": "value"}' -``` - -注意,如果想在 `${}` 插值字符串中单独使用 `$` 字符,则需要使用 `$$` 对 `$` 进行转义 - -```python -world = "world" -a = "hello {}".format(world) # "hello world" -b = "hello ${world}" # "hello world" -c = "$$hello ${world}$$" # "$hello world$" -c2 = "$" + "hello ${world}" + "$" # "$hello world$" -``` - -输出 YAML 为: - -```yaml -world: world -a: hello world -b: hello world -c: $hello world$ -c2: $hello world$ -``` - -- KCL 中使用字符串的 `startswith` 和 `endswith` 方法检查字符串的前缀和后缀 - -```python -data = "length" -isEndsWith = data.endswith("th") # True -isStartsWith = "length".startswith('len') # True -``` - -- KCL 中使用字符串的 replace 方法或者 regex.replace 函数替换字符串的内容 - -```python -import regex -data1 = "length".replace("len", "xxx") # 使用"xxx"替换"len", "xxxgth" -data2 = regex.replace("abc123", r"\D", "0") # 替换"abc123"中的所有非数字为"0", "000123" -``` - -其中,`r"\D"` 表示不需要使用 `\\` 转义 `\D` 中的反斜杠 `\`,多用于正则表达式字符串中 - -此外,我们可以在字符串格式化表达式中插入索引占位符或者关键字占位符用于格式化多个字符串 - -- 索引占位符 - -```python -x = '{2} {1} {0}'.format('directions', 'the', 'Read') -y = '{0} {0} {0}'.format('string') -``` - -输出为: - -```yaml -x: Read the directions -y: string string string -``` - -- 关键字占位符 - -```python -x = 'a: {a}, b: {b}, c: {c}'.format(a = 1, b = 'Two', c = 12.3) -``` - -输出为: - -```yaml -x: "a: 1, b: Two, c: 12.3" -``` - -## 13. 字符串中使用单引号和双引号的区别是什么? - -KCL 单引号和双引号字符串几乎没有区别。唯一的区别是,不需要在单引号字符串中使用 `\"` 转义双引号 `"`,不需要在双引号字符串中使用 `\'` 转义单引号引号 `'`。 - -```python -singleQuotedString = 'This is my book named "foo"' # Don’t need to escape double quotes in single quoted strings. -doubleQuotedString = "This is my book named 'foo'" # Don’t need to escape single quotes in double quoted strings. -``` - -此外在 KCL 中,使用三个单引号或者三个双引号组成的长字符串,无需在其中对单引号或者三引号进行转义 (除字符串首尾),比如如下例子: - -```python -longStrWithQuote0 = """Double quotes in long strings "(not at the beginning and end)""" -longStrWithQuote1 = '''Double quotes in long strings "(not at the beginning and end)''' -longStrWithQuote2 = """Single quotes in long strings '(not at the beginning and end)""" -longStrWithQuote3 = '''Single quotes in long strings '(not at the beginning and end)''' -``` - -输出 YAML: - -```yaml -longStrWithQuote0: Double quotes in long strings "(not at the beginning and end) -longStrWithQuote1: Double quotes in long strings "(not at the beginning and end) -longStrWithQuote2: Single quotes in long strings '(not at the beginning and end) -longStrWithQuote3: Single quotes in long strings '(not at the beginning and end) -``` - -## 14. 如何编写跨行的长字符串? - -KCL 中可以使用单引号字符串 + 换行符 `\n` 或者三引号字符串书写一个多行字符串,并且可以借助续行符 `\` 优化 KCL 字符串的形式,比如对于如下代码中的三个多行字符串变量,它们的制是相同的: - -```python -string1 = "The first line\nThe second line\nThe third line\n" -string2 = """The first line -The second line -The third line -""" -string3 = """\ -The first line -The second line -The third line -""" # 推荐使用 string3 长字符串的书写形式 -``` - -输出 YAML 为: - -```yaml -string1: | - The first line - The second line - The third line -string2: | - The first line - The second line - The third line -string3: | - The first line - The second line - The third line -``` - -## 15. 如何使用正则表达式? - -通过在 KCL 中导入正则表达式库 `import regex` 即可使用正则表达式,其中包含了如下函数: - -- **match**: 正则表达式匹配函数,根据正则表达式对输入字符串进行匹配,返回 bool 类型表示是否匹配成功 -- **split**: 正则表达式分割函数,根据正则表达式分割字符串,返回分割字串的列表 -- **replace**: 正则表达式替换函数,替换字符串中所有满足正则表达式的子串,返回被替换的字符串 -- **compile**: 正则表达式编译函数,返回 bool 类型表示是否是一个合法的正则表达式 -- **search**: 正则表达式搜索函数,搜索所有满足正则表达式的子串,返回子串的列表 - -使用举例: - -```python -import regex - -regex_source = "Apple,Google,Baidu,Xiaomi" -regex_split = regex.split(regex_source, ",") -regex_replace = regex.replace(regex_source, ",", "|") -regex_compile = regex.compile("$^") -regex_search = regex.search("aaaa", "a") -regex_find_all = regex.findall("aaaa", "a") -regex_result = regex.match("192.168.0.1", "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$") # 判断是否是一个IP字符串 -regex_result_false = regex.match("192.168.0,1", "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$") # 判断是否是一个IP字符串 -``` - -输出 YAML: - -```yaml -regex_source: Apple,Google,Baidu,Xiaomi -regex_split: - - Apple - - Google - - Baidu - - Xiaomi -regex_replace: Apple|Google|Baidu|Xiaomi -regex_compile: true -regex_search: true -regex_find_all: - - a - - a - - a - - a -regex_result: true -regex_result_false: false -``` - -对于比较长的正则表达式,还可以使用 r-string 忽略 `\` 符号的转义简化正则表达式字符串的书写: - -```python -import regex - -isIp = regex.match("192.168.0.1", r"^(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)$") # 判断是否是一个IP字符串 -``` - -更多举例: - -```python -import regex - -schema Resource: - cpu: str = "1" - memory: str = "1024Mi" - disk: str = "10Gi" - check: - regex.match(cpu, r"^([+-]?[0-9.]+)([m]*[-+]?[0-9]*)$"), "cpu must match specific regular expression" - regex.match(memory, r"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"), "memory must match specific regular expression" - regex.match(disk, r"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"), "disk must match specific regular expression" -``` - -```python -import regex - -schema Env: - name: str - value?: str - check: - len(name) <= 63, "a valid env name must be no more than 63 characters" - regex.match(name, r"[A-Za-z_][A-Za-z0-9_]*"), "a valid env name must start with alphabetic character or '_', followed by a string of alphanumeric characters or '_'" -``` - -## 16. KCL 当中的 schema 是什么含义? - -schema 是 KCL 中一种语言元素,用于定义配置数据的类型,像 C 语言中的 struct 或者 Java 中的 class 一样,在其中可以定义属性,每种属性具有相应的类型。 - -## 17. 如何声明 schema? - -KCL 中使用 schema 关键字可以定义一个结构,在其中可以申明 schema 的各个属性 - -```python -# 一个Person结构,其中具有属性字符串类型的firstName, 字符串类型的lastName, 整数类型的age -schema Person: - firstName: str - lastName: str - # age属性的默认值为0 - age: int = 0 -``` - -一个复杂例子: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels: {str:str} -``` - -在上面的代码中,`cpu` 和 `memory` 被定义为整数 int 类型;`name`,`image` 和 `service` 是字符串 str 类型; `command` 是字符串类型的列表; labels 是字典类型,其键类型和值类型均为字符串。 - -## 18. 如何为 schema 属性添加 "不可变"、"必选" 约束? - -KCL 中使用 `?` 运算符定义一个 schema 的"可选"约束,schema 属性默认都是"必选"的 - -```python -# 一个Person结构,其中具有属性字符串类型的firstName, 字符串类型的lastName, 整数类型的age -schema Person: - firstName?: str # firstName是一个可选属性,可以赋值为None/Undefined - lastName?: str # age是一个可选属性,可以赋值为None/Undefined - # age属性的默认值为0 - age: int = 18 # age是一个必选属性,不能赋值为None/Undefined,并且是一个不可变属性 - age = 10 # Error, age是一个不可变的属性 -``` - -## 19. 如何为 schema 中的属性编写校验规则? - -在 schema 定义当中可以使用 check 关键字编写 schema 属性的校验规则, 如下所示,check 代码块中的每一行都对应一个条件表达式,当满足条件时校验成功,当不满足条件时校验失败。条件表达式后可跟 `, "check error message"` 表示当校验失败时需要显示的信息 - -```python -import regex - -schema Sample: - foo: str # Required, 不能为None/Undefined, 且类型必须为str - bar: int # Required, 不能为None/Undefined, 且类型必须为int - fooList: [int] # Required, 不能为None/Undefined, 且类型必须为int列表 - color: "Red" | "Yellow" | "Blue" # Required, 字面值联合类型,且必须为"Red", "Yellow", "Blue"中的一个,枚举作用 - id?: int # Optional,可以留空,类型必须为int - - check: - bar >= 0 # bar必须大于等于0 - bar < 100 # bar必须小于100 - len(fooList) > 0 # fooList不能为None/Undefined,并且长度必须大于0 - len(fooList) < 100 # fooList不能为None/Undefined,并且长度必须小于100 - regex.match(foo, "^The.*Foo$") # regex 正则表达式匹配 - bar in range(100) # range, bar范围只能为1到99 - bar in [2, 4, 6, 8] # enum, bar只能取2, 4, 6, 8 - bar % 2 == 0 # bar必须为2的倍数 - all foo in fooList { - foo > 1 - } # fooList中的所有元素必须大于1 - any foo in fooList { - foo > 10 - } # fooList中至少有一个元素必须大于10 - abs(id) > 10 if id # check if 表达式,当 id 不为空时,id的绝对值必须大于10 -``` - -此外,上述 check 当中比较表达式还可以简写为: - -```python -0 <= bar < 100 -0 < len(fooList) < 100 -``` - -综上所述,KCL Schema 中支持的校验类型为: - -| 校验类型 | 使用方法 | -| -------- | ---------------------------------------------------------- | -| 范围校验 | 使用 `<`, `>` 等比较运算符 | -| 正则校验 | 使用 `regex` 系统库中的 `match` 等方法 | -| 长度校验 | 使用 `len` 内置函数,可以求 `list/dict/str` 类型的变量长度 | -| 枚举校验 | 使用字面值联合类型 | -| 非空校验 | 使用 schema 的可选/必选属性 | -| 条件校验 | 使用 check if 条件表达式 | - -## 20. 如何为 schema 及其属性添加文档注释? - -一个完整的 schema 属性注释使用三引号字符串表示,其中的结构如下所示: - -```python -schema Person: - """The schema person definition - - Attributes - ---------- - name : str - The name of the person - age : int - The age of the person - - See Also - -------- - Son: - Sub-schema Son of the schema Person. - - Examples - -------- - person = Person { - name = "Alice" - age = 18 - } - """ - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -``` - -## 21. 如何基于 schema 编写配置?多个配置之间如何复用公共的配置? - -在 schema 实例化的过程中可以使用解包运算符 `**` 对公共的配置进行展开 - -```python -schema Boy: - name: str - age: int - hc: int - -schema Girl: - name: str - age: int - hc: int - -config = { - age = 18 - hc = 10 -} - -boy = Boy { - **config - name = "Bob" -} -girl = Girl { - **config - name = "Alice" -} -``` - -输出 YAML 为: - -```yaml -config: - age: 18 - hc: 10 -boy: - name: Bob - age: 18 - hc: 10 -girl: - name: Alice - age: 18 - hc: 10 -``` - -## 22. 基于 schema 编写配置时如何覆盖 schema 属性的默认值? - -在定义 schema 后,可以使用 schema 名称实例化相应的配置,使用 `:` 运算符对 schema 默认值进行 union, 使用 `=` 对 schema 默认值进行覆盖。对于 int/float/bool/str 类型的 schema 属性,union 和覆盖的效果相同; 对于 list/dict/schema 类型的 schema 属性,union 和覆盖的效果不同; - -```python -schema Meta: - labels: {str:str} = {"key1" = "value1"} - annotations: {str:str} = {"key1" = "value1"} - -meta = Meta { - labels: {"key2": "value2"} - annotations = {"key2" = "value2"} -} -``` - -输出 YAML 为: - -```yaml -meta: - labels: - key1: value1 - key2: value2 - annotations: - key2: value2 -``` - -## 23. 如何通过继承来复用 schema 定义? - -可以在 schema 定义处声明 schema 需要继承的 schema 名称: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 - -# An employee **is** a person, and has some additional information. -schema Employee(Person): - bankCard: int - nationality: str - -employee = Employee { - firstName = "Bob" - lastName = "Green" - age = 18 - bankCard = 123456 - nationality = "China" -} -``` - -输出 YAML 为: - -```yaml -employee: - firstName: Bob - lastName: Green - age: 18 - bankCard: 123456 - nationality: China -``` - -注意: KCL 只允许 schema 单继承 - -## 24. 如何通过组合复用 schema 逻辑? - -可以使用 KCL schema mixin 复用 schema 逻辑,mixin 一般被用于 schema 内部属性的分离数据,和数据映射等功能,可以使 KCL 代码更具模块化和声明性。注意不同的 mixin 之间的混入属性不建议定义依赖关系,会使得 mixin 使用方式复杂,一般一个 mixin 中作不超过三个属性混入即可。 - -```python -schema Person: - mixin [FullNameMixin, UpperMixin] - - firstName: str - lastName: str - fullName: str - upper: str - -schema FullNameMixin: - fullName = "{} {}".format(firstName, lastName) - -schema UpperMixin: - upper = fullName.upper() - -person = Person { - firstName = "John" - lastName = "Doe" -} -``` - -输出 YAML 为: - -```yaml -person: - firstName: John - lastName: Doe - fullName: John Doe - upper: JOHN DOE -``` - -## 25. 如何导入其他 KCL 文件? - -通过 import 关键字可以导入其他 KCL 文件,KCL 配置文件被组织为模块。单个 KCL 文件被视为一个模块,目录被视为一个包,作为一个特殊的模块。import 关键字支持相对路径导入和绝对路径导入两种方式 - -比如对于如下目录结构: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ │── service1.k - │ └── service2.k - └── mixin - └── mixin1.k -``` - -对于 `main.k`, 相对路径导入和绝对路径导入分别可以表示为: - -```python -import service # 绝对路径导入, 根目录为kcl.mod所在的路径 -import mixin # 绝对路径导入, 根目录为kcl.mod所在的路径 - -import .model1 # 相对路径导入, 当前目录模块 -import ..service # 相对路径导入, 父目录 -import ...root # 相对路径导入, 父目录的父目录 -``` - -注意,对于 KCL 的入口文件 `main.k`, 其不能导入自身所在的文件夹,否则会发生循环导入错误: - -```python -import model # Error: recursively loading -``` - -## 26. 什么情况下可以省略 import ? - -除了 main 包当中的同一文件夹下的 KCL 可以相互引用而不需通过 import 相互引用,比如对于如下目录结构: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ │── service1.k - │ └── service2.k - └── mixin - └── mixin1.k -``` - -当 main.k 作为 KCL 命令行入口文件时, model 文件夹中的 main.k, model1.k 和 model2.k 中的变量不能相互引用,需要通过 import 导入,但是 service 文件夹中的 service1.k 和 service2.k 当中的变量可以互相引用,忽略 import - -service1.k - -```python -schema BaseService: - name: str - namespace: str -``` - -service2.k - -```python -schema Service(BaseService): - id: str -``` - -## 27. 有一行代码太长了,如何在语法正确的情况下优雅地换行? - -在 KCL 中可以使用续行符 `\` 进行换行, 并且在字符串中也可以使用 `\` 表示续行 - -长字符串连接续行举例: - -```python -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " -``` - -推导表达式续行举例: - -```python -data = [1, 2, 3, 4] -dataNew = [ - d + 2 \ - for d in data \ - if d % 2 == 0 -] -``` - -if 表达式续行举例: - -```python -condition = 1 -data1 = 1 \ - if condition \ - else 2 -data2 = 2 \ -if condition \ -else 1 -``` - -三引号字符串内部续行举例: - -```python -longString = """\ -The first line\ -The continue second line\ -""" -``` - -注意: 使用续行符 `\` 的同时缩进的保持, 如下所示: - -错误用例: - -```python -data1 = [ - 1, 2, - 3, 4 \ -] # Error, 需要保持右方括号]的缩进 - -data2 = [ - 1, 2, - 3, 4 -] # Error, 需要数字1和3的缩进统一 -``` - -正确用例: - -```python -data1 = [ - 1, 2, - 3, 4 -] # Right, 带缩进的列表定义 - -data2 = [ \ - 1, 2, \ - 3, 4 \ -] # Right, 使用续行符的列表定义, 实际效果是单行列表 - -data3 = [ \ - 1, 2, \ - 3, 4 \ -] # Right, 使用续行符的列表定义, 无需保持缩进, 实际效果是单行列表 -``` - -## 28. \*_, _ 这些符号是什么意思? - -- `**`, `*` 出现在 dict/list 外部时分别表示乘方运算符和乘法运算符 - -```python -data1 = 2 ** 4 # 2的4次方等于16 -data2 = 2 * 3 # 2乘以3等于6 -``` - -- `**`, `*` 出现在 dict/list 内部时表示解包运算符,经常用于 list/dict 的解包和合并, 与 Python 当中的解包运算符用法相同 - -dict 的解包: - -```python -data = {"key1" = "value1"} -dataUnpack = {**data, "key2" = "value2"} # 将data解包合并入dataUnpack中, {"key1": "value1", "key2": "value2"} -``` - -list 的解包: - -```python -data = [1, 2, 3] -dataUnpack = [*data, 4, 5, 6] # 将data解包合并入dataUnpack中, [1, 2, 3, 4, 5, 6] -``` - -## 29. 如何取 list/dict/schema 的子元素 - -在 KCL 中可以使用 select 表达式或者 subscript 表达式取 list/dict/schema 的子元素 - -- 对于 list 类型,可以使用 `[]` 取列表中的某一个元素或者某一些元素 - -```python -data = [1, 2, 3] # 定义一个整数类型的数组 -theFirstItem = data[0] # 取数组中索引为0的元素,即第一个元素 1 -theSecondItem = data[1] # 取数组中索引为1的元素,即第一个元素 2 -``` - -注意:索引的取值不能超出列表的长度,否则会发生错误,可以使用 `len` 函数获得数组的长度 - -```python -data = [1, 2, 3] -dataLength = len(data) # 数组长度为3 -item = data[3] # 发生数组索引越界错误 -``` - -此外,还可以使用负数索引倒序获得列表中的元素 - -```python -data = [1, 2, 3] -item1 = data[-1] # 取数组中索引为-1的元素,即最后一个元素 3 -item2 = data[-2] # 取数组中索引为-2的元素,即倒数第二个元素 2 -``` - -综上,列表索引的取值范围为 `[-len, len - 1]` - -当想要取得列表的一部分时,可以在 `[]` 中使用切片表达式,其具体语法为 `[<列表开始索引>:<列表终止索引>:<列表遍历步长>]`,注意索引开始终止的取值区间为 `左闭右开[<列表开始索引>, <列表终止索引>)`,注意三个参数均可省略不写 - -```python -data = [1, 2, 3, 4, 5] -dataSlice0 = data[1:2] # 取列表中索引开始为 1, 终止索引为 2 的元素集合 [2] -dataSlice1 = data[1:3] # 取列表中索引开始为 1, 终止索引为 3 的元素集合 [2, 3] -dataSlice2 = data[1:] # 取列表中索引开始为 1, 终止索引为 最后一个索引 的元素集合 [2, 3, 4, 5] -dataSlice3 = data[:3] # 取列表中索引开始为 第一个索引, 终止索引为 3 的元素集合 [1, 2, 3] -dataSlice4 = data[::2] # 取列表中索引开始为 第一个索引, 终止索引为 最后一个索引 的元素集合(步长为2) [1, 3, 5] -dataSlice5 = data[::-1] # 反转一个列表,[5, 4, 3, 2, 1] -dataSlice6 = data[2:1] # 当开始,终止,步长三个参数组合不满足条件时返回空列表 [] - -``` - -- 对于 dict/schema 类型,可以使用 `[]` 和 `.` 两种方式取 dict/schema 中的子元素 - -```python -data = {key1: "value1", key2: "value2"} -data1 = data["key1"] # "value1" -data2 = data.key1 # "value1" -data3 = data["key2"] # "value2" -data4 = data.key2 # "value2" -``` - -```python -schema Person: - name: str = "Alice" - age: int = 18 - -person = Person {} -name1 = person.name # "Alice" -name2 = person["name"] # "Alice" -age1 = person.age # 18 -age2 = person.age # 18 -``` - -当键值在 dict 中不存在时,返回未定义值 `Undefined` - -```python -data = {key1 = "value1", key2 = "value2"} -data1 = data["not_exist_key"] # Undefined -data2 = data.not_exist_key # Undefined -``` - -可以使用 `in` 关键字判断某个键值是否在 dict/schema 中存在 - -```python -data = {key1 = "value1", key2 = "value2"} -exist1 = "key1" in data # True -exist2 = "not_exist_key" in data # False -``` - -当键值中存在 `.` 时或者需要运行时取一个键值变量对应的值时,只能使用 `[]` 方式,如无特殊情况,使用 `.` 即可: - -```python -name = "key1" -data = {key1 = "value1", key2 = "value2", "contains.dot" = "value3"} -data1 = data[name] # "value1" -data2 = data["contains.dot"] # "value3" -# 注意这样子是不对的 data3 = data.contains.dot -``` - -注意:上述取子元素的运算符不能对非 list/dict/schema 集合类型的值进行操作,比如整数,空值等。 - -```python -data = 1 -data1 = 1[0] # error -``` - -```python -data = None -data1 = None[0] # error -``` - -在取集合类型的子元素时往往要进行非空或者长度判断: - -```python -data = [] -item = data[0] if data else None -``` - -可以使用非空判断符 `?` 添加在 `[]`, `.` 的前面表示进行 if 非空判断,当不满足条件时返回 None,比如上述代码可以简化为: - -```python -data = [] -item1 = data?[0] # 当data为空时,返回空值 None -item2 = data?[0] or 1 # 当data为空时,返回空值 None, 如果不想返回 None, 还可与 or 运算符连用返回其他默认值 -``` - -使用 `?` 可以进行递归调用, 避免复杂繁琐的非空判断 - -```python -data = {key1.key2.key3 = []} -item = data?.key1?.key2?.key3?[0] -``` - -## 30. 如何在 KCL 代码中判断变量的类型 - -KCL typeof built-in 函数可以在该函数执行时立即返回一个变量的类型(字符串表示)用于类型断言 - -用法举例: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person{} -t3 = typeof(_x1) - -_x2 = pkg.Person{} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# 输出 -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -## 31. 关键字和 KCL 变量名冲突了可以怎么解决? - -对于与关键字冲突的标识符,可以在标识符前添加 `$` 前缀用于定义一个关键字标识符,比如如下代码中使用了 `if`, `else` 等关键字作为标识符并且可以得到相应的 YAML 输出 - -```python -$if = 1 -$else = "s" - -schema Data: - $filter: str = "filter" - -data = Data {} -``` - -输出 YAML: - -```yaml -data: - filter: filter -if: 1 -else: s -``` - -注意:在非关键字标识符前添加 `$` 前缀的效果与不添加相同 - -```python -_a = 1 -$_a = 2 # 等效于 `_a = 2` -``` - -## 32. KCL 的内置类型是 KCL 的关键字吗?是否可用于变量的定义 - -KCL 的内置类型包括 `int`, `float`, `bool` 和 `str` 四种类型,它们不是 KCL 的关键字,可用于变量的定义,比如如下代码: - -```py -int = 1 -str = 2 -``` - -输出 YAML 为: - -```yaml -int: 1 -str: 2 -``` - -注意:如无特殊需求,不建议变量的名称取这些内置类型,因为在有些语言当中,它们作为关键字存在 - -## 33. 如何在 KCL 中实现类似 Enum 枚举的功能 - -有两种方式可以在 KCL 中实现 Enum 枚举的方式 - -- (推荐)使用**字面值类型**的**联合类型** - -```python -schema Person: - name: str - gender: "Male" | "Female" - -person = Person { - name = "Alice" - gender = "Male" # gender 只能为 "Male" 或者 "Female" -} -``` - -一个复杂例子 - -```python -schema Config: - colors: ["Red" | "Yellow" | "Blue"] # colors 是一个枚举数组 - -config = Config { - colors = [ - "Red" - "Blue" - ] -} -``` - -- 使用 schema 的 check 表达式 - -```python -schema Person: - name: str - gender: "Male" | "Female" - - check: - gender in ["Male", "Female"] - -person = Person { - name = "Alice" - gender = "Male" # gender 只能为 "Male" 或者 "Female" -} -``` - -## 34. 如何求字典 dict 的长度 - -在 KCL 中可以使用 `len` 内置函数直接求 dict 的长度 - -```python -len1 = len({k1: "v1"}) # 1 -len2 = len({k1: "v1", k2: "v2"}) # 2 -varDict = {k1 = 1, k2 = 2, k3 = 3} -len3 = len(varDict) # 3 -``` - -此外,使用 `len` 函数还可以求 `str` 和 `list` 类型长度 - -```python -len1 = len("hello") # 5 -len2 = len([1, 2, 3]) # 3 -``` - -## 35. 如何在 KCL 中编写带条件的配置 - -在 KCL 中,除了支持在顶级的语句中书写 `if-elif-else` 条件表达式以外,还支持在 KCL 复杂结构(list/dict/schema)中书写条件表达式,支持带条件的配置书写。 - -```python -x = 1 -# List 结构中的 if 条件语句 -dataList = [ - if x == 1: 1 -] -# Dict 结构中的 if 条件语句 -dataDict = { - if x == 1: key1 = "value1" # 可以同一行书写 - elif x == 2: - key2 = "value2" # 可以跨行书写 -} -# Schema 结构中的 if 条件语句 -schema Config: - id?: int -env = "prod" -dataSchema = Config { - if env == "prod": - id = 1 - elif env == "pre": - id = 2 - elif env == "test": - id = 3 -} -``` - -## 36. KCL 中的 == 运算符会作深度比较嘛? - -KCL 中的 `==` 运算符 - -- 对于基本类型 `int`, `float`, `bool`, `str` 的变量是直接比较它们的值是否相等 -- 对于复合类型 `list`, `dict`, `schema` 的变量会深度递归地比较其中的子元素是否相等 - - `list` 类型深度递归递归比较每个索引的值以及长度 - - `dict`/`schema` 类型深度递归比较每个属性的值(与属性出现的顺序无关) - -```python -print([1, 2] == [1, 2]) # True -print([[0, 1], 1] == [[0, 1], 1]) # True -print({k1 = 1, k2 = 2} == {k2 = 2, k1 = 1}) # True - -print([1, 2] == [1, 2, 3]) # False -print({k1 = 1, k2 = 2, k3 = 3} == {k2 = 2, k1 = 1}) # False -``` - -## 37. 如何对 KCL 中已有的配置块进行修改 - -在 KCL 中,存在三种**属性运算符** `=`、`+=`、`:`,可以用来对已有配置块进行修改,并且可以使用**解包运算符** `**` 等"继承"一个配置块的所有属性字段和值。 - -- `=` 属性运算符表示覆盖,使用 `=` 运算符可以对属性进行有优先级的覆盖/删除,(如果是用 `Undefined` 覆盖则表示删除) -- `+=` 属性运算符表示添加,一般用于对 list 类型的属性添加子元素,`+=` 属性运算符后跟的操作数类型也只能为 list 类型 -- `:` 属性运算符表示幂等合并,当值发生冲突时进行报错,不冲突时进行合并 - -### 覆盖属性运算符= - -最常使用的属性运算符是 `=`,表示一个属性的赋值,多次对同一个属性进行使用时表示覆盖,对于 `{}` 外的全局变量或者 `{}` 内的属性均表示使用值覆盖这个全局变量或者属性 - -```python -data = { # 定义一个字典类型的变量 data - a = 1 # 使用 = 在 data 中声明一个值为 1 的属性 a - b = 2 # 使用 = 在 data 中声明一个值为 1 的属性 b -} # 最终 data 的值为 {"a": 1, "b": 1} -``` - -在 schema 实例化处也可以使用覆盖属性运算符实现对 schema 默认值的覆盖效果,一般在创建新的 schema 实例时如无特殊的需求,一般使用 `=` 即可 - -```python -schema Person: - name: str = "Alice" # schema Person 的 name 属性具有默认值 "Alice" - age: int = 18 # schema Person 的 age 属性具有默认值 18 - -bob = Person { - name = "Bob" # "Bob" -> "Alice", 属性 name 的值 "Bob" 的值会覆盖 schema Person name 属性的默认值 "Alice" - age = 10 # 10 -> 18, 属性 age 的值 10 的值会覆盖 schema Person age 属性的默认值 18 -} # 最终 bob 的值为 {"name": "Bob", age: 10} -``` - -### 插入属性运算符 += - -插入属性运算符表示对一个属性的值进行原地添加,比如向一个 list 类型的属性添加新的元素 - -```python -data = { - args = ["kcl"] # 使用 = 在 data 中声明一个值为 ["kcl"] 的属性 args - args += ["-Y", "settings.yaml"] # 使用 += 运算符向属性 args 中添加两个元素"-Y", "settings.yaml" -} # 最终 data 的值为 {"args": ["kcl", "-Y", "settings.yaml"]} -``` - -### 合并属性运算符: - -合并属性运算符表示对一个属性的不同配置块值进行幂等的合并,当需要合并的值发生冲突时进行报错,多用于复杂配置合并场景 - -```python -data = { - labels: {key1: "value1"} # 定义一个 labels, 它的类型为 dict, 值为 {"key1": "value1"} - labels: {key2: "value2"} # 使用 : 将 labels 不同的配置值进行合并 -} # 最终 data 的值为 {"labels": {"key1": "value1", "key2": "value2"}} -``` - -合并属性运算符属于幂等运算符,需要合并的配置块的书写顺序不影响其最终结果,比如上述例子中的两个 `labels` 属性也可以调换顺序书写 - -```python -data = { # 同一个属性 labels 的合并书写顺序不影响最终结果 - labels: {key2: "value2"} # 定义一个 labels, 它的类型为 dict, 值为 {"key2": "value2"} - labels: {key1: "value1"} # 使用 : 将 labels 不同的配置值进行合并 -} # 最终 data 的值为 {"labels": {"key1": "value1", "key2": "value2"}} -``` - -注意:合并属性运算符会对合并的值进行冲突检查,当需要合并的配置值发生冲突时进行报错 - -```python -data = { - a: 1 # a 的值为 1 - a: 2 # Error: a 的值 2 不能与 a 的值 1 进行合并,因为其结果存在冲突,且合并是不可交换的 -} -``` - -```python -data = { - labels: {key: "value"} - labels: {key: "override_value"} # Error: 两个 labels 的 key 属性的值 "value" 和 "override_value" 是冲突的,不可合并 -} -``` - -合并运算符对不同类型的使用方式不同 - -- 不同类型的属性不能进行合并 -- 当属性为 int/float/str/bool 等基本类型时,运算符会判断需要合并的值是否相等,不相等时发生合并冲突错误 - -```python -data = { - a: 1 - a: 1 # Ok - a: 2 # Error -} -``` - -- 当属性为 list 类型时 - - 当需要合并的两个 list 长度不相等时,发生合并冲突错误 - - 当需要合并的两个 list 长度相等时,按照索引递归地合并 list 当中的每一个元素 - -```python -data = { - args: ["kcl"] - args: ["-Y", "settings.yaml"] # Error: 两个 args 属性的长度不相同,不能进行合并 - env: [{key1: "value1"}] - env: [{key2: "value2"}] # Ok: 最终 env 属性的值为 [{"key1": "value1"}, {"key2": "value2"}] -} -``` - -- 当属性为 dict/schema 类型时,按照 key 递归地合并 dict/schema 当中的每一个元素 - -```python -data = { - labels: {key1: "value1"} - labels: {key2: "value2"} - labels: {key3: "value3"} -} # 最终 data 的值为 {"labels": {"key1": "value1", "key2": "value2", "key3": "value3"}} -``` - -- 任意类型的属性与 None/Undefined 合并的结果都是其自身 - -```python -data = { - args: ["kcl"] - args: None # Ok - args: Undefined #Ok -} # 最终 data 的值为 {"args": ["kcl"]} -``` - -支持顶级变量使用 `:` 属性声明与合并(仍然可使用 `config = Config {}` 的方式声明一个配置块) - -```python -schema Config: - id: int - value: str - -config: Config { - id: 1 -} -config: Config { - value: "1" -} -""" -此处定义了两个 Config 配置块,使用 : 运算符将可以两个配置块合并在一起,其合并的等效代码如下: -config: Config { - id: 1 - value: "1" -} -""" -``` - -综上所述,合并属性运算符 `:` 的使用场景主要为复杂数据结构 list/dict/schema 的合并操作,一般情况如无特殊需求使用 `=` 和 `+=` 两种属性运算符即可,因此属性运算符的最佳实践如下 - -- 对于基本类型,采用 `=` 运算符 -- 对于 list 类型,一般采用 `=` 和 `+=` 运算符,使用 `=` 表示完全覆盖 list 属性,使用 `+=` 表示向 list 中添加元素 -- 对于 dict/schema 类型,一般采用 `:` 运算符 - -此外,当已经存在一个配置时,可以使用解包运算符 `**` 获得此配置的所有字段值并对其中的字段使用不同属性运算符进行修改,并获得一个新的配置 - -```python -configBase = { - intKey = 1 # 一个 int 类型的属性 - floatKey = 1.0 # 一个 float 类型的属性 - listKey = [0] # 一个 list 类型的属性 - dictKey = {key1: "value1"} # 一个 dict 类型的属性 -} -configNew = { - **configBase # 将 configBase 解包内联到 configNew 中 - intKey = 0 # 使用 覆盖属性运算符 = 将 intKey 属性覆盖为 1 - floatKey = Undefined # 使用 覆盖属性运算符 = 删除 floatKey 属性 - listKey += [1] # 使用 添加属性运算符 += 为 listKey 属性尾部添加一个属性 1 - dictKey: {key2: "value2"} # 使用 合并属性运算符 : 为 dictKey 属性扩展一个键-值对 -} -``` - -输出的 YAML 结果为: - -```yaml -configBase: - intKey: 1 - floatKey: 1.0 - listKey: - - 0 - dictKey: - key1: value1 -configNew: - intKey: 0 - listKey: - - 0 - - 1 - dictKey: - key1: value1 - key2: value2 -``` - -或者可以使用 `|` 运算符对两个配置块合并: - -```python -configBase = { - intKey = 1 # 一个 int 类型的属性 - floatKey = 1.0 # 一个 float 类型的属性 - listKey = [0] # 一个 list 类型的属性 - dictKey = {key1: "value1"} # 一个 dict 类型的属性 -} -configNew = configBase | { # 使用 | 进行合并 - intKey = 0 # 使用 覆盖属性运算符 = 将 intKey 属性覆盖为 1 - floatKey = Undefined # 使用 覆盖属性运算符 = 删除 floatKey 属性 - listKey += [1] # 使用 添加属性运算符 += 为 listKey 属性尾部添加一个属性 1 - dictKey: {key2: "value2"} # 使用 合并属性运算符 : 为 dictKey 属性扩展一个键-值对 -} -``` - -输出的 YAML 结果为: - -```yaml -configBase: - intKey: 1 - floatKey: 1.0 - listKey: - - 0 - dictKey: - key1: value1 -configNew: - intKey: 0 - listKey: - - 0 - - 1 - dictKey: - key1: value1 - key2: value2 -``` - -### KCL 发生 conflicting values on the attribute 'attr' between {value1} and {value2} 错误的解决方式 - -当 KCL 发生类似 conflicting values on the attribute 'attr' between {value1} and {value2} 错误时,一般是合并属性运算符 `:` 的使用问题,表明 `value1` 和 `value2` 配置进行合并时在属性 `attr` 处发生了冲突错误。一般情况将 value2 的 attr 属性修改为其他属性运算符即可,使用 `=` 表示覆盖,使用 `+=` 表示添加 - -比如对于如下代码: - -```python -data = {k: 1} | {k: 2} # Error: conflicting values on the attribute 'k' between {'k': 1} and {'k': 2} -``` - -则可以使用 `=` 属性运算符修改为如下形式 - -```python -data = {k: 1} | {k = 2} # Ok: the value 2 will override the value 1 through the `=` operator -``` - -## 38. KCL 中如何同时遍历多个元素 - -KCL 中可以使用 for 推导表达式遍历多个元素 - -- 举例 1: 使用 for 进行 2 维元素遍历 - -```python -dimension1 = [1, 2, 3] # dimension1 列表的长度是 3 -dimension2 = [1, 2, 3] # dimension2 列表的长度是 3 -matrix = [x + y for x in dimension1 for y in dimension2] # matrix 列表的长度是 9 = 3 * 3 -``` - -输出结果如下: - -```yaml -dimension1: - - 1 - - 2 - - 3 -dimension2: - - 1 - - 2 - - 3 -matrix: - - 2 - - 3 - - 4 - - 3 - - 4 - - 5 - - 4 - - 5 - - 6 -``` - -- 举例 2: 使用 for 循环配合 zip 内置函数按照索引一一对应对多个列表进行遍历 - -```python -dimension1 = [1, 2, 3] # dimension1 列表的长度是 3 -dimension2 = [1, 2, 3] # dimension2 列表的长度是 3 -dimension3 = [d[0] + d[1] for d in zip(dimension1, dimension2)] # dimension3 列表的长度是 3 -``` - -输出结果如下: - -```yaml -dimension1: - - 1 - - 2 - - 3 -dimension2: - - 1 - - 2 - - 3 -dimension3: - - 2 - - 4 - - 6 -``` - -## 39. KCL 中如何为 option 函数设定默认值 - -在 KCL 中,当 option 属性的值为 None/Undefined 空时,可以使用逻辑或 `or` 直接指定一个默认值 - -```python -value = option("key") or "default_value" # 当 key 的值存在时,取 option("key") 的值,否则取 "default_value" -``` - -或者使用 option 函数的 default 参数 - -```python -value = option("key", default="default_value") # 当 key 的值存在时,取 option("key") 的值,否则取 "default_value" -``` - -## 40. KCL 中 schema 怎么检查多个属性不能同时为空或同时设置 - -在 KCL 中,对于 schema 的单个属性不能为空可以使用属性非空标记 - -```python -schema Person: - name: str # required. name 不能为空 - age: int # required. age 不能为空 - id?: int # optional. id 可以留空 -``` - -而对于需要检查 schema 属性不能同时为空或者只能有一者为空的情况时,需要借助 schema check 表达式进行书写,下面以同一个 schema Config 的两个属性 a, b 为例进行说明 - -- Config 的 a, b 属性不能同时为空 - -```python -schema Config: - a?: str - b?: str - - check: - a or b, "a属性和b属性不能同时为空" -``` - -- Config 的 a, b 属性只能有一个为空或者都为空(不能同时存在或不为空) - -```python -schema Config: - a?: str - b?: str - - check: - not a or not b, "a属性和b属性不能同时填写" -``` - -## 41. KCL 中 import 了某个文件但是找不到其同目录下其他 KCL 文件定义的 schema 可能是什么原因 - -可能是与使用 import 仅导入了这个文件夹的这一个文件导致,在 KCL 中,import 支持导入整个文件夹,也支持导入某一个文件夹下的的某一个 KCL 文件,比如对于如下目录结构 - -``` -. -├── kcl.mod -├── main.k -└── pkg - ├── pkg1.k - ├── pkg2.k - └── pkg3.k -``` - -在根目录下存在入口文件 main.k,可以在 main.k 中书写如下代码导入整个 pkg 文件夹,此时 pkg 文件夹下的所有 schema 定义互相可见 - -```python -import pkg -``` - -还可以书写如下代码导入单个文件 pkg/pkg1.k,此时 pkg1.k 不能找到其他文件即 pkg2.k/pkg3.k 下的 schema 定义 - -```python -import pkg.pkg1 -``` - -## 42. KCL 中的缩进是如何处理的? - -在 KCL 中,在出现冒号 `:`、中括号对 `[]` 以及大括号对 `{}` 时,一般需要使用换行 + 缩进,同一缩进级的缩进空格数需要保持一致,一个缩进级一般采用 4 个空格表示 - -- 冒号 `:` 后跟换行 + 缩进 - -```python -"""if 语句中的缩进""" -_a = 1 -_b = 1 -if _a >= 1: # 冒号后跟换行+缩进 - if _a > 8: - _b = 2 - elif a > 6: - _b = 3 - -"""schema 定义中的缩进""" -schema Person: # 冒号后跟换行+缩进 - name: str - age: int -``` - -- 中括号对 `[]` 后跟换行 + 缩进 - -```python -data = [ # 左中括号 [ 后跟换行+缩进 - 1 - 2 - 3 -] # 右中括号 ] 前取消缩进 -``` - -```python -data = [ # 左中括号 [ 后跟换行+缩进 - i * 2 for i in range(5) -] # 右中括号 ] 前取消缩进 -``` - -- 大括号对 `{}` 后跟换行 + 缩进 - -```python -data = { # 左大括号 { 后跟换行+缩进 - k1 = "v1" - k2 = "v2" -} # 右大括号 } 前取消缩进 -``` - -```python -data = { # 左大括号 { 后跟换行+缩进 - str(i): i * 2 for i in range(5) -} # 右大括号 } 前取消缩进 -``` - -## 43. 如何为 KCL 代码编写简单的测试? - -KCL 目前的版本还不支持内部程序调试,可以使用 assert 语句以及 print 函数实现数据的断言和打印查看 - -```python -a = 1 -print("The value of a is", a) -assert a == 1 -``` - -此外,还可以借助 kcl-test 测试工具编写 KCL 内部编写测试用例 - -假设有 hello.k 文件,代码如下: - -```python -schema Person: - name: str = "kcl" - age: int = 1 - -hello = Person { - name = "hello kcl" - age = 102 -} -``` - -构造 hello_test.k 测试文件,内容如下: - -```python -schema TestPerson: - a = Person{} - assert a.name == 'kcl' - -schema TestPerson_age: - a = Person{} - assert a.age == 1 - -schema TestPerson_ok: - a = Person{} - assert a.name == "kcl" - assert a.age == 1 -``` - -然后在目录下执行 kcl-test 命令: - -``` -$ kcl-test -ok /pkg/to/app [365.154142ms] -$ -``` - -## 44. KCL 中如何定义函数或定义方法? - -schema 结构在一定程度上充当了函数的功能,并且这个函数具有多个输入参数和多个输出参数的能力,比如如下代码可以实现一个斐波那契数列的功能: - -```python -schema Fib: - n: int - value: int = 1 if n <= 2 else (Fib {n: n - 1}).value + (Fib {n: n - 2}).value - -fib8 = (Fib {n: 8}).value -``` - -输出结果为: - -```yaml -fib8: 21 -``` - -一个合并列表为字典的 schema 函数 - -```python -schema UnionAll[data, n]: - _?: [] = data - value?: {:} = ((UnionAll(data=data, n=n - 1) {}).value | data[n] if n > 0 else data[0]) if data else {} - -schema MergeList[data]: - """Union一个列表中的所有元素返回合并字典 - - [{"key1": "value1"}, {"key2": "value2"}, {"key3": "value3"}] -> {"key1": "value1", "key2": "value2", "key3": "value3"} - """ - _?: [] = data - value?: {:} = (UnionAll(data=data, n=len(data) - 1) {}).value if data else {} -``` - -此外,KCL 支持使用 `lambda` 关键字定义一个函数: - -```python -func = lambda x: int, y: int -> int { - x + y -} -a = func(1, 1) # 2 -``` - -lambda 函数具有如下特性: - -- lambda 函数将最后一个表达式的值作为函数的返回值,空函数体返回 None。 -- 返回值类型注解可以省略,返回值类型为最后一个表达式值的类型 -- 函数体中没有与顺序无关的特性,所有的表达式都是按顺序执行的 - -```python -_func = lambda x: int, y: int -> int { - x + y -} # 使用 lambda 表达式定义一个函数 -_func = lambda x: int, y: int -> int { - x - y -} # Ok -_func = lambda x: int, y: int -> str { - str(x + y) -} # Error (int, int) -> str can't be assigned to (int, int) -> int -``` - -lambda 函数对象不能参与任何计算,只能在赋值语句和调用语句中使用。 - -```python -func = lambda x: int, y: int -> int { - x + y -} -x = func + 1 # Error: unsupported operand type(s) for +: 'function' and 'int(1)' -``` - -```python -a = 1 -func = lambda x: int { - x + a -} -funcOther = lambda f, para: int { - f(para) -} -r = funcOther(func, 1) # 2 -``` - -输出为: - -```python -a: 1 -r: 2 -``` - -可以定义一个匿名函数并直接调用 - -```python -result = (lambda x, y { - z = 2 * x - z + y -})(1, 1) # 3 -``` - -可以在 for 循环使用使用匿名函数 - -```python -result = [(lambda x, y { - x + y -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 3, 3, 4] -``` - -可以在 KCL schema 中定义并使用函数 - -```python -_funcOutOfSchema = lambda x: int, y: int { - x + y -} -schema Data: - _funcInSchema = lambda x: int, y: int { - x + y - } - id0: int = _funcOutOfSchema(1, 1) - id1: int = _funcInSchema(1, 1) - id2: int = (lambda x: int, y: int { - x + y - })(1, 1) -``` - -输出 YAML 为: - -```yaml -data: - id0: 2 - id1: 2 - id2: 2 -``` - -## 45. 为什么变量赋值为枚举类型(字面值联合类型)时会报错 - -在 KCL 中,被定义为字面值联合类型的属性,在赋值时仅允许接收一个字面值或者同为字面值联合类型的变量,比如如下代码是正确的: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -data = Data { - color = "Red" # Ok, 赋值为 "Red"、"Yellow" 和 "Blue" 均可 -} -``` - -然而以下代码是错误的: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -_color = "Red" - -data = Data { - color = _color # Error: expect str(Red)|str(Yellow)|str(Blue), got str -} -``` - -这是因为没有为变量 `_color` 申明一个类型,它会被 KCL 编译器推导为 `str` 字符串类型,因此当一个 “较大” 的类型 `str` 赋值为一个 “较小” 的类型时 `"Red" | "Yellow" | "Blue"` 会报错,一个解决方式是为 `_color` 变量声明一个类型,以下代码是正确的: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -_color: "Red" | "Yellow" | "Blue" = "Red" - -data = Data { - color = _color # Ok -} -``` - -进一步地,我们可以使用类型别名来简化枚举(字面值联合类型的书写),比如如下代码: - -```python -type Color = "Red" | "Yellow" | "Blue" # 定义一个类型别名,可以在不同的地方重复使用,降低代码书写量 - -schema Data: - color: Color - -_color: Color = "Red" - -data = Data { - color = _color # Ok -} -``` - -## 46. 过程式的 for 循环 - -KCL 中为何不支持过程式的 for 循环! - -KCL 提供了推导表达式以及 all/any/map/filter 表达式等用于对一个集合元素进行处理,满足大部分需求,提供过程式的 for 循环体从目前场景看需求暂时不强烈,因此暂未提供过程式的 for 循环支持 - -此外,KCL 中虽然没有支持过程式的 for 循环,但是可以通过 for 循环和 lambda 函数“构造”相应的过程式 for 循环 - -```python -result = [(lambda x: int, y: int -> int { - # 在其中书写过程式的 for 循环逻辑 - z = x + y - x * 2 -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 2, 4, 4] -``` - -## 47. 默认变量不可变 - -KCL 变量不可变性是指 KCL 顶层结构中的非下划线 `_` 开头的导出变量初始化后不能被改变。 - -```python -schema Person: - name: str - age: int - -a = 1 # a会输出到YAML中,一旦赋值不可修改 -_b = 1 # _b变量以下划线开头命名,不会输出到YAML中, 可多次赋值修改 -_b = 2 -alice = Person { - name = "Alice" - age = 18 -} -``` - -规定变量不可变的方式分为两类: - -- schema 外的非下划线顶层变量 - -```python -a = 1 # 不可变导出变量 -_b = 2 # 可变非导出变量 -``` - -## 48. 在 KCL 中存在类似 Go `interface{}`/`any` 或者 Java `Object` 的类型嘛? - -在 KCL 中,我们可以使用 `any` 类型注解来定义一个变量存储任意类型比如整数、字符串、schema 结构等数据。比如如下例子: - -```python -schema Data: - id: int = 1 - -var_list: [any] = [1, "12", Data {}] -``` - -输出 YAML 为: - -```yaml -var_list: - - 1 - - "12" - - id: 1 -``` - -此外,我们可以使用 `typeof` 函数来判断 KCL 变量的类型: - -```python -schema Data1: - id: int = 1 - -schema Data2: - name: str = "name" - -data_list: [any] = [Data1 {}, Data2 {}] -data_type_list: [str] = [typeof(data) for data in data_list] -``` - -输出 YAML 为: - -```yaml -data_list: - - id: 1 - - name: name -data_type_list: - - Data1 - - Data2 -``` - -## 49. 如何通过编写 KCL 插件进行扩展? - -KCL 插件在 KCL 的 plugins 子目录(通常安装在 `$HOME/.kcl/plugins` 目录),或者通过 `$KCL_PLUGINS_ROOT` 环境变量设置(环境变量优先级更高)。对于插件开发人员,插件都在 [Git 仓库](https://github.com/kcl-lang/kcl-plugin)管理,可以将插件仓库克隆到该目录进行开发。 - -KCL 内置了 kcl-plugin 脚手架命令用于辅助用户使用 Python 语言编写 KCL 插件,以便在 KCL 文件当中调用相应的插件对 KCL 语言本身进行增强,比如访问网络,读写 IO,CMDB 查询和加密解密等功能。 - -``` -usage: kcl-plugin [-h] {list,init,info,gendoc,test} ... - -positional arguments: - {list,init,info,gendoc,test} - kcl plugin sub commands - list list all plugins - init init a new plugin - info show plugin document - gendoc gen all plugins document - test test plugin - -optional arguments: - -h, --help show this help message and exit -``` - -比如想要开发一个名为 io 插件,就可以使用如下命令成功新建一个 io 插件 - -``` -kcl-plugin init io -``` - -然后可以使用如下命令获得 plugin 的根路径并 cd 到相应的 io 插件目录进行开发 - -``` -kcl-plugin info -``` - -比如想要开发一个读文件的函数 read_file,就可以在 `$plugin_root/io` 的 `plugin.py` 中进行 python 代码编写: - -```python -# Copyright 2020 The KCL Authors. All rights reserved. - -import pathlib - -INFO = { - 'name': 'io', - 'describe': 'my io plugin description test', - 'long_describe': 'my io plugin long description test', - 'version': '0.0.1', -} - - -def read_file(file: str) -> str: - """Read string from file""" - return pathlib.Path(file).read_text() - -``` - -另外可以在 `plugin_test.py` 中编写相应的测试函数,也可以直接编写如下所示 KCL 文件进行测试: - -```python -import kcl_plugin.io - -text = io.read_file('test.txt') -``` - -还可以使用 info 命令查看 io 插件的信息 - -``` -kcl-plugin info io -``` - -``` -{ - "name": "io", - "describe": "my io plugin description test", - "long_describe": "my io plugin long description test", - "version": "0.0.1", - "method": { - "read_file": "Read string from file" - } -} -``` - -最后将编写测试完成的插件在 `kcl_plugins` 仓库提 MR 合并即可 - -## 50. 如何在 KCL 中进行基本类型转换 - -可以使用`int()`, `float()`和`str()` 这些内置的方法来进行 `int`, `float` 和 `str` 之间的基本类型转换. - -``` -_t = 1 - -t_str: str = str(_t) # 输出的 t_str 为一个字符串 "t_str: '1'" -t_int: int = int(t_str) # 输出的 t_int 为一个整型 "t_int: 1" -t_float: float = float(t_str) # 输出的 t_float 为一个浮点型 "t_float: 1.0" -``` - -如果您想查看更多详细的关于KCL类型系统和类型转换的内容,您可以查阅 [KCL 内置类型](https://kcl-lang.io/docs/reference/lang/tour#built-in-types) 和 [KCL 类型系统](https://kcl-lang.io/docs/reference/lang/tour#type-system)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/support/faq-yaml.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/support/faq-yaml.md deleted file mode 100644 index 4dd12c00..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/support/faq-yaml.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -sidebar_position: 3 ---- - -# YAML 语法 - -## 1. YAML 字符串使用单引号和双引号的区别是什么? - -- YAML 双引号字符串是唯一能够表达任意字符串的样式,通过使用 `\` 转义字符,比如使用 `\"` 转义双引号 `"`,使用 `\\` 转义反斜杠 `\`,并且可以使用单个反斜杠 `\` 作为双引号字符串的续行符 -- YAML 单引号字符串与 YAML 双引号字符串不同的是可以自由地使用 `\` 和 `"` 而不需要转义,但是使用两个单引号 `''` 转义单引号 `'` 字符 - -比如对于如下的例子,三个字符串变量的内容是相同的 - -```yaml -string1: 'here '' s to "quotes"' -string2: 'here''s to "quotes"' -string3: here's to "quotes" -``` - -因此,KCL 输出 YAML 字符串的策略是当字符串内容出现单引号时,优先输出无引号字符串或双引号字符串,其他情况输出单引号字符串以避免理解上的负担。 - -更多细节可参考: [YAML 规范 v1.2](https://yaml.org/spec/1.2.1/) - -## 2. YAML 中出现的 | - + > 等符号是什么含义? - -在使用 KCL 多行字符串(使用三引号括起来的字符串),输出的 YAML 经常会携带一些特殊的记号,如 `|`,`-`,`+` 和 `>` 等,这些记号通常为 YAML 多行字符串的表示方法,比如对于如下 KCL 代码: - -```python -data = """This is a KCL multi line string (the first line) -This is a KCL multi line string (the second line) -This is a KCL multi line string (the third line) - - -""" -var = 1 -``` - -输出 YAML 为: - -```yaml -data: |+ - This is a KCL multi line string (the first line) - This is a KCL multi line string (the second line) - This is a KCL multi line string (the third line) - - -var: 1 -``` - -- `|` 表示**块字符串样式**,用于表示一个多行字符串,其中的所有换行符都表示字符串真实的换行; -- `>` 表示**块折叠样式**,在其中所有的换行符将被空格替换; -- `+` 和 `-` 用于控制在字符串末尾使用换行符的情况。默认情况为字符串末尾保留单个换行符,如果要删除所有换行符,可以在样式指示符 `|` 或 `>` 后面放置一个 `-` 来完成,如果要保留末尾的换行符,则需要在 `|` 或 `>` 后面放置一个 `+` - -更多细节可参考: [YAML 多行字符串](https://yaml-multiline.info/) 和 [YAML 规范 v1.2](https://yaml.org/spec/1.2.1/) - -## 3. YAML 中在 | - + > 等符号之后出现的数字是什么含义? - -数字表示 YAML 当中的**显式缩进指示符**。对于 YAML 中的长字符串,YAML 通常第一个非空行确定字符串的缩进级别,而当第一个非空行前面具有非前导字符时,比如换行符,YAML 要求必须使用**显式缩进指示符**来指定内容的缩进级别,比如 `|2` 和 `|1` 等 - -比如对于如下 KCL 代码: - -```python -longStringStartWithNewline = """ -This is the second line -This is the third line -""" - -``` - -```yaml -longStringStartWithNewline: |2 - - This is the second line - This is the third line -``` - -如果不需要长字符串开头的空行或换行符,则可以以如下两种方式进行 KCL 长字符串书写 - -- 长字符串从第 1 行开始书写 - -```python -longString = """This is the second line -This is the third line -""" -``` - -- 使用续行符 - -```python -longString = """\ -This is the second line -This is the third line -""" -``` - -以上两种方式输出的 YAML 均为: - -```yaml -longString: | - This is the second line - This is the third line -``` - -更多细节可参考: [YAML 规范 v1.2](https://yaml.org/spec/1.2.1/) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/support/support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/support/support.md deleted file mode 100644 index 648ee5a3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/support/support.md +++ /dev/null @@ -1,3 +0,0 @@ -# 常见问答 - -KCL 安装、使用过程中遇到的常见问题,包括基本概念解释、KCL 语法、KCL 语言设计、命令行工具和 YAML 等常见问题。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/contribute/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/contribute/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/contribute/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/contribute/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/contribute/contribute-code.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/contribute/contribute-code.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/contribute/contribute-code.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/contribute/contribute-code.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/contribute/contribute-docs.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/contribute/contribute-docs.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/contribute/contribute-docs.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/contribute/contribute-docs.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/contribute/contribute.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/contribute/contribute.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/contribute/contribute.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/contribute/contribute.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/contribute/git-guideline.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/contribute/git-guideline.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/contribute/git-guideline.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/contribute/git-guideline.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/intro/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/intro/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/intro/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/intro/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/intro/intro.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/intro/intro.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/intro/intro.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/intro/intro.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/intro/license.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/intro/license.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/intro/license.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/intro/license.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/intro/support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/intro/support.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/intro/support.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/intro/support.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/release-policy/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/release-policy/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/release-policy/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/release-policy/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/release-policy/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/release-policy/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/release-policy/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/release-policy/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/release-policy/kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/release-policy/kcl.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/release-policy/kcl.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/release-policy/kcl.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/release-policy/roadmap.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/release-policy/roadmap.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/community/release-policy/roadmap.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/community/release-policy/roadmap.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/cheatsheets/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/cheatsheets/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/cheatsheets/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/cheatsheets/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/cheatsheets/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/cheatsheets/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/cheatsheets/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/cheatsheets/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/codelab/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/codelab/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/codelab/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/codelab/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/codelab/collaborative.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/codelab/collaborative.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/codelab/collaborative.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/codelab/collaborative.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/codelab/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/codelab/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/codelab/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/codelab/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/codelab/schema.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/codelab/schema.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/codelab/schema.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/codelab/schema.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/codelab/simple.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/codelab/simple.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/codelab/simple.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/codelab/simple.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/error/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/error/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/error/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/error/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/error/_error.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/error/_error.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/error/_error.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/error/_error.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/error/exception.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/error/exception.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/error/exception.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/error/exception.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/error/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/error/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/error/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/error/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/spec/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/spec/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/spec/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/spec/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/spec/codestyle.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/spec/codestyle.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/spec/codestyle.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/spec/codestyle.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/spec/datatypes.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/spec/datatypes.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/spec/datatypes.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/spec/datatypes.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/spec/error.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/spec/error.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/spec/error.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/spec/error.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/spec/expressions.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/spec/expressions.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/spec/expressions.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/spec/expressions.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/spec/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/spec/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/spec/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/spec/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/spec/kcl-spec.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/spec/kcl-spec.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/spec/kcl-spec.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/spec/kcl-spec.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/spec/lexical.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/spec/lexical.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/spec/lexical.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/spec/lexical.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/spec/modules.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/spec/modules.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/spec/modules.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/spec/modules.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/spec/schema.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/spec/schema.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/spec/schema.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/spec/schema.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/spec/statements.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/spec/statements.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/spec/statements.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/spec/statements.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/spec/variables.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/spec/variables.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/spec/variables.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/spec/variables.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/tour.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/tour.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/tour.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/tour.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/types/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/types/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/types/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/types/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/types/types.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/types/types.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/lang/types/types.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/lang/types/types.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/base64.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/base64.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/base64.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/base64.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/builtin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/builtin.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/builtin.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/builtin.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/crypto.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/crypto.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/crypto.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/crypto.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/datetime.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/datetime.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/datetime.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/datetime.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/json.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/json.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/json.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/json.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/manifests.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/manifests.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/manifests.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/manifests.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/math.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/math.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/math.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/math.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/net.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/net.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/net.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/net.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/overview.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/overview.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/regex.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/regex.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/regex.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/regex.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/units.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/units.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/model/units.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/units.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/yaml.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/yaml.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/model/yaml.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/model/yaml.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/package-management/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/package-management/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/package-management/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/package-management/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/package-management/command-reference/1.init.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/package-management/command-reference/1.init.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/package-management/command-reference/1.init.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/package-management/command-reference/1.init.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/package-management/command-reference/10.help.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/package-management/command-reference/10.help.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/package-management/command-reference/10.help.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/package-management/command-reference/10.help.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/package-management/command-reference/2.add.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/package-management/command-reference/2.add.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/package-management/command-reference/2.add.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/package-management/command-reference/2.add.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/package-management/command-reference/3.pkg.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/package-management/command-reference/3.pkg.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/package-management/command-reference/3.pkg.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/package-management/command-reference/3.pkg.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/package-management/command-reference/4.metadata.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/package-management/command-reference/4.metadata.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/package-management/command-reference/4.metadata.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/package-management/command-reference/4.metadata.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/package-management/command-reference/5.run.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/package-management/command-reference/5.run.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/package-management/command-reference/5.run.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/package-management/command-reference/5.run.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/package-management/command-reference/6.login.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/package-management/command-reference/6.login.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/package-management/command-reference/6.login.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/package-management/command-reference/6.login.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/package-management/command-reference/7.logout.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/package-management/command-reference/7.logout.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/package-management/command-reference/7.logout.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/package-management/command-reference/7.logout.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/package-management/command-reference/8.push.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/package-management/command-reference/8.push.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/package-management/command-reference/8.push.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/package-management/command-reference/8.push.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/package-management/command-reference/9.pull.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/package-management/command-reference/9.pull.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/package-management/command-reference/9.pull.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/package-management/command-reference/9.pull.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/package-management/command-reference/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/package-management/command-reference/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/package-management/command-reference/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/package-management/command-reference/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/package-management/command-reference/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/package-management/command-reference/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/package-management/command-reference/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/package-management/command-reference/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/plugin/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/plugin/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/plugin/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/plugin/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/plugin/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/plugin/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/plugin/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/plugin/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/plugin/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/plugin/overview.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/plugin/overview.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/plugin/overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/plugin/project_context.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/plugin/project_context.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/plugin/project_context.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/plugin/project_context.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/xlang-api/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/xlang-api/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/xlang-api/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/xlang-api/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/xlang-api/go-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/xlang-api/go-api.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/xlang-api/go-api.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/xlang-api/go-api.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/xlang-api/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/xlang-api/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/xlang-api/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/xlang-api/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/xlang-api/java-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/xlang-api/java-api.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/xlang-api/java-api.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/xlang-api/java-api.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/xlang-api/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/xlang-api/overview.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/xlang-api/overview.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/xlang-api/overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/xlang-api/python-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/xlang-api/python-api.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/xlang-api/python-api.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/xlang-api/python-api.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/xlang-api/rest-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/xlang-api/rest-api.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/reference/xlang-api/rest-api.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/reference/xlang-api/rest-api.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/Ide/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/Ide/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/Ide/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/Ide/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/Ide/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/Ide/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/Ide/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/Ide/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/Ide/intellij.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/Ide/intellij.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/Ide/intellij.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/Ide/intellij.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/Ide/neovim.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/Ide/neovim.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/Ide/neovim.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/Ide/neovim.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/Ide/vs-code.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/Ide/vs-code.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/tools/Ide/vs-code.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/Ide/vs-code.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/kcl/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/kcl/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/kcl/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/kcl/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/kcl/docgen.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/kcl/docgen.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/kcl/docgen.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/kcl/docgen.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/kcl/fmt.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/kcl/fmt.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/kcl/fmt.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/kcl/fmt.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/kcl/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/kcl/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/kcl/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/kcl/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/kcl/lint.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/kcl/lint.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/kcl/lint.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/kcl/lint.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/kcl/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/kcl/overview.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/kcl/overview.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/kcl/overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/kcl/test.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/kcl/test.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/kcl/test.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/kcl/test.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/kcl/vet.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/kcl/vet.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/kcl/vet.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/kcl/vet.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/openapi/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/openapi/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/openapi/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/openapi/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/openapi/crd-to-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/openapi/crd-to-kcl.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/openapi/crd-to-kcl.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/openapi/crd-to-kcl.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/openapi/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/openapi/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/openapi/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/openapi/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/openapi/openapi-to-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/openapi/openapi-to-kcl.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/openapi/openapi-to-kcl.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/openapi/openapi-to-kcl.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/openapi/quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/openapi/quick-start.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/openapi/quick-start.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/openapi/quick-start.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/openapi/spec.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/openapi/spec.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/tools/cli/openapi/spec.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/tools/cli/openapi/spec.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/concepts/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/concepts/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/concepts/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/concepts/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/concepts/concepts.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/concepts/concepts.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/concepts/concepts.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/concepts/concepts.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/concepts/package-and-module.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/concepts/package-and-module.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/concepts/package-and-module.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/concepts/package-and-module.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/concepts/type-and-definition.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/concepts/type-and-definition.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/concepts/type-and-definition.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/concepts/type-and-definition.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/getting-started/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/getting-started/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/getting-started/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/getting-started/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/getting-started/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/getting-started/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/getting-started/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/getting-started/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/getting-started/install.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/getting-started/install.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/getting-started/install.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/getting-started/install.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/getting-started/intro.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/getting-started/intro.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/getting-started/intro.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/getting-started/intro.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/getting-started/kcl-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/getting-started/kcl-quick-start.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/getting-started/kcl-quick-start.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/getting-started/kcl-quick-start.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/abstraction.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/abstraction.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/abstraction.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/abstraction.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/automation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/automation.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/automation.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/automation.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/ci-integration/1-github-actions.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/ci-integration/1-github-actions.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/ci-integration/1-github-actions.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/ci-integration/1-github-actions.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/ci-integration/_2-gitlab-ci.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/ci-integration/_2-gitlab-ci.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/ci-integration/_2-gitlab-ci.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/ci-integration/_2-gitlab-ci.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/ci-integration/_3-jenkins-ci.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/ci-integration/_3-jenkins-ci.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/ci-integration/_3-jenkins-ci.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/ci-integration/_3-jenkins-ci.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/ci-integration/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/ci-integration/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/ci-integration/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/ci-integration/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/configuration.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/configuration.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/configuration.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/configuration.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/data-integration.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/data-integration.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/data-integration.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/data-integration.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/gitops/1-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/gitops/1-quick-start.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/gitops/1-quick-start.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/gitops/1-quick-start.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/gitops/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/gitops/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/gitops/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/gitops/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/package-management/1-overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/package-management/1-overview.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/package-management/1-overview.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/package-management/1-overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/package-management/2-installation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/package-management/2-installation.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/package-management/2-installation.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/package-management/2-installation.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/package-management/3-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/package-management/3-quick-start.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/package-management/3-quick-start.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/package-management/3-quick-start.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/package-management/4-how-to/6-push_github_action.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/package-management/4-how-to/6-push_github_action.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/package-management/4-how-to/6-push_github_action.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/package-management/4-how-to/6-push_github_action.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/package-management/4-how-to/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/package-management/4-how-to/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/package-management/4-how-to/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/package-management/4-how-to/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/package-management/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/package-management/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/package-management/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/package-management/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/schema-definition.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/schema-definition.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/schema-definition.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/schema-definition.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/secret-management/1-vault.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/secret-management/1-vault.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/secret-management/1-vault.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/secret-management/1-vault.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/secret-management/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/secret-management/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/secret-management/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/secret-management/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/validation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/validation.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/validation.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/validation.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-k8s/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-k8s/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-k8s/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-k8s/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-k8s/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-k8s/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-k8s/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-k8s/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-konfig/1-overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-konfig/1-overview.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-konfig/1-overview.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-konfig/1-overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-konfig/2-structure.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-konfig/2-structure.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-konfig/2-structure.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-konfig/2-structure.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-konfig/3-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-konfig/3-quick-start.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-konfig/3-quick-start.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-konfig/3-quick-start.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-konfig/4-best-practice.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-konfig/4-best-practice.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-konfig/4-best-practice.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-konfig/4-best-practice.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-konfig/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-konfig/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-konfig/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-konfig/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-kusion/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-kusion/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-kusion/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-kusion/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-kusion/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-kusion/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/guides/working-with-kusion/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/guides/working-with-kusion/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/support/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/support/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/support/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/support/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/support/faq-cli.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/support/faq-cli.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/support/faq-cli.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/support/faq-cli.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/support/faq-install.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/support/faq-install.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/support/faq-install.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/support/faq-install.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/support/faq-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/support/faq-kcl.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/support/faq-kcl.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/support/faq-kcl.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/support/faq-yaml.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/support/faq-yaml.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/support/faq-yaml.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/support/faq-yaml.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/support/support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/support/support.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.0/user_docs/support/support.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5/user_docs/support/support.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/_category_.json deleted file mode 100644 index f763b5c8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "社区", - "position": 5 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/contribute/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/contribute/_category_.json deleted file mode 100644 index 131bb8e3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/contribute/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "贡献指南", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/contribute/contribute-code.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/contribute/contribute-code.md deleted file mode 100644 index 8e8392fe..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/contribute/contribute-code.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -sidebar_position: 2 ---- - -# 如何贡献代码? - -欢迎参与 KCL 共建贡献完善代码、完善代码文档和测试,同时也欢迎通过 Issue 提供反馈。本文主要针对修改和完善已有的代码,如果是希望增加 KCL 语言特性请通过 KEP 流程提交。 - -## 1. 代码和注释中的错别字 - -如果只是修改代码和注释中的错别字,不涉及代码逻辑的调整,那么可以直接在 Github 克隆仓库后直接修改并提交 PR。需要注意的是尽量保持代码风格一致。 - -## 2. 如何贡献 KCL 代码 - -- 先确保本地测试环境正常 -- 修改代码并补充测试 -- 本地测试通过后提交 PR - -## 3. 如何贡献 VS Code 插件代码 - -请参考 VS Code 插件仓库的相关文档 - -## 4. 开发流程相关代码 - -欢迎通过 Issue 和讨论组讨论。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/contribute/contribute-docs.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/contribute/contribute-docs.md deleted file mode 100644 index 7b846680..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/contribute/contribute-docs.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 如何贡献文档? - -本文主要针对已有的文档做局部修改。如果是投稿博客文章、添加新的文档或者调整文档目录结构请先联系团队成员。 - -KCL 文档分为用户指南、开发文档、内部文档、参考手册和博客文章等,他们的区别如下: - -- 用户指南:对应使用文档,是让用户以最小的代价快速使用 KCL 工具完整工作,不要涉及太多的内部原理和实现 -- 开发文档:内部是怎么实现的,主要针对希望了解 KCL 原理和参与贡献和开发的同学 -- 内部文档:针对企业用户的一些内部场景定制的文档 -- 参考手册:KCL 语言、工具和 IDE 等全部特性的文档,内容覆盖最广但比较琐碎 -- 博客文章:没有特别的限制,可以是针对某些具体的场景、某些技术点或者是整体发展展望等分享文章 - -在贡献不同类型的文档时,最好能够结合上面的定位对不同的内容做一些适当的裁剪,给读者最佳体验。 - -## 1. 基本规范 - -- 除标题外,内部小标题尽量带编号,便于阅读 -- 工具自动输出的文档需要由到源代码的链接,小标题可以不带编号 -- 尽量不要贴大段的代码(30行以内),代码最好给出文字解释和对应的参考链接 -- 有图有真相,但是不推荐过度复杂的架构图 -- 内部链接:采用 `/docs/user_docs/getting-started/intro` 绝对路径形式 - -**标点和空格** - -- 在中文的文档中优先使用中文的标点 -- 中文和英文之间需要增加 1 个空格 -- 中文和数字之间需要增加 1 个空格 -- 中文使用全角标点,标点前后均不添加空格 -- 英文内容使用半角标点,标点后面加 1 个空格 -- 链接前后需要保留一个空格,但是段落开头和中文全角标点附近不用添加空格。 - -**图片和资源文件名** - -- 文件名和目录名只能用数字、英文字母、下划线 `_` 和减号 `-` 组成 -- 当前文档的图片放在当前目录的 images 目录下 -- 矢量图片可以通过 [drawio 离线版](https://github.com/jgraph/drawio-desktop/releases) 绘制(并同时提交源文件),以 200% 分辨率导出 png 格式图片 - -## 2. 使用文档内容的基本模式 - -每个使用文档可以看作是一个相对完整的分享或博客文章(参考手册不再此类)。使用文档遵循以下模式组织内容: - -1. 概览:本文希望解决什么问题,达到什么效果,可以先放最终效果截图 -1. 依赖的环境:需要安装什么工具,并给出相关链接 -1. 引入本文构建资源的关系图或架构图 - - 需要用到的 Konfig 模型,给出模型参考页面链接,以及对应的上游原始模型的文档链接 -1. 具体的操作步骤 - - 尽量确保最小化代码,甚至可以刻意隐藏一些干扰代码,同时给出完整代码对应的链接 - - 列出每个步骤命令的概要输出信息,并配以文字描述 -1. 给出测试方式 - - 尽量采用社区通用的方式(比如kube、curl命令、或浏览器)测试 - - 给出测试结果的截图(和开头呼应) -1. 总结和展望 - - 简单回顾当前操作的流程,以及一些可以展开的地方(可以给出一些链接) - -## 3. 测试和提交 PR - -先克隆文档仓库,本地通过 `npm run start` 和 `npm run build` 命令测试查看效果,确保可以正常浏览后提交 PR 即可。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/contribute/contribute.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/contribute/contribute.md deleted file mode 100644 index 692df6ab..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/contribute/contribute.md +++ /dev/null @@ -1 +0,0 @@ -# 贡献指南 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/contribute/git-guideline.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/contribute/git-guideline.md deleted file mode 100644 index c475057d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/contribute/git-guideline.md +++ /dev/null @@ -1,132 +0,0 @@ -# Git 提交指南 - -本文介绍了 Git 提交变更时需要注意的事项,如果拒绝接受本文的内容会导致提交的变更无法被接受。 - -## 1. 关于 issue - -在提交一个 issue 之前,请先查阅已经关闭的 issue ,也许在关闭的 issue 中已经存在合适的解决方案。 - -如果没有找到合适的方案,我们提供了4种模版在创建 issue 的时候使用。 - -- Bug Report : 发现了一个 Bug,可以通过 Bug Report 模版创建 issue 与我们联系。 -- Enhancement : 开发者对工具进行了增强,可以通过 Enhancement 模版创建 issue 来介绍增加的内容。 -- Feature Request : 在使用的过程中想要为工具增加某些新的特性或者功能,可以通过 Feature Request 模版创建 issue 来描述新特性。 -- Ask a Question : 如果有任何的疑问,可以通过 Ask a Question 模版来创建一个 issue 与我们联系。 - -在选择合适的模版后,只需要填写模版上的要求填写的内容即可。如果在创建 issue 的时候发现没有模版,或者模版内容为空,可以通过微信群,钉钉群或者邮件向我们反馈这个问题。 - -## 2. 关于 Git 分支 - -要向 kcl-lang 贡献代码,您必须拥有一个 GitHub 帐户,以便您可以将代码推送到您自己的分支并创建拉取请求。我们推荐参考 [Angular 规范](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines) 为您自己的分支命名。 -推荐的格式如下: - -``` -{type}-{a_short_description} -``` - -分支名称主要包括两个字段,并通过 “-” 分割。其中: - -- {type} : 当前分支内容的类型。 -- {a_short_description}: 一个简短的描述,介绍这个分支的主要内容。 - -e.g. 张三首先 Fork 仓库到自己账户下,然后创建对应名称 `zhangsan:fix-output-fmt-bug` 的分支(冒号之前是张三的账号),用于修复输出格式化 bug。 - -## 3. 关于 Git Commit - -我们参考 [Commitizen](https://github.com/commitizen/cz-cli) 书写 Commit Message。 - -``` -注: 如果直接使用 Commitizen 生成 Commit Message,需要注意因为 Commitizen -是开发人员管理 commit 的工具,与项目本身无关联,因此由 Commitizen 生成的中间产物 -(如: node_modules 文件目录)可能没有在项目 .gitignore 文件中。 - -您可以 git add {filename} 选择要提交的文件而忽视中间产物。 -或者您可以向 .gitignore 文件中添加如下内容而自动忽视中间产物: -# commitizen -package.json -package-lock.json -node_modules/* -``` - -如果手动编写 Commit Message,我们也建议采用 [Commitizen](https://github.com/commitizen/cz-cli) 的 commit message 格式。 - -``` -{type} ( {component_or_file} ) {a_short_description} - {a_longer_description} - BREAKING CHANGE: {breaking_change_description}. - {linked issue} -``` - -其中主要包括6个字段: - -- {type} : 当前 commit 对应的分支的类型。 -- {component_or_file}: 当前 commit 改动的模块或者文件的名称。 -- {a_short_description}: 简短的描述介绍 commit 中的内容。 -- {a_longer_description}: 详细的描述用来介绍 commit 中的内容。 -- {breaking_change_description}: 如果 commit 中包含破环兼容性的改动,需要对兼容性改动产生的影响进行介绍。 -- {linked issue}: 与当前这个 commit 关联的 issue。 - -其中 {breaking_change_description} 和 {linked issue} 如果 commit 中不包含破坏兼容性的改动和关联的 issue,可以省略。 - -e.g. 张三在分支 `zhangsan:fix-output-fmt-bug` 中创建的 commit。 - -``` - - fix(kcl-printer): fix an output format bug in kcl-printer - - There is an output format bug in kcl-printer because ..., - So, The calling of method "XXX" is replaced by "HHHH"..., - ... - - -- 如果没有破坏兼容性的改动和关联的 issue 可以省略下面内容。 - - BREAKING CHANGE: This change maybe cause ....... - - fix #123 - -``` - -## 4. 关于 pull request - -在提交一个 PR 之前,可能需要优先考虑以下几个问题: - -- 请先查阅已经关闭的 PR ,也许在已经关闭的 PR 中,可能存在已经完成的解决方案。 -- 我们建议在提交变更之前,提交一个对应的 issue 描述变更中将要解决的问题,并将变更对应的 PR 与 issue 关联。 -- 在向我们提交 PR 之后,请签署 [Contributor License Agreement (CLA)](#cla) ,如果拒绝签署,我们将无法接受 PR。 -- 请确保每次改动都创建了一个新的分支,并根据上文中提到的规范为分支命名。 -- 一次 PR 请不要超过两个 commit ,请将多余的 commit 通过 squash 压缩,并根据上文中提到的规范,编写 commit message 。 -- 我们提供了 [PR 模版](https://github.com/kcl-lang/.github/blob/main/.github/PULL_REQUEST_TEMPLATE.md),只需要添加模版中要求的内容即可,如果在创建PR时发现没有模版或者模版内容为空,可以通过微信群,钉钉群或者邮件向我们反馈这个问题。 - -我们建议PR的标题与分支名、commit message 风格保持一致: - -``` -{type} ( {component_name_or_file_name} ) :{a_short_description} -``` - -e.g. 张三为分支`fix/zhangsan/fix_output_fmt_bug`创建的PR名称。 - -``` -fix(kcl-printer): fix an output format bug in kcl-printer. -``` - -## 5. 目前 type 支持的类型 - -参考[Angular 规范](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines),type 支持类型的类型如下: - -``` -- feat: -- 添加了新的功能特性。 -- fix: -- 进行了 Bug 的修复。 -- docs: -- 进行了文档部分的修改。 -- style: -- 对代码格式的修改,并不影响代码的功能,如:删除多余空格,代码缩进等。 -- refactor: -- 在不改变代码功能的基础上对代码进行了的重构。 -- perf: -- 对代码进行了性能优化。 -- test: -- 添加或者调整已有的测试用例。 -- build: -- 对构建系统或者外部依赖库进行了调整。 -- ci: -- 调整了 CI 的配置文件或者脚本。 -- chore: -- 对源代码和测试文件之外其他部分的调整。 -- revert: -- 对 commit 进行回滚。 -``` - -## 6. Contributor License Agreement (CLA) - -在第一次向我们提交 PR 之后,在 PR 中的 CLA 检查将会失败并提示签署 CLA。您可以通过自己的账户之间在 PR 回复 "I have read the CLA Document and I hereby sign the CLA" 表示同意签署 CLA,然后手动重启失败的 CLA 检查 Action 即可。当 PR 被成功合并之后将会被锁定不能再修改。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/intro/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/intro/_category_.json deleted file mode 100644 index e4cb1869..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/intro/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "简介", - "position": 1 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/intro/intro.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/intro/intro.md deleted file mode 100644 index af94bc33..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/intro/intro.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 社区 - -欢迎来到 KCL 开源社区,每个人的参与都是所有开源项目健康成长的动力!有很多方法可以参与开源。每个人都可以通过提交PR(Pull Request)来创建问题或修复 bug、改进文档或修改代码, - -可以查看[社区](https://github.com/kcl-lang/community)并加入我们。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/intro/license.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/intro/license.md deleted file mode 100644 index fe1db435..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/intro/license.md +++ /dev/null @@ -1,211 +0,0 @@ ---- -sidebar_position: 99 ---- - -# 许可 - -KCL 使用 [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0): - -``` - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2023 The KCL Authors. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/intro/support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/intro/support.md deleted file mode 100644 index 70ecd7e8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/intro/support.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 寻求帮助 - -KCL拥有一个由众多爱好者组成的开发者和用户社区。在此页面上,我们列出了您可以参与的KCL相关社区;有关其他在线和离线学习材料,请参阅本节的其他页面。 - -在加入 KCL 社区之前,请阅读[贡献者条款](https://www.contributor-covenant.org/version/2/0/code_of_conduct/),所有社区成员都需要遵守这些条款。 - -## 讨论 - -- 在 Github 上提交问题 -- 在 Github 讨论组中交流 -- 通过官方网站、Github、Twitter、微信和其他帐户获取 KCL 最新状态。可以查看[社区](https://github.com/kcl-lang/community)并加入我们。 - -## 新功能 - -请尽量避免提交新功能的拉取请求,我们可能已经有人在处理这些功能,或者这个功能已经是我们未来计划的一部分。总之,请在提交新功能之前与我们联系! diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/release-policy/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/release-policy/_category_.json deleted file mode 100644 index bf01a053..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/release-policy/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "发布策略", - "position": 3 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/release-policy/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/release-policy/index.md deleted file mode 100644 index a4a0bc3d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/release-policy/index.md +++ /dev/null @@ -1 +0,0 @@ -# 发布策略 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/release-policy/kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/release-policy/kcl.md deleted file mode 100644 index 0f9115b8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/release-policy/kcl.md +++ /dev/null @@ -1,39 +0,0 @@ -# KCL 发布策略 - -KCL 开发团队采用 [语义化版本](https://semver.org/lang/zh-CN/) 来简化管理。版本格式:主版本号.次版本号.修订号。版本号递增规则如下:主版本号对应不兼容的 API 修改,次版本号对应向下兼容的功能性新增,修订号对应向下兼容的问题修正。总体目标是每一个半月发布一个特性增强的次要版本,根据需要不定期发布其他版本的修订。 - -KCL 项目版本发布策略如下: - -- 主版本号:当进行重大的架构调整或者加入重大的新功能时,需要提升主版本号。对于 KCL 项目来说,目前的主版本号为 0。 -- 次版本号:当添加的功能和特性有较大的变化时,提升次版本号。目前的次版本号为 5,2023 年度会相继发布 0.5, 0.6, 0.7 版本。 -- 修订号:通过修复漏洞或者改进性能来更新程序时,会提升修订号,修订号从 0 开始计数以此加 1。 -- 发布周期:在未达到 v1.0.0 版本之前,计划每隔 3 个月发布一个新的次要版本。在此期间,需要持续收集用户反馈,并进行必要的修复和改进。 -- 发布流程:在发布新版本之前,需要进行严格的测试和审核,确保新版本的质量。封板并测试完成后,会在 Github 上发布新版本的源代码,二进制和镜像,并提供详细的文档和使用指南。 -- 版本支持:我们将对最新的版本提供长期支持,包括漏洞修复和安全更新。对于旧版本,我们将提供有限的支持,仅在必要时进行修复。 - -## 发布流程与规则 - -- 特性开发:main 分支主干开发,分支发布,block 用户使用的问题和严重的 bug, 安全隐患,高优先级解决,尽可能保持在一周内收敛,高于一般的功能研发。 -- 迭代周期:我们的迭代周期通常为 3 个月,即每 3 个月发布一个新的次要版本。 -- 版本规划:发版前两周产出 alpha 版本,前一周产出 beta 版本,alpha 版本仍可进行特性合并,beta 版本只合并错误修复,最终产出正式版本并打 tag 作为长期保存的 release 分支。 -- 发版计划:在每个发布周期开始时制定详细的发版计划(Github Milestone),包括发布日期、版本号、功能列表和测试计划等。需要尽可能地遵守发版计划,确保按时发布新版本。 -- 发布前测试:在发布新版本之前,需要进行全面的测试,包括单元测试、集成测试,模糊测试,压测,用户验收测试等。只有经过测试并无问题后,我们才会发布新版本。 -- 版本回滚:如果在发布后发现了严重的问题,需要立即回滚版本,并尽快修复问题。并通过邮件、社交媒体等渠道及时通知用户,并提供解决方案。 -- 发布文档:需要在发布时提供详细的文档,包括发布说明、更新日志、API 文档和使用指南等,帮助用户了解和使用新版本。在 KCL 中,我们统一在 KCL 网站进行维护。 -- 版本兼容性:在发布新版本时,需要尽可能保持兼容性,以确保用户无需进行过多的修改和适应。KCL 还没有达到 v1,暂时没有兼容性保证。KCL 的目标是尽可能少地进行重大更改,不应轻率地考虑对语言的更改,为了语言自身更好地演进和发展,一般认为更改具有重大好处时才会进行(较好地解决了目标场景的问题或者提升了绝大用户的使用体验)。对于可能引入兼容性问题的功能或变更,提供相应的提示和解决方案,同时会提供逐步升级的指南或提供自动迁移的工具,以帮助用户平滑地迁移到新版本。 - -## 发布组件 - -![](/img/docs/community/release-policy/kcl-components.png) - -每次版本发布时,KCL 相关所有组件保持一个依赖同一个 KCL 核心主要版本,整体采用树形结构组织依赖顺序发布并进行回归测试,直到发布测试完成,尽力避免三角依赖,禁止循环依赖。 - -## 一个 Feature 的生命周期 - -- 设计方案/文档:通过 Issue 回答清楚这个 feature 的动机是什么,它解决什么问题以及目标是什么,用户需求和用户故事是怎样的;这个 feature 做什么,如何做,难度怎样,需要多长时间,依赖项,需要做什么测试等。(Tips: 大的设计尽量拆分成小的设计,通过权衡和广泛的调研找到一个简单且可持续的解决方案,并且具备一定得到可扩展以适应未来的业务或技术变化,通过持续讨论和方案评审确定最终设计)。 -- 编写代码:通过高频小改动进行迭代、持续沟通和协作,提前设计单元测试、集成测试和 benchmark 等测试用例,确保编写代码 100% 测试覆盖,注释完整和逻辑清晰,并通过 Demo 演示持续收集反馈。 -- 文档撰写:在 [KCL 网站](https://kcl-lang.io) 中更新用户文档。 -- 测试和反馈:在发布功能之前,让一些同行/用户通过**随循文档**而不是口述来尝试和测试这些新功能。接收反馈并改进。 -- 发布和公告:撰写 Release Note, PR 文章,场景和新特性解读等以及渠道宣发等。 - -> 注:以上所有信息全是公开的,需要透出给所有社区研发者进行参与、讨论和贡献。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/release-policy/roadmap.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/release-policy/roadmap.md deleted file mode 100644 index 2f0ee86a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/community/release-policy/roadmap.md +++ /dev/null @@ -1,3 +0,0 @@ -# 路线规划 - -![](/img/docs/community/release-policy/roadmap.jpg) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/_category_.json deleted file mode 100644 index 1910abe4..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "参考手册", - "position": 5 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/cheatsheets/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/cheatsheets/_category_.json deleted file mode 100644 index 7839b7a2..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/cheatsheets/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "备忘录", - "position": 10 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/cheatsheets/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/cheatsheets/index.md deleted file mode 100644 index 6bfb2e4c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/cheatsheets/index.md +++ /dev/null @@ -1,5 +0,0 @@ -# KCL 备忘录 - -![](/img/docs/reference/cheatsheets/cheatsheet.png) - -[Download PDF](https://github.com/kcl-lang/kcl-lang.io/blob/main/cheatsheet/cheatsheet.pdf) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/index.md deleted file mode 100644 index 9fd0c276..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/index.md +++ /dev/null @@ -1 +0,0 @@ -# 学习 KCL diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/_category_.json deleted file mode 100644 index 6066c82b..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KCL", - "position": 1 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/codelab/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/codelab/_category_.json deleted file mode 100644 index c0133443..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/codelab/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "代码实验室", - "position": 2 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/codelab/collaborative.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/codelab/collaborative.md deleted file mode 100644 index 883f4853..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/codelab/collaborative.md +++ /dev/null @@ -1,345 +0,0 @@ ---- -title: "使用配置操作分块编写配置" -linkTitle: "使用配置操作分块编写配置" -type: "docs" -weight: 2 -description: 使用配置操作分块编写配置 -sidebar_position: 3 ---- - -## 1. Introduction - -KCL 是一种简单易用的配置语言,用户可以简单地编写可重复使用的配置代码。 - -在这个教程中,我们将学习如何使用 KCL 配置操作(config operation)功能以协同的方式编写配置。 - -### 本节将会学习 - -1. 定义 schema 并组织项目目录。 -2. 通过KCL的配置操作功能创建多个环境配置。 -3. 配置编译参数和测试。 - -## 2. 定义 Schema 和 组织项目目录 - -### Schema 定义 - -假设我们想定义具有某些属性的服务器配置,我们可以通过创建一个 `server.k` 文件来创建一个简单的配置,我们可以填写以下代码来定义服务器配置的可重用模式: - -```python -import units - -type Unit = units.NumberMultiplier - -schema Server: - replicas: int = 1 - image: str - resource: Resource = {} - mainContainer: Main = {} - labels?: {str:str} - annotations?: {str:str} - -schema Main: - name: str = "main" - command?: [str] - args?: [str] - ports?: [Port] - -schema Resource: - cpu?: int = 1 - memory?: Unit = 1024Mi - disk?: Unit = 10Gi - -schema Port: - name?: str - protocol: "HTTP" | "TCP" - port: 80 | 443 - targetPort: int - - check: - targetPort > 1024, "targetPort must be larger than 1024" -``` - -在上面的代码中,我们定义了一个名为 Server 的 schema,该 schema 表示用户将要编写的配置类型,其中包含一些基本类型属性(例如`replicas`、`image` 等)和一些复合类型属性(例如 `resource`、`main` 等)。除了一些在 [schema codelab](./schema.md)中提到的基本类型之外,我们可以看到上面的代码中有两种类型 `Unit` 和 `units.NumberMultiplier`。其中,`units.NumberMultiplier` 表示 KCL 数字单位类型,意味着可以在 KCL 数字后添加自然单位或二进制单位,例如 `1K` 表示 `1000`,`1Ki` 表示 `1024`。 `Unit` 是 `units.NumberMultiplier` 的类型别名,用于简化类型注释的编写。 - -### 项目目录 - -为了完成协同的配置的开发,我们首先需要一个配置项目,其中包含测试应用程序的配置以及不同环境的差异化配置,因此我们正在创建以下项目目录: - -``` -. -├── appops -│ └── test_app -│ ├── base -│ │ └── base.k -│ ├── dev -│ │ ├── ci-test -│ │ │ └── stdout.golden.yaml -│ │ ├── kcl.yaml -│ │ └── main.k -│ └── prod -│ ├── ci-test -│ │ └── stdout.golden.yaml -│ ├── kcl.yaml -│ └── main.k -├── kcl.mod -└── pkg - └── sever.k -``` - -该项目目录主要包含三个部分: - -- `kcl.mod`:用于标识KCL项目的根目录的文件。 -- `pkg`:不同应用程序配置所共用的 `Server Schema` 结构。 -- `appops`:不同应用程序的 Server 配置,目前仅包含一个名为 `test_app` 的应用程序。 - - `base`:供所有环境使用的应用程序通用配置。 - - `dev`:供开发环境使用的应用程序配置。 - - `prod`:供生产环境使用的应用程序配置。 - -后续章节将会介绍`base.k`、`main.k`、`kcl.yaml` 和 `ci-test/stdout.golden.yaml` 的含义。 - -## 3. 通过 KCL 配置操作功能创建多个环境配置 - -### 创建基线配置 - -在组织好项目目录和基本的服务器配置模型之后,我们可以编写用户应用程序的配置。我们可以创建自己的测试应用程序文件夹 `test_app`,并将其放置在应用程序配置文件夹 `appops` 中。 - -对于应用程序的配置,我们通常将其分为基本配置和多个环境的差异化配置并进行合并。通过 KCL 的配置合并功能,我们可以轻松实现这一点。假设我们有开发环境和生产环境的两个配置,我们可以创建三个文件夹:`base`、`dev` 和 `prod` 分别存储基线、开发环境和生产环境的配置。首先,我们编写 `base/base.k` 的配置: - -```python -import pkg - -server: pkg.Server { - # 设置镜像的值为 "nginx:1.14.2" - image = "nginx:1.14.2" - # 添加 app label - labels.app = "test_app" - # 添加一个mainContainer配置,它的端口是 [{protocol = "HTTP", port = 80, targetPort = 1100}] - mainContainer.ports = [{ - protocol = "HTTP" - port = 80 - targetPort = 1100 - }] -} -``` - -正如上述代码中所示,我们使用 `import` 关键字在 `base.k` 中导入放置在 `pkg` 下的 `Server` schema,并使用它实例化一个名为`server` 的配置,在其中将 `image` 属性设置为 `"nginx:1.14.2"`,并添加一个带有值为 `test_app` 的标签 `app`。此外,我们还在 `ports` 属性中添加了主容器 `mainContainer` 的配置,其值为 `[{protocol = "HTTP", port = 80, targetPort = 1100}]`。 - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k -``` - -输出: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2 - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app -``` - -当前,我们已经有了一个基线配置。 - -### 创建多重环境配置 - -接下来我们将配置一个差异化的多环境配置。首先假设我们想在开发环境中使用自己的临时镜像 `nginx:1.14.2-dev`,然后使用它来覆盖基准中的服务器配置,我们可以在 `dev/main.k` 中编写以下配置: - -```python -import pkg - -server: pkg.Server { - # 覆盖 base 配置中的声明的镜像 - image = "nginx:1.14.2-dev" -} -``` - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -输出: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app -``` - -可以看出输出的 YAML 文件的 `image` 字段被覆盖为 `nginx:1.14.2-dev`。假设我们还想将一个具有键为 `env`,值为 `dev` 的标签添加到 `dev` 环境中,我们将以下代码添加到 `dev/main.k` 中: - -```python -import pkg - -server: pkg.Server { - # 覆盖 base 配置中的声明的镜像 - image = "nginx:1.14.2-dev" - # 将新标签 env 合并到 base 标签中 - labels.env = "dev" -} -``` - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app - env: dev -``` - -可以看到输出的 YAML 文件的 `labels` 字段中有两个标签。 - -此外,我们还可以使用 `+=` 运算符将新值添加到列表类型属性中,例如在基准环境中的 `mainContainer.ports` 配置,继续修改 `dev/main.k` 中的代码: - -```python -import pkg - -server: pkg.Server { - # 覆盖 base 配置中的声明的镜像 - image = "nginx:1.14.2-dev" - # 将新标签 env 合并到 base 标签中 - labels.env = "dev" - # 在 base ports配置中添加一个 port - mainContainer.ports += [{ - protocol = "TCP" - port = 443 - targetPort = 1100 - }] -} -``` - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -输出: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - - protocol: TCP - port: 443 - targetPort: 1100 - labels: - app: test_app - env: dev -``` - -使用相同的方法,我们可以构建生产配置,在 `dev/main.k` 文件中编写代码,并为其添加标签。 - -```python -import pkg - -server: pkg.Server { - # 将新标签 env 合并到 base 标签中 - labels.env = "prod" -} -``` - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k appops/test_app/prod/main.k -``` - -输出: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2 - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app - env: prod -``` - -## 4. 配置编译参数和测试 - -在前面的章节中,我们通过代码构建了一个多环境配置。可以看出不同环境的 KCL 命令行编译参数相似,因此我们可以将这些编译参数配置到一个文件中,并将其输入到 KCL 命令行中进行调用。请将以下代码配置在 `dev/kcl.yaml`中: - -```yaml -kcl_cli_configs: - files: - - ../base/base.k - - main.k - output: ./ci-test/stdout.golden.yaml -``` - -然后我们可以使用以下命令在开发环境中编译配置: - -```bash -cd appops/test_app/dev && kcl -Y ./kcl.yaml -``` - -此外,我们已经在 `dev/kcl.yaml` 中配置了 `output` 字段,以将 YAML 输出到文件,以便进行后续配置分发或测试。您可以通过遍历每个环境中的 `kcl.yaml` 构建,并将其与 `./ci-test/stdout.golden.yaml` 进行比较,可以验证应用程序的配置是否符合预期。 - -## 5. 最后 - -恭喜! - -我们已经完成了关于 KCL 的第三课。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/codelab/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/codelab/index.md deleted file mode 100644 index 123c0878..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/codelab/index.md +++ /dev/null @@ -1 +0,0 @@ -# 代码实验室 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/codelab/schema.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/codelab/schema.md deleted file mode 100644 index 434e1f5c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/codelab/schema.md +++ /dev/null @@ -1,814 +0,0 @@ ---- -title: "使用 KCL Schema 编写复杂配置" -linkTitle: "使用 KCL Schema 编写复杂配置" -type: "docs" -weight: 2 -description: 使用 KCL Schema 编写复杂配置 -sidebar_position: 2 ---- - -## 1. 介绍 - -KCL 是一种简单易用的配置语言,用户可以简单地编写可重用的配置代码。 - -在本节教程中,我们将学习如何使用 KCL 编写定制配置,这样我们就可以定义一个架构并以协作方式编写配置。 - -### 本节将会学习 - -1. 定义一个简单的 schema -2. 为 schema 字段设置默认的不可变值 -3. 基于简单的 schema 创建配置 -4. 在 schema 中编写复杂的逻辑 -5. 通过 schema 的组合创建新的 schema -6. 使用 dict/map 创建具有深度嵌套 schema 的配置 -7. 通过 schema 继承创建新的 schema -8. 通过多个 mixin schema 创建新的 schema -9. 声明 schema 验证规则 -10. 配置 schema 的输出布局 -11. 共享和重用 schema - -## 2. 编写简单的 Schema - -假设我们希望定义一个具有特定属性的工作负载,我们可以通过创建一个 `my_config.k` 文件来创建一个简单的配置。我们可以按以下方式填写下面的代码,定义一个可重复使用的部署配置的 schema: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels: {str:str} -``` - -在上述代码中,`cpu` 和 `memory` 被定义为 int 值;`name`、`image` 和 `service` 是字符串;`command` 是由字符串构成的列表;`labels` 是字典类型,其键和值的类型均为字符串。 - -另外,每个属性都**必须**被赋予非 None 值作为 schema 实例,除非它被标记问号 **?** 而作为可选参数。 - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels?: {str:str} # labels 是一个可选的参数 -``` - -当存在继承关系时: - -- 如果在基 schema 中该属性为可选(optional)参数,则在子 schema 中它应该是可选的(optional)或必需的(required)。 -- 如果在基 schema 中该属性为必需(required)属性,则在子 schema 中它需要是必需的(required)。 - -## 3. Enhance Schema as Needed - -Suppose we need to set default values to service and replica, we can make them as below: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str = "my-service" # defaulting - replica: int = 1 # defaulting - command: [str] - labels?: {str:str} # labels is an optional attribute -``` - -And then we can set the service type annotation as the string literal type to make it immutable: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: "my-service" = "my-service" - replica: int = 1 - command: [str] - labels?: {str:str} -``` - -In the schema, type hint is a `must`, for example we can define cpu as `cpu: int`. - -Specially, we can define a string-interface dict as `{str:}`, and in case we want to define an object or interface, just define as `{:}`. - -## 4. 基于简单 Schema 创建配置 - -现在我们有了一个简单的 schema 定义,我们可以用它来定义配置: - -```python -nginx = Deployment { - name = "my-nginx" - cpu = 256 - memory = 512 - image = "nginx:1.14.2" - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python - kcl my_config.k -``` - -标准输出: - -```yaml -nginx: - name: my-nginx - cpu: 256 - memory: 512 - image: nginx:1.14.2 - service: my-service - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -> 有关集合数据类型和块的更多详细信息,请查看手册和规范。 - -此外,**配置选择器表达式**(config selector expressions)可以用于初始化 schema 实例,我们可以忽略配置表达式中行末的逗号。 - -```python -nginx = Deployment { - name = "my-nginx" - cpu = 256 - memory = 512 - image = "nginx:1.14.2" - command = ["nginx"] # 忽略行尾的逗号 - labels.run = "my-nginx" # schema 中的字典变量可以使用选择器表达式 - labels.env = "pre-prod" # schema 中的字典变量可以使用选择器表达式 -} -``` - -## 5. 在 Schema 中编写更为复杂的逻辑 - -假设我们有一些schema逻辑,我们可以将它包装进 schema 中: - -```python -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - image: str - service: "my-service" = "my-service" - replica: int = 1 - command: [str] - labels?: {str:str} - - _cpu = 2048 - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 -``` - -现在,我们可以通过创建 schema 实例来定义配置,并将优先级作为参数传递给模式: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl my_config.k -``` - -标准输出: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - image: nginx:1.14.2 - service: my-service - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 6. 通过 Schema 组合创建新 Schema - -现在我们想要定义一个详细的 schema,包括服务(service)和卷(volumes),我们可以按以下方式进行操作: - -```python -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - volumes?: [Volume] - image: str - service?: Service - replica: int = 1 - command: [str] - labels?: {str:str} - - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 - -schema Port: - name: str - protocol: str - port: int - targetPort: int - -schema Service: - name: "my-service" = "my-service" - ports: [Port] - -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -在这种情况下,Deployment 由 Service 和一系列 Volume 组成,而 Service 又由一系列 Port 组成。 - -## 7. 使用 dict/map 创建具有深度嵌套 schema 的配置 - -现在我们有一个新的 Deployment schema,但我们可能会注意到,它包含多层嵌套的结构,在复杂的结构定义中,这是非常常见的,我们通常必须编写命令式组装代码来生成最终结构。 - -使用 KCL,我们可以使用简单的字典声明创建配置,并具有完整的 schema 初始化和验证功能。例如,我们可以按照以下方式使用新的 Deployment schema简单地配置 nginx: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl my_config.k -``` - -标准输出: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -请注意,我们用于定义 Deployment 配置的字典必须与 schema 定义对齐,否则我们将会得到一个错误。例如,假设我们将服务端口的类型定义错误如下: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = [80] # 错误的数据类型,试图将 List 分配给 int - targetPort = 9376 - }] -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl my_config.k -``` - -标准错误输出: - -``` -The type got is inconsistent with the type expected: expect int, got [int(80)] -``` - -## 8. 声明 Schema 验证规则 - -现在我们已经看到了一个复杂的 schema,在其中每个字段都有一个类型提示,以使其更加不容错(error-prone)。 - -但是这还不够好,我们希望为我们的 schema 支持更多的增强验证,以便尽快发现 schema 和配置中的代码错误。许多验证规则,如 None 类型检查、范围检查、值检查、长度检查、正则表达式匹配、枚举检查已经被添加或陆续添加进来。以下是一段代码示例: - -```python -import regex - -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - volumes?: [Volume] - image: str - service?: Service - replica: int = 1 - command: [str] - labels?: {str:str} - - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 - - check: - multiplyof(cpu, 256), "cpu must be a multiplier of 256" - regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$"), "image name should be like 'nginx:1.14.2'" - 1 <= replica < 100, "replica should be in range (1, 100)" - len(labels) >= 2 if labels, "the length of labels should be large or equal to 2" - "env" in labels, "'env' must be in labels" - len(command) > 0, "the command list should be non-empty" - -schema Port: - name: str - protocol: str - port: int - targetPort: int - - check: - port in [80, 443], "we can only expose 80 and 443 port" - protocol in ["HTTP", "TCP"], "protocol must be either HTTP or TCP" - 1024 < targetPort, "targetPort must be larger than 1024" - -schema Service: - name: "my-service" = "my-service" - ports: [Port] - - check: - len(ports) > 0, "ports list must be non-empty" - -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -由于schema定义的属性默认是**必需的**(required),因此可以省略判断变量不能为 None/Undefined 的验证。 - -```python -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -现在我们可以基于新的 schema 编写配置,并及时暴露配置错误。例如,使用以下无效的配置: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1142" # 镜像值不匹配正则表达式 - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -每个字段都是类型有效的,但镜像名无效。 - -运行 KCL,我们将看到如下错误信息: - -KCL 命令: - -```python -kcl my_config.k -``` - -标准错误输出: - -``` -Schema check is failed to check condition: regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$"), "image name should be like 'nginx:1.14.2'" -``` - -> KCL 的验证功能涵盖了 Openapi 定义的验证,因此我们可以通过 KCL 编写任何 API 验证。 - -## 9. 通过 Schema 继承创建新 Schema - -现在,我们拥有了一个稳定的部署 schema 定义,可以用它来声明配置。 - -通常,部署 schema 将被用于多个场景中。我们可以直接使用 schema 在不同的用例中声明配置(见上文的部分),或者我们可以通过继承生成一个更具体的 schema 定义。 - -例如,我们可以使用部署 schema 作为基础,来定义 nginx 的基本 schema,并在每个场景中扩展定义。在这种情况下,我们定义了一些常用的属性。请注意,我们使用“final”关键字将名称标记为不可变,以防止被覆盖。 - -```python -schema Nginx(Deployment): - """ A base nginx schema """ - name: "my-nginx" = "my-nginx" - image: str = "nginx:1.14.2" - replica: int = 3 - command: [str] = ["nginx"] - -schema NginxProd(Nginx): - """ A prod nginx schema with stable configurations """ - volumes: [Volume] = [{ - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - """ A volume mapped to host path """ - service: Service = { - ports = [{ - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] - } - """ An 80 port to target backend server """ -``` - -现在我们有了一些 nginx 的静态配置。建议将我们认为是静态的配置声明在那里,并将更多的动态配置放在下面: - -```python -nginx = Nginx { - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -```python -nginx = NginxProd { - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -现在,我们只需要通过运行时标签值 “prod” 来简单定义 不那么静态的 nginx 生产环境配置。 - -实际上,在某些复杂情况下,我们可以将所有配置分为基本配置、业务配置和环境配置定义,并基于此实现团队成员之间的协作。 - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl prod_config.k -``` - -标准输出: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 3 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 10. Create New Schema by Multiple Protocol and Mixin Schemas Inheritance - -现在,我们可以通过 Deployment schema 完成服务器配置的声明。 - -然而,通常实际情况更为复杂,部署可能有各种可选变量附件。 - -例如,我们想要在现有 schema 中支持声明持久卷,作为可重用的 Kubernetes schema。在这种情况下,我们可以通过以下 `mixin` 和 `protocal` 进行包装: - -```python -import k8spkg.api.core.v1 - -protocol PVCProtocol: - pvc?: {str:} - -mixin PersistentVolumeClaimMixin for PVCProtocol: - """ - PersistentVolumeClaim (PVC) sample: - Link: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims - """ - - # Mix in a new attribute `kubernetesPVC` - kubernetesPVC?: v1.PersistentVolumeClaim - - if pvc: - kubernetesPVC = v1.PersistentVolumeClaim { - metadata.name = pvc.name - metadata.labels = pvc.labels - spec = { - accessModes = pvc.accessModes - resources = pvc.resources - storageClassName = pvc.storageClassName - } - } -``` - -有了 PersistentVolumeClaimMixin,我们使用清晰的用户界面(user interface)定义了一个 PVC schema,并使用 Kubernetes PVC 作为实现。然后,我们可以使用 Deployment schema 和 PVC mixin schema 定义一个 server schema。 - -```python -schema Server(Deployment): - mixin [PersistentVolumeClaimMixin] - pvc?: {str:} - """ pvc user interface data defined by PersistentVolumeClaimMixin """ -``` - -在 Server schema 中,Deployment schema 是基础 schema,而 PersistentVolumeClaimMixin 是一个可选附加项,其用户界面数据为`pvc?:{str:}`。 - -请注意,mixin 通常用于向宿主 schema 添加新属性,或修改宿主 schema 的现有属性。因此,mixin 可以使用宿主 schema 中的属性。由于其被设计为可重用,因此我们需要一个额外的协议来限制 mixin 中宿主 schema 中属性的名称和类型。 - -现在,如果我们想要使用 PVC 进行部署,只需声明用户界面: - -```python -server = Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] - pvc = { - name = "my_pvc" - accessModes = ["ReadWriteOnce"] - resources.requests.storage = "8Gi" - storageClassName = "slow" - } -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl server.k -``` - -标准输出: - -```yaml -server: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod - pvc: - name: my_pvc - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 8Gi - storageClassName: slow ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: my_pvc -spec: - accessModes: - - ReadWriteOnce - storageClassName: slow - resources: - requests: - storage: 8Gi -``` - -如果我们不需要持久卷,只需删除 pvc 配置块。 - -## 11. 共享和重用 Schema - -可以通过导入来共享 Server schema,我们只需要将代码与 KCL 一起打包即可。 - -```python -import pkg - -server = pkg.Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -另一个关于共享代码的技巧是:在同一包下的模块不需要相互导入。 - -假设我们在 pkg 中有如下 models: - -``` -pkg/ - - deploy.k - - server.k - - pvc.k -``` - -在 `server.k` 中,我们可以只使用 `deploy.k` 中的 Deployment schema 和 `pvc.k` 中的 pvc schema 而无需导入: - -```python -# 无需 import -schema Server(Deployment): - mixin [PersistentVolumeClaimMixin] - pvc?: {str:} - """ pvc user interface data defined by PersistentVolumeClaimMixin """ -``` - -然后用户必须导入 pkg 才能作为一个整体使用它: - -```python -import pkg - -server = pkg.Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [pkg.Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } - service.ports = [pkg.Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -运行 KCL 命令: - -```python -kcl pkg_server.k -``` - -Output: - -```yaml -server: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 12. 最后 - -恭喜! - -我们已经完成了 KCL 的第二节课。我们使用 KCL 来替换我们的 key-value 文本文件,以便获得更好的可编程性。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/codelab/simple.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/codelab/simple.md deleted file mode 100644 index 32ad2612..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/codelab/simple.md +++ /dev/null @@ -1,495 +0,0 @@ ---- -title: "使用 KCL 编写简单配置" -linkTitle: "使用 KCL 编写简单配置" -type: "docs" -weight: 2 -description: 使用 KCL 编写简单配置 -sidebar_position: 1 ---- - -## 1. 介绍 - -KCL 是一种简单易用的配置语言,用户可以简单地编写可重用的配置代码。 - -在这个第一个教程中,我们将学习如何使用 KCL 编写一个简单的配置。 - -学习这个代码实验只需要基本的编程知识,如果你有 Python 经验,将会更容易上手。 - -### 本节将会学习 - -1. 用一种可编程的方式编写简单的 key-value 配置 -2. 使用 KCL 编写简单的逻辑 -3. 使用 KCL 编写集合(collections) -4. 使用 KCL 代码进行测试和调试 -5. 在 KCL 代码中使用内置(built-in)支持 -6. 共享和重用 KCL 代码 -7. 使用动态输入参数编写配置 - -## 2. 编写Key-Value键值对 - -通过创建 `my_config.k` 来生成一个简单的配置,我们可以填充下面的代码,并且不需要严格的格式描述部署的配置。 - -```python -cpu = 256 -memory = 512 -image = "nginx:1.14.2" -service = "my-service" -``` - -在上述代码中,cpu 和 memory 被声明为 int 类型的值,而 image 和 service 被声明为字符串字面值。 - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -KCL 命令: - -```bash -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -可导出变量(exported variable)默认情况下是不可变的,一旦声明,就不能在其他地方修改它。 - -## 3. 编写简单逻辑 - -有时候我们想在配置中编写一些逻辑,那么我们就可以使用: - -- 以 `_` 开头的非导出可变变量(mutable and non-exported variable) -- if-else 语句 - -非导出变量表示它不会出现在输出的 YAML 中,且它可以被多次赋值。 - -这是一个示例,显示如何根据条件调整资源。 - -KCL 命令: - -```python -kcl my_config.k -``` - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -image = "nginx:1.14.2" -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -```python -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -.. 注意:: -KCL 对运算符和字符串成员函数有丰富的支持,请阅读手册和规范以了解更多细节。 - -## 4. 编写集合 - -我们可以使用集合来表示复杂的数据类型。已支持的集合类型有: - -- list -- dict - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -command = ["nginx"] # 列表 -labels = {run = "my-nginx"} # a dict -image = "nginx:1.14.2" -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -KCL 命令: - -```bash -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx -image: nginx:1.14.2 -service: my-service -``` - -> 有关集合数据类型和成员函数的更多信息,请查阅手册和规范。 - -## 5. 在集合中添加元素 - -我们可以将逻辑表达式、推导式、切片、联合类型等特性组合起来,动态地将元素添加到集合中。 - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 -_env = "pre-prod" - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -_command = ["nginx"] # 列表 -_command = _command + ["-f", "file"] # 使用 + 运算符将元素附加到命令中以连接两个列表 -command = [c.lower() for c in _command] # # 将列表中的每个元素转为小写 -_labels = { - run = "my-nginx" - if _env: - env = _env # 当 _env 不是 None/Undefined 或为空时使用 if 表达式添加一个字典键值对 -} # 字典 -labels = _labels -image = "nginx:1.14.2" -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -```python -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 256 -memory: 512 -command: - - nginx - - -f - - file -labels: - run: my-nginx -image: nginx:1.14.2 -service: my-service -``` - -## 6. 编写断言 - -为了使代码可测试且健壮,我们可以使用断言(assertions)验证配置数据。 - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -command = ["nginx"] # 列表 -labels = {run = "my-nginx"} # 字典 -image = "nginx:1.14.2" -service = "my-service" -assert "env" in labels, "env label is a must" -assert cpu >= 256, "cpu cannot be less than 256" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -```bash -kcl my_config.k -``` - -标准错误输出: - -```bash -Assertion failure: env label is a must. -``` - -将 env:pre-prod 对添加到标签中后,我们将得到如下输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 7. 使用方便的内置支持 - -更重要的是,我们可以使用内置函数来帮助我们调试或简化编码。 - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -_name = "nginx" -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # 列表 -labels = { - run = "my-{}".format(_name) - env = "pre-prod" -} # a dict -image = "{}:1.14.2".format(_name) # 字符串格式 -service = "my-service" - -# debugging -print(labels) # 通过打印调式 - -# test -assert len(labels) > 0, "labels can't be empty" # 使用 len() 得到列表长度 -assert "env" in labels, "env label is a must" -assert cpu >= 256, "cpu cannot be less than 256" -``` - -此示例展示了我们如何使用 `format()`、`len()`、`print()` 函数来帮助自定义配置。 - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -KCL 命令: - -```bash -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -run: my-nginx -env: pre-prod -``` - -注意:更多的内置函数和模块可以在 spec/module 目录中查看。 - -## 8. 重用另一个模块的变量 - -为了使我们的代码得到良好的组织,我们可以将代码简单地分为 `my_config.k` 和 `my_config_test.k` 两个文件。 - -在 `my_config.k` 中定义配置数据: - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 -_name = "nginx" - -# 可导出变量 -cpu = _cpu -memory = _cpu * 2 -command = [_name] # 列表 -labels = { - run = "my-{}".format(_name) - env = "pre-prod" -} # a dict -image = "{}:1.14.2".format(_name) # 字符串格式 -service = "my-service" -``` - -而测试代码定义在 `my_config_test.k` 中,我们可以在其中导入 `my_config.k`: - -```python -import my_config - -# debugging -print(my_config.labels) # 通过打印调试 - -# test -assert len(my_config.labels) > 0, "labels can't be empty" # 使用 len() 得到列表长度 -assert "env" in my_config.labels, "env label is a must" -assert my_config.cpu >= 256, "cpu cannot be less than256" -``` - -## 9. 配置输入参数 - -有时我们需要获得通过从最终用户或平台动态获取的外部输入参数。 - -在这种情况下,我们可以按需传递 `priority` 和 `env` 参数: - -- 通过参数传递: `-D priority=1 -D env=pre-prod` -- 可以在 KCL 代码中使用 `option` 关键字获取这些值 - -```python -_priority = option("priority") # 非导出可变变量 -_env = option("env") # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -_name = "nginx" -# 可导出变量 -cpu = _cpu -memory = _cpu * 2 -command = [_name] # 列表 -labels = { - run = "my-{}".format(_name) - env = _env -} # a dict -image = "{}:1.14.2".format(_name) # 字符串格式 -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -```bash -kcl my_config.k -D priority=2 -D env=pre-prod -``` - -标准输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 10. 使用 Dict 简化逻辑表达式 - -当我们需要编写复杂的逻辑时,可以使用dict来简化逻辑的编写。 - -```python -_priority = option("priority") # 非导出可变变量 -_env = option("env") # 非导出可变变量 -_priorityCpuMap = { - "1" = 256 - "2" = 512 - "3" = 1024 -} -# 使用字典简化逻辑,默认值为2048 -_cpu = _priorityCpuMap[_priority] or 2048 -_name = "nginx" -# 可导出变量 -cpu = _cpu -memory = _cpu * 2 -command = [_name] # 列表 -labels = { - run = "my-{}".format(_name) - env = _env -} # a dict -image = "{}:1.14.2".format(_name) # 字符串格式 -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -KCL 命令: - -```bash -kcl my_config.k -D priority=2 -D env=pre-prod -``` - -标准输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 11. 最后 - -恭喜! - -我们已经完成了关于 KCL 的第一课程,我们使用 KCL 来替换我们的键值文本文件,以获得更好的编程支持。 - -建议立即查看架构代码实验,以了解如何使用 KCL `schema` 机制协作编写高级配置。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/error/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/error/_category_.json deleted file mode 100644 index 4f285ced..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/error/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "错误与警告", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/error/_error.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/error/_error.md deleted file mode 100644 index a2f192b8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/error/_error.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: "错误检查" -linkTitle: "错误检查" -type: "docs" -weight: 1 -description: KCL 语言规范 ---- - -When errors happen, developers should be able to detect the error and abort -execution. Thus, KCL introduce the `assert` syntax. - -In the previous topic of `schema` syntax. Errors can also be raised when a -schema is violated. - -## Syntax - -The syntax of the `assert` statement is the following. - -``` -assert_stmt: 'assert' test [',' test] -``` - -In the basic form, an `assert` statement evaluates an expression. If the -expression is evaluated to `False`, the assertion is failed, and an error -should be reported. - -In the extended form, an error message can be provided. The error message is -another expression. It is only evaluated when the expression to be evaluated -is evaluated to `False`. The evaluation result of the error message is printed -when reporting the error. - -The following is an example: - -```py -a = 1 -b = 3 -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -``` - -## The Implementation - -When an error happens, no matter it is caused by the `assert` or the `schema` syntax, -the virtual machine should exit with an exit code greater than `0`. - -The virtual machine may choose to dump the back trace information, and it is strongly -recommended to implement it. - -In practice, KCL can dump back trace by default, and an argument can be introduced -to disable it. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/error/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/error/index.md deleted file mode 100644 index e4f702ec..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/error/index.md +++ /dev/null @@ -1 +0,0 @@ -# 错误与警告 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/index.md deleted file mode 100644 index 66fd3dde..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/index.md +++ /dev/null @@ -1 +0,0 @@ -# KCL diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/_category_.json deleted file mode 100644 index c088e386..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "规范", - "position": 3 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/codestyle.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/codestyle.md deleted file mode 100644 index dd40925e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/codestyle.md +++ /dev/null @@ -1,608 +0,0 @@ ---- -title: "Code Style" -linkTitle: "Code Style" -type: "docs" -weight: 2 -description: Code Style ---- - -## Introduction - -This document gives the KCL code style conventions. Good code style can play a vital role in the development and maintenance of the project. We can learn the KCL code style by referring to the full text of the description and sample codes, and use KCL format and lint tools to help coding. - -## Source File Encoding - -KCL file encoding should always use **UTF-8**. - -## Code Layout - -### Indentation - -Use **4 spaces** per indentation level such as in the schema statement and if statement. - -```python -schema PersonA: - name: str # non-recommended - age: int - -schema PersonB: - name: str # recommended - age: int - -if True: - a = 1 # recommended -elif True: - b = 2 # non-recommended -else: - c = 3 # non-recommended -``` - -The closing brace/bracket/parenthesis on multiline constructs should line up under **first character** of the line that starts the multiline construct, as in: - -```python -# valid and recommended -my_list = [ - 1, 2, 3, - 4, 5, 6, -] -``` - -```python -# invalid -my_list = [ - 1, 2, 3, - 4, 5, 6, - ] -``` - -### Tabs or Spaces - -- Spaces are the preferred indentation method. -- Tabs should be used solely to remain consistent with code that is already indented with tabs. - -KCL disallows mixing the use of tabs and spaces for indentation and an error will be reported during the compile time. - -### Blank Lines - -- Surround top-level schema definitions with one blank line. -- Keep at most one blank line between two statements and remove redundant blank lines. -- Remove extra blank characters at the end of the line -- Remove extra blank characters in a blank line. -- There is no blank line in the header of the file, start writing from the first line. -- Only one blank line will be left at the end of the KCL file. - -```python -# Remove blank lines in the file header -a = 1 # Remove white space at the end of the line -# Keep at most one blank line between two statements - -b = 2 -# Only leave one blank line at the end of the file - -``` - -### Inline Expressions - -Write indentation of KCL `if`, `elif`, `else` and other conditions on different lines. - -```python -if True: print("") # non-recommended - -if True: # recommended - print("") -``` - -### Line Break and Continuation lines - -- For long expressions, use the line continuation symbol `\` and keep the left end of multiple expressions aligned. -- The 4-space rule is optional for continuation lines. - -```python -anotherString = "Too long expression " + \ - "Too long expression " # non-recommended - -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " # recommended -``` - -### When to Use Trailing Commas - -- Always use trailing commas. - -### Maximum Line Length - -- The general recommendation is **80 characters** but not absolute. - -### Symbol Break White Space - -Try to keep the spaces between different symbols, but not too many, usually one is good. - -```python -a = 1 # recommended -b = 1 + 2 # non-recommended -``` - -### Whitespace in Expressions and Statements - -Avoid extraneous whitespace in the following situations: - -- The parentheses `()`, brackets `[]` and braces `{}` in the expression have no spaces inside. - -```python -a = (1 + 2) # recommended -b = ( 1 + 2 ) # non-recommended - -c = [1, 2, 3] # recommended -d = [ 1, 2, 3 ] # non-recommended - -e = {key = "value"} # recommended -f = { key = "value" } # non-recommended -``` - -```python -spam(ham[1], {eggs = 2}) # recommended -spam( ham[ 1 ], { eggs = 2 } ) # non-recommended -``` - -- Between a trailing comma and a following close parenthesis. - -```python -foo = [0,] # recommended -bar = [0, ] # non-recommended -``` - -- Immediately before the open parenthesis that starts the argument list of a function call. - -```python -print(1) # recommended -print (1) # non-recommended -``` - -- Immediately before the open parenthesis that starts indexing or slicing. - -```python -dct = {key = "value"} -lst = [1, 2, 3] - -a = dct['key'] # recommended -b = dct ['key'] # non-recommended - -c = lst[0] # recommended -d = lst [1] # non-recommended -``` - -- More than one space around an assignment `=` (or other) operator to align it with another. - -```python -# recommended: -x = 1 -y = 2 -long_variable = 3 -``` - -```python -# non-recommended: -x = 1 -y = 2 -long_variable = 3 -``` - -- Always surround these binary operators with a single space on either side: assignment (`=`), augmented assignment (`+=`, `-=`, etc.), comparisons (`==`, `<`, `>`, `!=`, `<=`, `>=`, `in`, `not in`, `is`, `is not`), booleans (`and`, `or`, `not`). - -```python -# recommended: -i = i + 1 -submitted += 1 -x = x * 2 - 1 -hypot2 = x * x + y * y -c = (a + b) * (a - b) -``` - -```python -# non-recommended: -i = i+1 -submitted+=1 -x = x*2 - 1 -hypot2 = x*x + y*y -c = (a+b) * (a-b) -``` - -- Break one blank line between different statements e.g., import, schema and expression statements. - -```python -import math -import net - -schema Person: - name: str - -person = Person { - name = "Alice" -} -``` - -- Compound statements (multiple statements on the same line) are generally discouraged - -```python -# recommended: -if foo == 'blah': - do_blah_thing() -do_one() -do_two() -do_three() -``` - -```python -# non-recommended: -if foo == 'blah': do_blah_thing() -do_one(); do_two(); do_three() -``` - -## Naming Conventions - -### Naming Styles - -The following naming styles are commonly distinguished: - -- `b` (single lowercase letter) -- `B` (single uppercase letter) -- `lowercase` -- `lower_case_with_underscores` -- `UPPERCASE` -- `UPPER_CASE_WITH_UNDERSCORES` -- `CapitalizedWords` (capitalize all letters of the acronym in `CapitalizedWords` e.g., `HTTPServer`.) -- `mixedCase` (differs from `CapitalizedWords` by initial lowercase character) -- `Capitalized_Words_With_Underscores` (ugly and non-recommended) - -### Names to Avoid - -Never use the characters 'l' (lowercase letter el), 'O' (uppercase letter oh), or 'I' (uppercase letter eye) as single-character variable names. - -### Package and Module Names - -Package and module names should have short, all-lowercase names. - -### Schema Names - -Schema names should normally use the `CapWords` convention. - -### Constants - -Constants are usually defined on a module level and written in all capital letters with underscores separating words such as `MAX_OVERFLOW` and `TOTAL`. - -## Import - -- Imports should usually be on separate lines. -- Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants. -- Imports should be grouped in the following order and we should put a blank line between each group of imports. - 1. Standard library imports. - 2. Related third party plugin imports. - 3. Local application/library specific imports. -- Use an alias when we import a package name with a relatively long path. -- Leave only one space between the Import keyword and the package name. - -```python -import net # recommended -import math # non-recommended - -import ..pkg.internal_pkg as alias_pkg # recommended -``` - -## Comments - -- Comments should be complete sentences. The first word should be capitalized unless it is an identifier that begins with a lower-case letter (never alter the case of identifiers!). -- Block comments generally consist of one or more paragraphs built out of complete sentences, with each sentence ending in a period. -- Use two spaces after a sentence-ending period in multi-sentence comments, except after the final sentence. - -### Block Comments - -Block comments generally apply to some (or all) code that follows them, and are indented to the same level as that code. Each line of a block comment starts with a `#` and **a single space**(unless it is indented text inside the comment). - -Paragraphs inside a block comment are separated by a line containing a single `#`. - -```python -# This is a block comment -a = 1 -``` - -### Inline Comments - -Use inline comments sparingly. - -An inline comment is a comment on the same line as a statement. Inline comments should be separated by **at least two spaces** from the statement. They should start with a `#` and **a single space**. - -```python -a = 1 # This is an inline comment -``` - -### Documentation Strings - -Write doc strings for all public schema and schema attributes. - -```python -schema Person: - """ - Person schema doc string - """ - - name: str = "Alice" -``` - -## String - -- Single-quoted strings and double-quoted strings are the same in KCL. -- Use double-quoted string with lowercase prefix -- For triple-quoted strings, always use double quote characters to be consistent with the docstring convention. -- When a string contains single or double quote characters, use the other one to avoid backslashes in the string. - -```python -strC = "'123'" # recommended -strD = "\"123\"" # non-recommended -``` - -## Number - -- Use lowercase for the prefix of non-decimal numbers, and use uppercase for the number itself. - -```python -foo = 0xAB # recommended -bar = 0Xab # non-recommended -``` - -## Operators - -### Binary Operators - -- Leave only one space before and after the assignment `=`. -- Leave only one space before and after the binary operator in the expression. - -```python -a = 1 # recommended -b=2 # non-recommended -c= 3 # non-recommended -d =4 # non-recommended - -_value = (1 + 2 * 3) # recommended -_value = (1+2*3) # non-recommended -``` - -### Unary Operators - -- There is only no space after unary operators e.g., `~`, `+` and `-`. - -```python -_value = 1 + -2 * ~3 # recommended -_value = 1+ - 2 * ~ 3 # non-recommended -``` - -- There is no space after `**` and `*` in the dict/list deduction expressions and argument expressions. - -```python -_list = [1, 2, 3] -_list = [*_list, [4, 5 ,6]] # recommended -_list = [* _list, [4, 5 ,6]] # non-recommended - -_dict = {**{k = "v"}, **{k = "v"}} # recommended -_dict = {** {k = "v"}, ** {k = "v"}} # non-recommended -``` - -- Use `is not` operator rather than `not ... is`. - -```python -# recommended: -if foo is not None: - a = 1 -``` - -```python -# non-recommended: -if not foo is None: - a = 1 -``` - -## Dict - -- There is no space before the colon `:` at the instantiation of KCL dict and schema config, and a space after the colon `:`. - -```python -d1 = {labels: {k1 = "v1"}} # recommended -d2 = {labels : {k1 = "v1"}} # non-recommended -d3 = {labels :{k1 = "v1"}} # non-recommended -``` - -- Always surround the override attribute operator `=` and the insert attribute operator `+=` with a single space on either sid. - -```python -d1 = {key = "value"} # recommended -d2 = {key= "value"} # non-recommended -d3 = {key ="value"} # non-recommended -``` - -```python -d1 = {key += [0, 1, 2]} # recommended -d2 = {key+= [0, 1, 2]} # non-recommended -d3 = {key +=[0, 1, 2]} # non-recommended -``` - -- Remove all commas at the end of the line in the KCL multiline dict because the end commas of each line are optional. - -```python -d = { - key1 = "value1" - key2 = "value2" - key3 = "value3" - key4 = "value4" -} -``` - -## List - -- Keep only **one space** after the comma `,` separating elements in the list - -```python -a = [1, 2, 3] # recommended -b = [1,2,3] # non-recommended -``` - -- Keep only **one space** before and after the comprehension expression token `for` and `in` in the dict and list. - -```python -a = [i for i in range(10)] # recommended -b = [i for i in range(10)] # non-recommended -``` - -## Slice - -- Keep the same number of spaces before and after the colon `:` of the list slice. - -```python -l = [1, 2, 3] -a = l[0:2] # recommended -b = l[0 : 2] # non-recommended -c = l[0: 2] # non-recommended - -d = l[0 + 0 : 1 + 1] # recommended -e = l[0 + 0:1 + 1] # non-recommended -``` - -## Schema - -- Leave only one space before and after the schema attribute assignment `=`. -- Always add a doc string to a schema, which is a good programming habit. - -```python -schema Person: - """ - Schema doc string - """ - name: str = "Alice" # recommended - age : int=12 # non-recommended - -person = Person {} -``` - -- Keep **no spaces** around the schema inheritance operator `()` - -```python -schema Base: - name: str - -schema Person(Base): # recommended - age: int - -schema Schema ( Base ): # non-recommended - age: int -``` - -- Keep **only one space** between the brackets and the schema name of the config at schema instantiation. - -```python -schema Base: - name: str - -schema Person(Base): - age: int - -personA = Person{} # non-recommended -personB = Person {} # recommended -``` - -- Keep **only one space** between the **mixin** keyword and the following `[]` operator - -```python -schema NameMixin: - name: str = "name" - -schema Person: - mixin [NameMixin] # non-recommended - age: int - -schema Parent: - mixin [NameMixin] # recommended - age: int -``` - -### Attribute Annotations - -- Annotations for schema attributes should have a single space after the colon `:` and no space before the colon `:`. - -```python -# recommended: -schema Person: - name: str # No space before the colon `:` - age: int = 18 # Spaces around assignment`=` -``` - -```python -# non-recommended: -schema Person: - codeA:int # No space after the colon `:` - codeB : int # Space before the colon `:` - name: str="Alice" # No spaces around assignment`=` -``` - -- There are no spaces around the colon `:` in the dict type annotation. - -```python -schema Person: - labels: {str:str} # recommended - keyValues: {str : str} # non-recommended -``` - -### Arguments - -- There are no spaces around the assignment `=` in the function/schema/decorator keyword arguments (kwargs). - -```python -schema Person[nameVar]: - # Decorator kwargs - @deprecated(strict=False) # recommended - name: str = nameVar - - @deprecated(strict = False) # non-recommended - age: int - -# Schema kwargs -personA = Person(nameVar="Alice") {} # recommended -personB = Person(nameVar = "Bob") {} # non-recommended - -# Function kwargs -print("", end='') # recommended -print("", end = '') # non-recommended -``` - -## Keywords - -- Only one space is usually reserved around the keyword, such as `schema`, `mixin`, `is` and `not`, etc. - -```python -schema NameMixin: - check: - name not None - -schema Person: - """ - Person schema definition - """ - mixin [NameMixin] - - name: str = "Alice" - age: int - -person = Person { - age = 18 -} -``` - -## Function - -- There are no spaces around the function/package select operator `.` -- There are no spaces between the function name and the parentheses `()`. - -```python -import math - -print(math.log(10)) # recommended -print( math . log (10)) # non-recommended -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/error.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/error.md deleted file mode 100644 index 2a58b553..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/error.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: "Errors" -linkTitle: "Errors" -type: "docs" -weight: 2 -description: Errors ---- - -When errors happen, developers should be able to detect the error and abort -execution. Thus, KCL introduce the `assert` syntax. - -In the previous topic of `schema` syntax. Errors can also be raised when a -schema is violated. - -## Syntax - -The syntax of the `assert` statement is the following. - -```bnf -assert_stmt: 'assert' test ['if' test] [',' test] -``` - -In the basic form, an `assert` statement evaluates an expression. If the -expression is evaluated to `False`, the assertion is failed, and an error -should be reported. - -In the extended form, an error message can be provided. The error message is -another expression. It is only evaluated when the expression to be evaluated -is evaluated to `False`. The evaluation result of the error message is printed -when reporting the error. - -The following is an example: - -```python -a = 1 -b = 3 -condition = False -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -# if condition is True, then assert `a == b`, if failed, the message "error message" will be printed. -assert a == b if condition, "error message" -``` - -## The Implementation - -When an error happens, no matter it is caused by the `assert` or the `schema` syntax, -the virtual machine should exit with an exit code greater than `0`. - -The virtual machine may choose to dump the back trace information, and it is strongly recommended to implement it. - -In practice, KCL can dump back trace by default, and an argument can be introduced to disable it. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/expressions.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/expressions.md deleted file mode 100644 index b52c10f3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/expressions.md +++ /dev/null @@ -1,915 +0,0 @@ ---- -title: "Expressions" -linkTitle: "Expressions" -type: "docs" -weight: 2 -description: Expressions ---- - -## Syntax - -In KCL, an expression specifies the computation of a value. - -The syntax is the following: - -```bnf -expression: test ("," test)* -test: if_expr | primary_expr | unary_expr | binary_expr -``` - -KCL expressions consist of `if` expression, `primary` expression, `unary` expression, and `binary` expression. - -### Primary Expressions - -Primary expressions are the operands for unary and binary expressions. - -Operands are self-delimiting. An **operand** may be followed by any number of selector dot, a function call, or slice suffixes, to form a primary expression. The grammar uses `expression`, where a multiple-component expression is allowed, and `test` where it accepts an expression of only a single component. - -Syntax: - -```bnf -primary_expr: operand | primary_expr select_suffix | primary_expr call_suffix | primary_expr subscript_suffix -``` - -### Operands - -Operand denotes the elementary value in an expression. An operand may be an identifier, a literal, or a parenthesized expression. - -Syntax: - -```bnf -operand: operand_name | number | string | "True" | "False" | "None" | "Undefined" | list_expr | list_comp | dict_expr | dict_comp | "(" expression ")" -operand_name: identifier | qualified_identifier -``` - -### Identifiers - -In KCL, an identifier is a name, may with selectors, that identifies a value. - -Syntax: - -```bnf -identifier: NAME -``` - -Examples: - -```python -x -a -_b -``` - -Use the `$` character prefix to define keyword identifiers. - -```python -$if = 1 -$else = "s" -``` - -Please note: whether the non-keyword identifier is prefixed with `$` has the same effect. - -```python -_a = 1 -$_a = 2 # equal to `_a = 2` -``` - -To simplify the definition of the qualified identifier, such as 'pkg.type', we additionally define `qualified_identifier`: - -Syntax: - -```bnf -qualified_identifier: identifier "." identifier -``` - -Examples: - -```python -pkg.a -``` - -The package name in qualified_identifier must be imported. - -### Basic Literals - -Basic literals supported in KCL are `int`, `float`, `string` and `bool` including `True` and `False`. Evaluation of basic literal yields a value of the given type with the given value. - -Syntax: - -```bnf -operand: number | string | "True" | "False" | "None" | "Undefined" -``` - -Examples: - -```python -1 -2.3 -"abc" -True -False -None -Undefined -``` - -See more details about **data type** spec. - -### Parenthesized Expressions - -An expression enclosed in parentheses yields the result of that expression. - -Syntax: - -```bnf -operand: '(' expression ')' -``` - -Examples: - -```python -x = (1 + 2) * (3 + 4) # 21 -``` - -### Dictionary Expressions - -A dictionary expression is a comma-separated immutable list of colon-separated key/value expression pairs, enclosed in curly brackets, and it yields a new dictionary object. An optional comma may follow the final pair. - -```bnf -config_expr: '{' config_entries '}' -config_entries: config_entry [config_entry*] -config_comp: '{' (config_entry comp_clause+) '}' -config_entry: expr (':' | '=' | '+=') expr | double_star_expr | if_entry -double_star_expr: "**" expression -if_entry: - 'if' expr ';' if_entry_exec_block - ('elif' expr ':' if_entry_exec_block)* - ('else' ':' if_entry_exec_block)? -NEWLINE: '/r?/n' -``` - -Examples: - -```python -{} -{"one": 1} -{"one": 1, "two": 2} -``` - -The key and value expressions are evaluated in left-to-right order. Evaluation fails if the same key is used multiple times. - -Only hashable values may be used as the keys of a dictionary. This includes all built-in types except dictionaries, and lists. - -We can ignore the comma `,` at the end of the line for writing dict key-value pairs in multiple lines: - -```python -data = { - "key1" = "value1" # Ignore the comma ',' at the end of line - "key2" = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -We can ignore the key quotation marks when we writing simple literals on the key. - -```python -data = { - key1 = "value1" # Ignore the comma ',' at the end of line - key2 = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -In addition, the **config selector expressions** can be used to init a schema instance. - -```python -person = { - base.count = 2 - base.value = "value" - labels.key = "value" -} # {"base": {"count": 2, "value": "value"}, "labels": {"key": "value"}} -``` - -We can **merge** dict using the dict unpacking operator `**` like this: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = {**_part1, **_part2} # {"a: "b", "c": "d"} -``` - -We can use `if expressions` to dynamically add elements to the dict element, elements that meet the conditions are added to the dict, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = { - key1 = "value1" - if a == 1: key2 = "value2" - if a > 0: key3 = "value3" - if a < 0: key4 = "value4" -} # {"key1": "value1", "key2": "value2", "key3": "value3"} -``` - -```python -a = 1 # 1 -data1 = { - key1 = "value1" - if a == 1: - key2 = "value2" - elif a > 0: - key3 = "value3" - else: - key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -data2 = { - key1 = "value1" - if a == 1: key2 = "value2" - elif a > 0: key3 = "value3" - else: key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -``` - -### List Expressions - -A list expression is a comma-separated immutable list of element expressions, enclosed in square brackets, and it yields a new list. An optional comma may follow the last element expression. - -```bnf -list_expr: '[' [list_item [',']] ']' -list_item: test | "*" primary_expr | if_expr -``` - -Element expressions are evaluated in left-to-right order. - -Examples: - -```python -[] # [], empty list -[1] # [1], a 1-element list -[1, 2, 3] # [1, 2, 3], a 3-element list -``` - -We can use `if expressions` to dynamically add elements to the list element, elements that meet the conditions are added to the list, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = [ - 1 - if a == 1: 2 - if a > 0: 3 - if a < 0: 4 -] # [1, 2, 3] -``` - -```python -a = 1 # 1 -data1 = [ - 1 - if a == 1: - 2 - elif a == 2: - 3 - else: - 3 -] # [1, 2] -data2 = [ - 1 - if a == 1: 2 - elif a == 2: 2 - else: 3 -] # [1, 2] -``` - -### Comprehensions - -A comprehension constructs a new list or dictionary value by looping over one or more iterables and evaluating a body expression that produces successive elements of the result. - -Syntax: - -```bnf -list_comp: '[' list_item comp_clause+ ']' . -dict_comp: '{' entry comp_clause+ '}' . - -comp_clause: 'for' loop_variables [","] 'in' test ['if' test] -loop_variables: primary_expr (',' primary_expr)* -``` - -A list comprehension consists of a single expression followed by one or more clauses, the first of which must be a `for` clause. Each `for` clause resembles a `for` statement, and specifies an iterable operand and a set of variables to be assigned by successive values of the iterable. An `if` cause resembles an `if` statement, and specifies a condition that must be met for the body expression to be evaluated. A sequence of `for` and `if` clauses acts like a nested sequence of `for` and `if` statements. - -Examples: - -```python -[x * x for x in range(5)] # [0, 1, 4, 9, 16] -[x * x for x in range(5) if x % 2 == 0] # [0, 4, 16] -[[x, y] for x in range(5) \ - if x % 2 == 0 \ - for y in range(5) \ - if y > x] # [[0, 1], [0, 2], [0, 3], [0, 4], [2, 3], [2, 4]] -``` - -Besides, we can use two variables in the list comprehension, the first variable denotes the list index and the second variable denotes the list item. - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use `_` to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -A dict comprehension resembles a list comprehension, but its body is a pair of expressions, key: value, separated by a colon, and its result is a dictionary containing the key/value pairs for which the body expression was evaluated. Evaluation fails if the value of any key is un-hashable. - -Besides, we can use two variables in the dict comprehension, the first variable denotes the dict key and the second variable denotes the dict value of the key. - -```python -data = {"key1" = "value1", "key2" = "value2"} -# Single variable loop -dataKeys1 = {k: k for k in data} # {"key1": "key1", "key2": "key2"} -dataValues1 = {k: data[k] for k in data} # {"key1": "value1", "key2": "value2"} -# Double variable loop -dataKeys2 = {k: k for k, v in data} # {"key1": "key1", "key2": "key2"} -dataValues2 = {v: v for k, v in data} # {"value1": "value1", "value2": "value2"} -dataFilter = {k: v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use `_` to ignore loop variables -dataKeys3 = {k: k for k, _ in data} # {"key1": "key1", "key2": "key2"} -dataValues3 = {v: v for _, v in data} # {"value1": "value1", "value2": "value2"} -``` - -As with a `for` loop, the loop variables may exploit compound assignment: - -```python -[x * y + z for [x, y], z in [[[2, 3], 5], [["o", 2], "!"]]] # [11, 'oo!'] -``` - -KCL does not accept an un-parenthesized list as the operand of a for clause: - -```python -[x * x for x in 1, 2, 3] # parse error: unexpected comma -``` - -Comprehensions defines a new lexical block, so assignments to loop variables have no effect on variables of the same name in an enclosing block: - -```python -x = 1 -_ = [x for x in [2]] # new variable x is local to the comprehension -print(x) # 1 -``` - -The operand of a comprehension's first clause (always a for) is resolved in the lexical block enclosing the comprehension. In the examples below, identifiers referring to the outer variable named x have been distinguished by subscript. - -```python -x0 = [1, 2, 3] -[x * x for x in x0] # [1, 4, 9] -[x * x for x in x0 if x % 2 == 0] # [4] -``` - -All subsequent for and if expressions are resolved within the comprehension's lexical block, as in this rather obscure example: - -```python -x0 = [[1, 2], [3, 4], [5, 6]] -[x * x for x in x0 for x in x if x % 2 == 0] # [4, 16, 36] -``` - -which would be more clearly rewritten as: - -```python -x = [[1, 2], [3, 4], [5, 6]] -[z * z for y in x for z in y if z % 2 == 0] # [4, 16, 36] -``` - -### Conditional Expressions - -A conditional expression has the form `a if cond else b`. It first evaluates the condition `cond`. If it's true, it evaluates `a` and yields its value; otherwise it yields the value of `b`. - -Syntax: - -```bnf -if_expr: test "if" test "else" test -``` - -Examples: - -```python -x = True if enabled else False # if enabled is -``` - -### Unary Expressions - -In KCL, supported unary operators are `+`, `-`, `~`, and `not`. - -Syntax: - -```bnf -unary_expr: ("+" | "-" | "~") primary_expr - | "not" test -``` - -Usage: - -```bnf -+ number unary positive (int, float) -- number unary negation (int, float) -~ number unary bitwise inversion (int) -not x logical negation (any type) -``` - -The `+` and `-` operators may be applied to any number (int or float) and return the number. -The `not` operator returns the negation of the truth value of its operand. - -Examples: - -```python -~1 # -2 -~-1 # 0 -~0 # -1 -not True # False -not 0 # True -``` - -### Binary Expressions - -In KCL, binary expressions consist of `comparisons`, `logical operations`, `arithmetic operations` and `membership tests`. - -Syntax: - -```bnf -binary_expr: test bin_op test -bin_op: 'or' - | 'and' - | '==' | '!=' | '<' | '>' | '<=' | '>=' - | 'in' | 'not' 'in' - | '|' - | '^' - | '&' - | '-' | '+' - | '*' | '%' | '/' | '//' - | '<<' | '>>' -``` - -#### Logical Operations - -The `or` and `and` operators yield the logical disjunction and conjunction of their arguments, which need not be Booleans. - -The expression `x or y` yields the value of `x` if its truth value is `True`, or the value of `y` otherwise. - -```python -False or False # False -False or True # True -True or True # True -1 or "hello" # 1 -``` - -Similarly, `x` and `y` yields the value of `x` if its truth value is `False`, or the value of `y` otherwise. - -```python -False and False # False -False and True # False -True and True # True -1 and "hello" # "hello" -``` - -These operators use "short circuit" evaluation, so the second expression is not evaluated if the value of the first expression has already determined the result, allowing constructions like these: - -```python -x and x[0] == 1 # x[0] is not evaluated if x is empty -len(x) == 0 or x[0] == "" -not x or not x[0] -``` - -#### Comparisons - -The `==` operator reports whether its operands are equal; the `!=` operator is its negation. - -The operators `<`, `>`, `<=`, and `>=` perform an ordered comparison of their operands. It is an error to apply these operators to operands of unequal type, unless one of the operands is an `int` and the other is a `float`. Of the built-in types, only the following support ordered comparison, using the ordering relation shown: - -```bnf -NoneType # None <= None -bool # False < True -int # mathematical -float # as defined by IEEE 754 -string # lexicographical -list # lexicographical -``` - -Comparison of floating-point values follows the IEEE 754 standard, which breaks several mathematical identities. For example, if `x` is a `NaN` value, the comparisons `x < y`, `x == y`, and `x > y` all yield false for all values of `y`. - -The remaining built-in types support only equality comparisons. Values of type `dict` and `schema` compare equal if their elements compare equal, and values of type function or `builtin_function_or_method` are equal only to themselves. - -```bnf -dict # equal contents -schema # equal exported-attributes -function # identity -builtin_function_or_method # identity -``` - -#### Arithmetic Operations - -The following table summarizes the binary arithmetic operations available for built-in types: - -```bnf -Arithmetic (int or float; result has type float unless both operands have type int) - number + number # addition - number - number # subtraction - number * number # multiplication - number / number # real division (result is always a float) - number // number # floored division - number % number # remainder of floored division - number ^ number # bitwise XOR - number << number # bitwise left shift - number >> number # bitwise right shift - -Concatenation - string + string - list + list - -Repetition (string/list) - int * sequence - sequence * int - -Union - int | int - list | list - dict | dict - schema | schema - schema | dict -basictype | basictype -``` - -The operands of the arithmetic operators `+`, `-`, `*`, `//`, and `%` must both be numbers (`int` or `float`) but need not have the same type. The type of the result has type `int` only if both operands have that type. The result of real division / always has type `float`. - -The `+` operator may be applied to non-numeric operands of the same type, such as two lists, or two strings, in which case it computes the concatenation of the two operands and yields a new value of the same type. - -```python -"Hello, " + "world" # "Hello, world" -[1, 2] + [3, 4] # [1, 2, 3, 4] -``` - -The `*` operator may be applied to an integer n and a value of type `string`, `list`, in which case it yields a new value of the same sequence type consisting of n repetitions of the original sequence. The order of the operands is immaterial. Negative values of n behave like zero. - -```python -'mur' * 2 # 'murmur' -3 * range(3) # [0, 1, 2, 0, 1, 2, 0, 1, 2] -``` - -The `&` operator requires two operands of the same type, such as `int`. For integers, it yields the bitwise intersection (AND) of its operands. - -The `|` operator likewise computes bitwise, unions basic types and unions collection and schema data, such as **list**, **dict** and **schema**. - -Computing bitwise examples: - -```python -0x12345678 | 0xFF # 0x123456FF -``` - -Unioning basic types examples: - -```python -schema x: - a: int | str # attribute a could be a int or string -``` - -A union type is used to define a schema attribute type. See more details in **schema** spec. -Supported types in a union type are `int`, `str`, `float`, `bool`, `list` and `dict`. - -Unioning collection and schema data: - -- Unioning List. Overwrite the list expression on the right side of the operator `|` to the list variable on the left side of the operator one by one according to the **index**. - -```python -_a = [1, 2, 3] -_b = [4, 5, 6, 7] -x = _a | _b # [4, 5, 6, 7] 4 -> 1; 5 -> 2; 6 -> 3; 7 -> None -``` - -Unioning to the specific index or all elements is still under discussion. - -- Unioning Dict. Union the dict expression on the right side of the operator `|` one by one to the dict variable on the left side of the operator according to the **key** - -```python -_a = {key1 = "value1"} -_b = {key1 = "overwrite", key2 = "value2"} -_c = _a | _b # {"key1": "overwrite", "key2": "value2"} -``` - -The union of collection and schema is a new one whose attributes are unioning b to a, preserving the order of the attributes of the operands, left before right. - -Unioning to the specific key or all keys is still under discussion. - -- Unioning Schema. - -The union operation for schema is similar to dict. - -Schema union could be done as: - -```bnf -schema Person: - firstName: str - lastName: str - -_a = Person { - firstName = "John" -} -_b = {lastName = "Doe"} -_a = _a | _b # {"firstName": "John", "lastName": "Doe"} -``` - -Unioning to a specific attribute is still under discussion. Unioning to all attributes is not applicable to schema instances. - -See **selector expression** in **expression** spec for more details. - -The `^` operator accepts operands of `int`. For integers, it yields the bitwise XOR (exclusive OR) of its operands. - -The `<<` and `>>` operators require operands of `int` type both. They shift the first operand to the left or right by the number of bits given by the second operand. It is a dynamic error if the second operand is negative. Implementations may impose a limit on the second operand of a left shift. - -```python -0x12345678 & 0xFF # 0x00000078 -0b01011101 ^ 0b110101101 # 0b111110000 -0b01011101 >> 2 # 0b010111 -0b01011101 << 2 # 0b0101110100 -``` - -#### Membership Tests - -Usage: - -```bnf - any in sequence (list, dict, schema, string) - any not in sequence -``` - -The `in` operator reports whether its first operand is a member of its second operand, which must be a list, dict, schema, or string. The `not in` operator is its negation. Both return a Boolean. - -The meaning of membership varies by the type of the second operand: the members of a list are its elements; the members of a dict are its keys; the members of a string are all its substrings. - -```python -1 in [1, 2, 3] # True - -d = {"one" = 1, "two" = 2} -"one" in d # True -"three" in d # False -1 in d # False -[] in d # False - -"nasty" in "dynasty" # True -"a" in "banana" # True -"f" not in "way" # True - -d = data {one = 1, two = 2} # data is a schema with attributes one and two -"one" in d # True -"three" in d # False -``` - -### Function Invocations - -KCL allows calling built-in functions and functions from built-in and system modules. Whether KCL allows defining new functions is under discussion. - -Syntax: - -```bnf -call_suffix: "(" [arguments [","]] ")" -arguments: argument ("," argument)* -argument: test | identifier "=" test | "*" test | "**" test -``` - -To call a function, the basic way is shown as the following code excerpt: - -```python -print("An argument") - -import math -# 2 powers 3 is 8. -a = math.pow(2, 3) -``` - -As you can see, arguments are separated with `,`. Arguments can only be passed in this way. KCL supports positional arguments and key-value arguments. - -Note that: - -- Some functions have parameters with default values. -- Some functions accept variadic arguments. - -When an argument is not supplied for a parameter without a default value, -an error will be reported. - -### Selector Expressions - -A selector expression selects the attribute or method of the value. - -#### Select Attributes - -Syntax: - -```bnf -select_suffix: ["?"] "." identifier -``` - -KCL provides a wealth of ways to identify or filter attributes. - -x.y - -- schema: it denotes the attribute value of a schema `x` identified by `y` -- package: it denotes the identifier of a package `x` identified by `y` - -Examples: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -name = person.name # "Alice" -age = person.age # 18 -``` - -x?.y - -If the x if None/Undefined or empty(empty list or dict), just return None, otherwise behave as x.y. - -Examples - -```python -noneData = None -data?.name # None - -emptyDict = {} -emptyDict?.name # None - -emptyList = [] -emptyList?[0] # None -``` - -As a supplementary of the `selector` expression in KCL code, the KCL compiler needs to provide corresponding identifying and filtering features through the command line and api form. - -#### Select Methods - -Syntax: - -```bnf -select_suffix: "." identifier -``` - -A `identifier` identifies method belongs to the built-in types `string`, `list`, `dict`, and `schema`. - -- A selector expression fails if the value does not have an attribute of the specified name. -- A selector expression that selects a method typically appears within a call expression, as in these examples: - -Examples: - -```python -["able", "baker", "charlie"].index("baker") # 1 -"banana".count("a") # 3 -"banana".reverse() # error: string has no .reverse field or method -Person.instances() # all instances of schema Person -``` - -But when not called immediately, the selector expression evaluates to a bound method, that is, a method coupled to a specific receiver value. A bound method can be called like an ordinary function, without a receiver argument: - -```bnf -f = "banana".count -f # -f("a") # 3 -f("n") # 2 -``` - -### Index Expressions - -An index expression `a[i]` yields the `i` th element of an indexable type such as a string or list. The index `i` must be an `int` value in the range `-n` ≤ `i` < `n`, where `n` is `len(a)`; any other index results in an error. - -Syntax: - -```bnf -subscript_suffix: "[" [test] "]" -``` - -A valid negative index `i` behaves like the non-negative index `n+i`, allowing for convenient indexing relative to the end of the sequence. - -```python -"abc"[0] # "a" -"abc"[1] # "b" -"abc"[-1] # "c" - -["zero", "one", "two"][0] # "zero" -["zero", "one", "two"][1] # "one" -["zero", "one", "two"][-1] # "two" -``` - -An index expression `d[key]` may also be applied to a dictionary `d`, to obtain the value associated with the specified key. It returns `Undefined` if the dictionary contains no such key. - -An index expression appearing on the left side of an assignment causes the specified list or dictionary element to be updated: - -```python -a = range(3) # a == [0, 1, 2] -b = a[2] # 2 - - -``` - -It is a dynamic error to attempt to update an element of an immutable type, such as a list or string, or a frozen value of a mutable type. - -### Slice Expressions - -A slice expression `a[start:stop:stride]` yields a new value containing a sub-sequence of `a`, which must be a string, or list. - -```bnf -subscript_suffix: "[" [test] [":" [test] [":" [test]]] "]" -``` - -Each of the `start`, `stop`, and `stride` operands is optional; if present, and not `None`, each must be an integer. -The `stride` value defaults to 1. If the stride is not specified, the colon preceding it may be omitted too. It is an error to specify a stride of zero. - -Conceptually, these operands specify a sequence of values `i` starting at start and successively adding `stride` until `i` reaches or passes `stop`. The result consists of the concatenation of values of `a[i]` for which `i` is valid.` - -The effective start and stop indices are computed from the three operands as follows. Let `n` be the length of the sequence. - -**If the stride is positive**: If the `start` operand was omitted, it defaults to -infinity. If the `end` operand was omitted, it defaults to +infinity. For either operand, if a negative value was supplied, `n` is added to it. The `start` and `end` values are then "clamped" to the nearest value in the range 0 to `n`, inclusive. - -**If the stride is negative**: If the `start` operand was omitted, it defaults to +infinity. If the `end` operand was omitted, it defaults to -infinity. For either operand, if a negative value was supplied, `n` is added to it. The `start` and `end` values are then "clamped" to the nearest value in the range -1 to `n`-1, inclusive. - -```python -"abc"[1:] # "bc" (remove first element) -"abc"[:-1] # "ab" (remove last element) -"abc"[1:-1] # "b" (remove first and last element) -"banana"[1::2] # "aaa" (select alternate elements starting at index 1) -"banana"[4::-2] # "nnb" (select alternate elements in reverse, starting at index 4) -``` - -It's not allowed to define a slice expression as a left value in KCL. -Cause list and string are immutable, re-slicing can directly operate to operand to ensure better performance. - -#### Quantifier Expressions - -Quantifier expressions act on collection: list or dict, generally used to obtain a certain result after processing the collection, mainly in the following four forms: - -```bnf -quant_expr: quant_op [ identifier ',' ] identifier 'in' quant_target '{' expr ['if' expr] '}' -quant_target: string | identifier | list_expr |list_comp | dict_expr | dict_comp -quant_op: 'all' | 'any' | 'filter' | 'map' -``` - -- **all** - - Used to detect that all elements in the collection satisfy the given logical expression, and return a boolean value as the result. - - Only when all elements in the collection satisfy the expression true, the `all` expression is true, otherwise it is false. - - If the original collection is empty, return true. - - Supports short-circuiting of logical expressions during expression execution. -- **any** - - Used to detect that at least one element in the collection satisfies the given logical expression, and returns a boolean value as the result. - - When at least one element in the collection satisfies the expression true, the `any` expression is true, otherwise it is false. - - If the original collection is empty, return false. - - Supports short-circuiting of logical expressions during expression execution. -- **map** - - Generate a new **list** by mapping the elements in the original collection. - - The length of the new list is exactly the same as the original collection. -- **filter** - - By logically judging and filtering the elements in the original collection, and returning the filtered sub-collection. - - Only when the element judges the expression to be true, it is added to the sub-collection. - - The type (list, dict and schema) of the new collection is exactly the same as the original collection, and the length range is `[0, len(original-collection)]`. - -**all** and **any** expression sample codes: - -```python -schema Config: - volumes: [{str:}] - services: [{str:}] - - check: - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - }, "invalid cluster ip" - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } -``` - -**map** and **filter** expression sample codes: - -```python -a = map e in [{name = "1", value = 1}, {name = "2", value = 2}] { - {name = e.name, value = int(e.value) ** 2} -} # [{"name": "1", value: 1}, {"name": "2", "value": 4}] - -b = map k, v in {a = "foo", b = "bar"} { v } # ["foo", "bar"] - -c = filter e in [{name = "1", value = 1}, {name = "2", value = 2}] { - int(e.value) > 1 -} # [{"name": "2", "value": 2}] - -d = filter _, v in {a = "foo", b = "bar"} { - v == "foo" -} # {"a": "foo"} -``` - -Please pay attention to distinguish the difference between any expression and any type. When `any` is used in type annotations, it means that the value of the variable is arbitrary, while the any expression means that one of the elements in a set satisfies the condition. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/index.md deleted file mode 100644 index c3ecc162..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/index.md +++ /dev/null @@ -1 +0,0 @@ -# KCL 语言规范 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/kcl-spec.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/kcl-spec.md deleted file mode 100644 index 63a9d6e7..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/kcl-spec.md +++ /dev/null @@ -1,343 +0,0 @@ ---- -title: "KCL Spec" -linkTitle: "KCL Spec" -type: "docs" -weight: 2 -description: KCL Spec ---- - -## Lexical rules - -### Keywords and reserved words - -The following are the keywords of the KCL: - -```python -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -The following are reserved words for the KCL: - -```python -pass return validate rule flow -def del raise except try -finally while from with yield -global nonlocal struct class final -``` - -### Line comment - -```python -# a comment -``` - -### Operators - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != = -+= -= *= **= /= //= %= -<<= >>= &= ^= -``` - -### Delimiters - -```python -( ) [ ] { } -, : . ; @ -``` - -### Operator precedence - -The following list of operators is ordered from **highest to lowest**: - -| Operator | Description | -| -------------------------------------------------------------------------------- | -------------------------------------------------------- | -| `**` | Exponentiation (highest priority) | -| `+x` `-x` `~x` | Positive, negative, bitwise NOT | -| `*` `/` `%` `//` | Multiplication, division, floor division and remainder | -| `+` `-` | Addition and subtraction | -| `<<` `>>` | Left and right shifts | -| `&` | Bitwise AND | -| `^` | Bitwise XOR | -| \| | Bitwise OR | -| `in`, `not in`, `is`, `is not`, `<`, `<=`, `>`, `>=`, `!=`, `==` | Comparisons, including membership and identity operators | -| `not` | Boolean NOT | -| `and` | Boolean AND | -| `or` | Boolean OR | -| `if – else` | Conditional expression = | -| `=`, `+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `=`, `^=`, `\*\*=`, `//=`, `<<=`, `>>=` | Assign | - -## Grammar - -KCL uses Python's [LarkParser](https://lark-parser.readthedocs.io/en/latest/) tool to describe the grammar, and the specification rules are as follows: - -```bnf -//////////// KCL grammar //////////// -start: (NEWLINE | statement)* - -statement: simple_stmt | compound_stmt -simple_stmt: (assign_stmt | unification_stmt | expr_stmt | assert_stmt | import_stmt | type_alias_stmt) NEWLINE -compound_stmt: if_stmt | schema_stmt | rule_stmt - -//////////// import_stmt //////////// -import_stmt: IMPORT dot_name (AS NAME)? -dot_name: (leading_dots identifier) | identifier -leading_dots: DOT+ - -/////////// assert_stmt //////////// -assert_stmt: ASSERT simple_expr (IF simple_expr)? (COMMA test)? - -//////////// if_stmt //////////// -if_stmt: IF test COLON execution_block (ELIF test COLON execution_block)* (ELSE COLON execution_block)? -execution_block: if_simple_stmt | NEWLINE _INDENT schema_init_stmt+ _DEDENT -if_simple_stmt: (simple_assign_stmt | unification_stmt | expr_stmt | assert_stmt) NEWLINE - -//////////// assign_stmt //////////// -assign_stmt: identifier [COLON type] (ASSIGN identifier)* ASSIGN test - | identifier (COMP_PLUS | COMP_MINUS | COMP_MULTIPLY | COMP_DOUBLE_STAR | COMP_DIVIDE - | COMP_DOUBLE_DIVIDE | COMP_MOD | COMP_AND | COMP_OR | COMP_XOR | COMP_SHIFT_LEFT - | COMP_SHIFT_RIGHT) test - -simple_assign_stmt: identifier ASSIGN test - | identifier (COMP_PLUS | COMP_MINUS | COMP_MULTIPLY | COMP_DOUBLE_STAR | COMP_DIVIDE - | COMP_DOUBLE_DIVIDE | COMP_MOD | COMP_AND | COMP_OR | COMP_XOR | COMP_SHIFT_LEFT - | COMP_SHIFT_RIGHT) test - -//////////// unification_stmt //////////// -unification_stmt: identifier COLON schema_expr - -//////////// schema_stmt //////////// -schema_stmt: [decorators] (SCHEMA|MIXIN|PROTOCOL) NAME [LEFT_BRACKETS [schema_arguments] RIGHT_BRACKETS] [LEFT_PARENTHESES identifier (COMMA identifier)* RIGHT_PARENTHESES] [for_host] COLON NEWLINE [schema_body] -schema_arguments: schema_argument (COMMA schema_argument)* -schema_argument: NAME [COLON type] [ASSIGN test] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt|schema_init_stmt|schema_index_signature)* [check_block] _DEDENT -schema_attribute_stmt: attribute_stmt NEWLINE -attribute_stmt: [decorators] identifier [QUESTION] COLON type [(ASSIGN|COMP_OR) test] -schema_init_stmt: if_simple_stmt | if_stmt -schema_index_signature: LEFT_BRACKETS [NAME COLON] [ELLIPSIS] basic_type RIGHT_BRACKETS COLON type [ASSIGN test] NEWLINE - -//////////// rule_stmt //////////// -rule_stmt: [decorators] RULE NAME [LEFT_BRACKETS [schema_arguments] RIGHT_BRACKETS] [LEFT_PARENTHESES identifier (COMMA identifier)* RIGHT_PARENTHESES] [for_host] COLON NEWLINE [rule_body] -rule_body: _INDENT (string NEWLINE)* check_expr+ _DEDENT - -for_host: FOR identifier - -/////////// decorators //////////// -decorators: (AT decorator_expr NEWLINE)+ -decorator_expr: identifier [call_suffix] - -//////////// type //////////// -type: type_element (OR type_element)* -type_element: schema_type | basic_type | compound_type | literal_type -schema_type: identifier -basic_type: STRING_TYPE | INT_TYPE | FLOAT_TYPE | BOOL_TYPE | ANY_TYPE -compound_type: list_type | dict_type -list_type: LEFT_BRACKETS (type)? RIGHT_BRACKETS -dict_type: LEFT_BRACE (type)? COLON (type)? RIGHT_BRACE -literal_type: string | number | TRUE | FALSE | NONE - -//////////// type alias //////////// -type_alias_stmt: TYPE NAME ASSIGN type - -//////////// check_stmt //////////// -check_block: CHECK COLON NEWLINE _INDENT check_expr+ _DEDENT -check_expr: simple_expr [IF simple_expr] [COMMA primary_expr] NEWLINE - -//////////// mixin_stmt //////////// -mixin_stmt: MIXIN LEFT_BRACKETS [mixins | multiline_mixins] RIGHT_BRACKETS NEWLINE -multiline_mixins: NEWLINE _INDENT mixins NEWLINE _DEDENT -mixins: identifier (COMMA (NEWLINE mixins | identifier))* - - -//////////// expression_stmt //////////// -expr_stmt: testlist_expr -testlist_expr: test (COMMA test)* -test: if_expr | simple_expr -if_expr: simple_expr IF simple_expr ELSE test - -simple_expr: unary_expr | binary_expr | primary_expr - -unary_expr: un_op simple_expr -binary_expr: simple_expr bin_op simple_expr - -bin_op: L_OR | L_AND - | OR | XOR | AND - | SHIFT_LEFT | SHIFT_RIGHT - | PLUS | MINUS | MULTIPLY | DIVIDE | MOD | DOUBLE_DIVIDE - | DOUBLE_STAR - | EQUAL_TO | NOT_EQUAL_TO - | LESS_THAN | GREATER_THAN | LESS_THAN_OR_EQUAL_TO | GREATER_THAN_OR_EQUAL_TO - | IN | L_NOT IN | IS | IS L_NOT | L_NOT | AS -un_op: L_NOT | PLUS | MINUS | NOT - -primary_expr: identifier call_suffix | operand | primary_expr select_suffix | primary_expr call_suffix | primary_expr slice_suffix -operand: identifier | number | string | constant | quant_expr | list_expr | list_comp | config_expr | dict_comp | schema_expr | lambda_expr | LEFT_PARENTHESES test RIGHT_PARENTHESES -select_suffix: [QUESTION] DOT NAME -call_suffix: LEFT_PARENTHESES [arguments [COMMA]] RIGHT_PARENTHESES -slice_suffix: [QUESTION] LEFT_BRACKETS (test | [test] COLON [test] [COLON [test]]) RIGHT_BRACKETS -arguments: argument (COMMA argument)* -argument: test | NAME ASSIGN test | MULTIPLY test | DOUBLE_STAR test - - -//////////// operand //////////// -identifier: NAME (DOT NAME)* -quant_expr: quant_op [ identifier COMMA ] identifier IN quant_target LEFT_BRACE (simple_expr [IF simple_expr] | NEWLINE _INDENT simple_expr [IF simple_expr] NEWLINE _DEDENT)? RIGHT_BRACE -quant_target: string | identifier | list_expr | list_comp | config_expr | dict_comp -quant_op: ALL | ANY | FILTER | MAP -list_expr: LEFT_BRACKETS [list_items | NEWLINE [_INDENT list_items _DEDENT]] RIGHT_BRACKETS -list_items: list_item ((COMMA [NEWLINE] | [NEWLINE]) list_item)* [COMMA] [NEWLINE] -list_item: test | star_expr | if_item -list_comp: LEFT_BRACKETS (list_item comp_clause+ | NEWLINE _INDENT list_item comp_clause+ _DEDENT) RIGHT_BRACKETS -dict_comp: LEFT_BRACE (entry comp_clause+ | NEWLINE _INDENT entry comp_clause+ _DEDENT) RIGHT_BRACE -entry: test (COLON | ASSIGN | COMP_PLUS) test -comp_clause: FOR loop_variables [COMMA] IN simple_expr [NEWLINE] [IF test [NEWLINE]] -if_entry: IF test COLON if_entry_exec_block (ELIF test COLON if_entry_exec_block)* (ELSE COLON if_entry_exec_block)? -if_entry_exec_block: (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry) [NEWLINE] | NEWLINE _INDENT (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry) ((COMMA [NEWLINE] | [NEWLINE]) (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry))* [COMMA] [NEWLINE] _DEDENT -if_item: IF test COLON if_item_exec_block (ELIF test COLON if_item_exec_block)* (ELSE COLON if_item_exec_block)? -if_item_exec_block: list_item [NEWLINE] | NEWLINE _INDENT list_item ((COMMA [NEWLINE] | NEWLINE) list_item)* [COMMA] [NEWLINE] _DEDENT - -star_expr: MULTIPLY test -double_star_expr: DOUBLE_STAR test -loop_variables: primary_expr (COMMA primary_expr)* -schema_expr: identifier (LEFT_PARENTHESES [arguments] RIGHT_PARENTHESES)? config_expr -config_expr: LEFT_BRACE [config_entries | NEWLINE [_INDENT config_entries _DEDENT]] RIGHT_BRACE -config_entries: config_entry ((COMMA [NEWLINE] | [NEWLINE]) config_entry)* [COMMA] [NEWLINE] -config_entry: test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry - -//////////// lambda_expr //////////// -lambda_expr: LAMBDA [schema_arguments] [RIGHT_ARROW type] LEFT_BRACE [expr_stmt | NEWLINE _INDENT schema_init_stmt+ _DEDENT] RIGHT_BRACE - -//////////// misc //////////// -number: DEC_NUMBER [multiplier] | HEX_NUMBER | BIN_NUMBER | OCT_NUMBER | FLOAT_NUMBER -multiplier: SI_N_L | SI_U_L | SI_M_L | SI_K_L | SI_K | SI_M | SI_G | SI_T | SI_P - | SI_K_IEC | SI_M_IEC | SI_G_IEC | SI_T_IEC | SI_P_IEC -string: STRING | LONG_STRING -constant : TRUE | FALSE | NONE | UNDEFINED -// Tokens - -ASSIGN: "=" -COLON: ":" -SEMI_COLON: ";" -COMMA: "," -QUESTION: "?" -ELLIPSIS: "..." -RIGHT_ARROW: "->" -LEFT_PARENTHESES: "(" -RIGHT_PARENTHESES: ")" -LEFT_BRACKETS: "[" -RIGHT_BRACKETS: "]" -LEFT_BRACE: "{" -RIGHT_BRACE: "}" -PLUS: "+" -MINUS: "-" -MULTIPLY: "*" -DIVIDE: "/" -MOD: "%" -DOT: "." -AND: "&" -OR: "|" -XOR: "^" -NOT: "~" -LESS_THAN: "<" -GREATER_THAN: ">" -EQUAL_TO: "==" -NOT_EQUAL_TO: "!=" -GREATER_THAN_OR_EQUAL_TO: ">=" -LESS_THAN_OR_EQUAL_TO: "<=" -DOUBLE_STAR: "**" -DOUBLE_DIVIDE: "//" -SHIFT_LEFT: "<<" -SHIFT_RIGHT: ">>" -AT: "@" - -COMP_PLUS: "+=" -COMP_MINUS: "-=" -COMP_MULTIPLY: "*=" -COMP_DIVIDE: "/=" -COMP_MOD: "%=" -COMP_AND: "&=" -COMP_OR: "|=" -COMP_XOR: "^=" -COMP_DOUBLE_STAR: "**=" -COMP_DOUBLE_DIVIDE: "//=" -COMP_SHIFT_LEFT: "<<=" -COMP_SHIFT_RIGHT: ">>=" - -// Special tokens -IMPORT: "import" -AS: "as" -RULE: "rule" -SCHEMA: "schema" -MIXIN: "mixin" -PROTOCOL: "protocol" -CHECK: "check" -FOR: "for" -ASSERT: "assert" -IF: "if" -ELIF: "elif" -ELSE: "else" -L_OR: "or" -L_AND: "and" -L_NOT: "not" -IN: "in" -IS: "is" -LAMBDA: "lambda" -ALL: "all" -ANY: "any" -FILTER: "filter" -MAP: "map" -TYPE: "type" - -ANY_TYPE: "any" -STRING_TYPE: "str" -INT_TYPE: "int" -FLOAT_TYPE: "float" -BOOL_TYPE: "bool" - -// Constant tokens -TRUE: "True" -FALSE: "False" -NONE: "None" -UNDEFINED: "Undefined" - -// Binary prefix -SI_N_L: "n" -SI_U_L: "u" -SI_M_L: "m" -SI_K_L: "k" -SI_K: "K" -SI_M: "M" -SI_G: "G" -SI_T: "T" -SI_P: "P" -SI_K_IEC: "Ki" -SI_M_IEC: "Mi" -SI_G_IEC: "Gi" -SI_T_IEC: "Ti" -SI_P_IEC: "Pi" -IEC: "i" - -NAME: /\$?[a-zA-Z_]\w*/ -COMMENT: /#[^\n]*/ -NEWLINE: ( /\r?\n[\t ]*/ | COMMENT )+ - -STRING: /r?("(?!"").*?(? **note** -> -> Any character except the ASCII space, tab (`\t`) and formfeed (`\f`) is considered a none-space character. - -- A line ending in a backslash cannot carry a comment (, which will be introduced shortly afterwards). -- A backslash does not continue a comment. -- A backslash does not continue a token except for string literals (i.e., tokens other than string literals cannot be split across physical lines using a backslash). -- A backslash is illegal elsewhere on a line outside a string literal. - -### Implicit Line Joining - -Expressions in parentheses, square brackets or curly braces can be split over more than one physical line without using backslashes. - -- Implicitly continued lines can carry comments. -- The indentation of the continuation lines is not important. -- Blank continuation lines are allowed. -- There is no `NEWLINE` token between implicit continuation lines. -- Implicitly continued lines can also occur within triple-quoted strings (see below); in that case they cannot carry comments. - -### Blank Lines - -### Indentation - -### Comments - -Starting with a `#` character that is not part of a string literal is a comment. A comment ends at the end of the physical line. - -A comment signifies the end of the logical line unless the implicit line joining rules are invoked. - -Comments are ignored by the syntax. - -### Identifiers and Keywords - -Identifiers (also referred to as names) are described by the following lexical definitions. - -Within the ASCII range (from `U+0001` to `U+007F`), the valid characters for identifiers are the uppercase and lowercase letters `A` through `Z`, the underscore `_` and, except for the first character, the digits `0` through `9`. - -Identifiers are unlimited in length. The case is significant. - -### Keywords - -The following identifiers are used as reserved words, or keywords of the language, and cannot be used as ordinary identifiers. They must be spelled exactly as written here: - -```python -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -The following tokens are not used, but they are reserved as possible future keywords: - -```python -pass return validate rule flow -def del raise except try -finally while from with yield -global nonlocal struct class final -``` - -### Literals - -Literals are notations for constant values of some built-in types. - -### String Literals - -String literals are described by the following lexical definitions: - -``` -stringliteral ::= [stringprefix](shortstring | longstring) -stringprefix ::= "r" | "R" -shortstring ::= "'" shortstringitem* "'" | '"' shortstringitem* '"' -longstring ::= "'''" longstringitem* "'''" | '"""' longstringitem* '"""' -shortstringitem ::= shortstringchar | stringescapeseq -longstringitem ::= longstringchar | stringescapeseq -shortstringchar ::= -longstringchar ::= -stringescapeseq ::= "\" -``` - -Multiple adjacent string or bytes literals (delimited by whitespace),possibly using different quoting conventions, are allowed, and their meaning is the same as their concatenation. - -### Numeric Literals - -There are two types of numeric literals: integers and floating-point numbers. - -Integer literals are described by the following lexical definitions: - -``` -integer ::= decinteger | bininteger | octinteger | hexinteger -decinteger ::= nonzerodigit (["_"] digit)* | "0"+ (["_"] "0")* -bininteger ::= "0" ("b" | "B") (["_"] bindigit)+ -octinteger ::= "0" ("o" | "O") (["_"] octdigit)+ -hexinteger ::= "0" ("x" | "X") (["_"] hexdigit)+ -nonzerodigit ::= "1"..."9" -digit ::= "0"..."9" -bindigit ::= "0" | "1" -octdigit ::= "0"..."7" -hexdigit ::= digit | "a"..."f" | "A"..."F" -``` - -Floating-point literals are described by the following lexical definitions: - -``` -floatnumber ::= pointfloat | exponentfloat -pointfloat ::= [digitpart] fraction | digitpart "." -exponentfloat ::= (digitpart | pointfloat) exponent -digitpart ::= digit (["_"] digit)* -fraction ::= "." digitpart -exponent ::= ("e" | "E") ["+" | "-"] digitpart -``` - -## Operators and Delimiters - -### Operators - -The following tokens are operators: - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != @ -``` - -### Delimiters - -The following tokens serve as delimiters in the grammar: - -```python -( ) [ ] { } -, : . ; = += --= *= **= /= //= %= -<<= >>= &= |= ^= -``` - -The period can also occur in floating-point literals. - -The following printing ASCII characters have special meaning as part of other tokens or are otherwise significant to the lexical analyzer: - -``` -' " # \ -``` - -The following printing ASCII characters are not used in KCL. Their occurrence outside string literals and comments is an unconditional error: - -``` -? ` -``` - -## Reference - -Since the lexical conventions of KCL is very similar to that of Python, we use the following document as the reference when writing this chapter. - -- [https://docs.python.org/3/reference/lexical_analysis.html](https://docs.python.org/3/reference/lexical_analysis.html) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/modules.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/modules.md deleted file mode 100644 index f8608619..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/modules.md +++ /dev/null @@ -1,621 +0,0 @@ ---- -title: "Modules" -linkTitle: "Modules" -type: "docs" -weight: 2 -description: Modules ---- - -## Modules and the Import System - -KCL code is organized in **modules**. For code in one module to access the code defined in another module, a process called **importing** must be used. - -Importing is undertaken at compile-time in KCL. The advantage is to have static checking enabled. - -A regular KCL module is a file on the file system. It is required to have a `.k` suffix. - -## Packages - -To help manage modules and provide a naming hierarchy, KCL has the concept of packages. In KCL, a package maps to exactly a file system directory, and a regular module maps to a file. - -Files directly under a package are considered parts of the package, instead of individual regular modules. - -Packages can have sub-packages. - -Packages are special modules: - -- All packages in KCL are modules. -- A single-file module can never be a package. - -All modules have a name. - -Sub package names are separated from their parent package name by dots. - -To summary, a regular KCL module is a `.k` file, and a package is a directory on the file system. All `.k` files directly under the directory are included in the package, other files are ignored. If the directory has subdirectories, they become sub-packages as long as there are `.k` files underneath. - -### Intra-Package Name Space Sharing - -Inside a package, all `.k` files are considered parts of the package, instead of regular modules. Code in these files share a single name space and can access names defined in other files, without explicitly granted. - -### Package Initialization - -A package can have the initialization code. The code must exist in only one of the `.k` files under this package. The interpreter guarantees that the initialization code is executed after all definitions. - -## Searching - -The searching begins when an `import` statement is used to import a module. - -### Module Cache - -In KCL, only standard system modules are cached. When a cached module is imported, the cached version is used. In other words, KCL runtime would not create another copy of the standard system module in memory. - -However, other modules are uncached. Importing a module multiple time would create multiple instances of the module. - -### Module Names - -An `import` statement specifies the name of the module to import. The syntax is: - -``` -import [as ] -``` - -The rule to search with the module name is very simple: - -- **Step 1**: Searches the module name from the **standard system modules**, then **plugins modules**. - - See **standard system modules** and **plugins modules** for more details. If matched, the module is imported. Otherwise, continue to **Step 2**. -- **Step 2**. Whether a module name starts with a `.` is checked. If yes, the name is a so-called relative pathname, and we go to **Step 5**. Otherwise, continue to **Step 3**. -- **Step 3**: If the module name does not start with any `.`, then the compiler searches the nearest `root path` directory from this directory to the parent, and find the module according to the name just from the `root path`. If no `root path` is found, find the module according to the name from the folder the `.k` file including this `import` statement exists. - - **root path**: the directory contains a `kcl.mod` file. If matched, the module is imported. Otherwise, continue to **Step 4**. -- **Step 4**: Then the compiler checks if the name is the name of any library module that requires explicit loading. If matched, the library module is imported. Otherwise, continue to **Step 6**. -- **Step 5**. For relative importing, find the module according to the name from the folder the `.k` file including this `import` statement exists. Interpret leading dots using the following rule: -- One dot: Ignore. -- Tow or more dots: Suppose there are `n` leading dots, then the searching starts at `n - 1` levels above this folder. If matched, the module is imported. Otherwise, continue to **Step 6**. -- **Step 6**. Module not found, report an error. - -Do case-sensitive search when the operating system allows. If case-sensitive search is not allowed, search directories before regular files. - -In KCL, the `from <> import <>` is unsupported, and relative import is performed with the `import <>` syntax. - -### Uniqueness of Module - -Each module has a unique location path in its scope, so that a module or package could be located with a unique location path, such as `a.b.c`. - -Searching by location path should be supported by the kcl compiler, which needs to provide corresponding searching features through the command line and api form. - -## Standard System Packages - -KCL supports a few standard system modules. The following is the full list of these standard system modules: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PackageMember
datetimetoday
now
ticks
date
mathceil
exp
expm1
factorial
floor
gcd
isfinite
isinf
isnan
log
log1p
log2
log10
modf
pow
sqrt
regexreplace
match
compile
findall
search
split
unitsn
u
m
k
K
M
G
T
P
Ki
Mi
Gi
Ti
Pi
to_n
to_u
to_m
to_K
to_M
to_G
to_T
to_P
to_Ki
to_Mi
to_Gi
to_Ti
to_Pi
jsonencode
decode
dump_to_file
yamlencode
decode
dump_to_file
netsplit_host_port
join_host_port
fqdn
parse_IP
to_IP4
to_IP16
IP_string
is_IPv4
is_IP
is_loopback_IP
is_multicast_IP
is_interface_local_multicast_IP
is_link_local_multicast_IP
is_link_local_unicast_IP
is_global_unicast_IP
is_unspecified_IP
base64encode
decode
cryptomd5
sha1
sha224
sha256
sha384
sha512
- -- datetime - - ticks() -> float - Return the current time in seconds since the Epoch. Fractions of a second may be present if the system clock provides them. - - date() -> str - return the `%Y-%m-%d %H:%M:%S` format date. - - now() -> str - return the local time. e.g. `'Sat Jun 06 16:26:11 1998'` - - today() -> str - return the `%Y-%m-%d %H:%M:%S.%{ticks}` format date. -- math - - ceil(x) -> int - Return the ceiling of x as an Integral. This is the smallest integer >= x. - - factorial(x) -> int - Return x!. Raise a error if x is negative or non-integral. - - floor(x) -> int - Return the floor of x as an Integral. This is the largest integer <= x. - - gcd(a: int, b: int) -> int - Return the greatest common divisor of x and y - - isfinite(x) -> bool - Return True if x is neither an infinity nor a NaN, and False otherwise. - - isinf(x) -> bool - Return True if x is a positive or negative infinity, and False otherwise. - - isnan(x) -> bool - Return True if x is a NaN (not a number), and False otherwise. - - modf(x) -> Listfloat, float] - Return the fractional and integer parts of x. Both results carry the sign of x and are floats. - - exp(x) -> float - Return e raised to the power of x. - - expm1(x) -> float - Return exp(x)-1. This function avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small x. - - log(x, base=2.71828182845904523536028747135266250) -> float - Return the logarithm of x to the base e. - - log1p(x) -> float - Return the natural logarithm of 1+x (base e). The result is computed in a way which is accurate for x near zero. - - log2(x) -> float - Return the base 2 logarithm of x. - - log10(x) -> float - Return the base 10 logarithm of x. - - pow(x, y) -> float - Return x\*\*y (x to the power of y). - - sqrt(x) -> float - Return the square root of x. -- regex - - replace(string: str, pattern: str, replace: str, count=0) -> str - Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement. - - match(string: str, pattern: str) -> bool - Try to apply the pattern at the start of the string, returning a bool value True if any match was found, or False if no match was found. - - compile(pattern: str) -> bool - Compile a regular expression pattern, returning a bool value denoting whether the pattern is valid. - - findall(string: str, pattern: str) -> List[str] - Return a list of all non-overlapping matches in the string. - - search(string: str, pattern: str) -> bool - Scan through string looking for a match to the pattern, returning a bool value True if any match was found, or False if no match was found. - - split(string: str, pattern: str, maxsplit=0) -> List[str] - Scan through string looking for a match to the pattern, returning a Match object, or None if no match was found. -- units - - Unit constants - - Fixed point: `n`, `u`, `m`, `k`, `K`, `G`, `T` and `P`. - - Power of 2: `Ki`, `Mi`, `Gi`, `Ti` and `Pi`. - - Functions - - to_n(num: int) -> str - Int literal to string with `n` suffix - - to_u(num: int) -> str - Int literal to string with `u` suffix - - to_m(num: int) -> str - Int literal to string with `m` suffix - - to_K(num: int) -> str - Int literal to string with `K` suffix - - to_M(num: int) -> str - Int literal to string with `M` suffix - - to_G(num: int) -> str - Int literal to string with `G` suffix - - to_T(num: int) -> str - Int literal to string with `T` suffix - - to_P(num: int) -> str - Int literal to string with `P` suffix - - to_Ki(num: int) -> str - Int literal to string with `Ki` suffix - - to_Mi(num: int) -> str - Int literal to string with `Mi` suffix - - to_Gi(num: int) -> str - Int literal to string with `Gi` suffix - - to_Ti(num: int) -> str - Int literal to string with `Ti` suffix - - to_Pi(num: int) -> str - Int literal to string with `Pi` suffix -- json - - encode(data: any, sort_keys: bool = False, indent: int = None, ignore_private: bool = False, ignore_none: bool = False) -> str - Serialize a KCL object `data` to a JSON formatted str. - - decode(value: str) -> any - Deserialize `value` (a string instance containing a JSON document) to a KCL object. - - dump_to_file(data: any, filename: str, ignore_private: bool = False, ignore_none: bool = False) -> None - Serialize a KCL object `data` to a JSON formatted str and write it into the file `filename`. -- yaml - - encode(data: any, sort_keys: bool = False, ignore_private: bool = False, ignore_none: bool = False) -> str - Serialize a KCL object `data` to a YAML formatted str. - - decode(value: str) -> any - Deserialize `value` (a string instance containing a YAML document) to a KCL object. - - dump_to_file(data: any, filename: str, ignore_private: bool = False, ignore_none: bool = False) -> None - Serialize a KCL object `data` to a YAML formatted str and write it into the file `filename`. -- net - - split_host_port(ip_end_point: str) -> List[str] - Split the 'host' and 'port' from the ip end point. - - join_host_port(host, port) -> str - Merge the 'host' and 'port'. - - fqdn(name: str = '') -> str - Return Fully Qualified Domain Name (FQDN). - - parse_IP(ip) -> str - Parse 'ip' to a real IP address - - to_IP4(ip) -> str - Get the IP4 form of 'ip'. - - to_IP16(ip) -> int - Get the IP16 form of 'ip'. - - IP_string(ip: str | int) -> str - Get the IP string. - - is_IPv4(ip: str) -> bool - Whether 'ip' is a IPv4 one. - - is_IP(ip: str) -> bool - Whether ip is a valid ip address. - - is_loopback_IP(ip: str) -> bool - Whether 'ip' is a loopback one. - - is_multicast_IP(ip: str) -> bool - Whether 'ip' is a multicast one. - - is_interface_local_multicast_IP(ip: str) -> bool - Whether 'ip' is a interface, local and multicast one. - - is_link_local_multicast_IP(ip: str) -> bool - Whether 'ip' is a link local and multicast one. - - is_link_local_unicast_IP(ip: str) -> bool - Whether 'ip' is a link local and unicast one. - - is_global_unicast_IP(ip: str) -> bool - Whether 'ip' is a global and unicast one. - - is_unspecified_IP(ip: str) -> bool - Whether 'ip' is a unspecified one. -- base64 - - encode(value: str, encoding: str = "utf-8") -> str - Encode the string `value` using the codec registered for encoding. - - decode(value: str, encoding: str = "utf-8") -> str - Decode the string `value` using the codec registered for encoding. -- crypto - - md5(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `MD5` and the codec registered for encoding. - - sha1(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA1` and the codec registered for encoding. - - sha224(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA224` and the codec registered for encoding. - - sha256(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA256` and the codec registered for encoding. - - sha384(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA384` and the codec registered for encoding. - - sha512(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA512` and the codec registered for encoding. -- manifests - - `yaml_stream(values: [any], opts: {str:} = {sort_keys = False, ignore_private = True, ignore_none = False, sep = "---"}`. This function is used to serialize the KCL object list into YAML output with the `---` separator - -### The Built-in System Package - -KCL provides a list of built-in system modules, which are loaded automatically and can be directly used without providing any module name. For example, `print` is a widely used built-in module. - -The following is the full list of these built-in system modules: - -- print() - - The print function. -- multiplyof(a, b) - - Check if the modular result of a and b is 0 -- isunique(inval) - - Check if a list has duplicated elements -- len(inval) - Return the length of a value -- abs(x) - Return the absolute value of the argument. -- all(iterable) - Return True if bool(x) is True for all values x in the iterable. If the iterable is empty, return True. -- any(iterable) - Return True if bool(x) is True for any x in the iterable. If the iterable is empty, return False. -- bin(number) - Return the binary representation of an integer. -- hex(number) - Return the hexadecimal representation of an integer. -- oct(number) - Return the octal representation of an integer. -- ord(c) -> int - Return the Unicode code point for a one-character string. -- sorted(iterable) - Return a new list containing all items from the iterable in ascending order. A custom key function can be supplied to customize the sort order, and the reverse flag can be set to request the result in descending order. -- range(start, end, step=1) - Return the range of a value with start, end and step parameter. -- min(iterable) - With a single iterable argument, return its smallest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the smallest argument. -- max(iterable) - With a single iterable argument, return its biggest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the largest argument. -- sum(iterable, start) - Return the sum of a 'start' value (default: 0) plus an iterable of numbers. When the iterable is empty, return the start value. This function is intended specifically for use with numeric values and may reject non-numeric types. -- pow(x, y, z) - Equivalent to `x**y` (with two arguments) or `x**y % z` (with three arguments). Some types, such as ints, are able to use a more efficient algorithm when invoked using the three argument form. -- round(number, ndigits) - Round a number to a given precision in decimal digits. The return value is an integer if ndigits is omitted or None. Otherwise the return value has the same type as the number. ndigits may be negative. -- typeof(x: any, \*, full_name: bool = False) -> str - Return the type of the value 'x' at runtime. When the 'full_name' is 'True', return the full package type name such as `pkg.schema`. - -### Plugin Modules - -KCL compiler needs to provide the ability to dynamically expand and load plugin modules without modifying the compiler itself. KCL compiler needs to support flexible pluggable module extension mechanism, so that KCL users can use more abundant built-in function capabilities to simplify writing. - -KCL compiler needs to ensure the stability and safety of the expansion mechanism, without affecting the core of the compiler. - -Searching extended plugin module is performed after the standard system module. The standard system module has a higher priority in naming. If it exists a standard or built-in system module with the same name, the extended plugin module will be ignored. - -Importing and using the extended plugin module should be consistent with the standard or built-in system module. - -### Replacing Standard System Packages - -Replacing standard system modules is not allowed. - -## Examples - -We show more module features through an example. - -Suppose we have the following directories and files: - -``` - . - ├── mod1.k - ├── mod2.k - ├── pkg1 - │   ├── def1.k - │   ├── def2.k - │   └── def3init.k - └── pkg2 - ├── file2.k - └── subpkg3 - └── file3.k -``` - -From the structure we can see that `pkg1` and `pkg2` are two packages, `subpkg3` is a subpackage of `pkg2`, and `mod1.k` and `mod2.k` are regular modules. - -### Importing a Standard System Package - -The following statement can import the standard system module `math` - -```python -import math -``` - -This is the only way to import a standard system module. After importing a standard system module, functions, variables and schemas defined in it can be used. For example, the following statement uses the `log10` function -defined in `math` - -```python -a = math.log10(100) # a is 2 after computation. -``` - -### Importing a Regular Module - -In `mod1.k`, we can import `mod2` using one of the following syntaxes. - -```python -import mod2 -``` - -```python -import .mod2 -``` - -The difference is that in the first syntax, the KCL compiler will first try to check if `mod2` matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where `mod1.k` resists in, like what the second statement does. - -Suppose in `mod2.k` there is a definition of a variable:: - -```python -a = 100 -``` - -After importing `mod2`, we can access `a` in `mod1.k` using the following syntax - -```python -b = mod2.a -``` - -### Importing a Package - -In `mod1.k`, we can import `pkg1` using one of the following syntaxes. - -```python -import pkg1 -``` - -```python -import .pkg1 -``` - -The difference is that in the first syntax, the KCL compiler will first try to check if `pkg1` matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where `mod1.k` resists in, like what the second statement does. - -We can use similar statements to import `pkg2`. Note that importing `pkg2` will not import `subpkg3`. - -The name of the package is the name of the imported module. - -Suppose in `file2.k` that is inside `pkg2` there is a definition to variable `foo` - -```python -foo = 100 -``` - -This variable can be used in `mod1.k` after importing `pkg2` like the following - -```python -bar = pkg2.foo -``` - -### Importing a Subpackage - -To import `subpkg3` from `mod1.k`, one of the following statements can be used. - -```python -import pkg2.subpkg3 -``` - -```python -import .pkg2.subpkg3 -``` - -The behaviors of these statements are identical. - -The name of the subpackage is the name of the imported module. - -Suppose in `file3.k` that is inside `subpkg3` there is a definition to variable `foo` - -```python -foo = 100 -``` - -This variable can be used in `mod1.k` after importing `subpkg3` like the following - -```python -bar = subpkg3.foo -``` - -### Relative Importing - -Relative importing is useful when there is code trying to import modules that does not exist recursively inside the current directory. - -For example, the following statements, if written in `file3.k`, can be used to import `pkg2`, `pkg1` and `mod2` respectively. - -```python -import ...pkg2 # Go two levels up then import pkg2 -import ...pkg1 # Go two levels up then import pkg1 -import ...mod2 # Go two levels up then import mod2 -``` - -### Importing from a Root Path - -Suppose we have a `kcl.mod` file in the directory to mark it as a root path, then we have the following files: - -``` - . - |── kcl.mod - ├── mod1.k - ├── mod2.k - ├── pkg1 - │   ├── def1.k - │   ├── def2.k - │   └── def3init.k - └── pkg2 - ├── file2.k - └── subpkg3 - └── file3.k -``` - -In `pkg1` `def1.k`, we can import `pkg2.subpkg3` `file3` using the following syntaxes. - -```python -import pkg2.subpkg3.file3 -``` - -Importing from the root path is very convenient when the code is trying to import modules from a directory needs to look up multiple directories above this directory. At also, it is helpful to organize a large number of files in a root directory. - -### Importing a Module Inside a Package - -Note that `subpkg3` is only implemented with one file `file3.k`. The file can be regarded as a regular module and imported directly. - -In `mod1.k`, the importing statement would be:: - -```python -import pkg2.subpkg3.file3 -``` - -Different from importing `subpkg3`, now the name of the module is `file3`. We can access the variable `foo` defined in this module with the following -statement - -```python -bar = file3.foo -``` - -### Precedence of Importing - -When an import statement specifies a package to import, the virtual machine first looks for a directory named according to the import statement in the file system. - -If such a directory is not found, the virtual machine looks for a single file module. - -For example, when the statement `import a.b.c` appears, the virtual machine first looks for the directory `a/b/c` from the directory of the current file. If `a/b/c` is not found, the virtual machine looks for a file named `a/b/c.k`. If the file is also absent, an error is reported. - -### Package Implemented with Multiple Files - -Package `pkg1` is implemented with multiple KCL files. - -Multiple files can be used to define variables, schemas and functions, and they can access names defined in other files of this package. - -For example, suppose `def1.k` defines a variable `foo`, `def2.k` defines `bar`, and `def3init.k` defines a variable `baz`, when `pkg1` is imported by `mod1.k`, all these variable can be used - -```python -import pkg1 -a = pkg1.foo + pkg1.bar + pkg1.baz -``` - -Inside a module, names defined in a file can be accessed in another file without further importing. For example, suppose `bar` in `def2.k` would invoke `foo` defined in `def1.k`, it can directly use `foo` like the following - -```python -bar = foo + 1 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/schema.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/schema.md deleted file mode 100644 index c3d09f65..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/schema.md +++ /dev/null @@ -1,916 +0,0 @@ ---- -title: "Schema" -linkTitle: "Schema" -type: "docs" -weight: 2 -description: Schema ---- - -## Syntax - -### Schema Definition - -A schema is a language element to define a type of configuration data. - -To define a schema, the syntax is the following: - -```bnf -schema_stmt: [decorators] "schema" ["relaxed"] identifier ["[" [arguments] "]"] ["(" operand_name ")"] ":" NEWLINE [schema_body] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt | schema_index_signature | statement)* [check_block] _DEDENT -``` - -Attributes could be defined in a schema, the syntax is the following: - -```bnf -schema_attribute_stmt: [decorators] identifier ["?"] ":" type [(ASSIGN | augassign) test] NEWLINE -``` - -Index signature could be defined in a schema, the syntax is the following: - -```bnf -schema_index_signature: LEFT_BRACKETS [NAME COLON] [ELLIPSIS] basic_type RIGHT_BRACKETS COLON type [ASSIGN test] NEWLINE -``` - -Once defined, an attribute must have a valid type: - -```bnf -type: type_element ("|" type_element)* -type_element: schema_type | basic_type | list_type | dict_type -schema_type: operand_name -basic_type: "str" | "int" | "float" | "bool" -list_type: "[" (type)? "]" -dict_type: "{" (type)? COLON (type)? "}" -``` - -The followings are some basic examples: - -```python -# A person has a first name, a last name and an age. -schema person: - firstName: str - lastName: str - # fullName is generated by firstName and lastName - fullName: str = firstName + ' ' + lastName - # The default value of age is 0 - age: int = 0 - -# An employee IS a person, and has some additional information. -schema employee(person): - bankCard: int - nationality: str - -# A company has a name and many employees. -schema company: - name: str - employees: [employee] -``` - -More complex schema definitions will be elaborated after other concepts are -introduced. - -#### Optional Attribute - -Each attribute **must** be assigned with a not-None value as a schema instance unless it is modified by a question mark as an optional attribute. - -Examples: - -```bnf -schema employee(person): - bankCard?: int # bankCard is an optional attribute - nationality?: str # # nationality is an optional attribute -``` - -When there is an inheritance relationship: - -- If the attribute is optional in the base schema, it could be optional or required in the sub-schema. -- If the attribute is required in the base schema, it must be required in the sub-schema. - -### Configuration Definition - -A configuration is structured data stored in a dict-like structure. In KCL, we have introduced -the configuration definition syntax as a variant of dict definition syntax. - -```bnf -schema_expr: operand_name ("(" [arguments] ")")? dict_expr -``` - -As can be seen, apart from having an identifier as schema type, a configuration definition -is just an ordinary dict definition, and each key in the dict matches an attribute in the schema. - -To simplify configuration, schema attribute key is much easier to define as: - -- schema attribute key can be unquoted. When the attribute key has the same name as a variable, it must be quoted as a normal dict to avoid naming conflict. -- schema attribute key can be defined nested through `select expression`, such as `a.b.c`. - -The comma at the end of each line can be omitted. - -For example, we can define a `person` named `John Doe` using the following statement: - -```python -johnDoe = person { - # In the result, 'lastName' appears later than 'firstName', according the schema - lastName = 'Doe' - firstName = 'John' - # If we don't specify the 'age', the default value 0 is used. - # 'age': 20 -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' - 'age': 0 -} -``` - -Compared to the ordinary dict definition, a configuration definition has the following features: - -- Each attribute defined in the schema (or one of the schemas) could be configured, and config data has higher priority than the default value. -- When an attribute defined in the schema (or one of the schemas) is not configured in the configuration definition statement, and it has a default value, the default value is used. -- Unless the schema (or one of the schemas) is a **relaxed schema**, no more attributes can be defined. -- The quotation marks of dict key can be omitted. -- The comma at the end of each line can be omitted. -- Cases of **inheritance** will be discussed separately. - -For attributes of list, dict and schema types, the config data is added by **union** instead of reassignment. For instance: - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name = { - firstNam = "John" - lastName = "default" - } - -JohnDoe = Person { - name.lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' -} -``` - -#### Attribute Identify - -Each key identifier in the configuration expr identifies an element or a range of elements in a schema. The key identifier may consist of multiple attribute identifiers, and each attribute may be a basic type value, a list, a dict or schema. For example, the key identifier 'a.b.c' identifies the element 'c' in the 'A' schema: - -```python - -schema C: - c: int - -schema B: - b: C - -schema A: - a: B - -A { - a.b.c: 5 -} -``` - -To make the key identifier usage rules as clear as possible, we define the way of identifying with complex data types as follows. - -##### List - -Suppose we have a list attribute a. - -Identify an element in a: - -```python -a[0] # the first element -a[3] # the 4th element -a[-1] # the last element -a[-2] # the penultimate element -``` - -Identify a range of elements in the list: - -```python -a[2:5] # a slice of the third, 4th, and 5th elements -a[:5] # a slice of the first to 5th elements -``` - -#### Attribute Operator - -Once we identified the element(s), we can declare operation on it. It follows the pattern of `identifier op E`. - -#### Union - -Pattern: `identifier : E` - -The value of the expression `E` will be unioned into the element value. - -Examples: - -```python -a = A { - # union {d:4} into the element b.c, suppose c is a schema with an int type attribute d. - b.c : { - d : 4 - } -} -``` - -See 'union' in `expressions` spec for more details. - -#### Override - -Pattern: `identifier = E` - -The value of the expression `E` will override the element value. - -Examples: - -```python -a = A { - # override {c:4} to the element b, suppose b is a schema with an int type attribute c. - b = { - c: 4 - } -} -``` - -Unlike union, the override operation will reassign the element with a brand new value. -For basic type value, `union` and `override` have equivalent effects. - -Note: - -- Especially, we can "delete" its content by overriding the element to `Undefined`, such as `{ a = Undefined }`. - -#### Insert - -Pattern: `identifier += E` -Insert only works for list type `identifier`. - -List `E` will be inserted just after the specified index of the list `identifier`, and the following elements after the index will be automatically shifted. - -Examples: - -```python -a = A { - # insert {c:4} to the end position(just after index=1), suppose b is a list of schema with an int type attribute c. - b += { - c: 4 - } -} -``` - -If no index is specified, the last index will be used. - -The type of 'E' must be compatible with the type of list. See `types` for more details. - -#### Index Signature - -Index signatures can be defined in the KCL schema, and it means that the key-value constraints of the index signature can be used to construct a dict with the schema type, or additional checks can be added to the relaxed schema attributes to enhance the KCL type and semantic checks. - -- Use the form `[{attr_alias}: {key_type}]: {value_type}` to define an index signature in the schema, and `{attr_alias}` can be omitted. - -```python -schema Map: - """ - Map is a relaxed schema with a key of str type and a value of str type - """ - [str]: str # `{attr_alias}` can be omitted. - -data = Map { - key1 = "value1" - key2 = "value2" -} -``` - -- Mandatory all attributes of the schema key and value types - -```python -schema Person: - name: str - age: int # error, conflicts with the index signature definition `[str]: str` - [str]: str # The values of all attributes of the schema can only be strings -``` - -- Mandatory all attribute key and value types are defined in the schema, which is equivalent to restricting all attribute types except the relaxed attributes. - -```python -schema Person: - name: str - age: int - [...str]: str # Except for the `name` and `age` attributes, the key type of all other attributes of the schema must be `str`, and the value type must also be `str`. -``` - -- Define the index signature attribute alias and use it with the check block. - -```python -schema Data: - [dataName: str]: str - check: - dataName in ["Alice", "Bob", "John"] - -data = Data { - Alice = "10" - Bob = "12" - Jonn = "8" # error Jonn not in ["Alice", "Bob", "John"] -} -``` - -```python -import regex - -schema DataMap: - [attr: str]: str - check: - regex.match(attr, r'^[-._a-zA-Z0-9]+$') - -data = DataMap { - key1 = "value1" - "foo.bar" = "value2" # check error -} -``` - -### Schema Context - -The schema definition space can be regarded as a separate function context. - -Init statement could be defined inside the schema, the syntax is the following: - -```bnf -statement: small_stmt NEWLINE | if_stmt -``` - -The following is an example: - -```python -schema Person: - firstName: str = "John" - lastName: str - # fullName is generated by firstName and lastName in a separate init statement - fullName: str = firstName + ' ' + lastName - -JohnDoe = Person { - lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' -} -``` - -If statement, expr statement and assert statement are supported as a schema init -statement. See more in statement spec. - -- The attributes must be defined first, including inherited ones, and then used in the init statement. -- Statements in the schema context will be executed sequentially. -- The value of attributes referenced in the init statement will be evaluated at runtime. - See the **Configuration Definition** section for the assignment rules of non-referenced attributes. For example, `"fullName"` in Person is generated by `"firstName"` and `"lastName"` evaluated at runtime, in which firstName is 'John', and lastName is "Doe". - -The immutability of attributes in the schema context follows the same rules as the immutability of global variables: - -```python -schema Person: - age: int = 1 # Immutable attribute - _name: str = "Alice" # Mutable attribute - - age = 10 # Error - _name = "Bob" # Ok -``` - -#### Arguments - -Schema context can also have arguments. The following is an example. - -```python -schema Person[separator]: - firstName: str = "John" - lastName: str - fullName: str = firstName + separator + lastName - -JohnDoe = Person('_') { - lastName = "Doe" -} -``` - -The example is similar to the previous one, except that the separator character used in -the `"fullName"` member is passed in as an argument. The way to perform a schema generation -when the schema has an initialization function with arguments is demonstrated in the code. - -### Check Block - -Optionally, a check block can be added to a schema definition to allow -additional checking to be performed. - -The syntax is the following: - -```bnf -check_block: "check" ":" NEWLINE _INDENT check_expr+ _DEDENT -check_expr: test (IF test)? [":" primary_expr] NEWLINE -``` - -In terms of grammatical definition, a check block consists of a list of conditional expressions. The following is an example: - -```python -schema employee(person): - bankCard: int - gender: str - - check: - len(str(bankCard)) == 16 - gender in ['male', 'female'], "The gender {} is unsupported".format(gender) -``` - -The ability of KCL check expressions covers the abilities that can be defined by OpenAPI spec and is aligned with the ability of logical expressions. We consider further aligning the syntax with `CEL` spec. -Whether to support `lambda expressions` is still under discussion. - -Summary: - -- A check block consists of one or more logical **expressions**. -- When defining a configuration, the expressions in the check block are evaluated - in any order. If any of the expression is `False`, an error is reported. -- A custom error message can be provided after an expression. - -### Specifying Types - -Optionally, the type of any member of a schema can be specified. As previous examples have shown. - -A member can be of a basic type, such as a string (`str`), a floating-point number (`float`), a fixed-point number (`int`) or a boolean number (`bool`). - -A member can also be of a dictionary generated from another schema. In such a case, the name of the other schema is used as the type name. - -A member can also be a list or an ordinary dict: - -- A list with unspecified type of elements is `[]`. -- A list with elements of type `t` is `[t]`. Here `t` is another type. -- A dict with keys of type `kt` and values of type `vt` is `{kt:vt}`. -- `kt`, `vt` or both of them can be missing, like a list with unspecified type of elements. - -The followings are some more examples: - -- A list of lists of strings: `[[str]]`. -- A dict of keys with the type string and unspecified value types: `{str:}`. - -A member can be a **union type** defined by `|`, such as `a | b`, which means the type of the member could be a or b. - -A union type can include types of `int`, `str`, `float`, `bool`, `list` and `dict` and support type nesting e.g. `{str:str|int}` and `[[int|str]|str|float]`, etc. - -Examples: - -```python -schema x: - p: int | str # p could be defined as a int or string -``` - -### Immutability - -KCL pursues strict immutability of schema attributes. It's generally followed the rules: - -- For the attributes of the basic type, such as string, int and float, it's allowed to be reassigned - through the init statement in **schema context** or by the **configuration definition**. -- For the attributes of list, dict and schema type, it's allowed to be reassigned only by the init statement in **schema context**. The content of it is allowed to be operated in **schema context** or by the **configuration definition**. -- Any other attempt to reassign or modify schema attribute will report an error. - -#### Assign by Value - -When using a schema variable to assign the value to another variable, we can only get a deep copy of its value, not a pointer or reference. That is, modifying the assigned value will not change the assigned schema variable. - -```python -schema Person: - name: str - -person = { - name = "Alice" -} -personCopy = person # 'personCopy' is a deep copy of 'person' and modifying 'personCopy' will not affect 'person' -``` - -### Union Operator - -For list, dict and schema, we can union delta to existing data. For example: - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name = { - firstName = "John" - } - - # union a schema and a dict - name: Name { - lastName = "Doe" - } - -person = Person {} -``` - -The result is a **dict**: - -```python -{ - 'person': { - 'name': { - 'firstName': 'Jhon', - 'lastName': 'Doe' - } - } -} -``` - -### Other Operators - -Except for `assignment` and `union assignment`, it's not support other operators on schema type data. -Report an error if trying to use other operators on schema type data. - -### Deprecated - -The schema attribute can be marked as deprecated once it's considered invalid. - -```python -schema Person: - @deprecated(version="1.1.0", reason="use fullName instead", strict=True) - name: str - ... # Omitted contents - -person = Person { - # report an error on configing a deprecated attribute - name = "name" -} -``` - -- Deprecated attributes cannot be configured under any circumstances. Report an error or warning once the attribute is assigned. -- Define the expired version of the attribute through **version**, and define the reason for the attribute expired through **reason**. -- When strict is true, the attribute assignment will cause an error, otherwise it will report a warning and ignore the attribute assignment. - -### Composition - -The composition is a common way to define complex structures. KCL provides simplified means for the configuration definition of combined structures. - -Assuming we have the following schemas, which is defined by a combination of multiple schemas. - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name - age: int - -schema Group: - name: str - persons: [Person] -``` - -To config a group: - -```python -group = Group { - name = "group" - persons = [{ - name = { - firstName = "John" - lastName = "Doe" - } - age = 24 - }] -} -``` - -- Top-level schema name is required to config a schema. -- The schema of the attributes in the schema can be omitted. - -Multi-level nested schemas will make the configuration verbose. KCL supports defining attributes in the schema through `selector expression`. The selector form is **x.y.z**, see the following example: - -```python -group = Group { - name = "group" - persons = [{ - name.firstName = "John" - name.lastName = "Doe" - age = 24 - }] -} -``` - -- Selector can be used to represent attribute in a schema - -### Inheritance - -Inheritance is an effective means to define a hierarchical structure definition, and KCL supports limited **single inheritance** of the schema. - -```python -schema Person: - firstName: str - lastName: str - -# schema Scholar inherits schema Person -schema Scholar(Person): - fullName: str = firstName + '_' + lastName - subject: str - -JohnDoe = Scholar { - firstName = "John", - lastName = "Doe", - subject = "CS" -} -``` - -The result is a **dict**: - -```python -{ - 'JohnDoe': { - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' - 'subject': 'CS' - } -} -``` - -Each schema can be treated as a separated function context. Statements, including attribute statements and init statements, in the context of schemas will be evaluated from base schema to subschema according to the inheritance order. Each schema context is evaluated only once sequentially. The same goes for expressions in the check block. In the example, firstName and lastName are configured in the context of Person schema, and fullName is formed by splicing firstName and lastName in the context of Scholar schema. - -The default value can be modified in each schema. Value defined in **Configuration Definition** has a higher priority than the default value. Attributes with default values in any schema context ​​will eventually be unioned by configuration data. References to attributes in the schema context statements will use the value with unioned configuration data on evaluating at runtime. For example: - -```python -schema a: - x = 1 - y = x * 2 - -schema b(a): - x = 2 - -v = a { - x = 3 -} - -``` - -The result is a **dict**: - -```python -{ - 'v': { - 'x': 3 - 'y': 6 - } -} -``` - -Notes: - -- Report an error if inheriting more than one base schema. -- The type of the base schema attribute cannot be modified in the subschema. -- Report an error if inheriting a **mixin**. -- Report an error when a circular dependency occurs. - -Limitations: - -Since inheritance will derive some complex demands, we are cautious about these complex demands. There are still some restrictions on inheritance, and it's still under discussion. - -- KCL provides limited and deterministic polymorphism support, more complex and flexible polymorphism support, such as **self**, **super** keywords, are temporarily not included in the schema definition. -- Currently, KCL only supports the polymorphism of the inherited attributes of the schema, and does not support the polymorphism of the expressions in the check block. -- For the case of multiple levels of schema inheritance, the schema arguments can only be passed to the last level of sub-schema. - -### Mixin - -In addition to **composition** and **inheritance**, KCL supports declarative reuse of schema code through the **mixin** mechanism. To use a mixin, we only need to declare the **mixin** in the schema definition. - -The **mixin** syntax is the following: - -```bnf -//////////// mixin_stmt //////////// -mixin_stmt: "mixin" "[" [mixins | multiline_mixins] "]" "\n" -multiline_mixins: "\n" _INDENT mixins "\n" _DEDENT -mixins: operand_name ("," ("\n" mixins | operand_name))* -``` - -Here is a simple example: - -```python -schema Person: - mixin [FullNameMixin] - firstName: str = "default" - lastName: str - -schema FullNameMixin: - fullName: str = "{} {}".format(firstName, lastName) - -JohnDoe = Person { - firstName = "John" - lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'JohnDoe': { - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' - } -} -``` - -Multiple mixins can be added to a single schema, and mixins context will be evaluated after the host schema context at runtime. In the inheritance scenario, the mixin context can be regarded as a part of the host schema context, and the overall evaluation of schema context order is not affected. - -Notes: - -- The name of **mixin** schema must end with 'Mixin', otherwise an error will be reported. -- The attributes referenced in the **mixin** must be defined in the **mixin** itself or host schema, otherwise an error will be reported. - -### Protocol - -In addition to schema, an additional type definition method `protocol` is provided in KCL, and its properties are as follows: - -- In a protocol, only attributes and their types can be defined, complex logic and check expressions cannot be written, and mixins cannot be used. -- A protocol can only inherit or refer to other protocols, but cannot inherit or refer to other schemas. - -We can use **protocol** to add an optional host type to the dynamically inserted **mixin**. - -The **mixin** can define its host type through the `for` keyword, and internally it will query the type corresponding to the attribute from the host type. - -```python -protocol DataProtocol: # A mixin host type - data: str - -mixin DataMixin for DataProtocol: # Using the `for` keyword to define a mixin host type - x: int = data # The type of `data` is `str`, which is from `data` of `DataProtocol` -``` - -In `DataMixin`, the `data` attribute is obtained according to the `DataProtocol` host type as `str` type, and then a type error will occur when the value is assigned to `x` of type `int`: - -```python -protocol DataProtocol: - data: str - -mixin DataMixin for DataProtocol: - x: int = data # Error: expect int, got str - x: str = data # Error: can't change schema field type of 'x' from int to str -``` - -Please note that the host type **protocol** can only be used for **mixin** definitions (the suffix name is `Mixin`), otherwise an error will be reported. - -```python -protocol DataProtocol: - data: str - -schema Data for DataProtocol: # Error: only schema mixin can inherit from protocol - x: str = data -``` - -### Schema Context Evaluation - -The schema definition is composed of attribute statements, configuration data, init statements, mixins, and checks. In a separate schema context, the evaluation top-down order is as follows: - -``` -|------------------------------------------| -| attribute defaulting | -|------------------------------------------| -| configuration union | -|------------------------------------------| -| attribute templating | -|------------------------------------------| -| statements in declaration order | -|------------------------------------------| -| mixins in declaration order | -|------------------------------------------| -| check expressions in any order | -|------------------------------------------| -``` - -In the case of schema inheritance, each schema context is evaluated from the base schema in the order of inheritance, and each context is evaluated only once. -Suppose there are schemas a, b, and c, where c inherits b and b inherits a. Schema contexts will be evaluated in top-down order as: - -``` -|-----------------| -| schema a | -|-----------------| -| schema b | -|-----------------| -| schema c | -|-----------------| -``` - -### Members - -Built-in function and members of schema - -- instances() - Return the list of existing instances of a schema. - -### Irrelevant Order Calculation - -The irrelevant order calculation in the schema indicates the reference relationship between the internal attributes of the schema. For example, when we declare an expression of the form `a = b + 1`, the calculation of the value of `a` depends on the calculation of the value of `b`. When the compiler calculate the value of `a` and the value of `a` depends on the value of `b`, the compiler will choose to first calculate the value of `b`, and then calculate the value of a according to the expression `a = b + 1`, which is slightly different from the calculation method of traditional procedural language the difference. - -Since the calculation of values in the schema is based on dependencies, just like a directed acyclic graph traverses each node in the graph according to the order of topological sorting, the order of declaration of attributes in the schema is not so important, so the feature is called the irrelevant order calculation. - -Please note that there can be no circular references between different schema attribute values. - -We can see this feature through the following examples. - -```python -schema Person: - name?: str - age: int = _age - - _age = 10 - - if name == "Son": - _age = 18 - -schema Son(Person): - name: str = "Son" - -person = Person {} -son = Son {} -``` - -The output is - -```yaml -person: - name: null - age: 10 -son: - name: Son - age: 18 -``` - -Besides, we can achieve KCL polymorphism such as - -```python -schema Person: - name?: str - _age: int = _age - - _age = 10 - if name == "Son": - _age = 18 - elif name == "SonConf": - _age = 24 - -schema Son(Person): - name: str = "Son" - -person = Person() {} -son = Son() { - name = "SonConf" -} -``` - -The output is - -```yaml -person: - name: null - age: 10 -son: - name: SonConf - age: 24 -``` - -More examples: - -```python -schema Fib: - n1: int = n - 1 - n2: int = n1 - 1 - n: int - value: int = _value - - if n <= 2: - _value = 1 - else: - _value = (Fib {n = n1}).value + (Fib {n = n2}).value - -fib8 = (Fib {n = 8}).value -``` - -The output is - -```yaml -fib8: 21 -``` - -As in the above examples, we can see that in the schema, we only need to simply specify the dependency between attributes, and the compiler will automatically calculate the value based on the dependency, which can help us save a lot of boilerplate code and reduce configuration difficulty of writing. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/statements.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/statements.md deleted file mode 100644 index b09488b9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/statements.md +++ /dev/null @@ -1,185 +0,0 @@ ---- -title: "Statements" -linkTitle: "Statements" -type: "docs" -weight: 2 -description: Statements ---- - -## Syntax - -In KCL, statements consist of small statements and compound statements. The syntax is the following: - -```bnf -preamble_statement: preamble_small_stmt | preamble_compound_stmt -preamble_small_stmt: (small_stmt | import_stmt) NEWLINE -preamble_compound_stmt: compound_stmt | schema_stmt -statement: small_stmt NEWLINE | compound_stmt -compound_stmt: if_stmt -small_stmt: assign_stmt | expr_stmt | assert_stmt -``` - -The preamble statement is used to define the module level statements, consist of `statement`, `import_stmt`, and `schema_stmt`. The statement is used to define the block level statements, which are used in the `if` statement and `schema` statement. - -### Small Statements - -A small statement is comprised of a single logical line. Multiple statements in one-line are not allowed. - -#### Assignment Statements - -Generally, assign_stmt is divided into assignment and augmented assignment. The syntax is the following: - -```bnf -assign_stmt: target_primary ("=" target_primary)* "=" test | target_primary augassign test -augassign: "+=" | "-=" | "*=" | "**=" | "/=" | "//=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>=" | "or" | "and" -target_primary: identifier | target_primary DOT identifier -``` - -An assignment statement has the form `lhs = rhs`. It evaluates the expression on the right-hand side then assigns its value (or values) to the variable (or variables) on the left-hand side. - -The **target_primary** on the left-hand side is an `identifier` or an `identifier` followed by select dots. - -Note: When using **target_primary** will cause collisions, use **primary_expr** as an alternative. - -Examples: - -```python -k = 1 -a.b = "a.b" -``` - -To keep it simple, the compound target is not supported as **target_primary**. - -The right value of an assignment statement is a conditional expression, which is discussed separately. - -An augmented assignment, which has the form `lhs op= rhs` updates the variable `lhs` by applying a binary arithmetic operator op (one of +, -, \*, /, //, %, &, |, ^, <<, >>) to the previous value of `lhs` and the value of `rhs`. - -The **target_primary** on the left-hand side is the same as assignment statement. Examples: - -```python -_x -= 1 -_filename += ".k" -``` - -There is no concept of in-place modification in KCL. The `augassign` statement will modify a copy of the **target_primary** and assign the copy to **target_primary**. - -In particular, in KCL, the `|=` symbol represents the **union** operation, which is defined as follows: - -- The behavior of the **union** operation needs to be consistent with the behavior of the **configuration definition**. - -See **expressions** spec for more details of union operator in **Arithmetic Operations**. - -#### Expression Statements - -An expression statement evaluates an expression and discards its result. - -Syntax: - -```bnf -expr_stmt: expression -``` - -An expression statement supported in KCL is function invocation expression, which is discussed in **expression** spec. - -```python -print(k) # print a variable -``` - -#### Import Statements - -Import statements are used to **search** and **load** a module, and define a name or names in the local namespace for the scope where the import statement occurs. - -Syntax: - -```bnf -import_stmt: "import" dot_name ("as" NAME)? -dot_name: [leading_dots] identifier (DOT identifier)* -leading_dots: "."+ -``` - -Examples: - -```python -import math # import a built-in module math -import pkg # import pkg -import pkg.foo # import pkg.foo -import pkg.subpkg # import a subpkg in a pkg -import .pkg2.subpkg3 # import a subpkg in a pkg inside of current pkg -import ...pkg2 # Go two levels up then import pkg2 -``` - -See **module** spec for more details of module spec. - -#### Assert Statements - -Assert statements are a convenient way to insert debugging assertions into KCL code. - -The syntax is the following: - -``` -assert_stmt: ASSERT test ("," test)? -``` - -The conditional expression in assert will be evaluated and get a boolean. Report an error if returning a `False`. - -Examples: - -```python -assert: x > 1 # report an error on x <= 1 -``` - -#### Conditional Statements - -KCL allows using conditional statements to control the instructions to -be executed. They are also called the control-flow statements. - -The only type of control-flow syntax is the well-known `if-elif-else` syntax. - -The syntax of the `if-elif-else` statement is the following. - -```bnf -if_stmt: "if" test ":" suite ("elif" test ":" suite)* (ELSE ":" suite)? -suite: small_stmt | NEWLINE _INDENT statement+ _DEDENT -``` - -An `if` or `elif` statement evaluates a given expression. When the expression -is evaluated to `True`, a list of statements following `:` are executed. - -The following is an example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - print("maybe a is negative") -else: - print("a >= 100") -``` - -`if-elif-else` statements can be nested. For example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - if a < 0: - print("a is negative") - print("No matter a is negative or positive, this message is printed") -else: - print("a >= 100") -``` - -#### Schema Statements - -Schema statements are used to define a type of configuration data. The syntax is the following: - -```bnf -schema_stmt: [decorators] "schema" ["relaxed"] identifier ["[" [arguments] "]"] ["(" operand_name ")"] ":" NEWLINE [schema_body] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt | statement)* [check_block] _DEDENT -``` - -See **schema** spec for more details of schema spec. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/types/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/types/_category_.json deleted file mode 100644 index a8f40915..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/types/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "类型系统", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/types/types.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/types/types.md deleted file mode 100644 index 182ffaf2..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/types/types.md +++ /dev/null @@ -1,1401 +0,0 @@ -# 类型系统 - -本文档描述 KCL 的类型系统,包括: - -- 类型规则 -- 类型检查 -- 类型转换 -- 类型推导 - -## 类型规则 - -### 基础定义 - -#### 断言 - -$S$ 的所有自由变量都定义在 $\Gamma$ 中 - -$$ -\Gamma \vdash S -$$ - -$\Gamma$ 是一个变量的类型声明环境(well-formed environment),如:$x_1:T_1$, ..., $x_n:T_n$ - -$S$ 的断言有三种形式: - -**环境断言** 断言表示 $\Gamma$ 是良构类型 (well-formed type) - -$$ -\Gamma \vdash ◇ -$$ - -**良构类型断言** 在环境 $\Gamma$ 下,$nat$ 是类型表达式 - -$$ -\Gamma \vdash nat -$$ - -**类型判断断言** 在环境 $\Gamma$ 下,$E$ 具有类型 $T$ - -$$ -\Gamma \vdash E: T -$$ - -#### 推理规则 - -表示法 - -$$ -\frac{\Gamma \vdash S_1, ..., \Gamma \vdash S_n}{\Gamma \vdash S} -$$ - -推理规则中的 $u$, $v$, $w$ 用于表示变量,$i$, $j$, $k$ 用于表示整数,$a$, $b$ 用于表示浮点数,$s$ 用于表示字符串,$c$ 代表常量(整数、浮点数、字符串、布尔)的字面值, $f$ 用于表示函数, $T$, $S$, $U$ 用于表示类型。 - -## 环境规则 - -Env ⌀ - -$$ -\frac{}{⌀ \vdash ◇ } -$$ - -## 类型定义 - -Type Bool - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash boolean} -$$ - -Type Int - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash integer} -$$ - -Type Float - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash float} -$$ - -Type String - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash string} -$$ - -Type Literal - -$$ -\frac{ c \in \{boolean, integer, float, string\}}{\Gamma \vdash literalof(c)} -$$ - -Type List - -$$ -\frac{\Gamma \vdash T \ T \neq Void}{\Gamma \vdash listof(T) } -$$ - -Type Dict - -$$ -\frac{\Gamma \vdash T_1 \ \Gamma \vdash T_2\ T_1 \neq Void \ \ T_2 \neq Void}{\Gamma \vdash dictof(T_k=T_1, T_v=T_2)} -$$ - -Type Struct - -$$ -\frac{\Gamma \vdash T_{1} \ ... \ \Gamma \vdash T_{n} \ \ T_i \neq Void \ K_1 \neq K_n}{\Gamma \vdash structof(K_1 : T_{1}, ... , K_n : T_{n})} -$$ - -Type Union - -$$ -\frac{\Gamma \vdash T_1 \ ... \ \Gamma \vdash T_n \ \ T_i \neq Void}{\Gamma \vdash unionof(T_1, ..., T_n)} -$$ - -Type None - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash None} -$$ - -Type Undefined - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Undefined} -$$ - -Type Void - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Void} -$$ - -Type Any - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Any} -$$ - -Type Nothing - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Nothing} -$$ - -## 类型判断规则 - -### Operand Expr - -Exp Truth - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash true: boolean} -$$ - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash false: boolean} -$$ - -Exp Int - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash int: integer} -$$ - -Exp Flt - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash flt: float} -$$ - -Exp Str - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash str: string} -$$ - -Exp None - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash none: none} -$$ - -Exp Undefined - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash undefined: undefined} -$$ - -Expr ListExp - -$$ -\frac{\Gamma \vdash E_1: T_1 \ E_2: T_2 \ ... \ E_n: T_n}{\Gamma \vdash [E_1, E_2, ..., E_n]: listof \ sup(T_1, T_2, ..., T_n)} -$$ - -Expr ListComp - -$$ -\frac{\Gamma \vdash E_1: T_1 \ \Gamma \vdash v: T \ \Gamma \vdash E_2: listof \ T \ \Gamma \vdash E_3: boolean}{\Gamma \vdash [E_1 \ for \ v \ in \ E_2 \ if \ E_3]: listof(T_1) } -$$ - -Expr DictExp - -$$ -\frac{\Gamma \vdash E_{k1}: T_{k1} \ \Gamma \vdash E_{v1}: T_{v1} \ ... \ \Gamma \vdash E_{kn}: T_{kN} \ \Gamma \vdash E_{vn}: T_{vN}}{\Gamma \vdash \{E_{k1}: E_{v1}, ..., E_{{kn}}: E_{vn}\}: dictof(T_{k}=sup(T_{k1}, T_{k2}, ... T_{kn}), \ T_{v}=sup(T_{v1}, T_{v2}, ..., T_{vn}))} -$$ - -Expr DictComp - -$$ -\frac{\Gamma \vdash E_1: T_{rki} \ \Gamma \vdash E_2: T_{rvi} \ \Gamma \vdash v_1: T_k \ \Gamma \vdash v_2: T_v \ \Gamma \vdash E_3: dictof(T_{k}, \ T_{v}) \ \Gamma \vdash E_4: boolean}{\Gamma \vdash \{E_1:E_2 \ for \ (v_1, v_2) \ in \ E_3 \ if \ E_4\}: dictof(T_{k}=sup(T_{rk1}, T_{rk2}, ..., T_{rkn}), T_{v}=sup(T_{rv1}, T_{rv2}, ..., T_{rvn})) } -$$ - -Expr StructExpr - -$$ -\frac{\Gamma \vdash E_{1}: T_{1} \ ... \ \Gamma \vdash E_{n}: T_{n} \ K_1 \neq K_n}{\Gamma \vdash \{K_{1} = E_{1}, ..., K_{{n}} = E_{n}\}: structof(K_1 : T_{1}, ... , K_n : T_{n})} -$$ - -Literal 类型是基础类型的值类型,Union 类型是类型的组合类型,Void、Any、Nothing 是特殊的类型指代,本身没有直接的值表达式对应关系。 - -### Primary Expr - -Expr Index - -$$ -\frac{\Gamma \vdash E: listof(T) \ \Gamma \vdash Index: integer}{\Gamma \vdash E[Index]: T} -$$ - -Expr Call - -$$ -\frac{\Gamma \vdash E_1: T_1 \rightarrow T_2 \ \Gamma \vdash E_2: T_1}{\Gamma \vdash E_1 \ (E_2): T_2} -$$ - -Expr List Selector - -$$ -\frac{\Gamma \vdash E: listof(T) \ \Gamma \vdash Index: integer}{\Gamma \vdash E.[Index]: T} -$$ - -Expr Dict Selector - -$$ -\frac{\Gamma \vdash E: dictof(T_k = T_1, T_v=T_2) \ \Gamma \vdash S_1: string \ ... \ \Gamma \vdash S_n: string}{\Gamma \vdash E.\{S_1, ..., S_n\}: dictof(T_k = T_1, T_v=T_2)} -$$ - -Expr Struct Selector - -$$ -\frac{\Gamma \vdash E: structof(K_1 : T_{1}, ... , K_n : T_{n}) \ \Gamma \vdash K_i: string}{\Gamma \vdash E.K_i: T_{i}} -$$ - -### Unary Expr - -Expr + - -$$ -\frac{\Gamma \vdash E: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash \ +E: T} -$$ - -Expr - - -$$ -\frac{\Gamma \vdash E: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash \ -E: T} -$$ - -Expr ~ - -$$ -\frac{\Gamma \vdash E: integer}{\Gamma \vdash \ ~E: integer} -$$ - -Expr not - -$$ -\frac{\Gamma \vdash E: boolean}{\Gamma \vdash \ not \ E: boolean} -$$ - -### Binary Expr - -算数运算符 - -Expr op, op $\in$ {-, /, %, \*\*, //} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash E_1 \ op \ E_2: T} -$$ - -Expr + - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, float, string, listof(T_1)\}}{\Gamma \vdash E_1 \ + \ E_2: T} -$$ - -Expr \* - -$$ -\frac{\Gamma \vdash E_1: T_1 \ \ \ \Gamma \vdash E_2: T_2 \ \ \ \ (T_1==T_2 \in \{integer, float\}) \ or \ (T_1 == interger \ and \ T_2 \ \in \ \{string, listof(T_3)\}) \ or \ (T_2 == interger \ and \ T_1 \ \in \ \{string, listof(T_3)\})} {\Gamma \vdash E_1 \ * \ E_2: T} -$$ - -示例 - -Expr % - -$$ -\frac{\Gamma \vdash E_1: interger \ \ \ \Gamma \vdash E_2: integer}{\Gamma \vdash E_1 \ \% \ E_2: interger} -$$ - -逻辑运算符 - -Expr op, op $\in$ \{or, and\} - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ op \ E_2: boolean} -$$ - -示例 - -Expr and - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ and \ E_2: boolean} -$$ - -比较运算符 - -Expr op, op $\in$ \{==, !=, <, >, <=, >=\} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T}{\Gamma \vdash E_1 \ op \ E_2: boolean} -$$ - -示例 - -Expr > - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ > \ E_2: boolean} -$$ - -位运算符 - -Expr op, op $\in$ {&, ^, ~, <<, >>} - -$$ -\frac{\Gamma \vdash E_1: integer \ \ \ \Gamma \vdash E_2: integer}{\Gamma \vdash E_1 \ op \ E_2: integer} -$$ - -Expr | - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, listof(T_1), dictof(T_k, T_v), structof(K_1=T_1, ..., K_n=T_n)\}}{\Gamma \vdash E_1 \ | \ E_2: T} -$$ - -成员运算符 - -Expr op, op $\in$ {in, not in} - -$$ -\frac{\Gamma \vdash E_1: string \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{dictof, structof\}}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -Expr op, op $\in$ {in, not in} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: listof(S), T \sqsubseteq S}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -身份运算符 - -Expr op $\in$ {is, is not} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -### IF Expr - -Expr If - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: T \ \ \ \Gamma \vdash E_3: T}{\Gamma \vdash if \ E_1 \ then \ E_2 \ else \ E_3: T} -$$ - -### Stmt - -Stmt If - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash S_1: Void \ \ \ \Gamma \vdash S_2: Void}{\Gamma \vdash if \ E_1 \ then \ S_1 \ else \ S_2: Void} -$$ - -Stmt Assign - -$$ -\frac{\Gamma \vdash id: T_0 \ \ \ \Gamma \vdash T_1 \ \ \ \Gamma \vdash E: T_2}{\Gamma \vdash id: T_1 \ = \ E : Void} -$$ - -Type Alias - -$$ -\frac{\Gamma \vdash id: T_0 \ \ \ \Gamma \vdash T_1}{\Gamma \vdash type \ id \ = \ T_1 : Void} -$$ - -## Union - -### Union 规则 - -List Union - -$$ -\frac{\Gamma \vdash \ listof(T) \ \ \ \Gamma \vdash \ listof(S)}{\Gamma \vdash \ listof(unionof(T, S))} -$$ - -Dict Union - -$$ -\frac{\Gamma \vdash \ dictof(T_1, T_2) \ \ \ \Gamma \vdash \ dictof(S_1, S_2)}{\Gamma \vdash \ dictof(unionof(T_1, S_1), unionof(T_2, S_2))} -$$ - -Struct Union - -给定两个结构体 $structof(K_{1}: T_{1}, ..., K_{n}: T_{n}),structof(H_{1}: S_{1}, ..., H_{m}: S_{n})$ - -定义他们的 union 类型: - -$$ -structof(J_{1}: U_{1}, ..., J_{p}: U_{n}) = structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \bigcup structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) -$$ - -例如: - -$$ -structof() \ \bigcup \ structof(H_{1}: T_{1}, ..., H_{m}: T_{n}) = structof(H_{1}: T_{1}, ..., H_{m}: T_{n}) -$$ - -$$ -structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \ \bigcup \ structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) = structof(K_1: T_1) :: (structof(K_{2}: T_{2}, ..., K_{n}: T_{n}) \ \bigcup \ structof(H_{1}: S_{1}, ..., H_{m}: S_{n})) -$$ - -其中把 "::" 表示把一个对偶加入到一个结构的操作,定义如下: - -$$ -structof(K_{1}: T_{1}) :: structof() = structof(K_{1}: T_{1}) -$$ - -$$ -structof(K_{1}: T_{1}) :: structof(K_{1}: T_{1}', ..., K_n: T_{n}) = structof(K_{1}: union\_op(T_{1}, T_{1}'), ..., K_{n}: T_{n}) -$$ - -$$ -structof(K_{1}: T_{1}) :: structof(K_{2}: T_{2}, ..., K_n: T_{n}) = structof(K_{2}: T_2) :: structof(K_{1}: T_1) :: structof(K_{3}: T_3, ..., K_{n}: T_{n}) -$$ - -基于此,两个 Struct 的 union 定义为: - -$$ -\frac{\Gamma \vdash structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \ \Gamma \vdash structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) \ structof(J_{1}: U_{1}, ..., J_{p}: U_{n}) = structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \bigcup structof(H_{1}: S_{1}, ..., H_{m}: S_{n})}{\Gamma \vdash structof(J_{1}: U_{1}, ..., J_{p}: U_{n}))} -$$ - -其中 $union\_op(T_1, T_2)$ 表示对相同 $K_i$ 的不同类型的判断操作: - -- 当 $T_1$ 与 $T_2$ 有偏序关系时, 如果 $T_1 \sqsubseteq T_2$ 时,返回 $T_2$,否则返回 $T_1$,即取最小上界 -- 当 $T_1$ 与 $T_2$ 不存在偏序关系时,有三种可选的处理逻辑: - - 结构体 union 失败,返回 type_error - - 返回后者的类型,此处为 $T_2$ - - 返回类型 $unionof(T_1, T_2)$ - -此处需要根据实际需求选择适当的处理方式。 - -结构体继承可以看做一种特殊的 union,整体逻辑与 union 相似,但在 $union\_op(T_1, T_2)$ 中对相同 $K_i$ 的不同类型的判断操作如下: - -- 当 $T_1$ 与 $T_2$ 有偏序关系且 $T_1 \sqsubseteq T_2$ 时,返回 $T_1$,即仅当 $T_1$ 是 $T_2$ 的下界时以下界 $T_1$ 为准 -- 否则返回 type_error - -通过这样的继承设计可以实现分层的、自下而上逐层收缩的类型定义。 - -## Operation - -KCL 支持对结构体属性进行如 `p op E` 形式的操作。 即对给定结构体 $A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})$, 对结构体中的路径 `p` 以 `E` 的值进行指定的操作(如 union,assign,insert 等)。 - -定义如下更新操作: - -$$ -\frac{{\Gamma\vdash A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})}  {\Gamma\vdash p \in (K_{1}, ..., K_{n})} \ {\Gamma\vdash e:T}   k \neq k_1, ..., k \neq k_n} -{ A \{p \ op \ e\}:\{K_1:T_1, ..., K_n:T_n\}∪\{p:T\}} -$$ - -即对路径 $p$ 进行操作本质上是对两个结构体的一种 union,对同名属性类型 union 时的规则根据情况而定。例如路径 $p$ 是一个可用作字段名的标识符 $p=k_1$,并且结构体 A 中字段名也是 $k_1$,它的类型为 $T_1$,并且表达式 $e$ 的类型也为 $T_1$ ,那么 - -$$ -\frac{{\Gamma\vdash A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})}  {\Gamma\vdash p = K_{1}} \ {\Gamma\vdash e:T_1}   k \neq k_1, ..., k \neq k_n} -{ A \{p \ op \ e\}:\{K_1:T_1, ..., K_n:T_n\}} -$$ - -注意: - -- 此处表达式 $e$ 的类型 $T_1$ 同原先同名属性 $K_1$ 的具有相同的类型。可根据实际情况需要适当放松,如 $e$ 的类型 $\sqsubseteq T_1$ 即可。 -- 对于多层结构体嵌套的操作,递归的使用以上规则即可。 - -## 类型偏序 - -### 基础类型 - -$$ -Type \ T \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ T -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Bool \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Int \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Float \sqsubseteq Type \ Any -$$ - -$$ -Type \ Int \sqsubseteq Type \ Float -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ String \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Literal \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ List \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Dict \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Struct \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ None \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Void \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Any -$$ - -### 字面值类型 - -$$ -Type \ Literal(Bool) \sqsubseteq Type \ Bool -$$ - -$$ -Type \ Literal(Int) \sqsubseteq Type \ Int -$$ - -$$ -Type \ Literal(Float) \sqsubseteq Type \ Float -$$ - -$$ -Type \ Literal(String) \sqsubseteq Type \ String -$$ - -### 联合类型 - -$$ -Type \ X \sqsubseteq Type \ Union(X, Y) -$$ - -### 自反 - -$$ -Type \ X \sqsubseteq Type \ X -$$ - -示例 - -$$ -Type \ Bool \sqsubseteq Type \ Bool -$$ - -$$ -Type \ Int \sqsubseteq Type \ Int -$$ - -$$ -Type \ Float \sqsubseteq Type \ Float -$$ - -$$ -Type \ String \sqsubseteq Type \ String -$$ - -$$ -Type \ List \sqsubseteq Type \ List -$$ - -$$ -Type \ Dict \sqsubseteq Type \ Dict -$$ - -$$ -Type \ Struct \sqsubseteq Type \ Struct -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Nothing -$$ - -$$ -Type \ Any \sqsubseteq Type \ Any -$$ - -$$ -Type \ Union(Type Int, Type Bool) \sqsubseteq Type \ Union(Type Int, Type Bool) -$$ - -### 传递 - -$$ -Type \ X \sqsubseteq Type \ Z \ if \ Type \ X \sqsubseteq Type \ Y \ and \ Type \ Y \sqsubseteq \ Type \ Z -$$ - -### 包含 - -$$ -Type \ List(T_1) \sqsubseteq Type \ List(T_2) \ if \ T_1 \sqsubseteq T_2 -$$ - -$$ -Type \ Dict(T_{k1}, T_{v1}) \sqsubseteq Type \ Dict(T_{k2}, T_{v2}) \ if \ T_{k1} \sqsubseteq T_{k2} \ and \ T_{v1} \sqsubseteq T_{v1} -$$ - -$$ -Type \ Structure(K_1: T_{a1}, K_2: T_{a2}, ..., K_n: T_{an}) \sqsubseteq Type \ Structure(K_1: T_{b1}, K_2: T_{b2}, ..., K_n: T_{bn}) \ if \ T_{a1} \sqsubseteq T_{b1} \ and \ T_{a2} \sqsubseteq T_{b2} \ and \ ... \ and \ T_{an} \sqsubseteq T_{bn} -$$ - -### 继承 - -$$ -Type \ Struct \ A \sqsubseteq Type \ Struct \ B \ if \ A \ inherits \ B -$$ - -### None - -$$ -Type \ None \sqsubseteq Type \ X, X \notin \{Type \ Nothing, \ Type \ Void\} -$$ - -### Undefined - -$$ -Type \ Undefined \sqsubseteq Type \ X, X \notin \{Type \ Nothing, \ Type \ Void\} -$$ - -## 相等性 - -交换律 - -$$ -Type \ Union(X, Y) == Type \ Union(Y, X) -$$ - -示例 - -$$ -Type \ Union(Int, Bool) == Type \ Union(Bool, Int) -$$ - -结合律 - -$$ -Type \ Union(Union(X, Y), Z) == Type \ Union(X, Union(Y, Z)) -$$ - -示例 - -$$ -Type \ Union(Union(Int, String), Bool) == Type \ Union(Int, Union(String, Bool)) -$$ - -幂等性 - -$$ -Type \ Union(X, X) == Type \ X -$$ - -示例 - -$$ -Type \ Union(Int, Int) == Type \ Int -$$ - -偏序推导 - -$$ -Type \ Union(X, Y) == Type \ Y \ if \ X \sqsubseteq Y -$$ - -示例 - -假设 Struct A 继承 Struct B - -$$ -Type \ Union(A, B) == Type \ B -$$ - -幂等性是偏序自反的一个特例 - -### List - -$$ -Type \ List(X) == Type \ List(Y) \ if \ X == Y -$$ - -### Dict - -$$ -Type \ Dict(T_k, T_v) == Type \ Dict(S_k, S_v) \ if \ T_k == S_k \ and \ T_v == S_v -$$ - -### Struct - -$$ -Type \ Struct(K_1: T_{1}, K_2: T_{2}, ..., K_n: T_{n}) == Type \ Struct(K_1: S_{1}, K_2: S_{2}, ..., K_n: S_{n}) \ if \ T_{1} == S_{1} \ and \ ... \ and \ T_{n} == S_{n} -$$ - -### 偏序检查 - -$$ -Type \ X == Type \ Y \ if \ Type \ X \sqsubseteq Type \ Y \ and \ Type \ Y \sqsubseteq \ Type \ X -$$ - -## 基础方法 - -- sup(t1: T, t2: T) -> T: 根据类型偏序计算两类型 t1, t2 的最小上界。需要动态创建 union type。 -- typeEqual(t1: T, t2: T) -> bool: 比较两类型 t1, t2 是否相等。 -- typeToString(t: T) -> string: 自顶向下递归解析并转化类型成对应的字符串类型。 - -### Sup Function - -- 暂不考虑类型参数,条件类型等特性 -- 使用一个有序集合存储 UnionType 的所有类型 -- 使用一个全局的 Map 根据 UnionType 的名称存储产生的所有 UnionType -- 根据偏序关系计算类型之间的包含关系 - -```go -// The Sup function returns the minimum supremum of all types in an array of types -func Sup(types: T[]) -> T { - typeOf(types, removeSubTypes=true) -} - -// Build a sup type from types [T1, T2, ... , Tn] -func typeOf(types: T[], removeSubTypes: bool = false) -> T { - assert isNotNullOrEmpty(types) - // 1. Initialize an ordered set to store the type array - typeSet: Set[T] = {} - // 2. Add the type array to the ordered set for sorting by the type id and de-duplication - addTypesToTypeSet(typeSet, types) - // 3. Remove sub types according to partial order relation rules e.g. sub schema types - if removeSubTypes { - removeSubTypes(typeSet) - } - if len(typeSet) == 1 { - // If the typeSet has only one type, return it - return typeSet[0] - } - // 4. Get or set the union type from the global union type map - id := getIdentifierFromTypeSet(typeSet) - unionType := globalUnionTypeMap.get(id) - if !unionType { - unionType = createUnionType(typeSet) // Build a new union type - globalUnionTypeMap.set(id, unionType) - } - return unionType -} - -// Add many types into the type set -func addTypesToTypeSet(typeSet: Set[T], types: T[]) -> void { - for type in types { - addTypeToTypeSet(typeSet, type) - } -} - -// Add one type into the type set -func addTypeToTypeSet(typeSet: Set[T], type: T) -> void { - if isUnion(type) { - return addTypesToTypeSet(typeSet, toUnionOf(type).types) - } - // Ignore the void type check - if !isVoid(type) { - // De-duplication according to the type of id - typeSet.add(type) - } -} - -func removeSubTypes(types: Set[T]) -> void { - for source in types { - for target in types { - if !typeEqual(source, target) { - // If the two types have an inheritance relationship, the base class is retained, or if the two types have a partial order relationship according to the relation table. - if (isPartialOrderRelatedTo(source, target)) { - types.remove(source) - } - } - } - } -} - -// isPartialOrderRelatedTo function Determine whether two types have a partial order relationship `source \sqsubseteq target` -// according to the partial order relationship table and rules -func isPartialOrderRelatedTo(source: T, target: T) -> bool { - assert isNotNullOrEmpty(source) - assert isNotNullOrEmpty(target) - if isNoneOrUndefined(source) and !isNothing(target) and !isVoid(target) { - return true - } - if isAny(target) { - return true - } - if typeEqual(source, target) { - return true - } - if isUnion(target) and source in target.types { - return true - } - // Literal Type - if (isStringLiteral(source) and isString(target)) or \ - (isBooleanLiteral(source) and isBool(target)) or \ - (isIntLiteral(source) and isInt(target)) or \ - (isFloatLiteral(source) and isFloat(target)) { - return true - } - if isInt(source) and isFloat(target) { - return true - } - if isList(source) and isList(target) { - return isPartialOrderRelatedTo(toListOf(source).eleType, toListOf(target).eleType - } - if isDict(source) and isDict(target) { - return isPartialOrderRelatedTo(toDictOf(source).keyType, toDictOf(target).keyType) and isPartialOrderRelatedTo(toDictOf(source).valueType, toDictOf(target).valueType) - } - if isStruct(source) and isStruct(target) { - if isTypeDerivedFrom(source, target) { - return true - } - // Empty Object - if len(target.keys) == 0 { - return true - } - if any([key Not in source.keys for key in target.keys]) { - return false - } - for key, sourceType in (source.keys, source.types) { - targetType = getKeyType(target, key) ? getKeyType(target, key) : anyTypeOf() - if !isPartialOrderRelatedTo(sourceType, targetType) { - return false - } - } - return true - } - return false -} -``` - -## 类型检查 - -### 类型检查器 - -类型检查器通过语法制导翻译的方式,自顶向下遍历语法树,并根据上下文有关的**定型规则**来判定程序构造是否为良类型程序。 - -类型检查器依赖类型规则,类型环境 $\Gamma$ 的信息记入符号表。对类型表达式采用抽象语法,如 listof(T)。类型检查失败时产生 type_error,并根据语法上下文产生错误信息。 - -### 基础方法 - -1. isUpperBound(t1, t2): supUnify(t1, t2) == t2 -2. supUnify(t1, t2): - -- 对于基础类型,根据偏序关系计算 sup(t1, t2) -- 对于 list、 dict、 Struct, 递归地对其中元素的类型进行 supUnify -- 不存在偏序关系时,返回 Nothing - -### 检查逻辑 - -#### Operand Expr - -$D \to id: T$ - -``` -env.addtype(id.entry, T.type) -``` - -$T \to boolean$ - -``` -T.type = boolean -``` - -$T \to integer$ - -``` -T.type = integer -``` - -$T \to float$ - -``` -T.type = float -``` - -$T \to string$ - -``` -T.type = string -``` - -$T \to c, \ c \in \{boolean, integer, float, string\}$ - -``` -T.type = literalof(c) -``` - -$T \to None$ - -``` -T.type = None -``` - -$T \to Undefined$ - -``` -T.type = Undefined -``` - -$T \to \ [T_1]$ - -``` -T.type = listof (T1.type) -``` - -$T \to { \{T_1: T_2\} }$ - -``` -T.type = dictof (T1.type: T2.type) -``` - -$T \to { \{N_1: T_1, N2: T_2, ..., N_n: T_n\} }$ - -``` -T.type = structof (N1: T1.type, N2: T2.type, ..., Nn: Tn.type) -``` - -$E \to id$ - -``` -E.type = env.lookup(id.entry) -``` - -$E \to [E_1, E_2, ..., E_n]$ - -``` -func listExpr(E) { - supe = sup([e.type for e in E]]) - E.type = listof(type) -} -``` - -$E \to [E_1 \ for \ E_2 \ in \ E_3 \ if \ E_4]$ - -``` -func listComp(E) { - if !typeEqual(E4.type, boolean) { - raise type_error - } - if !isUpperBound(listof(Any), E3.type) { - raise type_error(E) - } - if !isUpperBound(E3.type, E2.type) { - raise type_error(E) - } - E.type = listof(E1.type) -} -``` - -$E \to \{E_{k1}: E_{v1}, ..., E_{kn}: E_{vn}\}$ - -``` -func dictExpr(E) { - supk := sup([e.type for e in E.keys()]]) - supv := sup([e.type for e in E.values()]]) - E.type = dictof(supk, supv) -} -``` - -$E \to \{E_1:E_2 \ for \ (E_3, E_4) \ in \ E_5 \ if \ E_6\}$ - -``` -func dictComp(E) { - if !typeEqual(E6.type, boolean) { - raise type_error(E) - } - if !isUpperBound(dictof(Any, Any), E5.type) { - raise type_error(E) - } - if !isUpperBound(E5.type, dictof(E3.type, E4.type)) { - raise type_error(E) - } - E.type = dictof(E1.type, E2.type) -} -``` - -$E \to \{E_{k1}: E_{v1}, ..., E_{kn}: E_{vn}\}$ - -``` -func dictExpr(E) { - supk := sup(Ek1, ..., Ekn) - supv = sup(Ev1, ..., Evn) - E.type = dictof(supk, supv) -} -``` - -$E \to \{N_{1} = E_{1}, ..., N_{{n}} = E_{n}\}$ - -``` -func structExpr(E) { - Struct = structof() - for n, e in E { - Struct.add(n, e.type) - } - E.type = Struct -} -``` - -#### Primary Expr - -$E \to E_1[E_2]$ - -``` -func sliceSuffix(E) { - if !isUpperBound(listof(Any), E.E1.type) { - raise type_error(E) - } - if typeEqual(E.E2.type, integer) { - raise type_error(E) - } - E.type = E.E1.type.eleType -} -``` - -$E \to E_1(E_2)$ - -``` -func callSuffix(E) { - if !typeEqual(E.E1.type, func) { - raise type_error(E) - } - if !isUpperBound(listof(E.E1.arguType), E.E2.type) { - raise type_error(E) - } - E.type = E.E1.returnType -} -``` - -#### Unary Expr - -根据每条双目运算符的推理规则推导,以 '+' 为例 - -$E \to + E_1$ - -``` -func Plus(E) { - if !typeEqual(E.E1.type, [integer, float]) { - raise type_error(E) - } - E.type = E.E1.type -} -``` - -#### Binary Expr - -根据每条双目运算符的推理规则推导,以 '%' 为例 - -$E \to E_1 \ % \ E_2$ - -``` -func Mod(E) { - if !(typeEqual(E.E1.type, [integer, float]) && typeEqual(E.E2.type, [integer, float])) { - raise type_error(E) - } - E.type = E.E1.type -} -``` - -#### IF Binary Expr - -$E \to if E_1 \ then \ E_2 else \ E_3$ - -``` -func ifExpr(E) { - if !typeEqual(E.type, boolean) { - raise type_error(E) - } - if !typeEqual(E_2.type, E_3.type) { - raise type_error(E) - } - E.type = E_2.type -} -``` - -#### Stmt - -$S \to if \ E \ then \ S_1 \ else \ S_2$ - -``` -func ifStmt(S) { - if !typeEqual(S.E.type, boolean) { - raise type_error(E) - } - if !typeEqual(S.S1.type, S.S2.type) { - raise type_error(E) - } - S.type = S.S1.type -} -``` - -$S \to id: T = E$ - -$S \to id = T E$ - -``` -func assignStmt(S) { - tpe := env.lookup(id.entry) - if tpe != nil && tpe != S.T { - raise type_error(E) - } - if isUpperBound(tpe, E.type) { - raise type_error(E) - } - env.addtype(id.entry, T.type) -} -``` - -## 类型转换 - -### 基础定义 - -通过语法制导翻译的方式,根据运算符特征,对参与运算的值类型进行自动类型转换 - -### 转换规则 - -$E \to E_1 \ op \ E_2, , op \in \{+, -, *, /, \%, **, //\}$ - -``` -func binOp(E) { - if E.E1.type == integer and E.E2.type == integer { - E.type = integer - } else if E.E1.type == integer and E.E2.type == float { - E.type = float - } else if E.E1.type == float and E.E2.type == integer { - E.type = float - } else if E.E1.type == float and E.E2.type == float { - E.type = float - } -} -``` - -## 类型推导 - -### 基础定义 - -- 在类型信息不完全的情况下类型规则推导、重建类型 -- 自底向上推导并重建数程序中的数据结构类型,如基础类型,list, dict, Struct - -### 基础方法 - -1. typeOf(expr, subst): 输入为表达式和代换规则集合,返回 expr 的类型和新的代换规则集合 -2. unifier(t1, t2, subst, expr) 用 t1=t2 尝试代换,如果代换成功(未出现且无冲突),则将 t1=t2 加入 subst 并返回 subst。否则报错已出现或有冲突。 - -### 推导逻辑 - -$E \to id = E_1$ - -``` -func assignExpr(E, subst) { - return unifier(E.id.type, E.E_1.type, subst, E) -} -``` - -$unifier(t1, t2, subst, expr) \rightarrow subst$ - -``` -func unifier(t1, t2, subst, expr) { - t1 = applySubstToTypeEquation(t1, subst) - t2 = applySubstToTypeEquation(t2, subst) - - if t1 == t2 { - return subst - } - - if isTypeVar(t1) { - if isNoOccur(t1, t2) { - addTypeEquationToSubst(subst, t1, t2) - return subst - } else { - raise occurrence_violation_error(t1, t2, expr) - } - } - - if isTypeVar(t2) { - if isNoOccur(t2, t1) { - addTypeEquationToSubst(subst, t2, t1) - return subst - } else { - raise occurrence_violation_error(t2, t1, expr) - } - } - - if isList(t1) and isList(t2) { - return unifier(toListOf(t1).eleType, toListOf(t2).eleType, subst, expr) - } - if isDict(t1) and isDict(t2) { - dict1of := toDictOf(t1) - dict2of := toDictOf(t2) - subst = unifier(dict1of.keyType, dict2of.keyType, subst, expr) - subst = unifier(dict1of.valueType, dict2of.valueType, subst, expr) - return subst - } - if isStruct(t1) and isStruct(t2) { - Struct1of := tostructof(t1) - Struct2of := tostructof(t2) - for key, _ in Struct1of { - subst = unifier(t1[key].type, t2[key].type, subst, expr) - } - return subst - } - - raise unification_error(t1, t2, expr) -} - -func applySubstToTypeEquation(t, subst) { - // walks through the type t, replacing each type variable by its binding in the substitution -σ. If a variable is Not bound in the substitution, then it is left unchanged. - if isBasicType(t) { - return t - } - if isList(t) { - return listOf(applySubstToTypeEquation(toListOf(t).eleType, subst)) - } - if isDict(t) { - dictof := toDictOf(t) - kT := applySubstToTypeEquation(dictof.keyType, subst) - vT := applySubstToTypeEquation(dictof.valueType, subst) - return dictOf(kT, vT) - } - if isStruct(t) { - structof := tostructof(t) - s := structof() - for key, type in Struct1of { - kT := applySubstToTypeEquation(type, subst) - s.add(key, kT) - } - return s - } - if hasTypeVar(t) { - for tvar in t.vars { - if tvar in subst { - *tvar = subst[tvar] - } - } - } - return t -} - -func addTypeEquationToSubst(subst, tvar, t) { - // takes the substitution σ and adds the equation tv = t to it - for _, t in subst { - for tvar in t.vars { - tmp := applyOneSubst(tsvar, tvar, t) - *tvar = tmp - } - } - subst.add(tvar, t) -} - -func applyOneSubst(t0, tvar, t1) { - // substituting t1 for every occurrence of tv in t0. - if isBasicType(t0) { - return t0 - } - if isList(t0) { - return listOf(applyOneSubst(toListOf(t).eleType, tvar, t1)) - } - if isDict(t0) { - dictof := toDictOf(t) - kT := applyOneSubst(dictof.keyType, tvar, t1) - vT := applyOneSubst(dictof.valueType, tvar, t1) - return dictOf(kT, vT) - } - if isStruct(t0) { - structof := tostructof(t) - s := structof() - for key, type in Struct1of { - kT := applyOneSubst(type, tvar, t1) - s.add(key, kT) - } - return s - } - if t0 == tvar { - return t1 - } - return t0 -} - -func isNoOccur(tvar, t) { - // No variable bound in the substitution occurs in any of the right-hand sides of the substitution. - if isBasicType(t) { - return true - } - if isList(t) { - return isNoOccur(tvar, toListOf(t).eleType) - } - if isDict(t) { - dictof := toDictOf(t) - return isNoOccur(tvar, dictof.keyType) and isNoOccur(tvar, dictof.valueType) - } - if isStruct(t) { - structof := tostructof(t) - noOccur := true - for _, type in structof { - noOccur = noOccur and isNoOccur(tvar, type) - } - return noOccur - } - return tvar != t -} -``` - -### 示例 - -#### 正常推导 - -``` -T : { - a = 1 - b = "2" - c = a * 2 - d = { - d0 = [a, c] - } -} - -x: T = { - a = 10 -} -``` - -#### Occurrence Violation Error - -``` -T = { - a = a -} -``` - -#### Type Unification Error - -``` -T : { - a = 1 -} - -T : { - a = "1" -} -``` - -## Reference - -- [https://en.wikipedia.org/wiki/Type_system](https://en.wikipedia.org/wiki/Type_system) -- Pierce, Benjamin C. (2002). Types and Programming Languages. MIT Press. -- [https://www.cs.cornell.edu/courses/cs4110/2010fa/](https://www.cs.cornell.edu/courses/cs4110/2010fa/) -- [https://www.typescriptlang.org/docs/handbook/basic-types.html](https://www.typescriptlang.org/docs/handbook/basic-types.html) -- [https://www.typescriptlang.org/docs/handbook/advanced-types.html](https://www.typescriptlang.org/docs/handbook/advanced-types.html) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/_category_.json deleted file mode 100644 index 53e27fd4..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "模块系统", - "position": 2 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/base64.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/base64.md deleted file mode 100644 index 0db738f0..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/base64.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: "base64" -linkTitle: "base64" -type: "docs" -description: base64 编码解码 -weight: 100 ---- - -## encode - -`encode(value: str, encoding: str = "utf-8") -> str` - -使用注册的编码器对字符串 `value` 进行编码。 - -## decode - -`decode(value: str, encoding: str = "utf-8") -> str` - -使用注册的编码器对字符串 `value` 进行解码。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/builtin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/builtin.md deleted file mode 100644 index 44085174..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/builtin.md +++ /dev/null @@ -1,401 +0,0 @@ ---- -title: "builtin" -sidebar_position: 1 ---- - -KCL 提供了一个内置系统模块的列表,这些模块是自动加载的,无需提供任何模块名称即可直接使用。例如,`print` 就是一个广泛使用的内置模块提供的函数。 - -## 类型转换函数 - -KCL的 `bool`、`int`、`float`、`str`、`list`、`dict`等类型有内置同名的转换函数。其中 `int` 不仅仅可以用于截断浮点数,也可以用来将字符串转化为整数(解析时为10进制,也可以制定其他值)。 - -下面是类型相关函数常见的用法: - -```py -b1 = bool(1) # true -b2 = bool(1.5) # true -b3 = bool("true") # true -b4 = bool("") # false -b5 = bool([]) # false -b6 = bool({}) # false - -i1 = int("11") # 11 -i2 = int("11", base=8) # 9 -i3 = int("11", base=2) # 3 - -f1 = float(1) # 1.0 -f2 = float("1.5") # 1.5 - -s1 = str(1) # 1 - -l1 = list([1, 2, 3]) -``` - -## String 类型成员函数 - -参考 [String 文档](/docs/reference/lang/spec/datatypes) - -## print - -`print(*args:any, end:str='\n')` - -内置的打印函数,提供不同类型的可变参数打印,默认在结尾添加一个换行符号。以下上常见的用法: - -```python -print("hello KCL") -print() -print(None, end=':') -print(None) -print(True) -print(False) -print(123) -print(123.0) -print('abc ${123}') -print("abc ${456}") -print([1,'a', True]) -print(1,'a', True) -print({}) -print({a: 123}) -``` - -输出格式如下: - -```shell -hello KCL - -None:None -True -False -123 -123.0 -abc 123 -abc 456 -[1, 'a', True] -1 a True -{} -{'a': 123} -``` - -如果不希望在默认换行时,可以通过 `end=''` 命名参数重新指定结尾的字符串。 - -## multiplyof - -`multiplyof(a:int, b:int) -> bool` - -判断整数 `a` 是否为 `b` 的整数倍,返回布尔值: - -```python -print(multiplyof(2, 1)) # True -print(multiplyof(1, 2)) # False -print(multiplyof(0, 1)) # True -print(multiplyof(0, 2)) # True -print(multiplyof(1, 0)) # Error -``` - -`0` 是任何数的倍数。但是 `b` 不能为 `0`,否则将抛出异常。 - -## isunique - -`isunique(list: [any]) -> bool` - -判断数组中是否存在重复的元素,返回布尔值: - -```python -print(isunique([])) # True -print(isunique([1])) # True -print(isunique([1, 2])) # True - -print(isunique([1, 1])) # False -print(isunique([1, 1.0])) # False -print(isunique([1.1, 1.1])) # False - -print(isunique(['abc', "abc"])) # False -print(isunique(['abc', "a${'bc'}"])) # False -``` - -需要注意的是整数和浮点数会忽略类型差异,根据值是否相等判断。 - -## len - -`len(x: str | [any] | {:}) -> int` - -返回字符串、列表和数组的长度: - -```python -print(len([])) # 0 -print(len({})) # 0 - -print(len([1])) # 1 -print(len({abc:123})) # 1 - -print("abc") # 3 -``` - -注:不支持对 `schema` 对象计算长度。 - -## abs - -`abs(x: number) -> number` - -计算 `x` 的绝对值。 - -## all_true - -`all_true(x:str|[]|{:}) -> bool` - -判断列表或字典类全部元素为真,用法如下: - -```python -print(all_true([])) # True -print(all_true({})) # True - -print(all_true([True])) # True -print(all_true([1])) # True - -print(all_true([True, False])) # False -print(all_true([True, None])) # False -``` - -当列表为空时返回真。 - - - -## any_true - -`any_true(x:str|[]|{:}) -> bool` - -判断可迭代对象中至少有一个元素为真,用法如下: - -```python -print(any_true([])) # False -print(any_true([1])) # True -``` - -## bin - -`bin(x:number) -> str` - -返回整数的二进制表示的字符串,用法如下: - -```python -print(bin(8)) # 0b1000 -``` - -## hex - -`hex(number)` - -返回整数的十六进制表示的字符串,用法如下: - -```python -print(hex(18)) # 0x12 -``` - -## oct - -`oct(number)` - -返回整数的八进制表示的字符串,用法如下: - -```python -print(oct(10)) # 0o12 -``` - -## option - -`option(key:str, type:str='', required=False, default=None, help="") -> any` - -获取命令行参数输入的值。 - -## ord - -`ord(c) -> int` - -获取字符的 Unicode 码点值,用法如下: - -```python -print(ord('A')) # 65 -print(ord('B')) # 66 -print(ord('C')) # 67 -``` - -## sorted - -`sorted(x: []) -> []` - -返回排序后的列表,用法如下: - -```python -_a = [] -_b = [2, 1] - -_c = sorted(_a) -_d = sorted(_b) - -print(_a) # [] -print(_b) # [2, 1] -print(_c) # [] -print(_d) # [1, 2] -``` - -## range - -`range(start:int, end:int, step=1) -> [int]` - -产生迭代列表,用法如下: - -```python -print(range(1,5)) # [1, 2, 3, 4] -print(range(1,5, 2)) # [1, 3] -print(range(5, 1, -1)) # [5, 4, 3, 2] -``` - -## min - -`min(x:[number]) -> number` - -返回列表中最小的元素,用法如下: - -```python -print(min([1,2])) # 1 -print(min([2,1])) # 1 -``` - - - -## max - -`max(x:[number]) -> number` - -返回列表中最大的元素,用法如下: - -```python -print(max([1,2])) # 2 -print(max([2,1])) # 2 -``` - -## sum - -`sum(x:[number], init_value=0) -> number` - -返回列表中全部元素的和,用法如下: - -``` -print(sum([1,2])) # 3 -print(sum([2,1], 1000)) # 1003 -``` - -## pow - -`pow(x: number, y: number, z: number = None) -> number` - -计算 `x**y`,如果 `z` 非空则计算 `(x**y)%z`,支持整数和浮点数。 - -下面的常见的用法: - -```python -print(pow(2,3)) # 8 -print(pow(2, 3, 5)) # 8%5 == 3 - -print(pow(2, 0.5)) # 1.414 -``` - -## round - -`round(number: int|float, ndigits:int|None) -> float | int` - -返回 `number` 的四舍五入近似值。如果 `ndigits` 非 `None` 则返回浮点数并保留指定位数的小数(不能为负数),否则返回整数结构。 - -下面是常用的用法: - -```python -print(round(1)) # 1 -print(round(1.4)) # 1 -print(round(1.5)) # 2 - -print(round(1.5555, 1)) # 1.6 -print(round(1.5555, 2)) # 1.56 - -print(round(1.5555)) # 2 -print(round(1.5555, 0)) # 2.0 -``` - -需要注意的是,`ndigits` 为 `None` 和 `0` 的区别是前缀返回 `int` 类型、后者返回 `float` 类型。 - -## typeof - -`typeof(x: any, full_name: bool = False) -> str` - -输出 `x` 在运算时的类型。当 `full_name` 参数设置为 `True` 时,将返回 `pkg.schema` 形式的包前缀。 - -下面是常见的用法: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person{} -t3 = typeof(_x1) - -_x2 = pkg.Person{} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# 输出 -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -## zip - -`zip(*args: str|list|dict)` - -用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。 - -下面是常见的用法: - -```py -a = zip([0, 1, 2], [3, 4, 5]) -b = zip([0, 1], [3, 4, 5]) -c = zip([0, 1, 2], [3, 4, 5, 6]) - -# 输出 -# a: -# - - 0 -# - 3 -# - - 1 -# - 4 -# - - 2 -# - 5 -# b: -# - - 0 -# - 3 -# - - 1 -# - 4 -# c: -# - - 0 -# - 3 -# - - 1 -# - 4 -# - - 2 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/crypto.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/crypto.md deleted file mode 100644 index cef03352..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/crypto.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "crypto" -linkTitle: "crypto" -type: "docs" -description: crypto 包 - 提供 SHA 相关的哈希函数 -weight: 100 ---- - -## md5 - -`md5(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `MD5` 算法对字符串 `value` 进行加密。 - -## sha1 - -`sha1(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA1` 算法对字符串 `value` 进行加密。 - -## sha224 - -`sha224(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA224` 算法对字符串 `value` 进行加密。 - -## sha256 - -`sha256(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA256` 算法对字符串 `value` 进行加密。 - -## sha384 - -`sha384(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA384` 算法对字符串 `value` 进行加密。 - -## sha512 - -`sha512(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA512` 算法对字符串 `value` 进行加密。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/index.md deleted file mode 100644 index c1f4b4a0..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# 系统模块 - -KCL 通过系统模块、用户模块和插件模块提供工程化的扩展能力。本节介绍系统模块的基本概念,插件模块可以参考插件系统。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/manifests.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/manifests.md deleted file mode 100644 index 5c54e9c7..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/manifests.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: "manifests" -linkTitle: "manifests" -type: "docs" -description: manifests system module -weight: 100 ---- - -## yaml_stream - -```python -yaml_stream(values: [any], opts: {str:} = { - sort_keys = False - ignore_private = True - ignore_none = False - sep = "---" -}) -``` - -这个函数的功能是将 KCL 对象列表序列化为带 `---` 分隔符的样式 YAML 输出,它具有两个参数: - -- `values` - 一个 KCL 对象列表 -- `opts` - YAML 序列化选项 - - `sort_keys`:是否按属性名称的字典序对序列化结果进行排序(默认为 `False`)。 - - `ignore_private`:是否忽略名称以 `_` 开头的属性序列化输出(默认为 `True`)。 - - `ignore_none`:是否忽略值为 `None` 的属性(默认为 `False`)。 - - `sep`:在多个 YAML 文档之间选择怎样的分隔符(默认为 `"---"`)。 - -下面我们通过一个例子来说明: - -```python -# 使用 `import` 关键词导入 `manifests` 模块 -import manifests - -# `Deployment` schema 定义 -schema Deployment: - apiVersion: str = "v1" - kind: str = "Deployment" - metadata: {str:} = { - name = "deploy" - } - spec: {str:} = { - replica = 2 - } - -# `Service` schema 定义 -schema Service: - apiVersion: str = "v1" - kind: str = "Service" - metadata: {str:} = { - name = "svc" - } - spec: {str:} = {} - -# 定义两个 `Deployment` 资源 -deployments = [Deployment {}, Deployment {}] -# 定义两个 `Service` 资源 -services = [Service {}, Service {}] -# 将它们放入 KCL 列表,并调用 `manifests.yaml_stream` 函数。 -manifests.yaml_stream(deployments + services) -``` - -首先我们通过 `import` 关键字导入 `manifests` 模块并定义 2 个 Deployment 以及 2 个 Service 资源,当我们想以 YAML stream 并以 `---` 作为分隔符的格式依次输出这 4 个资源时,我们可以将它们合并为一个 KCL 列表并作为 `manifests.yaml_stream` 函数的 `values` 形参进行传入 (如无特殊需求,opts 参数一般使用默认值即可),最终得到 YAML 输出为: - -```yaml -apiVersion: v1 -kind: Deployment -metadata: - name: deploy -spec: - replica: 2 ---- -apiVersion: v1 -kind: Deployment -metadata: - name: deploy -spec: - replica: 2 ---- -apiVersion: v1 -kind: Service -metadata: - name: svc ---- -apiVersion: v1 -kind: Service -metadata: - name: svc -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/math.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/math.md deleted file mode 100644 index 3b2ff0cc..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/math.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: "math" -linkTitle: "math" -type: "docs" -description: math 包 - 数学函数 -weight: 100 ---- - -## ceil - -`ceil(x) -> int` - -返回 `x` 向上取整得到的整数,这是大于等于 `x` 的最小整数。 - -## factorial - -`factorial(x) -> int` - -返回 `x` 的阶乘(即 `x!`),如果 `x` 是负数或者不是整数,则会引发一个错误。 - -## floor - -`floor(x) -> int` - -返回 `x` 向下取整得到的整数,这是小于等于 `x` 的最大整数。 - -## gcd - -`gcd(a: int, b: int) -> int` - -返回 `x` 和 `y` 的最大公约数。 - -## isfinite - -`isfinite(x) -> bool` - -如果 `x` 既不是无穷大也不是 `NaN` 返回 `True`,否则返回 `False`。 - -## isinf - -`isinf(x) -> bool` - -如果 `x` 是正无穷或负无穷返回 `True`,否则返回 `False`。 - -## isnan - -`isnan(x) -> bool` - -如果 `x` 是 `NaN` 返回 `True`,否则返回 `False`。 - -## modf - -`modf(x) -> List[float, float]` - -返回 `x` 的整数和小数部分,两个结果均与 `x` 的正负号相同,并且均为浮点数。 - -## exp - -`exp(x) -> float` - -返回以 `e` 为底数, `x` 的幂。 - -## expm1 - -`expm1(x) -> float` - -返回 `e` 的 `x` 次方减去 1,该函数能够避免由于直接计算 `exp(x) - 1` 而引起的精度损失。 - -## log - -`log(x, base=2.71828182845904523536028747135266250) -> float` - -返回以 `e` 为底数,`x` 的对数。 - -## log1p - -`log1p(x) -> float` - -返回以 `e` 为底数,`1 + x` 的自然对数,该函数能够在 `x` 靠近 0 时精确计算结果。 - -## log2 - -`log2(x) -> float` - -返回 `x` 的以 2 为底的对数。 - -## log10 - -`log10(x) -> float` - -返回 `x` 的以 10 为底的对数。 - -## pow - -`pow(x, y) -> float` - -返回 `x` 的 `y` 次幂(即 `x` 的 `y` 次方)。 - -## sqrt - -`sqrt(x) -> float` - -返回 `x` 的平方根。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/net.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/net.md deleted file mode 100644 index 1050d16d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/net.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: "net" -linkTitle: "net" -type: "docs" -description: net 包 - 网络IP处理 -weight: 100 ---- - -## split_host_port - -`split_host_port(ip_end_point: str) -> List[str]` - -从 `ip_end_point` 分离出 `host` 和 `port`。 - -## join_host_port - -`join_host_port(host, port) -> str` - -合并 `host` 和 `port`。 - -## fqdn - -`fqdn(name: str = '') -> str` - -返回完全限定域名(FQDN)。 - -## parse_IP - -`parse_IP(ip) -> str` - -将 `ip` 解析为真实的 IP 地址。 - -## to_IP4 - -`to_IP4(ip) -> str` - -获取 `ip` 的 IPv4 表示形式。 - -## to_IP16 - -`to_IP16(ip) -> int` - -获取 `ip` 的 IPv6 表示形式。 - -## IP_string - -`IP_string(ip: str | int) -> str` - -返回 IP 字符串。 - -## is_IPv4 - -`is_IPv4(ip: str) -> bool` - -判断 `ip` 是否为 IPv4。 - -## is_IP - -`is_IP(ip: str) -> bool` - -判断 `ip` 是否为有效的 IP 地址。 - -## is_loopback_IP - -`is_loopback_IP(ip: str) -> bool` - -判断 `ip` 是否为回环地址。 - -## is_multicast_IP - -`is_multicast_IP(ip: str) -> bool` - -判断 `ip` 是否为组播地址。 - -## is_interface_local_multicast_IP - -`is_interface_local_multicast_IP(ip: str) -> bool` - -判断 `ip` 是否为接口、本地和组播地址。 - -## is_link_local_multicast_IP - -`is_link_local_multicast_IP(ip: str) -> bool` - -判断 `ip` 是否为链路本地和组播地址。 - -## is_link_local_unicast_IP - -`is_link_local_unicast_IP(ip: str) -> bool` - -判断 `ip` 是否为链路本地和单播地址。 - -## is_global_unicast_IP - -`is_global_unicast_IP(ip: str) -> bool` - -判断 `ip` 是否为全局单播地址。 - -## is_unspecified_IP - -`is_unspecified_IP(ip: str) -> bool` - -判断 `ip` 是否为 `unspecified` 地址。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/overview.md deleted file mode 100644 index aa3eaeb3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/overview.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -sidebar_position: 0 ---- - -# 概览 - -KCL 是面向配置的编程语言,通过内置模块、KCL 模块和插件模块提供工程化的扩展能力。 - -![](/img/docs/reference/lang/model/kcl-module.png) - -用户代码中不用导入直接使用 builtin 的函数(比如用 `len` 计算列表的长度、通过 `typeof` 获取值的类型等),而对于字符串等基础类型也提供了一些内置方法(比如转化字符串的大小写等方法)。对于相对复杂的通用工作则通过标准库提供,比如通过 import 导入 `math` 库就可以使用相关的数学函数,可以通过导入 `regex` 库使用正则表达式库。而针对 KCL 代码也可以组织为模块,比如 Konfig 大库中将基础设施和各种标准的应用抽象为模块供上层用户使用。此外还可以通过 Plugin 机制,采用 Python 为 KCL 开发插件,比如目前有 meta 插件可以通过网络查询中心配置信息,`app-context` 插件则可以用于获取当前应用的上下文信息从而简化代码的编写。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/regex.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/regex.md deleted file mode 100644 index e7b0c25c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/regex.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "regex" -linkTitle: "regex" -type: "docs" -description: regex 包 - 正则表达式 -weight: 100 ---- - -## replace - -`replace(string: str, pattern: str, replace: str, count=0) -> str` - -替换字符串 `string`中最左边、不重叠并且匹配模式 `pattern` 的部分替换为指定的字符串 `replace`,并返回替换后的字符串 - -## match - -`match(string: str, pattern: str) -> bool` - -尝试在字符串开头应用模式 `pattern`,找到了任何匹配项则返回 `True`,返回 `False` 表示没有找到匹配项 - -## compile - -`compile(pattern: str) -> bool` - -编译正则表达式模式 `pattern`,并返回一个布尔值,表示该模式是否有效 - -## findall - -`findall(string: str, pattern: str) -> List[str]` - -查找 `pattern` 在 `string` 中的所有非重叠匹配,并以字符串列表的形式返回 - -## search - -`search(string: str, pattern: str) -> bool` - -扫描字符串 `string` 以查找与模式匹配的项,如果找到任何匹配项,则返回布尔值 `True`,否则返回 `False` - -## split - -`split(string: str, pattern: str, maxsplit=0) -> List[str]` - -返回一个由字符串内单词组成的列表,使用 `pattern` 作为分隔字符串,最多进行 `maxsplit` 次拆分 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/units.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/units.md deleted file mode 100644 index 8c862d0e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/units.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: "units" -linkTitle: "units" -type: "docs" -description: units 包 - 单位处理 -weight: 100 ---- - -## 单位的常量 - -- 定点数: `n`, `u`, `m`, `k`, `K`, `G`, `T` 和 `P`. -- 2 的幂: `Ki`, `Mi`, `Gi`, `Ti` 和 `Pi`. - -## 函数列表 - -- `to_n(num: int) -> str` - 将 int 转换为以 `n` 作为后缀的字符串 -- `to_u(num: int) -> str` - 将 int 转换为以 `u` 作为后缀的字符串 -- `to_m(num: int) -> str` - 将 int 转换为以 `m` 作为后缀的字符串 -- `to_K(num: int) -> str` - 将 int 转换为以 `K` 作为后缀的字符串 -- `to_M(num: int) -> str` - 将 int 转换为以 `M` 作为后缀的字符串 -- `to_G(num: int) -> str` - 将 int 转换为以 `G` 作为后缀的字符串 -- `to_T(num: int) -> str` - 将 int 转换为以 `T` 作为后缀的字符串 -- `to_P(num: int) -> str` - 将 int 转换为以 `P` 作为后缀的字符串 -- `to_Ki(num: int) -> str` - 将 int 转换为以 `Ki` 作为后缀的字符串 -- `to_Mi(num: int) -> str` - 将 int 转换为以 `Mi` 作为后缀的字符串 -- `to_Gi(num: int) -> str` - 将 int 转换为以 `Gi` 作为后缀的字符串 -- `to_Ti(num: int) -> str` - 将 int 转换为以 `Ti` 作为后缀的字符串 -- `to_Pi(num: int) -> str` - 将 int 转换为以 `Pi` 作为后缀的字符串 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/plugin/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/plugin/_category_.json deleted file mode 100644 index 645deb88..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/plugin/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "插件系统", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/plugin/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/plugin/index.md deleted file mode 100644 index e2fe86d6..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/plugin/index.md +++ /dev/null @@ -1 +0,0 @@ -# 插件系统 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/plugin/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/plugin/overview.md deleted file mode 100644 index b3cc9469..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/plugin/overview.md +++ /dev/null @@ -1,183 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 简介 - -KCL 是声明式配置策略语言,对于不方便通过配置直接描述的复杂的业务逻辑可以通过通用的编程语言开发 KCL 插件对语言进行扩展。KCL 支持通过通用语言开发插件,KCL 程序导入插件中的函数。KCL 通过插件运行时和辅助的命令行工具提供插件支持。KCL 插件框架支持多种不同的通用语言开发插件,这里我们以 Python 为例简单说明插件的使用。 - -插件的 Git 仓库: [https://github.com/kcl-lang/kcl-plugin](https://github.com/kcl-lang/kcl-plugin) - -## 0. 前置依赖 - -使用 KCL Python 插件需要您的 `PATH` 中存在 `Python3.7+`。 - -## 1. 你好插件 - -KCL 插件在 KCL 的 `plugins` 子目录(通常安装在 `$HOME/.kcl/plugins` 目录),或者通过 `$KCL_PLUGINS_ROOT` 环境变量设置(环境变量优先级更高)。此外,`plugins` 插件目录还可以放在执行 KCL 命令的 `pwd` 路径或者父路径中。对于插件开发人员,插件都在 Git 仓库管理: [https://github.com/kcl-lang/kcl-plugin](https://github.com/kcl-lang/kcl-plugin) ,可以将插件仓库克隆到该目录进行开发。 - -输入 `kcl-plugin info` 命令查看查看插件目录(将其中的 `/Users/kcl_user` 替换成本地的 `$HOME` 路径): - -```shell -$ kcl-plugin info -# plugin_root: /Users/kcl_user/.kcl/plugins -``` - -通过 `kcl-plugin list` 子命令查看插件列表: - -```shell -$ kcl-plugin list -hello: hello doc - 0.0.1 -``` - -其中 `hello` 是 KCL 内置的示例插件(不要修改改插件)。 - -在 KCL 代码中,可以通过 `kcl_plugin.hello` 导入 `hello` 插件。`main.k` 代码如下: - -```python -import kcl_plugin.hello - -name = "kcl" -three = hello.add(1,2) -``` - -输出结果如下: - -```shell -$ python3 -m kclvm main.k -name: kcl -three: 3 -``` - -## 2. `kcl-plugin` 辅助命令 - -`kcl-plugin` 是提供的插件辅助工具,命令行帮助如下: - -```shell -$ kcl-plugin -usage: kcl-plugin [-h] {list,info,init,gendoc,test} ... -positional arguments: - {list,info,init,gendoc,test} - kcl plugin sub commands - list list all plugins - info show plugin document - init init a new plugin - gendoc gen all plugins document - test test plugin -optional arguments: - -h, --help show this help message and exit -``` - -其中 `list` 子命令用于查看插件列表;`info` 用户查看插件目录和每个插件的信息;`init` 可以用户初始化新插件;`gendoc` 更新全部插件的 API 文档;`test` 测试指定的插件。 - -## 3. 插件信息和文档 - -输入 `kcl-plugin info hello` 查看 `hello` 插件信息: - -```shell -$ kcl-plugin info hello -{ - "name": "hello", - "describe": "hello doc", - "long_describe": "long describe", - "version": "0.0.1", - "method": { - "add": "add two numbers, and return result", - "foo": "no doc", - "list_append": "no doc", - "say_hello": "no doc", - "tolower": "no doc", - "update_dict": "no doc" - } -} -``` - -插件的信息主要包含插件的名字和版本信息,插件提供的函数信息。该信息和插件目录中自动生成的 `api.md` 文件是一致的(插件 API 变化时通过 `kcl-plugin gendoc` 为全部的插件重新生成 `api.md` 文件)。 - -## 4. 插件的目录结构 - -插件的目录结构如下(将其中的 `/Users/kcl_user` 替换成本地的 `$HOME` 路径): - -```shell -$ tree /Users/kcl_user/.kcl/plugins/ -/Users/kcl_user/.kcl/plugins/ -├── _examples -├── _test -└── hello - ├── api.md - ├── plugin.py - └── plugin_test.py -$ -``` - -其中 `_examples` 目录下是插件的示例代码,`_test` 目录下是插件的 KCL 测试代码,其他以字母开头的目录是普通的插件(目录中同时包含 `plugin.py` 和 `plugin_test.py` 文件)。 - -KCL 的插件是有一个独立的纯 Python 代码文件实现,并且插件相互之间不能直接调用。插件的内容如下: - -```shell -$ cat ./hello/plugin.py -# Copyright 2020 The KCL Authors. All rights reserved. -INFO = { - 'name': 'hello', - 'describe': 'hello doc', - 'long_describe': 'long describe', - 'version': '0.0.1', -} -def add(a: int, b: int) -> int: - """add two numbers, and return result""" - return a + b -... -``` - -其中 `INFO` 指明了插件的名字、概要说明、详细说明和版本信息。而所有名字以字母开头的函数是插件给 KCL 提供的函数,因此 KCL 中可以直接调用 `add` 函数。 - -## 5. 创建一个插件 - -通过 `kcl-plugin init` 命令可以创建一个插件示例: - -``` -$ kcl-plugin init hi -$ kcl-plugin list -hello: hello doc - 0.0.1 -hi: hi doc - 0.0.1 -``` - -`kcl-plugin init` 命令会以内置的模板构造一个新的插件,然后通过 `kcl-plugin list` 命令可以查看到新创建的插件。 - -## 6. 插件的删除 - -KCL 插件在 KCL 的 `plugins` 子目录(通常安装在 `$HOME/.kcl/plugins` 目录)。 -可以通过命令 `kcl-plugin info` 查询插件安装目录。 - -```shell -$ kcl-plugin info -/Users/kcl_user/.kcl/plugins/ -$ tree /Users/kcl_user/.kcl/plugins/ -/Users/kcl_user/.kcl/plugins/ -├── _examples -├── _test -└── hello -- 删除这个目录就可以删除 hello plugin - ├── api.md - ├── plugin.py - └── plugin_test.py -$ -``` - -## 7. 插件的测试 - -插件是独立的纯 Python 文件实现,插件目录下有个 `plugin_test.py` 文件是插件的单元测试文件(基于 pytest 测试框架)。此外在 `_test` 目录下放置的是 KCL 文件的插件集成测试。`plugin_test.py` 单元测试是必须的,`_test` 目录下的 KCL 集成测试可以根据情况添加。 - -可以通过 `kcl-plugin test` 执行插件的单元测试: - -```shell -$ kcl-plugin test hello -============================= test session starts ============================== -platform darwin -- Python 3.7.6+, pytest-5.3.5, py-1.9.0, pluggy-0.13.1 -rootdir: /Users/kcl_user -collected 5 items -.kcl/plugins/hello/plugin_test.py ..... [100%] -============================== 5 passed in 0.03s =============================== -$ -``` - -集成测试可以通过在 `_test` 目录下执行 `python3 -m pytest` 命令进行测试。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/plugin/project_context.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/plugin/project_context.md deleted file mode 100644 index 0be02e78..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/plugin/project_context.md +++ /dev/null @@ -1,59 +0,0 @@ -# project_context - -project_context extract base info from project.yaml&stack.yaml - -_version: 0.0.1_ - -## `get_project_current_path` - -return the relative path of first file - -Example: - -```py -import kcl_plugin.project_context as ctx - -path = ctx.get_project_current_path() -print(path) -``` - -## `get_project_input_file` - -return compiling file list - -Example: - -```py -import kcl_plugin.project_context as ctx - -input_file = ctx.get_project_input_file() -print(input_file) -``` - -## `get_project_context` - -return the current project context from project.yaml - -Example: - -```py -import kcl_plugin.project_context as ctx - -project = ctx.get_project_context() -# Get project name -print(project?.name) -``` - -## `get_stack_context` - -return the current stack context from stack.yaml - -Example: - -```py -import kcl_plugin.project_context as ctx - -stack = ctx.get_stack_context() -# Get stack name -print(stack?.name) -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/_category_.json deleted file mode 100644 index e26f646c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "多语言", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/go-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/go-api.md deleted file mode 100644 index 2a978250..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/go-api.md +++ /dev/null @@ -1,665 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Go API - -```go -import kcl "kcl-lang.io/kcl-go" -``` - -## KCL Go SDK - -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ kcl files │ │ KCL-Go-API │ │ KCLResultList │ -│ ┌───────────┐ │ │ │ │ │ -│ │ 1.k │ │ │ │ │ │ -│ └───────────┘ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ ┌───────────┐ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.Get("a.b.c") │ -│ │ 2.k │ │ │ │ Run(path) │ │ │ └───────────┘ │ └───────────────┘ -│ └───────────┘ │────┐ │ └───────────┘ │ │ │ -│ ┌───────────┐ │ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ │ 3.k │ │ │ │ │ │ │ KCLResult │──┼────────▶│x.Get("k", &v) │ -│ └───────────┘ │ │ │ │ │ └───────────┘ │ └───────────────┘ -│ ┌───────────┐ │ ├───▶│ ┌───────────┐ │──────────▶│ │ -│ │setting.yml│ │ │ │ │RunFiles() │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ └───────────┘ │ │ │ └───────────┘ │ │ │ KCLResult │──┼────────▶│x.JSONString() │ -└─────────────────┘ │ │ │ │ └───────────┘ │ └───────────────┘ - │ │ │ │ │ -┌─────────────────┐ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ Options │ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.YAMLString() │ -│WithOptions │ │ │ │MustRun() │ │ │ └───────────┘ │ └───────────────┘ -│WithOverrides │────┘ │ └───────────┘ │ │ │ -│WithWorkDir │ │ │ │ │ -│WithDisableNone │ │ │ │ │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ -``` - -
Example -

- -```go -{ - const k_code = ` -name = "kcl" -age = 1 - -two = 2 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {} -x1 = Person { - age = 101 -} -` - - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First().YAMLString() - fmt.Println(yaml) - - fmt.Println("----") - - result := kcl.MustRun("./testdata/main.k").First() - fmt.Println(result.JSONString()) - - fmt.Println("----") - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - - fmt.Println("----") - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x1", &person)) -} -``` - -

-
- -## Index - -- [Go API](#go-api) - - [KCL Go SDK](#kcl-go-sdk) - - [Index](#index) - - [Constants](#constants) - - [func FormatCode](#func-formatcode) - - [func FormatPath](#func-formatpath) - - [func InitKclvmPath](#func-initkclvmpath) - - [func InitKclvmRuntime](#func-initkclvmruntime) - - [func LintPath](#func-lintpath) - - [func ListDepFiles](#func-listdepfiles) - - [func ListDownStreamFiles](#func-listdownstreamfiles) - - [func ListUpStreamFiles](#func-listupstreamfiles) - - [func OverrideFile](#func-overridefile) - - [func ValidateCode](#func-validatecode) - - [type KCLResult](#type-kclresult) - - [type KCLResultList](#type-kclresultlist) - - [func MustRun](#func-mustrun) - - [func Run](#func-run) - - [func RunFiles](#func-runfiles) - - [type KclType](#type-kcltype) - - [func GetSchemaType](#func-getschematype) - - [type ListDepFilesOption](#type-listdepfilesoption) - - [type ListDepsOptions](#type-listdepsoptions) - - [type Option](#type-option) - - [func WithCode](#func-withcode) - - [func WithDisableNone](#func-withdisablenone) - - [func WithKFilenames](#func-withkfilenames) - - [func WithOptions](#func-withoptions) - - [func WithOverrides](#func-withoverrides) - - [func WithPrintOverridesAST](#func-withprintoverridesast) - - [func WithSettings](#func-withsettings) - - [func WithSortKeys](#func-withsortkeys) - - [func WithWorkDir](#func-withworkdir) - - [type ValidateOptions](#type-validateoptions) - -## Constants - -KclvmAbiVersion is the current kclvm ABI version. - -```go -const KclvmAbiVersion = scripts.KclvmAbiVersion -``` - -## func [FormatCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L110) - -```go -func FormatCode(code interface{}) ([]byte, error) -``` - -FormatCode returns the formatted code. - -
Example -

- -```go -{ - out, err := kcl.FormatCode(`a = 1+2`) - if err != nil { - log.Fatal(err) - } - fmt.Println(string(out)) - -} -``` - -``` -a = 1 + 2 -``` - -

-
- -## func [FormatPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L122) - -```go -func FormatPath(path string) (changedPaths []string, err error) -``` - -FormatPath formats files from the given path path: if path is \`.\` or empty string, all KCL files in current directory will be formatted, not recursively if path is \`path/file.k\`, the specified KCL file will be formatted if path is \`path/to/dir\`, all KCL files in the specified dir will be formatted, not recursively if path is \`path/to/dir/...\`, all KCL files in the specified dir will be formatted recursively - -the returned changedPaths are the changed file paths \(relative path\) - -
Example -

- -```go -{ - changedPaths, err := kcl.FormatPath("testdata/fmt") - if err != nil { - log.Fatal(err) - } - fmt.Println(changedPaths) -} -``` - -

-
- -## func [InitKclvmPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L54) - -```go -func InitKclvmPath(kclvmRoot string) -``` - -InitKclvmPath init kclvm path. - -## func [InitKclvmRuntime](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L59) - -```go -func InitKclvmRuntime(n int) -``` - -InitKclvmRuntime init kclvm process. - -## func [LintPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L142) - -```go -func LintPath(paths []string) (results []string, err error) -``` - -LintPath lint files from the given path - -
Example -

- -```go -{ - - results, err := kcl.LintPath([]string{"testdata/lint/import.k"}) - if err != nil { - log.Fatal(err) - } - for _, s := range results { - fmt.Println(s) - } - -} -``` - -``` -Module 'a' is reimported multiple times -Module 'a' imported but unused -``` - -

-
- -## func [ListDepFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L127) - -```go -func ListDepFiles(workDir string, opt *ListDepFilesOption) (files []string, err error) -``` - -ListDepFiles return the depend files from the given path - -## func [ListDownStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L137) - -```go -func ListDownStreamFiles(workDir string, opt *ListDepsOptions) ([]string, error) -``` - -ListDownStreamFiles return a list of downstream depend files from the given changed path list. - -## func [ListUpStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L132) - -```go -func ListUpStreamFiles(workDir string, opt *ListDepsOptions) (deps []string, err error) -``` - -ListUpStreamFiles return a list of upstream depend files from the given path list - -## func [OverrideFile](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L154) - -```go -func OverrideFile(file string, specs, importPaths []string) (bool, error) -``` - -OverrideFile rewrites a file with override spec file: string. The File that need to be overridden specs: \[\]string. List of specs that need to be overridden. - -``` -Each spec string satisfies the form: := or :- -When the pkgpath is '__main__', it can be omitted. -``` - -importPaths. List of import statements that need to be added - -## func [ValidateCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L159) - -```go -func ValidateCode(data, code string, opt *ValidateOptions) (ok bool, err error) -``` - -ValidateCode validate data match code - -## type [KCLResult](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L47) - -```go -type KCLResult = kcl.KCLResult -``` - -
Example -

- -```go -{ - const k_code = ` -name = "kcl" -age = 1 - -two = 2 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {name = "kcl-go"} -x1 = Person {age = 101} -` - - result := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First() - - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - -} -``` - -``` -x0.name: kcl-go -x1.age: 101 -``` - -

-
- -
Example ('et_struct) -

- -```go -{ - const k_code = ` -schema Person: - name: str = "kcl" - age: int = 1 - X: int = 2 - -x = { - "a": Person {age = 101} - "b": 123 -} -` - - result := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First() - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x.a", &person)) - fmt.Printf("person: %+v\n", person) - -} -``` - -``` -person: &{Name:kcl Age:101} -person: {Name:kcl Age:101} -``` - -

-
- -## type [KCLResultList](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L48) - -```go -type KCLResultList = kcl.KCLResultList -``` - -### func [MustRun](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L64) - -```go -func MustRun(path string, opts ...Option) *KCLResultList -``` - -MustRun is like Run but panics if return any error. - -
Example -

- -```go -{ - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(`name = "kcl"`)).First().YAMLString() - fmt.Println(yaml) - -} -``` - -``` -name: kcl -``` - -

-
- -
Example (Raw Yaml) -

- -```go -{ - const code = ` -b = 1 -a = 2 -` - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(code)).GetRawYamlResult() - fmt.Println(yaml) - - yaml_sorted := kcl.MustRun("testdata/main.k", kcl.WithCode(code), kcl.WithSortKeys(true)).GetRawYamlResult() - fmt.Println(yaml_sorted) - -} -``` - -``` -b: 1 -a: 2 -a: 2 -b: 1 -``` - -

-
- -
Example (Schema Type) -

- -```go -{ - const code = ` -schema Person: - name: str = "" - -x = Person() -` - json := kcl.MustRun("testdata/main.k", kcl.WithCode(code)).First().JSONString() - fmt.Println(json) - -} -``` - -``` -{ - "x": { - "name": "" - } -} -``` - -

-
- -
Example (Settings) -

- -```go -{ - yaml := kcl.MustRun("./testdata/app0/kcl.yaml").First().YAMLString() - fmt.Println(yaml) -} -``` - -

-
- -### func [Run](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L69) - -```go -func Run(path string, opts ...Option) (*KCLResultList, error) -``` - -Run evaluates the KCL program with path and opts, then returns the object list. - -
Example (Get Field) -

- -```go -{ - - x, err := kcl.Run("./testdata/app0/kcl.yaml") - assert(err == nil, err) - - fmt.Println(x.First().Get("deploy_topology.1.zone")) - -} -``` - -``` -R000A -``` - -

-
- -### func [RunFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L74) - -```go -func RunFiles(paths []string, opts ...Option) (*KCLResultList, error) -``` - -RunFiles evaluates the KCL program with multi file path and opts, then returns the object list. - -
Example -

- -```go -{ - result, _ := kcl.RunFiles([]string{"./testdata/app0/kcl.yaml"}) - fmt.Println(result.First().YAMLString()) -} -``` - -

-
- -## type [KclType](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L50) - -```go -type KclType = kcl.KclType -``` - -### func [GetSchemaType](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L176) - -```go -func GetSchemaType(file, code, schemaName string) ([]*KclType, error) -``` - -GetSchemaType returns schema types from a kcl file or code. - -file: string - -``` -The kcl filename -``` - -code: string - -``` -The kcl code string -``` - -schema_name: string - -``` -The schema name got, when the schema name is empty, all schemas are returned. -``` - -## type [ListDepFilesOption](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L45) - -```go -type ListDepFilesOption = list.Option -``` - -## type [ListDepsOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L44) - -```go -type ListDepsOptions = list.DepOptions -``` - -## type [Option](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L43) - -```go -type Option = kcl.Option -``` - -### func [WithCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L79) - -```go -func WithCode(codes ...string) Option -``` - -WithCode returns a Option which hold a kcl source code list. - -### func [WithDisableNone](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L97) - -```go -func WithDisableNone(disableNone bool) Option -``` - -WithDisableNone returns a Option which hold a disable none switch. - -### func [WithKFilenames](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L82) - -```go -func WithKFilenames(filenames ...string) Option -``` - -WithKFilenames returns a Option which hold a filenames list. - -### func [WithOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L85) - -```go -func WithOptions(key_value_list ...string) Option -``` - -WithOptions returns a Option which hold a key=value pair list for option function. - -
Example -

- -```go -{ - const code = ` -name = option("name") -age = option("age") -` - x, err := kcl.Run("hello.k", kcl.WithCode(code), - kcl.WithOptions("name=kcl", "age=1"), - ) - if err != nil { - log.Fatal(err) - } - - fmt.Println(x.First().YAMLString()) - -} -``` - -``` -age: 1 -name: kcl -``` - -

-
- -### func [WithOverrides](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L88) - -```go -func WithOverrides(override_list ...string) Option -``` - -WithOverrides returns a Option which hold a override list. - -### func [WithPrintOverridesAST](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L100) - -```go -func WithPrintOverridesAST(printOverridesAST bool) Option -``` - -WithPrintOverridesAST returns a Option which hold a printOverridesAST switch. - -### func [WithSettings](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L91) - -```go -func WithSettings(filename string) Option -``` - -WithSettings returns a Option which hold a settings file. - -### func [WithSortKeys](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L105) - -```go -func WithSortKeys(sortKeys bool) Option -``` - -WithSortKeys returns a Option which hold a sortKeys switch. - -### func [WithWorkDir](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L94) - -```go -func WithWorkDir(workDir string) Option -``` - -WithWorkDir returns a Option which hold a work dir. - -## type [ValidateOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L46) - -```go -type ValidateOptions = validate.ValidateOptions -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/index.md deleted file mode 100644 index ea02d458..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/index.md +++ /dev/null @@ -1 +0,0 @@ -# 多语言 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/java-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/java-api.md deleted file mode 100644 index 1cea9e49..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/java-api.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Java API - -目前 KCL Java SDK 还处于早期预览版本,后续 KCL 团队会持续更新并提供更丰富的功能,更多信息请参阅:[https://github.com/kcl-lang/kcl-java](https://github.com/kcl-lang/kcl-java)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/overview.md deleted file mode 100644 index 29c8680d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/overview.md +++ /dev/null @@ -1,295 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 简介 - -KCL 语言提供 C/Rust/Go/Python/Java 等通用编程语言接口,相关语言正在开发完整中。 - -## C/Rust 语言 - -KCL 核心采用 Rust 语言开发,对外导出 C 语言 API 供 Go/Python/Java 等高级语言包装和集成。 - -## Go 语言 - -Go 语言是通过 CGO 包装 KCL 提供的 C-API,同时提供更深度的定制特性以满足上层工具的需求。 - -### API 抽象模型 - -Go 语言 API 的抽象模型如下图: - -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ kcl files │ │ KCL-Go-API │ │ KCLResultList │ -│ ┌───────────┐ │ │ │ │ │ -│ │ 1.k │ │ │ │ │ │ -│ └───────────┘ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ ┌───────────┐ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.Get("a.b.c") │ -│ │ 2.k │ │ │ │ Run(path) │ │ │ └───────────┘ │ └───────────────┘ -│ └───────────┘ │────┐ │ └───────────┘ │ │ │ -│ ┌───────────┐ │ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ │ 3.k │ │ │ │ │ │ │ KCLResult │──┼────────▶│x.Get("k", &v) │ -│ └───────────┘ │ │ │ │ │ └───────────┘ │ └───────────────┘ -│ ┌───────────┐ │ ├───▶│ ┌───────────┐ │──────────▶│ │ -│ │setting.yml│ │ │ │ │RunFiles() │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ └───────────┘ │ │ │ └───────────┘ │ │ │ KCLResult │──┼────────▶│x.JSONString() │ -└─────────────────┘ │ │ │ │ └───────────┘ │ └───────────────┘ - │ │ │ │ │ -┌─────────────────┐ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ Options │ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.YAMLString() │ -│WithOptions │ │ │ │MustRun() │ │ │ └───────────┘ │ └───────────────┘ -│WithOverrides │────┘ │ └───────────┘ │ │ │ -│WithWorkDir │ │ │ │ │ -│WithDisableNone │ │ │ │ │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ -``` - -其中输入的文件包含 KCL 文件和 `setting.yml` 配置文件,`Options` 可以用于指定额外的参数和工作目录等信息。“KCL-Go-API”部分是提供的 KCL 执行函数,执行函数根据输入文件和额外的参数执行 KCL 程序,最终输出 `KCLResultList` 结果。`KCLResultList` 是一个 `KCLResult` 构成的列表,每个 `KCLResult` 对应一个生成的配置文件或 `map[string]interface{}`。 - -### 例子 - -```go -package main - -import ( - "fmt" - - kcl "kcl-lang.io/kcl-go" -) - - -func main() { - const k_code = ` -name = "kcl" -age = 1 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person{} -x1 = Person{age:101} -` - - result := kcl.MustRun("hello.k", kcl.WithCode(k_code)).First() - fmt.Println(result.YAMLString()) - - fmt.Println("----") - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - - fmt.Println("----") - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x1", &person)) -} -``` - -输出结果: - -```yaml -age: 1 -name: kcl -x0: - age: 1 - name: kcl -x1: - age: 101 - name: kcl - ----- -x0.name: kcl -x1.age: 101 ----- -person: &{Name:kcl Age:101} -``` - -## REST-API - -KCL 提供的 C-API 并没有 REST-API,REST-API 是通过 Protobuf 定义,最终由上层的 Go-SDK 提供实现。 - -### 启动 REST 服务 - -通过以下方式可以启动 RestAPI 服务: - -```shell -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -然后可以通过 POST 协议请求服务: - -```shell -$ curl -X POST http://127.0.0.1:2021/api:protorpc/BuiltinService.Ping --data '{}' -{ - "error": "", - "result": {} -} -``` - -其中 POST 请求和返回的 JSON 数据和 Protobuf 定义的结构保持一致。 - -### `BuiltinService` 服务 - -其中 `/api:protorpc/BuiltinService.Ping` 路径表示 `BuiltinService` 服务的 `Ping` 方法。 - -完整的 `BuiltinService` 由 Protobuf 定义: - -```protobuf -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} -``` - -其中 `Ping` 方法可以验证服务是否正常,`ListMethod` 方法可以查询提供的全部服务和函数列表。 - -### `KclvmService` 服务 - -`KclvmService` 服务是和 KCL 功能相关的服务。用法和 `BuiltinService` 服务一样。 - -比如有以下的 `Person` 结构定义: - -```python -schema Person: - key: str - - check: - "value" in key # 'key' is required and 'key' must contain "value" -``` - -然后希望通过 `Person` 来校验以下的 JSON 数据: - -```json -{ "key": "value" } -``` - -可以通过 `KclvmService` 服务的 `ValidateCode` 方法完成。参考 `ValidateCode` 方法的 `ValidateCode_Args` 参数结构: - -```protobuf -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} -``` - -根据 `ValidateCode_Args` 参数结构构造 POST 请求需要的 JSON 数据,其中包含 `Person` 定义和要校验的 JSON 数据: - -```json -{ - "code": "\nschema Person:\n key: str\n\n check:\n \"value\" in key # 'key' is required and 'key' must contain \"value\"\n", - "data": "{\"key\": \"value\"}" -} -``` - -将该 JSON 数据保存到 `vet-hello.json` 文件,然后通过以下命令进行校验: - -```shell -$ curl -X POST \ - http://127.0.0.1:2021/api:protorpc/KclvmService.ValidateCode \ - -H "accept: application/json" \ - --data @./vet-hello.json -{ - "error": "", - "result": { - "success": true - } -} -``` - -说明校验成功。 - -## Python 语言 - -使用 Python SDK 要求您本地具备高于 3.7.3 的 Python 版本和 pip 包管理工具,可以通过如下命令进行安装并获得帮助信息 - -```bash -python3 -m pip install kclvm --user && python3 -m kclvm --help -``` - -### 命令行工具 - -编写名为 `main.k` 的 KCL 文件: - -```python -name = "kcl" -age = 1 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {} -x1 = Person { - age = 101 -} -``` - -执行如下命令并获得输出: - -```shell -$ python3 -m kclvm hello.k -name: kcl -age: 1 -x0: - name: kcl - age: 1 -x1: - name: kcl - age: 101 -``` - -### API - -此外,我们还可以通过 Python 代码实现对 KCL 文件的执行 - -编写名为 `main.py` 的 python 文件: - -```python -import kclvm.program.exec as kclvm_exec -import kclvm.vm.planner as planner - -print(planner.plan(kclvm_exec.Run(["hello.k"]).filter_by_path_selector())) -``` - -执行如下命令并获得输出: - -```shell -$ python3 main.py -name: kcl -age: 1 -x0: - name: kcl - age: 1 -x1: - name: kcl - age: 101 -``` - -可以看出通过命令行工具和 API 可以获得同样的输出。 - -目前 KCL Python SDK 还处于早期预览版本,后续 KCL 团队会持续更新并提供更丰富的功能,更多信息请参阅:[https://github.com/kcl-lang/kcl-py](https://github.com/kcl-lang/kcl-py) - -## 其它语言 - -用户也可以基于 C-API 和 RestAPI 包装其它语言的 SDK。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/python-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/python-api.md deleted file mode 100644 index ad3ad867..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/python-api.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Python API - -目前 KCL Python SDK 还处于早期预览版本,后续 KCL 团队会持续更新并提供更丰富的功能,更多信息请参阅:[https://github.com/kcl-lang/kcl-py](https://github.com/kcl-lang/kcl-py)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/rest-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/rest-api.md deleted file mode 100644 index 74a9bf4c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/xlang-api/rest-api.md +++ /dev/null @@ -1,455 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Rest API - -## 1. 启动 REST 服务 - -通过以下方式可以启动 RestAPI 服务: - -```shell -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -或者 - -```shell -go install kcl-lang.io/kcl-go/cmds/kcl-go@main -kcl-go rest-server -``` - -然后可以通过 POST 协议请求服务: - -```shell -curl -X POST http://127.0.0.1:2021/api:protorpc/BuiltinService.Ping --data '{}' -``` - -期望输出为 - -```shell -{ - "error": "", - "result": {} -} -``` - -其中 POST 请求和返回的 JSON 数据和 Protobuf 定义的结构保持一致。 - -## 2. `BuiltinService` 服务 - -其中 `/api:protorpc/BuiltinService.Ping` 路径表示 `BuiltinService` 服务的 `Ping` 方法。 - -完整的 `BuiltinService` 由 Protobuf 定义: - -```protobuf -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} -``` - -其中 `Ping` 方法可以验证服务是否正常,`ListMethod` 方法可以查询提供的全部服务和函数列表。 - -## 3. `KclvmService` 服务 - -`KclvmService` 服务是和 KCL 功能相关的服务。用法和 `BuiltinService` 服务一样。 - -比如有以下的 `Person` 结构定义: - -```python -schema Person: - key: str - - check: - "value" in key # 'key' is required and 'key' must contain "value" -``` - -然后希望通过 `Person` 来校验以下的 JSON 数据: - -```json -{ "key": "value" } -``` - -可以通过 `KclvmService` 服务的 `ValidateCode` 方法完成。参考 `ValidateCode` 方法的 `ValidateCode_Args` 参数结构: - -```protobuf -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} -``` - -根据 `ValidateCode_Args` 参数结构构造 POST 请求需要的 JSON 数据,其中包含 `Person` 定义和要校验的 JSON 数据: - -```json -{ - "code": "\nschema Person:\n key: str\n\n check:\n \"value\" in key # 'key' is required and 'key' must contain \"value\"\n", - "data": "{\"key\": \"value\"}" -} -``` - -将该 JSON 数据保存到 `vet-hello.json` 文件,然后通过以下命令进行校验: - -```shell -curl -X POST \ - http://127.0.0.1:2021/api:protorpc/KclvmService.ValidateCode \ - -H "accept: application/json" \ - --data @./vet-hello.json -``` - -如果看到输出 - -```json -{ - "error": "", - "result": { - "success": true - } -} -``` - -说明校验成功。 - -## 4. 完整的 Protobuf 服务定义 - -跨语言的 API 通过 Protobuf 定义([https://github.com/kcl-lang/kcl-go/blob/main/pkg/spec/gpyrpc/gpyrpc.proto](https://github.com/kcl-lang/kcl-go/blob/main/pkg/spec/gpyrpc/gpyrpc.proto)): - -```protobuf -// Copyright 2023 The KCL Authors. All rights reserved. -// -// This file defines the request parameters and return structure of the KCL RPC server. -// We can use the following command to start a KCL RPC server. - -syntax = "proto3"; - -package gpyrpc; - -import "google/protobuf/any.proto"; -import "google/protobuf/descriptor.proto"; - -// ---------------------------------------------------------------------------- - -// kcl main.k -D name=value -message CmdArgSpec { - string name = 1; - string value = 2; -} - -// kcl main.k -O pkgpath:path.to.field=field_value -message CmdOverrideSpec { - string pkgpath = 1; - string field_path = 2; - string field_value = 3; - string action = 4; -} - -// ---------------------------------------------------------------------------- -// gpyrpc request/response/error types -// ---------------------------------------------------------------------------- - -message RestResponse { - google.protobuf.Any result = 1; - string error = 2; - KclError kcl_err = 3; -} - -message KclError { - string ewcode = 1; // See kclvm/kcl/error/kcl_err_msg.py - string name = 2; - string msg = 3; - repeated KclErrorInfo error_infos = 4; -} - -message KclErrorInfo { - string err_level = 1; - string arg_msg = 2; - string filename = 3; - string src_code = 4; - string line_no = 5; - string col_no = 6; -} - -// ---------------------------------------------------------------------------- -// service requset/response -// ---------------------------------------------------------------------------- - -// gpyrpc.BuiltinService -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -// gpyrpc.KclvmService -service KclvmService { - rpc Ping(Ping_Args) returns(Ping_Result); - - rpc ExecProgram(ExecProgram_Args) returns(ExecProgram_Result); - - rpc FormatCode(FormatCode_Args) returns(FormatCode_Result); - rpc FormatPath(FormatPath_Args) returns(FormatPath_Result); - rpc LintPath(LintPath_Args) returns(LintPath_Result); - rpc OverrideFile(OverrideFile_Args) returns (OverrideFile_Result); - - rpc GetSchemaType(GetSchemaType_Args) returns(GetSchemaType_Result); - rpc GetSchemaTypeMapping(GetSchemaTypeMapping_Args) returns(GetSchemaTypeMapping_Result); - rpc ValidateCode(ValidateCode_Args) returns(ValidateCode_Result); - - rpc ListDepFiles(ListDepFiles_Args) returns(ListDepFiles_Result); - rpc LoadSettingsFiles(LoadSettingsFiles_Args) returns(LoadSettingsFiles_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} - -message ParseFile_AST_Args { - string filename = 1; - string source_code = 2; -} -message ParseFile_AST_Result { - string ast_json = 1; // json value - KclError kcl_err = 2; -} - -message ParseProgram_AST_Args { - repeated string k_filename_list = 1; -} -message ParseProgram_AST_Result { - string ast_json = 1; // json value - KclError kcl_err = 2; -} - -message ExecProgram_Args { - string work_dir = 1; - - repeated string k_filename_list = 2; - repeated string k_code_list = 3; - - repeated CmdArgSpec args = 4; - repeated CmdOverrideSpec overrides = 5; - - bool disable_yaml_result = 6; - - bool print_override_ast = 7; - - // -r --strict-range-check - bool strict_range_check = 8; - - // -n --disable-none - bool disable_none = 9; - // -v --verbose - int32 verbose = 10; - - // -d --debug - int32 debug = 11; - - // yaml/json: sort keys - bool sort_keys = 12; - // include schema type path in JSON/YAML result - bool include_schema_type_path = 13; -} -message ExecProgram_Result { - string json_result = 1; - string yaml_result = 2; - - string escaped_time = 101; -} - -message ResetPlugin_Args { - string plugin_root = 1; -} -message ResetPlugin_Result { - // empty -} - -message FormatCode_Args { - string source = 1; -} - -message FormatCode_Result { - bytes formatted = 1; -} - -message FormatPath_Args { - string path = 1; -} - -message FormatPath_Result { - repeated string changed_paths = 1; -} - -message LintPath_Args { - repeated string paths = 1; -} - -message LintPath_Result { - repeated string results = 1; -} - -message OverrideFile_Args { - string file = 1; - repeated string specs = 2; - repeated string import_paths = 3; -} - -message OverrideFile_Result { - bool result = 1; -} - -message EvalCode_Args { - string code = 1; -} -message EvalCode_Result { - string json_result = 2; -} - -message ResolveCode_Args { - string code = 1; -} - -message ResolveCode_Result { - bool success = 1; -} - -message GetSchemaType_Args { - string file = 1; - string code = 2; - string schema_name = 3; -} -message GetSchemaType_Result { - repeated KclType schema_type_list = 1; -} - -message GetSchemaTypeMapping_Args { - string file = 1; - string code = 2; - string schema_name = 3; -} -message GetSchemaTypeMapping_Result { - map schema_type_mapping = 1; -} - -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} - -message ValidateCode_Result { - bool success = 1; - string err_message = 2; -} - -message Position { - int64 line = 1; - int64 column = 2; - string filename = 3; -} - -message ListDepFiles_Args { - string work_dir = 1; - bool use_abs_path = 2; - bool include_all = 3; - bool use_fast_parser = 4; -} - -message ListDepFiles_Result { - string pkgroot = 1; - string pkgpath = 2; - repeated string files = 3; -} - -// --------------------------------------------------------------------------------- -// LoadSettingsFiles API -// Input work dir and setting files and return the merged kcl singleton config. -// --------------------------------------------------------------------------------- - -message LoadSettingsFiles_Args { - string work_dir = 1; - repeated string files = 2; -} - -message LoadSettingsFiles_Result { - CliConfig kcl_cli_configs = 1; - repeated KeyValuePair kcl_options = 2; -} - -message CliConfig { - repeated string files = 1; - string output = 2; - repeated string overrides = 3; - repeated string path_selector = 4; - bool strict_range_check = 5; - bool disable_none = 6; - int64 verbose = 7; - bool debug = 8; -} - -message KeyValuePair { - string key = 1; - string value = 2; -} - -// ---------------------------------------------------------------------------- -// JSON Schema Lit -// ---------------------------------------------------------------------------- - -message KclType { - string type = 1; // schema, dict, list, str, int, float, bool, any, union, number_multiplier - repeated KclType union_types = 2 ; // union types - string default = 3; // default value - - string schema_name = 4; // schema name - string schema_doc = 5; // schema doc - map properties = 6; // schema properties - repeated string required = 7; // required schema properties, [property_name1, property_name2] - - KclType key = 8; // dict key type - KclType item = 9; // dict/list item type - - int32 line = 10; - - repeated Decorator decorators = 11; // schema decorators -} - -message Decorator { - string name = 1; - repeated string arguments = 2; - map keywords = 3; -} - -// ---------------------------------------------------------------------------- -// END -// ---------------------------------------------------------------------------- -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/Ide/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/Ide/_category_.json deleted file mode 100644 index fcdc7f10..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/Ide/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "集成开发环境", - "position": 2 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/_category_.json deleted file mode 100644 index 5170334a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "工具", - "position": 3 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/_category_.json deleted file mode 100644 index 8fac9ad8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "命令行工具", - "position": 1 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/index.md deleted file mode 100644 index f754b5ca..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# 命令行工具 - -KCL 提供了 IDE 插件、丰富的语言工具和 OpenAPI 工具。通过这些工具,可以提供一整套解决方案,包括配置语言、模型界面、自动化工具和最佳实践。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/_category_.json deleted file mode 100644 index b22440b7..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KCL 语言工具", - "position": 2 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/docgen.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/docgen.md deleted file mode 100644 index 37b660ed..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/docgen.md +++ /dev/null @@ -1,313 +0,0 @@ ---- -sidebar_position: 5 ---- - -# 文档生成工具 - -KCL 命令行工具支持从 KCL 源码中一键提取模型文档,并支持丰富的输出格式:JSON,YAML 和 Markdown 等。本文介绍 KCL 语言的文档规范,举例说明如何使用 KCL 文档生成工具提取文档,并展示新增本地化语言文档的流程。 - -## 1. KCL 语言的文档规范 - -KCL文件的文档主要包含如下两个部分: - -- 当前 KCL Moudle 的文档:对当前 KCL 文件的说明 -- KCL 文件内包含的所有 Schema 的文档:对当前 Schema 的说明,其中包含 Schema 描述、Schema 各属性的描述、Examples 三部分,具体格式如下: - -1. Schema 描述 - -```python -"""这是Schema一个简短的描述信息 -""" -``` - -2. Schema 各属性的描述:包含属性描述、属性类型、默认值、是否可选 - -```python -""" -Attributes ----------- -x : type, default is a, optional. - Description of parameter `x`. -y : type, default is b, required. - Description of parameter `y`. -""" -``` - -其中,使用 `----------` 表示 `Attributes` 为一个标题(`-` 符号长度与标题长度保持一致),属性名称与属性类型用冒号 `:` 分隔,属性的说明另起一行并增加缩进进行书写。属性的默认值说明跟在属性类型之后使用逗号 `,` 分隔,书写为 `default is {默认值}` 形式,此外需要说明属性是否为可选/必选,对于可选属性在默认值之后书写 `optional`,对于必选属性在默认值之后书写 `required`。 - -3. Examples - -```python -""" -Examples --------- -val = Schema { - name = "Alice" - age = 18 -} -""" -``` - -此外,KCL 文档字符串语法应采用 [re-structured text (reST)](https://docutils.sourceforge.io/rst.html) 语法子集,并使用 [Sphinx](https://www.sphinx-doc.org/en/master/) 渲染呈现。 - -## 2. 从 KCL 源码生成文档 - -使用 kcl-doc generate 命令,从用户指定的文件或目录中提取文档,并输出到指定目录。 - -1. 参数说明 - -``` -usage: kcl-doc generate [-h] [--format YAML] [-o OUTPUT] [--r] - [--i18n-locale LOCALE] [--repo-url REPO_URL] - [files [files ...]] - -positional arguments: - files KCL file paths. If there's more than one files to - generate, separate them by space - -optional arguments: - -h, --help show this help message and exit - --format YAML Doc file format, support YAML, JSON and MARKDOWN. - Defaults to MARKDOWN - -o OUTPUT, --output-path OUTPUT - Specify the output directory. Defaults to ./kcl_doc - --r, -R, --recursive Search directory recursively - --i18n-locale LOCALE I18n locale, e.g.: zh, zh_cn, en, en_AS. Defaults to - en - --repo-url REPO_URL The source code repository url. It will be displayed in - the generated doc to link to the source code. -``` - -2. 从指定的一个或多个文件中提取文档,并输出到指定目录 - -```text -kcl-doc generate your_config.k your_another_config.k -o your_docs_output_dir -``` - -3. 从指定目录内,递归地查找 KCL 源码文件,并提取文档 - -```text -kcl-doc generate your_config_dir -r -o your_docs_output_dir -``` - -4. 在生成文档时,指定源码仓库地址。一经指定,生成的文档中将包含指向源码文件的链接 - -```text -kcl-doc generate your_config.k -o your_docs_output_dir --repo-url https://url/to/source_code -``` - -## 3. 新增本地化语言的文档 - -如前所示,默认情况下,文档生成工具提取的文档以源码 docstring 的内容为准,因而文档的语言随 docstring 编写语言而定。如果需要为源文件新增本地化语言的文档,则可以遵循按如下步骤: - -1. 初始化 i18n 配置文件。该步骤基于指定的 KCL 源码文件,生成相应的 i18n 配置文件,文件格式可选 JSON/YAML,默认为 YAML. 输出的配置文件名称将以指定的目标本地化方言结尾 - -```text -kcl-doc init-i18n your_config.k --format JSON --i18n-locale your_target_locale -``` - -2. 手动修改上述生成的 i18n 配置文件,使用目标语言修改配置中的 doc 字段 - -3. 基于修改后的 i18n 配置,生成本地化语言的文档。工具将查找指定目标语言的 i18n 配置文件,并转化为最终的文档 - -```text -kcl-doc generate your_config_dir --i18n-locale your_target_locale --format Markdown -``` - -接下来,通过一个小例子演示新增本地化语言文档的过程。 - -3.1 准备 KCL 源码文件,例如 server.k: - - ```python - schema Server: - """Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - - Attributes - ---------- - workloadType : str, default is "Deployment", required - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - name : str, required - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - labels : {str:str}, optional - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - - Examples - ---------------------- - myCustomApp = AppConfiguration { - name = "componentName" - } - """ - - workloadType: str = "Deployment" - name: str - labels?: {str: str} - ``` - -3.2 从 server.k 得到初始化的 i18n 配置文件,例如希望为其增加中文文档,指定生成的配置文件格式为 YAML - - ```text - kcl-doc init-i18n server.k --format YAML --i18n-locale zh_cn - ``` - - 该命令将在当前目录下创建 kcl_doc 目录,并生成 i18n 配置文件 kcl_doc/i18n_server_zh_cn.yaml,其内容如下: - - ```yaml - name: server - relative_path: ./server.k - schemas: - - name: Server - doc: | - Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - attributes: - - name: workloadType - doc: | - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - default_value: '"Deployment"' - is_optional: false - - name: name - doc: | - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: false - default_value: '' - - name: labels - doc: | - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - type: - type_str: '{str: str}' - type_category: DICT - dict_type: - key_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - value_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: true - default_value: '' - examples: | - myCustomApp = AppConfiguration { - name = "componentName" - } - doc: '' - source_code_url: '' - ``` - -3.3 修改初始化得到的 i18n 配置,将其中的 doc 字段修改为中文的描述,修改后的配置如下: - - ```yaml - name: server - relative_path: ./server.k - schemas: - - name: Server - doc: | - Server 模型定义了采用 Kubernetes 最佳实践的持续运行的服务的通用配置接口 - attributes: - - name: workloadType - doc: | - workloadType 属性定义了服务的类型,是服务级别的属性。合法的取值有:Deployment, CafeDeployment. - 另请查看:k8s/core/v1/workload_metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - default_value: '"Deployment"' - is_optional: false - - name: name - doc: | - name 为服务的名称,是服务级别的属性。 - 另请查看:k8s/core/v1/metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: false - default_value: '' - - name: labels - doc: | - labels 为服务的标签,是服务级别的属性。 - 另请查看:k8s/core/v1/metadata.k. - type: - type_str: '{str: str}' - type_category: DICT - dict_type: - key_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - value_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: true - default_value: '' - examples: | - myCustomApp = AppConfiguration { - name = "componentName" - } - doc: '' - source_code_url: '' - ``` - -3.4 基于修改后的 i18n 配置,生成本地化语言的文档,执行如下命令,将输出中文的文档 kcl_doc/doc_server_zh_cn.md,命令及生成的文档内容如下: - - ```text - kcl-doc generate server.k --i18n-locale zh_cn --format Markdown - ``` - - ~~~markdown - # server - ## Schema Server - Server 模型定义了采用 Kubernetes 最佳实践的持续运行的服务的通用配置接口 - - ### Attributes - |Name and Description|Type|Default Value|Required| - |--------------------|----|-------------|--------| - |**workloadType**
workloadType 属性定义了服务的类型,是服务级别的属性。合法的取值有:Deployment, CafeDeployment.
另请查看:k8s/core/v1/workload_metadata.k.|str|"Deployment"|**required**| - |**name**
name 为服务的名称,是服务级别的属性。
另请查看:k8s/core/v1/metadata.k.|str|Undefined|**required**| - |**labels**
labels 为服务的标签,是服务级别的属性。
另请查看:k8s/core/v1/metadata.k.|{str: str}|Undefined|optional| - ### Examples - ``` - myCustomApp = AppConfiguration { - name = "componentName" - } - ``` - - - - ~~~ - -## 4. 附录 - -### 1. 常见的 reST 概念 - -对于 reST 格式的文档,段落和缩进很重要,新段落用空白行标记,缩进即为表示输出中的缩进。可以使用如下方式表示字体样式: - -- \*斜体\* -- \*\*粗体\*\* -- \`\`等宽字体\`\` - -参考 [reST 文档](https://docutils.sourceforge.io/rst.html)获得更多帮助。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/fmt.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/fmt.md deleted file mode 100644 index 11199215..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/fmt.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -sidebar_position: 2 ---- - -# 格式化代码 - -KCL 支持通过内置的命令行工具一键格式化多个 KCL 文件文档。本文展示 KCL 编码风格和 KCL 格式化工具的使用方式。 - -## KCL 编码风格 - -KCL 格式化对文件的修改样式具体见 KCL 编码风格:[Style Guide for KCL Code](/docs/reference/lang/spec/codestyle) - -## 使用方式 - -- 单文件格式化 - -```text -kcl-fmt your_config.k -``` - -- 文件夹内多文件格式化 - -```text -kcl-fmt your_config_path -R -``` - -- 命令行参数 - - `-R|--recursive` 设置是否递归遍历子文件夹 - - `-w|--fmt-output` 设置是否输出到标准输出流,不加 `-w` 表示原地格式化 KCL 文件 - -## 格式化文件效果展示 - -- 格式化前 - -```py -import math -mixin DeploymentMixin: - service:str ="my-service" -schema DeploymentBase: - name: str - image : str -schema Deployment[replicas] ( DeploymentBase ) : - mixin[DeploymentMixin] - replicas : int = replicas - command: [str ] - labels: {str: str} -deploy = Deployment(replicas = 3){} -``` - -- 格式化后 - -```py -import math - -mixin DeploymentMixin: - service: str = "my-service" - -schema DeploymentBase: - name: str - image: str - -schema Deployment[replicas](DeploymentBase): - mixin [DeploymentMixin] - replicas: int = replicas - command: [str] - labels: {str:str} - -deploy = Deployment(replicas=3) {} - -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/index.md deleted file mode 100644 index 51f69ee6..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# KCL 语言工具 - -KCL 不仅提供了 kcl 命令编译和执行配置程序,还提供了 fmt、lint、test、vet、docgen 等配套的辅助工具。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/lint.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/lint.md deleted file mode 100644 index 7a66d3b3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/lint.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Lint 检查代码风格 - -KCL 支持通过内置的命令行工具对 KCL 代码进行检查,并支持多种输出格式。本文档展示 KCL Lint 工具的使用方式。 - -## 示例 - -### 工程结构 - -```text -. -└── Test - └── kcl.mod - └── a.k - └── b.k - └── dir - └── c.k - └── test.k -``` - -`a.k`,`b.k`,`c.k`,`test.k` 为测试的 kcl 文件。 - -命令: - -```shell -kcl-lint your_config.k -``` - -或 - -```shell -kcl-lint your_config_path -``` - -### CLI 参数 - -```shell -USAGE: - kcl-lint [OPTIONS] [--] [input]... - -ARGS: - ... Sets the input file to use - -OPTIONS: - --emit_warning Emit warning message - -h, --help Print help information - -v, --verbose Print test information verbosely - -Y, --setting ... Sets the input file to use -``` - -- input: 需要检查的单个 `.k` 文件路径或路径目录下的所有 `.k` 文件,支持绝对路径或当前目录的相对路径 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/overview.md deleted file mode 100644 index 4fa606dc..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/overview.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 概览 - -KCL 工具链是 KCL 语言的工具集合,旨在提升 KCL 的批量迁移、编写、编译和测试的效率。 - -| 类别 | 工具名称 | 说明 | -| ---------- | ---------------------- | --------------------------------------------------------- | -| 主工具集 | **kcl** | kcl 命令行工具提供对基于 KCL 语言的配置编写、编译和运行。 | -| | kcl-test | 即将提供 | -| | kcl-fmt | kcl-fmt 工具提供对 KCL 代码的格式化 | -| | kcl-lint | kcl-lint 工具提供对 KCL 代码的 lint 检查和自动修复 | -| | kcl-doc | kcl-doc 工具提供对 KCL 代码的文档解析和生成 | -| | kcl-vet | 使用 KCL 代码校验诸如 JSON 和 YAML 的数据格式 | -| ide 插件集 | IntelliJ IDEA KCL 插件 | 提供 IntelliJ IDEA 平台的 KCL 编写、编译辅助 | -| | VS Code KCL 插件 | 提供 VS Code 平台的 KCL 编写、编译辅助 | - -## KCL 工具 - -### 命令行参数 - -```shell -USAGE: - kcl [OPTIONS] [--] [input]... - -Arguments: - [input]... Specify the input files to run - -Options: - -o, --output - Specify the YAML output file path - -Y, --setting ... - Specify the input setting file - -v, --verbose... - Print test information verbosely - -n, --disable_none - Disable dumping None values - -r, --strict_range_check - Do perform strict numeric range checks - -d, --debug - Run in debug mode (for developers only) - -k, --sort_keys - Sort result keys - -D, --argument ... - Specify the top-level argument - -S, --path_selector ... - Specify the path selector - -O, --overrides ... - Specify the configuration override path and value - --target - Specify the target type - -E, --external ... - Mapping of package name and path where the package is located - -h, --help - Print help -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/test.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/test.md deleted file mode 100644 index f8707ff9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/test.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 5 ---- - -# 测试工具 - -即将到来! diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/vet.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/vet.md deleted file mode 100644 index 2c70ce91..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/kcl/vet.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Validation 校验代码 - -## 简介 - -KCL 支持通过内置的 `kcl-vet` 命令行工具提供了基本的配置数据校验能力,可以编写 KCL schema 对输入的 JSON/YAML 格式文件进行类型以及数值的校验。 - -## 使用方式 - -假设有 data.json 文件,代码如下: - -```json -{ - "name": "Alice", - "age": 18, - "message": "This is Alice", - "data": { - "id": 1, - "value": "value1" - }, - "labels": { - "key": "value" - }, - "hc": [1, 2, 3] -} -``` - -构造 schema.k 校验文件,内容如下: - -```py -schema User: - name: str - age: int - message?: str - data: Data - labels: {str:} - hc: [int] - - check: - age > 10 - -schema Data: - id: int - value: str -``` - -在目录下执行如下命令 - -```shell -$ kcl-vet data.json schema.k -``` - -## 指定校验的 schema - -当校验的 KCL 文件中存在多个 schema 定义时,kcl-vet 工具会默认取第一个 schema 定义进行校验,如果需要指定校验的 schema,可以使用 `-d|--schema` 参数 - -```shell -$ kcl-vet data.json schema.k -d User -``` - -## 命令行参数 - -```shell -$ kcl-vet -h -USAGE: - kcl-vet [OPTIONS] [ARGS] - -ARGS: - Validation data file - KCL file - -OPTIONS: - -d, --schema - Iterate through subdirectories recursively - - --format - Validation data file format, support YAML and JSON, default is JSON - - -h, --help - Print help information - - -n, --attribute_name - The attribute name for the data loading -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/openapi/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/openapi/_category_.json deleted file mode 100644 index 5df621d8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/openapi/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "OpenAPI 工具", - "position": 3 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/openapi/crd-to-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/openapi/crd-to-kcl.md deleted file mode 100644 index 5b6f070c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/openapi/crd-to-kcl.md +++ /dev/null @@ -1,118 +0,0 @@ -# CRD to KCL - -命令 - -```shell -kcl-openapi generate model --crd -f ${your_CRD.yaml} -t ${the_kcl_files_output_dir} --skip-validation -``` - -# 示例 - -- 输入文件:test_crontab_CRD.yaml: - -```yaml -# Deprecated in v1.16 in favor of apiextensions.k8s.io/v1 -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - # name must match the spec fields below, and be in the form: . - name: crontabs.stable.example.com -spec: - # group name to use for REST API: /apis// - group: stable.example.com - # list of versions supported by this CustomResourceDefinition - versions: - - name: v1 - # Each version can be enabled/disabled by Served flag. - served: true - # One and only one version must be marked as the storage version. - storage: true - # either Namespaced or Cluster - scope: Namespaced - names: - # plural name to be used in the URL: /apis/// - plural: crontabs - # singular name to be used as an alias on the CLI and for display - singular: crontab - # kind is normally the CamelCased singular type. Your resource manifests use this. - kind: CronTab - # shortNames allow shorter string to match your resource on the CLI - shortNames: - - ct - preserveUnknownFields: false - validation: - openAPIV3Schema: - type: object - properties: - spec: - type: object - properties: - cronSpec: - type: string - image: - type: string - replicas: - type: integer -``` - -- 命令 - -```shell -kcl-openapi generate model -f test_crontab_CRD.yaml -t ~/ --skip-validation --crd -``` - -- 输出文件: ~/models/stable_example_com_v1_cron_tab.k - -```python -""" -This file was generated by the KCL auto-gen tool. DO NOT EDIT. -Editing this file might prove futile when you re-run the KCL auto-gen generate command. -""" -import kusion_kubernetes.apimachinery.apis - - -schema CronTab: - """stable example com v1 cron tab - - Attributes - ---------- - apiVersion : str, default is "stable.example.com/v1", required - APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - kind : str, default is "CronTab", required - Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - metadata : apis.ObjectMeta, default is Undefined, optional - metadata - spec : StableExampleComV1CronTabSpec, default is Undefined, optional - spec - """ - - - apiVersion: "stable.example.com/v1" = "stable.example.com/v1" - - kind: "CronTab" = "CronTab" - - metadata?: apis.ObjectMeta - - spec?: StableExampleComV1CronTabSpec - - -schema StableExampleComV1CronTabSpec: - """stable example com v1 cron tab spec - - Attributes - ---------- - cronSpec : str, default is Undefined, optional - cron spec - image : str, default is Undefined, optional - image - replicas : int, default is Undefined, optional - replicas - """ - - - cronSpec?: str - - image?: str - - replicas?: int -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/openapi/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/openapi/index.md deleted file mode 100644 index 0654db2a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/openapi/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# OpenAPI Tools - -kcl-openapi 工具支持将通过 OpenAPI 规范描述的模型转换为 KCL 配置策略语言,除了能直接转换 OpenAPI 描述文件之外,还可以从 Kubernetes CRD 中提取并转换为 KCL schema. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/openapi/openapi-to-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/openapi/openapi-to-kcl.md deleted file mode 100644 index 6d9f8e54..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/openapi/openapi-to-kcl.md +++ /dev/null @@ -1,64 +0,0 @@ -# OpenAPI to KCL - -命令 - -```shell -kcl-openapi generate model -f ${your_open_api_spec.yaml} -t ${the_kcl_files_output_dir} -``` - -示例: - -- 输入文件:test_open_api_spec.yaml: - -```yaml -definitions: - v1.TestInt: - type: object - properties: - name: - type: string - format: int-or-string - required: - - name - x-kcl-type: - import: - package: v1.test_int - alias: test_int - type: TestInt -swagger: "2.0" -info: - title: KCL - version: v0.0.2 -paths: {} -``` - -- 命令: - -```shell -kcl-openapi generate model -f test_open_api_spec.yaml -t ~/ -``` - -- 输出:~/models/v1/test_int.k - -```python -""" -This is the test_int module in v1 package. -This file was generated by the KCL auto-gen tool. DO NOT EDIT. -Editing this file might prove futile when you re-run the KCL auto-gen generate command. -""" - - -schema TestInt: - """v1 test int - - Attributes - ---------- - name : int | str, default is Undefined, required - name - """ - - - name: int | str - - -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/openapi/quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/openapi/quick-start.md deleted file mode 100644 index 3d6a125d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/openapi/quick-start.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 快速开始 - -## 1. 安装 KCLOpenAPI 工具 - -目前有多种安装方式可选: - -- [通过 go install 安装](#11-通过-go-install-安装) -- [通过 curl|sh 安装(仅限 MacOS & Linux)](#12-通过-curlsh-安装(仅限-MacOS--Linux)) -- [下载发布包](#13-下载发布包) - -## 1.1 通过 go install 安装 - -```shell -go install kcl-lang.io/kcl-openapi@latest -``` - -## 1.2 通过 curl|sh 安装(仅限 MacOS & Linux) - -```shell -curl -fsSL https://kcl-lang.io/script/install-kcl-openapi.sh | /bin/bash -``` - -## 1.3 下载发布包 - -```shell -# 1. 下载二进制程序 -# https://github.com/kcl-lang/kcl-openapi/releases - -# 2. 解压发布包,并将命令添加至 PATH -export PATH=":$PATH" -``` - -## 1.4 验证安装结果 - -```shell -➜ kcl-openapi -v -kcl-openapi 0.5.0 -``` - -## 2. 生成 KCL 文件 - -- [将 OpenAPI 描述文件转换为 KCL](../openapi/openapi-to-kcl.md) -- [将 Kubernetes CRD 转换为 KCL](../openapi/crd-to-kcl.md) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/openapi/spec.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/openapi/spec.md deleted file mode 100644 index aee9fc92..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/openapi/spec.md +++ /dev/null @@ -1,424 +0,0 @@ -# KCL OpenAPI 规范 - -[OpenAPI](https://www.openapis.org/) 允许 API 提供方规范地描述 API 操作和模型,并基于它生成自动化工具和特定语言的客户端。 - -## KCL OpenAPI 文件结构 - -依据 OpenAPI 3.0 规范,OpenAPI 文件中应至少包含 openapi、components、 info、paths 四种根节点对象,KCL OpenAPI 聚焦于其中模型定义的部分,即 OpenAPI 文件中的 `definitions`,而描述操作的 Restful API 部分(即 OpenAPI 文件中的 `paths`)则不属于 KCL OpenAPI 定义的范畴。 -​ - -注:除以上列出的节点外,OpenAPI 官方规范还支持 servers、security、tags、externalDocs 四种可选的根节点,但都不是 KCL OpenAPI 所关心的,因此用户无需填写这部分内容,即使填写了也不会产生任何影响。 -​ - -| OpenAPI 顶层对象 | 类型 | 含义 | KCL OpenAPI 工具支持情况 | -| ---------------- | ----------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | -| swagger | string | openapi 版本信息 | 必填项,目前支持 openapi 2.0,即合法取值为 "2.0" | -| definitions | Definition Object | 模型定义 | 必填项 | -| info | Info Object | 当前 API 文件的元数据信息,例如标题、描述信息、版本、开源协议等 | 必填项,定义当前 OpenAPI 文件的基本信息,不会输出到 KCL 代码,但可用于 Swagger-UI 工具可视化展示 | - -为方便初学者快速理解,下面给出一个典型的 KCL OpenAPI 文件(截取自 swagger example [Petstore](https://petstore.swagger.io/))应包含的节点图示。KCL OpenAPI 工具重点关注其中的 definitions 节点,可以看到文件中定义了两个模型(Pet 和 Category),并且 Pet 模型中包含三个属性(name、id、category) - -## KCL schema - -KCL 中使用 schema 结构来定义配置数据的“类型”,关于 KCL schema,可参考文档:传送门 -在 definitions 节点下新增 definition 元素,即可定义 KCL schema. -示例: -下例在 KCL 代码中定义了 Pet、Category 两个 schema,同样地,其对应的 OpenAPI 也在 definitions 节点下包含这两个模型的描述。 - -```python -# KCL schema: -schema Pet: - name: str - id?: int - category?: Category - -schema Category: - name?: str - -# 对应的 OpenAPI 描述 -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "id": { - "type": "integer", - "format": "int64" - }, - "category": { - "$ref": "#/definitions/Category" - } - }, - "required": [ - "name" - ] - }, - "Category": { - "type": "object", - "properties": { - "name": { - "type": "string" - } - } - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -``` - -### schema 名称 - -在 KCL 中,schema 名称紧跟在 schema 关键字后声明,在 OpenAPI 中,模型的名称通过 definition 元素的 key 来定义。 - -### schema 类型 - -KCL schema 在 OpenAPI 中的类型为 "object". 例如上例中 "Pet" 的 "type" 值应为 "object". - -### schema 属性 - -KCL schema 中可以定义若干属性,属性的声明一般包含如下几部分: - -- 属性注解:可选,以 @ 开头,例如 @deprecated 注解表示属性被废弃 -- 属性名称:必须 -- 属性 optional 修饰符(?):可选,带问号表示当前属性为可选属性,可以不被赋值。反之,不带问号表示必填属性 -- 属性类型:必须,可以是基本数据类型,也可以是 schema 类型, 或者是前述两种类型的并集 -- 属性默认值:非必须 - -它们与 OpenAPI 规范的对应关系如下: - -| KCL schema 属性元素 | OpenAPI 元素 | -| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- | -| 属性注解 | 暂不支持,计划扩展一个 deprecate 字段用于描述 deprecated 注解 | | -| 属性名称 | properties 节点下,每个属性的 key 即为属性名称 | -| 属性 optional 修饰符(?) | 模型节点下,通过 required 字段列出该模型的所有必填属性的名称,未被列出的属性即为 optional | -| 属性类型 | 属性节点下,设置 type + format 可以标识属性的基本类型,如果是 schema 类型则用 $ref 字段表示,类型 union 则由扩展字段 x-kcl-types 来标识,此外,属性节点的 enum、pattern 也可以用于表示 KCL 类型。 | -| KCL-OpenAPI 关于类型的对照关系,详见“基本数据类型”小节 | | -| 属性默认值 | 属性节点下,设置 default 字段即可为属性设置默认值 | - -示例: -下例中 Pet 模型包含了 2 个属性:name(string 类型,必填属性,无注解,无默认值)、id(int64 类型,无注解,非必填,默认值为 -1) - -```python -# KCL schema Pet,包含两个属性 name 和 id -schema Pet: - name: str - id?: int = -1 - -# 对应的 OpenAPI 文档 -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - "id": { - "type": "integer", - "format": "int64", - "default": -1 - } - }, - "required": [ - "name" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### schema 索引签名 - -KCL schema 允许定义索引签名,用于定义属性名不固定的 dict,起到静态模板的作用。具体来说,KCL schema 索引签名包含如下几个元素: - -- 索引签名中 key 的类型:在方括号中声明,必须是基础类型 -- 索引签名中 value 的类型:在冒号后声明,可以是任意合法的 KCL 类型 -- 索引签名中的省略符:在方括号中,key 类型之前声明,使用"..."表示。如果带有该符号,表示该索引签名只用于约束未在 schema 中定义的属性;否则,表示 schema 中所有已定义和未定义属性都收到该索引签名的约束。 -- 索引签名中 key 的别名:在方括号中,紧随左方括号之后声明,使用名称 + 冒号表示,该别名可用于按名称引用索引签名 -- 索引签名的默认值:可以为索引签名设置默认值 - -在 OpenAPI 中,可以借助在模型节点的 `additionalProperties` 字段描述某些 key 为 string 的索引签名。但对于 KCL 索引签名中非 string 类型的 dict key、索引签名 key 的 check 校验,在 OpenAPI 规范没有对等的描述。它们与 OpenAPI 规范的对应关系如下: - -| KCL 索引签名元素 | OpenAPI 元素 | -| ----------------------- | ---------------------------------------------------------------------- | -| 索引签名中 key 的类型 | OpenAPI 仅支持 key 为 string 类型,无法自定义 | -| 索引签名中 value 的类型 | 模型节点的下 additionalProperties 下的 "type" 字段 | -| 索引签名中的省略符 | OpenAPI 中表示索引签名时,只能表示 KCL 中带有省略符的情况 | -| 索引签名中 key 的别名 | OpenAPI 中不支持为索引签名定义 key 别名,(预计通过扩展支持:x-alias) | -| 索引签名的默认值 | 目前不支持 | - -示例:下例中的 KCL schema Pet,包含两个预定义的属性 name 和 id,除此之外,还允许使用该 schema 的配置额外地赋值其他 key 为 string 类型,value 为 bool 类型的属性: - -```python -# KCL schema Pet,包含两个预定义的属性 name 和 id,允许额外给 key 为 string、value 为 bool 的属性赋值 -schema Pet: - name: str - id?: int - [...str]: bool - -# 对应的 OpenAPI 描述 -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - "id": { - "type": "integer", - "format": "int64", - } - }, - "additionalProperties": { - "type": "bool" - }, - "required": [ - "name" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### schema 继承关系 - -### 内联 schema - -OpenAPI 支持嵌套地定义 schema,但 KCL 目前暂不支持 schema 的内联。OpenAPI 中内联定义的 schema 将被转换为 KCL 中带名称的 schema,其名称的命名规则为:在该内联 schema 的上层 schema 名称的基础上,增加相应的后缀。在拼接后缀时,根据定义了该内联 schema 的外层 OpenAPI 元素类型,后缀内容如下: - -| OpenAPI 文档中定义内联 schema 的元素 | KCL schema 名称拼接规则 | -| ------------------------------------ | ------------------------------ | -| 某属性节点 | 增加该属性节点的名称为后缀 | -| AdditionalProperties 节点 | 增加"AdditionalProperties"后缀 | - -注:KCL 未来也可能会支持内联 schema,届时再更新这部分转换规则 -示例 1:下例中的模型 Deployment 包含有 kind、spec 两个属性,其中 deploymentSpec 属性的 schema 通过内联的方式定义: - -```python -# OpenAPI 文档 -{ - "definitions": { - "Deployment": { - "type": "object", - "properties": { - "kind": { - "type": "string", - }, - "spec": { - "type": "object", - "properties": { - "replicas": { - "type": "integer", - "format": "int64" - } - } - } - }, - "required": [ - "kind", - "spec" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -# 转换为 KCL Schema 如下: -schema Deployment: - kind: str - spec: DeploymentSpec - -schema DeploymentSpec: - replicas?: int -``` - -示例 2:下例中的模型 Person 中除固定属性 name 外,还允许包含额外的属性(additionalProperties),并且这部分额外属性的属性值的 schema 通过内联的方式定义: - -```python -# OpenAPI 文档 -{ - "definitions": { - "Person": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - }, - "required": [ - "name", - "spec" - ], - "additionalProperties": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "description": { - "type": "string" - } - }, - "required": [ - "name" - ] - }, - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -# 转换为 KCL Schema 如下: -schema Person: - name: str - [...str]: [PersonAdditionalProperties] - -schema PersonAdditionalProperties: - name: str - description?: str -``` - -## KCL 文档 - -KCL doc 规范请参考:[传送门](../kcl/docgen.md) -KCL 文档包含 module 文档、schema 文档两类,其中 schema 文档可以由 OpenAPI 转换得到。KCL schema 文档包含: - -- schema 描述信息:位于 schema 声明之后、schema 属性声明之前,是对 schema 的总体介绍 -- schema 属性信息:位于 shcema 描述信息之后,以 Attributes + 分割线分隔 -- schema 附加信息:位于 schema 属性信息之后,以 See Also + 分割线分隔 -- schema 示例信息:位于 schema 附加信息之后,以 Examples + 分割线分隔 - -它们与 OpenAPI 规范的对应关系如下: - -| KCL 文档元素 | OpenAPI 元素 | -| --------------- | ---------------------------------------------------- | -| schema 描述信息 | definitions 节点下,每个模型节点的 description 字段 | -| schema 属性信息 | properties 节点下,每个属性节点的 description 字段 | -| schema 附加信息 | definitions 节点下,每个模型节点的 externalDocs 字段 | -| schema 示例信息 | definitions 节点下,每个模型节点的 example 字段 | - -示例: -下例中为 Pet 模型定义了其 schema 描述文档 "The schema Pet definition";Pet 的两个属性 "name" 和 "id" 也分别定义了其属性文档 "The name of the pet" 及 "The id of the pet";Pet 的附加信息为 "Find more info here. [https://petstore.swagger.io/](https://petstore.swagger.io/)";此外,Pet 模型还提供了模型实例的示例写法。 - -```python -# KCL schema Pet,采用规范的 KCL 文档格式 -schema Pet: - """The schema Pet definition - - Attributes - ---------- - name : str, default is Undefined, required - The name of the pet - id : int, default is -1, optional - The age of the pet - - See Also - -------- - Find more info here. https://petstore.swagger.io/ - - Examples - -------- - pet = Pet { - name = "doggie" - id = 123 - } - """ - name: str - id?: int = -1 - -# 对应的 OpenAPI 文档 -{ - "definitions": { - "Pet": { - "description": "The schema Pet definition", - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "The name of the pet" - }, - "id": { - "type": "integer", - "format": "int64", - "default": -1, - "description": "The age of the pet" - } - }, - "required": [ - "name" - ], - "externalDocs": { - "description": "Find more info here", - "url": "https://petstore.swagger.io/" - }, - "example": { - "name": "doggie", - "id": 123 - } - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -​ - -## 基本数据类型 - -| JSON Schema type | swagger type | KCL type | comment | -| ---------------- | --------------------------- | --------------- | --------------------------------------------------------------------------- | -| boolean | boolean | bool | | -| number | number | float | | -| | number format double | **unsupported** | | -| | number format float | float | | -| integer | integer | int (32) | | -| | integer format int64 | **unsupported** | | -| | integer format int32 | int (32) | | -| string | string | str | | -| | string format byte | str | | -| | string format int-or-string | int | str | -| | string format binay | str | | -| | string format date | unsupported | As defined by full-date - [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) | -| | string format date-time | unsupported | As defined by date-time - [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) | -| | string format password | unsupported | for swagger: A hint to UIs to obscure input. | -| | datetime | datetime | | - -## Reference - -- openapi spec 2.0:[https://swagger.io/specification/v2/](https://swagger.io/specification/v2/) -- openapi spec 3.0:[https://spec.openapis.org/oas/v3.1.0](https://spec.openapis.org/oas/v3.1.0) -- openapi spec 3.0(swagger 版本):[https://swagger.io/specification/](https://swagger.io/specification/) -- openapi spec 2.0 #SchemaObject:[https://swagger.io/specification/v2/#schemaObject](https://swagger.io/specification/v2/#schemaObject) -- go swagger:[https://goswagger.io/use/models/schemas.html](https://goswagger.io/use/models/schemas.html) -- swagger data models:[https://swagger.io/docs/specification/data-models/](https://swagger.io/docs/specification/data-models/) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/1.init.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/1.init.md deleted file mode 100644 index 0bfc0303..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/1.init.md +++ /dev/null @@ -1,45 +0,0 @@ -# kpm init - -初始化一个 kcl 包。 - -## 使用 - -```shell -kpm init [options][package_name] -``` - -## 介绍 - -`kpm init` 会在当前目录初始化一个 kcl 包。如果没有提供包名,会使用当前目录的名字作为包名。 - -如果提供了包名,会在当前目录下创建一个以包名命名的子目录,并在该目录下初始化 kcl 包。 - -`kpm init` 会在包目录下创建 `kcl.mod`、`kcl.mod.lock` 和 `main.k`。 - -## 选线 - -### --help, -h - -显示帮助信息。 - -## 示例 - -### 初始化当前目录为 kcl 包 - -```shell -# 创建一个目录 -$ mkdir my_package - -# 进入目录 -$ cd my_package - -# 初始化当前目录为 kcl 包 -$ kpm init -``` - -### 初始化一个名为 my_package 的 kcl 包 - -```shell -# 初始化一个名为 my_package 的 kcl 包 -kpm init my_package -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/10.help.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/10.help.md deleted file mode 100644 index 0fd9fa3a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/10.help.md +++ /dev/null @@ -1,21 +0,0 @@ -# kpm help - -输出 kpm 命令的帮助信息。 - -## 使用 - -```shell -kpm help -``` - -## 介绍 - -`kpm help` 会输出 kpm 命令的帮助信息。 - -## 示例 - -使用 `kpm help` 输出 kpm 命令的帮助信息。 - -```shell -kpm help -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/2.add.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/2.add.md deleted file mode 100644 index 09fd5d46..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/2.add.md +++ /dev/null @@ -1,53 +0,0 @@ -# kpm add - -添加一个依赖到 kcl 包。 - -## 使用 - -```shell -kpm add [options][package_reference] -``` - -## 介绍 - -`kpm add` 会添加一个依赖到 kcl 包。依赖可以来自 git 仓库,或者 kcl registry。 - -`package_reference` 是一个 kcl 包引用,格式为 `package_name:version`。 - -## 选项 - -### --git - -指定依赖来自 git 仓库的 git url。 - -### --tag - -指定依赖来自 git 仓库的 tag。 - -### --help, -h - -显示帮助信息。 - -## 示例 - -### 添加一个来自 kcl registry 的依赖 - -添加一个名为 `k8s` 的依赖,版本为最新版本。 - -```shell -kpm add k8s -``` - -添加一个名为 `k8s` 的依赖,版本为 `v1.27.2`。 - -```shell -kpm add k8s:v1.27.2 -``` - -### 添加一个来自 git 仓库的依赖 - -添加一个来自 git 仓库的 kcl 包依赖,tag 为 v0.1.0 - -```shell -kpm add --git https://github.com/awesome-kusion/konfig.git --tag v0.1.0 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/3.pkg.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/3.pkg.md deleted file mode 100644 index fd708d03..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/3.pkg.md +++ /dev/null @@ -1,33 +0,0 @@ -# kpm pkg - -打包一个 kcl 包。 - -## 使用 - -```shell -kpm pkg [options] -``` - -## 介绍 - -`kpm pkg` 会打包一个 kcl 包为 `*.tar`。 - -选项 `--target` 用于指定打包后的 `*.tar` 文件路径。 - -## 选项 - -### --target - -指定打包后的 `*.tar` 文件路径。 - -### --help, -h - -显示帮助信息。 - -## 示例 - -### 打包当前 kcl 包为 `*.tar` - -```shell -kpm pkg --target /Users/my_package_tar -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/4.metadata.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/4.metadata.md deleted file mode 100644 index 199ebd2e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/4.metadata.md +++ /dev/null @@ -1,41 +0,0 @@ -# kpm metadata - -打印 kcl 包的元数据。 - -## 使用 - -```shell -kpm metadata [options] -``` - -## 介绍 - -`kpm metadata` 会打印 kcl 包的元数据。元数据包括包的依赖信息。 - -`--update` 选项用于自动下载缺失的依赖包。 - -## 选项 - -### --update - -自动下载缺失的依赖包。 - -### --help, -h - -展示 `kpm metadata` 命令的帮助信息。 - -## 示例 - -### 打印 kcl 包的元数据 - -打印 kcl 包的元数据。 - -```shell -kpm metadata -``` - -打印 kcl 包的元数据,并自动下载缺失的依赖包。 - -```shell -kpm metadata --update -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/5.run.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/5.run.md deleted file mode 100644 index eee83e08..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/5.run.md +++ /dev/null @@ -1,69 +0,0 @@ -# kpm run - -编译一个 kcl 包。 - -## 使用 - -```shell -kpm run [options][package_source] -``` - -## 介绍 - -`kpm run` 会编译一个 kcl 包。 - -## 选项 - -### --input - -指定包的入口文件路径。 - -### --tag - -指定 oci url 的包的 tag。 - -### --vendor - -`--vendor` 选项会将依赖包移动到当前包,并自动下载缺失的依赖包。 - -### --kcl_args - -`--kcl_args` 描述了传递给 kcl 编译器的参数。 - -### --help, -h - -展示 `kpm run` 命令的帮助信息。 - -## 示例 - -### 编译当前 kcl 包 - -在 kcl 包目录下,`kpm run` 可以用于编译当前 kcl 包。 - -```shell -kpm run -``` - -### 编译一个 kcl 包 tar 文件 - -`kpm run` 可以用于编译一个 kcl 包 tar 文件。 - -```shell -kpm run /Users/demo/my_package.tar -``` - -### 编译一个 kcl 包来自 oci url - -`kpm run` 可以用于编译一个 kcl 包从 oci url。 - -```shell -kpm run --tag 0.0.1 oci://localhost:5001/test/my_package -``` - -### 编译一个 kcl 包来自 oci ref - -`kpm run` 可以用于编译一个 kcl 包从 oci ref。 - -```shell -kpm run test/my_package:0.0.1 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/6.login.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/6.login.md deleted file mode 100644 index 9055d8fb..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/6.login.md +++ /dev/null @@ -1,68 +0,0 @@ -# kpm login - -登陆 kpm registry. - -## 使用 - -```shell -kpm login [options][kpm_registry] -``` - -## 介绍 - -`kpm login` 将会登陆 kpm registry。 - -## 选项 - -### --username, -u - -指定 kpm registry 的用户名。 - -### --password, -p - -指定 kpm registry 的密码。 - -### --help, -h - -展示 `kpm login` 命令的帮助信息。 - -## 示例 - -### 登陆到 kpm registry, 通过参数输入用户名和密码 - -```shell -kpm login -u -p -``` - -期望输出为 - -```shell -Login succeeded -``` - -### 登陆到 kpm registry, 通过参数输入用户名,密码通过交互式输入 - -```shell -kpm login -u -``` - -期望输出为 - -```shell -Password: -Login succeeded -``` - -### 登陆到 kpm registry, 用户名和密码通过交互式输入 - -```shell -kpm login -``` - -期望输出为 - -```shell -Username: -Password: -Login succeeded -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/7.logout.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/7.logout.md deleted file mode 100644 index 65dd317e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/7.logout.md +++ /dev/null @@ -1,27 +0,0 @@ -# kpm logout - -从 kpm registry 登出。 - -## 使用 - -```shell -kpm logout [options][kpm_registry] -``` - -## 介绍 - -`kpm logout` 会从 kpm registry 登出。 - -## 选项 - -### --help, -h - -展示 `kpm logout` 命令的帮助信息。 - -## 示例 - -### 从 kpm registry 登出 - -```shell -kpm logout -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/8.push.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/8.push.md deleted file mode 100644 index 53c2e520..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/8.push.md +++ /dev/null @@ -1,46 +0,0 @@ -# kpm push - -上传一个 kcl 包到 kpm registry。 - -## 使用 - -```shell -kpm push [options][kpm_registry] -``` - -## 介绍 - -`kpm push` 将会上传一个 kcl 包到 kpm registry。 - -## 选项 - -### --tar_path - -指定上传的 `*.tar` 文件路径。 - -### --help, -h - -展示 `kpm push` 命令的帮助信息。 - -## 示例 - -### 上传当前 kcl 包到 kpm registry - -你可以在 kcl 包的根目录下使用 `kpm push` 命令上传一个 kcl 包到 kpm registry。 - -```shell -# 创建一个 kcl 包 -$ kpm init -# 进入 kcl 包目录 -$ cd -# 上传 kcl 包到 kpm registry -$ kpm push -``` - -### 上传一个 `*.tar` 文件到 kpm registry - -你也可以使用 `kpm push` 命令上传一个 `*.tar` 文件到 kpm registry。 - -```shell -kpm push --tar_path -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/9.pull.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/9.pull.md deleted file mode 100644 index cec49291..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/9.pull.md +++ /dev/null @@ -1,41 +0,0 @@ -# kpm pull - -下载 kcl 包从 kpm registry。 - -## 使用 - -```shell -kpm pull [options][package_source] -``` - -## 介绍 - -`kpm pull` 会从 kpm registry 下载 kcl 包。 - -## 选项 - -### --tag - -使用 oci url 下载包时, 指定要下载的 kcl 包的 tag。 - -### --help, -h - -展示 `kpm pull` 命令的帮助信息。 - -## 示例 - -### 从 kpm registry 下载 kcl 包 - -你可以使用 `kpm pull` 命令从 默认的 kpm registry 下载 kcl 包。 - -```shell -kpm pull : -``` - -### 下载 kcl 包通过 oci url - -你可以使用 `kpm pull` 命令从一个 oci url 下载 kcl 包。 - -```shell -kpm pull --tag -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/_category_.json deleted file mode 100644 index abcc956a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "命令参考", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/index.md deleted file mode 100644 index e3025db9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/command-reference/index.md +++ /dev/null @@ -1,36 +0,0 @@ -# kpm - -kpm 命令。 - -## 使用 - -```shell -kpm [arguments]... -``` - -## 介绍 - -`kpm` 是 kcl 包管理工具。它用于分发和管理 kcl 包。 - -## 选项 - -### --help, -h - -展示 `kpm` 命令的帮助信息。 - -### --version, -v - -展示 `kpm` 命令的版本信息。 - -## 子命令 - -- [kpm init](./1.init.md) - 初始化一个 kcl 包 -- [kpm add](./2.add.md) - 添加一个依赖到 kcl 包 -- [kpm pkg](./3.pkg.md) - 打包一个 kcl 包为 `*.tar` -- [kpm metadata](./4.metadata.md) - 打印一个 kcl 包的元数据 -- [kpm run](./5.run.md) - 编译一个 kcl 包为 yaml 并运行 -- [kpm login](./6.login.md) - 登录到一个 kcl registry -- [kpm logout](./7.logout.md) - 登出一个 kcl registry -- [kpm push](./8.push.md) - 上传一个 kcl 包到一个 registry -- [kpm pull](./9.pull.md) - 下载一个 kcl 包从一个 registry -- [kpm help](./10.help.md) - 打印 kpm 命令的帮助信息 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/concepts/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/concepts/_category_.json deleted file mode 100644 index d3ae7a0a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/concepts/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "核心概念", - "position": 5 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/concepts/concepts.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/concepts/concepts.md deleted file mode 100644 index e2034db2..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/concepts/concepts.md +++ /dev/null @@ -1,3 +0,0 @@ -# 核心概念 - -学习更多关于 KCL 核心概念。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/concepts/package-and-module.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/concepts/package-and-module.md deleted file mode 100644 index fbde28f3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/concepts/package-and-module.md +++ /dev/null @@ -1,156 +0,0 @@ -# 模块和包 - -本节主要介绍如何组织 KCL 中的文件。 - -## 概述 - -在一个**module**中,KCL 按**package**进行组织文件。package 可以在 module 内定义,也可以通过 KCL 包管理器 `kpm` 从外部导入。在后一种情况下,KCL 在专用位置中维护包的副本。 - -## Module - -KCL 模块按目录层次结构布置配置。它包含了确定 KCL 配置结果所需的一切。此目录的根标记为包含 `kcl.mod` 目录。此目录的内容大多由 kcl 工具(如 `kpm` 等)管理。从这个意义上讲,`kcl.mod` 类似于 `.git` 目录,标记着仓库的根目录,但它的内容主要由 git 工具管理。此外,KCL 模块是文件组织的最大单位,具有所有 KCL 文件和依赖项的固定位置。 - -> 注意: 使用 KCL 模块(例如 `kcl.mod`)是可选的,但如果您想使用语义版本管理、分发、共享和重用代码,则需要使用它。 - -### 创建一个 module - -可以通过在模块根目录中运行以下命令来创建模块: - -```bash -kpm init [module name] -``` - -模块名在需要在模块内导入另一个模块的包时是**必需的**。也可以通过手动设置 `kcl.mod` 文件来创建模块。 - -## Package - -在 KCL 中,一个包通常由包含 KCL 文件的“文件夹”组成。这个文件夹可以是实际的磁盘物理路径,也可以由多个 KCL 文件(通常是主包)组成。不同的包通过不同的包路径(如 `kubernetes.core.v1`)唯一地定位。 - -在同一个模块内,可以通过相对或绝对路径的 import 语句互相导入不同的包。在 KCL 解析过程中,相对 import 将被替换为绝对 import,并通过包路径找到相应的 KCL 代码。 - -### 相对导入路径 - -我们可以使用 `.` 运算符来实现 KCL 入口文件的相对路径导入。 - -main.k: - -```python -import .model1 # Current directory module -import ..service # Parent directory -import ...root # Parent of parent directory - -s = service.ImageService {} -m = root.Schema {} -``` - -### 绝对导入路径 - -KCL 语句`import a.b.c.d` 的语义是: - -1. 如果 `kcl.mod` 不存在,则将当前目录视为包根目录,并从当前目录搜索路径 `a/b/c/d`。 -2. 如果当前目录搜索失败,则从根路径 `ROOT_PATH/a/b/c/d` 搜索,否则引发导入错误。 - -根路径 `ROOT_PATH` 的定义是相对于 `kcl.mod` 文件的目录。 - -代码结构: - -```bash -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -### 内置包 - -KCL 有一系列内置包,例如 `math`,`regex` 等。要使用内置包,直接导入并使用其限定标识符调用函数。例如, - -```python -import regex - -image = "nginx:1.14.2" -is_match = regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$") - -``` - -输出的 YAML 为 - -```yaml -image: nginx:1.14.2 -is_match: true -``` - -### 插件包 - - - -KCL 还有一系列插件包,例如 `hello`,`project_context` 等。要使用插件包,需要用 `kcl_plugin.` 包路径前缀导入,并使用其限定标识符调用函数。例如, - -```python -import kcl_plugin.hello - -result = hello.add(1, 1) -``` - -输出的 YAML 为 - -```yaml -result: 2 -``` - -### 主包 - -在 KCL 中,主包的组成通常由编译器参数确定。这是因为KCL模式和约束可以在包中的文件中分隔,甚至可以在目录中组织,考虑将配置写入和维护在隔离块中的便利性。 - -#### 属于主包的文件 - -用户可以使用KCL命令行决定使用哪些配置和约束,例如, - -```bash -kcl file1.k file2.k -``` - -因此,主包包含两个名为 `file1.k` 和 `file2.k` 的 KCL 文件。 - -如果 KCL 被告知为特定目录加载文件,例如: - -```bash -kcl ./path/to/package -``` - -它将只查找 `.k` 后缀的 KCL 文件,并忽略 `_` 或 `_test.k` 前缀的 KCL 文件合并到主包中。此外,如果 `./path/to/package` 包含 `kcl.yaml` 文件,则 `kcl.yaml` 文件将被忽略。 - -此外,我们可以通过配置命令行编译设置文件(例如 `kcl.yaml`)来设置主包文件,如下所示: - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k -``` - -```bash -kcl -Y kcl.yaml -``` - -> 注意:如果没有为 KCL 指定任何输入文件,KCL 将从命令行执行路径查找默认的 `kcl.yaml` 文件读取输入文件。此外,如果我们告诉KCL输入文件和编译设置文件,KCL将把用户输入的输入文件作为最终值。 - -```bash -# 无论`kcl.yaml` 中是否配置 `files` 字段,输入文件的最终值为["file1.k", "file2.k"] -kcl -Y kcl.yaml file1.k file2.k -``` - -## kcl.mod 和 kcl.yaml 异同 - -首先,在 KCL 中,`kcl.mod` 和 `kcl.yaml` 都是可选的。它们之间的区别在于 `kcl.mod` 确定包路径的根路径以及 KCL 模块是否具有分发和重用要求,而 `kcl.yaml` 确定主包的 KCL 文件组成。 - -其次,对于仅用于外部使用的 kcl module,`kcl.yaml` 是可选的,但 `kcl.mod` 是必需的,因为 `kcl.mod` 需要声明 KCL 版本,模块版本,依赖关系和其他信息。 - -最后,对于 KCL IDE 插件,它需要知道主包信息才能形成完整的编译过程,因此它需要根据光标位置自动查找主包组成,因为没有人可以通过 KCL 命令行指定这些信息。一般的查询逻辑是查找 `kcl.yaml` 的存在性。如果找到了,主包由 `kcl.yaml` 中的文件属性组成,如果找不到,主包由当前文件组成。KCL IDE 插件会有选择地了解 `kcl.mod` 文件。当 `kcl.mod` 文件存在时,IDE 插件会读取所有包路径及其在外部依赖项中的实际路径的相应信息。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/getting-started/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/getting-started/_category_.json deleted file mode 100644 index c826d665..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/getting-started/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "快速开始", - "position": 1 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/getting-started/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/getting-started/index.md deleted file mode 100644 index 5d58acf6..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/getting-started/index.md +++ /dev/null @@ -1 +0,0 @@ -# 快速开始 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/getting-started/kcl-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/getting-started/kcl-quick-start.md deleted file mode 100644 index 8d75e878..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/getting-started/kcl-quick-start.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -sidebar_position: 3 ---- - -# KCL 语言速览 - -KCL 是一个面相云原生配置策略领域的编程语言。KCL 设计之初受 Python3 启发,同时吸收了声明式、OOP 编程范式的设计理念,是一种专用于配置策略定义、校验的静态强类型的面相配置和策略场景的语言。本节我们将快速展示 KCL 语言的基本特性。 - -## 1. Hello KCL - -学习新语言的最佳途径是自己亲手写几个小程序,配置语言也是如此。KCL 作为一种配置策略语言,我们可以像写配置一样写 KCL 程序。 - -下面是一个简单的 `hello.k` 程序: - -```python -hello = "KCL" -``` - -将 `hello` 属性设置为 `"KCL"` 字符串。然后将代码保存到 `hello.k` 文件中。 - -如何执行这个程序取决于具体的开发环境,我们先假设本地的 macOS 或者是 Linux 系统已经安装了 `kcl` 命令(或者通过 `docker run --rm -it kcllang/kcl` 进入 Docker 环境测试)。然后在文件所在的目录命令行输入以下命令执行: - -```shell -kcl hello.k -``` - -输出为 - -```yaml -hello: KCL -``` - -命令行执行的效果如图所示: - -![](/img/docs/user_docs/getting-started/hello.gif) - -输出的是 YAML 格式的配置数据。这个程序虽然简单,但是我们可以通过执行 KCL 配置程序到输出结果验证了开发环境和 `kcl` 命令行的基本用法。 - -## 2. 再复杂一点的配置 - -常见的配置数据除了的普通的 key-value 对,还有嵌套的字典和列表类型,同时 value 基础类型除了字符串还有布尔和数值等类型。下面是更为复杂一点的 `server.k` 配置: - -```python -# This is a KCL document - -title = "KCL Example" - -owner = { - name = "The KCL Authors" - data = "2020-01-02T03:04:05" -} - -database = { - enabled = True - ports = [8000, 8001, 8002] - data = [["delta", "phi"], [3.14]] - temp_targets = {cpu = 79.5, case = 72.0} -} - -servers = [ - {ip = "10.0.0.1", role = "frontend"} - {ip = "10.0.0.2", role = "backend"} -] -``` - -其中 `#` 开头的表示行注释。`owner` 的 value 是一个字典,字典的面值通过 `{}` 方式包含的内容,字典内部的 key-value 和 `hello = "KCL"` 例子的写法类似。`database` 则是另一个字典,其中字典属性的 value 出现了布尔 `True`、列表 `[]` 和 `{}` 字典,其中列表和字典中还出现了数值类型的 value。 最后一个 `servers` 属性则是一个列表,列表内部嵌套着字典(字典和列表以及后续将要讲到的 `schema` 都可以相互嵌套)。 - -该配置输出的 YAML 结果如下: - -```yaml -$ kcl server.k -title: KCL Example -owner: - name: The KCL Authors - data: '2020-01-02T03:04:05' -database: - enabled: true - ports: - - 8000 - - 8001 - - 8002 - data: - - - delta - - phi - - - 3.14 - temp_targets: - cpu: 79.5 - case: 72.0 -servers: -- ip: 10.0.0.1 - role: frontend -- ip: 10.0.0.2 - role: backend -``` - -## 3. schema 定义配置的结构 - -KCL 通过 `schema` 语法结构为有着固定属性结构和默认值行为的属性提供抽象支持。 - -比如上面例子的中 `database` 的配置一般是用默认值即可。这样我们可以通过为数据库的默认配置定义一个结构: - -```python -schema DatabaseConfig: - enabled: bool = True - ports: [int] = [8000, 8001, 8002] - data: [[str|float]] = [["delta", "phi"], [3.14]] - temp_targets: {str: float} = {cpu = 79.5, case = 72.0} -``` - -`enabled` 是布尔类型;`ports` 为整数列表类型;`data` 为列表的列表,内层的列表元素是字符串或者浮点数类型;`temp_targets` 则是一个字典类型,字典的属性值是浮点数类型。并且 `DatabaseConfig` 的每个属性都定义了默认值。 - -然后通过 `database = DatabaseConfig {}` 就可以产生和默认值相同属性的结构。用户也可以修改默认值: - -```python -database = DatabaseConfig { - ports = [2020, 2021] -} -``` - -`schema DatabaseConfig` 不仅仅为属性提供了默认值,还为属性添加了类型信息。因此,如果用户不小心写错属性值类型的话,KCL 将会给出友好的错误提示,比如下面的例子将 `ports` 错误地写成了浮点数类型: - -```python -database = DatabaseConfig { - ports = [1.2, 1.3] -} -``` - -执行时将产生类似以下的错误(显示的文件路径和本地环境有关): - -```shell -kcl server.k -``` - -输出为 - -```shell -error[E2G22]: TypeError - --> /path/to/server.k:8:5 - | -8 | ports = [1.2, 1.3] - | ^ expected [int], got [float(1.2)|float(1.3)] - | - - --> /path/to/server.k:3:5 - | -3 | ports: [int] = [8000, 8001, 8002] - | ^ variable is defined here, its type is [int], but got [float(1.2)|float(1.3)] - | -``` - -类似地我们可以用以下的代码封装 `servers` 部分的属性: - -```python -schema ServerConfig: - ip: str - role: "frontend" | "backend" - -servers = [ - ServerConfig {ip = "10.0.0.1", role = "frontend"} - ServerConfig {ip = "10.0.0.2", role = "backend"} -] -``` - -其中 `ServerConfig` 的 `ip` 是字符串类型,并没有给出默认值。用户在生成 `ServerConfig` 类型的属性时必须手工添加 `ip` 属性的值,否则 KCL 将会报出缺少必填属性的错误。`role` 属性是 `"frontend" | "backend"` 枚举字符串类型。 - -此外,`schema` 还可以结合 `check`、`mixin`、可选属性、继承和扩展模块实现更为复杂的配置和策略数据的抽象,细节可以参考手册部分的文档。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/_category_.json deleted file mode 100644 index 1fdf894e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "用户手册", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/abstraction.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/abstraction.md deleted file mode 100644 index da590317..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/abstraction.md +++ /dev/null @@ -1,149 +0,0 @@ ---- -title: "抽象" -sidebar_position: 3 ---- - -## 什么是抽象 - -抽象是指一个实体的简化表示,它允许隐藏特定的具体细节,同时向程序员提供最相关的信息。每一个抽象都是为满足特定需求而定制的,并且可以极大地提高给定实体的可用性。在 KCL 的上下文中,抽象可以使代码更容易理解和维护,同时也可以简化用户界面。 - -需要注意的是,代码抽象并不是为了减少代码大小,而是为了提高代码的可维护性和可扩展性。在抽象代码的过程中,应考虑可重用性、可读性和可扩展性等因素,并根据需要对代码进行不断优化。 - -良好的抽象可以提供如下价值 - -1. 提供不同的焦点,不同角色和场景关注点分离。 -2. 屏蔽较低级别的细节,避免潜在的错误。 -3. 提升用户界面和自动化友好性。 - -KCL 自身可能不会评估用户定义模型抽象的合理性,但它提供了技术解决方案来帮助用户构建抽象。 - -## 使用 KCL 进行抽象 - -现在,让我们将 Docker Compose 和 Kubernetes 资源抽象为应用程序配置 - -`Docker Compose` 是一个用于定义和运行多容器 Docker 应用程序的工具。使用 Docker Compose,您可以在一个文件中定义应用程序的服务、网络和卷,然后使用它作为一个单元启动和停止应用程序。Docker Compose 通过处理网络、存储和其他基础设施问题的细节,简化了运行复杂的多容器应用程序的过程。 - -Kubernetes 清单是定义 Kubernete 对象(如 Pods、Deployments 和 Services)的 YAML 文件。清单提供了一种声明性的方法来定义应用程序的所需状态,包括副本数量、要使用的镜像和网络配置。Kubernetes 使用清单来创建和管理部署和运行应用程序所需的资源。 - -以下是一些参考资料,可以帮助了解更多关于 Docker Compose 和 Kubernetes 相关的信息: - -- [Docker Compose 文档](https://docs.docker.com/compose/) -- [Kubernetes 对象文档](https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/) - -以应用程序为中心的开发使开发人员能够专注于其工作负载的体系结构,而不是目标环境、基础设施或平台中的技术栈。我们用 `App` 结构定义了应用程序模型,然后使用 KCL CLI 将其翻译到多个平台,例如不同版本的 `Docker Compose` 或 `Kubernetes`。该应用程序模型旨在通过只需定义一个跨多个平台工作的 KCL 文件来减少开发人员的工作量和认知负荷。现在,让我们学习如何做到这一点。 - -### 0. 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. 获取示例 - -首先,我们执行 git 命令获得用例 - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/abstraction -``` - -我们可以运行以下命令来显示配置。 - -```bash -cat main.k -``` - -输出为 - -```python -import .app - -app.App { - name = "app" - containers.nginx = { - image = "nginx" - ports = [{containerPort = 80}] - } - service.ports = [{ port = 80 }] -} -``` - -在上面的代码中,我们使用 `App` schema 定义了一个配置,其中我们配置了一个 `nginx` 容器,并开启 `80` 端口配置。 - -此外,KCL 允许开发人员以声明式的方式定义应用程序所需的资源,并允许生成特定于平台的配置文件,如 `docker_compose.yaml` 或 Kubernetes `manifests.yaml` 文件。接下来,让我们生成相应的配置。 - -### 2. 将应用配置转换为 Docker Compose 配置 - -如果我们想将应用程序配置转换为 Docker Compose 配置,我们可以简单地运行如下命令: - -```shell -kcl main.k docker_compose_render.k -``` - -输出为 - -```yaml -services: - app: - image: nginx - ports: - - published: 80 - target: 80 - protocol: TCP -``` - -### 3. 将应用配置转换为 Kubernetes Deployment and Service 资源清单 - -如果我们想将应用程序配置转换为 Kubernetes 清单,我们可以简单地运行如下命令: - -```shell -kcl main.k kubernetes_render.k -``` - -输出为 - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: app - labels: - app: app -spec: - replicas: 1 - selector: - matchLabels: - app: app - template: - metadata: - labels: - app: app - spec: - containers: - - name: nginx - image: nginx - ports: - - protocol: TCP - containerPort: 80 ---- -apiVersion: v1 -kind: Service -metadata: - name: app - labels: - app: app -spec: - selector: - app: app - ports: - - port: 80 - protocol: TCP -``` - -如果您想了解有关应用程序模型的更多信息,可以参考[此处](https://github.com/kcl-lang/kcl-lang.io/tree/main/examples/abstraction). - -## 小结 - -通过使用 KCL,我们能够分离模型的抽象和实现细节,允许将抽象模型映射到各种基础设施或平台。这是通过不同实现之间的灵活切换和 KCL 组合编译来实现的,以屏蔽配置差异,减轻认知负担。 - -## 更多信息 - -除了手动维护配置外,我们还可以使用 KCL API 将**自动配置更改能力**集成到我们的应用程序中。有关 KCL 自动化能力的相关说明,请参阅[此处](/docs/user_docs/guides/automation)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/ci-integration/1-github-actions.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/ci-integration/1-github-actions.md deleted file mode 100644 index b93fdec9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/ci-integration/1-github-actions.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -id: github-actions -sidebar_label: Github Actions ---- - -# Github Actions 集成 - -## 简介 - -在 GitOps 章节,我们介绍了如何将 KCL 与 GitOps 进行集成。在本文中,我们将继续提供 KCL 和 CI 集成的示例方案,希望通过使用容器、用于生成的持续集成 (CI) 和用于持续部署 (CD) 的 GitOps 来实现端到端应用程序开发流程。在此方案中,我们使用一个 Flask 应用和 Github Actions 将用作示例。 - -> 注意:你可以在此方案中使用任何容器化应用以及不同的 CI 系统如 Gitlab CI,Jenkins CI 等。 - -整体工作流程如下: - -- 应用代码开发并提交到提交到 GitHub 存储库 -- GitHub Actions 从应用代码生成容器镜像,并将容器镜像推送到 docker.io 容器注册表 -- GitHub Actions 根据 docker.io 容器注册表中容器镜像的版本号并同步更新 KCL 清单部署文件 - -## 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -## 具体步骤 - -### 1. 获得示例 - -我们将业务源码和部署清单放在不同仓库,可以分不同角色进行分别维护,实现关注点分离。 - -- 获得业务源码 - -```shell -git clone https://github.com/kcl-lang/flask-demo.git/ -cd flask-demo -``` - -这是一个使用 Python 编写的 Web 应用,我们可以使用应用目录的 `Dockerfile` 来生成这个应用的容器镜像,同时可以通过 Github CI 自动构建 `flask_demo` 镜像,CI 配置如下 - -```yaml -# This is a basic workflow to help you get started with Actions - -name: CI - -# Controls when the workflow will run -on: - # Triggers the workflow on push or pull request events but only for the main branch - push: - branches: [main] - pull_request: - branches: [main] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "build" - build: - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - - - name: Docker Login - uses: docker/login-action@v1.10.0 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - logout: true - - # Runs a set of commands using the runners shell - - name: build image - run: | - make image - docker tag flask_demo:latest ${{ secrets.DOCKER_USERNAME }}/flask_demo:${{ github.sha }} - docker push ${{ secrets.DOCKER_USERNAME }}/flask_demo:${{ github.sha }} - - # Trigger KCL manifest - - name: Trigger CI - uses: InformaticsMatters/trigger-ci-action@1.0.1 - with: - ci-owner: kcl-lang - ci-repository: flask-demo-kcl-manifests - ci-ref: refs/heads/main - ci-user: kcl-bot - ci-user-token: ${{ secrets.DEPLOY_ACCESS_TOKEN }} - ci-name: CI - ci-inputs: >- - image=${{ secrets.DOCKER_USERNAME }}/flask_demo - sha-tag=${{ github.sha }} -``` - -我们需要源码仓库的工作流自动触发部署清单仓库中的工作流,此时需要创建具有 Github CI 操作权限的 `secrets.DEPLOY_ACCESS_TOKEN` 以及 Docker Hub 镜像推送的账号信息 `secrets.DOCKER_USERNAME` 和 `secrets.DOCKER_PASSWORD`, 这些可以在 Github 仓库的 `Secrets and variables` 设置中进行配置,如下图所示 - -![](/img/docs/user_docs/guides/ci-integration/github-secrets.png) - -### 2. 提交应用代码 - -flask-demo 仓库提交代码后,Github 会自动构建容器镜像,并将制品推送到 Docker hub 中,会再触发 flask-demo-kcl-manifests 仓库的 Action,[通过 KCL 自动化 API](/docs/user_docs/guides/automation) 修改部署清单仓库中的镜像地址。现在让我们为 flask-demo 仓库创建一个提交,我们可以看到代码提交后触发业务仓库 Github CI 流程 - -![](/img/docs/user_docs/guides/ci-integration/app-ci.png) - -### 3. 配置自动更新 - -当业务仓库 Github CI 流程执行完成后,会自动在存放 KCL 资源配置的仓库触发一个 CI 自动更新配置并提交到 flask-demo-kcl-manifests main 分支,commit 信息如下 - -![](/img/docs/user_docs/guides/ci-integration/image-auto-update.png) - -- 我们可以获得部署清单源码进行编译验证 - -```shell -git clone https://github.com/kcl-lang/flask-demo-kcl-manifests.git/ -cd flask-demo-kcl-manifests -git checkout main && git pull && kcl -``` - -输出 YAML 为 - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - replicas: 1 - selector: - matchLabels: - app: flask_demo - template: - metadata: - labels: - app: flask_demo - spec: - containers: - - name: flask_demo - image: "kcllang/flask_demo:6428cff4309afc8c1c40ad180bb9cfd82546be3e" - ports: - - protocol: TCP - containerPort: 5000 ---- -apiVersion: v1 -kind: Service -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - type: NodePort - selector: - app: flask_demo - ports: - - port: 5000 - protocol: TCP - targetPort: 5000 -``` - -从上述配置可以看出资源的镜像确实自动更新为了新构建的镜像内容。此外,我们还可以使用 Argo CD KCL 插件 自动从 Git 存储库同步或从中拉取数据并将应用部署到 Kubernetes 集群。 - -## 小结 - -通过将 KCL 和 Github CI 集成,我们能够将任意的业务代码的产出容器化镜像进行自动化修改并部署配置,以实现端到端应用程序开发流程并提升研发部署效率。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/ci-integration/_2-gitlab-ci.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/ci-integration/_2-gitlab-ci.md deleted file mode 100644 index 5ec96ce9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/ci-integration/_2-gitlab-ci.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -id: gitlab-ci -sidebar_label: Gitlab CI ---- - -Coming Soon - -## Introduction - -## How to - -## Summary diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/configuration.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/configuration.md deleted file mode 100644 index 127505c9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/configuration.md +++ /dev/null @@ -1,129 +0,0 @@ ---- -title: "配置" -sidebar_position: 1 ---- - -## 简介 - -配置是软件系统的一个重要方面,由于不断发展的业务需求、基础设施需求和其他因素,这些系统会不断发生变化。通常,快速改变这些系统的行为可能具有挑战性,尤其是当这样做需要昂贵且耗时的重建和重新部署过程时。在这种情况下,仅仅对业务代码进行更改可能是不够的。幸运的是,配置提供了一种低开销的方式来修改系统功能。 - -我们可以根据需要将静态配置存储在 JSON 或 YAML 等文件中。此外,配置也可以存储在高级语言中,从而实现更灵活的配置。这种语言可以进行编码、呈现和静态配置。KCL 是一种提供此类功能的配置语言。开发人员可以编写 KCL 代码来生成JSON/YAML 和其他配置。 - -## 使用 KCL 编写配置代码 - -KCL 的核心特性是其**建模**和**约束**能力,KCL 核心功能基本围绕 KCL 这个两个核心特性展开,对于代码而言(包括配置代码)都存在对配置数据约束的需求,比如类型约束、配置字段必选/可选约束、范围约束、不可变性约束等,这也是 KCL 致力于解决的核心问题之一。 - -现在我们已经了解了 KCL 的基本功能,让我们探索如何使用它来生成配置。 - -### 0. 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. 获取示例 - -首先,执行如下命令获取示例 - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/configuration -``` - -我们可以执行如下命令显示配置代码 - -```shell -cat nginx.k -``` - -输出为: - -```python -schema Nginx: - """Schema for Nginx configuration files""" - http: Http - -schema Http: - server: Server - -schema Server: - listen: int | str # The attribute `listen` can be int type or a string type. - location?: Location # Optional, but must be non-empty when specified - -schema Location: - root: str - index: str - -nginx = Nginx { - http.server = { - listen = 80 - location = { - root = "/var/www/html" - index = "index.html" - } - } -} -``` - -### 2. 使用 KCL 生成 YAML - -执行如下命令: - -```bash -kcl nginx.k -``` - -我们可以获得如下 YAML 输出 - -```yaml -nginx: - http: - server: - listen: 80 - location: - root: /var/www/html - index: index.html -``` - -### 3. 为配置添加动态参数 - -此外,我们可以通过 KCL 内置函数 `option` 动态接收外部参数。例如,对于下面的 KCL 文件(db.k),我们可以使用命令行 `-D` 标志来接收外部动态参数。 - -```python -env: str = option("env") or "dev" # The attribute `env` has a default value "den" -database: str = option("database") -hosts = { - dev = "postgres.dev" - stage = "postgres.stage" - prod = "postgres.prod" -} -dbConfig = { - host = hosts[env] - database = database - port = "2023" - conn = "postgres://${host}:${port}/${database}" -} -``` - -```bash -# Use the `-D` flag to input external parameters. -kcl db.k -D database="foo" -``` - -输出为 - -```yaml -env: dev -database: foo -hosts: - dev: postgres.dev - stage: postgres.stage - prod: postgres.prod -dbConfig: - host: postgres.dev - database: foo - port: "2023" - conn: "postgres://postgres.dev:2023/foo" -``` - -## 小结 - -通过使用KCL,我们可以生成更低低级别的数据配置。此外啊,我们通过 `-D` 标志设置动态参数以满足不同的场景需求。有关更多 KCL 的功能和教程,请参阅[此处](/docs/reference/lang/tour)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/data-integration.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/data-integration.md deleted file mode 100644 index 89511b2e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/data-integration.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: "数据集成" -sidebar_position: 4 ---- - -## 简介 - -在 KCL 中,不仅可以将 KCL 编写的配置代码编译输出为 YAML 格式的数据,还可以将 JSON/YAML 等数据直接嵌入到 KCL 语言当中。 - -## 使用 KCL 进行数据集成 - -### 0. 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. 获得示例 - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/data-integration -``` - -### 2. YAML 集成 - -我们可以运行以下命令来显示 KCL YAML 集成配置。 - -```bash -cat yaml.k -``` - -```python -import yaml - -schema Server: - ports: [int] - -server: Server = yaml.decode("""\ -ports: -- 80 -- 8080 -""") -server_yaml = yaml.encode({ - ports = [80, 8080] -}) -``` - -在上述代码中,我们通过 KCL 内置的 `yaml` 模块以及其中的 `yaml.decode` 直接完成 YAML 数据的集成,并且使用 `Server` schema 对集成的 YAML 数据直接进行校验。此外,我们可以使用 `yaml.encode` 完成 YAML 数据的序列化。 - -我们通过如下命令可以获得配置输出: - -```shell -kcl yaml.k -``` - -输出为 - -```yaml -server: - ports: - - 80 - - 8080 -server_yaml: | - ports: - - 80 - - 8080 -``` - -### 3. JSON 集成 - -同样的,对于 JSON 数据,我们可以使用 `json.encode` 和 `json.decode` 函数以同样的方式进行数据集成。 - -我们可以运行以下命令来显示 KCL JSON 集成配置。 - -```bash -cat json.k -``` - -```python -import json - -schema Server: - ports: [int] - -server: Server = json.decode('{"ports": [80, 8080]}') -server_json = json.encode({ - ports = [80, 8080] -}) -``` - -执行命令输出为: - -```shell -kcl json.k -``` - -```yaml -server: - ports: - - 80 - - 8080 -server_json: '{"ports": [80, 8080]}' -``` - -## 小结 - -本文介绍了如何在 KCL 中进行数据集成,使用 KCL 内置的 yaml 和 json 包将 YAML 和 JSON 数据直接集成到 KCL 语言中,并使用相应的解码和编码功能对其进行验证和序列化。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/gitops/1-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/gitops/1-quick-start.md deleted file mode 100644 index 673064c4..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/gitops/1-quick-start.md +++ /dev/null @@ -1,145 +0,0 @@ ---- -id: gitops-quick-start -sidebar_label: 快速开始 ---- - -# 快速开始 - -## 简介 - -### 什么是 GitOps - -GitOps 是一种实现持续交付的现代方式。它的核心思想是拥有一个包含环境和应用程序配置的 Git 存储库。通过更改应用存储库中的文件,可以自动部署应用程序。应用 GitOps 的好处包括: - -- 提高生产力,持续交付可以加快部署时间。 -- 降低开发人员部署的障碍。通过推送代码而不是容器配置,开发人员可以在不知道其内部实现的情况下轻松部署 Kubernetes 集群和应用。 -- 追踪变更记录。使用 Git 管理配置使每一项更改都具有可跟踪性,从而增强审计跟踪。 - -### 将 KCL 与 ArgoCD 一起使用 - -将 [KCL](https://github.com/kcl-lang/kcl) 与 [ArgoCD](https://github.com/argoproj/argo-cd) 等 GitOps 工具一起使用具有如下好处: - -- 通过 KCL 语言的[抽象能力](/docs/user_docs/guides/abstraction)和可编程能力可以帮助我们**简化复杂的 Kubernetes 部署配置文件**,降低手动编写 YAML 文件的错误率,消除多余的配置模版,提升多环境多租户的配置扩展能力,同时提高配置的可读性和可维护性。 -- KCL 允许开发人员以声明式的方式定义应用程序所需的资源,通过将 KCL 和 ArgoCD 相结合可以帮助我们更好地实现**基础设施即代码(IaC)**,提高部署效率,简化应用程序的配置管理。 -- ArgoCD 可以**自动化**地实现应用程序的连续部署,并提供友好的可视化界面。 - -使用 GitOps,开发人员和运维团队可以通过分别修改应用和配置代码来管理应用程序的部署,GitOps 工具链将自动同步对配置的更改,从而实现持续部署并确保一致性。如果出现问题,可以使用 GitOps 工具链快速回滚。 - -## 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -## 快速开始 - -### 1. 获取示例 - -首先,我们执行 git 命令获得用例 - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/gitops -``` - -我们可以运行以下命令来显示配置 - -```bash -cat config/main.k -``` - -The output is - -```python -import .app - -config = app.App { - name = "kcl-guestbook-ui" - containers.guestbook = { - image = "gcr.io/heptio-images/ks-guestbook-demo:0.2" - ports = [{containerPort = 80}] - } - service.ports = [{ port = 80 }] - service.type = "LoadBalancer" -} -``` - -在上述代码中,我们定义使用 `App` schema 定义了应用的配置,其中我们配置了一个镜像为 `gcr.io/heptio-images/ks-guestbook-demo:0.2` 容器,并启用了 `80` 端口。 - -### 2. 安装 Kubernetes 和 GitOps 工具 - -#### 配置 Kubernetes 集群和 ArgoCD 控制器 - -- 安装 [K3d](https://github.com/k3d-io/k3d) 并创建一个集群 - -```bash -k3d cluster create mycluster -``` - -> 注意:你可以在此方案中使用其他方式创建您自己的 Kubernetes 集群,如 kind, minikube 等。 - -- 安装 [ArgoCD](https://github.com/argoproj/argo-cd/releases/). - -```bash -kubectl create namespace argocd -kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml -``` - -- 安装 ArgoCD KCL 插件 - -```bash -kubectl apply -f ./install/kcl-cmp.yaml && kubectl -n argocd patch deploy/argocd-repo-server -p "$(cat ./install/patch-argocd-repo-server.yaml)" -``` - -- 通过 `kubectl get` 命令查看 argocd 控制器容器是否初始化完成进入运行(Running)状态。 - -```bash -kubectl get pod -n argocd -l app.kubernetes.io/name=argocd-repo-server -``` - -- 通过如下命令打开 ArgoCD UI - -```bash -kubectl port-forward svc/argocd-server -n argocd 8080:443 -``` - -- 打开浏览器 `https://localhost:8080` 输入用户名 "admin" 和密码登陆 ArgoCD UI,密码可以通过如下命令得到: - -```bash -kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d -``` - -#### 安装 ArgoCD 客户端工具 - -- 安装 [ArgoCD 客户端工具](https://github.com/argoproj/argo-cd/releases) - -- 使用用户名 "admin" 和刚才得到的密码登陆 - -```bash -argocd login localhost:8080 -``` - -通过如下命令创建一个 ArgoCD KCL 应用 - -```bash -argocd app create guestbook \ ---repo https://github.com/kcl-lang/kcl-lang.io \ ---path examples/gitops/config \ ---dest-namespace default \ ---dest-server https://kubernetes.default.svc \ ---config-management-plugin kcl-v1.0 -``` - -如果创建成功,您可以看到如下输出: - -```bash -application 'guestbook' created -``` - -> 如果您使用的是私有存储库,则在执行 create 命令之前,需要使用私钥凭据配置专用私有存储库访问权限。请参阅[这里](https://argo-cd.readthedocs.io/en/stable/user-guide/private-repositories/)以获取更多详细信息。 - -通过 ArgoCD UI,您可以看到创建的应用程序尚未同步,您可以手动进行配置同步或设置为自动同步。 - -![](/img/docs/user_docs/guides/gitops/argocd-kcl-app.jpg) - -有关同步策略的更多信息,可以请参阅[这里](https://argo-cd.readthedocs.io/en/stable/user-guide/sync-options/) - -![](/img/docs/user_docs/guides/gitops/argocd-kcl-app-dashboard.jpg) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/index.md deleted file mode 100644 index c0613d42..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/index.md +++ /dev/null @@ -1 +0,0 @@ -# 用户手册 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/1-overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/1-overview.md deleted file mode 100644 index ce7b13cb..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/1-overview.md +++ /dev/null @@ -1,3 +0,0 @@ -# 简介 - -KCL 通过包管理工具 [kpm](https://github.com/kcl-lang/kpm) 对 KCL 包进行管理。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/2-installation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/2-installation.md deleted file mode 100644 index 7b0892a5..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/2-installation.md +++ /dev/null @@ -1,53 +0,0 @@ -# 安装 - -## 安装 `kpm` - -kpm 将调用 `KCL`编译器来编译 KCL 程序。在使用 `kpm` 之前,您需要确保 `KCL` 编译器已经成功安装,您可以参照[如何安装 KCL 编译器](https://kcl-lang.io/docs/user_docs/getting-started/install)。 - -### 使用 `go install` 安装 `kpm` - -您可以使用 go install 命令安装 kpm。 - -```shell -go install kcl-lang.io/kpm@latest -``` - -### 从 Github release 页面手动安装 `kpm` - -您可以从 [kpm Github Release](https://github.com/kcl-lang/kpm/releases) 中获取 `kpm` ,并将 `kpm` 的二进制文件路径设置到环境变量 PATH 中。 - -```shell -# KPM_INSTALLATION_PATH 是 `kpm` 二进制文件的所在目录. -export PATH=$KPM_INSTALLATION_PATH:$PATH -``` - -请使用以下命令以确保您成功安装了`kpm`。 - -```shell -kpm --help -``` - -如果你看到以下输出信息,那么你已经成功安装了`kpm`,可以继续执行下一步操作。 - -```shell -NAME: - kpm - kpm is a kcl package manager - -USAGE: - kpm [arguments]... - -COMMANDS: - init initialize new module in current directory - add add new dependency - pkg package a kcl package into tar - metadata output the resolved dependencies of a package - run compile kcl package. - login login to a registry - logout logout from a registry - push push kcl package to OCI registry. - pull pull kcl package from OCI registry. - help, h Shows a list of commands or help for one command - -GLOBAL OPTIONS: - --help, -h show help -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/3-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/3-quick-start.md deleted file mode 100644 index 455987c8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/3-quick-start.md +++ /dev/null @@ -1,108 +0,0 @@ -# 快速开始 - -## 1. 初始化一个空的 KCL 包 - -使用 `kpm init` 命令创建一个名为 `my_package` 的 kcl 程序包, 并且在我们创建完成一个名为 `my_package` 的包后,我们需要通过命令 `cd my_package` 进入这个包来进行后续的操作。 - -```shell -kpm init my_package && cd my_package -``` - -![kpm_init](/img/docs/user_docs/guides/package-management/gifs/kpm_init.gif) - -`kpm` 将会在执行`kpm init my_package`命令的目录下创建两个默认的配置文件 `kcl.mod` 和 `kcl.mod.lock`。 - -```shell -- my_package - |- kcl.mod - |- kcl.mod.lock - |- # 你可以直接在这个目录下写你的kcl程序。 -``` - -`kcl.mod.lock` 是 `kpm` 用来固定依赖版本的文件,是自动生成的,请不要人工修改这个文件。 - -`kpm` 将会为这个新包创建一个默认的 `kcl.mod`。如下所示: - -```shell -[package] -name = "my_package" -edition = "0.0.1" -version = "0.0.1" -``` - -## 2. 为 KCL 包添加依赖 - -然后,您可以通过 `kpm add` 命令来为您当前的库添加一个外部依赖。 - -如下面的命令所示,为当前包添加一个版本号为 `1.27.2` 并且名为 `k8s` 的依赖包。 - -```shell -kpm add k8s:1.27.2 -``` - -![kpm_add_k8s](/img/docs/user_docs/guides/package-management/gifs/kpm_add_k8s.gif) - -`kpm` 会为您将依赖添加到 kcl.mod 文件中. - -```shell -[package] -name = "my_package" -edition = "0.0.1" -version = "0.0.1" - -[dependencies] -k8s = "1.27.2" # The dependency 'k8s' with version '1.27.2' -``` - -## 编写一个程序使用包 `konfig` 中的内容 - -在当前包中创建 `main.k`。 - -```shell -- my_package - |- kcl.mod - |- kcl.mod.lock - |- main.k # Your KCL program. -``` - -并且将下面的内容写入 `main.k` 文件中。 - -```kcl -# 导入并使用外部依赖 `k8s` 包中的内容。 -import k8s.api.core.v1 as k8core - -k8core.Pod { - metadata.name = "web-app" - spec.containers = [{ - name = "main-container" - image = "nginx" - ports = [{containerPort = 80}] - }] -} - -``` - -## 3. 运行 KCL 代码 - -你可以使用 kpm 编译刚才编写的 `main.k` 文件, 得到编译后的结果。 - -```shell -kpm run -``` - -输出为 - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: web-app -spec: - containers: - - image: nginx - name: main-container - ports: - - containerPort: 80 -``` - -![kpm_run](/img/docs/user_docs/guides/package-management/gifs/kpm_run.gif) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md deleted file mode 100644 index 23dd53a5..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md +++ /dev/null @@ -1,73 +0,0 @@ -# 发布 KCL 包到 ghcr.io - -本文将指导您如何使用 kcl 包管理将您的 kcl 包推送到发布到 OCI Registry 中。kcl 包管理默认使用 [ghcr.io](https://ghcr.io) 作为 OCI Registry, 您可以通过修改 kcl 包管理配置文件来更改默认的 OCI Registry。关于如何修改 kcl 包管理配置文件的信息,请参阅 [kcl oci registry](https://github.com/kcl-lang/kpm/blob/main/docs/kpm_oci-zh.md#kpm-registry) - -下面是一个简单的步骤,指导您如何使用 kcl 包管理将您的 kcl 包推送到 ghcr.io。 - -## 步骤 1:安装 KCL CLI - -首先,您需要在您的计算机上安装 KCL CLI。您可以按照 [KCL CLI 安装文档](https://kcl-lang.io/zh-CN/docs/user_docs/getting-started/install)中的说明进行操作。 - -## 步骤 2:创建一个 ghcr.io 令牌 - -如果您使用默认的 OCI Registry, 要将 kcl 包推送到 ghcr.io,您需要创建一个用于身份验证的令牌。您可以参考以下文档。 - -- [创建 ghcr.io token](https://docs.github.com/zh/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic) - -## 步骤 3:登录 ghcr.io - -在安装了 kcl 包管理并创建了 ghcr.io 令牌后,您需要使用 kcl 包管理登录 ghcr.io。您可以使用以下命令进行操作: - -```shell -kcl registry login -u -p ghcr.io -``` - -其中 `` 是您的 GitHub 用户名,`` 是您在步骤 2 中创建的令牌。 - -关于如何使用 kcl 包管理登录 ghcr.io 的更多信息,请参阅 [kcl registry login](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/login)。 - -## 步骤 4:推送您的 kcl 包 - -现在,您可以使用 kcl 包管理将您的 kcl 包推送到 ghcr.io。 - -### 1. 一个合法的 kcl 包 - -首先,您需要确保您推送的内容是符合一个 kcl 包的规范,即必须包含合法的 kcl.mod 和 kcl.mod.lock 文件。 - -如果您不知道如何得到一个合法的 `kcl.mod` 和 `kcl.mod.lock`。您可以使用 `kcl mod init` 命令。 - -```shell -# 创建一个名为 my_package 的 kcl 包 -kcl mod init my_package -``` - -`kcl mod init my_package` 命令将会为您创建一个新的 kcl 包 `my_package`, 并为这个包创建 `kcl.mod` 和 `kcl.mod.lock` 文件。 - -如果您已经有了一个包含 kcl 文件的目录 `exist_kcl_package`,您可以使用以下命令将其转换为一个 kcl 包,并为其创建合法的 `kcl.mod` 和 `kcl.mod.lock`。 - -```shell -# 在 exist_kcl_package 目录下 -$ pwd -/home/user/exist_kcl_package - -# 执行 kcl 包管理init 命令来创建 kcl.mod 和 kcl.mod.lock -$ kcl mod init -``` - -关于如何使用 kcl 包管理init 的更多信息,请参阅 [kcl mod init](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/init)。 - -### 2. 推送 kcl 包 - -您可以在 `kcl` 包的根目录下使用以下命令进行操作: - -```shell -# 在 exist_kcl_package 包的根目录下 -$ pwd -/home/user/exist_kcl_package - -# 推送 kcl 包到默认的 OCI Registry -$ kcl mod push -``` - -完成上述步骤后,您就成功地将您的 kcl 包推送到了默认的 OCI Registry 中。 -关于如何使用 kcl mod push 的更多信息,请参阅 [kcl mod push](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/push)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md deleted file mode 100644 index 9bb9f1cc..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md +++ /dev/null @@ -1,65 +0,0 @@ -# 发布 KCL 包到 docker.io - -本文将指导您如何使用 kcl 包管理将您的 kcl 包推送到发布到 docker.io 中。 - -## 步骤 1:安装 KCL CLI - -首先,您需要在您的计算机上安装 KCL CLI。您可以按照 [KCL CLI 安装文档](https://kcl-lang.io/zh-CN/docs/user_docs/getting-started/install)中的说明进行操作。 - -## 步骤 2:创建一个 docker.io 账户 - -您需要创建一个 docker.io 账户以支持您的 kcl 包的推送。 - -## 步骤 3:登录 docker.io - -您可以直接使用 docker.io 的账户名和密码登录。 - -```shell -kcl registry login -u -p docker.io -``` - -其中 `` 是您的 docker.io 用户名,`` 是您 docker.io 账户的密码。 - -关于如何使用 KCL CLI 登录 docker.io 的更多信息,请参阅 [kcl registry login](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/login)。 - -## 步骤 4:推送您的 kcl 包 - -现在,您可以使用 KCL CLI 将您的 kcl 包推送到 docker.io。 - -### 1. 一个合法的 kcl 包 - -首先,您需要确保您推送的内容是符合一个 kcl 包的规范,即必须包含合法的 kcl.mod 和 kcl.mod.lock 文件。 - -如果您不知道如何得到一个合法的 `kcl.mod` 和 `kcl.mod.lock`。您可以使用 `kcl mod init` 命令。 - -例如:创建一个名为 my_package 的 kcl 包 - -```shell -# 创建一个名为 my_package 的 kcl 包 -kcl mod init my_package -``` - -`kcl mod init my_package` 命令将会为您创建一个新的 kcl 包 `my_package`, 并为这个包创建 `kcl.mod` 和 `kcl.mod.lock` 文件。 - -如果您已经有了一个包含 kcl 文件的目录 `exist_kcl_package`,您可以使用以下命令将其转换为一个 kcl 包,并为其创建合法的 `kcl.mod` 和 `kcl.mod.lock`。 - -在 `exist_kcl_package` 目录下执行: - -```shell -kcl mod init -``` - -关于如何使用 kpm init 的更多信息,请参阅 [kcl mod init](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/init)。 - -### 2. 推送 kcl 包 - -您可以在 `kcl` 包的根目录下使用以下命令进行操作: - -在 `exist_kcl_package` 包的根目录下, 执行 - -```shell -kcl mod push oci://docker.io//exist_kcl_package -``` - -完成上述步骤后,您就成功地将您的 kcl 包 `exist_kcl_package` 推送到了 docker.io 中。 -关于如何使用 kcl mod push 的更多信息,请参阅 [kcl mod push](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/push)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/4-how-to/6-push_github_action.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/4-how-to/6-push_github_action.md deleted file mode 100644 index 2f18b66f..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/4-how-to/6-push_github_action.md +++ /dev/null @@ -1,83 +0,0 @@ -# 如何在 github action 中使用 kcl 包管理发布您的 KCL 包 - -本文将指导您如何在 GitHub Action 中使用 kcl 包管理将您的 kcl 包推送到发布到 ghcr.io 中。 - -## 步骤 1:安装 KCL CLI - -首先,您需要在您的计算机上安装 KCL CLI。您可以按照 [KCL CLI 安装文档](https://kcl-lang.io/zh-CN/docs/user_docs/getting-started/install)中的说明进行操作。 - -## 步骤 2:创建一个 GitHub 账号 - -如果您已经有 GitHub 帐号了,您可以选择跳过这一步 - -[注册新的一个 GitHub 账号](https://docs.github.com/zh/get-started/signing-up-for-github/signing-up-for-a-new-github-account) - -## 步骤 3: 为您的 KCL 包创建一个 GitHub 仓库并进行相关配置 - -### 1. 为您的 KCL 程序包准备仓库 - -您需要为您的 KCL 程序包准备一个 GitHub 仓库。 - -[创建一个 GitHub 仓库](https://docs.github.com/zh/get-started/quickstart/create-a-repo) - -在这个仓库中添加您的 KCL 程序,以仓库 https://github.com/awesome-kusion/catalog.git 为例, - -```bash -├── .github -│ └── workflows -│ └── push.yaml # github action 文件 -├── LICENSE -├── README.md -├── kcl.mod # kcl.mod 将当前仓库内容定义为一个 kcl 包 -├── kcl.mod.lock # kcl.mod.lock 是 kcl 包管理工具自动生成的文件 -└── main.k # 您的 KCL 程序 -``` - -### 2. 为您的仓库设置 OCI Registry,账户和密码 - -以 docker.io 为例,您可以为您的仓库设置 secrets `REG`, `REG_ACCOUNT` 和 `REG_TOKEN`。`REG` 的值为 `docker.io`,`REG_ACCOUNT` 的值为您的 docker.io 账户, `REG_TOKEN` 为您的 `docker.io` 登录密码。 - -[为仓库添加 secrets](https://docs.github.com/zh/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) - -如果您使用 `ghcr.io` 作为 `Registry`, 您需要使用 GitHub token 作为 secrets。 - -[创建一个 GitHub Token](https://docs.github.com/zh/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#personal-access-tokens-classic) - -## 步骤 4: 将您的 KCL 包添加到仓库中并编写 github action workflow - -为这个仓库添加 github action 文件 `.github/workflows/push.yml`,内容如下: - -```yaml -name: KPM Push Workflow - -on: - push: - branches: - - main - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Set up Go 1.21 - uses: actions/setup-go@v2 - with: - go-version: 1.21 - - - name: Install KCL CLI - run: go install kcl-lang.io/cli/cmd/kcl@latest - - - name: Login and Push - env: - # 通过环境变量指定 OCI Registry 和账户 - KPM_REG: ${{ secrets.REG }} - KPM_REPO: ${{ secrets.REG_ACCOUNT }} - # kcl registry login 时使用 secrets.REG_TOKEN - run: kcl registry login -u ${{ secrets.REG_ACCOUNT }} -p ${{ secrets.REG_TOKEN }} ${{ secrets.REG }} && kcl mod push - - - name: Run KCL project from oci registry - run: kcl run oci://${{ secrets.REG }}/${{ secrets.REG_ACCOUNT }}/catalog --tag 0.0.1 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/4-how-to/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/4-how-to/_category_.json deleted file mode 100644 index 370cb4e9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/4-how-to/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "如何使用", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/schema-definition.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/schema-definition.md deleted file mode 100644 index 735667b9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/schema-definition.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -title: "模型定义" -sidebar_position: 3 ---- - -## 简介 - -KCL 的核心场景是写配置和校验,因此 KCL 被设计之初的一个核心特性就是**建模**,对应到 KCL 的关键字 `schema`,`schema` 可以被用于定义结构和约束,比如字段的类型,默认值,字段的范围和各种其他约束等内容。此外,使用 KCL schema 定义的结构可以反过来用于验证实现、验证输入(JSON、YAML 等结构化数据)或生成代码(生成多语言结构体、OpenAPI 等)。 - -## 使用 KCL 定义结构和约束 - -### 0. 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. 获得示例 - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/definition -``` - -我们可以执行如下命令显示配置 - -```bash -cat main.k -``` - -输出为 - -```python -import .app_module # A relative path import - -app: app_module.App { - domainType = "Standard" - containerPort = 80 - volumes = [ - { - mountPath = "/tmp" - } - ] - services = [ - { - clusterIP = "None" - $type = "ClusterIP" - } - ] -} -``` - -我们将 `App` 模型放入单独的 `app_module.k` 中,在需要时我们可以在 `main.k` 中使用 `import` 关键字进行模块化管理,比如下面的文件结构 - -``` -. -├── app_module.k -└── main.k -``` - -其中 `app_module.k` 的内容为 - -```python -schema App: - domainType: "Standard" | "Customized" | "Global" - containerPort: int - volumes: [Volume] - services: [Service] - - check: - 1 <= containerPort <= 65535 - -schema Service: - clusterIP: str - $type: str - - check: - clusterIP == "None" if $type == "ClusterIP" - -schema Volume: - container: str = "*" # `container` 的默认值为 "*" - mountPath: str - - check: - mountPath not in ["/", "/boot", "/home", "dev", "/etc", "/root"] -``` - -在上面的文件中。在其中,我们使用 `schema` 关键字定义了三个模型 `App`,`Service` 和 `Volume`。并且 `App` 模型具有四个属性 `domainType`, `containerPort`, `volumes` 和 `services`,其中 - -- `domainType` 的类型为字符串字面值联合类型,与“枚举”类似,这表明 `domainType` 的值只能取 `"Standard"`, `"Customized"` 和 `"Global"` 中的一个 -- `containerPort` 的类型为整数 `int`, 此外我们使用 `check` 关键字定义了其取值范围 1 ~ 65535 -- `services` 的类型为 `Service` 列表类型,`Service`,并且我们用 `?` 标记了它是一个可选属性,这意味着我们可以不为其赋值。 -- `volumes` 的类型为 `Volume` 列表类型,并且我们用 `?` 标记了它是一个可选属性,这意味着我们可以不为其赋值。 - -### 2. 输出配置 - -我们可以使用如下命令行可以获得 `app` 实例的 YAML 输出 - -```shell -kcl main.k -``` - -输出为 - -```yaml -app: - domainType: Standard - containerPort: 80 - volumes: - - container: "*" - mountPath: /tmp - services: - - clusterIP: None - type: ClusterIP -``` - -## 小结 - -KCL 是一种用于定义配置和约束的语言,其核心功能是使用 schema 关键字进行建模,schema 允许定义具有属性、默认值、范围检查和其他约束的结构。使用 KCL schema 定义的结构可以用于验数据或生成代码。该文档演示了如何使用 schema 定义模型,使用 import 导入模型进行模块化管理,并使用 kcl 命令输出已定义结构实例的 YAML 配置。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/secret-management/1-vault.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/secret-management/1-vault.md deleted file mode 100644 index f070a784..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/secret-management/1-vault.md +++ /dev/null @@ -1,142 +0,0 @@ ---- -id: vault -sidebar_label: Vault ---- - -# Vault - -## 简介 - -This guide will show you that KCL solves the secret management problem by integrating [Vault](https://developer.hashicorp.com/vault) and [Vals](https://github.com/helmfile/vals). - -## 先决条件 - -- Install [KCL](/docs/user_docs/getting-started/install) -- Prepare a [Kubernetes Cluster](https://kubernetes.io/) -- Install [Vault](https://developer.hashicorp.com/vault/downloads) -- Install [Vals](https://github.com/helmfile/vals) - -## 具体步骤 - -### 1. 获得示例 - -We put the application source code and infrastructure deployment code in different repos, which can be maintained by different roles to achieve the separation of concerns. - -- Get the application code - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/secret-management/vault -``` - -- Show the config - -```shell -cat main.k -``` - -The output is - -```python -# Secret Management using Vault and Vals - -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" - annotations: { - "secret-store": "vault" - # Valid format: - # "ref+vault://PATH/TO/KV_BACKEND#/KEY" - "foo": "ref+vault://secret/foo#/foo" - "bar": "ref+vault://secret/bar#/bar" - } -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -The main.k file extends the configuration of the Nginx application and customizes annotations. Among them, the value of annotation `foo` and `bar` follow secret reference format (`ref+vault://PATH/TO/KV_BACKEND#/KEY`): - -- `ref+vault`: indicates that this is a secret reference, and the external storage service is `Vault`. -- `PATH/TO/KV_BACKEND`: specifies the path where a secret is stored. -- `KEY`: specifies the key to reading secret. - -The complete format is concatenated using a style similar to URI expressions, which can retrieve a secret stored externally. - -### 2. 预存敏感信息 - -Start the Vault Server - -```shell -vault server -dev -export VAULT_ADDR='http://127.0.0.1:8200' -# Note: Replace with your token -export VAULT_TOKEN=yourtoken -``` - -After Vault is started in development mode and unpacked, secrets are pre-stored, and the path and keys are consistent with `main.k`: - -```shell -vault kv put secret/foo foo=foo -vault kv put secret/bar bar=bar -``` - -### 3. 部署配置 - -Using the following command to apply the deployment manifest. - -```shell -kcl main.k | vals eval -f - | kubectl apply -f - -``` - -The expect output is - -```shell -deployment.apps/nginx created -``` - -### 4. 验证敏感信息 - -Next, verify that the secrets have been retrieved from Vault and replace the values of annotations of Nginx: - -- Verify the `foo` annotation - -```shell -kubectl get deploy nginx -o yaml | grep 'foo:' -``` - -The output is - -```yaml -foo: foo -``` - -- Verify the `bar` annotation - -```shell -kubectl get deploy nginx -o yaml | grep 'bar:' -``` - -The output is - -```yaml -bar: bar -``` - -So far, we have retrieved the secrets hosted in `Vault` and put them into use. - -## 小结 - -This guide introduces how KCL solves the secret management by integrating Vault and Vals. By following these steps, we can retrieve the secrets hosted in Vault and utilize them. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/validation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/validation.md deleted file mode 100644 index 2368ec22..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/validation.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: "校验" -sidebar_position: 2 ---- - -## 简介 - -验证是校验数据是否准确、可靠并满足某些要求或限制的过程,包括检查数据的完整性、一致性、准确性和相关性。进行数据验证是为了确保数据符合其预期目的,并能有效使用。 - -我们可以使用 KCL 及其校验工具手动或自动进行数据验证,以确保数据的一致性。 - -## 使用 KCL 校验数据 - -除了使用 KCL 代码生成 JSON/YAML 等配置格式,KCL 还支持对 JSON/YAML 数据进行格式校验。作为一种配置语言,KCL 在验证方面几乎涵盖了 OpenAPI 的所有功能。在 KCL 中可以通过一个结构定义来约束配置数据,同时支持通过 check 块自定义约束规则,在 schema 中书写校验表达式对 schema 定义的属性进行校验和约束。通过 check 表达式可以非常清晰简单地校验输入的 JSON/YAML 是否满足相应的 schema 结构定义与 check 约束。 - -### 0. 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. 获得示例 - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/validation -``` - -我们可以执行如下命令显示配置 - -```bash -cat schema.k -``` - -输出为 - -```python -schema User: - name: str - age: int - message?: str - data: Data - labels: {str:} - hc: [int] - - check: - age > 10, "age must > 10" - -schema Data: - id: int - value: str -``` - -在 schema 中,我们可以使用 `check` 关键字来编写每个 schema 属性的验证规则。`check` 块中的每一行都对应于一个条件表达式。当满足条件时,验证成功。条件表达式后面可以跟 `, "报错信息"`,以指示检查失败时要给用户显示的消息。 - -综上所述,KCL Schema 中支持的校验类型为: - -| 校验类型 | 使用方法 | -| -------- | ---------------------------------------------------------- | -| 范围校验 | 使用 `<`, `>` 等比较运算符 | -| 正则校验 | 使用 `regex` 系统库中的 `match` 等方法 | -| 长度校验 | 使用 `len` 内置函数,可以求 `list/dict/str` 类型的变量长度 | -| 枚举校验 | 使用字面值联合类型 | -| 非空校验 | 使用 schema 的可选/必选属性 | -| 条件校验 | 使用 check if 条件表达式 | - -### 2. 验证数据 - -新建一个名为 `data.json` 的 JSON 配置文件: - -```json -{ - "name": "Alice", - "age": 18, - "message": "This is Alice", - "data": { - "id": 1, - "value": "value1" - }, - "labels": { - "key": "value" - }, - "hc": [1, 2, 3] -} -``` - -执行如下命令获得校验结果 - -```bash -kcl-vet data.json schema.k -``` - -## 小结 - -KCL 是一种配置语言,通过其结构定义和用户定义的约束规则来支持数据验证。KCL Schema 中支持的验证类型包括范围、正则表达式、长度、枚举、可选/必需和条件。并且可以使用 KCL 验证工具或在此基础上构建的可视化产品来验证数据。 - -## 未来计划 - -KCL 校验能力的提升将逐渐围绕"静态化"方面展开工作,即在编译时,结合形式化验证的能力直接分析得出数据是否满足约束条件、约束条件是否冲突等结论,并且可以通过 IDE 实时透出约束错误,而无需在运行时发现错误。 - -我们还期望 KCL Schema 和约束可以作为一个包来管理(这个包只有 KCL 文件)。例如,Kubernetes 模型和约束可以开箱即用。用户可以生成配置或验证现有配置,并且可以通过 KCL 继承简单地扩展用户想要的模型和约束。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md deleted file mode 100644 index e674c946..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md +++ /dev/null @@ -1,249 +0,0 @@ ---- -title: "使用 KCL 生成并管理 Kubernetes 资源配置" -sidebar_position: 2 ---- - -## 简介 - -当我们管理 Kubernetes 资源清单时,我们常常会手写维护,或者使用 Helm 和 Kustomize 等工具来维护我们 YAML 配置或者配置模版,然后通过 kubectl 和 helm 命令行等工具将资源下发到集群。但是作为一个 "YAML 工程师" 每天维护 YAML 配置无疑是琐碎且无聊的,并且容易出错。 - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: ... # Omit -spec: - selector: - matchlabels: - cell: RZ00A - replicas: 2 - template: - metadata: ... # Omit - spec: - tolerations: - - effect: NoSchedules - key: is-over-quota - operator: Equal - value: 'true' - containers: - - name: test-app - image: images.example/app:v1 # Wrong ident - resources: - limits: - cpu: 2 # Wrong type. The type of cpu should be str - memory: 4Gi - # Field missing: ephemeral-storage - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: is-over-quota - operator: In - values: - - 'true' -``` - -- YAML 中的结构化数据是无类型的,缺乏验证方法,无法立即检查所有数据的有效性 -- YAML 编程能力欠佳,容易写出不正确的缩进,也没有逻辑判断等常见代码组织方式,容易写出大量重复配置,难以维护 -- Kubernetes 设计是复杂的,用户很难理解所有细节,比如上面配置中的 `toleration` 和 `affinity` 字段,如果用户不理解调度逻辑,它可能被错误地省略掉或者多余的添加 - -因此,KCL 期望在 Kubernetes YAML 资源管理解决如下问题: - -- 用**生产级高性能编程语言**以**编写代码**的方式提升配置的灵活度,比如条件语句、循环、函数、包管理等特性提升配置重用的能力 -- 在代码层面提升**配置语义验证**的能力,比如字段可选/必选、类型、范围等配置检查能力 -- 提供**配置分块编写、组合和抽象的能力**,比如结构定义、结构继承、约束定义等能力 - -## 先决条件 - -首先可以在 [KCL 快速开始](/docs/user_docs/getting-started/kcl-quick-start) 根据指导下载并安装 KCL,然后准备一个 [Kubernetes](https://kubernetes.io/) 环境 - -## 快速开始 - -### 1. 生成 Kubernetes 资源 - -我们可以编写如下 KCL 代码并命名为 main.k ,KCL 受 Python 启发,基础语法十分接近 Python, 比较容易学习和上手, 配置模式写法很简单,`k [: T] = v`, 其中 `k` 表示配置的属性名称; `v` 表示配置的属性值; `: T` 表示一个可选的类型注解。 - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -上述 KCL 代码中我们分别声明了一个 Kubernetes Deployment 资源的 `apiVersion`、`kind`、`metadata` 和 `spec` 等变量,并分别赋值了相应的内容,特别地,我们将 `metadata.labels` 字段分别重用在 `spec.selector.matchLabels` 和 `spec.template.metadata.labels` 字段。可以看出,相比于 YAML,KCL 定义的数据结构更加紧凑,而且可以通过定义局部变量实现配置重用。 - -我们可以执行如下命令行得到一个 Kubernetes YAML 文件 - -```bash -kcl main.k -``` - -输出为: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -当然我们可以将 KCL 工具与 kubectl 等工具结合使用,让我们执行如下命令并看看效果 - -```shell -kcl main.k | kubectl apply -f - -``` - -输出为 - -```shell -deployment.apps/nginx-deployment configured -``` - -可以从命令行的结果看出与我们使用直接使用 YAML 配置和 kubectl apply 的一个 Deployment 体验完全一致 - -通过 kubectl 检查部署状态 - -```shell -kubectl get deploy -``` - -输出为 - -```shell -NAME READY UP-TO-DATE AVAILABLE AGE -nginx-deployment 3/3 3 3 15s -``` - -### 2. 编写代码管理 Kubernetes 资源 - -对于 Kubernetes 资源发布时,我们常常会遇到配置参数需要动态指定的场景,比如不同的环境需要设置不同的 `image` 字段值生成不同环境的资源。对于这种场景,我们可以通过 KCL 的条件语句和 `option` 函数动态地接收外部参数。我们可以在上述例子的基础上根据不同的环境调整配置参数,比如对于如下代码,我们编写了一个条件语句并输入一个名为 `env` 的动态参数 - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" if option("env") == "prod" else "${metadata.name}:latest" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -使用 KCL 命令行 `-D` 标记接收一个外部设置的动态参数: - -```bash -kcl main.k -D env=prod -``` - -输出为: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -上述代码片段中的 `image = metadata.name + ":1.14.2" if option("env") == "prod" else metadata.name + ":latest"` 意思为:当动态参数 `env` 的值被设置为 `prod` 时,image 字段值为 `nginx:1.14.2`, 否则为 `nginx:latest`,因此我们可以根据需要为 env 设置为不同的值获得不同内容的 Kubernetes 资源。 - -并且 KCL 支持将 option 函数动态参数维护在配置文件中,比如编写下面展示的 `kcl.yaml` 文件 - -```yaml -kcl_options: - - key: env - value: prod -``` - -使用如下命令行也可以得到同样的 YAML 输出,以简化 KCL 动态参数的输入过程 - -```bash -kcl main.k -Y kcl.yaml -``` - -输出为: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## 小结 - -KCL 可以用于生成和管理 Kubernetes 资源,解决管理 YAML 配置的局限性,例如缺乏验证方法和较弱的编程能力等,并可以通过条件语句和 option 函数动态接收外部参数,从而能够根据不同的环境调整配置参数。此外,KCL 可以与 kubectl 等其他工具一起使用将配置一键生效到集群。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md deleted file mode 100644 index 5fe97d05..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: "Kubectl KCL 插件" -sidebar_position: 1 ---- - -## 简介 - -[Kubectl](https://kubernetes.io/docs/reference/kubectl/) is a command line tool for communicating with a Kubernetes cluster's control plane, using the Kubernetes API. You can use the `Kubectl-KCL-Plugin` to - -- Edit the YAML configuration in a hook way to separate data and logic for the Kubernetes manifests management. -- For multi-environment and multi-tenant scenarios, you can maintain these configurations gracefully rather than simply copy and paste. -- Validate all KRM resources using the KCL schema. - -## 前置条件 - -- Install [Kubectl](https://github.com/kubernetes/kubectl) -- Install [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) - -## 快速开始 - -Let’s write a KCL function which add annotation `managed-by=krm-kcl` only to `Deployment` resources in the helm chart. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/kubectl-kcl.git/ -cd ./kubectl-kcl/examples/ -``` - -### 2. Test and Run - -Run the KCL code via the `Kubectl KCL Plugin`. - -```bash -kubectl kcl run -f ./kcl-run.yaml -``` - -The output yaml is - -```yaml -apiVersion: config.kubernetes.io/v1 -kind: ResourceList -items: - - apiVersion: apps/v1 - kind: Deployment - metadata: - annotations: - managed-by: krm-kcl - labels: - app: nginx - name: nginx-deployment - spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - image: "nginx:1.14.2" - name: nginx - ports: - - containerPort: 80 - - apiVersion: v1 - kind: Service - metadata: - name: test - spec: - ports: - - port: 80 - protocol: TCP - targetPort: 9376 - selector: - app: MyApp -functionConfig: - # kcl-fn-config.yaml - apiVersion: krm.kcl.dev/v1alpha1 - kind: KCLRun - metadata: - # EDIT THE SOURCE! - # This should be your KCL code which preloads the `ResourceList` to `option("resource_list") - spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "krm-kcl"}} for resource in option("resource_list").items] -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md deleted file mode 100644 index 271f08e8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: "Helm KCL 插件" -sidebar_position: 2 ---- - -## 简介 - -[Helm](https://github.com/helm/helm) 是一个管理 Charts 的工具。Charts 是预配置的 Kubernetes 资源的包。您可以使用 `Helm-KCL-Plugin` 来完成以下操作: - -- 以 hook 的方式编辑 Helm charts,将数据和逻辑分离以便更好地管理 Kubernetes manifests -- 对于多环境和多租户方案,可以优雅地维护这些配置,而不仅仅是简单地复制和粘贴 -- 使用 KCL 模式验证所有 KRM 资源 - -## 先决条件 - -- 安装 [Helm](https://github.com/helm/helm) -- 安装 [Helm KCL 插件](https://github.com/kcl-lang/helm-kcl) - -## 快速开始 - -让我们编写一个仅向 `Deployment` 资源添加 annotation `managed-by=helm-kcl-plugin` 的 KCL 函数 - -### 1. 获取示例 - -```bash -git clone https://github.com/kcl-lang/helm-kcl.git/ -cd ./helm-kcl/examples/workload-charts-with-kcl -``` - -### 2. 测试和运行 - -通过 `Helm KCL Plugin` 运行KCL代码。 - -```bash -helm kcl template --file ./kcl-run.yaml -``` - -输出的YAML为 - -```yaml -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: workload - app.kubernetes.io/version: 0.1.0 - helm.sh/chart: workload-0.1.0 - name: workload -spec: - ports: - - name: www - port: 80 - protocol: TCP - targetPort: 80 - selector: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - type: ClusterIP ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: workload - app.kubernetes.io/version: 0.1.0 - helm.sh/chart: workload-0.1.0 - name: workload - annotations: - managed-by: helm-kcl-plugin -spec: - selector: - matchLabels: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - template: - metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - spec: - containers: - - image: nginx:alpine - name: frontend -``` - -## KCL 开发指南 - -以下是您可以在 KCL 代码中执行的操作: - -- 从 `option("resource_list")` 读取资源。`option("resource_list")` 符合 [KRM 函数规范](https://kpt.dev/book/05-developing-functions/01-functions-specification)。 你可以从 `option("resource_list")["items"]` 读取输入资源,并从 `option("resource_list")["functionConfig"]` 读取 `functionConfig`。 -- 返回输出资源的 KPM 列表。 -- 使用 `assert {condition},{error_message}` 返回错误消息。 - -## 更多文档和示例 - -- [Helm KCL 插件](https://github.com/kcl-lang/helm-kcl) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md deleted file mode 100644 index 4f1c8c56..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -title: "Kustomize KCL 插件" -sidebar_position: 3 ---- - -## 简介 - -[Kustomize](https://github.com/kubernetes-sigs/kustomize) 允许自定义用于多种目的原始的、无模板的 YAML 文件,同时保留原始 YAML 不变和可用。 - -KCL 可用于创建函数,以改变和/或验证 Kubernetes 资源模型(KRM)的 YAML 输入/输出格式,并且我们提供 Kustomize KCL 函数来简化函数编写过程。 - -## 先决条件 - -- 安装 [kustomize](https://github.com/kubernetes-sigs/kustomize) - -## 快速开始 - -让我们编写一个仅向 Deployment 资源添加 annotation `managed-by=kustomize-kcl` 的 KCL 函数 - -### 1. 获取示例 - -```bash -git clone https://github.com/kcl-lang/kustomize-kcl.git -cd ./kustomize-kcl/examples/set-annotation/ -``` - -### 2. 测试和运行 - -```bash -kustomize fn run ./local-resource/ --dry-run -``` - -输出的YAML为 - -```yaml -apiVersion: krm.kcl.dev/v1alpha1 -kind: KCLRun -metadata: - name: set-annotation - annotations: - config.kubernetes.io/function: | - container: - image: docker.io/kcllang/kustomize-kcl:v0.2.0 - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml -# EDIT THE SOURCE! -# This should be your KCL code which preloads the `ResourceList` to `option("resource_list") -spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "kustomize-kcl"}} for resource in option("resource_list").items] ---- -apiVersion: v1 -kind: Service -metadata: - name: test - annotations: - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml -spec: - selector: - app: MyApp - ports: - - protocol: TCP - port: 80 - targetPort: 9376 ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx - annotations: - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml - managed-by: kustomize-kcl -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## KCL 开发指南 - -以下是可以使用 KCL 执行的操作: - -- 从 `option("resource_list")` 读取资源。`option("resource_list")` 符合 [KRM 函数规范](https://kpt.dev/book/05-developing-functions/01-functions-specification)。 你可以从 `option("resource_list")["items"]` 读取输入资源,并从 `option("resource_list")["functionConfig"]` 读取 `functionConfig`。 -- 返回输出资源的 KPM 列表。 -- 使用 `assert {condition},{error_message}` 返回错误消息。 - -## 更多文档和示例 - -- [Kustomize KCL 插件](https://github.com/kcl-lang/kustomize-kcl) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md deleted file mode 100644 index 1981ae3d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: "KPT KCL SDK" -sidebar_position: 4 ---- - -## 简介 - -[kpt](https://github.com/GoogleContainerTools/kpt) 是一个以包为中心的工具链,可实现配置原地编辑、自动化和交付,通过将声明性配置作为数据进行操作,从而简化 Kubernetes 平台和 KRM 驱动的基础设施(例如,Config Connector、Crossplane)的大规模管理,以实现 Kubernetes 配置编辑的自动化包括转换和验证。 - -KCL 可用于创建函数来转换和/或验证 YAML Kubernetes 资源模型 (KRM) 输入/输出格式,但我们提供 KPT KCL SDK 来简化函数编写过程。 - -## 先决条件 - -- 安装 [kpt](https://github.com/GoogleContainerTools/kpt) -- 安装 [Docker](https://www.docker.com/) - -## 快速开始 - -让我们编写一个仅向 Deployment 资源添加 annotation `managed-by=kpt` 的 KCL 函数 - -### 1. 获取示例 - -```bash -git clone https://github.com/kcl-lang/kpt-kcl-sdk.git/ -cd ./kpt-kcl-sdk/get-started/set-annotation -``` - -### 2. 显示 KRM - -```bash -kpt pkg tree -``` - -输出为 - -```bash -set-annotation -├── [kcl-fn-config.yaml] KCLRun set-annotation -└── data - ├── [resources.yaml] Deployment nginx-deployment - └── [resources.yaml] Service test -``` - -### 3. 显示和更新 KCL `FunctionConfig` - -```bash -cat ./kcl-fn-config.yaml -``` - -输出为 - -```yaml -# kcl-fn-config.yaml -apiVersion: krm.kcl.dev/v1alpha1 -kind: KCLRun -metadata: # kpt-merge: /set-annotation - name: set-annotation -spec: - # 编辑此源代码 - # 您在此的 KCL 代码将 `ResourceList` 预加载到 `option("resource_list")` - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "kpt"}} for resource in option("resource_list").items] -``` - -### 4. 测试和运行 - -通过 kpt 运行 KCL 代码 - -```bash -kpt fn eval ./data -i docker.io/kcllang/kpt-kcl:v0.2.0 --fn-config kcl-fn-config.yaml - -# 验证 annotation 是否添加到 `Deployment` 资源并且其他资源 `Service` 没有这个 annotation。 -cat ./data/resources.yaml | grep annotations -A1 -B0 -``` - -输出为 - -```bash - annotations: - managed-by: kpt -``` - -可以看出,我们确实成功添加了 `managed-by=kpt` 标签 - -## 更多文档和示例 - -- [KPT KCL SDK](https://github.com/kcl-lang/kpt-kcl-sdk) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/index.md deleted file mode 100644 index 8d6340de..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/index.md +++ /dev/null @@ -1 +0,0 @@ -# Kubernetes diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-konfig/4-best-practice.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-konfig/4-best-practice.md deleted file mode 100644 index c4bf4b08..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-konfig/4-best-practice.md +++ /dev/null @@ -1,271 +0,0 @@ ---- -id: practice -sidebar_label: 最佳实践 ---- - -# 最佳实践 - -本文档旨在讲解新的业务模型接入 Konfig 大库以及 KCL 代码模型设计与编写的最佳实践,新业务模型一般采用前-后端模型分离的最佳实践进行设计与抽象,区分前端模型和后端模型的直接目的是将「用户界面」和「模型实现」进行分离,实现用户友好的简单的配置界面以及自动化配置增删改查接口。 - -## 工作流程 - -![](/img/docs/user_docs/guides/konfig/workflow.png) - -1. 首先使用 KCL OpenAPI 工具生成下游所需配置的 KCL 模型代码,对于 Kubernetes 模型;可以根据 CRD 或者 Swagger Model 生成,对于其他场景,可以使用 Terraform provider schema、Java Class 或者 Go Struct 生成相应 KCL Schema (建设中),作为后端模型并存放在 "基础配置代码" 中; -2. 使用 KCL 开发工具(包括 KCL 编译器、KCL format,doc,lint,test 等工具和 IDE 插件等),根据业务语义抽象前端模型; -3. 依据 Project & Stack 方式在 Konfig 仓库中组织用户侧配置代码(主要是对前端模型的实例化),Konfig 会自动根据 project.yaml 和 stack.yaml 文件进行测试; -4. 最后编译 KCL 代码生成 YAML,通过测试后,利用 CI/CD 流程完成配置的 diff 与分发。 - -## 模型结构 - -正如 web 应用会提供友好的用户界面,而在应用的后端对用户输入进行进一步推演得到最终落库的数据,类似地,使用 KCL 进行模型设计时同样遵循前后端分离的逻辑。此外当下游所需的数据内容发生变化时,我们仅需修改用户配置数据到后端模型的渲染/逻辑即可,从而避免了大规模修改用户配置的情况。以应用服务的 sidecar 配置为例,直接暴露给用户的只有 `user_sidecar_feature_gates`,而最终交给下游处理的数据中,则应是把 `user_sidecar_feature_gates` 作为 `sidecars` 配置的一部分包装起来的结果。比如如下代码: - -```python -# 用户可配的: -user_sidecar_feature_gates: str - -# 下游能处理的: -sidecars = [ - { - name = "sidecar_name" # sidecars 参数的额外模版参数,用户不需要进行配置 - feature_gates = user_sidecar_feature_gates - } -] -``` - -## Konfig 建模的一些最佳实践 - -### 使用一个属性代替配置模板 - -对于一些后端模型所需要填写的配置字段往往是大而全的设计,需要用户主动输入较为复杂的配置模版,并且不同用户对于该字段的填写内容基本一致,比如在下面示出的超卖逻辑的配置就需要用户填写大量的模板数据,心智成本较高。 - -对于此类常用复杂的模板一个简单的最佳实践是在前端模型中抽象为一个简单的 bool 类型的变量 overQuota,让用户做选择题而不是填空题,比如当 overQuota 变量为 True 时,后端模型才会渲染这个复杂逻辑。 - -- 前端模型属性 `overQuota` - -```python -overQuota: bool -``` - -- 后端模型 YAML 输出 - -```yaml -spec: - template: - spec: - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: k8s/is-over-quota - operator: In - values: - - "true" -``` - -此外也可以根据具体的业务场景设计不同的模版名称来填空,比如如下所示的代码设计一个属性 template 来辅助用户做模版的选择而不是直接填入模板内容。合法的 template 值可以为 "success_ratio" 或者 "service_cost", 当后端模型扩展更多的模版时,前端代码无需作出任何修改,仅需在后端模型中适配相应模板逻辑即可。 - -```python -schema SLI: - template: str = "success_ratio" -``` - -此外,尽量不采用复杂的结构直接作为前端模型属性,避免用户使用该模型时需要借助过多的 KCL 语法特性(比如解包、循环等特性)或者书写很多临时变量完成该结构的实例化。 - -### 使用字面值类型和联合类型 - -在上述小节提到了可以使用一个字符串属性表示不同的模板名称,更进一步地是可以使用字面值类型表述 template 可选的内容,比如可以进行如下改进。 - -```python -schema SLI: - template: "success_ratio" | "service_cost" = "success_ratio" -``` - -其中 template 的类型为两个字符串类型的联合,表示 template 只能为 "success_ratio" 或者 "service_cost",当用户填写了其他字符串的值时,KCL 编译器会进行报错。 - -除了对字面值类型使用联合类型外,KCL 还支持对复杂类型如 schema 类型的联合。对于这种后端 oneof 配置的支持,KCL 内置了复合结构的联合类型进行支持。比如我们可以针对多种种场景定义自己的 SLI 前端类型:CustomSliDataSource,PQLSLIDataSource 和 StackSLIDataSource。 - -```python -schema CustomSLIDataSource: - customPluginUrl: str - -schema PQLSLIDataSource: - total?: str - error?: str - success?: str - cost?: str - count?: str - -schema StackSLIDataSource: - stack: str - groupBy?: str - metric?: str - -# Simplify type definitions using type aliases -type DataSource = CustomSLIDataSource | PQLSLIDataSource | StackSLIDataSource - -schema DataConfiguration: - sources: {str: DataSource} -``` - -这样前端模型设计的好处是编译器可以静态地检查出用户书写的类型只能是某一种类型,如果直接使用后端模型无法从模型上直接获得不同类型 type 与需要填写字段的映射关系。 - -此外,前端模型的整体设计上也应该考虑横向扩展性,尽可能地采用联合类型,充分利用代码化的优势,避免对接不同后端或者后端模型发生改变时带来不必要的大量代码前端代码与用户代码重构与修改。此外,对于其他 GPL 语言中常用的工厂模式,在 KCL 中也可以使用联合类型代替,比如想要根据某个字符串内容获得某个类型的构造函数,可以直接使用联合类型进行优化。 - -KCL 中书写工厂模式 - -```python -schema DataA: - id?: int = 1 - value?: str = "value" - -schema DataB: - name?: str = "DataB" - -_dataFactory: {str:} = { - DataA = DataA - DataB = DataB -} -dataA = _dataFactory["DataA"]() -dataB = _dataFactory["DataB"]() -``` - -使用联合类型替换工厂模式 - -```python -schema DataA: - id?: int = 1 - value?: str = "value" - -schema DataB: - name?: str = "DataB" - -# 直接使用联合类型即可 -dataA: DataA | DataB = DataA() -dataB: DataA | DataB = DataB() -``` - -### 列表/数组属性字典化 - -为了便于作配置的原地修改或者程序自动化查询修改,尽量将列表/数组属性定义为字典类型方便索引,因为在大部分配置场景对于复杂结构的列表类型,列表的索引 0, 1, 2, ..., n 不具备任何业务含义,列表中元素的顺序对该列表配置无任何影响,此时采用字典类型而不是列表类型更方便数据的查询与修改。首先以一个简单例子举例: - -```python -schema Person: - name: str - age: int - -schema House: - persons: [Person] - -house = House { - persons = [ - Person { - name = "Alice" - age = 18 - } - Person { - name = "Bob" - age = 10 - } - ] -} -``` - -比如在上述例子中,想要查询 name 为 "Alice" 的年龄 age, 就需要在 house.persons 这个列表中作遍历才能很查询到 Alice 的 age。而将 persons 定义为如下代码所示的字典,不仅从代码上看起来更加简洁,并且可以通过 house.persons.Alice.age 直接获得 Alice 的 age,并且整个配置的信息完整且无冗余信息。 - -```python -schema Person: - age: int - -schema House: - persons: {str: Person} # 将 persons 定义为字典而不是数组 - -house = House { - persons = { - Alice = Person { age = 18 } - Bob = Person { age = 10 } - } -} -``` - -### 为模型书写校验表达式 - -对于前端模型,往往需要对用户填写的字段进行校验,此时可以使用 KCL 的 check 表达式与 KCL 的内置函数/语法/系统库进行配合对字段进行校验。对于前端模型的校验尽可能直接书写在前端模型的定义中进行校验前置,避免错误传递到后端模型中发生意想不到的错误。 - -使用 all/any 表达式与 check 表达式进行校验 - -```python -import regex - -schema ConfigMap: - name: str - data: {str:str} - configMounts?: [ConfigMount] - - check: - all k in data { - regex.match(k, r"[A-Za-z0-9_.-]*") - }, "a valid config key must consist of alphanumeric characters, '-', '_' or '.'" - -schema ConfigMount: - containerName: str - mountPath: str - subPath?: str - - check: - ":" not in mountPath, "mount path must not contain ':'" -``` - -### 使用数值单位类型 - -KCL 中带单位的数字具有一个内置的类型 units.NumberMultiplier, 不允许进行任意四则运算。 - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -x0: NumberMultiplier = 1M # Ok -x1: NumberMultiplier = x0 # Ok -x2 = x0 + x1 # Error: unsupported operand type(s) for +: 'number_multiplier(1M)' and 'number_multiplier(1M)' -``` - -可以使用 `int()/float()` 函数和 `str()` 函数将数字单位类型转换为整数类型或者字符串类型,产生的字符串保留原有数字单位类型的单位。 - -```python -a: int = int(1Ki) # 1024 -b: str = str(1Mi) # "1Mi" -``` - -对于在 Konfig 中的 Kubernetes Resource 资源相关的定义均可使用数值单位类型进行书写 - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -schema Resource: - cpu?: NumberMultiplier | int = 1 - memory?: NumberMultiplier = 1024Mi - disk?: NumberMultiplier = 10Gi - epchygontee?: int -``` - -### 前端模型实例的自动化修改 - -在 KCL,可以通过命令行和 API 界面实现对前端模型实例的自动化修改,比如想要修改某个应用(Konfig Stack Path: appops/nginx-example/dev)配置的镜像内容,可以直接执行如下指令修改镜像 - -```python -kcl -Y kcl.yaml ci-test/settings.yaml -o ci-test/stdout.golden.yaml -d -O :appConfiguration.image=\"test-image-v1\" -``` - -更多与自动化相关的使用文档请参考 [自动化](/docs/user_docs/guides/automation) 一节 - -### 为模型添加代码注释 - -为便于用户理解以及模型文档自动生成,需要对定义的模型编写注释,注释内容一般包括模型的解释,模型字段的解释,类型,默认值,使用样例等。详细的 KCL Schema 代码注释编写规范以及模型文档自动生成可以参考 [KCL 文档规范](/docs/tools/cli/kcl/docgen) - -## 后端模型 - -后端模型是「模型实现」,主要包括将前端模型映射为后端模型的逻辑代码。当编写完成前端模型后,我们可以使用前端模型 Schema 新建前端模型的实例 instance 并编写相应的后端映射/渲染代码将这些前端 instance 转换为后端模型,并且利用 KCL 多文件编译和 `Schema.instances()` 函数可以做到前端代码和后端代码的高度解耦,用户仅需关心前端的配置而不感知模型复杂的校验、逻辑判断等代码。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-kusion/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-kusion/index.md deleted file mode 100644 index 2906ab83..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-kusion/index.md +++ /dev/null @@ -1,15 +0,0 @@ -# KusionStack - -**KusionStack 是开源的云原生可编程技术栈!** - -KusionStack 是一个可编程、高灵活性的应用交付及运维技术栈,灵感源于融合(Fusion)一词,旨在帮助企业构建的应用运维配置管理平面及 DevOps 生态。 - -1. 融合**专有云**,**混合云**,**多云**混合场景 -2. 融合以**云原生技术**为主,同时采用**多种平台技术**的混合平台技术选型 -3. 融合**多项目**、**多团队**、**多角色**、**多租户**、**多环境**的企业级诉求 - -基于 Platform as Code (平台服务即代码)理念,研发者可以快速收敛围绕**应用运维生命周期**的全量配置定义,面向**混合技术体系及云环境**,完成从应用运维研发到上线的**端到端工作流程**,真正做到**一处编写,随处交付**。 - -![](/img/docs/user_docs/intro/kusion-stack-1.png) - -更多文档请参考: [https://kusionstack.io/](https://kusionstack.io/) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/support/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/support/_category_.json deleted file mode 100644 index d670513b..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/support/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "常见问答", - "position": 6 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/support/faq-cli.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/support/faq-cli.md deleted file mode 100644 index 035c021c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/support/faq-cli.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -sidebar_position: 4 ---- - -# 命令行工具 - -## 1. Konfig 大库应用目录下的 settings.yaml 文件的作用是什么? - -KCL 中 settings.yaml 文件表示 KCL 命令行工具的配置参数文件,可以将编译的配置放入其中进行调用比如需要编译的文件,需要输入的 option 动态参数 `-d`,是否需要忽略掉空值 None `-n` 等配置。 - -比如对于如下的命令行运行参数 - -```shell -kcl main.k -D key=value -n -r -``` - -就可以使用如下的命令行参数和 settings.yaml 配置文件代替 - -```shell -kcl -Y settings.yaml -``` - -settings.yaml - -```yaml -kcl_cli_configs: - files: - - main.k - disable_none: true - strict_range_check: true -kcl_options: - - key: key - value: value -``` - -- `kcl_cli_configs` 表示可以配置的编译参数,`file` 用于配置编译的 KCL 文件,`disable_none` 表示是否使用 `-n` 参数,`strict_range_check` 表示是否使用 `-r` 参数。 -- `kcl_options` 表示可以配置的动态参数,`key` 表示动态参数的名称,`value` 表示动态参数的值 - -注意:settings.yaml 的文件名称可替换,只要其中的配置结构满足规定即可 - -## 2. 如何传入动态参数?如何在代码中获取命令行传入的动态参数? - -KCL 支持多种方式传入动态参数 - -- `-D`: 使用 KCL 命令行的-D 参数可以直接传入动态参数,支持基本数据类型 str/int/float/bool, 以及结构数据类型 list/dict - -```shell -kcl main.k -D env-type=TEST -D deploy-topology='[{"cluster":"my-cluster","idc":"my-idc","replicas":2,"workspace":"my-idc","zone":"my-zone"}]' -``` - -- `-Y`: 使用 KCL 命令行的-Y 参数可以间接通过配置文件传入动态参数: - -```yaml -kcl_options: - - key: env-type - value: TEST - - key: deploy-topology - value: - - cluster: my-cluster - idc: my-idc - replicas: 2 - workspace: my-workspace - zone: my-zone -``` - -在代码中使用内置的 option 函数获取即可 - -```python -env = option("env-type") -deploy_topology = option("deploy-topology") -``` - -输出 YAML - -```yaml -env: TEST -deploy_topology: - - cluster: my-cluster - idc: my-idc - replicas: 2 - workspace: my-workspace - zone: my-zone -``` - -## 3. 如何使用 kcl 的多文件编译特性? - -- 使用 KCL 命令行工具直接书写多文件编译 - -```shell -kcl file1.k file2.k file3.k -``` - -- 在配置文件中配置并配合 KCL 命令行工具参数 `-Y` 使用 - -settings.yaml - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - - file3.k -``` - -```shell -kcl -Y settings.yaml -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/support/faq-yaml.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/support/faq-yaml.md deleted file mode 100644 index 4dd12c00..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/support/faq-yaml.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -sidebar_position: 3 ---- - -# YAML 语法 - -## 1. YAML 字符串使用单引号和双引号的区别是什么? - -- YAML 双引号字符串是唯一能够表达任意字符串的样式,通过使用 `\` 转义字符,比如使用 `\"` 转义双引号 `"`,使用 `\\` 转义反斜杠 `\`,并且可以使用单个反斜杠 `\` 作为双引号字符串的续行符 -- YAML 单引号字符串与 YAML 双引号字符串不同的是可以自由地使用 `\` 和 `"` 而不需要转义,但是使用两个单引号 `''` 转义单引号 `'` 字符 - -比如对于如下的例子,三个字符串变量的内容是相同的 - -```yaml -string1: 'here '' s to "quotes"' -string2: 'here''s to "quotes"' -string3: here's to "quotes" -``` - -因此,KCL 输出 YAML 字符串的策略是当字符串内容出现单引号时,优先输出无引号字符串或双引号字符串,其他情况输出单引号字符串以避免理解上的负担。 - -更多细节可参考: [YAML 规范 v1.2](https://yaml.org/spec/1.2.1/) - -## 2. YAML 中出现的 | - + > 等符号是什么含义? - -在使用 KCL 多行字符串(使用三引号括起来的字符串),输出的 YAML 经常会携带一些特殊的记号,如 `|`,`-`,`+` 和 `>` 等,这些记号通常为 YAML 多行字符串的表示方法,比如对于如下 KCL 代码: - -```python -data = """This is a KCL multi line string (the first line) -This is a KCL multi line string (the second line) -This is a KCL multi line string (the third line) - - -""" -var = 1 -``` - -输出 YAML 为: - -```yaml -data: |+ - This is a KCL multi line string (the first line) - This is a KCL multi line string (the second line) - This is a KCL multi line string (the third line) - - -var: 1 -``` - -- `|` 表示**块字符串样式**,用于表示一个多行字符串,其中的所有换行符都表示字符串真实的换行; -- `>` 表示**块折叠样式**,在其中所有的换行符将被空格替换; -- `+` 和 `-` 用于控制在字符串末尾使用换行符的情况。默认情况为字符串末尾保留单个换行符,如果要删除所有换行符,可以在样式指示符 `|` 或 `>` 后面放置一个 `-` 来完成,如果要保留末尾的换行符,则需要在 `|` 或 `>` 后面放置一个 `+` - -更多细节可参考: [YAML 多行字符串](https://yaml-multiline.info/) 和 [YAML 规范 v1.2](https://yaml.org/spec/1.2.1/) - -## 3. YAML 中在 | - + > 等符号之后出现的数字是什么含义? - -数字表示 YAML 当中的**显式缩进指示符**。对于 YAML 中的长字符串,YAML 通常第一个非空行确定字符串的缩进级别,而当第一个非空行前面具有非前导字符时,比如换行符,YAML 要求必须使用**显式缩进指示符**来指定内容的缩进级别,比如 `|2` 和 `|1` 等 - -比如对于如下 KCL 代码: - -```python -longStringStartWithNewline = """ -This is the second line -This is the third line -""" - -``` - -```yaml -longStringStartWithNewline: |2 - - This is the second line - This is the third line -``` - -如果不需要长字符串开头的空行或换行符,则可以以如下两种方式进行 KCL 长字符串书写 - -- 长字符串从第 1 行开始书写 - -```python -longString = """This is the second line -This is the third line -""" -``` - -- 使用续行符 - -```python -longString = """\ -This is the second line -This is the third line -""" -``` - -以上两种方式输出的 YAML 均为: - -```yaml -longString: | - This is the second line - This is the third line -``` - -更多细节可参考: [YAML 规范 v1.2](https://yaml.org/spec/1.2.1/) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/support/support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/support/support.md deleted file mode 100644 index 648ee5a3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/support/support.md +++ /dev/null @@ -1,3 +0,0 @@ -# 常见问答 - -KCL 安装、使用过程中遇到的常见问题,包括基本概念解释、KCL 语法、KCL 语言设计、命令行工具和 YAML 等常见问题。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/contribute/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/contribute/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/contribute/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/contribute/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/contribute/contribute-code.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/contribute/contribute-code.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/contribute/contribute-code.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/contribute/contribute-code.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/contribute/contribute-docs.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/contribute/contribute-docs.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/contribute/contribute-docs.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/contribute/contribute-docs.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/contribute/contribute.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/contribute/contribute.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/contribute/contribute.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/contribute/contribute.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/contribute/git-guideline.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/contribute/git-guideline.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/contribute/git-guideline.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/contribute/git-guideline.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/intro/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/intro/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/intro/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/intro/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/intro/intro.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/intro/intro.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/intro/intro.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/intro/intro.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/intro/license.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/intro/license.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/intro/license.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/intro/license.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/intro/support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/intro/support.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/intro/support.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/intro/support.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/release-policy/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/release-policy/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/release-policy/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/release-policy/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/release-policy/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/release-policy/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/release-policy/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/release-policy/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/release-policy/kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/release-policy/kcl.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/release-policy/kcl.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/release-policy/kcl.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/release-policy/roadmap.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/release-policy/roadmap.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/community/release-policy/roadmap.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/community/release-policy/roadmap.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/cheatsheets/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/cheatsheets/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/cheatsheets/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/cheatsheets/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/cheatsheets/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/cheatsheets/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/cheatsheets/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/cheatsheets/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/codelab/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/codelab/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/codelab/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/codelab/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/codelab/collaborative.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/codelab/collaborative.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/codelab/collaborative.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/codelab/collaborative.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/codelab/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/codelab/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/codelab/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/codelab/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/codelab/schema.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/codelab/schema.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/codelab/schema.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/codelab/schema.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/codelab/simple.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/codelab/simple.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/codelab/simple.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/codelab/simple.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/error/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/error/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/error/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/error/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/error/_error.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/error/_error.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/error/_error.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/error/_error.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/error/exception.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/error/exception.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/error/exception.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/error/exception.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/error/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/error/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/error/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/error/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/spec/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/spec/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/spec/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/spec/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/spec/codestyle.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/spec/codestyle.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/spec/codestyle.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/spec/codestyle.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/spec/datatypes.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/spec/datatypes.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/spec/datatypes.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/spec/datatypes.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/spec/error.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/spec/error.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/spec/error.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/spec/error.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/spec/expressions.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/spec/expressions.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/spec/expressions.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/spec/expressions.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/spec/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/spec/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/spec/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/spec/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/spec/kcl-spec.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/spec/kcl-spec.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/spec/kcl-spec.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/spec/kcl-spec.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/spec/lexical.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/spec/lexical.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/spec/lexical.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/spec/lexical.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/spec/modules.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/spec/modules.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/spec/modules.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/spec/modules.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/spec/schema.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/spec/schema.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/spec/schema.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/spec/schema.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/spec/statements.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/spec/statements.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/spec/statements.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/spec/statements.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/spec/variables.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/spec/variables.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/spec/variables.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/spec/variables.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/tour.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/tour.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/tour.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/tour.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/types/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/types/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/types/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/types/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/types/types.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/types/types.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/lang/types/types.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/lang/types/types.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/base64.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/base64.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/base64.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/base64.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/builtin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/builtin.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/builtin.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/builtin.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/crypto.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/crypto.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/crypto.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/crypto.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/datetime.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/datetime.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/datetime.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/datetime.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/json.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/json.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/json.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/json.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/manifests.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/manifests.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/manifests.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/manifests.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/math.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/math.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/math.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/math.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/net.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/net.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/net.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/net.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/overview.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/overview.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/regex.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/regex.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/regex.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/regex.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/units.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/units.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/model/units.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/units.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/yaml.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/yaml.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/model/yaml.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/model/yaml.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/plugin/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/plugin/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/plugin/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/plugin/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/plugin/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/plugin/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/plugin/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/plugin/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/plugin/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/plugin/overview.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/plugin/overview.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/plugin/overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/plugin/project_context.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/plugin/project_context.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/plugin/project_context.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/plugin/project_context.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/xlang-api/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/xlang-api/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/xlang-api/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/xlang-api/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/xlang-api/go-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/xlang-api/go-api.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/xlang-api/go-api.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/xlang-api/go-api.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/xlang-api/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/xlang-api/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/xlang-api/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/xlang-api/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/xlang-api/java-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/xlang-api/java-api.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/xlang-api/java-api.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/xlang-api/java-api.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/xlang-api/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/xlang-api/overview.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/xlang-api/overview.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/xlang-api/overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/xlang-api/python-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/xlang-api/python-api.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/xlang-api/python-api.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/xlang-api/python-api.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/xlang-api/rest-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/xlang-api/rest-api.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/xlang-api/rest-api.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/reference/xlang-api/rest-api.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/Ide/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/Ide/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/Ide/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/Ide/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/Ide/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/Ide/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/Ide/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/Ide/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/Ide/intellij.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/Ide/intellij.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/Ide/intellij.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/Ide/intellij.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/Ide/neovim.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/Ide/neovim.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/tools/Ide/neovim.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/Ide/neovim.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/Ide/vs-code.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/Ide/vs-code.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/Ide/vs-code.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/Ide/vs-code.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/kcl/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/kcl/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/kcl/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/kcl/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/kcl/docgen.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/kcl/docgen.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/kcl/docgen.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/kcl/docgen.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/kcl/fmt.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/kcl/fmt.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/kcl/fmt.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/kcl/fmt.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/kcl/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/kcl/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/kcl/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/kcl/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/kcl/lint.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/kcl/lint.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/kcl/lint.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/kcl/lint.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/kcl/overview.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/overview.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/kcl/overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/kcl/test.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/kcl/test.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/kcl/test.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/kcl/test.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/kcl/vet.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/kcl/vet.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/kcl/vet.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/kcl/vet.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/openapi/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/openapi/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/openapi/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/openapi/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/openapi/crd-to-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/openapi/crd-to-kcl.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/openapi/crd-to-kcl.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/openapi/crd-to-kcl.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/openapi/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/openapi/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/openapi/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/openapi/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/openapi/openapi-to-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/openapi/openapi-to-kcl.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/openapi/openapi-to-kcl.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/openapi/openapi-to-kcl.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/openapi/quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/openapi/quick-start.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/openapi/quick-start.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/openapi/quick-start.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/openapi/spec.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/openapi/spec.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/tools/cli/openapi/spec.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/openapi/spec.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/package-management/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/cli/package-management/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/package-management/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/command-reference/1.init.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/package-management/command-reference/1.init.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/command-reference/1.init.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/package-management/command-reference/1.init.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/command-reference/10.help.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/package-management/command-reference/10.help.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/command-reference/10.help.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/package-management/command-reference/10.help.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/command-reference/2.add.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/package-management/command-reference/2.add.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/command-reference/2.add.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/package-management/command-reference/2.add.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/command-reference/3.pkg.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/package-management/command-reference/3.pkg.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/command-reference/3.pkg.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/package-management/command-reference/3.pkg.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/command-reference/4.metadata.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/package-management/command-reference/4.metadata.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/command-reference/4.metadata.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/package-management/command-reference/4.metadata.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/command-reference/5.run.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/package-management/command-reference/5.run.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/command-reference/5.run.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/package-management/command-reference/5.run.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/command-reference/6.login.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/package-management/command-reference/6.login.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/command-reference/6.login.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/package-management/command-reference/6.login.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/command-reference/7.logout.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/package-management/command-reference/7.logout.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/command-reference/7.logout.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/package-management/command-reference/7.logout.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/command-reference/8.push.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/package-management/command-reference/8.push.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/command-reference/8.push.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/package-management/command-reference/8.push.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/command-reference/9.pull.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/package-management/command-reference/9.pull.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/command-reference/9.pull.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/package-management/command-reference/9.pull.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/command-reference/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/package-management/command-reference/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/command-reference/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/package-management/command-reference/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/command-reference/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/package-management/command-reference/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/reference/package-management/command-reference/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/tools/cli/package-management/command-reference/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/concepts/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/concepts/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/concepts/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/concepts/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/concepts/concepts.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/concepts/concepts.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/concepts/concepts.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/concepts/concepts.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/concepts/package-and-module.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/concepts/package-and-module.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/concepts/package-and-module.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/concepts/package-and-module.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/concepts/type-and-definition.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/concepts/type-and-definition.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/concepts/type-and-definition.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/concepts/type-and-definition.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/getting-started/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/getting-started/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/getting-started/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/getting-started/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/getting-started/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/getting-started/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/getting-started/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/getting-started/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/getting-started/install.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/getting-started/install.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/getting-started/install.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/getting-started/install.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/getting-started/intro.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/getting-started/intro.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/getting-started/intro.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/getting-started/intro.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/getting-started/kcl-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/getting-started/kcl-quick-start.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/getting-started/kcl-quick-start.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/getting-started/kcl-quick-start.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/abstraction.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/abstraction.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/abstraction.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/abstraction.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/automation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/automation.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/automation.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/automation.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/ci-integration/1-github-actions.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/ci-integration/1-github-actions.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/ci-integration/1-github-actions.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/ci-integration/1-github-actions.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/ci-integration/_2-gitlab-ci.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/ci-integration/_2-gitlab-ci.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/ci-integration/_2-gitlab-ci.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/ci-integration/_2-gitlab-ci.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/ci-integration/_3-jenkins-ci.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/ci-integration/_3-jenkins-ci.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/ci-integration/_3-jenkins-ci.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/ci-integration/_3-jenkins-ci.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/ci-integration/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/ci-integration/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/ci-integration/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/ci-integration/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/configuration.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/configuration.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/configuration.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/configuration.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/data-integration.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/data-integration.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/data-integration.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/data-integration.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/gitops/1-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/gitops/1-quick-start.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/gitops/1-quick-start.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/gitops/1-quick-start.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/gitops/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/gitops/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/gitops/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/gitops/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/package-management/1-overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/package-management/1-overview.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/package-management/1-overview.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/package-management/1-overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/package-management/2-installation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/package-management/2-installation.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/package-management/2-installation.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/package-management/2-installation.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/package-management/3-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/package-management/3-quick-start.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/package-management/3-quick-start.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/package-management/3-quick-start.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/package-management/4-how-to/6-push_github_action.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/package-management/4-how-to/6-push_github_action.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/package-management/4-how-to/6-push_github_action.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/package-management/4-how-to/6-push_github_action.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/package-management/4-how-to/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/package-management/4-how-to/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/package-management/4-how-to/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/package-management/4-how-to/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/package-management/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/package-management/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/package-management/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/schema-definition.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/schema-definition.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/schema-definition.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/schema-definition.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/secret-management/1-vault.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/secret-management/1-vault.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/secret-management/1-vault.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/secret-management/1-vault.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/secret-management/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/secret-management/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/secret-management/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/secret-management/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/validation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/validation.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/validation.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/validation.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-k8s/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-k8s/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-k8s/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-k8s/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-k8s/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-k8s/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-k8s/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-k8s/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-konfig/1-overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-konfig/1-overview.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-konfig/1-overview.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-konfig/1-overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-konfig/2-structure.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-konfig/2-structure.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-konfig/2-structure.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-konfig/2-structure.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-konfig/3-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-konfig/3-quick-start.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-konfig/3-quick-start.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-konfig/3-quick-start.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-konfig/4-best-practice.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-konfig/4-best-practice.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-konfig/4-best-practice.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-konfig/4-best-practice.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-konfig/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-konfig/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-konfig/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-konfig/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-kusion/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-kusion/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-kusion/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-kusion/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-kusion/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-kusion/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/guides/working-with-kusion/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/guides/working-with-kusion/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/support/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/support/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/support/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/support/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/support/faq-cli.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/support/faq-cli.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/support/faq-cli.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/support/faq-cli.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/support/faq-install.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/support/faq-install.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/support/faq-install.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/support/faq-install.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/support/faq-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/support/faq-kcl.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/support/faq-kcl.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/support/faq-kcl.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/support/faq-yaml.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/support/faq-yaml.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/support/faq-yaml.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/support/faq-yaml.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/support/support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/support/support.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.1/user_docs/support/support.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6/user_docs/support/support.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/_category_.json deleted file mode 100644 index f763b5c8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "社区", - "position": 5 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/contribute/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/contribute/_category_.json deleted file mode 100644 index 131bb8e3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/contribute/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "贡献指南", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/contribute/contribute-code.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/contribute/contribute-code.md deleted file mode 100644 index 8e8392fe..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/contribute/contribute-code.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -sidebar_position: 2 ---- - -# 如何贡献代码? - -欢迎参与 KCL 共建贡献完善代码、完善代码文档和测试,同时也欢迎通过 Issue 提供反馈。本文主要针对修改和完善已有的代码,如果是希望增加 KCL 语言特性请通过 KEP 流程提交。 - -## 1. 代码和注释中的错别字 - -如果只是修改代码和注释中的错别字,不涉及代码逻辑的调整,那么可以直接在 Github 克隆仓库后直接修改并提交 PR。需要注意的是尽量保持代码风格一致。 - -## 2. 如何贡献 KCL 代码 - -- 先确保本地测试环境正常 -- 修改代码并补充测试 -- 本地测试通过后提交 PR - -## 3. 如何贡献 VS Code 插件代码 - -请参考 VS Code 插件仓库的相关文档 - -## 4. 开发流程相关代码 - -欢迎通过 Issue 和讨论组讨论。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/contribute/contribute-docs.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/contribute/contribute-docs.md deleted file mode 100644 index 7b846680..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/contribute/contribute-docs.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 如何贡献文档? - -本文主要针对已有的文档做局部修改。如果是投稿博客文章、添加新的文档或者调整文档目录结构请先联系团队成员。 - -KCL 文档分为用户指南、开发文档、内部文档、参考手册和博客文章等,他们的区别如下: - -- 用户指南:对应使用文档,是让用户以最小的代价快速使用 KCL 工具完整工作,不要涉及太多的内部原理和实现 -- 开发文档:内部是怎么实现的,主要针对希望了解 KCL 原理和参与贡献和开发的同学 -- 内部文档:针对企业用户的一些内部场景定制的文档 -- 参考手册:KCL 语言、工具和 IDE 等全部特性的文档,内容覆盖最广但比较琐碎 -- 博客文章:没有特别的限制,可以是针对某些具体的场景、某些技术点或者是整体发展展望等分享文章 - -在贡献不同类型的文档时,最好能够结合上面的定位对不同的内容做一些适当的裁剪,给读者最佳体验。 - -## 1. 基本规范 - -- 除标题外,内部小标题尽量带编号,便于阅读 -- 工具自动输出的文档需要由到源代码的链接,小标题可以不带编号 -- 尽量不要贴大段的代码(30行以内),代码最好给出文字解释和对应的参考链接 -- 有图有真相,但是不推荐过度复杂的架构图 -- 内部链接:采用 `/docs/user_docs/getting-started/intro` 绝对路径形式 - -**标点和空格** - -- 在中文的文档中优先使用中文的标点 -- 中文和英文之间需要增加 1 个空格 -- 中文和数字之间需要增加 1 个空格 -- 中文使用全角标点,标点前后均不添加空格 -- 英文内容使用半角标点,标点后面加 1 个空格 -- 链接前后需要保留一个空格,但是段落开头和中文全角标点附近不用添加空格。 - -**图片和资源文件名** - -- 文件名和目录名只能用数字、英文字母、下划线 `_` 和减号 `-` 组成 -- 当前文档的图片放在当前目录的 images 目录下 -- 矢量图片可以通过 [drawio 离线版](https://github.com/jgraph/drawio-desktop/releases) 绘制(并同时提交源文件),以 200% 分辨率导出 png 格式图片 - -## 2. 使用文档内容的基本模式 - -每个使用文档可以看作是一个相对完整的分享或博客文章(参考手册不再此类)。使用文档遵循以下模式组织内容: - -1. 概览:本文希望解决什么问题,达到什么效果,可以先放最终效果截图 -1. 依赖的环境:需要安装什么工具,并给出相关链接 -1. 引入本文构建资源的关系图或架构图 - - 需要用到的 Konfig 模型,给出模型参考页面链接,以及对应的上游原始模型的文档链接 -1. 具体的操作步骤 - - 尽量确保最小化代码,甚至可以刻意隐藏一些干扰代码,同时给出完整代码对应的链接 - - 列出每个步骤命令的概要输出信息,并配以文字描述 -1. 给出测试方式 - - 尽量采用社区通用的方式(比如kube、curl命令、或浏览器)测试 - - 给出测试结果的截图(和开头呼应) -1. 总结和展望 - - 简单回顾当前操作的流程,以及一些可以展开的地方(可以给出一些链接) - -## 3. 测试和提交 PR - -先克隆文档仓库,本地通过 `npm run start` 和 `npm run build` 命令测试查看效果,确保可以正常浏览后提交 PR 即可。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/contribute/contribute.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/contribute/contribute.md deleted file mode 100644 index 692df6ab..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/contribute/contribute.md +++ /dev/null @@ -1 +0,0 @@ -# 贡献指南 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/contribute/git-guideline.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/contribute/git-guideline.md deleted file mode 100644 index c475057d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/contribute/git-guideline.md +++ /dev/null @@ -1,132 +0,0 @@ -# Git 提交指南 - -本文介绍了 Git 提交变更时需要注意的事项,如果拒绝接受本文的内容会导致提交的变更无法被接受。 - -## 1. 关于 issue - -在提交一个 issue 之前,请先查阅已经关闭的 issue ,也许在关闭的 issue 中已经存在合适的解决方案。 - -如果没有找到合适的方案,我们提供了4种模版在创建 issue 的时候使用。 - -- Bug Report : 发现了一个 Bug,可以通过 Bug Report 模版创建 issue 与我们联系。 -- Enhancement : 开发者对工具进行了增强,可以通过 Enhancement 模版创建 issue 来介绍增加的内容。 -- Feature Request : 在使用的过程中想要为工具增加某些新的特性或者功能,可以通过 Feature Request 模版创建 issue 来描述新特性。 -- Ask a Question : 如果有任何的疑问,可以通过 Ask a Question 模版来创建一个 issue 与我们联系。 - -在选择合适的模版后,只需要填写模版上的要求填写的内容即可。如果在创建 issue 的时候发现没有模版,或者模版内容为空,可以通过微信群,钉钉群或者邮件向我们反馈这个问题。 - -## 2. 关于 Git 分支 - -要向 kcl-lang 贡献代码,您必须拥有一个 GitHub 帐户,以便您可以将代码推送到您自己的分支并创建拉取请求。我们推荐参考 [Angular 规范](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines) 为您自己的分支命名。 -推荐的格式如下: - -``` -{type}-{a_short_description} -``` - -分支名称主要包括两个字段,并通过 “-” 分割。其中: - -- {type} : 当前分支内容的类型。 -- {a_short_description}: 一个简短的描述,介绍这个分支的主要内容。 - -e.g. 张三首先 Fork 仓库到自己账户下,然后创建对应名称 `zhangsan:fix-output-fmt-bug` 的分支(冒号之前是张三的账号),用于修复输出格式化 bug。 - -## 3. 关于 Git Commit - -我们参考 [Commitizen](https://github.com/commitizen/cz-cli) 书写 Commit Message。 - -``` -注: 如果直接使用 Commitizen 生成 Commit Message,需要注意因为 Commitizen -是开发人员管理 commit 的工具,与项目本身无关联,因此由 Commitizen 生成的中间产物 -(如: node_modules 文件目录)可能没有在项目 .gitignore 文件中。 - -您可以 git add {filename} 选择要提交的文件而忽视中间产物。 -或者您可以向 .gitignore 文件中添加如下内容而自动忽视中间产物: -# commitizen -package.json -package-lock.json -node_modules/* -``` - -如果手动编写 Commit Message,我们也建议采用 [Commitizen](https://github.com/commitizen/cz-cli) 的 commit message 格式。 - -``` -{type} ( {component_or_file} ) {a_short_description} - {a_longer_description} - BREAKING CHANGE: {breaking_change_description}. - {linked issue} -``` - -其中主要包括6个字段: - -- {type} : 当前 commit 对应的分支的类型。 -- {component_or_file}: 当前 commit 改动的模块或者文件的名称。 -- {a_short_description}: 简短的描述介绍 commit 中的内容。 -- {a_longer_description}: 详细的描述用来介绍 commit 中的内容。 -- {breaking_change_description}: 如果 commit 中包含破环兼容性的改动,需要对兼容性改动产生的影响进行介绍。 -- {linked issue}: 与当前这个 commit 关联的 issue。 - -其中 {breaking_change_description} 和 {linked issue} 如果 commit 中不包含破坏兼容性的改动和关联的 issue,可以省略。 - -e.g. 张三在分支 `zhangsan:fix-output-fmt-bug` 中创建的 commit。 - -``` - - fix(kcl-printer): fix an output format bug in kcl-printer - - There is an output format bug in kcl-printer because ..., - So, The calling of method "XXX" is replaced by "HHHH"..., - ... - - -- 如果没有破坏兼容性的改动和关联的 issue 可以省略下面内容。 - - BREAKING CHANGE: This change maybe cause ....... - - fix #123 - -``` - -## 4. 关于 pull request - -在提交一个 PR 之前,可能需要优先考虑以下几个问题: - -- 请先查阅已经关闭的 PR ,也许在已经关闭的 PR 中,可能存在已经完成的解决方案。 -- 我们建议在提交变更之前,提交一个对应的 issue 描述变更中将要解决的问题,并将变更对应的 PR 与 issue 关联。 -- 在向我们提交 PR 之后,请签署 [Contributor License Agreement (CLA)](#cla) ,如果拒绝签署,我们将无法接受 PR。 -- 请确保每次改动都创建了一个新的分支,并根据上文中提到的规范为分支命名。 -- 一次 PR 请不要超过两个 commit ,请将多余的 commit 通过 squash 压缩,并根据上文中提到的规范,编写 commit message 。 -- 我们提供了 [PR 模版](https://github.com/kcl-lang/.github/blob/main/.github/PULL_REQUEST_TEMPLATE.md),只需要添加模版中要求的内容即可,如果在创建PR时发现没有模版或者模版内容为空,可以通过微信群,钉钉群或者邮件向我们反馈这个问题。 - -我们建议PR的标题与分支名、commit message 风格保持一致: - -``` -{type} ( {component_name_or_file_name} ) :{a_short_description} -``` - -e.g. 张三为分支`fix/zhangsan/fix_output_fmt_bug`创建的PR名称。 - -``` -fix(kcl-printer): fix an output format bug in kcl-printer. -``` - -## 5. 目前 type 支持的类型 - -参考[Angular 规范](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines),type 支持类型的类型如下: - -``` -- feat: -- 添加了新的功能特性。 -- fix: -- 进行了 Bug 的修复。 -- docs: -- 进行了文档部分的修改。 -- style: -- 对代码格式的修改,并不影响代码的功能,如:删除多余空格,代码缩进等。 -- refactor: -- 在不改变代码功能的基础上对代码进行了的重构。 -- perf: -- 对代码进行了性能优化。 -- test: -- 添加或者调整已有的测试用例。 -- build: -- 对构建系统或者外部依赖库进行了调整。 -- ci: -- 调整了 CI 的配置文件或者脚本。 -- chore: -- 对源代码和测试文件之外其他部分的调整。 -- revert: -- 对 commit 进行回滚。 -``` - -## 6. Contributor License Agreement (CLA) - -在第一次向我们提交 PR 之后,在 PR 中的 CLA 检查将会失败并提示签署 CLA。您可以通过自己的账户之间在 PR 回复 "I have read the CLA Document and I hereby sign the CLA" 表示同意签署 CLA,然后手动重启失败的 CLA 检查 Action 即可。当 PR 被成功合并之后将会被锁定不能再修改。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/intro/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/intro/_category_.json deleted file mode 100644 index e4cb1869..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/intro/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "简介", - "position": 1 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/intro/intro.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/intro/intro.md deleted file mode 100644 index af94bc33..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/intro/intro.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 社区 - -欢迎来到 KCL 开源社区,每个人的参与都是所有开源项目健康成长的动力!有很多方法可以参与开源。每个人都可以通过提交PR(Pull Request)来创建问题或修复 bug、改进文档或修改代码, - -可以查看[社区](https://github.com/kcl-lang/community)并加入我们。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/intro/license.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/intro/license.md deleted file mode 100644 index fe1db435..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/intro/license.md +++ /dev/null @@ -1,211 +0,0 @@ ---- -sidebar_position: 99 ---- - -# 许可 - -KCL 使用 [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0): - -``` - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2023 The KCL Authors. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/intro/support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/intro/support.md deleted file mode 100644 index 70ecd7e8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/intro/support.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 寻求帮助 - -KCL拥有一个由众多爱好者组成的开发者和用户社区。在此页面上,我们列出了您可以参与的KCL相关社区;有关其他在线和离线学习材料,请参阅本节的其他页面。 - -在加入 KCL 社区之前,请阅读[贡献者条款](https://www.contributor-covenant.org/version/2/0/code_of_conduct/),所有社区成员都需要遵守这些条款。 - -## 讨论 - -- 在 Github 上提交问题 -- 在 Github 讨论组中交流 -- 通过官方网站、Github、Twitter、微信和其他帐户获取 KCL 最新状态。可以查看[社区](https://github.com/kcl-lang/community)并加入我们。 - -## 新功能 - -请尽量避免提交新功能的拉取请求,我们可能已经有人在处理这些功能,或者这个功能已经是我们未来计划的一部分。总之,请在提交新功能之前与我们联系! diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/release-policy/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/release-policy/_category_.json deleted file mode 100644 index bf01a053..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/release-policy/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "发布策略", - "position": 3 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/release-policy/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/release-policy/index.md deleted file mode 100644 index a4a0bc3d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/release-policy/index.md +++ /dev/null @@ -1 +0,0 @@ -# 发布策略 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/release-policy/kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/release-policy/kcl.md deleted file mode 100644 index 0f9115b8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/release-policy/kcl.md +++ /dev/null @@ -1,39 +0,0 @@ -# KCL 发布策略 - -KCL 开发团队采用 [语义化版本](https://semver.org/lang/zh-CN/) 来简化管理。版本格式:主版本号.次版本号.修订号。版本号递增规则如下:主版本号对应不兼容的 API 修改,次版本号对应向下兼容的功能性新增,修订号对应向下兼容的问题修正。总体目标是每一个半月发布一个特性增强的次要版本,根据需要不定期发布其他版本的修订。 - -KCL 项目版本发布策略如下: - -- 主版本号:当进行重大的架构调整或者加入重大的新功能时,需要提升主版本号。对于 KCL 项目来说,目前的主版本号为 0。 -- 次版本号:当添加的功能和特性有较大的变化时,提升次版本号。目前的次版本号为 5,2023 年度会相继发布 0.5, 0.6, 0.7 版本。 -- 修订号:通过修复漏洞或者改进性能来更新程序时,会提升修订号,修订号从 0 开始计数以此加 1。 -- 发布周期:在未达到 v1.0.0 版本之前,计划每隔 3 个月发布一个新的次要版本。在此期间,需要持续收集用户反馈,并进行必要的修复和改进。 -- 发布流程:在发布新版本之前,需要进行严格的测试和审核,确保新版本的质量。封板并测试完成后,会在 Github 上发布新版本的源代码,二进制和镜像,并提供详细的文档和使用指南。 -- 版本支持:我们将对最新的版本提供长期支持,包括漏洞修复和安全更新。对于旧版本,我们将提供有限的支持,仅在必要时进行修复。 - -## 发布流程与规则 - -- 特性开发:main 分支主干开发,分支发布,block 用户使用的问题和严重的 bug, 安全隐患,高优先级解决,尽可能保持在一周内收敛,高于一般的功能研发。 -- 迭代周期:我们的迭代周期通常为 3 个月,即每 3 个月发布一个新的次要版本。 -- 版本规划:发版前两周产出 alpha 版本,前一周产出 beta 版本,alpha 版本仍可进行特性合并,beta 版本只合并错误修复,最终产出正式版本并打 tag 作为长期保存的 release 分支。 -- 发版计划:在每个发布周期开始时制定详细的发版计划(Github Milestone),包括发布日期、版本号、功能列表和测试计划等。需要尽可能地遵守发版计划,确保按时发布新版本。 -- 发布前测试:在发布新版本之前,需要进行全面的测试,包括单元测试、集成测试,模糊测试,压测,用户验收测试等。只有经过测试并无问题后,我们才会发布新版本。 -- 版本回滚:如果在发布后发现了严重的问题,需要立即回滚版本,并尽快修复问题。并通过邮件、社交媒体等渠道及时通知用户,并提供解决方案。 -- 发布文档:需要在发布时提供详细的文档,包括发布说明、更新日志、API 文档和使用指南等,帮助用户了解和使用新版本。在 KCL 中,我们统一在 KCL 网站进行维护。 -- 版本兼容性:在发布新版本时,需要尽可能保持兼容性,以确保用户无需进行过多的修改和适应。KCL 还没有达到 v1,暂时没有兼容性保证。KCL 的目标是尽可能少地进行重大更改,不应轻率地考虑对语言的更改,为了语言自身更好地演进和发展,一般认为更改具有重大好处时才会进行(较好地解决了目标场景的问题或者提升了绝大用户的使用体验)。对于可能引入兼容性问题的功能或变更,提供相应的提示和解决方案,同时会提供逐步升级的指南或提供自动迁移的工具,以帮助用户平滑地迁移到新版本。 - -## 发布组件 - -![](/img/docs/community/release-policy/kcl-components.png) - -每次版本发布时,KCL 相关所有组件保持一个依赖同一个 KCL 核心主要版本,整体采用树形结构组织依赖顺序发布并进行回归测试,直到发布测试完成,尽力避免三角依赖,禁止循环依赖。 - -## 一个 Feature 的生命周期 - -- 设计方案/文档:通过 Issue 回答清楚这个 feature 的动机是什么,它解决什么问题以及目标是什么,用户需求和用户故事是怎样的;这个 feature 做什么,如何做,难度怎样,需要多长时间,依赖项,需要做什么测试等。(Tips: 大的设计尽量拆分成小的设计,通过权衡和广泛的调研找到一个简单且可持续的解决方案,并且具备一定得到可扩展以适应未来的业务或技术变化,通过持续讨论和方案评审确定最终设计)。 -- 编写代码:通过高频小改动进行迭代、持续沟通和协作,提前设计单元测试、集成测试和 benchmark 等测试用例,确保编写代码 100% 测试覆盖,注释完整和逻辑清晰,并通过 Demo 演示持续收集反馈。 -- 文档撰写:在 [KCL 网站](https://kcl-lang.io) 中更新用户文档。 -- 测试和反馈:在发布功能之前,让一些同行/用户通过**随循文档**而不是口述来尝试和测试这些新功能。接收反馈并改进。 -- 发布和公告:撰写 Release Note, PR 文章,场景和新特性解读等以及渠道宣发等。 - -> 注:以上所有信息全是公开的,需要透出给所有社区研发者进行参与、讨论和贡献。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/_category_.json deleted file mode 100644 index 1910abe4..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "参考手册", - "position": 5 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/cheatsheets/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/cheatsheets/_category_.json deleted file mode 100644 index 7839b7a2..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/cheatsheets/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "备忘录", - "position": 10 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/cheatsheets/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/cheatsheets/index.md deleted file mode 100644 index 6bfb2e4c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/cheatsheets/index.md +++ /dev/null @@ -1,5 +0,0 @@ -# KCL 备忘录 - -![](/img/docs/reference/cheatsheets/cheatsheet.png) - -[Download PDF](https://github.com/kcl-lang/kcl-lang.io/blob/main/cheatsheet/cheatsheet.pdf) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/index.md deleted file mode 100644 index 9fd0c276..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/index.md +++ /dev/null @@ -1 +0,0 @@ -# 学习 KCL diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/_category_.json deleted file mode 100644 index 6066c82b..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KCL", - "position": 1 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/codelab/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/codelab/_category_.json deleted file mode 100644 index c0133443..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/codelab/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "代码实验室", - "position": 2 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/codelab/collaborative.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/codelab/collaborative.md deleted file mode 100644 index 883f4853..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/codelab/collaborative.md +++ /dev/null @@ -1,345 +0,0 @@ ---- -title: "使用配置操作分块编写配置" -linkTitle: "使用配置操作分块编写配置" -type: "docs" -weight: 2 -description: 使用配置操作分块编写配置 -sidebar_position: 3 ---- - -## 1. Introduction - -KCL 是一种简单易用的配置语言,用户可以简单地编写可重复使用的配置代码。 - -在这个教程中,我们将学习如何使用 KCL 配置操作(config operation)功能以协同的方式编写配置。 - -### 本节将会学习 - -1. 定义 schema 并组织项目目录。 -2. 通过KCL的配置操作功能创建多个环境配置。 -3. 配置编译参数和测试。 - -## 2. 定义 Schema 和 组织项目目录 - -### Schema 定义 - -假设我们想定义具有某些属性的服务器配置,我们可以通过创建一个 `server.k` 文件来创建一个简单的配置,我们可以填写以下代码来定义服务器配置的可重用模式: - -```python -import units - -type Unit = units.NumberMultiplier - -schema Server: - replicas: int = 1 - image: str - resource: Resource = {} - mainContainer: Main = {} - labels?: {str:str} - annotations?: {str:str} - -schema Main: - name: str = "main" - command?: [str] - args?: [str] - ports?: [Port] - -schema Resource: - cpu?: int = 1 - memory?: Unit = 1024Mi - disk?: Unit = 10Gi - -schema Port: - name?: str - protocol: "HTTP" | "TCP" - port: 80 | 443 - targetPort: int - - check: - targetPort > 1024, "targetPort must be larger than 1024" -``` - -在上面的代码中,我们定义了一个名为 Server 的 schema,该 schema 表示用户将要编写的配置类型,其中包含一些基本类型属性(例如`replicas`、`image` 等)和一些复合类型属性(例如 `resource`、`main` 等)。除了一些在 [schema codelab](./schema.md)中提到的基本类型之外,我们可以看到上面的代码中有两种类型 `Unit` 和 `units.NumberMultiplier`。其中,`units.NumberMultiplier` 表示 KCL 数字单位类型,意味着可以在 KCL 数字后添加自然单位或二进制单位,例如 `1K` 表示 `1000`,`1Ki` 表示 `1024`。 `Unit` 是 `units.NumberMultiplier` 的类型别名,用于简化类型注释的编写。 - -### 项目目录 - -为了完成协同的配置的开发,我们首先需要一个配置项目,其中包含测试应用程序的配置以及不同环境的差异化配置,因此我们正在创建以下项目目录: - -``` -. -├── appops -│ └── test_app -│ ├── base -│ │ └── base.k -│ ├── dev -│ │ ├── ci-test -│ │ │ └── stdout.golden.yaml -│ │ ├── kcl.yaml -│ │ └── main.k -│ └── prod -│ ├── ci-test -│ │ └── stdout.golden.yaml -│ ├── kcl.yaml -│ └── main.k -├── kcl.mod -└── pkg - └── sever.k -``` - -该项目目录主要包含三个部分: - -- `kcl.mod`:用于标识KCL项目的根目录的文件。 -- `pkg`:不同应用程序配置所共用的 `Server Schema` 结构。 -- `appops`:不同应用程序的 Server 配置,目前仅包含一个名为 `test_app` 的应用程序。 - - `base`:供所有环境使用的应用程序通用配置。 - - `dev`:供开发环境使用的应用程序配置。 - - `prod`:供生产环境使用的应用程序配置。 - -后续章节将会介绍`base.k`、`main.k`、`kcl.yaml` 和 `ci-test/stdout.golden.yaml` 的含义。 - -## 3. 通过 KCL 配置操作功能创建多个环境配置 - -### 创建基线配置 - -在组织好项目目录和基本的服务器配置模型之后,我们可以编写用户应用程序的配置。我们可以创建自己的测试应用程序文件夹 `test_app`,并将其放置在应用程序配置文件夹 `appops` 中。 - -对于应用程序的配置,我们通常将其分为基本配置和多个环境的差异化配置并进行合并。通过 KCL 的配置合并功能,我们可以轻松实现这一点。假设我们有开发环境和生产环境的两个配置,我们可以创建三个文件夹:`base`、`dev` 和 `prod` 分别存储基线、开发环境和生产环境的配置。首先,我们编写 `base/base.k` 的配置: - -```python -import pkg - -server: pkg.Server { - # 设置镜像的值为 "nginx:1.14.2" - image = "nginx:1.14.2" - # 添加 app label - labels.app = "test_app" - # 添加一个mainContainer配置,它的端口是 [{protocol = "HTTP", port = 80, targetPort = 1100}] - mainContainer.ports = [{ - protocol = "HTTP" - port = 80 - targetPort = 1100 - }] -} -``` - -正如上述代码中所示,我们使用 `import` 关键字在 `base.k` 中导入放置在 `pkg` 下的 `Server` schema,并使用它实例化一个名为`server` 的配置,在其中将 `image` 属性设置为 `"nginx:1.14.2"`,并添加一个带有值为 `test_app` 的标签 `app`。此外,我们还在 `ports` 属性中添加了主容器 `mainContainer` 的配置,其值为 `[{protocol = "HTTP", port = 80, targetPort = 1100}]`。 - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k -``` - -输出: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2 - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app -``` - -当前,我们已经有了一个基线配置。 - -### 创建多重环境配置 - -接下来我们将配置一个差异化的多环境配置。首先假设我们想在开发环境中使用自己的临时镜像 `nginx:1.14.2-dev`,然后使用它来覆盖基准中的服务器配置,我们可以在 `dev/main.k` 中编写以下配置: - -```python -import pkg - -server: pkg.Server { - # 覆盖 base 配置中的声明的镜像 - image = "nginx:1.14.2-dev" -} -``` - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -输出: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app -``` - -可以看出输出的 YAML 文件的 `image` 字段被覆盖为 `nginx:1.14.2-dev`。假设我们还想将一个具有键为 `env`,值为 `dev` 的标签添加到 `dev` 环境中,我们将以下代码添加到 `dev/main.k` 中: - -```python -import pkg - -server: pkg.Server { - # 覆盖 base 配置中的声明的镜像 - image = "nginx:1.14.2-dev" - # 将新标签 env 合并到 base 标签中 - labels.env = "dev" -} -``` - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app - env: dev -``` - -可以看到输出的 YAML 文件的 `labels` 字段中有两个标签。 - -此外,我们还可以使用 `+=` 运算符将新值添加到列表类型属性中,例如在基准环境中的 `mainContainer.ports` 配置,继续修改 `dev/main.k` 中的代码: - -```python -import pkg - -server: pkg.Server { - # 覆盖 base 配置中的声明的镜像 - image = "nginx:1.14.2-dev" - # 将新标签 env 合并到 base 标签中 - labels.env = "dev" - # 在 base ports配置中添加一个 port - mainContainer.ports += [{ - protocol = "TCP" - port = 443 - targetPort = 1100 - }] -} -``` - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -输出: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - - protocol: TCP - port: 443 - targetPort: 1100 - labels: - app: test_app - env: dev -``` - -使用相同的方法,我们可以构建生产配置,在 `dev/main.k` 文件中编写代码,并为其添加标签。 - -```python -import pkg - -server: pkg.Server { - # 将新标签 env 合并到 base 标签中 - labels.env = "prod" -} -``` - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k appops/test_app/prod/main.k -``` - -输出: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2 - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app - env: prod -``` - -## 4. 配置编译参数和测试 - -在前面的章节中,我们通过代码构建了一个多环境配置。可以看出不同环境的 KCL 命令行编译参数相似,因此我们可以将这些编译参数配置到一个文件中,并将其输入到 KCL 命令行中进行调用。请将以下代码配置在 `dev/kcl.yaml`中: - -```yaml -kcl_cli_configs: - files: - - ../base/base.k - - main.k - output: ./ci-test/stdout.golden.yaml -``` - -然后我们可以使用以下命令在开发环境中编译配置: - -```bash -cd appops/test_app/dev && kcl -Y ./kcl.yaml -``` - -此外,我们已经在 `dev/kcl.yaml` 中配置了 `output` 字段,以将 YAML 输出到文件,以便进行后续配置分发或测试。您可以通过遍历每个环境中的 `kcl.yaml` 构建,并将其与 `./ci-test/stdout.golden.yaml` 进行比较,可以验证应用程序的配置是否符合预期。 - -## 5. 最后 - -恭喜! - -我们已经完成了关于 KCL 的第三课。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/codelab/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/codelab/index.md deleted file mode 100644 index 123c0878..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/codelab/index.md +++ /dev/null @@ -1 +0,0 @@ -# 代码实验室 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/codelab/schema.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/codelab/schema.md deleted file mode 100644 index 434e1f5c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/codelab/schema.md +++ /dev/null @@ -1,814 +0,0 @@ ---- -title: "使用 KCL Schema 编写复杂配置" -linkTitle: "使用 KCL Schema 编写复杂配置" -type: "docs" -weight: 2 -description: 使用 KCL Schema 编写复杂配置 -sidebar_position: 2 ---- - -## 1. 介绍 - -KCL 是一种简单易用的配置语言,用户可以简单地编写可重用的配置代码。 - -在本节教程中,我们将学习如何使用 KCL 编写定制配置,这样我们就可以定义一个架构并以协作方式编写配置。 - -### 本节将会学习 - -1. 定义一个简单的 schema -2. 为 schema 字段设置默认的不可变值 -3. 基于简单的 schema 创建配置 -4. 在 schema 中编写复杂的逻辑 -5. 通过 schema 的组合创建新的 schema -6. 使用 dict/map 创建具有深度嵌套 schema 的配置 -7. 通过 schema 继承创建新的 schema -8. 通过多个 mixin schema 创建新的 schema -9. 声明 schema 验证规则 -10. 配置 schema 的输出布局 -11. 共享和重用 schema - -## 2. 编写简单的 Schema - -假设我们希望定义一个具有特定属性的工作负载,我们可以通过创建一个 `my_config.k` 文件来创建一个简单的配置。我们可以按以下方式填写下面的代码,定义一个可重复使用的部署配置的 schema: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels: {str:str} -``` - -在上述代码中,`cpu` 和 `memory` 被定义为 int 值;`name`、`image` 和 `service` 是字符串;`command` 是由字符串构成的列表;`labels` 是字典类型,其键和值的类型均为字符串。 - -另外,每个属性都**必须**被赋予非 None 值作为 schema 实例,除非它被标记问号 **?** 而作为可选参数。 - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels?: {str:str} # labels 是一个可选的参数 -``` - -当存在继承关系时: - -- 如果在基 schema 中该属性为可选(optional)参数,则在子 schema 中它应该是可选的(optional)或必需的(required)。 -- 如果在基 schema 中该属性为必需(required)属性,则在子 schema 中它需要是必需的(required)。 - -## 3. Enhance Schema as Needed - -Suppose we need to set default values to service and replica, we can make them as below: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str = "my-service" # defaulting - replica: int = 1 # defaulting - command: [str] - labels?: {str:str} # labels is an optional attribute -``` - -And then we can set the service type annotation as the string literal type to make it immutable: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: "my-service" = "my-service" - replica: int = 1 - command: [str] - labels?: {str:str} -``` - -In the schema, type hint is a `must`, for example we can define cpu as `cpu: int`. - -Specially, we can define a string-interface dict as `{str:}`, and in case we want to define an object or interface, just define as `{:}`. - -## 4. 基于简单 Schema 创建配置 - -现在我们有了一个简单的 schema 定义,我们可以用它来定义配置: - -```python -nginx = Deployment { - name = "my-nginx" - cpu = 256 - memory = 512 - image = "nginx:1.14.2" - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python - kcl my_config.k -``` - -标准输出: - -```yaml -nginx: - name: my-nginx - cpu: 256 - memory: 512 - image: nginx:1.14.2 - service: my-service - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -> 有关集合数据类型和块的更多详细信息,请查看手册和规范。 - -此外,**配置选择器表达式**(config selector expressions)可以用于初始化 schema 实例,我们可以忽略配置表达式中行末的逗号。 - -```python -nginx = Deployment { - name = "my-nginx" - cpu = 256 - memory = 512 - image = "nginx:1.14.2" - command = ["nginx"] # 忽略行尾的逗号 - labels.run = "my-nginx" # schema 中的字典变量可以使用选择器表达式 - labels.env = "pre-prod" # schema 中的字典变量可以使用选择器表达式 -} -``` - -## 5. 在 Schema 中编写更为复杂的逻辑 - -假设我们有一些schema逻辑,我们可以将它包装进 schema 中: - -```python -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - image: str - service: "my-service" = "my-service" - replica: int = 1 - command: [str] - labels?: {str:str} - - _cpu = 2048 - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 -``` - -现在,我们可以通过创建 schema 实例来定义配置,并将优先级作为参数传递给模式: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl my_config.k -``` - -标准输出: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - image: nginx:1.14.2 - service: my-service - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 6. 通过 Schema 组合创建新 Schema - -现在我们想要定义一个详细的 schema,包括服务(service)和卷(volumes),我们可以按以下方式进行操作: - -```python -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - volumes?: [Volume] - image: str - service?: Service - replica: int = 1 - command: [str] - labels?: {str:str} - - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 - -schema Port: - name: str - protocol: str - port: int - targetPort: int - -schema Service: - name: "my-service" = "my-service" - ports: [Port] - -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -在这种情况下,Deployment 由 Service 和一系列 Volume 组成,而 Service 又由一系列 Port 组成。 - -## 7. 使用 dict/map 创建具有深度嵌套 schema 的配置 - -现在我们有一个新的 Deployment schema,但我们可能会注意到,它包含多层嵌套的结构,在复杂的结构定义中,这是非常常见的,我们通常必须编写命令式组装代码来生成最终结构。 - -使用 KCL,我们可以使用简单的字典声明创建配置,并具有完整的 schema 初始化和验证功能。例如,我们可以按照以下方式使用新的 Deployment schema简单地配置 nginx: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl my_config.k -``` - -标准输出: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -请注意,我们用于定义 Deployment 配置的字典必须与 schema 定义对齐,否则我们将会得到一个错误。例如,假设我们将服务端口的类型定义错误如下: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = [80] # 错误的数据类型,试图将 List 分配给 int - targetPort = 9376 - }] -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl my_config.k -``` - -标准错误输出: - -``` -The type got is inconsistent with the type expected: expect int, got [int(80)] -``` - -## 8. 声明 Schema 验证规则 - -现在我们已经看到了一个复杂的 schema,在其中每个字段都有一个类型提示,以使其更加不容错(error-prone)。 - -但是这还不够好,我们希望为我们的 schema 支持更多的增强验证,以便尽快发现 schema 和配置中的代码错误。许多验证规则,如 None 类型检查、范围检查、值检查、长度检查、正则表达式匹配、枚举检查已经被添加或陆续添加进来。以下是一段代码示例: - -```python -import regex - -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - volumes?: [Volume] - image: str - service?: Service - replica: int = 1 - command: [str] - labels?: {str:str} - - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 - - check: - multiplyof(cpu, 256), "cpu must be a multiplier of 256" - regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$"), "image name should be like 'nginx:1.14.2'" - 1 <= replica < 100, "replica should be in range (1, 100)" - len(labels) >= 2 if labels, "the length of labels should be large or equal to 2" - "env" in labels, "'env' must be in labels" - len(command) > 0, "the command list should be non-empty" - -schema Port: - name: str - protocol: str - port: int - targetPort: int - - check: - port in [80, 443], "we can only expose 80 and 443 port" - protocol in ["HTTP", "TCP"], "protocol must be either HTTP or TCP" - 1024 < targetPort, "targetPort must be larger than 1024" - -schema Service: - name: "my-service" = "my-service" - ports: [Port] - - check: - len(ports) > 0, "ports list must be non-empty" - -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -由于schema定义的属性默认是**必需的**(required),因此可以省略判断变量不能为 None/Undefined 的验证。 - -```python -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -现在我们可以基于新的 schema 编写配置,并及时暴露配置错误。例如,使用以下无效的配置: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1142" # 镜像值不匹配正则表达式 - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -每个字段都是类型有效的,但镜像名无效。 - -运行 KCL,我们将看到如下错误信息: - -KCL 命令: - -```python -kcl my_config.k -``` - -标准错误输出: - -``` -Schema check is failed to check condition: regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$"), "image name should be like 'nginx:1.14.2'" -``` - -> KCL 的验证功能涵盖了 Openapi 定义的验证,因此我们可以通过 KCL 编写任何 API 验证。 - -## 9. 通过 Schema 继承创建新 Schema - -现在,我们拥有了一个稳定的部署 schema 定义,可以用它来声明配置。 - -通常,部署 schema 将被用于多个场景中。我们可以直接使用 schema 在不同的用例中声明配置(见上文的部分),或者我们可以通过继承生成一个更具体的 schema 定义。 - -例如,我们可以使用部署 schema 作为基础,来定义 nginx 的基本 schema,并在每个场景中扩展定义。在这种情况下,我们定义了一些常用的属性。请注意,我们使用“final”关键字将名称标记为不可变,以防止被覆盖。 - -```python -schema Nginx(Deployment): - """ A base nginx schema """ - name: "my-nginx" = "my-nginx" - image: str = "nginx:1.14.2" - replica: int = 3 - command: [str] = ["nginx"] - -schema NginxProd(Nginx): - """ A prod nginx schema with stable configurations """ - volumes: [Volume] = [{ - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - """ A volume mapped to host path """ - service: Service = { - ports = [{ - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] - } - """ An 80 port to target backend server """ -``` - -现在我们有了一些 nginx 的静态配置。建议将我们认为是静态的配置声明在那里,并将更多的动态配置放在下面: - -```python -nginx = Nginx { - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -```python -nginx = NginxProd { - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -现在,我们只需要通过运行时标签值 “prod” 来简单定义 不那么静态的 nginx 生产环境配置。 - -实际上,在某些复杂情况下,我们可以将所有配置分为基本配置、业务配置和环境配置定义,并基于此实现团队成员之间的协作。 - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl prod_config.k -``` - -标准输出: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 3 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 10. Create New Schema by Multiple Protocol and Mixin Schemas Inheritance - -现在,我们可以通过 Deployment schema 完成服务器配置的声明。 - -然而,通常实际情况更为复杂,部署可能有各种可选变量附件。 - -例如,我们想要在现有 schema 中支持声明持久卷,作为可重用的 Kubernetes schema。在这种情况下,我们可以通过以下 `mixin` 和 `protocal` 进行包装: - -```python -import k8spkg.api.core.v1 - -protocol PVCProtocol: - pvc?: {str:} - -mixin PersistentVolumeClaimMixin for PVCProtocol: - """ - PersistentVolumeClaim (PVC) sample: - Link: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims - """ - - # Mix in a new attribute `kubernetesPVC` - kubernetesPVC?: v1.PersistentVolumeClaim - - if pvc: - kubernetesPVC = v1.PersistentVolumeClaim { - metadata.name = pvc.name - metadata.labels = pvc.labels - spec = { - accessModes = pvc.accessModes - resources = pvc.resources - storageClassName = pvc.storageClassName - } - } -``` - -有了 PersistentVolumeClaimMixin,我们使用清晰的用户界面(user interface)定义了一个 PVC schema,并使用 Kubernetes PVC 作为实现。然后,我们可以使用 Deployment schema 和 PVC mixin schema 定义一个 server schema。 - -```python -schema Server(Deployment): - mixin [PersistentVolumeClaimMixin] - pvc?: {str:} - """ pvc user interface data defined by PersistentVolumeClaimMixin """ -``` - -在 Server schema 中,Deployment schema 是基础 schema,而 PersistentVolumeClaimMixin 是一个可选附加项,其用户界面数据为`pvc?:{str:}`。 - -请注意,mixin 通常用于向宿主 schema 添加新属性,或修改宿主 schema 的现有属性。因此,mixin 可以使用宿主 schema 中的属性。由于其被设计为可重用,因此我们需要一个额外的协议来限制 mixin 中宿主 schema 中属性的名称和类型。 - -现在,如果我们想要使用 PVC 进行部署,只需声明用户界面: - -```python -server = Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] - pvc = { - name = "my_pvc" - accessModes = ["ReadWriteOnce"] - resources.requests.storage = "8Gi" - storageClassName = "slow" - } -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl server.k -``` - -标准输出: - -```yaml -server: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod - pvc: - name: my_pvc - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 8Gi - storageClassName: slow ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: my_pvc -spec: - accessModes: - - ReadWriteOnce - storageClassName: slow - resources: - requests: - storage: 8Gi -``` - -如果我们不需要持久卷,只需删除 pvc 配置块。 - -## 11. 共享和重用 Schema - -可以通过导入来共享 Server schema,我们只需要将代码与 KCL 一起打包即可。 - -```python -import pkg - -server = pkg.Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -另一个关于共享代码的技巧是:在同一包下的模块不需要相互导入。 - -假设我们在 pkg 中有如下 models: - -``` -pkg/ - - deploy.k - - server.k - - pvc.k -``` - -在 `server.k` 中,我们可以只使用 `deploy.k` 中的 Deployment schema 和 `pvc.k` 中的 pvc schema 而无需导入: - -```python -# 无需 import -schema Server(Deployment): - mixin [PersistentVolumeClaimMixin] - pvc?: {str:} - """ pvc user interface data defined by PersistentVolumeClaimMixin """ -``` - -然后用户必须导入 pkg 才能作为一个整体使用它: - -```python -import pkg - -server = pkg.Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [pkg.Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } - service.ports = [pkg.Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -运行 KCL 命令: - -```python -kcl pkg_server.k -``` - -Output: - -```yaml -server: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 12. 最后 - -恭喜! - -我们已经完成了 KCL 的第二节课。我们使用 KCL 来替换我们的 key-value 文本文件,以便获得更好的可编程性。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/codelab/simple.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/codelab/simple.md deleted file mode 100644 index 32ad2612..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/codelab/simple.md +++ /dev/null @@ -1,495 +0,0 @@ ---- -title: "使用 KCL 编写简单配置" -linkTitle: "使用 KCL 编写简单配置" -type: "docs" -weight: 2 -description: 使用 KCL 编写简单配置 -sidebar_position: 1 ---- - -## 1. 介绍 - -KCL 是一种简单易用的配置语言,用户可以简单地编写可重用的配置代码。 - -在这个第一个教程中,我们将学习如何使用 KCL 编写一个简单的配置。 - -学习这个代码实验只需要基本的编程知识,如果你有 Python 经验,将会更容易上手。 - -### 本节将会学习 - -1. 用一种可编程的方式编写简单的 key-value 配置 -2. 使用 KCL 编写简单的逻辑 -3. 使用 KCL 编写集合(collections) -4. 使用 KCL 代码进行测试和调试 -5. 在 KCL 代码中使用内置(built-in)支持 -6. 共享和重用 KCL 代码 -7. 使用动态输入参数编写配置 - -## 2. 编写Key-Value键值对 - -通过创建 `my_config.k` 来生成一个简单的配置,我们可以填充下面的代码,并且不需要严格的格式描述部署的配置。 - -```python -cpu = 256 -memory = 512 -image = "nginx:1.14.2" -service = "my-service" -``` - -在上述代码中,cpu 和 memory 被声明为 int 类型的值,而 image 和 service 被声明为字符串字面值。 - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -KCL 命令: - -```bash -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -可导出变量(exported variable)默认情况下是不可变的,一旦声明,就不能在其他地方修改它。 - -## 3. 编写简单逻辑 - -有时候我们想在配置中编写一些逻辑,那么我们就可以使用: - -- 以 `_` 开头的非导出可变变量(mutable and non-exported variable) -- if-else 语句 - -非导出变量表示它不会出现在输出的 YAML 中,且它可以被多次赋值。 - -这是一个示例,显示如何根据条件调整资源。 - -KCL 命令: - -```python -kcl my_config.k -``` - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -image = "nginx:1.14.2" -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -```python -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -.. 注意:: -KCL 对运算符和字符串成员函数有丰富的支持,请阅读手册和规范以了解更多细节。 - -## 4. 编写集合 - -我们可以使用集合来表示复杂的数据类型。已支持的集合类型有: - -- list -- dict - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -command = ["nginx"] # 列表 -labels = {run = "my-nginx"} # a dict -image = "nginx:1.14.2" -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -KCL 命令: - -```bash -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx -image: nginx:1.14.2 -service: my-service -``` - -> 有关集合数据类型和成员函数的更多信息,请查阅手册和规范。 - -## 5. 在集合中添加元素 - -我们可以将逻辑表达式、推导式、切片、联合类型等特性组合起来,动态地将元素添加到集合中。 - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 -_env = "pre-prod" - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -_command = ["nginx"] # 列表 -_command = _command + ["-f", "file"] # 使用 + 运算符将元素附加到命令中以连接两个列表 -command = [c.lower() for c in _command] # # 将列表中的每个元素转为小写 -_labels = { - run = "my-nginx" - if _env: - env = _env # 当 _env 不是 None/Undefined 或为空时使用 if 表达式添加一个字典键值对 -} # 字典 -labels = _labels -image = "nginx:1.14.2" -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -```python -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 256 -memory: 512 -command: - - nginx - - -f - - file -labels: - run: my-nginx -image: nginx:1.14.2 -service: my-service -``` - -## 6. 编写断言 - -为了使代码可测试且健壮,我们可以使用断言(assertions)验证配置数据。 - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -command = ["nginx"] # 列表 -labels = {run = "my-nginx"} # 字典 -image = "nginx:1.14.2" -service = "my-service" -assert "env" in labels, "env label is a must" -assert cpu >= 256, "cpu cannot be less than 256" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -```bash -kcl my_config.k -``` - -标准错误输出: - -```bash -Assertion failure: env label is a must. -``` - -将 env:pre-prod 对添加到标签中后,我们将得到如下输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 7. 使用方便的内置支持 - -更重要的是,我们可以使用内置函数来帮助我们调试或简化编码。 - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -_name = "nginx" -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # 列表 -labels = { - run = "my-{}".format(_name) - env = "pre-prod" -} # a dict -image = "{}:1.14.2".format(_name) # 字符串格式 -service = "my-service" - -# debugging -print(labels) # 通过打印调式 - -# test -assert len(labels) > 0, "labels can't be empty" # 使用 len() 得到列表长度 -assert "env" in labels, "env label is a must" -assert cpu >= 256, "cpu cannot be less than 256" -``` - -此示例展示了我们如何使用 `format()`、`len()`、`print()` 函数来帮助自定义配置。 - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -KCL 命令: - -```bash -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -run: my-nginx -env: pre-prod -``` - -注意:更多的内置函数和模块可以在 spec/module 目录中查看。 - -## 8. 重用另一个模块的变量 - -为了使我们的代码得到良好的组织,我们可以将代码简单地分为 `my_config.k` 和 `my_config_test.k` 两个文件。 - -在 `my_config.k` 中定义配置数据: - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 -_name = "nginx" - -# 可导出变量 -cpu = _cpu -memory = _cpu * 2 -command = [_name] # 列表 -labels = { - run = "my-{}".format(_name) - env = "pre-prod" -} # a dict -image = "{}:1.14.2".format(_name) # 字符串格式 -service = "my-service" -``` - -而测试代码定义在 `my_config_test.k` 中,我们可以在其中导入 `my_config.k`: - -```python -import my_config - -# debugging -print(my_config.labels) # 通过打印调试 - -# test -assert len(my_config.labels) > 0, "labels can't be empty" # 使用 len() 得到列表长度 -assert "env" in my_config.labels, "env label is a must" -assert my_config.cpu >= 256, "cpu cannot be less than256" -``` - -## 9. 配置输入参数 - -有时我们需要获得通过从最终用户或平台动态获取的外部输入参数。 - -在这种情况下,我们可以按需传递 `priority` 和 `env` 参数: - -- 通过参数传递: `-D priority=1 -D env=pre-prod` -- 可以在 KCL 代码中使用 `option` 关键字获取这些值 - -```python -_priority = option("priority") # 非导出可变变量 -_env = option("env") # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -_name = "nginx" -# 可导出变量 -cpu = _cpu -memory = _cpu * 2 -command = [_name] # 列表 -labels = { - run = "my-{}".format(_name) - env = _env -} # a dict -image = "{}:1.14.2".format(_name) # 字符串格式 -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -```bash -kcl my_config.k -D priority=2 -D env=pre-prod -``` - -标准输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 10. 使用 Dict 简化逻辑表达式 - -当我们需要编写复杂的逻辑时,可以使用dict来简化逻辑的编写。 - -```python -_priority = option("priority") # 非导出可变变量 -_env = option("env") # 非导出可变变量 -_priorityCpuMap = { - "1" = 256 - "2" = 512 - "3" = 1024 -} -# 使用字典简化逻辑,默认值为2048 -_cpu = _priorityCpuMap[_priority] or 2048 -_name = "nginx" -# 可导出变量 -cpu = _cpu -memory = _cpu * 2 -command = [_name] # 列表 -labels = { - run = "my-{}".format(_name) - env = _env -} # a dict -image = "{}:1.14.2".format(_name) # 字符串格式 -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -KCL 命令: - -```bash -kcl my_config.k -D priority=2 -D env=pre-prod -``` - -标准输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 11. 最后 - -恭喜! - -我们已经完成了关于 KCL 的第一课程,我们使用 KCL 来替换我们的键值文本文件,以获得更好的编程支持。 - -建议立即查看架构代码实验,以了解如何使用 KCL `schema` 机制协作编写高级配置。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/error/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/error/_category_.json deleted file mode 100644 index 4f285ced..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/error/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "错误与警告", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/error/_error.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/error/_error.md deleted file mode 100644 index a2f192b8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/error/_error.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: "错误检查" -linkTitle: "错误检查" -type: "docs" -weight: 1 -description: KCL 语言规范 ---- - -When errors happen, developers should be able to detect the error and abort -execution. Thus, KCL introduce the `assert` syntax. - -In the previous topic of `schema` syntax. Errors can also be raised when a -schema is violated. - -## Syntax - -The syntax of the `assert` statement is the following. - -``` -assert_stmt: 'assert' test [',' test] -``` - -In the basic form, an `assert` statement evaluates an expression. If the -expression is evaluated to `False`, the assertion is failed, and an error -should be reported. - -In the extended form, an error message can be provided. The error message is -another expression. It is only evaluated when the expression to be evaluated -is evaluated to `False`. The evaluation result of the error message is printed -when reporting the error. - -The following is an example: - -```py -a = 1 -b = 3 -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -``` - -## The Implementation - -When an error happens, no matter it is caused by the `assert` or the `schema` syntax, -the virtual machine should exit with an exit code greater than `0`. - -The virtual machine may choose to dump the back trace information, and it is strongly -recommended to implement it. - -In practice, KCL can dump back trace by default, and an argument can be introduced -to disable it. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/error/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/error/index.md deleted file mode 100644 index e4f702ec..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/error/index.md +++ /dev/null @@ -1 +0,0 @@ -# 错误与警告 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/index.md deleted file mode 100644 index 66fd3dde..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/index.md +++ /dev/null @@ -1 +0,0 @@ -# KCL diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/_category_.json deleted file mode 100644 index c088e386..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "规范", - "position": 3 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/codestyle.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/codestyle.md deleted file mode 100644 index dd40925e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/codestyle.md +++ /dev/null @@ -1,608 +0,0 @@ ---- -title: "Code Style" -linkTitle: "Code Style" -type: "docs" -weight: 2 -description: Code Style ---- - -## Introduction - -This document gives the KCL code style conventions. Good code style can play a vital role in the development and maintenance of the project. We can learn the KCL code style by referring to the full text of the description and sample codes, and use KCL format and lint tools to help coding. - -## Source File Encoding - -KCL file encoding should always use **UTF-8**. - -## Code Layout - -### Indentation - -Use **4 spaces** per indentation level such as in the schema statement and if statement. - -```python -schema PersonA: - name: str # non-recommended - age: int - -schema PersonB: - name: str # recommended - age: int - -if True: - a = 1 # recommended -elif True: - b = 2 # non-recommended -else: - c = 3 # non-recommended -``` - -The closing brace/bracket/parenthesis on multiline constructs should line up under **first character** of the line that starts the multiline construct, as in: - -```python -# valid and recommended -my_list = [ - 1, 2, 3, - 4, 5, 6, -] -``` - -```python -# invalid -my_list = [ - 1, 2, 3, - 4, 5, 6, - ] -``` - -### Tabs or Spaces - -- Spaces are the preferred indentation method. -- Tabs should be used solely to remain consistent with code that is already indented with tabs. - -KCL disallows mixing the use of tabs and spaces for indentation and an error will be reported during the compile time. - -### Blank Lines - -- Surround top-level schema definitions with one blank line. -- Keep at most one blank line between two statements and remove redundant blank lines. -- Remove extra blank characters at the end of the line -- Remove extra blank characters in a blank line. -- There is no blank line in the header of the file, start writing from the first line. -- Only one blank line will be left at the end of the KCL file. - -```python -# Remove blank lines in the file header -a = 1 # Remove white space at the end of the line -# Keep at most one blank line between two statements - -b = 2 -# Only leave one blank line at the end of the file - -``` - -### Inline Expressions - -Write indentation of KCL `if`, `elif`, `else` and other conditions on different lines. - -```python -if True: print("") # non-recommended - -if True: # recommended - print("") -``` - -### Line Break and Continuation lines - -- For long expressions, use the line continuation symbol `\` and keep the left end of multiple expressions aligned. -- The 4-space rule is optional for continuation lines. - -```python -anotherString = "Too long expression " + \ - "Too long expression " # non-recommended - -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " # recommended -``` - -### When to Use Trailing Commas - -- Always use trailing commas. - -### Maximum Line Length - -- The general recommendation is **80 characters** but not absolute. - -### Symbol Break White Space - -Try to keep the spaces between different symbols, but not too many, usually one is good. - -```python -a = 1 # recommended -b = 1 + 2 # non-recommended -``` - -### Whitespace in Expressions and Statements - -Avoid extraneous whitespace in the following situations: - -- The parentheses `()`, brackets `[]` and braces `{}` in the expression have no spaces inside. - -```python -a = (1 + 2) # recommended -b = ( 1 + 2 ) # non-recommended - -c = [1, 2, 3] # recommended -d = [ 1, 2, 3 ] # non-recommended - -e = {key = "value"} # recommended -f = { key = "value" } # non-recommended -``` - -```python -spam(ham[1], {eggs = 2}) # recommended -spam( ham[ 1 ], { eggs = 2 } ) # non-recommended -``` - -- Between a trailing comma and a following close parenthesis. - -```python -foo = [0,] # recommended -bar = [0, ] # non-recommended -``` - -- Immediately before the open parenthesis that starts the argument list of a function call. - -```python -print(1) # recommended -print (1) # non-recommended -``` - -- Immediately before the open parenthesis that starts indexing or slicing. - -```python -dct = {key = "value"} -lst = [1, 2, 3] - -a = dct['key'] # recommended -b = dct ['key'] # non-recommended - -c = lst[0] # recommended -d = lst [1] # non-recommended -``` - -- More than one space around an assignment `=` (or other) operator to align it with another. - -```python -# recommended: -x = 1 -y = 2 -long_variable = 3 -``` - -```python -# non-recommended: -x = 1 -y = 2 -long_variable = 3 -``` - -- Always surround these binary operators with a single space on either side: assignment (`=`), augmented assignment (`+=`, `-=`, etc.), comparisons (`==`, `<`, `>`, `!=`, `<=`, `>=`, `in`, `not in`, `is`, `is not`), booleans (`and`, `or`, `not`). - -```python -# recommended: -i = i + 1 -submitted += 1 -x = x * 2 - 1 -hypot2 = x * x + y * y -c = (a + b) * (a - b) -``` - -```python -# non-recommended: -i = i+1 -submitted+=1 -x = x*2 - 1 -hypot2 = x*x + y*y -c = (a+b) * (a-b) -``` - -- Break one blank line between different statements e.g., import, schema and expression statements. - -```python -import math -import net - -schema Person: - name: str - -person = Person { - name = "Alice" -} -``` - -- Compound statements (multiple statements on the same line) are generally discouraged - -```python -# recommended: -if foo == 'blah': - do_blah_thing() -do_one() -do_two() -do_three() -``` - -```python -# non-recommended: -if foo == 'blah': do_blah_thing() -do_one(); do_two(); do_three() -``` - -## Naming Conventions - -### Naming Styles - -The following naming styles are commonly distinguished: - -- `b` (single lowercase letter) -- `B` (single uppercase letter) -- `lowercase` -- `lower_case_with_underscores` -- `UPPERCASE` -- `UPPER_CASE_WITH_UNDERSCORES` -- `CapitalizedWords` (capitalize all letters of the acronym in `CapitalizedWords` e.g., `HTTPServer`.) -- `mixedCase` (differs from `CapitalizedWords` by initial lowercase character) -- `Capitalized_Words_With_Underscores` (ugly and non-recommended) - -### Names to Avoid - -Never use the characters 'l' (lowercase letter el), 'O' (uppercase letter oh), or 'I' (uppercase letter eye) as single-character variable names. - -### Package and Module Names - -Package and module names should have short, all-lowercase names. - -### Schema Names - -Schema names should normally use the `CapWords` convention. - -### Constants - -Constants are usually defined on a module level and written in all capital letters with underscores separating words such as `MAX_OVERFLOW` and `TOTAL`. - -## Import - -- Imports should usually be on separate lines. -- Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants. -- Imports should be grouped in the following order and we should put a blank line between each group of imports. - 1. Standard library imports. - 2. Related third party plugin imports. - 3. Local application/library specific imports. -- Use an alias when we import a package name with a relatively long path. -- Leave only one space between the Import keyword and the package name. - -```python -import net # recommended -import math # non-recommended - -import ..pkg.internal_pkg as alias_pkg # recommended -``` - -## Comments - -- Comments should be complete sentences. The first word should be capitalized unless it is an identifier that begins with a lower-case letter (never alter the case of identifiers!). -- Block comments generally consist of one or more paragraphs built out of complete sentences, with each sentence ending in a period. -- Use two spaces after a sentence-ending period in multi-sentence comments, except after the final sentence. - -### Block Comments - -Block comments generally apply to some (or all) code that follows them, and are indented to the same level as that code. Each line of a block comment starts with a `#` and **a single space**(unless it is indented text inside the comment). - -Paragraphs inside a block comment are separated by a line containing a single `#`. - -```python -# This is a block comment -a = 1 -``` - -### Inline Comments - -Use inline comments sparingly. - -An inline comment is a comment on the same line as a statement. Inline comments should be separated by **at least two spaces** from the statement. They should start with a `#` and **a single space**. - -```python -a = 1 # This is an inline comment -``` - -### Documentation Strings - -Write doc strings for all public schema and schema attributes. - -```python -schema Person: - """ - Person schema doc string - """ - - name: str = "Alice" -``` - -## String - -- Single-quoted strings and double-quoted strings are the same in KCL. -- Use double-quoted string with lowercase prefix -- For triple-quoted strings, always use double quote characters to be consistent with the docstring convention. -- When a string contains single or double quote characters, use the other one to avoid backslashes in the string. - -```python -strC = "'123'" # recommended -strD = "\"123\"" # non-recommended -``` - -## Number - -- Use lowercase for the prefix of non-decimal numbers, and use uppercase for the number itself. - -```python -foo = 0xAB # recommended -bar = 0Xab # non-recommended -``` - -## Operators - -### Binary Operators - -- Leave only one space before and after the assignment `=`. -- Leave only one space before and after the binary operator in the expression. - -```python -a = 1 # recommended -b=2 # non-recommended -c= 3 # non-recommended -d =4 # non-recommended - -_value = (1 + 2 * 3) # recommended -_value = (1+2*3) # non-recommended -``` - -### Unary Operators - -- There is only no space after unary operators e.g., `~`, `+` and `-`. - -```python -_value = 1 + -2 * ~3 # recommended -_value = 1+ - 2 * ~ 3 # non-recommended -``` - -- There is no space after `**` and `*` in the dict/list deduction expressions and argument expressions. - -```python -_list = [1, 2, 3] -_list = [*_list, [4, 5 ,6]] # recommended -_list = [* _list, [4, 5 ,6]] # non-recommended - -_dict = {**{k = "v"}, **{k = "v"}} # recommended -_dict = {** {k = "v"}, ** {k = "v"}} # non-recommended -``` - -- Use `is not` operator rather than `not ... is`. - -```python -# recommended: -if foo is not None: - a = 1 -``` - -```python -# non-recommended: -if not foo is None: - a = 1 -``` - -## Dict - -- There is no space before the colon `:` at the instantiation of KCL dict and schema config, and a space after the colon `:`. - -```python -d1 = {labels: {k1 = "v1"}} # recommended -d2 = {labels : {k1 = "v1"}} # non-recommended -d3 = {labels :{k1 = "v1"}} # non-recommended -``` - -- Always surround the override attribute operator `=` and the insert attribute operator `+=` with a single space on either sid. - -```python -d1 = {key = "value"} # recommended -d2 = {key= "value"} # non-recommended -d3 = {key ="value"} # non-recommended -``` - -```python -d1 = {key += [0, 1, 2]} # recommended -d2 = {key+= [0, 1, 2]} # non-recommended -d3 = {key +=[0, 1, 2]} # non-recommended -``` - -- Remove all commas at the end of the line in the KCL multiline dict because the end commas of each line are optional. - -```python -d = { - key1 = "value1" - key2 = "value2" - key3 = "value3" - key4 = "value4" -} -``` - -## List - -- Keep only **one space** after the comma `,` separating elements in the list - -```python -a = [1, 2, 3] # recommended -b = [1,2,3] # non-recommended -``` - -- Keep only **one space** before and after the comprehension expression token `for` and `in` in the dict and list. - -```python -a = [i for i in range(10)] # recommended -b = [i for i in range(10)] # non-recommended -``` - -## Slice - -- Keep the same number of spaces before and after the colon `:` of the list slice. - -```python -l = [1, 2, 3] -a = l[0:2] # recommended -b = l[0 : 2] # non-recommended -c = l[0: 2] # non-recommended - -d = l[0 + 0 : 1 + 1] # recommended -e = l[0 + 0:1 + 1] # non-recommended -``` - -## Schema - -- Leave only one space before and after the schema attribute assignment `=`. -- Always add a doc string to a schema, which is a good programming habit. - -```python -schema Person: - """ - Schema doc string - """ - name: str = "Alice" # recommended - age : int=12 # non-recommended - -person = Person {} -``` - -- Keep **no spaces** around the schema inheritance operator `()` - -```python -schema Base: - name: str - -schema Person(Base): # recommended - age: int - -schema Schema ( Base ): # non-recommended - age: int -``` - -- Keep **only one space** between the brackets and the schema name of the config at schema instantiation. - -```python -schema Base: - name: str - -schema Person(Base): - age: int - -personA = Person{} # non-recommended -personB = Person {} # recommended -``` - -- Keep **only one space** between the **mixin** keyword and the following `[]` operator - -```python -schema NameMixin: - name: str = "name" - -schema Person: - mixin [NameMixin] # non-recommended - age: int - -schema Parent: - mixin [NameMixin] # recommended - age: int -``` - -### Attribute Annotations - -- Annotations for schema attributes should have a single space after the colon `:` and no space before the colon `:`. - -```python -# recommended: -schema Person: - name: str # No space before the colon `:` - age: int = 18 # Spaces around assignment`=` -``` - -```python -# non-recommended: -schema Person: - codeA:int # No space after the colon `:` - codeB : int # Space before the colon `:` - name: str="Alice" # No spaces around assignment`=` -``` - -- There are no spaces around the colon `:` in the dict type annotation. - -```python -schema Person: - labels: {str:str} # recommended - keyValues: {str : str} # non-recommended -``` - -### Arguments - -- There are no spaces around the assignment `=` in the function/schema/decorator keyword arguments (kwargs). - -```python -schema Person[nameVar]: - # Decorator kwargs - @deprecated(strict=False) # recommended - name: str = nameVar - - @deprecated(strict = False) # non-recommended - age: int - -# Schema kwargs -personA = Person(nameVar="Alice") {} # recommended -personB = Person(nameVar = "Bob") {} # non-recommended - -# Function kwargs -print("", end='') # recommended -print("", end = '') # non-recommended -``` - -## Keywords - -- Only one space is usually reserved around the keyword, such as `schema`, `mixin`, `is` and `not`, etc. - -```python -schema NameMixin: - check: - name not None - -schema Person: - """ - Person schema definition - """ - mixin [NameMixin] - - name: str = "Alice" - age: int - -person = Person { - age = 18 -} -``` - -## Function - -- There are no spaces around the function/package select operator `.` -- There are no spaces between the function name and the parentheses `()`. - -```python -import math - -print(math.log(10)) # recommended -print( math . log (10)) # non-recommended -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/datatypes.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/datatypes.md deleted file mode 100644 index ef7ea71a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/datatypes.md +++ /dev/null @@ -1,452 +0,0 @@ ---- -title: "Data Types" -linkTitle: "Data Types" -type: "docs" -weight: 2 -description: Data Types ---- - -## Syntax - -### Bool - -Boolean values are the two constant objects `False` and `True`. They are used to represent truth values (although other values can also be considered false or true). The built-in function bool() can be used to convert any value to a Boolean, if the value can be interpreted as a truth value. - -### Int - -Int, or integer, is an arbitrarily sized integer, positive or negative, without decimals, of 64 binary digits precision(-9,223,372,036,854,775,808~9,223,372,036,854,775,807). Int is created by int literals or as the result of built-in functions and operators. Unadorned integer literals (including `hex`, `octal` and `binary` numbers) yield integers. The constructor int() can be used to produce int of a specific type. - -Besides, integer literals may have an `SI` or `IEC` multiplier. - -- `SI`: General integer or fixed-point number form: `P`, `T`, `G`, `M`, `K`, `k`, `m`, `u`, `n`. -- `IEC`: Corresponding power of 2: `Pi`, `Ti`, `Gi`, `Mi`, `Ki`. - -```python -a = 1 # positive integer: 1 -b = -1 # negative integer: -1 -c = 0x10 # hexadecimal literal: 16 -d = 0o10 # octal literal: 8, or the form `010` -e = 0b10 # binary literal: 2 -f = 10Ki # integer literal with IEC multiplier: 10240 -g = 1M # integer literal with SI multiplier: 1000000 -h = int("10") # int constructor: 10 -i = int("10Ki") # int constructor with multiplier: 10240 -``` - -Notes: - -- Report an error if unable to represent an integer value precisely. - -### Float - -Float, floating-point, approximation to real numbers, positive or negative, containing one or more decimals, of 64 bit IEEE 754 floats. The constructor float() can be used to produce int of a specific type. - -```python -a = 1.10 -b = 1.0 -c = -35.59 -d = 32.3+e18 -f = -90. -g = -32.54e100 -h = 70.2-E12 -i = float("112") # float constructor -``` - -Notes: - -- Report an error if unable to represent a floating-point value due to overflow -- Report a warning if unable to represent a floating-point value due to underflow. Round to the nearest representable value if unable to represent a floating-point value due to limits on precision. These requirements apply to the result of any expression except for built-in functions for which an unusual loss of precision must be explicitly documented. - -#### None - -In KCL, `None` can indicate that the value of the object is empty, which is similar to `nil` in Go or `null` in Java, and corresponds to `null` in YAML and JSON. - -```python -a = None -b = [1, 2, None] -c = {"key1" = "value1", "key2" = None} -``` - -Please note that `None` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + None # error -b = int(None) # error -c = not None # True -d = None == None # True -e = None or 1 # 1 -f = str(None) # None -``` - -#### Undefined - -`Undefined` is similar to None, but its semantics is that a variable is not assigned any value and will not be output to YAML or JSON. - -```python -a = Undefined -b = [1, 2, Undefined] -c = {"key1" = "value1", "key2" = Undefined} -``` - -Please note that `Undefined` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + Undefined # error -b = int(Undefined) # error -c = not Undefined # True -d = Undefined == Undefined # True -e = Undefined or 1 # 1 -f = str(Undefined) # Undefined -``` - -### Common Numeric Operations - -Int and Float support the following operations (see built-in proposal for built-in details): - -- `x + y`: sum of x and y. -- `x - y`: difference of x and y. -- `x * y`: product of x and y. -- `x / y`: quotient of x and y. -- `x // y`: floored quotient of x and y. -- `x % y`: remainder of x / y. -- `x ** y`: x to the power y. -- `-x`: x negated. -- `+x`: x unchanged. -- `~x`: x bitwise negation. -- `abs(x)`: absolute value or magnitude of x. -- `int(x)`: x converted to integer. -- `float(x)`: x converted to floating point. - -KCL supports mixed arithmetic: when a binary arithmetic operator has operands of different numeric types, the operand with the "narrower" type is widened to that of the other, where integer is narrower than floating-point. - -### String - -Strings are immutable sequences of Unicode characters. String literals are written in a variety of ways: - -```python -'allows embedded "double" quotes' # Single quotes -"allows embedded 'single' quotes" # Double quotes -'''Three single quotes''', """Three double quotes""" # Triple quoted -``` - -Triple quoted strings may span multiple lines. - -Indexing a string produces strings of length 1, for a non-empty string s, `s[0] == s[0:1]`. - -```python -a = "Hello, World!" -b = a[2:5] # "llo" -c = a[-5:-2] # "orl" -d = a[::-1] # "'!dlroW ,olleH'" -``` - -- `str(x=None) -> str` - -Return a string. If _x_ is not provided, raise a runtime error. - -```python -x = str(3.5) # "3.5" -``` - -#### Members - -Built-in function and members of a string - -- `str#len() -> int` - Return the number of characters in the string. -- `capitalize() -> str` - Return a copy of the string with its first character (if any) capitalized and the rest lowercased. -- `count(sub: str, start: int = 0, end: int = -1) -> int` - Returns the number of (non-overlapping) occurrences of substring sub in string, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `endswith(suffix: str, start: int = 0, end: int = -1) -> bool` - Returns `True` if the string ends with the specified suffix, otherwise return `False`, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `find(sub: str, start: int = 0, end: int = -1) -> int` - Returns the lowest index where substring sub is found, or -1 if no such index exists, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `format(*args, **kwargs) -> str` - Perform string interpolation. Format strings contain replacement fields surrounded by curly braces {}. Anything that is not contained in braces is considered literal text, which is copied unchanged to the output. If you need to include a bracket character in the literal text, it can be escaped by doubling: A replacement field can be either a name, a number or empty. Values are converted to strings using the str function. -- `index(sub: str, start: int = 0, end: int = -1) -> int` - Returns the first index where sub is found, or raises an error if no such index exists, optionally restricting to `[start:end]` start being inclusive and end being exclusive. -- `isalnum() -> bool` - Returns True if all characters in the string are alphanumeric (`[a-zA-Z0-9]`) and there is at least one character, False otherwise. -- `isalpha() -> bool` - Returns True if all characters in the string are alphabetic (`[a-zA-Z]`) and there is at least one character. -- `isdigit() -> bool` - Returns True if all characters in the string are digits (`[0-9]`) and there is at least one character. -- `islower() -> bool` - Returns True if all cased characters in the string are lowercase and there is at least one character. -- `isspace() -> bool` - Returns True if all characters are white space characters and the string contains at least one character. -- `istitle() -> bool` - Returns True if the string is in title case and it contains at least one character. This means that every uppercase character must follow an uncased one (e.g., whitespace) and every lowercase character must follow a cased one (e.g., uppercase or lowercase). -- `isupper() -> bool` - Returns True if all cased characters in the string are uppercase and there is at least one character. -- `join(iterable: list) -> str` - Return a string which is the concatenation of the strings in iterable. A TypeError will be raised if there are any non-string values in iterable. The separator between elements is the string providing this method. Example: - - ```python - >>> "|".join(["a", "b", "c"]) - "a|b|c" - ``` - -- `lower() -> str` - Returns a copy of the string with all the cased characters converted to lowercase. -- `lstrip(chars: str) -> str` - Return a copy of the string with leading characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.lstrip() - 'spacious ' - >>> 'www.example.com'.lstrip('cmowz.') - 'example.com' - ``` - -- `replace(old: str, new: str, count: int) -> str` - Return a copy of the string with all occurrences of substring old replaced by new. If the optional argument count is given, only the first count occurrences are replaced. -- `rfind(sub: str, start: int = 0, end: int = -1) -> int` - Return the highest index in the string where substring sub is found, such that sub is contained within s[start:end]. Optional arguments start and end are interpreted as in slice notation. Return -1 on failure. -- `rindex(sub: str, start: int = 0, end: int = -1) -> int` - Returns the last index where sub is found, or raises an ValueError if no such index exists, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `rsplit(sep: str, maxsplit: int = -1) -> list` - Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done, the rightmost ones. If sep is not specified or None, any whitespace string is a separator. Except for splitting from the right, rsplit() behaves like split() which is described in detail below. -- `rstrip(chars: str) -> str` - Return a copy of the string with trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a suffix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.rstrip() - ' spacious' - >>> 'mississippi'.rstrip('ipz') - 'mississ' - ``` - -- `split(sep: str, maxsplit: int) -> list` - Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done (thus, the list will have at most maxsplit+1 elements). If maxsplit is not specified or -1, then there is no limit on the number of splits (all possible splits are made). - - If sep is given, consecutive delimiters are not grouped together and are deemed to delimit empty strings (for example, `'1,,2'.split(',')` returns `['1', '', '2']`). The sep argument may consist of multiple characters (for example, `'1<>2<>3'.split('<>')` returns `['1', '2', '3']`). Splitting an empty string with a specified separator returns `['']`. - - For example: - - ```python - >>> '1,2,3'.split(',') - ['1', '2', '3'] - >>> '1,2,3'.split(',', maxsplit=1) - ['1', '2,3'] - >>> '1,2,,3,'.split(',') - ['1', '2', '', '3', ''] - ``` - - If sep is not specified or is None, a different splitting algorithm is applied: runs of consecutive whitespace are regarded as a single separator, and the result will contain no empty strings at the start or end if the string has leading or trailing whitespace. Consequently, splitting an empty string or a string consisting of just whitespace with a `None` separator returns `[]`. - - For example: - - ```python - >>> '1 2 3'.split() - ['1', '2', '3'] - >>> '1 2 3'.split(maxsplit=1) - ['1', '2 3'] - >>> ' 1 2 3 '.split() - ['1', '2', '3'] - ``` - -- `splitlines(keepends: str) -> list` - Return a list of the lines in the string, breaking at line boundaries('\n', '\r\n', '\r'). Line breaks are not included in the resulting list unless keepends is given and true. - - This method splits on the following line boundaries. In particular, the boundaries are a superset of universal newlines. - - For example: - - ```python - >>> 'ab c\n\nde fg\rkl\r\n'.splitlines() - ['ab c', '', 'de fg', 'kl'] - >>> 'ab c\n\nde fg\rkl\r\n'.splitlines(keepends=True) - ['ab c\n', '\n', 'de fg\r', 'kl\r\n'] - ``` - - Unlike `split()` when a delimiter string sep is given, this method returns an empty list for the empty string, and a terminal line break does not result in an extra line: - - ```python - >>> "".splitlines() - [] - >>> "One line\n".splitlines() - ['One line'] - ``` - - For comparison, `split('\n')` gives: - - ```python - >>> ''.split('\n') - [''] - >>> 'Two lines\n'.split('\n') - ['Two lines', ''] - ``` - -- `startswith(prefix: str, start: int = 0, end: int = -1) -> bool` - Return `True` if string starts with the prefix, otherwise return False. prefix can also be a list of prefixes to look for. With optional start, test string beginning at that position. With optional end, stop comparing string at that position. -- `strip(chars: str) -> str` - Return a copy of the string with the leading and trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix or suffix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.strip() - 'spacious' - >>> 'www.example.com'.strip('cmowz.') - 'example' - ``` - - The outermost leading and trailing chars argument values are stripped from the string. Characters are removed from the leading end until reaching a string character that is not contained in the set of characters in chars. A similar action takes place on the trailing end. For example: - - ```python - >>> comment_string = '#....... Section 3.2.1 Issue #32 .......' - >>> comment_string.strip('.#! ') - 'Section 3.2.1 Issue #32' - ``` - -- `title() -> str` - Return a titlecased version of the string where words start with an uppercase character and the remaining characters are lowercase. - - For example: - - ```python - >>> 'Hello world'.title() - 'Hello World' - ``` - - The algorithm uses a simple language-independent definition of a word as groups of consecutive letters. The definition works in many contexts but it means that apostrophes in contractions and possessives form word boundaries, which may not be the desired result: - - ```python - >>> "they're bill's friends from the UK".title() - "They'Re Bill'S Friends From The Uk" - ``` - -- `upper() -> str` - Return a copy of the string with all the cased characters 4 converted to uppercase. Note that `s.upper().isupper()` might be `False` if s contains uncased characters or if the Unicode category of the resulting character(s) is not “Lu” (Letter, uppercase), but e.g., “Lt” (Letter, titlecase). -- `removeprefix(prefix: str) -> str` - If the string starts with the prefix string, return string[len(prefix):]. Otherwise, return a copy of the original string. - ```python - >>> "prefix-data".removeprefix("prefix-") - "data" - ``` -- `rermovesuffix(suffix: str) -> str` - If the string ends with the suffix string and that suffix is not empty, return string[:-len(suffix)]. Otherwise, return a copy of the original string. - ```python - >>> "data-suffix".removesuffix("-suffix") - "data" - ``` - -### List - -Lists are immutable sequences, typically used to store collections of homogeneous items (where the precise degree of similarity will vary by application). - -Lists may be constructed in several ways: - -- Using a pair of square brackets to denote the empty list: `[]` -- Using square brackets, separating items with commas: `[a]`, `[a, b, c]` -- Using a list comprehension: `[x for x in iterable]` -- Using the type constructor: list() or list(iterable) - -The constructor builds a list whose items are the same and in the same order as iterable’s items.Iterable may be either a sequence, a container that supports iteration, or an iterator object. If iterable is already a list, a copy is made and returned, similar to `iterable[:]`. For example, `list('abc')` returns `['a', 'b', 'c']` and `list([1, 2, 3])` returns `[1, 2, 3]`. If no argument is given, the constructor creates a new empty list `[]`. - -Lists implement all of the common sequence operations. - -#### Members - -- `len()` - Return the number of items in the list. - -### Common Sequence Operations - -The operations in the following table are supported by List and Dict. - -This table lists the sequence operations sorted in ascending priority. In the table, s and t are sequences of the same type, n, i, j and k are integers and x is an arbitrary object that meets any type and value restrictions imposed by s. - -The `in` and `not in` operations have the same priorities as the comparison operations. The + -(concatenation) and \* (repetition) operations have the same priority as the corresponding numeric operations. - -| Operation | Result | Notes | -| ------------ | -------------------------------------------------- | ----- | -| `x in s` | `True` if an item of s is equal to x, else `False` | #1 | -| `x not in s` | `False` if an item of s is equal to x, else `True` | #1 | -| `s + t` | the concatenation of s and t | #5 | -| `s[i]` | ith item of s, origin 0 | #2 | -| `s[i:j]` | slice of s from i to j | #2 #3 | -| `s[i:j:k]` | slice of s from i to j with step k | #2 #4 | -| `min(s)` | smallest item of s | | -| `max(s)` | largest item of s | | - -Notes: - -- 1. While the in and not in operations are used only for simple containment testing in the - general case, some specialized sequences (str) also use them for subsequence testing: - -```python ->>> "gg" in "eggs" -True -``` - -- 2. If i or j is negative, the index is relative to the end of sequence s: `s.len() + i` or `s.len() + j` is substituted. But note that -0 is still 0. -- 3. The slice of s from i to j is defined as the sequence of items with index k such that `i <= k < j`. If i or j is greater than `s.len()`, use `s.len()`. If i is omitted or None, use 0. If j is omitted or None, use `s.len()`. If i is greater than or equal to j, the slice is empty. -- 4. The slice of s from i to j with step k is defined as the sequence of items with index `x = i + n*k` such that `0 <= n < (j-i)/k`. In other words, the indices are `i`, `i+k`, `i+2*k`, `i+3*k` and so on, stopping when j is reached (but never including j). When k is positive, i and j are reduced to s.len() if they are greater. When k is negative, i and j are reduced to s.len() - - - If they are greater. If i or j are omitted or None, they become “end” values (which end depends on the sign of k). Note, k cannot be zero. If k is None, it is treated like 1. - -- 5. Concatenating immutable sequences always results in a new object. This means that building up a sequence by repeated concatenation will have a quadratic runtime cost in the total sequence length. To get a linear runtime cost, you must switch to one of the alternatives below: - - - if concatenating str objects, you can build a list and use `str.join()` at the end - -- 6. `index` raises `ValueError` when x is not found in s. Not all implementations support passing the additional arguments i and j. These arguments allow efficient searching of subsections of the sequence. Passing the extra arguments is roughly equivalent to using `s[i:j].index(x)`, only without copying any data and with the returned index being relative to the start of the sequence rather than the start of the slice. - -### Dict - -Dict is an immutable mapping object maps hashable values to arbitrary objects. A dictionary’s keys are almost arbitrary values. Values that are not hashable, that is, values containing lists, dictionaries may not be used as keys. Numeric types used for keys obey the normal rules for numeric comparison: if two numbers compare equal (such as 1 and 1.0) then they can be used interchangeably to index the same dictionary entry. (Note however, that since computers store floating-point numbers as approximations it is usually unwise to use them as dictionary keys.) Dict is ordered. The order of the keys is the order of their declaration. - -Dictionaries can be created by placing a comma-separated list of keys: value pairs within braces, for example: `{'jack': 4098, 'sjoerd': 4127}` or `{4098: 'jack', 4127: 'sjoerd'}`, by the dict constructor, or list/dict comprehension. - -- `dict(obj)` - -Return a new dictionary initialized from an optional positional argument and a possibly empty set of keyword arguments.If no positional argument is given, an empty dictionary is created. If a positional argument is given and it is a mapping object, a dictionary is created with the same key-value pairs as the mapping object. Otherwise, the positional argument must be an iterable object. Each item in the iterable must itself be an iterable with exactly two objects. The first object of each item becomes a key in the new dictionary, and the second object the corresponding value. If a key occurs more than once, the last value for that key becomes the corresponding value in the new dictionary. If keyword arguments are given, the keyword arguments and their values are added to the dictionary created from the positional argument. If a key being added is already present, the value from the keyword argument replaces the value from the positional argument. To illustrate, the following examples all return a dictionary equal to `{"one": 1, "two": 2, "three": 3}`: - -```python ->>> a = {'two': 2, 'one': 1, 'three': 3} ->>> b = {'one': 1, 'two': 2, 'three': 3} ->>> c = {'three': 3, 'one': 1, 'two': 2} ->>> a == b == c -True -``` - -Providing keyword arguments as in the first example only works for keys that are valid KCL identifiers. Otherwise, any valid keys can be used. - -In the dict comprehension, key/value pairs yielded by the generator expression is set in the dictionary in the order yielded: the first occurrence of the key determines its insertion order, and the last determines the value associated to it. - -```python ->>> {str(i): 2 * i for i in range(3)} -{"0": 0, "1": 2, "2": 4} - ->>> a = {"one": 1, "two": 2, "three": 3} ->>> b = {k: v for k, v in a if v >= 2} -{two: 2, three: 3} -``` - -#### Operations & Members - -These are the operations that dictionaries the support. - -- `list(d)` - Return a list of all the keys used in the dictionary d. -- `len()` - Return the number of items in the dictionary d. -- `d[key]` - Return the item of d with key. Return Undefined if key is not in the map. -- `key in d` - Return True if d has a key, else False. -- `key not in d` - Equivalent to not key in d. -- `d.key` - Return the item of d with key. Return Undefined if key is not in the map. - -Dictionaries compare equal if and only if they have the same (key, value) pairs(keys' ordering matters). Order comparisons (‘<’, ‘<=’, ‘>=’, ‘>’) raise TypeError. - -```python ->>> d = {"one": 1, "two": 2, "three": 3, "four": 4} ->>> d -{'one': 1, 'two': 2, 'three': 3, 'four': 4} ->>> list(d) -['one', 'two', 'three', 'four'] -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/expressions.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/expressions.md deleted file mode 100644 index b52c10f3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/expressions.md +++ /dev/null @@ -1,915 +0,0 @@ ---- -title: "Expressions" -linkTitle: "Expressions" -type: "docs" -weight: 2 -description: Expressions ---- - -## Syntax - -In KCL, an expression specifies the computation of a value. - -The syntax is the following: - -```bnf -expression: test ("," test)* -test: if_expr | primary_expr | unary_expr | binary_expr -``` - -KCL expressions consist of `if` expression, `primary` expression, `unary` expression, and `binary` expression. - -### Primary Expressions - -Primary expressions are the operands for unary and binary expressions. - -Operands are self-delimiting. An **operand** may be followed by any number of selector dot, a function call, or slice suffixes, to form a primary expression. The grammar uses `expression`, where a multiple-component expression is allowed, and `test` where it accepts an expression of only a single component. - -Syntax: - -```bnf -primary_expr: operand | primary_expr select_suffix | primary_expr call_suffix | primary_expr subscript_suffix -``` - -### Operands - -Operand denotes the elementary value in an expression. An operand may be an identifier, a literal, or a parenthesized expression. - -Syntax: - -```bnf -operand: operand_name | number | string | "True" | "False" | "None" | "Undefined" | list_expr | list_comp | dict_expr | dict_comp | "(" expression ")" -operand_name: identifier | qualified_identifier -``` - -### Identifiers - -In KCL, an identifier is a name, may with selectors, that identifies a value. - -Syntax: - -```bnf -identifier: NAME -``` - -Examples: - -```python -x -a -_b -``` - -Use the `$` character prefix to define keyword identifiers. - -```python -$if = 1 -$else = "s" -``` - -Please note: whether the non-keyword identifier is prefixed with `$` has the same effect. - -```python -_a = 1 -$_a = 2 # equal to `_a = 2` -``` - -To simplify the definition of the qualified identifier, such as 'pkg.type', we additionally define `qualified_identifier`: - -Syntax: - -```bnf -qualified_identifier: identifier "." identifier -``` - -Examples: - -```python -pkg.a -``` - -The package name in qualified_identifier must be imported. - -### Basic Literals - -Basic literals supported in KCL are `int`, `float`, `string` and `bool` including `True` and `False`. Evaluation of basic literal yields a value of the given type with the given value. - -Syntax: - -```bnf -operand: number | string | "True" | "False" | "None" | "Undefined" -``` - -Examples: - -```python -1 -2.3 -"abc" -True -False -None -Undefined -``` - -See more details about **data type** spec. - -### Parenthesized Expressions - -An expression enclosed in parentheses yields the result of that expression. - -Syntax: - -```bnf -operand: '(' expression ')' -``` - -Examples: - -```python -x = (1 + 2) * (3 + 4) # 21 -``` - -### Dictionary Expressions - -A dictionary expression is a comma-separated immutable list of colon-separated key/value expression pairs, enclosed in curly brackets, and it yields a new dictionary object. An optional comma may follow the final pair. - -```bnf -config_expr: '{' config_entries '}' -config_entries: config_entry [config_entry*] -config_comp: '{' (config_entry comp_clause+) '}' -config_entry: expr (':' | '=' | '+=') expr | double_star_expr | if_entry -double_star_expr: "**" expression -if_entry: - 'if' expr ';' if_entry_exec_block - ('elif' expr ':' if_entry_exec_block)* - ('else' ':' if_entry_exec_block)? -NEWLINE: '/r?/n' -``` - -Examples: - -```python -{} -{"one": 1} -{"one": 1, "two": 2} -``` - -The key and value expressions are evaluated in left-to-right order. Evaluation fails if the same key is used multiple times. - -Only hashable values may be used as the keys of a dictionary. This includes all built-in types except dictionaries, and lists. - -We can ignore the comma `,` at the end of the line for writing dict key-value pairs in multiple lines: - -```python -data = { - "key1" = "value1" # Ignore the comma ',' at the end of line - "key2" = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -We can ignore the key quotation marks when we writing simple literals on the key. - -```python -data = { - key1 = "value1" # Ignore the comma ',' at the end of line - key2 = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -In addition, the **config selector expressions** can be used to init a schema instance. - -```python -person = { - base.count = 2 - base.value = "value" - labels.key = "value" -} # {"base": {"count": 2, "value": "value"}, "labels": {"key": "value"}} -``` - -We can **merge** dict using the dict unpacking operator `**` like this: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = {**_part1, **_part2} # {"a: "b", "c": "d"} -``` - -We can use `if expressions` to dynamically add elements to the dict element, elements that meet the conditions are added to the dict, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = { - key1 = "value1" - if a == 1: key2 = "value2" - if a > 0: key3 = "value3" - if a < 0: key4 = "value4" -} # {"key1": "value1", "key2": "value2", "key3": "value3"} -``` - -```python -a = 1 # 1 -data1 = { - key1 = "value1" - if a == 1: - key2 = "value2" - elif a > 0: - key3 = "value3" - else: - key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -data2 = { - key1 = "value1" - if a == 1: key2 = "value2" - elif a > 0: key3 = "value3" - else: key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -``` - -### List Expressions - -A list expression is a comma-separated immutable list of element expressions, enclosed in square brackets, and it yields a new list. An optional comma may follow the last element expression. - -```bnf -list_expr: '[' [list_item [',']] ']' -list_item: test | "*" primary_expr | if_expr -``` - -Element expressions are evaluated in left-to-right order. - -Examples: - -```python -[] # [], empty list -[1] # [1], a 1-element list -[1, 2, 3] # [1, 2, 3], a 3-element list -``` - -We can use `if expressions` to dynamically add elements to the list element, elements that meet the conditions are added to the list, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = [ - 1 - if a == 1: 2 - if a > 0: 3 - if a < 0: 4 -] # [1, 2, 3] -``` - -```python -a = 1 # 1 -data1 = [ - 1 - if a == 1: - 2 - elif a == 2: - 3 - else: - 3 -] # [1, 2] -data2 = [ - 1 - if a == 1: 2 - elif a == 2: 2 - else: 3 -] # [1, 2] -``` - -### Comprehensions - -A comprehension constructs a new list or dictionary value by looping over one or more iterables and evaluating a body expression that produces successive elements of the result. - -Syntax: - -```bnf -list_comp: '[' list_item comp_clause+ ']' . -dict_comp: '{' entry comp_clause+ '}' . - -comp_clause: 'for' loop_variables [","] 'in' test ['if' test] -loop_variables: primary_expr (',' primary_expr)* -``` - -A list comprehension consists of a single expression followed by one or more clauses, the first of which must be a `for` clause. Each `for` clause resembles a `for` statement, and specifies an iterable operand and a set of variables to be assigned by successive values of the iterable. An `if` cause resembles an `if` statement, and specifies a condition that must be met for the body expression to be evaluated. A sequence of `for` and `if` clauses acts like a nested sequence of `for` and `if` statements. - -Examples: - -```python -[x * x for x in range(5)] # [0, 1, 4, 9, 16] -[x * x for x in range(5) if x % 2 == 0] # [0, 4, 16] -[[x, y] for x in range(5) \ - if x % 2 == 0 \ - for y in range(5) \ - if y > x] # [[0, 1], [0, 2], [0, 3], [0, 4], [2, 3], [2, 4]] -``` - -Besides, we can use two variables in the list comprehension, the first variable denotes the list index and the second variable denotes the list item. - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use `_` to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -A dict comprehension resembles a list comprehension, but its body is a pair of expressions, key: value, separated by a colon, and its result is a dictionary containing the key/value pairs for which the body expression was evaluated. Evaluation fails if the value of any key is un-hashable. - -Besides, we can use two variables in the dict comprehension, the first variable denotes the dict key and the second variable denotes the dict value of the key. - -```python -data = {"key1" = "value1", "key2" = "value2"} -# Single variable loop -dataKeys1 = {k: k for k in data} # {"key1": "key1", "key2": "key2"} -dataValues1 = {k: data[k] for k in data} # {"key1": "value1", "key2": "value2"} -# Double variable loop -dataKeys2 = {k: k for k, v in data} # {"key1": "key1", "key2": "key2"} -dataValues2 = {v: v for k, v in data} # {"value1": "value1", "value2": "value2"} -dataFilter = {k: v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use `_` to ignore loop variables -dataKeys3 = {k: k for k, _ in data} # {"key1": "key1", "key2": "key2"} -dataValues3 = {v: v for _, v in data} # {"value1": "value1", "value2": "value2"} -``` - -As with a `for` loop, the loop variables may exploit compound assignment: - -```python -[x * y + z for [x, y], z in [[[2, 3], 5], [["o", 2], "!"]]] # [11, 'oo!'] -``` - -KCL does not accept an un-parenthesized list as the operand of a for clause: - -```python -[x * x for x in 1, 2, 3] # parse error: unexpected comma -``` - -Comprehensions defines a new lexical block, so assignments to loop variables have no effect on variables of the same name in an enclosing block: - -```python -x = 1 -_ = [x for x in [2]] # new variable x is local to the comprehension -print(x) # 1 -``` - -The operand of a comprehension's first clause (always a for) is resolved in the lexical block enclosing the comprehension. In the examples below, identifiers referring to the outer variable named x have been distinguished by subscript. - -```python -x0 = [1, 2, 3] -[x * x for x in x0] # [1, 4, 9] -[x * x for x in x0 if x % 2 == 0] # [4] -``` - -All subsequent for and if expressions are resolved within the comprehension's lexical block, as in this rather obscure example: - -```python -x0 = [[1, 2], [3, 4], [5, 6]] -[x * x for x in x0 for x in x if x % 2 == 0] # [4, 16, 36] -``` - -which would be more clearly rewritten as: - -```python -x = [[1, 2], [3, 4], [5, 6]] -[z * z for y in x for z in y if z % 2 == 0] # [4, 16, 36] -``` - -### Conditional Expressions - -A conditional expression has the form `a if cond else b`. It first evaluates the condition `cond`. If it's true, it evaluates `a` and yields its value; otherwise it yields the value of `b`. - -Syntax: - -```bnf -if_expr: test "if" test "else" test -``` - -Examples: - -```python -x = True if enabled else False # if enabled is -``` - -### Unary Expressions - -In KCL, supported unary operators are `+`, `-`, `~`, and `not`. - -Syntax: - -```bnf -unary_expr: ("+" | "-" | "~") primary_expr - | "not" test -``` - -Usage: - -```bnf -+ number unary positive (int, float) -- number unary negation (int, float) -~ number unary bitwise inversion (int) -not x logical negation (any type) -``` - -The `+` and `-` operators may be applied to any number (int or float) and return the number. -The `not` operator returns the negation of the truth value of its operand. - -Examples: - -```python -~1 # -2 -~-1 # 0 -~0 # -1 -not True # False -not 0 # True -``` - -### Binary Expressions - -In KCL, binary expressions consist of `comparisons`, `logical operations`, `arithmetic operations` and `membership tests`. - -Syntax: - -```bnf -binary_expr: test bin_op test -bin_op: 'or' - | 'and' - | '==' | '!=' | '<' | '>' | '<=' | '>=' - | 'in' | 'not' 'in' - | '|' - | '^' - | '&' - | '-' | '+' - | '*' | '%' | '/' | '//' - | '<<' | '>>' -``` - -#### Logical Operations - -The `or` and `and` operators yield the logical disjunction and conjunction of their arguments, which need not be Booleans. - -The expression `x or y` yields the value of `x` if its truth value is `True`, or the value of `y` otherwise. - -```python -False or False # False -False or True # True -True or True # True -1 or "hello" # 1 -``` - -Similarly, `x` and `y` yields the value of `x` if its truth value is `False`, or the value of `y` otherwise. - -```python -False and False # False -False and True # False -True and True # True -1 and "hello" # "hello" -``` - -These operators use "short circuit" evaluation, so the second expression is not evaluated if the value of the first expression has already determined the result, allowing constructions like these: - -```python -x and x[0] == 1 # x[0] is not evaluated if x is empty -len(x) == 0 or x[0] == "" -not x or not x[0] -``` - -#### Comparisons - -The `==` operator reports whether its operands are equal; the `!=` operator is its negation. - -The operators `<`, `>`, `<=`, and `>=` perform an ordered comparison of their operands. It is an error to apply these operators to operands of unequal type, unless one of the operands is an `int` and the other is a `float`. Of the built-in types, only the following support ordered comparison, using the ordering relation shown: - -```bnf -NoneType # None <= None -bool # False < True -int # mathematical -float # as defined by IEEE 754 -string # lexicographical -list # lexicographical -``` - -Comparison of floating-point values follows the IEEE 754 standard, which breaks several mathematical identities. For example, if `x` is a `NaN` value, the comparisons `x < y`, `x == y`, and `x > y` all yield false for all values of `y`. - -The remaining built-in types support only equality comparisons. Values of type `dict` and `schema` compare equal if their elements compare equal, and values of type function or `builtin_function_or_method` are equal only to themselves. - -```bnf -dict # equal contents -schema # equal exported-attributes -function # identity -builtin_function_or_method # identity -``` - -#### Arithmetic Operations - -The following table summarizes the binary arithmetic operations available for built-in types: - -```bnf -Arithmetic (int or float; result has type float unless both operands have type int) - number + number # addition - number - number # subtraction - number * number # multiplication - number / number # real division (result is always a float) - number // number # floored division - number % number # remainder of floored division - number ^ number # bitwise XOR - number << number # bitwise left shift - number >> number # bitwise right shift - -Concatenation - string + string - list + list - -Repetition (string/list) - int * sequence - sequence * int - -Union - int | int - list | list - dict | dict - schema | schema - schema | dict -basictype | basictype -``` - -The operands of the arithmetic operators `+`, `-`, `*`, `//`, and `%` must both be numbers (`int` or `float`) but need not have the same type. The type of the result has type `int` only if both operands have that type. The result of real division / always has type `float`. - -The `+` operator may be applied to non-numeric operands of the same type, such as two lists, or two strings, in which case it computes the concatenation of the two operands and yields a new value of the same type. - -```python -"Hello, " + "world" # "Hello, world" -[1, 2] + [3, 4] # [1, 2, 3, 4] -``` - -The `*` operator may be applied to an integer n and a value of type `string`, `list`, in which case it yields a new value of the same sequence type consisting of n repetitions of the original sequence. The order of the operands is immaterial. Negative values of n behave like zero. - -```python -'mur' * 2 # 'murmur' -3 * range(3) # [0, 1, 2, 0, 1, 2, 0, 1, 2] -``` - -The `&` operator requires two operands of the same type, such as `int`. For integers, it yields the bitwise intersection (AND) of its operands. - -The `|` operator likewise computes bitwise, unions basic types and unions collection and schema data, such as **list**, **dict** and **schema**. - -Computing bitwise examples: - -```python -0x12345678 | 0xFF # 0x123456FF -``` - -Unioning basic types examples: - -```python -schema x: - a: int | str # attribute a could be a int or string -``` - -A union type is used to define a schema attribute type. See more details in **schema** spec. -Supported types in a union type are `int`, `str`, `float`, `bool`, `list` and `dict`. - -Unioning collection and schema data: - -- Unioning List. Overwrite the list expression on the right side of the operator `|` to the list variable on the left side of the operator one by one according to the **index**. - -```python -_a = [1, 2, 3] -_b = [4, 5, 6, 7] -x = _a | _b # [4, 5, 6, 7] 4 -> 1; 5 -> 2; 6 -> 3; 7 -> None -``` - -Unioning to the specific index or all elements is still under discussion. - -- Unioning Dict. Union the dict expression on the right side of the operator `|` one by one to the dict variable on the left side of the operator according to the **key** - -```python -_a = {key1 = "value1"} -_b = {key1 = "overwrite", key2 = "value2"} -_c = _a | _b # {"key1": "overwrite", "key2": "value2"} -``` - -The union of collection and schema is a new one whose attributes are unioning b to a, preserving the order of the attributes of the operands, left before right. - -Unioning to the specific key or all keys is still under discussion. - -- Unioning Schema. - -The union operation for schema is similar to dict. - -Schema union could be done as: - -```bnf -schema Person: - firstName: str - lastName: str - -_a = Person { - firstName = "John" -} -_b = {lastName = "Doe"} -_a = _a | _b # {"firstName": "John", "lastName": "Doe"} -``` - -Unioning to a specific attribute is still under discussion. Unioning to all attributes is not applicable to schema instances. - -See **selector expression** in **expression** spec for more details. - -The `^` operator accepts operands of `int`. For integers, it yields the bitwise XOR (exclusive OR) of its operands. - -The `<<` and `>>` operators require operands of `int` type both. They shift the first operand to the left or right by the number of bits given by the second operand. It is a dynamic error if the second operand is negative. Implementations may impose a limit on the second operand of a left shift. - -```python -0x12345678 & 0xFF # 0x00000078 -0b01011101 ^ 0b110101101 # 0b111110000 -0b01011101 >> 2 # 0b010111 -0b01011101 << 2 # 0b0101110100 -``` - -#### Membership Tests - -Usage: - -```bnf - any in sequence (list, dict, schema, string) - any not in sequence -``` - -The `in` operator reports whether its first operand is a member of its second operand, which must be a list, dict, schema, or string. The `not in` operator is its negation. Both return a Boolean. - -The meaning of membership varies by the type of the second operand: the members of a list are its elements; the members of a dict are its keys; the members of a string are all its substrings. - -```python -1 in [1, 2, 3] # True - -d = {"one" = 1, "two" = 2} -"one" in d # True -"three" in d # False -1 in d # False -[] in d # False - -"nasty" in "dynasty" # True -"a" in "banana" # True -"f" not in "way" # True - -d = data {one = 1, two = 2} # data is a schema with attributes one and two -"one" in d # True -"three" in d # False -``` - -### Function Invocations - -KCL allows calling built-in functions and functions from built-in and system modules. Whether KCL allows defining new functions is under discussion. - -Syntax: - -```bnf -call_suffix: "(" [arguments [","]] ")" -arguments: argument ("," argument)* -argument: test | identifier "=" test | "*" test | "**" test -``` - -To call a function, the basic way is shown as the following code excerpt: - -```python -print("An argument") - -import math -# 2 powers 3 is 8. -a = math.pow(2, 3) -``` - -As you can see, arguments are separated with `,`. Arguments can only be passed in this way. KCL supports positional arguments and key-value arguments. - -Note that: - -- Some functions have parameters with default values. -- Some functions accept variadic arguments. - -When an argument is not supplied for a parameter without a default value, -an error will be reported. - -### Selector Expressions - -A selector expression selects the attribute or method of the value. - -#### Select Attributes - -Syntax: - -```bnf -select_suffix: ["?"] "." identifier -``` - -KCL provides a wealth of ways to identify or filter attributes. - -x.y - -- schema: it denotes the attribute value of a schema `x` identified by `y` -- package: it denotes the identifier of a package `x` identified by `y` - -Examples: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -name = person.name # "Alice" -age = person.age # 18 -``` - -x?.y - -If the x if None/Undefined or empty(empty list or dict), just return None, otherwise behave as x.y. - -Examples - -```python -noneData = None -data?.name # None - -emptyDict = {} -emptyDict?.name # None - -emptyList = [] -emptyList?[0] # None -``` - -As a supplementary of the `selector` expression in KCL code, the KCL compiler needs to provide corresponding identifying and filtering features through the command line and api form. - -#### Select Methods - -Syntax: - -```bnf -select_suffix: "." identifier -``` - -A `identifier` identifies method belongs to the built-in types `string`, `list`, `dict`, and `schema`. - -- A selector expression fails if the value does not have an attribute of the specified name. -- A selector expression that selects a method typically appears within a call expression, as in these examples: - -Examples: - -```python -["able", "baker", "charlie"].index("baker") # 1 -"banana".count("a") # 3 -"banana".reverse() # error: string has no .reverse field or method -Person.instances() # all instances of schema Person -``` - -But when not called immediately, the selector expression evaluates to a bound method, that is, a method coupled to a specific receiver value. A bound method can be called like an ordinary function, without a receiver argument: - -```bnf -f = "banana".count -f # -f("a") # 3 -f("n") # 2 -``` - -### Index Expressions - -An index expression `a[i]` yields the `i` th element of an indexable type such as a string or list. The index `i` must be an `int` value in the range `-n` ≤ `i` < `n`, where `n` is `len(a)`; any other index results in an error. - -Syntax: - -```bnf -subscript_suffix: "[" [test] "]" -``` - -A valid negative index `i` behaves like the non-negative index `n+i`, allowing for convenient indexing relative to the end of the sequence. - -```python -"abc"[0] # "a" -"abc"[1] # "b" -"abc"[-1] # "c" - -["zero", "one", "two"][0] # "zero" -["zero", "one", "two"][1] # "one" -["zero", "one", "two"][-1] # "two" -``` - -An index expression `d[key]` may also be applied to a dictionary `d`, to obtain the value associated with the specified key. It returns `Undefined` if the dictionary contains no such key. - -An index expression appearing on the left side of an assignment causes the specified list or dictionary element to be updated: - -```python -a = range(3) # a == [0, 1, 2] -b = a[2] # 2 - - -``` - -It is a dynamic error to attempt to update an element of an immutable type, such as a list or string, or a frozen value of a mutable type. - -### Slice Expressions - -A slice expression `a[start:stop:stride]` yields a new value containing a sub-sequence of `a`, which must be a string, or list. - -```bnf -subscript_suffix: "[" [test] [":" [test] [":" [test]]] "]" -``` - -Each of the `start`, `stop`, and `stride` operands is optional; if present, and not `None`, each must be an integer. -The `stride` value defaults to 1. If the stride is not specified, the colon preceding it may be omitted too. It is an error to specify a stride of zero. - -Conceptually, these operands specify a sequence of values `i` starting at start and successively adding `stride` until `i` reaches or passes `stop`. The result consists of the concatenation of values of `a[i]` for which `i` is valid.` - -The effective start and stop indices are computed from the three operands as follows. Let `n` be the length of the sequence. - -**If the stride is positive**: If the `start` operand was omitted, it defaults to -infinity. If the `end` operand was omitted, it defaults to +infinity. For either operand, if a negative value was supplied, `n` is added to it. The `start` and `end` values are then "clamped" to the nearest value in the range 0 to `n`, inclusive. - -**If the stride is negative**: If the `start` operand was omitted, it defaults to +infinity. If the `end` operand was omitted, it defaults to -infinity. For either operand, if a negative value was supplied, `n` is added to it. The `start` and `end` values are then "clamped" to the nearest value in the range -1 to `n`-1, inclusive. - -```python -"abc"[1:] # "bc" (remove first element) -"abc"[:-1] # "ab" (remove last element) -"abc"[1:-1] # "b" (remove first and last element) -"banana"[1::2] # "aaa" (select alternate elements starting at index 1) -"banana"[4::-2] # "nnb" (select alternate elements in reverse, starting at index 4) -``` - -It's not allowed to define a slice expression as a left value in KCL. -Cause list and string are immutable, re-slicing can directly operate to operand to ensure better performance. - -#### Quantifier Expressions - -Quantifier expressions act on collection: list or dict, generally used to obtain a certain result after processing the collection, mainly in the following four forms: - -```bnf -quant_expr: quant_op [ identifier ',' ] identifier 'in' quant_target '{' expr ['if' expr] '}' -quant_target: string | identifier | list_expr |list_comp | dict_expr | dict_comp -quant_op: 'all' | 'any' | 'filter' | 'map' -``` - -- **all** - - Used to detect that all elements in the collection satisfy the given logical expression, and return a boolean value as the result. - - Only when all elements in the collection satisfy the expression true, the `all` expression is true, otherwise it is false. - - If the original collection is empty, return true. - - Supports short-circuiting of logical expressions during expression execution. -- **any** - - Used to detect that at least one element in the collection satisfies the given logical expression, and returns a boolean value as the result. - - When at least one element in the collection satisfies the expression true, the `any` expression is true, otherwise it is false. - - If the original collection is empty, return false. - - Supports short-circuiting of logical expressions during expression execution. -- **map** - - Generate a new **list** by mapping the elements in the original collection. - - The length of the new list is exactly the same as the original collection. -- **filter** - - By logically judging and filtering the elements in the original collection, and returning the filtered sub-collection. - - Only when the element judges the expression to be true, it is added to the sub-collection. - - The type (list, dict and schema) of the new collection is exactly the same as the original collection, and the length range is `[0, len(original-collection)]`. - -**all** and **any** expression sample codes: - -```python -schema Config: - volumes: [{str:}] - services: [{str:}] - - check: - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - }, "invalid cluster ip" - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } -``` - -**map** and **filter** expression sample codes: - -```python -a = map e in [{name = "1", value = 1}, {name = "2", value = 2}] { - {name = e.name, value = int(e.value) ** 2} -} # [{"name": "1", value: 1}, {"name": "2", "value": 4}] - -b = map k, v in {a = "foo", b = "bar"} { v } # ["foo", "bar"] - -c = filter e in [{name = "1", value = 1}, {name = "2", value = 2}] { - int(e.value) > 1 -} # [{"name": "2", "value": 2}] - -d = filter _, v in {a = "foo", b = "bar"} { - v == "foo" -} # {"a": "foo"} -``` - -Please pay attention to distinguish the difference between any expression and any type. When `any` is used in type annotations, it means that the value of the variable is arbitrary, while the any expression means that one of the elements in a set satisfies the condition. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/index.md deleted file mode 100644 index c3ecc162..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/index.md +++ /dev/null @@ -1 +0,0 @@ -# KCL 语言规范 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/lexical.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/lexical.md deleted file mode 100644 index 773efecb..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/lexical.md +++ /dev/null @@ -1,213 +0,0 @@ ---- -title: "Lexical" -linkTitle: "Lexical" -type: "docs" -weight: 2 -description: Lexical ---- - -## Lexical Conventions - -This chapter covers the KCL lexical conventions including grammar notation, lines, comments and tokens. - -## Grammar Notation - -The syntax is specified using Extended Backus-Naur Form (EBNF), porting to lark parser ([https://github.com/lark-parser/lark](https://github.com/lark-parser/lark)). - -``` -- name grammar production -- NAME lexical token -- "x" lexical token -- () grouping -- | alternation -- [] option (0 or 1 times) -- ? option (0 or 1 times) -- * repetition (0 to n times) -- + repetition (1 to n times) -``` - -## Source File Encoding - -KCL source code is Unicode text encoded in **UTF-8**. - -The following are basic Unicode elements, which will be used in literal notations. - -``` -newline ::= U+000A -quota ::= singlequote | doublequote -singlequote ::= U+0027 -doublequote ::= U+0022 -source character ::= Unicode code point -``` - -The form a...b in literal notations represents the set of characters from a through b. - -## Line Structure - -The line structure of KCL programs is equivalent to that of Python. - -A KCL program is divided into a number of logical lines. Each logical line consists of one or more physical lines. - -A token named `NEWLINE` is used to divide logical lines. - -A physical line is a sequence of characters end with a line termination sequence, which can be the ASCII LF (linefeed) character, the ASCII sequence CR LF (return followed by linefeed), or the ASCII CR (return) character. - -### Explicit Line Joining - -To join multiple physical lines into one logical line, the `\` character can be used. The character should be the last none-space character in each physical line except the very last line. - -> **note** -> -> Any character except the ASCII space, tab (`\t`) and formfeed (`\f`) is considered a none-space character. - -- A line ending in a backslash cannot carry a comment (, which will be introduced shortly afterwards). -- A backslash does not continue a comment. -- A backslash does not continue a token except for string literals (i.e., tokens other than string literals cannot be split across physical lines using a backslash). -- A backslash is illegal elsewhere on a line outside a string literal. - -### Implicit Line Joining - -Expressions in parentheses, square brackets or curly braces can be split over more than one physical line without using backslashes. - -- Implicitly continued lines can carry comments. -- The indentation of the continuation lines is not important. -- Blank continuation lines are allowed. -- There is no `NEWLINE` token between implicit continuation lines. -- Implicitly continued lines can also occur within triple-quoted strings (see below); in that case they cannot carry comments. - -### Blank Lines - -### Indentation - -### Comments - -Starting with a `#` character that is not part of a string literal is a comment. A comment ends at the end of the physical line. - -A comment signifies the end of the logical line unless the implicit line joining rules are invoked. - -Comments are ignored by the syntax. - -### Identifiers and Keywords - -Identifiers (also referred to as names) are described by the following lexical definitions. - -Within the ASCII range (from `U+0001` to `U+007F`), the valid characters for identifiers are the uppercase and lowercase letters `A` through `Z`, the underscore `_` and, except for the first character, the digits `0` through `9`. - -Identifiers are unlimited in length. The case is significant. - -### Keywords - -The following identifiers are used as reserved words, or keywords of the language, and cannot be used as ordinary identifiers. They must be spelled exactly as written here: - -```python -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -The following tokens are not used, but they are reserved as possible future keywords: - -```python -pass return validate rule flow -def del raise except try -finally while from with yield -global nonlocal struct class final -``` - -### Literals - -Literals are notations for constant values of some built-in types. - -### String Literals - -String literals are described by the following lexical definitions: - -``` -stringliteral ::= [stringprefix](shortstring | longstring) -stringprefix ::= "r" | "R" -shortstring ::= "'" shortstringitem* "'" | '"' shortstringitem* '"' -longstring ::= "'''" longstringitem* "'''" | '"""' longstringitem* '"""' -shortstringitem ::= shortstringchar | stringescapeseq -longstringitem ::= longstringchar | stringescapeseq -shortstringchar ::= -longstringchar ::= -stringescapeseq ::= "\" -``` - -Multiple adjacent string or bytes literals (delimited by whitespace),possibly using different quoting conventions, are allowed, and their meaning is the same as their concatenation. - -### Numeric Literals - -There are two types of numeric literals: integers and floating-point numbers. - -Integer literals are described by the following lexical definitions: - -``` -integer ::= decinteger | bininteger | octinteger | hexinteger -decinteger ::= nonzerodigit (["_"] digit)* | "0"+ (["_"] "0")* -bininteger ::= "0" ("b" | "B") (["_"] bindigit)+ -octinteger ::= "0" ("o" | "O") (["_"] octdigit)+ -hexinteger ::= "0" ("x" | "X") (["_"] hexdigit)+ -nonzerodigit ::= "1"..."9" -digit ::= "0"..."9" -bindigit ::= "0" | "1" -octdigit ::= "0"..."7" -hexdigit ::= digit | "a"..."f" | "A"..."F" -``` - -Floating-point literals are described by the following lexical definitions: - -``` -floatnumber ::= pointfloat | exponentfloat -pointfloat ::= [digitpart] fraction | digitpart "." -exponentfloat ::= (digitpart | pointfloat) exponent -digitpart ::= digit (["_"] digit)* -fraction ::= "." digitpart -exponent ::= ("e" | "E") ["+" | "-"] digitpart -``` - -## Operators and Delimiters - -### Operators - -The following tokens are operators: - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != @ -``` - -### Delimiters - -The following tokens serve as delimiters in the grammar: - -```python -( ) [ ] { } -, : . ; = += --= *= **= /= //= %= -<<= >>= &= |= ^= -``` - -The period can also occur in floating-point literals. - -The following printing ASCII characters have special meaning as part of other tokens or are otherwise significant to the lexical analyzer: - -``` -' " # \ -``` - -The following printing ASCII characters are not used in KCL. Their occurrence outside string literals and comments is an unconditional error: - -``` -? ` -``` - -## Reference - -Since the lexical conventions of KCL is very similar to that of Python, we use the following document as the reference when writing this chapter. - -- [https://docs.python.org/3/reference/lexical_analysis.html](https://docs.python.org/3/reference/lexical_analysis.html) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/variables.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/variables.md deleted file mode 100644 index b3e1c539..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/variables.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: "Variables" -linkTitle: "Variable" -type: "docs" -weight: 2 -description: Variable ---- - -In KCL, variables can be defined using assign statements. For example, the following statement defines a variable `spam` to a string `"ham"`. - -```python -spam = "ham" -``` - -There are two types of variables, which are global variables and list comprehension local variables. - -- A global variable is defined not within any context. -- A comprehension local variable is defined inside a comprehension. - -A variable can be used after definition, until the end of the current scope. - -For a global variable, the scope is the module it is defined in. Note that a module can consists of multiple source files. - -For a list comprehension local variable, the scope is the list comprehension it is defined in. - -More information on modules, list comprehensions and scopes will be discussed in later chapters. - -## Immutability - -Global variables are immutable. In other words, once defined such a variable cannot be redefined (or, i.e., modified). - -The following code is illegal, and KCL will report an error during evaluation. - -```python -spam = "ham" -spam = "eggs" # Error: The immutability rule is violated! -``` - -- A variable starts with the `_` character is mutable. - -```python -_spam -cond = True -if cond: - _spam = "ham" -else: - _spam = "eggs" -``` - -## Variable Exporting - -As shown in the preview chapter, KCL is able to export evaluation results to the standard output according to a target data format. - -The rules are the followings: - -- Living global variables at the end of an evaluation will be dumped out. -- If the name of a variable starts with the `_` character, it will not be dumped out. - -## Uniqueness of Exported Variable Identifier - -Each exported variable identifier must be unique in its package, so that an exported variable could be located uniquely by package location path and variable identifier, such as 'a.b.c:var', in which 'a.b.c' locates a package. - -Two variable identifiers are different if: - -- they are spelled differently -- they are defined in different packages and are not compiled in a single execution - -Identifying an exported variable should be supported by the kcl compiler, which needs to provide corresponding identifying features through the command line and api form. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/types/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/types/_category_.json deleted file mode 100644 index a8f40915..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/types/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "类型系统", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/types/types.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/types/types.md deleted file mode 100644 index 182ffaf2..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/types/types.md +++ /dev/null @@ -1,1401 +0,0 @@ -# 类型系统 - -本文档描述 KCL 的类型系统,包括: - -- 类型规则 -- 类型检查 -- 类型转换 -- 类型推导 - -## 类型规则 - -### 基础定义 - -#### 断言 - -$S$ 的所有自由变量都定义在 $\Gamma$ 中 - -$$ -\Gamma \vdash S -$$ - -$\Gamma$ 是一个变量的类型声明环境(well-formed environment),如:$x_1:T_1$, ..., $x_n:T_n$ - -$S$ 的断言有三种形式: - -**环境断言** 断言表示 $\Gamma$ 是良构类型 (well-formed type) - -$$ -\Gamma \vdash ◇ -$$ - -**良构类型断言** 在环境 $\Gamma$ 下,$nat$ 是类型表达式 - -$$ -\Gamma \vdash nat -$$ - -**类型判断断言** 在环境 $\Gamma$ 下,$E$ 具有类型 $T$ - -$$ -\Gamma \vdash E: T -$$ - -#### 推理规则 - -表示法 - -$$ -\frac{\Gamma \vdash S_1, ..., \Gamma \vdash S_n}{\Gamma \vdash S} -$$ - -推理规则中的 $u$, $v$, $w$ 用于表示变量,$i$, $j$, $k$ 用于表示整数,$a$, $b$ 用于表示浮点数,$s$ 用于表示字符串,$c$ 代表常量(整数、浮点数、字符串、布尔)的字面值, $f$ 用于表示函数, $T$, $S$, $U$ 用于表示类型。 - -## 环境规则 - -Env ⌀ - -$$ -\frac{}{⌀ \vdash ◇ } -$$ - -## 类型定义 - -Type Bool - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash boolean} -$$ - -Type Int - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash integer} -$$ - -Type Float - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash float} -$$ - -Type String - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash string} -$$ - -Type Literal - -$$ -\frac{ c \in \{boolean, integer, float, string\}}{\Gamma \vdash literalof(c)} -$$ - -Type List - -$$ -\frac{\Gamma \vdash T \ T \neq Void}{\Gamma \vdash listof(T) } -$$ - -Type Dict - -$$ -\frac{\Gamma \vdash T_1 \ \Gamma \vdash T_2\ T_1 \neq Void \ \ T_2 \neq Void}{\Gamma \vdash dictof(T_k=T_1, T_v=T_2)} -$$ - -Type Struct - -$$ -\frac{\Gamma \vdash T_{1} \ ... \ \Gamma \vdash T_{n} \ \ T_i \neq Void \ K_1 \neq K_n}{\Gamma \vdash structof(K_1 : T_{1}, ... , K_n : T_{n})} -$$ - -Type Union - -$$ -\frac{\Gamma \vdash T_1 \ ... \ \Gamma \vdash T_n \ \ T_i \neq Void}{\Gamma \vdash unionof(T_1, ..., T_n)} -$$ - -Type None - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash None} -$$ - -Type Undefined - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Undefined} -$$ - -Type Void - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Void} -$$ - -Type Any - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Any} -$$ - -Type Nothing - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Nothing} -$$ - -## 类型判断规则 - -### Operand Expr - -Exp Truth - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash true: boolean} -$$ - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash false: boolean} -$$ - -Exp Int - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash int: integer} -$$ - -Exp Flt - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash flt: float} -$$ - -Exp Str - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash str: string} -$$ - -Exp None - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash none: none} -$$ - -Exp Undefined - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash undefined: undefined} -$$ - -Expr ListExp - -$$ -\frac{\Gamma \vdash E_1: T_1 \ E_2: T_2 \ ... \ E_n: T_n}{\Gamma \vdash [E_1, E_2, ..., E_n]: listof \ sup(T_1, T_2, ..., T_n)} -$$ - -Expr ListComp - -$$ -\frac{\Gamma \vdash E_1: T_1 \ \Gamma \vdash v: T \ \Gamma \vdash E_2: listof \ T \ \Gamma \vdash E_3: boolean}{\Gamma \vdash [E_1 \ for \ v \ in \ E_2 \ if \ E_3]: listof(T_1) } -$$ - -Expr DictExp - -$$ -\frac{\Gamma \vdash E_{k1}: T_{k1} \ \Gamma \vdash E_{v1}: T_{v1} \ ... \ \Gamma \vdash E_{kn}: T_{kN} \ \Gamma \vdash E_{vn}: T_{vN}}{\Gamma \vdash \{E_{k1}: E_{v1}, ..., E_{{kn}}: E_{vn}\}: dictof(T_{k}=sup(T_{k1}, T_{k2}, ... T_{kn}), \ T_{v}=sup(T_{v1}, T_{v2}, ..., T_{vn}))} -$$ - -Expr DictComp - -$$ -\frac{\Gamma \vdash E_1: T_{rki} \ \Gamma \vdash E_2: T_{rvi} \ \Gamma \vdash v_1: T_k \ \Gamma \vdash v_2: T_v \ \Gamma \vdash E_3: dictof(T_{k}, \ T_{v}) \ \Gamma \vdash E_4: boolean}{\Gamma \vdash \{E_1:E_2 \ for \ (v_1, v_2) \ in \ E_3 \ if \ E_4\}: dictof(T_{k}=sup(T_{rk1}, T_{rk2}, ..., T_{rkn}), T_{v}=sup(T_{rv1}, T_{rv2}, ..., T_{rvn})) } -$$ - -Expr StructExpr - -$$ -\frac{\Gamma \vdash E_{1}: T_{1} \ ... \ \Gamma \vdash E_{n}: T_{n} \ K_1 \neq K_n}{\Gamma \vdash \{K_{1} = E_{1}, ..., K_{{n}} = E_{n}\}: structof(K_1 : T_{1}, ... , K_n : T_{n})} -$$ - -Literal 类型是基础类型的值类型,Union 类型是类型的组合类型,Void、Any、Nothing 是特殊的类型指代,本身没有直接的值表达式对应关系。 - -### Primary Expr - -Expr Index - -$$ -\frac{\Gamma \vdash E: listof(T) \ \Gamma \vdash Index: integer}{\Gamma \vdash E[Index]: T} -$$ - -Expr Call - -$$ -\frac{\Gamma \vdash E_1: T_1 \rightarrow T_2 \ \Gamma \vdash E_2: T_1}{\Gamma \vdash E_1 \ (E_2): T_2} -$$ - -Expr List Selector - -$$ -\frac{\Gamma \vdash E: listof(T) \ \Gamma \vdash Index: integer}{\Gamma \vdash E.[Index]: T} -$$ - -Expr Dict Selector - -$$ -\frac{\Gamma \vdash E: dictof(T_k = T_1, T_v=T_2) \ \Gamma \vdash S_1: string \ ... \ \Gamma \vdash S_n: string}{\Gamma \vdash E.\{S_1, ..., S_n\}: dictof(T_k = T_1, T_v=T_2)} -$$ - -Expr Struct Selector - -$$ -\frac{\Gamma \vdash E: structof(K_1 : T_{1}, ... , K_n : T_{n}) \ \Gamma \vdash K_i: string}{\Gamma \vdash E.K_i: T_{i}} -$$ - -### Unary Expr - -Expr + - -$$ -\frac{\Gamma \vdash E: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash \ +E: T} -$$ - -Expr - - -$$ -\frac{\Gamma \vdash E: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash \ -E: T} -$$ - -Expr ~ - -$$ -\frac{\Gamma \vdash E: integer}{\Gamma \vdash \ ~E: integer} -$$ - -Expr not - -$$ -\frac{\Gamma \vdash E: boolean}{\Gamma \vdash \ not \ E: boolean} -$$ - -### Binary Expr - -算数运算符 - -Expr op, op $\in$ {-, /, %, \*\*, //} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash E_1 \ op \ E_2: T} -$$ - -Expr + - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, float, string, listof(T_1)\}}{\Gamma \vdash E_1 \ + \ E_2: T} -$$ - -Expr \* - -$$ -\frac{\Gamma \vdash E_1: T_1 \ \ \ \Gamma \vdash E_2: T_2 \ \ \ \ (T_1==T_2 \in \{integer, float\}) \ or \ (T_1 == interger \ and \ T_2 \ \in \ \{string, listof(T_3)\}) \ or \ (T_2 == interger \ and \ T_1 \ \in \ \{string, listof(T_3)\})} {\Gamma \vdash E_1 \ * \ E_2: T} -$$ - -示例 - -Expr % - -$$ -\frac{\Gamma \vdash E_1: interger \ \ \ \Gamma \vdash E_2: integer}{\Gamma \vdash E_1 \ \% \ E_2: interger} -$$ - -逻辑运算符 - -Expr op, op $\in$ \{or, and\} - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ op \ E_2: boolean} -$$ - -示例 - -Expr and - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ and \ E_2: boolean} -$$ - -比较运算符 - -Expr op, op $\in$ \{==, !=, <, >, <=, >=\} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T}{\Gamma \vdash E_1 \ op \ E_2: boolean} -$$ - -示例 - -Expr > - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ > \ E_2: boolean} -$$ - -位运算符 - -Expr op, op $\in$ {&, ^, ~, <<, >>} - -$$ -\frac{\Gamma \vdash E_1: integer \ \ \ \Gamma \vdash E_2: integer}{\Gamma \vdash E_1 \ op \ E_2: integer} -$$ - -Expr | - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, listof(T_1), dictof(T_k, T_v), structof(K_1=T_1, ..., K_n=T_n)\}}{\Gamma \vdash E_1 \ | \ E_2: T} -$$ - -成员运算符 - -Expr op, op $\in$ {in, not in} - -$$ -\frac{\Gamma \vdash E_1: string \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{dictof, structof\}}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -Expr op, op $\in$ {in, not in} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: listof(S), T \sqsubseteq S}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -身份运算符 - -Expr op $\in$ {is, is not} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -### IF Expr - -Expr If - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: T \ \ \ \Gamma \vdash E_3: T}{\Gamma \vdash if \ E_1 \ then \ E_2 \ else \ E_3: T} -$$ - -### Stmt - -Stmt If - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash S_1: Void \ \ \ \Gamma \vdash S_2: Void}{\Gamma \vdash if \ E_1 \ then \ S_1 \ else \ S_2: Void} -$$ - -Stmt Assign - -$$ -\frac{\Gamma \vdash id: T_0 \ \ \ \Gamma \vdash T_1 \ \ \ \Gamma \vdash E: T_2}{\Gamma \vdash id: T_1 \ = \ E : Void} -$$ - -Type Alias - -$$ -\frac{\Gamma \vdash id: T_0 \ \ \ \Gamma \vdash T_1}{\Gamma \vdash type \ id \ = \ T_1 : Void} -$$ - -## Union - -### Union 规则 - -List Union - -$$ -\frac{\Gamma \vdash \ listof(T) \ \ \ \Gamma \vdash \ listof(S)}{\Gamma \vdash \ listof(unionof(T, S))} -$$ - -Dict Union - -$$ -\frac{\Gamma \vdash \ dictof(T_1, T_2) \ \ \ \Gamma \vdash \ dictof(S_1, S_2)}{\Gamma \vdash \ dictof(unionof(T_1, S_1), unionof(T_2, S_2))} -$$ - -Struct Union - -给定两个结构体 $structof(K_{1}: T_{1}, ..., K_{n}: T_{n}),structof(H_{1}: S_{1}, ..., H_{m}: S_{n})$ - -定义他们的 union 类型: - -$$ -structof(J_{1}: U_{1}, ..., J_{p}: U_{n}) = structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \bigcup structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) -$$ - -例如: - -$$ -structof() \ \bigcup \ structof(H_{1}: T_{1}, ..., H_{m}: T_{n}) = structof(H_{1}: T_{1}, ..., H_{m}: T_{n}) -$$ - -$$ -structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \ \bigcup \ structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) = structof(K_1: T_1) :: (structof(K_{2}: T_{2}, ..., K_{n}: T_{n}) \ \bigcup \ structof(H_{1}: S_{1}, ..., H_{m}: S_{n})) -$$ - -其中把 "::" 表示把一个对偶加入到一个结构的操作,定义如下: - -$$ -structof(K_{1}: T_{1}) :: structof() = structof(K_{1}: T_{1}) -$$ - -$$ -structof(K_{1}: T_{1}) :: structof(K_{1}: T_{1}', ..., K_n: T_{n}) = structof(K_{1}: union\_op(T_{1}, T_{1}'), ..., K_{n}: T_{n}) -$$ - -$$ -structof(K_{1}: T_{1}) :: structof(K_{2}: T_{2}, ..., K_n: T_{n}) = structof(K_{2}: T_2) :: structof(K_{1}: T_1) :: structof(K_{3}: T_3, ..., K_{n}: T_{n}) -$$ - -基于此,两个 Struct 的 union 定义为: - -$$ -\frac{\Gamma \vdash structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \ \Gamma \vdash structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) \ structof(J_{1}: U_{1}, ..., J_{p}: U_{n}) = structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \bigcup structof(H_{1}: S_{1}, ..., H_{m}: S_{n})}{\Gamma \vdash structof(J_{1}: U_{1}, ..., J_{p}: U_{n}))} -$$ - -其中 $union\_op(T_1, T_2)$ 表示对相同 $K_i$ 的不同类型的判断操作: - -- 当 $T_1$ 与 $T_2$ 有偏序关系时, 如果 $T_1 \sqsubseteq T_2$ 时,返回 $T_2$,否则返回 $T_1$,即取最小上界 -- 当 $T_1$ 与 $T_2$ 不存在偏序关系时,有三种可选的处理逻辑: - - 结构体 union 失败,返回 type_error - - 返回后者的类型,此处为 $T_2$ - - 返回类型 $unionof(T_1, T_2)$ - -此处需要根据实际需求选择适当的处理方式。 - -结构体继承可以看做一种特殊的 union,整体逻辑与 union 相似,但在 $union\_op(T_1, T_2)$ 中对相同 $K_i$ 的不同类型的判断操作如下: - -- 当 $T_1$ 与 $T_2$ 有偏序关系且 $T_1 \sqsubseteq T_2$ 时,返回 $T_1$,即仅当 $T_1$ 是 $T_2$ 的下界时以下界 $T_1$ 为准 -- 否则返回 type_error - -通过这样的继承设计可以实现分层的、自下而上逐层收缩的类型定义。 - -## Operation - -KCL 支持对结构体属性进行如 `p op E` 形式的操作。 即对给定结构体 $A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})$, 对结构体中的路径 `p` 以 `E` 的值进行指定的操作(如 union,assign,insert 等)。 - -定义如下更新操作: - -$$ -\frac{{\Gamma\vdash A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})}  {\Gamma\vdash p \in (K_{1}, ..., K_{n})} \ {\Gamma\vdash e:T}   k \neq k_1, ..., k \neq k_n} -{ A \{p \ op \ e\}:\{K_1:T_1, ..., K_n:T_n\}∪\{p:T\}} -$$ - -即对路径 $p$ 进行操作本质上是对两个结构体的一种 union,对同名属性类型 union 时的规则根据情况而定。例如路径 $p$ 是一个可用作字段名的标识符 $p=k_1$,并且结构体 A 中字段名也是 $k_1$,它的类型为 $T_1$,并且表达式 $e$ 的类型也为 $T_1$ ,那么 - -$$ -\frac{{\Gamma\vdash A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})}  {\Gamma\vdash p = K_{1}} \ {\Gamma\vdash e:T_1}   k \neq k_1, ..., k \neq k_n} -{ A \{p \ op \ e\}:\{K_1:T_1, ..., K_n:T_n\}} -$$ - -注意: - -- 此处表达式 $e$ 的类型 $T_1$ 同原先同名属性 $K_1$ 的具有相同的类型。可根据实际情况需要适当放松,如 $e$ 的类型 $\sqsubseteq T_1$ 即可。 -- 对于多层结构体嵌套的操作,递归的使用以上规则即可。 - -## 类型偏序 - -### 基础类型 - -$$ -Type \ T \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ T -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Bool \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Int \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Float \sqsubseteq Type \ Any -$$ - -$$ -Type \ Int \sqsubseteq Type \ Float -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ String \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Literal \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ List \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Dict \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Struct \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ None \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Void \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Any -$$ - -### 字面值类型 - -$$ -Type \ Literal(Bool) \sqsubseteq Type \ Bool -$$ - -$$ -Type \ Literal(Int) \sqsubseteq Type \ Int -$$ - -$$ -Type \ Literal(Float) \sqsubseteq Type \ Float -$$ - -$$ -Type \ Literal(String) \sqsubseteq Type \ String -$$ - -### 联合类型 - -$$ -Type \ X \sqsubseteq Type \ Union(X, Y) -$$ - -### 自反 - -$$ -Type \ X \sqsubseteq Type \ X -$$ - -示例 - -$$ -Type \ Bool \sqsubseteq Type \ Bool -$$ - -$$ -Type \ Int \sqsubseteq Type \ Int -$$ - -$$ -Type \ Float \sqsubseteq Type \ Float -$$ - -$$ -Type \ String \sqsubseteq Type \ String -$$ - -$$ -Type \ List \sqsubseteq Type \ List -$$ - -$$ -Type \ Dict \sqsubseteq Type \ Dict -$$ - -$$ -Type \ Struct \sqsubseteq Type \ Struct -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Nothing -$$ - -$$ -Type \ Any \sqsubseteq Type \ Any -$$ - -$$ -Type \ Union(Type Int, Type Bool) \sqsubseteq Type \ Union(Type Int, Type Bool) -$$ - -### 传递 - -$$ -Type \ X \sqsubseteq Type \ Z \ if \ Type \ X \sqsubseteq Type \ Y \ and \ Type \ Y \sqsubseteq \ Type \ Z -$$ - -### 包含 - -$$ -Type \ List(T_1) \sqsubseteq Type \ List(T_2) \ if \ T_1 \sqsubseteq T_2 -$$ - -$$ -Type \ Dict(T_{k1}, T_{v1}) \sqsubseteq Type \ Dict(T_{k2}, T_{v2}) \ if \ T_{k1} \sqsubseteq T_{k2} \ and \ T_{v1} \sqsubseteq T_{v1} -$$ - -$$ -Type \ Structure(K_1: T_{a1}, K_2: T_{a2}, ..., K_n: T_{an}) \sqsubseteq Type \ Structure(K_1: T_{b1}, K_2: T_{b2}, ..., K_n: T_{bn}) \ if \ T_{a1} \sqsubseteq T_{b1} \ and \ T_{a2} \sqsubseteq T_{b2} \ and \ ... \ and \ T_{an} \sqsubseteq T_{bn} -$$ - -### 继承 - -$$ -Type \ Struct \ A \sqsubseteq Type \ Struct \ B \ if \ A \ inherits \ B -$$ - -### None - -$$ -Type \ None \sqsubseteq Type \ X, X \notin \{Type \ Nothing, \ Type \ Void\} -$$ - -### Undefined - -$$ -Type \ Undefined \sqsubseteq Type \ X, X \notin \{Type \ Nothing, \ Type \ Void\} -$$ - -## 相等性 - -交换律 - -$$ -Type \ Union(X, Y) == Type \ Union(Y, X) -$$ - -示例 - -$$ -Type \ Union(Int, Bool) == Type \ Union(Bool, Int) -$$ - -结合律 - -$$ -Type \ Union(Union(X, Y), Z) == Type \ Union(X, Union(Y, Z)) -$$ - -示例 - -$$ -Type \ Union(Union(Int, String), Bool) == Type \ Union(Int, Union(String, Bool)) -$$ - -幂等性 - -$$ -Type \ Union(X, X) == Type \ X -$$ - -示例 - -$$ -Type \ Union(Int, Int) == Type \ Int -$$ - -偏序推导 - -$$ -Type \ Union(X, Y) == Type \ Y \ if \ X \sqsubseteq Y -$$ - -示例 - -假设 Struct A 继承 Struct B - -$$ -Type \ Union(A, B) == Type \ B -$$ - -幂等性是偏序自反的一个特例 - -### List - -$$ -Type \ List(X) == Type \ List(Y) \ if \ X == Y -$$ - -### Dict - -$$ -Type \ Dict(T_k, T_v) == Type \ Dict(S_k, S_v) \ if \ T_k == S_k \ and \ T_v == S_v -$$ - -### Struct - -$$ -Type \ Struct(K_1: T_{1}, K_2: T_{2}, ..., K_n: T_{n}) == Type \ Struct(K_1: S_{1}, K_2: S_{2}, ..., K_n: S_{n}) \ if \ T_{1} == S_{1} \ and \ ... \ and \ T_{n} == S_{n} -$$ - -### 偏序检查 - -$$ -Type \ X == Type \ Y \ if \ Type \ X \sqsubseteq Type \ Y \ and \ Type \ Y \sqsubseteq \ Type \ X -$$ - -## 基础方法 - -- sup(t1: T, t2: T) -> T: 根据类型偏序计算两类型 t1, t2 的最小上界。需要动态创建 union type。 -- typeEqual(t1: T, t2: T) -> bool: 比较两类型 t1, t2 是否相等。 -- typeToString(t: T) -> string: 自顶向下递归解析并转化类型成对应的字符串类型。 - -### Sup Function - -- 暂不考虑类型参数,条件类型等特性 -- 使用一个有序集合存储 UnionType 的所有类型 -- 使用一个全局的 Map 根据 UnionType 的名称存储产生的所有 UnionType -- 根据偏序关系计算类型之间的包含关系 - -```go -// The Sup function returns the minimum supremum of all types in an array of types -func Sup(types: T[]) -> T { - typeOf(types, removeSubTypes=true) -} - -// Build a sup type from types [T1, T2, ... , Tn] -func typeOf(types: T[], removeSubTypes: bool = false) -> T { - assert isNotNullOrEmpty(types) - // 1. Initialize an ordered set to store the type array - typeSet: Set[T] = {} - // 2. Add the type array to the ordered set for sorting by the type id and de-duplication - addTypesToTypeSet(typeSet, types) - // 3. Remove sub types according to partial order relation rules e.g. sub schema types - if removeSubTypes { - removeSubTypes(typeSet) - } - if len(typeSet) == 1 { - // If the typeSet has only one type, return it - return typeSet[0] - } - // 4. Get or set the union type from the global union type map - id := getIdentifierFromTypeSet(typeSet) - unionType := globalUnionTypeMap.get(id) - if !unionType { - unionType = createUnionType(typeSet) // Build a new union type - globalUnionTypeMap.set(id, unionType) - } - return unionType -} - -// Add many types into the type set -func addTypesToTypeSet(typeSet: Set[T], types: T[]) -> void { - for type in types { - addTypeToTypeSet(typeSet, type) - } -} - -// Add one type into the type set -func addTypeToTypeSet(typeSet: Set[T], type: T) -> void { - if isUnion(type) { - return addTypesToTypeSet(typeSet, toUnionOf(type).types) - } - // Ignore the void type check - if !isVoid(type) { - // De-duplication according to the type of id - typeSet.add(type) - } -} - -func removeSubTypes(types: Set[T]) -> void { - for source in types { - for target in types { - if !typeEqual(source, target) { - // If the two types have an inheritance relationship, the base class is retained, or if the two types have a partial order relationship according to the relation table. - if (isPartialOrderRelatedTo(source, target)) { - types.remove(source) - } - } - } - } -} - -// isPartialOrderRelatedTo function Determine whether two types have a partial order relationship `source \sqsubseteq target` -// according to the partial order relationship table and rules -func isPartialOrderRelatedTo(source: T, target: T) -> bool { - assert isNotNullOrEmpty(source) - assert isNotNullOrEmpty(target) - if isNoneOrUndefined(source) and !isNothing(target) and !isVoid(target) { - return true - } - if isAny(target) { - return true - } - if typeEqual(source, target) { - return true - } - if isUnion(target) and source in target.types { - return true - } - // Literal Type - if (isStringLiteral(source) and isString(target)) or \ - (isBooleanLiteral(source) and isBool(target)) or \ - (isIntLiteral(source) and isInt(target)) or \ - (isFloatLiteral(source) and isFloat(target)) { - return true - } - if isInt(source) and isFloat(target) { - return true - } - if isList(source) and isList(target) { - return isPartialOrderRelatedTo(toListOf(source).eleType, toListOf(target).eleType - } - if isDict(source) and isDict(target) { - return isPartialOrderRelatedTo(toDictOf(source).keyType, toDictOf(target).keyType) and isPartialOrderRelatedTo(toDictOf(source).valueType, toDictOf(target).valueType) - } - if isStruct(source) and isStruct(target) { - if isTypeDerivedFrom(source, target) { - return true - } - // Empty Object - if len(target.keys) == 0 { - return true - } - if any([key Not in source.keys for key in target.keys]) { - return false - } - for key, sourceType in (source.keys, source.types) { - targetType = getKeyType(target, key) ? getKeyType(target, key) : anyTypeOf() - if !isPartialOrderRelatedTo(sourceType, targetType) { - return false - } - } - return true - } - return false -} -``` - -## 类型检查 - -### 类型检查器 - -类型检查器通过语法制导翻译的方式,自顶向下遍历语法树,并根据上下文有关的**定型规则**来判定程序构造是否为良类型程序。 - -类型检查器依赖类型规则,类型环境 $\Gamma$ 的信息记入符号表。对类型表达式采用抽象语法,如 listof(T)。类型检查失败时产生 type_error,并根据语法上下文产生错误信息。 - -### 基础方法 - -1. isUpperBound(t1, t2): supUnify(t1, t2) == t2 -2. supUnify(t1, t2): - -- 对于基础类型,根据偏序关系计算 sup(t1, t2) -- 对于 list、 dict、 Struct, 递归地对其中元素的类型进行 supUnify -- 不存在偏序关系时,返回 Nothing - -### 检查逻辑 - -#### Operand Expr - -$D \to id: T$ - -``` -env.addtype(id.entry, T.type) -``` - -$T \to boolean$ - -``` -T.type = boolean -``` - -$T \to integer$ - -``` -T.type = integer -``` - -$T \to float$ - -``` -T.type = float -``` - -$T \to string$ - -``` -T.type = string -``` - -$T \to c, \ c \in \{boolean, integer, float, string\}$ - -``` -T.type = literalof(c) -``` - -$T \to None$ - -``` -T.type = None -``` - -$T \to Undefined$ - -``` -T.type = Undefined -``` - -$T \to \ [T_1]$ - -``` -T.type = listof (T1.type) -``` - -$T \to { \{T_1: T_2\} }$ - -``` -T.type = dictof (T1.type: T2.type) -``` - -$T \to { \{N_1: T_1, N2: T_2, ..., N_n: T_n\} }$ - -``` -T.type = structof (N1: T1.type, N2: T2.type, ..., Nn: Tn.type) -``` - -$E \to id$ - -``` -E.type = env.lookup(id.entry) -``` - -$E \to [E_1, E_2, ..., E_n]$ - -``` -func listExpr(E) { - supe = sup([e.type for e in E]]) - E.type = listof(type) -} -``` - -$E \to [E_1 \ for \ E_2 \ in \ E_3 \ if \ E_4]$ - -``` -func listComp(E) { - if !typeEqual(E4.type, boolean) { - raise type_error - } - if !isUpperBound(listof(Any), E3.type) { - raise type_error(E) - } - if !isUpperBound(E3.type, E2.type) { - raise type_error(E) - } - E.type = listof(E1.type) -} -``` - -$E \to \{E_{k1}: E_{v1}, ..., E_{kn}: E_{vn}\}$ - -``` -func dictExpr(E) { - supk := sup([e.type for e in E.keys()]]) - supv := sup([e.type for e in E.values()]]) - E.type = dictof(supk, supv) -} -``` - -$E \to \{E_1:E_2 \ for \ (E_3, E_4) \ in \ E_5 \ if \ E_6\}$ - -``` -func dictComp(E) { - if !typeEqual(E6.type, boolean) { - raise type_error(E) - } - if !isUpperBound(dictof(Any, Any), E5.type) { - raise type_error(E) - } - if !isUpperBound(E5.type, dictof(E3.type, E4.type)) { - raise type_error(E) - } - E.type = dictof(E1.type, E2.type) -} -``` - -$E \to \{E_{k1}: E_{v1}, ..., E_{kn}: E_{vn}\}$ - -``` -func dictExpr(E) { - supk := sup(Ek1, ..., Ekn) - supv = sup(Ev1, ..., Evn) - E.type = dictof(supk, supv) -} -``` - -$E \to \{N_{1} = E_{1}, ..., N_{{n}} = E_{n}\}$ - -``` -func structExpr(E) { - Struct = structof() - for n, e in E { - Struct.add(n, e.type) - } - E.type = Struct -} -``` - -#### Primary Expr - -$E \to E_1[E_2]$ - -``` -func sliceSuffix(E) { - if !isUpperBound(listof(Any), E.E1.type) { - raise type_error(E) - } - if typeEqual(E.E2.type, integer) { - raise type_error(E) - } - E.type = E.E1.type.eleType -} -``` - -$E \to E_1(E_2)$ - -``` -func callSuffix(E) { - if !typeEqual(E.E1.type, func) { - raise type_error(E) - } - if !isUpperBound(listof(E.E1.arguType), E.E2.type) { - raise type_error(E) - } - E.type = E.E1.returnType -} -``` - -#### Unary Expr - -根据每条双目运算符的推理规则推导,以 '+' 为例 - -$E \to + E_1$ - -``` -func Plus(E) { - if !typeEqual(E.E1.type, [integer, float]) { - raise type_error(E) - } - E.type = E.E1.type -} -``` - -#### Binary Expr - -根据每条双目运算符的推理规则推导,以 '%' 为例 - -$E \to E_1 \ % \ E_2$ - -``` -func Mod(E) { - if !(typeEqual(E.E1.type, [integer, float]) && typeEqual(E.E2.type, [integer, float])) { - raise type_error(E) - } - E.type = E.E1.type -} -``` - -#### IF Binary Expr - -$E \to if E_1 \ then \ E_2 else \ E_3$ - -``` -func ifExpr(E) { - if !typeEqual(E.type, boolean) { - raise type_error(E) - } - if !typeEqual(E_2.type, E_3.type) { - raise type_error(E) - } - E.type = E_2.type -} -``` - -#### Stmt - -$S \to if \ E \ then \ S_1 \ else \ S_2$ - -``` -func ifStmt(S) { - if !typeEqual(S.E.type, boolean) { - raise type_error(E) - } - if !typeEqual(S.S1.type, S.S2.type) { - raise type_error(E) - } - S.type = S.S1.type -} -``` - -$S \to id: T = E$ - -$S \to id = T E$ - -``` -func assignStmt(S) { - tpe := env.lookup(id.entry) - if tpe != nil && tpe != S.T { - raise type_error(E) - } - if isUpperBound(tpe, E.type) { - raise type_error(E) - } - env.addtype(id.entry, T.type) -} -``` - -## 类型转换 - -### 基础定义 - -通过语法制导翻译的方式,根据运算符特征,对参与运算的值类型进行自动类型转换 - -### 转换规则 - -$E \to E_1 \ op \ E_2, , op \in \{+, -, *, /, \%, **, //\}$ - -``` -func binOp(E) { - if E.E1.type == integer and E.E2.type == integer { - E.type = integer - } else if E.E1.type == integer and E.E2.type == float { - E.type = float - } else if E.E1.type == float and E.E2.type == integer { - E.type = float - } else if E.E1.type == float and E.E2.type == float { - E.type = float - } -} -``` - -## 类型推导 - -### 基础定义 - -- 在类型信息不完全的情况下类型规则推导、重建类型 -- 自底向上推导并重建数程序中的数据结构类型,如基础类型,list, dict, Struct - -### 基础方法 - -1. typeOf(expr, subst): 输入为表达式和代换规则集合,返回 expr 的类型和新的代换规则集合 -2. unifier(t1, t2, subst, expr) 用 t1=t2 尝试代换,如果代换成功(未出现且无冲突),则将 t1=t2 加入 subst 并返回 subst。否则报错已出现或有冲突。 - -### 推导逻辑 - -$E \to id = E_1$ - -``` -func assignExpr(E, subst) { - return unifier(E.id.type, E.E_1.type, subst, E) -} -``` - -$unifier(t1, t2, subst, expr) \rightarrow subst$ - -``` -func unifier(t1, t2, subst, expr) { - t1 = applySubstToTypeEquation(t1, subst) - t2 = applySubstToTypeEquation(t2, subst) - - if t1 == t2 { - return subst - } - - if isTypeVar(t1) { - if isNoOccur(t1, t2) { - addTypeEquationToSubst(subst, t1, t2) - return subst - } else { - raise occurrence_violation_error(t1, t2, expr) - } - } - - if isTypeVar(t2) { - if isNoOccur(t2, t1) { - addTypeEquationToSubst(subst, t2, t1) - return subst - } else { - raise occurrence_violation_error(t2, t1, expr) - } - } - - if isList(t1) and isList(t2) { - return unifier(toListOf(t1).eleType, toListOf(t2).eleType, subst, expr) - } - if isDict(t1) and isDict(t2) { - dict1of := toDictOf(t1) - dict2of := toDictOf(t2) - subst = unifier(dict1of.keyType, dict2of.keyType, subst, expr) - subst = unifier(dict1of.valueType, dict2of.valueType, subst, expr) - return subst - } - if isStruct(t1) and isStruct(t2) { - Struct1of := tostructof(t1) - Struct2of := tostructof(t2) - for key, _ in Struct1of { - subst = unifier(t1[key].type, t2[key].type, subst, expr) - } - return subst - } - - raise unification_error(t1, t2, expr) -} - -func applySubstToTypeEquation(t, subst) { - // walks through the type t, replacing each type variable by its binding in the substitution -σ. If a variable is Not bound in the substitution, then it is left unchanged. - if isBasicType(t) { - return t - } - if isList(t) { - return listOf(applySubstToTypeEquation(toListOf(t).eleType, subst)) - } - if isDict(t) { - dictof := toDictOf(t) - kT := applySubstToTypeEquation(dictof.keyType, subst) - vT := applySubstToTypeEquation(dictof.valueType, subst) - return dictOf(kT, vT) - } - if isStruct(t) { - structof := tostructof(t) - s := structof() - for key, type in Struct1of { - kT := applySubstToTypeEquation(type, subst) - s.add(key, kT) - } - return s - } - if hasTypeVar(t) { - for tvar in t.vars { - if tvar in subst { - *tvar = subst[tvar] - } - } - } - return t -} - -func addTypeEquationToSubst(subst, tvar, t) { - // takes the substitution σ and adds the equation tv = t to it - for _, t in subst { - for tvar in t.vars { - tmp := applyOneSubst(tsvar, tvar, t) - *tvar = tmp - } - } - subst.add(tvar, t) -} - -func applyOneSubst(t0, tvar, t1) { - // substituting t1 for every occurrence of tv in t0. - if isBasicType(t0) { - return t0 - } - if isList(t0) { - return listOf(applyOneSubst(toListOf(t).eleType, tvar, t1)) - } - if isDict(t0) { - dictof := toDictOf(t) - kT := applyOneSubst(dictof.keyType, tvar, t1) - vT := applyOneSubst(dictof.valueType, tvar, t1) - return dictOf(kT, vT) - } - if isStruct(t0) { - structof := tostructof(t) - s := structof() - for key, type in Struct1of { - kT := applyOneSubst(type, tvar, t1) - s.add(key, kT) - } - return s - } - if t0 == tvar { - return t1 - } - return t0 -} - -func isNoOccur(tvar, t) { - // No variable bound in the substitution occurs in any of the right-hand sides of the substitution. - if isBasicType(t) { - return true - } - if isList(t) { - return isNoOccur(tvar, toListOf(t).eleType) - } - if isDict(t) { - dictof := toDictOf(t) - return isNoOccur(tvar, dictof.keyType) and isNoOccur(tvar, dictof.valueType) - } - if isStruct(t) { - structof := tostructof(t) - noOccur := true - for _, type in structof { - noOccur = noOccur and isNoOccur(tvar, type) - } - return noOccur - } - return tvar != t -} -``` - -### 示例 - -#### 正常推导 - -``` -T : { - a = 1 - b = "2" - c = a * 2 - d = { - d0 = [a, c] - } -} - -x: T = { - a = 10 -} -``` - -#### Occurrence Violation Error - -``` -T = { - a = a -} -``` - -#### Type Unification Error - -``` -T : { - a = 1 -} - -T : { - a = "1" -} -``` - -## Reference - -- [https://en.wikipedia.org/wiki/Type_system](https://en.wikipedia.org/wiki/Type_system) -- Pierce, Benjamin C. (2002). Types and Programming Languages. MIT Press. -- [https://www.cs.cornell.edu/courses/cs4110/2010fa/](https://www.cs.cornell.edu/courses/cs4110/2010fa/) -- [https://www.typescriptlang.org/docs/handbook/basic-types.html](https://www.typescriptlang.org/docs/handbook/basic-types.html) -- [https://www.typescriptlang.org/docs/handbook/advanced-types.html](https://www.typescriptlang.org/docs/handbook/advanced-types.html) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/_category_.json deleted file mode 100644 index 53e27fd4..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "模块系统", - "position": 2 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/base64.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/base64.md deleted file mode 100644 index 0db738f0..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/base64.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: "base64" -linkTitle: "base64" -type: "docs" -description: base64 编码解码 -weight: 100 ---- - -## encode - -`encode(value: str, encoding: str = "utf-8") -> str` - -使用注册的编码器对字符串 `value` 进行编码。 - -## decode - -`decode(value: str, encoding: str = "utf-8") -> str` - -使用注册的编码器对字符串 `value` 进行解码。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/builtin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/builtin.md deleted file mode 100644 index 44085174..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/builtin.md +++ /dev/null @@ -1,401 +0,0 @@ ---- -title: "builtin" -sidebar_position: 1 ---- - -KCL 提供了一个内置系统模块的列表,这些模块是自动加载的,无需提供任何模块名称即可直接使用。例如,`print` 就是一个广泛使用的内置模块提供的函数。 - -## 类型转换函数 - -KCL的 `bool`、`int`、`float`、`str`、`list`、`dict`等类型有内置同名的转换函数。其中 `int` 不仅仅可以用于截断浮点数,也可以用来将字符串转化为整数(解析时为10进制,也可以制定其他值)。 - -下面是类型相关函数常见的用法: - -```py -b1 = bool(1) # true -b2 = bool(1.5) # true -b3 = bool("true") # true -b4 = bool("") # false -b5 = bool([]) # false -b6 = bool({}) # false - -i1 = int("11") # 11 -i2 = int("11", base=8) # 9 -i3 = int("11", base=2) # 3 - -f1 = float(1) # 1.0 -f2 = float("1.5") # 1.5 - -s1 = str(1) # 1 - -l1 = list([1, 2, 3]) -``` - -## String 类型成员函数 - -参考 [String 文档](/docs/reference/lang/spec/datatypes) - -## print - -`print(*args:any, end:str='\n')` - -内置的打印函数,提供不同类型的可变参数打印,默认在结尾添加一个换行符号。以下上常见的用法: - -```python -print("hello KCL") -print() -print(None, end=':') -print(None) -print(True) -print(False) -print(123) -print(123.0) -print('abc ${123}') -print("abc ${456}") -print([1,'a', True]) -print(1,'a', True) -print({}) -print({a: 123}) -``` - -输出格式如下: - -```shell -hello KCL - -None:None -True -False -123 -123.0 -abc 123 -abc 456 -[1, 'a', True] -1 a True -{} -{'a': 123} -``` - -如果不希望在默认换行时,可以通过 `end=''` 命名参数重新指定结尾的字符串。 - -## multiplyof - -`multiplyof(a:int, b:int) -> bool` - -判断整数 `a` 是否为 `b` 的整数倍,返回布尔值: - -```python -print(multiplyof(2, 1)) # True -print(multiplyof(1, 2)) # False -print(multiplyof(0, 1)) # True -print(multiplyof(0, 2)) # True -print(multiplyof(1, 0)) # Error -``` - -`0` 是任何数的倍数。但是 `b` 不能为 `0`,否则将抛出异常。 - -## isunique - -`isunique(list: [any]) -> bool` - -判断数组中是否存在重复的元素,返回布尔值: - -```python -print(isunique([])) # True -print(isunique([1])) # True -print(isunique([1, 2])) # True - -print(isunique([1, 1])) # False -print(isunique([1, 1.0])) # False -print(isunique([1.1, 1.1])) # False - -print(isunique(['abc', "abc"])) # False -print(isunique(['abc', "a${'bc'}"])) # False -``` - -需要注意的是整数和浮点数会忽略类型差异,根据值是否相等判断。 - -## len - -`len(x: str | [any] | {:}) -> int` - -返回字符串、列表和数组的长度: - -```python -print(len([])) # 0 -print(len({})) # 0 - -print(len([1])) # 1 -print(len({abc:123})) # 1 - -print("abc") # 3 -``` - -注:不支持对 `schema` 对象计算长度。 - -## abs - -`abs(x: number) -> number` - -计算 `x` 的绝对值。 - -## all_true - -`all_true(x:str|[]|{:}) -> bool` - -判断列表或字典类全部元素为真,用法如下: - -```python -print(all_true([])) # True -print(all_true({})) # True - -print(all_true([True])) # True -print(all_true([1])) # True - -print(all_true([True, False])) # False -print(all_true([True, None])) # False -``` - -当列表为空时返回真。 - - - -## any_true - -`any_true(x:str|[]|{:}) -> bool` - -判断可迭代对象中至少有一个元素为真,用法如下: - -```python -print(any_true([])) # False -print(any_true([1])) # True -``` - -## bin - -`bin(x:number) -> str` - -返回整数的二进制表示的字符串,用法如下: - -```python -print(bin(8)) # 0b1000 -``` - -## hex - -`hex(number)` - -返回整数的十六进制表示的字符串,用法如下: - -```python -print(hex(18)) # 0x12 -``` - -## oct - -`oct(number)` - -返回整数的八进制表示的字符串,用法如下: - -```python -print(oct(10)) # 0o12 -``` - -## option - -`option(key:str, type:str='', required=False, default=None, help="") -> any` - -获取命令行参数输入的值。 - -## ord - -`ord(c) -> int` - -获取字符的 Unicode 码点值,用法如下: - -```python -print(ord('A')) # 65 -print(ord('B')) # 66 -print(ord('C')) # 67 -``` - -## sorted - -`sorted(x: []) -> []` - -返回排序后的列表,用法如下: - -```python -_a = [] -_b = [2, 1] - -_c = sorted(_a) -_d = sorted(_b) - -print(_a) # [] -print(_b) # [2, 1] -print(_c) # [] -print(_d) # [1, 2] -``` - -## range - -`range(start:int, end:int, step=1) -> [int]` - -产生迭代列表,用法如下: - -```python -print(range(1,5)) # [1, 2, 3, 4] -print(range(1,5, 2)) # [1, 3] -print(range(5, 1, -1)) # [5, 4, 3, 2] -``` - -## min - -`min(x:[number]) -> number` - -返回列表中最小的元素,用法如下: - -```python -print(min([1,2])) # 1 -print(min([2,1])) # 1 -``` - - - -## max - -`max(x:[number]) -> number` - -返回列表中最大的元素,用法如下: - -```python -print(max([1,2])) # 2 -print(max([2,1])) # 2 -``` - -## sum - -`sum(x:[number], init_value=0) -> number` - -返回列表中全部元素的和,用法如下: - -``` -print(sum([1,2])) # 3 -print(sum([2,1], 1000)) # 1003 -``` - -## pow - -`pow(x: number, y: number, z: number = None) -> number` - -计算 `x**y`,如果 `z` 非空则计算 `(x**y)%z`,支持整数和浮点数。 - -下面的常见的用法: - -```python -print(pow(2,3)) # 8 -print(pow(2, 3, 5)) # 8%5 == 3 - -print(pow(2, 0.5)) # 1.414 -``` - -## round - -`round(number: int|float, ndigits:int|None) -> float | int` - -返回 `number` 的四舍五入近似值。如果 `ndigits` 非 `None` 则返回浮点数并保留指定位数的小数(不能为负数),否则返回整数结构。 - -下面是常用的用法: - -```python -print(round(1)) # 1 -print(round(1.4)) # 1 -print(round(1.5)) # 2 - -print(round(1.5555, 1)) # 1.6 -print(round(1.5555, 2)) # 1.56 - -print(round(1.5555)) # 2 -print(round(1.5555, 0)) # 2.0 -``` - -需要注意的是,`ndigits` 为 `None` 和 `0` 的区别是前缀返回 `int` 类型、后者返回 `float` 类型。 - -## typeof - -`typeof(x: any, full_name: bool = False) -> str` - -输出 `x` 在运算时的类型。当 `full_name` 参数设置为 `True` 时,将返回 `pkg.schema` 形式的包前缀。 - -下面是常见的用法: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person{} -t3 = typeof(_x1) - -_x2 = pkg.Person{} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# 输出 -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -## zip - -`zip(*args: str|list|dict)` - -用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。 - -下面是常见的用法: - -```py -a = zip([0, 1, 2], [3, 4, 5]) -b = zip([0, 1], [3, 4, 5]) -c = zip([0, 1, 2], [3, 4, 5, 6]) - -# 输出 -# a: -# - - 0 -# - 3 -# - - 1 -# - 4 -# - - 2 -# - 5 -# b: -# - - 0 -# - 3 -# - - 1 -# - 4 -# c: -# - - 0 -# - 3 -# - - 1 -# - 4 -# - - 2 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/crypto.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/crypto.md deleted file mode 100644 index cef03352..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/crypto.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "crypto" -linkTitle: "crypto" -type: "docs" -description: crypto 包 - 提供 SHA 相关的哈希函数 -weight: 100 ---- - -## md5 - -`md5(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `MD5` 算法对字符串 `value` 进行加密。 - -## sha1 - -`sha1(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA1` 算法对字符串 `value` 进行加密。 - -## sha224 - -`sha224(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA224` 算法对字符串 `value` 进行加密。 - -## sha256 - -`sha256(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA256` 算法对字符串 `value` 进行加密。 - -## sha384 - -`sha384(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA384` 算法对字符串 `value` 进行加密。 - -## sha512 - -`sha512(value: str, encoding: str = "utf-8") -> str` - -使用注册编码器和 `SHA512` 算法对字符串 `value` 进行加密。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/manifests.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/manifests.md deleted file mode 100644 index 5c54e9c7..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/manifests.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: "manifests" -linkTitle: "manifests" -type: "docs" -description: manifests system module -weight: 100 ---- - -## yaml_stream - -```python -yaml_stream(values: [any], opts: {str:} = { - sort_keys = False - ignore_private = True - ignore_none = False - sep = "---" -}) -``` - -这个函数的功能是将 KCL 对象列表序列化为带 `---` 分隔符的样式 YAML 输出,它具有两个参数: - -- `values` - 一个 KCL 对象列表 -- `opts` - YAML 序列化选项 - - `sort_keys`:是否按属性名称的字典序对序列化结果进行排序(默认为 `False`)。 - - `ignore_private`:是否忽略名称以 `_` 开头的属性序列化输出(默认为 `True`)。 - - `ignore_none`:是否忽略值为 `None` 的属性(默认为 `False`)。 - - `sep`:在多个 YAML 文档之间选择怎样的分隔符(默认为 `"---"`)。 - -下面我们通过一个例子来说明: - -```python -# 使用 `import` 关键词导入 `manifests` 模块 -import manifests - -# `Deployment` schema 定义 -schema Deployment: - apiVersion: str = "v1" - kind: str = "Deployment" - metadata: {str:} = { - name = "deploy" - } - spec: {str:} = { - replica = 2 - } - -# `Service` schema 定义 -schema Service: - apiVersion: str = "v1" - kind: str = "Service" - metadata: {str:} = { - name = "svc" - } - spec: {str:} = {} - -# 定义两个 `Deployment` 资源 -deployments = [Deployment {}, Deployment {}] -# 定义两个 `Service` 资源 -services = [Service {}, Service {}] -# 将它们放入 KCL 列表,并调用 `manifests.yaml_stream` 函数。 -manifests.yaml_stream(deployments + services) -``` - -首先我们通过 `import` 关键字导入 `manifests` 模块并定义 2 个 Deployment 以及 2 个 Service 资源,当我们想以 YAML stream 并以 `---` 作为分隔符的格式依次输出这 4 个资源时,我们可以将它们合并为一个 KCL 列表并作为 `manifests.yaml_stream` 函数的 `values` 形参进行传入 (如无特殊需求,opts 参数一般使用默认值即可),最终得到 YAML 输出为: - -```yaml -apiVersion: v1 -kind: Deployment -metadata: - name: deploy -spec: - replica: 2 ---- -apiVersion: v1 -kind: Deployment -metadata: - name: deploy -spec: - replica: 2 ---- -apiVersion: v1 -kind: Service -metadata: - name: svc ---- -apiVersion: v1 -kind: Service -metadata: - name: svc -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/math.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/math.md deleted file mode 100644 index 3b2ff0cc..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/math.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: "math" -linkTitle: "math" -type: "docs" -description: math 包 - 数学函数 -weight: 100 ---- - -## ceil - -`ceil(x) -> int` - -返回 `x` 向上取整得到的整数,这是大于等于 `x` 的最小整数。 - -## factorial - -`factorial(x) -> int` - -返回 `x` 的阶乘(即 `x!`),如果 `x` 是负数或者不是整数,则会引发一个错误。 - -## floor - -`floor(x) -> int` - -返回 `x` 向下取整得到的整数,这是小于等于 `x` 的最大整数。 - -## gcd - -`gcd(a: int, b: int) -> int` - -返回 `x` 和 `y` 的最大公约数。 - -## isfinite - -`isfinite(x) -> bool` - -如果 `x` 既不是无穷大也不是 `NaN` 返回 `True`,否则返回 `False`。 - -## isinf - -`isinf(x) -> bool` - -如果 `x` 是正无穷或负无穷返回 `True`,否则返回 `False`。 - -## isnan - -`isnan(x) -> bool` - -如果 `x` 是 `NaN` 返回 `True`,否则返回 `False`。 - -## modf - -`modf(x) -> List[float, float]` - -返回 `x` 的整数和小数部分,两个结果均与 `x` 的正负号相同,并且均为浮点数。 - -## exp - -`exp(x) -> float` - -返回以 `e` 为底数, `x` 的幂。 - -## expm1 - -`expm1(x) -> float` - -返回 `e` 的 `x` 次方减去 1,该函数能够避免由于直接计算 `exp(x) - 1` 而引起的精度损失。 - -## log - -`log(x, base=2.71828182845904523536028747135266250) -> float` - -返回以 `e` 为底数,`x` 的对数。 - -## log1p - -`log1p(x) -> float` - -返回以 `e` 为底数,`1 + x` 的自然对数,该函数能够在 `x` 靠近 0 时精确计算结果。 - -## log2 - -`log2(x) -> float` - -返回 `x` 的以 2 为底的对数。 - -## log10 - -`log10(x) -> float` - -返回 `x` 的以 10 为底的对数。 - -## pow - -`pow(x, y) -> float` - -返回 `x` 的 `y` 次幂(即 `x` 的 `y` 次方)。 - -## sqrt - -`sqrt(x) -> float` - -返回 `x` 的平方根。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/net.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/net.md deleted file mode 100644 index 1050d16d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/net.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: "net" -linkTitle: "net" -type: "docs" -description: net 包 - 网络IP处理 -weight: 100 ---- - -## split_host_port - -`split_host_port(ip_end_point: str) -> List[str]` - -从 `ip_end_point` 分离出 `host` 和 `port`。 - -## join_host_port - -`join_host_port(host, port) -> str` - -合并 `host` 和 `port`。 - -## fqdn - -`fqdn(name: str = '') -> str` - -返回完全限定域名(FQDN)。 - -## parse_IP - -`parse_IP(ip) -> str` - -将 `ip` 解析为真实的 IP 地址。 - -## to_IP4 - -`to_IP4(ip) -> str` - -获取 `ip` 的 IPv4 表示形式。 - -## to_IP16 - -`to_IP16(ip) -> int` - -获取 `ip` 的 IPv6 表示形式。 - -## IP_string - -`IP_string(ip: str | int) -> str` - -返回 IP 字符串。 - -## is_IPv4 - -`is_IPv4(ip: str) -> bool` - -判断 `ip` 是否为 IPv4。 - -## is_IP - -`is_IP(ip: str) -> bool` - -判断 `ip` 是否为有效的 IP 地址。 - -## is_loopback_IP - -`is_loopback_IP(ip: str) -> bool` - -判断 `ip` 是否为回环地址。 - -## is_multicast_IP - -`is_multicast_IP(ip: str) -> bool` - -判断 `ip` 是否为组播地址。 - -## is_interface_local_multicast_IP - -`is_interface_local_multicast_IP(ip: str) -> bool` - -判断 `ip` 是否为接口、本地和组播地址。 - -## is_link_local_multicast_IP - -`is_link_local_multicast_IP(ip: str) -> bool` - -判断 `ip` 是否为链路本地和组播地址。 - -## is_link_local_unicast_IP - -`is_link_local_unicast_IP(ip: str) -> bool` - -判断 `ip` 是否为链路本地和单播地址。 - -## is_global_unicast_IP - -`is_global_unicast_IP(ip: str) -> bool` - -判断 `ip` 是否为全局单播地址。 - -## is_unspecified_IP - -`is_unspecified_IP(ip: str) -> bool` - -判断 `ip` 是否为 `unspecified` 地址。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/regex.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/regex.md deleted file mode 100644 index e7b0c25c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/regex.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "regex" -linkTitle: "regex" -type: "docs" -description: regex 包 - 正则表达式 -weight: 100 ---- - -## replace - -`replace(string: str, pattern: str, replace: str, count=0) -> str` - -替换字符串 `string`中最左边、不重叠并且匹配模式 `pattern` 的部分替换为指定的字符串 `replace`,并返回替换后的字符串 - -## match - -`match(string: str, pattern: str) -> bool` - -尝试在字符串开头应用模式 `pattern`,找到了任何匹配项则返回 `True`,返回 `False` 表示没有找到匹配项 - -## compile - -`compile(pattern: str) -> bool` - -编译正则表达式模式 `pattern`,并返回一个布尔值,表示该模式是否有效 - -## findall - -`findall(string: str, pattern: str) -> List[str]` - -查找 `pattern` 在 `string` 中的所有非重叠匹配,并以字符串列表的形式返回 - -## search - -`search(string: str, pattern: str) -> bool` - -扫描字符串 `string` 以查找与模式匹配的项,如果找到任何匹配项,则返回布尔值 `True`,否则返回 `False` - -## split - -`split(string: str, pattern: str, maxsplit=0) -> List[str]` - -返回一个由字符串内单词组成的列表,使用 `pattern` 作为分隔字符串,最多进行 `maxsplit` 次拆分 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/units.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/units.md deleted file mode 100644 index 8c862d0e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/units.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: "units" -linkTitle: "units" -type: "docs" -description: units 包 - 单位处理 -weight: 100 ---- - -## 单位的常量 - -- 定点数: `n`, `u`, `m`, `k`, `K`, `G`, `T` 和 `P`. -- 2 的幂: `Ki`, `Mi`, `Gi`, `Ti` 和 `Pi`. - -## 函数列表 - -- `to_n(num: int) -> str` - 将 int 转换为以 `n` 作为后缀的字符串 -- `to_u(num: int) -> str` - 将 int 转换为以 `u` 作为后缀的字符串 -- `to_m(num: int) -> str` - 将 int 转换为以 `m` 作为后缀的字符串 -- `to_K(num: int) -> str` - 将 int 转换为以 `K` 作为后缀的字符串 -- `to_M(num: int) -> str` - 将 int 转换为以 `M` 作为后缀的字符串 -- `to_G(num: int) -> str` - 将 int 转换为以 `G` 作为后缀的字符串 -- `to_T(num: int) -> str` - 将 int 转换为以 `T` 作为后缀的字符串 -- `to_P(num: int) -> str` - 将 int 转换为以 `P` 作为后缀的字符串 -- `to_Ki(num: int) -> str` - 将 int 转换为以 `Ki` 作为后缀的字符串 -- `to_Mi(num: int) -> str` - 将 int 转换为以 `Mi` 作为后缀的字符串 -- `to_Gi(num: int) -> str` - 将 int 转换为以 `Gi` 作为后缀的字符串 -- `to_Ti(num: int) -> str` - 将 int 转换为以 `Ti` 作为后缀的字符串 -- `to_Pi(num: int) -> str` - 将 int 转换为以 `Pi` 作为后缀的字符串 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/plugin/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/plugin/_category_.json deleted file mode 100644 index 645deb88..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/plugin/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "插件系统", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/plugin/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/plugin/index.md deleted file mode 100644 index e2fe86d6..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/plugin/index.md +++ /dev/null @@ -1 +0,0 @@ -# 插件系统 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/plugin/project_context.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/plugin/project_context.md deleted file mode 100644 index 0be02e78..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/plugin/project_context.md +++ /dev/null @@ -1,59 +0,0 @@ -# project_context - -project_context extract base info from project.yaml&stack.yaml - -_version: 0.0.1_ - -## `get_project_current_path` - -return the relative path of first file - -Example: - -```py -import kcl_plugin.project_context as ctx - -path = ctx.get_project_current_path() -print(path) -``` - -## `get_project_input_file` - -return compiling file list - -Example: - -```py -import kcl_plugin.project_context as ctx - -input_file = ctx.get_project_input_file() -print(input_file) -``` - -## `get_project_context` - -return the current project context from project.yaml - -Example: - -```py -import kcl_plugin.project_context as ctx - -project = ctx.get_project_context() -# Get project name -print(project?.name) -``` - -## `get_stack_context` - -return the current stack context from stack.yaml - -Example: - -```py -import kcl_plugin.project_context as ctx - -stack = ctx.get_stack_context() -# Get stack name -print(stack?.name) -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/xlang-api/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/xlang-api/_category_.json deleted file mode 100644 index e26f646c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/xlang-api/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "多语言", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/xlang-api/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/xlang-api/index.md deleted file mode 100644 index ea02d458..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/xlang-api/index.md +++ /dev/null @@ -1 +0,0 @@ -# 多语言 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/xlang-api/java-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/xlang-api/java-api.md deleted file mode 100644 index 1cea9e49..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/xlang-api/java-api.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Java API - -目前 KCL Java SDK 还处于早期预览版本,后续 KCL 团队会持续更新并提供更丰富的功能,更多信息请参阅:[https://github.com/kcl-lang/kcl-java](https://github.com/kcl-lang/kcl-java)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/xlang-api/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/xlang-api/overview.md deleted file mode 100644 index 29c8680d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/xlang-api/overview.md +++ /dev/null @@ -1,295 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 简介 - -KCL 语言提供 C/Rust/Go/Python/Java 等通用编程语言接口,相关语言正在开发完整中。 - -## C/Rust 语言 - -KCL 核心采用 Rust 语言开发,对外导出 C 语言 API 供 Go/Python/Java 等高级语言包装和集成。 - -## Go 语言 - -Go 语言是通过 CGO 包装 KCL 提供的 C-API,同时提供更深度的定制特性以满足上层工具的需求。 - -### API 抽象模型 - -Go 语言 API 的抽象模型如下图: - -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ kcl files │ │ KCL-Go-API │ │ KCLResultList │ -│ ┌───────────┐ │ │ │ │ │ -│ │ 1.k │ │ │ │ │ │ -│ └───────────┘ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ ┌───────────┐ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.Get("a.b.c") │ -│ │ 2.k │ │ │ │ Run(path) │ │ │ └───────────┘ │ └───────────────┘ -│ └───────────┘ │────┐ │ └───────────┘ │ │ │ -│ ┌───────────┐ │ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ │ 3.k │ │ │ │ │ │ │ KCLResult │──┼────────▶│x.Get("k", &v) │ -│ └───────────┘ │ │ │ │ │ └───────────┘ │ └───────────────┘ -│ ┌───────────┐ │ ├───▶│ ┌───────────┐ │──────────▶│ │ -│ │setting.yml│ │ │ │ │RunFiles() │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ └───────────┘ │ │ │ └───────────┘ │ │ │ KCLResult │──┼────────▶│x.JSONString() │ -└─────────────────┘ │ │ │ │ └───────────┘ │ └───────────────┘ - │ │ │ │ │ -┌─────────────────┐ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ Options │ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.YAMLString() │ -│WithOptions │ │ │ │MustRun() │ │ │ └───────────┘ │ └───────────────┘ -│WithOverrides │────┘ │ └───────────┘ │ │ │ -│WithWorkDir │ │ │ │ │ -│WithDisableNone │ │ │ │ │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ -``` - -其中输入的文件包含 KCL 文件和 `setting.yml` 配置文件,`Options` 可以用于指定额外的参数和工作目录等信息。“KCL-Go-API”部分是提供的 KCL 执行函数,执行函数根据输入文件和额外的参数执行 KCL 程序,最终输出 `KCLResultList` 结果。`KCLResultList` 是一个 `KCLResult` 构成的列表,每个 `KCLResult` 对应一个生成的配置文件或 `map[string]interface{}`。 - -### 例子 - -```go -package main - -import ( - "fmt" - - kcl "kcl-lang.io/kcl-go" -) - - -func main() { - const k_code = ` -name = "kcl" -age = 1 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person{} -x1 = Person{age:101} -` - - result := kcl.MustRun("hello.k", kcl.WithCode(k_code)).First() - fmt.Println(result.YAMLString()) - - fmt.Println("----") - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - - fmt.Println("----") - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x1", &person)) -} -``` - -输出结果: - -```yaml -age: 1 -name: kcl -x0: - age: 1 - name: kcl -x1: - age: 101 - name: kcl - ----- -x0.name: kcl -x1.age: 101 ----- -person: &{Name:kcl Age:101} -``` - -## REST-API - -KCL 提供的 C-API 并没有 REST-API,REST-API 是通过 Protobuf 定义,最终由上层的 Go-SDK 提供实现。 - -### 启动 REST 服务 - -通过以下方式可以启动 RestAPI 服务: - -```shell -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -然后可以通过 POST 协议请求服务: - -```shell -$ curl -X POST http://127.0.0.1:2021/api:protorpc/BuiltinService.Ping --data '{}' -{ - "error": "", - "result": {} -} -``` - -其中 POST 请求和返回的 JSON 数据和 Protobuf 定义的结构保持一致。 - -### `BuiltinService` 服务 - -其中 `/api:protorpc/BuiltinService.Ping` 路径表示 `BuiltinService` 服务的 `Ping` 方法。 - -完整的 `BuiltinService` 由 Protobuf 定义: - -```protobuf -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} -``` - -其中 `Ping` 方法可以验证服务是否正常,`ListMethod` 方法可以查询提供的全部服务和函数列表。 - -### `KclvmService` 服务 - -`KclvmService` 服务是和 KCL 功能相关的服务。用法和 `BuiltinService` 服务一样。 - -比如有以下的 `Person` 结构定义: - -```python -schema Person: - key: str - - check: - "value" in key # 'key' is required and 'key' must contain "value" -``` - -然后希望通过 `Person` 来校验以下的 JSON 数据: - -```json -{ "key": "value" } -``` - -可以通过 `KclvmService` 服务的 `ValidateCode` 方法完成。参考 `ValidateCode` 方法的 `ValidateCode_Args` 参数结构: - -```protobuf -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} -``` - -根据 `ValidateCode_Args` 参数结构构造 POST 请求需要的 JSON 数据,其中包含 `Person` 定义和要校验的 JSON 数据: - -```json -{ - "code": "\nschema Person:\n key: str\n\n check:\n \"value\" in key # 'key' is required and 'key' must contain \"value\"\n", - "data": "{\"key\": \"value\"}" -} -``` - -将该 JSON 数据保存到 `vet-hello.json` 文件,然后通过以下命令进行校验: - -```shell -$ curl -X POST \ - http://127.0.0.1:2021/api:protorpc/KclvmService.ValidateCode \ - -H "accept: application/json" \ - --data @./vet-hello.json -{ - "error": "", - "result": { - "success": true - } -} -``` - -说明校验成功。 - -## Python 语言 - -使用 Python SDK 要求您本地具备高于 3.7.3 的 Python 版本和 pip 包管理工具,可以通过如下命令进行安装并获得帮助信息 - -```bash -python3 -m pip install kclvm --user && python3 -m kclvm --help -``` - -### 命令行工具 - -编写名为 `main.k` 的 KCL 文件: - -```python -name = "kcl" -age = 1 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {} -x1 = Person { - age = 101 -} -``` - -执行如下命令并获得输出: - -```shell -$ python3 -m kclvm hello.k -name: kcl -age: 1 -x0: - name: kcl - age: 1 -x1: - name: kcl - age: 101 -``` - -### API - -此外,我们还可以通过 Python 代码实现对 KCL 文件的执行 - -编写名为 `main.py` 的 python 文件: - -```python -import kclvm.program.exec as kclvm_exec -import kclvm.vm.planner as planner - -print(planner.plan(kclvm_exec.Run(["hello.k"]).filter_by_path_selector())) -``` - -执行如下命令并获得输出: - -```shell -$ python3 main.py -name: kcl -age: 1 -x0: - name: kcl - age: 1 -x1: - name: kcl - age: 101 -``` - -可以看出通过命令行工具和 API 可以获得同样的输出。 - -目前 KCL Python SDK 还处于早期预览版本,后续 KCL 团队会持续更新并提供更丰富的功能,更多信息请参阅:[https://github.com/kcl-lang/kcl-py](https://github.com/kcl-lang/kcl-py) - -## 其它语言 - -用户也可以基于 C-API 和 RestAPI 包装其它语言的 SDK。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/xlang-api/python-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/xlang-api/python-api.md deleted file mode 100644 index ad3ad867..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/xlang-api/python-api.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Python API - -目前 KCL Python SDK 还处于早期预览版本,后续 KCL 团队会持续更新并提供更丰富的功能,更多信息请参阅:[https://github.com/kcl-lang/kcl-py](https://github.com/kcl-lang/kcl-py)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/Ide/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/Ide/_category_.json deleted file mode 100644 index fcdc7f10..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/Ide/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "集成开发环境", - "position": 2 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/_category_.json deleted file mode 100644 index 5170334a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "工具", - "position": 3 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/_category_.json deleted file mode 100644 index 8fac9ad8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "命令行工具", - "position": 1 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/index.md deleted file mode 100644 index f754b5ca..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# 命令行工具 - -KCL 提供了 IDE 插件、丰富的语言工具和 OpenAPI 工具。通过这些工具,可以提供一整套解决方案,包括配置语言、模型界面、自动化工具和最佳实践。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/kcl/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/kcl/_category_.json deleted file mode 100644 index b22440b7..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/kcl/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KCL 语言工具", - "position": 2 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/openapi/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/openapi/_category_.json deleted file mode 100644 index 5df621d8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/openapi/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "OpenAPI 工具", - "position": 3 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/openapi/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/openapi/index.md deleted file mode 100644 index 0654db2a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/openapi/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# OpenAPI Tools - -kcl-openapi 工具支持将通过 OpenAPI 规范描述的模型转换为 KCL 配置策略语言,除了能直接转换 OpenAPI 描述文件之外,还可以从 Kubernetes CRD 中提取并转换为 KCL schema. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/openapi/spec.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/openapi/spec.md deleted file mode 100644 index aee9fc92..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/openapi/spec.md +++ /dev/null @@ -1,424 +0,0 @@ -# KCL OpenAPI 规范 - -[OpenAPI](https://www.openapis.org/) 允许 API 提供方规范地描述 API 操作和模型,并基于它生成自动化工具和特定语言的客户端。 - -## KCL OpenAPI 文件结构 - -依据 OpenAPI 3.0 规范,OpenAPI 文件中应至少包含 openapi、components、 info、paths 四种根节点对象,KCL OpenAPI 聚焦于其中模型定义的部分,即 OpenAPI 文件中的 `definitions`,而描述操作的 Restful API 部分(即 OpenAPI 文件中的 `paths`)则不属于 KCL OpenAPI 定义的范畴。 -​ - -注:除以上列出的节点外,OpenAPI 官方规范还支持 servers、security、tags、externalDocs 四种可选的根节点,但都不是 KCL OpenAPI 所关心的,因此用户无需填写这部分内容,即使填写了也不会产生任何影响。 -​ - -| OpenAPI 顶层对象 | 类型 | 含义 | KCL OpenAPI 工具支持情况 | -| ---------------- | ----------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | -| swagger | string | openapi 版本信息 | 必填项,目前支持 openapi 2.0,即合法取值为 "2.0" | -| definitions | Definition Object | 模型定义 | 必填项 | -| info | Info Object | 当前 API 文件的元数据信息,例如标题、描述信息、版本、开源协议等 | 必填项,定义当前 OpenAPI 文件的基本信息,不会输出到 KCL 代码,但可用于 Swagger-UI 工具可视化展示 | - -为方便初学者快速理解,下面给出一个典型的 KCL OpenAPI 文件(截取自 swagger example [Petstore](https://petstore.swagger.io/))应包含的节点图示。KCL OpenAPI 工具重点关注其中的 definitions 节点,可以看到文件中定义了两个模型(Pet 和 Category),并且 Pet 模型中包含三个属性(name、id、category) - -## KCL schema - -KCL 中使用 schema 结构来定义配置数据的“类型”,关于 KCL schema,可参考文档:传送门 -在 definitions 节点下新增 definition 元素,即可定义 KCL schema. -示例: -下例在 KCL 代码中定义了 Pet、Category 两个 schema,同样地,其对应的 OpenAPI 也在 definitions 节点下包含这两个模型的描述。 - -```python -# KCL schema: -schema Pet: - name: str - id?: int - category?: Category - -schema Category: - name?: str - -# 对应的 OpenAPI 描述 -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "id": { - "type": "integer", - "format": "int64" - }, - "category": { - "$ref": "#/definitions/Category" - } - }, - "required": [ - "name" - ] - }, - "Category": { - "type": "object", - "properties": { - "name": { - "type": "string" - } - } - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -``` - -### schema 名称 - -在 KCL 中,schema 名称紧跟在 schema 关键字后声明,在 OpenAPI 中,模型的名称通过 definition 元素的 key 来定义。 - -### schema 类型 - -KCL schema 在 OpenAPI 中的类型为 "object". 例如上例中 "Pet" 的 "type" 值应为 "object". - -### schema 属性 - -KCL schema 中可以定义若干属性,属性的声明一般包含如下几部分: - -- 属性注解:可选,以 @ 开头,例如 @deprecated 注解表示属性被废弃 -- 属性名称:必须 -- 属性 optional 修饰符(?):可选,带问号表示当前属性为可选属性,可以不被赋值。反之,不带问号表示必填属性 -- 属性类型:必须,可以是基本数据类型,也可以是 schema 类型, 或者是前述两种类型的并集 -- 属性默认值:非必须 - -它们与 OpenAPI 规范的对应关系如下: - -| KCL schema 属性元素 | OpenAPI 元素 | -| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- | -| 属性注解 | 暂不支持,计划扩展一个 deprecate 字段用于描述 deprecated 注解 | | -| 属性名称 | properties 节点下,每个属性的 key 即为属性名称 | -| 属性 optional 修饰符(?) | 模型节点下,通过 required 字段列出该模型的所有必填属性的名称,未被列出的属性即为 optional | -| 属性类型 | 属性节点下,设置 type + format 可以标识属性的基本类型,如果是 schema 类型则用 $ref 字段表示,类型 union 则由扩展字段 x-kcl-types 来标识,此外,属性节点的 enum、pattern 也可以用于表示 KCL 类型。 | -| KCL-OpenAPI 关于类型的对照关系,详见“基本数据类型”小节 | | -| 属性默认值 | 属性节点下,设置 default 字段即可为属性设置默认值 | - -示例: -下例中 Pet 模型包含了 2 个属性:name(string 类型,必填属性,无注解,无默认值)、id(int64 类型,无注解,非必填,默认值为 -1) - -```python -# KCL schema Pet,包含两个属性 name 和 id -schema Pet: - name: str - id?: int = -1 - -# 对应的 OpenAPI 文档 -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - "id": { - "type": "integer", - "format": "int64", - "default": -1 - } - }, - "required": [ - "name" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### schema 索引签名 - -KCL schema 允许定义索引签名,用于定义属性名不固定的 dict,起到静态模板的作用。具体来说,KCL schema 索引签名包含如下几个元素: - -- 索引签名中 key 的类型:在方括号中声明,必须是基础类型 -- 索引签名中 value 的类型:在冒号后声明,可以是任意合法的 KCL 类型 -- 索引签名中的省略符:在方括号中,key 类型之前声明,使用"..."表示。如果带有该符号,表示该索引签名只用于约束未在 schema 中定义的属性;否则,表示 schema 中所有已定义和未定义属性都收到该索引签名的约束。 -- 索引签名中 key 的别名:在方括号中,紧随左方括号之后声明,使用名称 + 冒号表示,该别名可用于按名称引用索引签名 -- 索引签名的默认值:可以为索引签名设置默认值 - -在 OpenAPI 中,可以借助在模型节点的 `additionalProperties` 字段描述某些 key 为 string 的索引签名。但对于 KCL 索引签名中非 string 类型的 dict key、索引签名 key 的 check 校验,在 OpenAPI 规范没有对等的描述。它们与 OpenAPI 规范的对应关系如下: - -| KCL 索引签名元素 | OpenAPI 元素 | -| ----------------------- | ---------------------------------------------------------------------- | -| 索引签名中 key 的类型 | OpenAPI 仅支持 key 为 string 类型,无法自定义 | -| 索引签名中 value 的类型 | 模型节点的下 additionalProperties 下的 "type" 字段 | -| 索引签名中的省略符 | OpenAPI 中表示索引签名时,只能表示 KCL 中带有省略符的情况 | -| 索引签名中 key 的别名 | OpenAPI 中不支持为索引签名定义 key 别名,(预计通过扩展支持:x-alias) | -| 索引签名的默认值 | 目前不支持 | - -示例:下例中的 KCL schema Pet,包含两个预定义的属性 name 和 id,除此之外,还允许使用该 schema 的配置额外地赋值其他 key 为 string 类型,value 为 bool 类型的属性: - -```python -# KCL schema Pet,包含两个预定义的属性 name 和 id,允许额外给 key 为 string、value 为 bool 的属性赋值 -schema Pet: - name: str - id?: int - [...str]: bool - -# 对应的 OpenAPI 描述 -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - "id": { - "type": "integer", - "format": "int64", - } - }, - "additionalProperties": { - "type": "bool" - }, - "required": [ - "name" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### schema 继承关系 - -### 内联 schema - -OpenAPI 支持嵌套地定义 schema,但 KCL 目前暂不支持 schema 的内联。OpenAPI 中内联定义的 schema 将被转换为 KCL 中带名称的 schema,其名称的命名规则为:在该内联 schema 的上层 schema 名称的基础上,增加相应的后缀。在拼接后缀时,根据定义了该内联 schema 的外层 OpenAPI 元素类型,后缀内容如下: - -| OpenAPI 文档中定义内联 schema 的元素 | KCL schema 名称拼接规则 | -| ------------------------------------ | ------------------------------ | -| 某属性节点 | 增加该属性节点的名称为后缀 | -| AdditionalProperties 节点 | 增加"AdditionalProperties"后缀 | - -注:KCL 未来也可能会支持内联 schema,届时再更新这部分转换规则 -示例 1:下例中的模型 Deployment 包含有 kind、spec 两个属性,其中 deploymentSpec 属性的 schema 通过内联的方式定义: - -```python -# OpenAPI 文档 -{ - "definitions": { - "Deployment": { - "type": "object", - "properties": { - "kind": { - "type": "string", - }, - "spec": { - "type": "object", - "properties": { - "replicas": { - "type": "integer", - "format": "int64" - } - } - } - }, - "required": [ - "kind", - "spec" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -# 转换为 KCL Schema 如下: -schema Deployment: - kind: str - spec: DeploymentSpec - -schema DeploymentSpec: - replicas?: int -``` - -示例 2:下例中的模型 Person 中除固定属性 name 外,还允许包含额外的属性(additionalProperties),并且这部分额外属性的属性值的 schema 通过内联的方式定义: - -```python -# OpenAPI 文档 -{ - "definitions": { - "Person": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - }, - "required": [ - "name", - "spec" - ], - "additionalProperties": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "description": { - "type": "string" - } - }, - "required": [ - "name" - ] - }, - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -# 转换为 KCL Schema 如下: -schema Person: - name: str - [...str]: [PersonAdditionalProperties] - -schema PersonAdditionalProperties: - name: str - description?: str -``` - -## KCL 文档 - -KCL doc 规范请参考:[传送门](../kcl/docgen.md) -KCL 文档包含 module 文档、schema 文档两类,其中 schema 文档可以由 OpenAPI 转换得到。KCL schema 文档包含: - -- schema 描述信息:位于 schema 声明之后、schema 属性声明之前,是对 schema 的总体介绍 -- schema 属性信息:位于 shcema 描述信息之后,以 Attributes + 分割线分隔 -- schema 附加信息:位于 schema 属性信息之后,以 See Also + 分割线分隔 -- schema 示例信息:位于 schema 附加信息之后,以 Examples + 分割线分隔 - -它们与 OpenAPI 规范的对应关系如下: - -| KCL 文档元素 | OpenAPI 元素 | -| --------------- | ---------------------------------------------------- | -| schema 描述信息 | definitions 节点下,每个模型节点的 description 字段 | -| schema 属性信息 | properties 节点下,每个属性节点的 description 字段 | -| schema 附加信息 | definitions 节点下,每个模型节点的 externalDocs 字段 | -| schema 示例信息 | definitions 节点下,每个模型节点的 example 字段 | - -示例: -下例中为 Pet 模型定义了其 schema 描述文档 "The schema Pet definition";Pet 的两个属性 "name" 和 "id" 也分别定义了其属性文档 "The name of the pet" 及 "The id of the pet";Pet 的附加信息为 "Find more info here. [https://petstore.swagger.io/](https://petstore.swagger.io/)";此外,Pet 模型还提供了模型实例的示例写法。 - -```python -# KCL schema Pet,采用规范的 KCL 文档格式 -schema Pet: - """The schema Pet definition - - Attributes - ---------- - name : str, default is Undefined, required - The name of the pet - id : int, default is -1, optional - The age of the pet - - See Also - -------- - Find more info here. https://petstore.swagger.io/ - - Examples - -------- - pet = Pet { - name = "doggie" - id = 123 - } - """ - name: str - id?: int = -1 - -# 对应的 OpenAPI 文档 -{ - "definitions": { - "Pet": { - "description": "The schema Pet definition", - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "The name of the pet" - }, - "id": { - "type": "integer", - "format": "int64", - "default": -1, - "description": "The age of the pet" - } - }, - "required": [ - "name" - ], - "externalDocs": { - "description": "Find more info here", - "url": "https://petstore.swagger.io/" - }, - "example": { - "name": "doggie", - "id": 123 - } - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -​ - -## 基本数据类型 - -| JSON Schema type | swagger type | KCL type | comment | -| ---------------- | --------------------------- | --------------- | --------------------------------------------------------------------------- | -| boolean | boolean | bool | | -| number | number | float | | -| | number format double | **unsupported** | | -| | number format float | float | | -| integer | integer | int (32) | | -| | integer format int64 | **unsupported** | | -| | integer format int32 | int (32) | | -| string | string | str | | -| | string format byte | str | | -| | string format int-or-string | int | str | -| | string format binay | str | | -| | string format date | unsupported | As defined by full-date - [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) | -| | string format date-time | unsupported | As defined by date-time - [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) | -| | string format password | unsupported | for swagger: A hint to UIs to obscure input. | -| | datetime | datetime | | - -## Reference - -- openapi spec 2.0:[https://swagger.io/specification/v2/](https://swagger.io/specification/v2/) -- openapi spec 3.0:[https://spec.openapis.org/oas/v3.1.0](https://spec.openapis.org/oas/v3.1.0) -- openapi spec 3.0(swagger 版本):[https://swagger.io/specification/](https://swagger.io/specification/) -- openapi spec 2.0 #SchemaObject:[https://swagger.io/specification/v2/#schemaObject](https://swagger.io/specification/v2/#schemaObject) -- go swagger:[https://goswagger.io/use/models/schemas.html](https://goswagger.io/use/models/schemas.html) -- swagger data models:[https://swagger.io/docs/specification/data-models/](https://swagger.io/docs/specification/data-models/) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/package-management/command-reference/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/package-management/command-reference/_category_.json deleted file mode 100644 index abcc956a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/package-management/command-reference/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "命令参考", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/concepts/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/concepts/_category_.json deleted file mode 100644 index d3ae7a0a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/concepts/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "核心概念", - "position": 5 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/concepts/package-and-module.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/concepts/package-and-module.md deleted file mode 100644 index fbde28f3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/concepts/package-and-module.md +++ /dev/null @@ -1,156 +0,0 @@ -# 模块和包 - -本节主要介绍如何组织 KCL 中的文件。 - -## 概述 - -在一个**module**中,KCL 按**package**进行组织文件。package 可以在 module 内定义,也可以通过 KCL 包管理器 `kpm` 从外部导入。在后一种情况下,KCL 在专用位置中维护包的副本。 - -## Module - -KCL 模块按目录层次结构布置配置。它包含了确定 KCL 配置结果所需的一切。此目录的根标记为包含 `kcl.mod` 目录。此目录的内容大多由 kcl 工具(如 `kpm` 等)管理。从这个意义上讲,`kcl.mod` 类似于 `.git` 目录,标记着仓库的根目录,但它的内容主要由 git 工具管理。此外,KCL 模块是文件组织的最大单位,具有所有 KCL 文件和依赖项的固定位置。 - -> 注意: 使用 KCL 模块(例如 `kcl.mod`)是可选的,但如果您想使用语义版本管理、分发、共享和重用代码,则需要使用它。 - -### 创建一个 module - -可以通过在模块根目录中运行以下命令来创建模块: - -```bash -kpm init [module name] -``` - -模块名在需要在模块内导入另一个模块的包时是**必需的**。也可以通过手动设置 `kcl.mod` 文件来创建模块。 - -## Package - -在 KCL 中,一个包通常由包含 KCL 文件的“文件夹”组成。这个文件夹可以是实际的磁盘物理路径,也可以由多个 KCL 文件(通常是主包)组成。不同的包通过不同的包路径(如 `kubernetes.core.v1`)唯一地定位。 - -在同一个模块内,可以通过相对或绝对路径的 import 语句互相导入不同的包。在 KCL 解析过程中,相对 import 将被替换为绝对 import,并通过包路径找到相应的 KCL 代码。 - -### 相对导入路径 - -我们可以使用 `.` 运算符来实现 KCL 入口文件的相对路径导入。 - -main.k: - -```python -import .model1 # Current directory module -import ..service # Parent directory -import ...root # Parent of parent directory - -s = service.ImageService {} -m = root.Schema {} -``` - -### 绝对导入路径 - -KCL 语句`import a.b.c.d` 的语义是: - -1. 如果 `kcl.mod` 不存在,则将当前目录视为包根目录,并从当前目录搜索路径 `a/b/c/d`。 -2. 如果当前目录搜索失败,则从根路径 `ROOT_PATH/a/b/c/d` 搜索,否则引发导入错误。 - -根路径 `ROOT_PATH` 的定义是相对于 `kcl.mod` 文件的目录。 - -代码结构: - -```bash -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -### 内置包 - -KCL 有一系列内置包,例如 `math`,`regex` 等。要使用内置包,直接导入并使用其限定标识符调用函数。例如, - -```python -import regex - -image = "nginx:1.14.2" -is_match = regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$") - -``` - -输出的 YAML 为 - -```yaml -image: nginx:1.14.2 -is_match: true -``` - -### 插件包 - - - -KCL 还有一系列插件包,例如 `hello`,`project_context` 等。要使用插件包,需要用 `kcl_plugin.` 包路径前缀导入,并使用其限定标识符调用函数。例如, - -```python -import kcl_plugin.hello - -result = hello.add(1, 1) -``` - -输出的 YAML 为 - -```yaml -result: 2 -``` - -### 主包 - -在 KCL 中,主包的组成通常由编译器参数确定。这是因为KCL模式和约束可以在包中的文件中分隔,甚至可以在目录中组织,考虑将配置写入和维护在隔离块中的便利性。 - -#### 属于主包的文件 - -用户可以使用KCL命令行决定使用哪些配置和约束,例如, - -```bash -kcl file1.k file2.k -``` - -因此,主包包含两个名为 `file1.k` 和 `file2.k` 的 KCL 文件。 - -如果 KCL 被告知为特定目录加载文件,例如: - -```bash -kcl ./path/to/package -``` - -它将只查找 `.k` 后缀的 KCL 文件,并忽略 `_` 或 `_test.k` 前缀的 KCL 文件合并到主包中。此外,如果 `./path/to/package` 包含 `kcl.yaml` 文件,则 `kcl.yaml` 文件将被忽略。 - -此外,我们可以通过配置命令行编译设置文件(例如 `kcl.yaml`)来设置主包文件,如下所示: - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k -``` - -```bash -kcl -Y kcl.yaml -``` - -> 注意:如果没有为 KCL 指定任何输入文件,KCL 将从命令行执行路径查找默认的 `kcl.yaml` 文件读取输入文件。此外,如果我们告诉KCL输入文件和编译设置文件,KCL将把用户输入的输入文件作为最终值。 - -```bash -# 无论`kcl.yaml` 中是否配置 `files` 字段,输入文件的最终值为["file1.k", "file2.k"] -kcl -Y kcl.yaml file1.k file2.k -``` - -## kcl.mod 和 kcl.yaml 异同 - -首先,在 KCL 中,`kcl.mod` 和 `kcl.yaml` 都是可选的。它们之间的区别在于 `kcl.mod` 确定包路径的根路径以及 KCL 模块是否具有分发和重用要求,而 `kcl.yaml` 确定主包的 KCL 文件组成。 - -其次,对于仅用于外部使用的 kcl module,`kcl.yaml` 是可选的,但 `kcl.mod` 是必需的,因为 `kcl.mod` 需要声明 KCL 版本,模块版本,依赖关系和其他信息。 - -最后,对于 KCL IDE 插件,它需要知道主包信息才能形成完整的编译过程,因此它需要根据光标位置自动查找主包组成,因为没有人可以通过 KCL 命令行指定这些信息。一般的查询逻辑是查找 `kcl.yaml` 的存在性。如果找到了,主包由 `kcl.yaml` 中的文件属性组成,如果找不到,主包由当前文件组成。KCL IDE 插件会有选择地了解 `kcl.mod` 文件。当 `kcl.mod` 文件存在时,IDE 插件会读取所有包路径及其在外部依赖项中的实际路径的相应信息。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/concepts/type-and-definition.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/concepts/type-and-definition.md deleted file mode 100644 index 7331c007..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/concepts/type-and-definition.md +++ /dev/null @@ -1,94 +0,0 @@ -# 类型和定义 - -This section mainly covers the concepts related to types and definitions. - -## 类型 - -KCL features a **gradual static type system**, initially designed to consider scalability. Its aim is to significantly reduce the configuration writing difficulties for users while maintaining stability. Static typing enhances code quality, acts as documentation, and helps detect errors at an early stage when needed. For instance, defining a complete static type for data like JSON/YAML can be challenging, similar to how TypeScript adds complexity in handling type gymnastics due to the lack of runtime type checks for Javascript. In contrast, KCL incorporates a similar TypeScript type system while still retaining runtime type checks. Thus, type errors will always appear at runtime. Consequently, KCL has types, but they can be selectively used when necessary, and it handles interactions between typed and untyped code elegantly and securely. - -The configuration of attributes and types in KCL usually follows a simple pattern: - -$$ -k = (T) v -$$ - -where $k$ is the attribute name, $v$ is the attributes value, and $T$ is the type annotation. Since KCL has the ability of the type inference, $T$ is usually omitted. - -By default, KCL does not require type annotations and performs type checks at runtime. - -```python -name = "nginx" # The type of `name` is `str` -port = 80 # The type of `port` is `int` -``` - -As long as we operate on basic types such as integers and strings, it is generally sufficient to annotate the default type and directly write the configuration. KCL can infer the type of basic data. We recommend writing types for complex structures and function definitions, which will clearly provide a good input prompt for other users who use structures and functions. - -```python -# Types for schema -schema App: - name: str - domainType: "Standard" | "Customized" | "Global" - containerPort: int - volumes: [Volume] - services: [Service] - - check: - 1 <= containerPort <= 65535 - -schema Service: - clusterIP: str - $type: str - - check: - clusterIP == "None" if $type == "ClusterIP" - -schema Volume: - container: str = "*" # The default value of `container` is "*" - mountPath: str - - check: - mountPath not in ["/", "/boot", "/home", "dev", "/etc", "/root"] - -# Types for lambda -appFilterFunc = lambda apps: [App], name: str -> [App] { - [a for a in apps if a.name == name] -} -``` - -More formal definitions and usage of types are at the [type specification document](/docs/reference/lang/types/) and the [tour document of the type system](/docs/reference/lang/tour#type-system) - -**Schema** is the core type in KCL, just like a database schema, which defines the organization of configuration data. This includes logical constraints such as schema names, fields, data types, and the relationships between these entities. Patterns typically use visual representations to convey the architecture of a database, becoming the foundation for organizing configuration data. The process of designing schema patterns is also known as configuration modeling. KCL Schema typically serves various roles, such as application developers, DevOps platform administrators, and SRE, and provides them with a unified configuration interaction interface. - -In addition, the ability to enforce constraints from top to bottom is crucial for any large-scale configuration setting. Therefore, KCL not only provides the ability to define static types but also provides the rich ability to define constraints, which is to some extent equivalent to assertion statements in programming languages. To prevent assertions from constantly expanding, we place structural constraints together with structural type definitions and support custom error messages. - -In KCL, we can use schema to organize the configuration data to meet the requirements of model definition, abstraction, and templating. Schema is the core feature of KCL, which defines attributes, operations, and check-blocks. Usually, a formal form of KCL Schema can be written in the following form: - -$$ -S = \Sigma_{i = 1}^{N} \{s_i, T_i, \mathcal{T}[s_i]\}, -$$ - -where $N$ is the total number of attributes, $\mathcal{T}$ is the attribute constraint, $s_i$ and $T_i$ denotes the $i$-th attribute name and type. Simultaneously, to improve the reusability of the code and meet the needs of hierarchical definition, KCL draws on the experience of OOP and uses single inheritance to reuse and extend the schema. Schema inheritance can be regarded as a special type of partial order relationship, and satisfies - -$$ -unionof(T_1, T_2) = T_2 \Leftrightarrow T_1 \subseteq T_2, -$$ - -where $T_1$ and $T_2$ are both schema types. When the above equation is not satisfied, the KCL will throw a type check error. - -A typical schema with constraints is defined as follows: - -```python -import regex - -schema Secret: - name: str - # Data defines the keys and data that will be used by secret. - data?: {str:str} - - check: - all k in data { - regex.match(k, r"[A-Za-z0-9_.-]*") - } if data, "a valid secret data key must consist of alphanumeric characters, '-', '_' or '.'" -``` - -More specifications and usage of KCL schema and constraint is [here](/docs/reference/lang/spec/schema). diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/getting-started/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/getting-started/_category_.json deleted file mode 100644 index c826d665..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/getting-started/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "快速开始", - "position": 1 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/getting-started/kcl-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/getting-started/kcl-quick-start.md deleted file mode 100644 index 8d75e878..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/getting-started/kcl-quick-start.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -sidebar_position: 3 ---- - -# KCL 语言速览 - -KCL 是一个面相云原生配置策略领域的编程语言。KCL 设计之初受 Python3 启发,同时吸收了声明式、OOP 编程范式的设计理念,是一种专用于配置策略定义、校验的静态强类型的面相配置和策略场景的语言。本节我们将快速展示 KCL 语言的基本特性。 - -## 1. Hello KCL - -学习新语言的最佳途径是自己亲手写几个小程序,配置语言也是如此。KCL 作为一种配置策略语言,我们可以像写配置一样写 KCL 程序。 - -下面是一个简单的 `hello.k` 程序: - -```python -hello = "KCL" -``` - -将 `hello` 属性设置为 `"KCL"` 字符串。然后将代码保存到 `hello.k` 文件中。 - -如何执行这个程序取决于具体的开发环境,我们先假设本地的 macOS 或者是 Linux 系统已经安装了 `kcl` 命令(或者通过 `docker run --rm -it kcllang/kcl` 进入 Docker 环境测试)。然后在文件所在的目录命令行输入以下命令执行: - -```shell -kcl hello.k -``` - -输出为 - -```yaml -hello: KCL -``` - -命令行执行的效果如图所示: - -![](/img/docs/user_docs/getting-started/hello.gif) - -输出的是 YAML 格式的配置数据。这个程序虽然简单,但是我们可以通过执行 KCL 配置程序到输出结果验证了开发环境和 `kcl` 命令行的基本用法。 - -## 2. 再复杂一点的配置 - -常见的配置数据除了的普通的 key-value 对,还有嵌套的字典和列表类型,同时 value 基础类型除了字符串还有布尔和数值等类型。下面是更为复杂一点的 `server.k` 配置: - -```python -# This is a KCL document - -title = "KCL Example" - -owner = { - name = "The KCL Authors" - data = "2020-01-02T03:04:05" -} - -database = { - enabled = True - ports = [8000, 8001, 8002] - data = [["delta", "phi"], [3.14]] - temp_targets = {cpu = 79.5, case = 72.0} -} - -servers = [ - {ip = "10.0.0.1", role = "frontend"} - {ip = "10.0.0.2", role = "backend"} -] -``` - -其中 `#` 开头的表示行注释。`owner` 的 value 是一个字典,字典的面值通过 `{}` 方式包含的内容,字典内部的 key-value 和 `hello = "KCL"` 例子的写法类似。`database` 则是另一个字典,其中字典属性的 value 出现了布尔 `True`、列表 `[]` 和 `{}` 字典,其中列表和字典中还出现了数值类型的 value。 最后一个 `servers` 属性则是一个列表,列表内部嵌套着字典(字典和列表以及后续将要讲到的 `schema` 都可以相互嵌套)。 - -该配置输出的 YAML 结果如下: - -```yaml -$ kcl server.k -title: KCL Example -owner: - name: The KCL Authors - data: '2020-01-02T03:04:05' -database: - enabled: true - ports: - - 8000 - - 8001 - - 8002 - data: - - - delta - - phi - - - 3.14 - temp_targets: - cpu: 79.5 - case: 72.0 -servers: -- ip: 10.0.0.1 - role: frontend -- ip: 10.0.0.2 - role: backend -``` - -## 3. schema 定义配置的结构 - -KCL 通过 `schema` 语法结构为有着固定属性结构和默认值行为的属性提供抽象支持。 - -比如上面例子的中 `database` 的配置一般是用默认值即可。这样我们可以通过为数据库的默认配置定义一个结构: - -```python -schema DatabaseConfig: - enabled: bool = True - ports: [int] = [8000, 8001, 8002] - data: [[str|float]] = [["delta", "phi"], [3.14]] - temp_targets: {str: float} = {cpu = 79.5, case = 72.0} -``` - -`enabled` 是布尔类型;`ports` 为整数列表类型;`data` 为列表的列表,内层的列表元素是字符串或者浮点数类型;`temp_targets` 则是一个字典类型,字典的属性值是浮点数类型。并且 `DatabaseConfig` 的每个属性都定义了默认值。 - -然后通过 `database = DatabaseConfig {}` 就可以产生和默认值相同属性的结构。用户也可以修改默认值: - -```python -database = DatabaseConfig { - ports = [2020, 2021] -} -``` - -`schema DatabaseConfig` 不仅仅为属性提供了默认值,还为属性添加了类型信息。因此,如果用户不小心写错属性值类型的话,KCL 将会给出友好的错误提示,比如下面的例子将 `ports` 错误地写成了浮点数类型: - -```python -database = DatabaseConfig { - ports = [1.2, 1.3] -} -``` - -执行时将产生类似以下的错误(显示的文件路径和本地环境有关): - -```shell -kcl server.k -``` - -输出为 - -```shell -error[E2G22]: TypeError - --> /path/to/server.k:8:5 - | -8 | ports = [1.2, 1.3] - | ^ expected [int], got [float(1.2)|float(1.3)] - | - - --> /path/to/server.k:3:5 - | -3 | ports: [int] = [8000, 8001, 8002] - | ^ variable is defined here, its type is [int], but got [float(1.2)|float(1.3)] - | -``` - -类似地我们可以用以下的代码封装 `servers` 部分的属性: - -```python -schema ServerConfig: - ip: str - role: "frontend" | "backend" - -servers = [ - ServerConfig {ip = "10.0.0.1", role = "frontend"} - ServerConfig {ip = "10.0.0.2", role = "backend"} -] -``` - -其中 `ServerConfig` 的 `ip` 是字符串类型,并没有给出默认值。用户在生成 `ServerConfig` 类型的属性时必须手工添加 `ip` 属性的值,否则 KCL 将会报出缺少必填属性的错误。`role` 属性是 `"frontend" | "backend"` 枚举字符串类型。 - -此外,`schema` 还可以结合 `check`、`mixin`、可选属性、继承和扩展模块实现更为复杂的配置和策略数据的抽象,细节可以参考手册部分的文档。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/_category_.json deleted file mode 100644 index 1fdf894e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "用户手册", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/abstraction.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/abstraction.md deleted file mode 100644 index da590317..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/abstraction.md +++ /dev/null @@ -1,149 +0,0 @@ ---- -title: "抽象" -sidebar_position: 3 ---- - -## 什么是抽象 - -抽象是指一个实体的简化表示,它允许隐藏特定的具体细节,同时向程序员提供最相关的信息。每一个抽象都是为满足特定需求而定制的,并且可以极大地提高给定实体的可用性。在 KCL 的上下文中,抽象可以使代码更容易理解和维护,同时也可以简化用户界面。 - -需要注意的是,代码抽象并不是为了减少代码大小,而是为了提高代码的可维护性和可扩展性。在抽象代码的过程中,应考虑可重用性、可读性和可扩展性等因素,并根据需要对代码进行不断优化。 - -良好的抽象可以提供如下价值 - -1. 提供不同的焦点,不同角色和场景关注点分离。 -2. 屏蔽较低级别的细节,避免潜在的错误。 -3. 提升用户界面和自动化友好性。 - -KCL 自身可能不会评估用户定义模型抽象的合理性,但它提供了技术解决方案来帮助用户构建抽象。 - -## 使用 KCL 进行抽象 - -现在,让我们将 Docker Compose 和 Kubernetes 资源抽象为应用程序配置 - -`Docker Compose` 是一个用于定义和运行多容器 Docker 应用程序的工具。使用 Docker Compose,您可以在一个文件中定义应用程序的服务、网络和卷,然后使用它作为一个单元启动和停止应用程序。Docker Compose 通过处理网络、存储和其他基础设施问题的细节,简化了运行复杂的多容器应用程序的过程。 - -Kubernetes 清单是定义 Kubernete 对象(如 Pods、Deployments 和 Services)的 YAML 文件。清单提供了一种声明性的方法来定义应用程序的所需状态,包括副本数量、要使用的镜像和网络配置。Kubernetes 使用清单来创建和管理部署和运行应用程序所需的资源。 - -以下是一些参考资料,可以帮助了解更多关于 Docker Compose 和 Kubernetes 相关的信息: - -- [Docker Compose 文档](https://docs.docker.com/compose/) -- [Kubernetes 对象文档](https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/) - -以应用程序为中心的开发使开发人员能够专注于其工作负载的体系结构,而不是目标环境、基础设施或平台中的技术栈。我们用 `App` 结构定义了应用程序模型,然后使用 KCL CLI 将其翻译到多个平台,例如不同版本的 `Docker Compose` 或 `Kubernetes`。该应用程序模型旨在通过只需定义一个跨多个平台工作的 KCL 文件来减少开发人员的工作量和认知负荷。现在,让我们学习如何做到这一点。 - -### 0. 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. 获取示例 - -首先,我们执行 git 命令获得用例 - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/abstraction -``` - -我们可以运行以下命令来显示配置。 - -```bash -cat main.k -``` - -输出为 - -```python -import .app - -app.App { - name = "app" - containers.nginx = { - image = "nginx" - ports = [{containerPort = 80}] - } - service.ports = [{ port = 80 }] -} -``` - -在上面的代码中,我们使用 `App` schema 定义了一个配置,其中我们配置了一个 `nginx` 容器,并开启 `80` 端口配置。 - -此外,KCL 允许开发人员以声明式的方式定义应用程序所需的资源,并允许生成特定于平台的配置文件,如 `docker_compose.yaml` 或 Kubernetes `manifests.yaml` 文件。接下来,让我们生成相应的配置。 - -### 2. 将应用配置转换为 Docker Compose 配置 - -如果我们想将应用程序配置转换为 Docker Compose 配置,我们可以简单地运行如下命令: - -```shell -kcl main.k docker_compose_render.k -``` - -输出为 - -```yaml -services: - app: - image: nginx - ports: - - published: 80 - target: 80 - protocol: TCP -``` - -### 3. 将应用配置转换为 Kubernetes Deployment and Service 资源清单 - -如果我们想将应用程序配置转换为 Kubernetes 清单,我们可以简单地运行如下命令: - -```shell -kcl main.k kubernetes_render.k -``` - -输出为 - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: app - labels: - app: app -spec: - replicas: 1 - selector: - matchLabels: - app: app - template: - metadata: - labels: - app: app - spec: - containers: - - name: nginx - image: nginx - ports: - - protocol: TCP - containerPort: 80 ---- -apiVersion: v1 -kind: Service -metadata: - name: app - labels: - app: app -spec: - selector: - app: app - ports: - - port: 80 - protocol: TCP -``` - -如果您想了解有关应用程序模型的更多信息,可以参考[此处](https://github.com/kcl-lang/kcl-lang.io/tree/main/examples/abstraction). - -## 小结 - -通过使用 KCL,我们能够分离模型的抽象和实现细节,允许将抽象模型映射到各种基础设施或平台。这是通过不同实现之间的灵活切换和 KCL 组合编译来实现的,以屏蔽配置差异,减轻认知负担。 - -## 更多信息 - -除了手动维护配置外,我们还可以使用 KCL API 将**自动配置更改能力**集成到我们的应用程序中。有关 KCL 自动化能力的相关说明,请参阅[此处](/docs/user_docs/guides/automation)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/ci-integration/1-github-actions.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/ci-integration/1-github-actions.md deleted file mode 100644 index b93fdec9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/ci-integration/1-github-actions.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -id: github-actions -sidebar_label: Github Actions ---- - -# Github Actions 集成 - -## 简介 - -在 GitOps 章节,我们介绍了如何将 KCL 与 GitOps 进行集成。在本文中,我们将继续提供 KCL 和 CI 集成的示例方案,希望通过使用容器、用于生成的持续集成 (CI) 和用于持续部署 (CD) 的 GitOps 来实现端到端应用程序开发流程。在此方案中,我们使用一个 Flask 应用和 Github Actions 将用作示例。 - -> 注意:你可以在此方案中使用任何容器化应用以及不同的 CI 系统如 Gitlab CI,Jenkins CI 等。 - -整体工作流程如下: - -- 应用代码开发并提交到提交到 GitHub 存储库 -- GitHub Actions 从应用代码生成容器镜像,并将容器镜像推送到 docker.io 容器注册表 -- GitHub Actions 根据 docker.io 容器注册表中容器镜像的版本号并同步更新 KCL 清单部署文件 - -## 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -## 具体步骤 - -### 1. 获得示例 - -我们将业务源码和部署清单放在不同仓库,可以分不同角色进行分别维护,实现关注点分离。 - -- 获得业务源码 - -```shell -git clone https://github.com/kcl-lang/flask-demo.git/ -cd flask-demo -``` - -这是一个使用 Python 编写的 Web 应用,我们可以使用应用目录的 `Dockerfile` 来生成这个应用的容器镜像,同时可以通过 Github CI 自动构建 `flask_demo` 镜像,CI 配置如下 - -```yaml -# This is a basic workflow to help you get started with Actions - -name: CI - -# Controls when the workflow will run -on: - # Triggers the workflow on push or pull request events but only for the main branch - push: - branches: [main] - pull_request: - branches: [main] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "build" - build: - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - - - name: Docker Login - uses: docker/login-action@v1.10.0 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - logout: true - - # Runs a set of commands using the runners shell - - name: build image - run: | - make image - docker tag flask_demo:latest ${{ secrets.DOCKER_USERNAME }}/flask_demo:${{ github.sha }} - docker push ${{ secrets.DOCKER_USERNAME }}/flask_demo:${{ github.sha }} - - # Trigger KCL manifest - - name: Trigger CI - uses: InformaticsMatters/trigger-ci-action@1.0.1 - with: - ci-owner: kcl-lang - ci-repository: flask-demo-kcl-manifests - ci-ref: refs/heads/main - ci-user: kcl-bot - ci-user-token: ${{ secrets.DEPLOY_ACCESS_TOKEN }} - ci-name: CI - ci-inputs: >- - image=${{ secrets.DOCKER_USERNAME }}/flask_demo - sha-tag=${{ github.sha }} -``` - -我们需要源码仓库的工作流自动触发部署清单仓库中的工作流,此时需要创建具有 Github CI 操作权限的 `secrets.DEPLOY_ACCESS_TOKEN` 以及 Docker Hub 镜像推送的账号信息 `secrets.DOCKER_USERNAME` 和 `secrets.DOCKER_PASSWORD`, 这些可以在 Github 仓库的 `Secrets and variables` 设置中进行配置,如下图所示 - -![](/img/docs/user_docs/guides/ci-integration/github-secrets.png) - -### 2. 提交应用代码 - -flask-demo 仓库提交代码后,Github 会自动构建容器镜像,并将制品推送到 Docker hub 中,会再触发 flask-demo-kcl-manifests 仓库的 Action,[通过 KCL 自动化 API](/docs/user_docs/guides/automation) 修改部署清单仓库中的镜像地址。现在让我们为 flask-demo 仓库创建一个提交,我们可以看到代码提交后触发业务仓库 Github CI 流程 - -![](/img/docs/user_docs/guides/ci-integration/app-ci.png) - -### 3. 配置自动更新 - -当业务仓库 Github CI 流程执行完成后,会自动在存放 KCL 资源配置的仓库触发一个 CI 自动更新配置并提交到 flask-demo-kcl-manifests main 分支,commit 信息如下 - -![](/img/docs/user_docs/guides/ci-integration/image-auto-update.png) - -- 我们可以获得部署清单源码进行编译验证 - -```shell -git clone https://github.com/kcl-lang/flask-demo-kcl-manifests.git/ -cd flask-demo-kcl-manifests -git checkout main && git pull && kcl -``` - -输出 YAML 为 - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - replicas: 1 - selector: - matchLabels: - app: flask_demo - template: - metadata: - labels: - app: flask_demo - spec: - containers: - - name: flask_demo - image: "kcllang/flask_demo:6428cff4309afc8c1c40ad180bb9cfd82546be3e" - ports: - - protocol: TCP - containerPort: 5000 ---- -apiVersion: v1 -kind: Service -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - type: NodePort - selector: - app: flask_demo - ports: - - port: 5000 - protocol: TCP - targetPort: 5000 -``` - -从上述配置可以看出资源的镜像确实自动更新为了新构建的镜像内容。此外,我们还可以使用 Argo CD KCL 插件 自动从 Git 存储库同步或从中拉取数据并将应用部署到 Kubernetes 集群。 - -## 小结 - -通过将 KCL 和 Github CI 集成,我们能够将任意的业务代码的产出容器化镜像进行自动化修改并部署配置,以实现端到端应用程序开发流程并提升研发部署效率。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/ci-integration/_2-gitlab-ci.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/ci-integration/_2-gitlab-ci.md deleted file mode 100644 index 5ec96ce9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/ci-integration/_2-gitlab-ci.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -id: gitlab-ci -sidebar_label: Gitlab CI ---- - -Coming Soon - -## Introduction - -## How to - -## Summary diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/ci-integration/_3-jenkins-ci.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/ci-integration/_3-jenkins-ci.md deleted file mode 100644 index f85d231f..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/ci-integration/_3-jenkins-ci.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -id: github-ci -sidebar_label: Github CI ---- - -Coming Soon - -## Introduction - -## How to - -## Summary diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/ci-integration/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/ci-integration/_category_.json deleted file mode 100644 index 3145ed7f..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/ci-integration/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "CI Integration", - "position": 12 -} \ No newline at end of file diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/configuration.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/configuration.md deleted file mode 100644 index 127505c9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/configuration.md +++ /dev/null @@ -1,129 +0,0 @@ ---- -title: "配置" -sidebar_position: 1 ---- - -## 简介 - -配置是软件系统的一个重要方面,由于不断发展的业务需求、基础设施需求和其他因素,这些系统会不断发生变化。通常,快速改变这些系统的行为可能具有挑战性,尤其是当这样做需要昂贵且耗时的重建和重新部署过程时。在这种情况下,仅仅对业务代码进行更改可能是不够的。幸运的是,配置提供了一种低开销的方式来修改系统功能。 - -我们可以根据需要将静态配置存储在 JSON 或 YAML 等文件中。此外,配置也可以存储在高级语言中,从而实现更灵活的配置。这种语言可以进行编码、呈现和静态配置。KCL 是一种提供此类功能的配置语言。开发人员可以编写 KCL 代码来生成JSON/YAML 和其他配置。 - -## 使用 KCL 编写配置代码 - -KCL 的核心特性是其**建模**和**约束**能力,KCL 核心功能基本围绕 KCL 这个两个核心特性展开,对于代码而言(包括配置代码)都存在对配置数据约束的需求,比如类型约束、配置字段必选/可选约束、范围约束、不可变性约束等,这也是 KCL 致力于解决的核心问题之一。 - -现在我们已经了解了 KCL 的基本功能,让我们探索如何使用它来生成配置。 - -### 0. 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. 获取示例 - -首先,执行如下命令获取示例 - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/configuration -``` - -我们可以执行如下命令显示配置代码 - -```shell -cat nginx.k -``` - -输出为: - -```python -schema Nginx: - """Schema for Nginx configuration files""" - http: Http - -schema Http: - server: Server - -schema Server: - listen: int | str # The attribute `listen` can be int type or a string type. - location?: Location # Optional, but must be non-empty when specified - -schema Location: - root: str - index: str - -nginx = Nginx { - http.server = { - listen = 80 - location = { - root = "/var/www/html" - index = "index.html" - } - } -} -``` - -### 2. 使用 KCL 生成 YAML - -执行如下命令: - -```bash -kcl nginx.k -``` - -我们可以获得如下 YAML 输出 - -```yaml -nginx: - http: - server: - listen: 80 - location: - root: /var/www/html - index: index.html -``` - -### 3. 为配置添加动态参数 - -此外,我们可以通过 KCL 内置函数 `option` 动态接收外部参数。例如,对于下面的 KCL 文件(db.k),我们可以使用命令行 `-D` 标志来接收外部动态参数。 - -```python -env: str = option("env") or "dev" # The attribute `env` has a default value "den" -database: str = option("database") -hosts = { - dev = "postgres.dev" - stage = "postgres.stage" - prod = "postgres.prod" -} -dbConfig = { - host = hosts[env] - database = database - port = "2023" - conn = "postgres://${host}:${port}/${database}" -} -``` - -```bash -# Use the `-D` flag to input external parameters. -kcl db.k -D database="foo" -``` - -输出为 - -```yaml -env: dev -database: foo -hosts: - dev: postgres.dev - stage: postgres.stage - prod: postgres.prod -dbConfig: - host: postgres.dev - database: foo - port: "2023" - conn: "postgres://postgres.dev:2023/foo" -``` - -## 小结 - -通过使用KCL,我们可以生成更低低级别的数据配置。此外啊,我们通过 `-D` 标志设置动态参数以满足不同的场景需求。有关更多 KCL 的功能和教程,请参阅[此处](/docs/reference/lang/tour)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/data-integration.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/data-integration.md deleted file mode 100644 index 89511b2e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/data-integration.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: "数据集成" -sidebar_position: 4 ---- - -## 简介 - -在 KCL 中,不仅可以将 KCL 编写的配置代码编译输出为 YAML 格式的数据,还可以将 JSON/YAML 等数据直接嵌入到 KCL 语言当中。 - -## 使用 KCL 进行数据集成 - -### 0. 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. 获得示例 - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/data-integration -``` - -### 2. YAML 集成 - -我们可以运行以下命令来显示 KCL YAML 集成配置。 - -```bash -cat yaml.k -``` - -```python -import yaml - -schema Server: - ports: [int] - -server: Server = yaml.decode("""\ -ports: -- 80 -- 8080 -""") -server_yaml = yaml.encode({ - ports = [80, 8080] -}) -``` - -在上述代码中,我们通过 KCL 内置的 `yaml` 模块以及其中的 `yaml.decode` 直接完成 YAML 数据的集成,并且使用 `Server` schema 对集成的 YAML 数据直接进行校验。此外,我们可以使用 `yaml.encode` 完成 YAML 数据的序列化。 - -我们通过如下命令可以获得配置输出: - -```shell -kcl yaml.k -``` - -输出为 - -```yaml -server: - ports: - - 80 - - 8080 -server_yaml: | - ports: - - 80 - - 8080 -``` - -### 3. JSON 集成 - -同样的,对于 JSON 数据,我们可以使用 `json.encode` 和 `json.decode` 函数以同样的方式进行数据集成。 - -我们可以运行以下命令来显示 KCL JSON 集成配置。 - -```bash -cat json.k -``` - -```python -import json - -schema Server: - ports: [int] - -server: Server = json.decode('{"ports": [80, 8080]}') -server_json = json.encode({ - ports = [80, 8080] -}) -``` - -执行命令输出为: - -```shell -kcl json.k -``` - -```yaml -server: - ports: - - 80 - - 8080 -server_json: '{"ports": [80, 8080]}' -``` - -## 小结 - -本文介绍了如何在 KCL 中进行数据集成,使用 KCL 内置的 yaml 和 json 包将 YAML 和 JSON 数据直接集成到 KCL 语言中,并使用相应的解码和编码功能对其进行验证和序列化。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/gitops/1-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/gitops/1-quick-start.md deleted file mode 100644 index 673064c4..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/gitops/1-quick-start.md +++ /dev/null @@ -1,145 +0,0 @@ ---- -id: gitops-quick-start -sidebar_label: 快速开始 ---- - -# 快速开始 - -## 简介 - -### 什么是 GitOps - -GitOps 是一种实现持续交付的现代方式。它的核心思想是拥有一个包含环境和应用程序配置的 Git 存储库。通过更改应用存储库中的文件,可以自动部署应用程序。应用 GitOps 的好处包括: - -- 提高生产力,持续交付可以加快部署时间。 -- 降低开发人员部署的障碍。通过推送代码而不是容器配置,开发人员可以在不知道其内部实现的情况下轻松部署 Kubernetes 集群和应用。 -- 追踪变更记录。使用 Git 管理配置使每一项更改都具有可跟踪性,从而增强审计跟踪。 - -### 将 KCL 与 ArgoCD 一起使用 - -将 [KCL](https://github.com/kcl-lang/kcl) 与 [ArgoCD](https://github.com/argoproj/argo-cd) 等 GitOps 工具一起使用具有如下好处: - -- 通过 KCL 语言的[抽象能力](/docs/user_docs/guides/abstraction)和可编程能力可以帮助我们**简化复杂的 Kubernetes 部署配置文件**,降低手动编写 YAML 文件的错误率,消除多余的配置模版,提升多环境多租户的配置扩展能力,同时提高配置的可读性和可维护性。 -- KCL 允许开发人员以声明式的方式定义应用程序所需的资源,通过将 KCL 和 ArgoCD 相结合可以帮助我们更好地实现**基础设施即代码(IaC)**,提高部署效率,简化应用程序的配置管理。 -- ArgoCD 可以**自动化**地实现应用程序的连续部署,并提供友好的可视化界面。 - -使用 GitOps,开发人员和运维团队可以通过分别修改应用和配置代码来管理应用程序的部署,GitOps 工具链将自动同步对配置的更改,从而实现持续部署并确保一致性。如果出现问题,可以使用 GitOps 工具链快速回滚。 - -## 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -## 快速开始 - -### 1. 获取示例 - -首先,我们执行 git 命令获得用例 - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/gitops -``` - -我们可以运行以下命令来显示配置 - -```bash -cat config/main.k -``` - -The output is - -```python -import .app - -config = app.App { - name = "kcl-guestbook-ui" - containers.guestbook = { - image = "gcr.io/heptio-images/ks-guestbook-demo:0.2" - ports = [{containerPort = 80}] - } - service.ports = [{ port = 80 }] - service.type = "LoadBalancer" -} -``` - -在上述代码中,我们定义使用 `App` schema 定义了应用的配置,其中我们配置了一个镜像为 `gcr.io/heptio-images/ks-guestbook-demo:0.2` 容器,并启用了 `80` 端口。 - -### 2. 安装 Kubernetes 和 GitOps 工具 - -#### 配置 Kubernetes 集群和 ArgoCD 控制器 - -- 安装 [K3d](https://github.com/k3d-io/k3d) 并创建一个集群 - -```bash -k3d cluster create mycluster -``` - -> 注意:你可以在此方案中使用其他方式创建您自己的 Kubernetes 集群,如 kind, minikube 等。 - -- 安装 [ArgoCD](https://github.com/argoproj/argo-cd/releases/). - -```bash -kubectl create namespace argocd -kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml -``` - -- 安装 ArgoCD KCL 插件 - -```bash -kubectl apply -f ./install/kcl-cmp.yaml && kubectl -n argocd patch deploy/argocd-repo-server -p "$(cat ./install/patch-argocd-repo-server.yaml)" -``` - -- 通过 `kubectl get` 命令查看 argocd 控制器容器是否初始化完成进入运行(Running)状态。 - -```bash -kubectl get pod -n argocd -l app.kubernetes.io/name=argocd-repo-server -``` - -- 通过如下命令打开 ArgoCD UI - -```bash -kubectl port-forward svc/argocd-server -n argocd 8080:443 -``` - -- 打开浏览器 `https://localhost:8080` 输入用户名 "admin" 和密码登陆 ArgoCD UI,密码可以通过如下命令得到: - -```bash -kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d -``` - -#### 安装 ArgoCD 客户端工具 - -- 安装 [ArgoCD 客户端工具](https://github.com/argoproj/argo-cd/releases) - -- 使用用户名 "admin" 和刚才得到的密码登陆 - -```bash -argocd login localhost:8080 -``` - -通过如下命令创建一个 ArgoCD KCL 应用 - -```bash -argocd app create guestbook \ ---repo https://github.com/kcl-lang/kcl-lang.io \ ---path examples/gitops/config \ ---dest-namespace default \ ---dest-server https://kubernetes.default.svc \ ---config-management-plugin kcl-v1.0 -``` - -如果创建成功,您可以看到如下输出: - -```bash -application 'guestbook' created -``` - -> 如果您使用的是私有存储库,则在执行 create 命令之前,需要使用私钥凭据配置专用私有存储库访问权限。请参阅[这里](https://argo-cd.readthedocs.io/en/stable/user-guide/private-repositories/)以获取更多详细信息。 - -通过 ArgoCD UI,您可以看到创建的应用程序尚未同步,您可以手动进行配置同步或设置为自动同步。 - -![](/img/docs/user_docs/guides/gitops/argocd-kcl-app.jpg) - -有关同步策略的更多信息,可以请参阅[这里](https://argo-cd.readthedocs.io/en/stable/user-guide/sync-options/) - -![](/img/docs/user_docs/guides/gitops/argocd-kcl-app-dashboard.jpg) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/gitops/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/gitops/_category_.json deleted file mode 100644 index 29a73c67..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/gitops/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "GitOps", - "position": 11 -} \ No newline at end of file diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md deleted file mode 100644 index 23dd53a5..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md +++ /dev/null @@ -1,73 +0,0 @@ -# 发布 KCL 包到 ghcr.io - -本文将指导您如何使用 kcl 包管理将您的 kcl 包推送到发布到 OCI Registry 中。kcl 包管理默认使用 [ghcr.io](https://ghcr.io) 作为 OCI Registry, 您可以通过修改 kcl 包管理配置文件来更改默认的 OCI Registry。关于如何修改 kcl 包管理配置文件的信息,请参阅 [kcl oci registry](https://github.com/kcl-lang/kpm/blob/main/docs/kpm_oci-zh.md#kpm-registry) - -下面是一个简单的步骤,指导您如何使用 kcl 包管理将您的 kcl 包推送到 ghcr.io。 - -## 步骤 1:安装 KCL CLI - -首先,您需要在您的计算机上安装 KCL CLI。您可以按照 [KCL CLI 安装文档](https://kcl-lang.io/zh-CN/docs/user_docs/getting-started/install)中的说明进行操作。 - -## 步骤 2:创建一个 ghcr.io 令牌 - -如果您使用默认的 OCI Registry, 要将 kcl 包推送到 ghcr.io,您需要创建一个用于身份验证的令牌。您可以参考以下文档。 - -- [创建 ghcr.io token](https://docs.github.com/zh/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic) - -## 步骤 3:登录 ghcr.io - -在安装了 kcl 包管理并创建了 ghcr.io 令牌后,您需要使用 kcl 包管理登录 ghcr.io。您可以使用以下命令进行操作: - -```shell -kcl registry login -u -p ghcr.io -``` - -其中 `` 是您的 GitHub 用户名,`` 是您在步骤 2 中创建的令牌。 - -关于如何使用 kcl 包管理登录 ghcr.io 的更多信息,请参阅 [kcl registry login](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/login)。 - -## 步骤 4:推送您的 kcl 包 - -现在,您可以使用 kcl 包管理将您的 kcl 包推送到 ghcr.io。 - -### 1. 一个合法的 kcl 包 - -首先,您需要确保您推送的内容是符合一个 kcl 包的规范,即必须包含合法的 kcl.mod 和 kcl.mod.lock 文件。 - -如果您不知道如何得到一个合法的 `kcl.mod` 和 `kcl.mod.lock`。您可以使用 `kcl mod init` 命令。 - -```shell -# 创建一个名为 my_package 的 kcl 包 -kcl mod init my_package -``` - -`kcl mod init my_package` 命令将会为您创建一个新的 kcl 包 `my_package`, 并为这个包创建 `kcl.mod` 和 `kcl.mod.lock` 文件。 - -如果您已经有了一个包含 kcl 文件的目录 `exist_kcl_package`,您可以使用以下命令将其转换为一个 kcl 包,并为其创建合法的 `kcl.mod` 和 `kcl.mod.lock`。 - -```shell -# 在 exist_kcl_package 目录下 -$ pwd -/home/user/exist_kcl_package - -# 执行 kcl 包管理init 命令来创建 kcl.mod 和 kcl.mod.lock -$ kcl mod init -``` - -关于如何使用 kcl 包管理init 的更多信息,请参阅 [kcl mod init](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/init)。 - -### 2. 推送 kcl 包 - -您可以在 `kcl` 包的根目录下使用以下命令进行操作: - -```shell -# 在 exist_kcl_package 包的根目录下 -$ pwd -/home/user/exist_kcl_package - -# 推送 kcl 包到默认的 OCI Registry -$ kcl mod push -``` - -完成上述步骤后,您就成功地将您的 kcl 包推送到了默认的 OCI Registry 中。 -关于如何使用 kcl mod push 的更多信息,请参阅 [kcl mod push](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/push)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md deleted file mode 100644 index 9bb9f1cc..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md +++ /dev/null @@ -1,65 +0,0 @@ -# 发布 KCL 包到 docker.io - -本文将指导您如何使用 kcl 包管理将您的 kcl 包推送到发布到 docker.io 中。 - -## 步骤 1:安装 KCL CLI - -首先,您需要在您的计算机上安装 KCL CLI。您可以按照 [KCL CLI 安装文档](https://kcl-lang.io/zh-CN/docs/user_docs/getting-started/install)中的说明进行操作。 - -## 步骤 2:创建一个 docker.io 账户 - -您需要创建一个 docker.io 账户以支持您的 kcl 包的推送。 - -## 步骤 3:登录 docker.io - -您可以直接使用 docker.io 的账户名和密码登录。 - -```shell -kcl registry login -u -p docker.io -``` - -其中 `` 是您的 docker.io 用户名,`` 是您 docker.io 账户的密码。 - -关于如何使用 KCL CLI 登录 docker.io 的更多信息,请参阅 [kcl registry login](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/login)。 - -## 步骤 4:推送您的 kcl 包 - -现在,您可以使用 KCL CLI 将您的 kcl 包推送到 docker.io。 - -### 1. 一个合法的 kcl 包 - -首先,您需要确保您推送的内容是符合一个 kcl 包的规范,即必须包含合法的 kcl.mod 和 kcl.mod.lock 文件。 - -如果您不知道如何得到一个合法的 `kcl.mod` 和 `kcl.mod.lock`。您可以使用 `kcl mod init` 命令。 - -例如:创建一个名为 my_package 的 kcl 包 - -```shell -# 创建一个名为 my_package 的 kcl 包 -kcl mod init my_package -``` - -`kcl mod init my_package` 命令将会为您创建一个新的 kcl 包 `my_package`, 并为这个包创建 `kcl.mod` 和 `kcl.mod.lock` 文件。 - -如果您已经有了一个包含 kcl 文件的目录 `exist_kcl_package`,您可以使用以下命令将其转换为一个 kcl 包,并为其创建合法的 `kcl.mod` 和 `kcl.mod.lock`。 - -在 `exist_kcl_package` 目录下执行: - -```shell -kcl mod init -``` - -关于如何使用 kpm init 的更多信息,请参阅 [kcl mod init](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/init)。 - -### 2. 推送 kcl 包 - -您可以在 `kcl` 包的根目录下使用以下命令进行操作: - -在 `exist_kcl_package` 包的根目录下, 执行 - -```shell -kcl mod push oci://docker.io//exist_kcl_package -``` - -完成上述步骤后,您就成功地将您的 kcl 包 `exist_kcl_package` 推送到了 docker.io 中。 -关于如何使用 kcl mod push 的更多信息,请参阅 [kcl mod push](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/push)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/package-management/4-how-to/6-push_github_action.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/package-management/4-how-to/6-push_github_action.md deleted file mode 100644 index 2f18b66f..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/package-management/4-how-to/6-push_github_action.md +++ /dev/null @@ -1,83 +0,0 @@ -# 如何在 github action 中使用 kcl 包管理发布您的 KCL 包 - -本文将指导您如何在 GitHub Action 中使用 kcl 包管理将您的 kcl 包推送到发布到 ghcr.io 中。 - -## 步骤 1:安装 KCL CLI - -首先,您需要在您的计算机上安装 KCL CLI。您可以按照 [KCL CLI 安装文档](https://kcl-lang.io/zh-CN/docs/user_docs/getting-started/install)中的说明进行操作。 - -## 步骤 2:创建一个 GitHub 账号 - -如果您已经有 GitHub 帐号了,您可以选择跳过这一步 - -[注册新的一个 GitHub 账号](https://docs.github.com/zh/get-started/signing-up-for-github/signing-up-for-a-new-github-account) - -## 步骤 3: 为您的 KCL 包创建一个 GitHub 仓库并进行相关配置 - -### 1. 为您的 KCL 程序包准备仓库 - -您需要为您的 KCL 程序包准备一个 GitHub 仓库。 - -[创建一个 GitHub 仓库](https://docs.github.com/zh/get-started/quickstart/create-a-repo) - -在这个仓库中添加您的 KCL 程序,以仓库 https://github.com/awesome-kusion/catalog.git 为例, - -```bash -├── .github -│ └── workflows -│ └── push.yaml # github action 文件 -├── LICENSE -├── README.md -├── kcl.mod # kcl.mod 将当前仓库内容定义为一个 kcl 包 -├── kcl.mod.lock # kcl.mod.lock 是 kcl 包管理工具自动生成的文件 -└── main.k # 您的 KCL 程序 -``` - -### 2. 为您的仓库设置 OCI Registry,账户和密码 - -以 docker.io 为例,您可以为您的仓库设置 secrets `REG`, `REG_ACCOUNT` 和 `REG_TOKEN`。`REG` 的值为 `docker.io`,`REG_ACCOUNT` 的值为您的 docker.io 账户, `REG_TOKEN` 为您的 `docker.io` 登录密码。 - -[为仓库添加 secrets](https://docs.github.com/zh/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) - -如果您使用 `ghcr.io` 作为 `Registry`, 您需要使用 GitHub token 作为 secrets。 - -[创建一个 GitHub Token](https://docs.github.com/zh/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#personal-access-tokens-classic) - -## 步骤 4: 将您的 KCL 包添加到仓库中并编写 github action workflow - -为这个仓库添加 github action 文件 `.github/workflows/push.yml`,内容如下: - -```yaml -name: KPM Push Workflow - -on: - push: - branches: - - main - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Set up Go 1.21 - uses: actions/setup-go@v2 - with: - go-version: 1.21 - - - name: Install KCL CLI - run: go install kcl-lang.io/cli/cmd/kcl@latest - - - name: Login and Push - env: - # 通过环境变量指定 OCI Registry 和账户 - KPM_REG: ${{ secrets.REG }} - KPM_REPO: ${{ secrets.REG_ACCOUNT }} - # kcl registry login 时使用 secrets.REG_TOKEN - run: kcl registry login -u ${{ secrets.REG_ACCOUNT }} -p ${{ secrets.REG_TOKEN }} ${{ secrets.REG }} && kcl mod push - - - name: Run KCL project from oci registry - run: kcl run oci://${{ secrets.REG }}/${{ secrets.REG_ACCOUNT }}/catalog --tag 0.0.1 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/package-management/4-how-to/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/package-management/4-how-to/_category_.json deleted file mode 100644 index 370cb4e9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/package-management/4-how-to/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "如何使用", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/schema-definition.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/schema-definition.md deleted file mode 100644 index 735667b9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/schema-definition.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -title: "模型定义" -sidebar_position: 3 ---- - -## 简介 - -KCL 的核心场景是写配置和校验,因此 KCL 被设计之初的一个核心特性就是**建模**,对应到 KCL 的关键字 `schema`,`schema` 可以被用于定义结构和约束,比如字段的类型,默认值,字段的范围和各种其他约束等内容。此外,使用 KCL schema 定义的结构可以反过来用于验证实现、验证输入(JSON、YAML 等结构化数据)或生成代码(生成多语言结构体、OpenAPI 等)。 - -## 使用 KCL 定义结构和约束 - -### 0. 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. 获得示例 - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/definition -``` - -我们可以执行如下命令显示配置 - -```bash -cat main.k -``` - -输出为 - -```python -import .app_module # A relative path import - -app: app_module.App { - domainType = "Standard" - containerPort = 80 - volumes = [ - { - mountPath = "/tmp" - } - ] - services = [ - { - clusterIP = "None" - $type = "ClusterIP" - } - ] -} -``` - -我们将 `App` 模型放入单独的 `app_module.k` 中,在需要时我们可以在 `main.k` 中使用 `import` 关键字进行模块化管理,比如下面的文件结构 - -``` -. -├── app_module.k -└── main.k -``` - -其中 `app_module.k` 的内容为 - -```python -schema App: - domainType: "Standard" | "Customized" | "Global" - containerPort: int - volumes: [Volume] - services: [Service] - - check: - 1 <= containerPort <= 65535 - -schema Service: - clusterIP: str - $type: str - - check: - clusterIP == "None" if $type == "ClusterIP" - -schema Volume: - container: str = "*" # `container` 的默认值为 "*" - mountPath: str - - check: - mountPath not in ["/", "/boot", "/home", "dev", "/etc", "/root"] -``` - -在上面的文件中。在其中,我们使用 `schema` 关键字定义了三个模型 `App`,`Service` 和 `Volume`。并且 `App` 模型具有四个属性 `domainType`, `containerPort`, `volumes` 和 `services`,其中 - -- `domainType` 的类型为字符串字面值联合类型,与“枚举”类似,这表明 `domainType` 的值只能取 `"Standard"`, `"Customized"` 和 `"Global"` 中的一个 -- `containerPort` 的类型为整数 `int`, 此外我们使用 `check` 关键字定义了其取值范围 1 ~ 65535 -- `services` 的类型为 `Service` 列表类型,`Service`,并且我们用 `?` 标记了它是一个可选属性,这意味着我们可以不为其赋值。 -- `volumes` 的类型为 `Volume` 列表类型,并且我们用 `?` 标记了它是一个可选属性,这意味着我们可以不为其赋值。 - -### 2. 输出配置 - -我们可以使用如下命令行可以获得 `app` 实例的 YAML 输出 - -```shell -kcl main.k -``` - -输出为 - -```yaml -app: - domainType: Standard - containerPort: 80 - volumes: - - container: "*" - mountPath: /tmp - services: - - clusterIP: None - type: ClusterIP -``` - -## 小结 - -KCL 是一种用于定义配置和约束的语言,其核心功能是使用 schema 关键字进行建模,schema 允许定义具有属性、默认值、范围检查和其他约束的结构。使用 KCL schema 定义的结构可以用于验数据或生成代码。该文档演示了如何使用 schema 定义模型,使用 import 导入模型进行模块化管理,并使用 kcl 命令输出已定义结构实例的 YAML 配置。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/secret-management/1-vault.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/secret-management/1-vault.md deleted file mode 100644 index f070a784..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/secret-management/1-vault.md +++ /dev/null @@ -1,142 +0,0 @@ ---- -id: vault -sidebar_label: Vault ---- - -# Vault - -## 简介 - -This guide will show you that KCL solves the secret management problem by integrating [Vault](https://developer.hashicorp.com/vault) and [Vals](https://github.com/helmfile/vals). - -## 先决条件 - -- Install [KCL](/docs/user_docs/getting-started/install) -- Prepare a [Kubernetes Cluster](https://kubernetes.io/) -- Install [Vault](https://developer.hashicorp.com/vault/downloads) -- Install [Vals](https://github.com/helmfile/vals) - -## 具体步骤 - -### 1. 获得示例 - -We put the application source code and infrastructure deployment code in different repos, which can be maintained by different roles to achieve the separation of concerns. - -- Get the application code - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/secret-management/vault -``` - -- Show the config - -```shell -cat main.k -``` - -The output is - -```python -# Secret Management using Vault and Vals - -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" - annotations: { - "secret-store": "vault" - # Valid format: - # "ref+vault://PATH/TO/KV_BACKEND#/KEY" - "foo": "ref+vault://secret/foo#/foo" - "bar": "ref+vault://secret/bar#/bar" - } -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -The main.k file extends the configuration of the Nginx application and customizes annotations. Among them, the value of annotation `foo` and `bar` follow secret reference format (`ref+vault://PATH/TO/KV_BACKEND#/KEY`): - -- `ref+vault`: indicates that this is a secret reference, and the external storage service is `Vault`. -- `PATH/TO/KV_BACKEND`: specifies the path where a secret is stored. -- `KEY`: specifies the key to reading secret. - -The complete format is concatenated using a style similar to URI expressions, which can retrieve a secret stored externally. - -### 2. 预存敏感信息 - -Start the Vault Server - -```shell -vault server -dev -export VAULT_ADDR='http://127.0.0.1:8200' -# Note: Replace with your token -export VAULT_TOKEN=yourtoken -``` - -After Vault is started in development mode and unpacked, secrets are pre-stored, and the path and keys are consistent with `main.k`: - -```shell -vault kv put secret/foo foo=foo -vault kv put secret/bar bar=bar -``` - -### 3. 部署配置 - -Using the following command to apply the deployment manifest. - -```shell -kcl main.k | vals eval -f - | kubectl apply -f - -``` - -The expect output is - -```shell -deployment.apps/nginx created -``` - -### 4. 验证敏感信息 - -Next, verify that the secrets have been retrieved from Vault and replace the values of annotations of Nginx: - -- Verify the `foo` annotation - -```shell -kubectl get deploy nginx -o yaml | grep 'foo:' -``` - -The output is - -```yaml -foo: foo -``` - -- Verify the `bar` annotation - -```shell -kubectl get deploy nginx -o yaml | grep 'bar:' -``` - -The output is - -```yaml -bar: bar -``` - -So far, we have retrieved the secrets hosted in `Vault` and put them into use. - -## 小结 - -This guide introduces how KCL solves the secret management by integrating Vault and Vals. By following these steps, we can retrieve the secrets hosted in Vault and utilize them. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md deleted file mode 100644 index 1981ae3d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: "KPT KCL SDK" -sidebar_position: 4 ---- - -## 简介 - -[kpt](https://github.com/GoogleContainerTools/kpt) 是一个以包为中心的工具链,可实现配置原地编辑、自动化和交付,通过将声明性配置作为数据进行操作,从而简化 Kubernetes 平台和 KRM 驱动的基础设施(例如,Config Connector、Crossplane)的大规模管理,以实现 Kubernetes 配置编辑的自动化包括转换和验证。 - -KCL 可用于创建函数来转换和/或验证 YAML Kubernetes 资源模型 (KRM) 输入/输出格式,但我们提供 KPT KCL SDK 来简化函数编写过程。 - -## 先决条件 - -- 安装 [kpt](https://github.com/GoogleContainerTools/kpt) -- 安装 [Docker](https://www.docker.com/) - -## 快速开始 - -让我们编写一个仅向 Deployment 资源添加 annotation `managed-by=kpt` 的 KCL 函数 - -### 1. 获取示例 - -```bash -git clone https://github.com/kcl-lang/kpt-kcl-sdk.git/ -cd ./kpt-kcl-sdk/get-started/set-annotation -``` - -### 2. 显示 KRM - -```bash -kpt pkg tree -``` - -输出为 - -```bash -set-annotation -├── [kcl-fn-config.yaml] KCLRun set-annotation -└── data - ├── [resources.yaml] Deployment nginx-deployment - └── [resources.yaml] Service test -``` - -### 3. 显示和更新 KCL `FunctionConfig` - -```bash -cat ./kcl-fn-config.yaml -``` - -输出为 - -```yaml -# kcl-fn-config.yaml -apiVersion: krm.kcl.dev/v1alpha1 -kind: KCLRun -metadata: # kpt-merge: /set-annotation - name: set-annotation -spec: - # 编辑此源代码 - # 您在此的 KCL 代码将 `ResourceList` 预加载到 `option("resource_list")` - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "kpt"}} for resource in option("resource_list").items] -``` - -### 4. 测试和运行 - -通过 kpt 运行 KCL 代码 - -```bash -kpt fn eval ./data -i docker.io/kcllang/kpt-kcl:v0.2.0 --fn-config kcl-fn-config.yaml - -# 验证 annotation 是否添加到 `Deployment` 资源并且其他资源 `Service` 没有这个 annotation。 -cat ./data/resources.yaml | grep annotations -A1 -B0 -``` - -输出为 - -```bash - annotations: - managed-by: kpt -``` - -可以看出,我们确实成功添加了 `managed-by=kpt` 标签 - -## 更多文档和示例 - -- [KPT KCL SDK](https://github.com/kcl-lang/kpt-kcl-sdk) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json deleted file mode 100644 index 6e90c03c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Mutate or Validate Kubernetes Manifests", - "position": 3 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/_category_.json deleted file mode 100644 index 42681f2b..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Kubernetes", - "position": 9 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/index.md deleted file mode 100644 index 8d6340de..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/index.md +++ /dev/null @@ -1 +0,0 @@ -# Kubernetes diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-konfig/4-best-practice.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-konfig/4-best-practice.md deleted file mode 100644 index c4bf4b08..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-konfig/4-best-practice.md +++ /dev/null @@ -1,271 +0,0 @@ ---- -id: practice -sidebar_label: 最佳实践 ---- - -# 最佳实践 - -本文档旨在讲解新的业务模型接入 Konfig 大库以及 KCL 代码模型设计与编写的最佳实践,新业务模型一般采用前-后端模型分离的最佳实践进行设计与抽象,区分前端模型和后端模型的直接目的是将「用户界面」和「模型实现」进行分离,实现用户友好的简单的配置界面以及自动化配置增删改查接口。 - -## 工作流程 - -![](/img/docs/user_docs/guides/konfig/workflow.png) - -1. 首先使用 KCL OpenAPI 工具生成下游所需配置的 KCL 模型代码,对于 Kubernetes 模型;可以根据 CRD 或者 Swagger Model 生成,对于其他场景,可以使用 Terraform provider schema、Java Class 或者 Go Struct 生成相应 KCL Schema (建设中),作为后端模型并存放在 "基础配置代码" 中; -2. 使用 KCL 开发工具(包括 KCL 编译器、KCL format,doc,lint,test 等工具和 IDE 插件等),根据业务语义抽象前端模型; -3. 依据 Project & Stack 方式在 Konfig 仓库中组织用户侧配置代码(主要是对前端模型的实例化),Konfig 会自动根据 project.yaml 和 stack.yaml 文件进行测试; -4. 最后编译 KCL 代码生成 YAML,通过测试后,利用 CI/CD 流程完成配置的 diff 与分发。 - -## 模型结构 - -正如 web 应用会提供友好的用户界面,而在应用的后端对用户输入进行进一步推演得到最终落库的数据,类似地,使用 KCL 进行模型设计时同样遵循前后端分离的逻辑。此外当下游所需的数据内容发生变化时,我们仅需修改用户配置数据到后端模型的渲染/逻辑即可,从而避免了大规模修改用户配置的情况。以应用服务的 sidecar 配置为例,直接暴露给用户的只有 `user_sidecar_feature_gates`,而最终交给下游处理的数据中,则应是把 `user_sidecar_feature_gates` 作为 `sidecars` 配置的一部分包装起来的结果。比如如下代码: - -```python -# 用户可配的: -user_sidecar_feature_gates: str - -# 下游能处理的: -sidecars = [ - { - name = "sidecar_name" # sidecars 参数的额外模版参数,用户不需要进行配置 - feature_gates = user_sidecar_feature_gates - } -] -``` - -## Konfig 建模的一些最佳实践 - -### 使用一个属性代替配置模板 - -对于一些后端模型所需要填写的配置字段往往是大而全的设计,需要用户主动输入较为复杂的配置模版,并且不同用户对于该字段的填写内容基本一致,比如在下面示出的超卖逻辑的配置就需要用户填写大量的模板数据,心智成本较高。 - -对于此类常用复杂的模板一个简单的最佳实践是在前端模型中抽象为一个简单的 bool 类型的变量 overQuota,让用户做选择题而不是填空题,比如当 overQuota 变量为 True 时,后端模型才会渲染这个复杂逻辑。 - -- 前端模型属性 `overQuota` - -```python -overQuota: bool -``` - -- 后端模型 YAML 输出 - -```yaml -spec: - template: - spec: - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: k8s/is-over-quota - operator: In - values: - - "true" -``` - -此外也可以根据具体的业务场景设计不同的模版名称来填空,比如如下所示的代码设计一个属性 template 来辅助用户做模版的选择而不是直接填入模板内容。合法的 template 值可以为 "success_ratio" 或者 "service_cost", 当后端模型扩展更多的模版时,前端代码无需作出任何修改,仅需在后端模型中适配相应模板逻辑即可。 - -```python -schema SLI: - template: str = "success_ratio" -``` - -此外,尽量不采用复杂的结构直接作为前端模型属性,避免用户使用该模型时需要借助过多的 KCL 语法特性(比如解包、循环等特性)或者书写很多临时变量完成该结构的实例化。 - -### 使用字面值类型和联合类型 - -在上述小节提到了可以使用一个字符串属性表示不同的模板名称,更进一步地是可以使用字面值类型表述 template 可选的内容,比如可以进行如下改进。 - -```python -schema SLI: - template: "success_ratio" | "service_cost" = "success_ratio" -``` - -其中 template 的类型为两个字符串类型的联合,表示 template 只能为 "success_ratio" 或者 "service_cost",当用户填写了其他字符串的值时,KCL 编译器会进行报错。 - -除了对字面值类型使用联合类型外,KCL 还支持对复杂类型如 schema 类型的联合。对于这种后端 oneof 配置的支持,KCL 内置了复合结构的联合类型进行支持。比如我们可以针对多种种场景定义自己的 SLI 前端类型:CustomSliDataSource,PQLSLIDataSource 和 StackSLIDataSource。 - -```python -schema CustomSLIDataSource: - customPluginUrl: str - -schema PQLSLIDataSource: - total?: str - error?: str - success?: str - cost?: str - count?: str - -schema StackSLIDataSource: - stack: str - groupBy?: str - metric?: str - -# Simplify type definitions using type aliases -type DataSource = CustomSLIDataSource | PQLSLIDataSource | StackSLIDataSource - -schema DataConfiguration: - sources: {str: DataSource} -``` - -这样前端模型设计的好处是编译器可以静态地检查出用户书写的类型只能是某一种类型,如果直接使用后端模型无法从模型上直接获得不同类型 type 与需要填写字段的映射关系。 - -此外,前端模型的整体设计上也应该考虑横向扩展性,尽可能地采用联合类型,充分利用代码化的优势,避免对接不同后端或者后端模型发生改变时带来不必要的大量代码前端代码与用户代码重构与修改。此外,对于其他 GPL 语言中常用的工厂模式,在 KCL 中也可以使用联合类型代替,比如想要根据某个字符串内容获得某个类型的构造函数,可以直接使用联合类型进行优化。 - -KCL 中书写工厂模式 - -```python -schema DataA: - id?: int = 1 - value?: str = "value" - -schema DataB: - name?: str = "DataB" - -_dataFactory: {str:} = { - DataA = DataA - DataB = DataB -} -dataA = _dataFactory["DataA"]() -dataB = _dataFactory["DataB"]() -``` - -使用联合类型替换工厂模式 - -```python -schema DataA: - id?: int = 1 - value?: str = "value" - -schema DataB: - name?: str = "DataB" - -# 直接使用联合类型即可 -dataA: DataA | DataB = DataA() -dataB: DataA | DataB = DataB() -``` - -### 列表/数组属性字典化 - -为了便于作配置的原地修改或者程序自动化查询修改,尽量将列表/数组属性定义为字典类型方便索引,因为在大部分配置场景对于复杂结构的列表类型,列表的索引 0, 1, 2, ..., n 不具备任何业务含义,列表中元素的顺序对该列表配置无任何影响,此时采用字典类型而不是列表类型更方便数据的查询与修改。首先以一个简单例子举例: - -```python -schema Person: - name: str - age: int - -schema House: - persons: [Person] - -house = House { - persons = [ - Person { - name = "Alice" - age = 18 - } - Person { - name = "Bob" - age = 10 - } - ] -} -``` - -比如在上述例子中,想要查询 name 为 "Alice" 的年龄 age, 就需要在 house.persons 这个列表中作遍历才能很查询到 Alice 的 age。而将 persons 定义为如下代码所示的字典,不仅从代码上看起来更加简洁,并且可以通过 house.persons.Alice.age 直接获得 Alice 的 age,并且整个配置的信息完整且无冗余信息。 - -```python -schema Person: - age: int - -schema House: - persons: {str: Person} # 将 persons 定义为字典而不是数组 - -house = House { - persons = { - Alice = Person { age = 18 } - Bob = Person { age = 10 } - } -} -``` - -### 为模型书写校验表达式 - -对于前端模型,往往需要对用户填写的字段进行校验,此时可以使用 KCL 的 check 表达式与 KCL 的内置函数/语法/系统库进行配合对字段进行校验。对于前端模型的校验尽可能直接书写在前端模型的定义中进行校验前置,避免错误传递到后端模型中发生意想不到的错误。 - -使用 all/any 表达式与 check 表达式进行校验 - -```python -import regex - -schema ConfigMap: - name: str - data: {str:str} - configMounts?: [ConfigMount] - - check: - all k in data { - regex.match(k, r"[A-Za-z0-9_.-]*") - }, "a valid config key must consist of alphanumeric characters, '-', '_' or '.'" - -schema ConfigMount: - containerName: str - mountPath: str - subPath?: str - - check: - ":" not in mountPath, "mount path must not contain ':'" -``` - -### 使用数值单位类型 - -KCL 中带单位的数字具有一个内置的类型 units.NumberMultiplier, 不允许进行任意四则运算。 - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -x0: NumberMultiplier = 1M # Ok -x1: NumberMultiplier = x0 # Ok -x2 = x0 + x1 # Error: unsupported operand type(s) for +: 'number_multiplier(1M)' and 'number_multiplier(1M)' -``` - -可以使用 `int()/float()` 函数和 `str()` 函数将数字单位类型转换为整数类型或者字符串类型,产生的字符串保留原有数字单位类型的单位。 - -```python -a: int = int(1Ki) # 1024 -b: str = str(1Mi) # "1Mi" -``` - -对于在 Konfig 中的 Kubernetes Resource 资源相关的定义均可使用数值单位类型进行书写 - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -schema Resource: - cpu?: NumberMultiplier | int = 1 - memory?: NumberMultiplier = 1024Mi - disk?: NumberMultiplier = 10Gi - epchygontee?: int -``` - -### 前端模型实例的自动化修改 - -在 KCL,可以通过命令行和 API 界面实现对前端模型实例的自动化修改,比如想要修改某个应用(Konfig Stack Path: appops/nginx-example/dev)配置的镜像内容,可以直接执行如下指令修改镜像 - -```python -kcl -Y kcl.yaml ci-test/settings.yaml -o ci-test/stdout.golden.yaml -d -O :appConfiguration.image=\"test-image-v1\" -``` - -更多与自动化相关的使用文档请参考 [自动化](/docs/user_docs/guides/automation) 一节 - -### 为模型添加代码注释 - -为便于用户理解以及模型文档自动生成,需要对定义的模型编写注释,注释内容一般包括模型的解释,模型字段的解释,类型,默认值,使用样例等。详细的 KCL Schema 代码注释编写规范以及模型文档自动生成可以参考 [KCL 文档规范](/docs/tools/cli/kcl/docgen) - -## 后端模型 - -后端模型是「模型实现」,主要包括将前端模型映射为后端模型的逻辑代码。当编写完成前端模型后,我们可以使用前端模型 Schema 新建前端模型的实例 instance 并编写相应的后端映射/渲染代码将这些前端 instance 转换为后端模型,并且利用 KCL 多文件编译和 `Schema.instances()` 函数可以做到前端代码和后端代码的高度解耦,用户仅需关心前端的配置而不感知模型复杂的校验、逻辑判断等代码。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-konfig/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-konfig/_category_.json deleted file mode 100644 index a71426f9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-konfig/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Konfig", - "position": 10 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-kusion/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-kusion/index.md deleted file mode 100644 index 2906ab83..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-kusion/index.md +++ /dev/null @@ -1,15 +0,0 @@ -# KusionStack - -**KusionStack 是开源的云原生可编程技术栈!** - -KusionStack 是一个可编程、高灵活性的应用交付及运维技术栈,灵感源于融合(Fusion)一词,旨在帮助企业构建的应用运维配置管理平面及 DevOps 生态。 - -1. 融合**专有云**,**混合云**,**多云**混合场景 -2. 融合以**云原生技术**为主,同时采用**多种平台技术**的混合平台技术选型 -3. 融合**多项目**、**多团队**、**多角色**、**多租户**、**多环境**的企业级诉求 - -基于 Platform as Code (平台服务即代码)理念,研发者可以快速收敛围绕**应用运维生命周期**的全量配置定义,面向**混合技术体系及云环境**,完成从应用运维研发到上线的**端到端工作流程**,真正做到**一处编写,随处交付**。 - -![](/img/docs/user_docs/intro/kusion-stack-1.png) - -更多文档请参考: [https://kusionstack.io/](https://kusionstack.io/) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/support/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/support/_category_.json deleted file mode 100644 index d670513b..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/support/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "常见问答", - "position": 6 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/support/faq-cli.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/support/faq-cli.md deleted file mode 100644 index 035c021c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/support/faq-cli.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -sidebar_position: 4 ---- - -# 命令行工具 - -## 1. Konfig 大库应用目录下的 settings.yaml 文件的作用是什么? - -KCL 中 settings.yaml 文件表示 KCL 命令行工具的配置参数文件,可以将编译的配置放入其中进行调用比如需要编译的文件,需要输入的 option 动态参数 `-d`,是否需要忽略掉空值 None `-n` 等配置。 - -比如对于如下的命令行运行参数 - -```shell -kcl main.k -D key=value -n -r -``` - -就可以使用如下的命令行参数和 settings.yaml 配置文件代替 - -```shell -kcl -Y settings.yaml -``` - -settings.yaml - -```yaml -kcl_cli_configs: - files: - - main.k - disable_none: true - strict_range_check: true -kcl_options: - - key: key - value: value -``` - -- `kcl_cli_configs` 表示可以配置的编译参数,`file` 用于配置编译的 KCL 文件,`disable_none` 表示是否使用 `-n` 参数,`strict_range_check` 表示是否使用 `-r` 参数。 -- `kcl_options` 表示可以配置的动态参数,`key` 表示动态参数的名称,`value` 表示动态参数的值 - -注意:settings.yaml 的文件名称可替换,只要其中的配置结构满足规定即可 - -## 2. 如何传入动态参数?如何在代码中获取命令行传入的动态参数? - -KCL 支持多种方式传入动态参数 - -- `-D`: 使用 KCL 命令行的-D 参数可以直接传入动态参数,支持基本数据类型 str/int/float/bool, 以及结构数据类型 list/dict - -```shell -kcl main.k -D env-type=TEST -D deploy-topology='[{"cluster":"my-cluster","idc":"my-idc","replicas":2,"workspace":"my-idc","zone":"my-zone"}]' -``` - -- `-Y`: 使用 KCL 命令行的-Y 参数可以间接通过配置文件传入动态参数: - -```yaml -kcl_options: - - key: env-type - value: TEST - - key: deploy-topology - value: - - cluster: my-cluster - idc: my-idc - replicas: 2 - workspace: my-workspace - zone: my-zone -``` - -在代码中使用内置的 option 函数获取即可 - -```python -env = option("env-type") -deploy_topology = option("deploy-topology") -``` - -输出 YAML - -```yaml -env: TEST -deploy_topology: - - cluster: my-cluster - idc: my-idc - replicas: 2 - workspace: my-workspace - zone: my-zone -``` - -## 3. 如何使用 kcl 的多文件编译特性? - -- 使用 KCL 命令行工具直接书写多文件编译 - -```shell -kcl file1.k file2.k file3.k -``` - -- 在配置文件中配置并配合 KCL 命令行工具参数 `-Y` 使用 - -settings.yaml - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - - file3.k -``` - -```shell -kcl -Y settings.yaml -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/support/faq-yaml.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/support/faq-yaml.md deleted file mode 100644 index 4dd12c00..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/support/faq-yaml.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -sidebar_position: 3 ---- - -# YAML 语法 - -## 1. YAML 字符串使用单引号和双引号的区别是什么? - -- YAML 双引号字符串是唯一能够表达任意字符串的样式,通过使用 `\` 转义字符,比如使用 `\"` 转义双引号 `"`,使用 `\\` 转义反斜杠 `\`,并且可以使用单个反斜杠 `\` 作为双引号字符串的续行符 -- YAML 单引号字符串与 YAML 双引号字符串不同的是可以自由地使用 `\` 和 `"` 而不需要转义,但是使用两个单引号 `''` 转义单引号 `'` 字符 - -比如对于如下的例子,三个字符串变量的内容是相同的 - -```yaml -string1: 'here '' s to "quotes"' -string2: 'here''s to "quotes"' -string3: here's to "quotes" -``` - -因此,KCL 输出 YAML 字符串的策略是当字符串内容出现单引号时,优先输出无引号字符串或双引号字符串,其他情况输出单引号字符串以避免理解上的负担。 - -更多细节可参考: [YAML 规范 v1.2](https://yaml.org/spec/1.2.1/) - -## 2. YAML 中出现的 | - + > 等符号是什么含义? - -在使用 KCL 多行字符串(使用三引号括起来的字符串),输出的 YAML 经常会携带一些特殊的记号,如 `|`,`-`,`+` 和 `>` 等,这些记号通常为 YAML 多行字符串的表示方法,比如对于如下 KCL 代码: - -```python -data = """This is a KCL multi line string (the first line) -This is a KCL multi line string (the second line) -This is a KCL multi line string (the third line) - - -""" -var = 1 -``` - -输出 YAML 为: - -```yaml -data: |+ - This is a KCL multi line string (the first line) - This is a KCL multi line string (the second line) - This is a KCL multi line string (the third line) - - -var: 1 -``` - -- `|` 表示**块字符串样式**,用于表示一个多行字符串,其中的所有换行符都表示字符串真实的换行; -- `>` 表示**块折叠样式**,在其中所有的换行符将被空格替换; -- `+` 和 `-` 用于控制在字符串末尾使用换行符的情况。默认情况为字符串末尾保留单个换行符,如果要删除所有换行符,可以在样式指示符 `|` 或 `>` 后面放置一个 `-` 来完成,如果要保留末尾的换行符,则需要在 `|` 或 `>` 后面放置一个 `+` - -更多细节可参考: [YAML 多行字符串](https://yaml-multiline.info/) 和 [YAML 规范 v1.2](https://yaml.org/spec/1.2.1/) - -## 3. YAML 中在 | - + > 等符号之后出现的数字是什么含义? - -数字表示 YAML 当中的**显式缩进指示符**。对于 YAML 中的长字符串,YAML 通常第一个非空行确定字符串的缩进级别,而当第一个非空行前面具有非前导字符时,比如换行符,YAML 要求必须使用**显式缩进指示符**来指定内容的缩进级别,比如 `|2` 和 `|1` 等 - -比如对于如下 KCL 代码: - -```python -longStringStartWithNewline = """ -This is the second line -This is the third line -""" - -``` - -```yaml -longStringStartWithNewline: |2 - - This is the second line - This is the third line -``` - -如果不需要长字符串开头的空行或换行符,则可以以如下两种方式进行 KCL 长字符串书写 - -- 长字符串从第 1 行开始书写 - -```python -longString = """This is the second line -This is the third line -""" -``` - -- 使用续行符 - -```python -longString = """\ -This is the second line -This is the third line -""" -``` - -以上两种方式输出的 YAML 均为: - -```yaml -longString: | - This is the second line - This is the third line -``` - -更多细节可参考: [YAML 规范 v1.2](https://yaml.org/spec/1.2.1/) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/contribute/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/contribute/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/contribute/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/contribute/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/contribute/contribute-code.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/contribute/contribute-code.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/contribute/contribute-code.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/contribute/contribute-code.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/contribute/contribute-docs.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/contribute/contribute-docs.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/contribute/contribute-docs.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/contribute/contribute-docs.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/contribute/contribute.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/contribute/contribute.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/contribute/contribute.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/contribute/contribute.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/contribute/git-guideline.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/contribute/git-guideline.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/contribute/git-guideline.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/contribute/git-guideline.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/intro/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/intro/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/intro/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/intro/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/intro/intro.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/intro/intro.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/intro/intro.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/intro/intro.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/intro/license.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/intro/license.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/intro/license.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/intro/license.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/intro/support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/intro/support.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/intro/support.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/intro/support.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/release-policy/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/release-policy/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/release-policy/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/release-policy/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/release-policy/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/release-policy/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/release-policy/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/release-policy/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/release-policy/kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/release-policy/kcl.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/community/release-policy/kcl.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/release-policy/kcl.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/release-policy/roadmap.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/release-policy/roadmap.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/community/release-policy/roadmap.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/community/release-policy/roadmap.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/cheatsheets/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/cheatsheets/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/cheatsheets/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/cheatsheets/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/cheatsheets/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/cheatsheets/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/cheatsheets/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/cheatsheets/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/codelab/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/codelab/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/codelab/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/codelab/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/codelab/collaborative.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/codelab/collaborative.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/codelab/collaborative.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/codelab/collaborative.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/codelab/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/codelab/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/codelab/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/codelab/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/codelab/schema.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/codelab/schema.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/codelab/schema.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/codelab/schema.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/codelab/simple.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/codelab/simple.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/codelab/simple.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/codelab/simple.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/error/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/error/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/error/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/error/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/error/_error.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/error/_error.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/error/_error.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/error/_error.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/error/exception.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/error/exception.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/error/exception.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/error/exception.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/error/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/error/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/error/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/error/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/spec/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/spec/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/spec/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/spec/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/spec/codestyle.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/spec/codestyle.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/spec/codestyle.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/spec/codestyle.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/spec/datatypes.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/spec/datatypes.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/spec/datatypes.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/spec/datatypes.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/error.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/spec/error.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/error.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/spec/error.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/spec/expressions.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/spec/expressions.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/spec/expressions.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/spec/expressions.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/spec/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/spec/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/spec/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/spec/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/kcl-spec.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/spec/kcl-spec.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/kcl-spec.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/spec/kcl-spec.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/spec/lexical.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/spec/lexical.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/spec/lexical.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/spec/lexical.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/modules.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/spec/modules.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/modules.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/spec/modules.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/schema.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/spec/schema.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/schema.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/spec/schema.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/statements.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/spec/statements.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/spec/statements.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/spec/statements.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/spec/variables.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/spec/variables.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/spec/variables.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/spec/variables.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/tour.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/tour.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/lang/tour.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/tour.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/types/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/types/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/types/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/types/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/types/types.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/types/types.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/types/types.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/lang/types/types.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/model/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/model/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/base64.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/model/base64.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/base64.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/model/base64.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/builtin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/model/builtin.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/builtin.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/model/builtin.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/crypto.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/model/crypto.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/crypto.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/model/crypto.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/datetime.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/model/datetime.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/datetime.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/model/datetime.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/json.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/model/json.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/json.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/model/json.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/manifests.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/model/manifests.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/manifests.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/model/manifests.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/math.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/model/math.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/math.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/model/math.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/net.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/model/net.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/net.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/model/net.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/model/overview.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/overview.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/model/overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/regex.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/model/regex.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/regex.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/model/regex.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/units.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/model/units.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/model/units.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/model/units.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/yaml.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/model/yaml.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/model/yaml.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/model/yaml.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/plugin/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/plugin/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/plugin/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/plugin/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/plugin/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/plugin/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/plugin/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/plugin/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/plugin/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/plugin/overview.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/plugin/overview.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/plugin/overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/plugin/project_context.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/plugin/project_context.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/plugin/project_context.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/plugin/project_context.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/xlang-api/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/xlang-api/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/xlang-api/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/xlang-api/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/xlang-api/go-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/xlang-api/go-api.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/xlang-api/go-api.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/xlang-api/go-api.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/xlang-api/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/xlang-api/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/xlang-api/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/xlang-api/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/xlang-api/java-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/xlang-api/java-api.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/xlang-api/java-api.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/xlang-api/java-api.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/xlang-api/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/xlang-api/overview.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/xlang-api/overview.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/xlang-api/overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/xlang-api/python-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/xlang-api/python-api.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/xlang-api/python-api.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/xlang-api/python-api.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/xlang-api/rest-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/xlang-api/rest-api.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/reference/xlang-api/rest-api.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/reference/xlang-api/rest-api.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/Ide/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/Ide/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/Ide/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/Ide/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/Ide/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/Ide/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/Ide/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/Ide/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/Ide/intellij.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/Ide/intellij.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/Ide/intellij.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/Ide/intellij.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/Ide/neovim.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/Ide/neovim.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/tools/Ide/neovim.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/Ide/neovim.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/Ide/vs-code.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/Ide/vs-code.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/Ide/vs-code.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/Ide/vs-code.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/kcl/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/kcl/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/kcl/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/kcl/docgen.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/kcl/docgen.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/kcl/docgen.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/kcl/docgen.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/kcl/fmt.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/kcl/fmt.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/kcl/fmt.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/kcl/fmt.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/kcl/import.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/kcl/import.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/kcl/import.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/kcl/import.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/kcl/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/kcl/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/kcl/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/kcl/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/kcl/lint.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/kcl/lint.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/kcl/lint.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/kcl/lint.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/kcl/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/kcl/overview.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/kcl/overview.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/kcl/overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/kcl/run.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/kcl/run.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/kcl/run.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/kcl/run.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/kcl/test.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/kcl/test.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/kcl/test.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/kcl/test.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/kcl/vet.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/kcl/vet.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/kcl/vet.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/kcl/vet.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/openapi/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/openapi/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/openapi/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/openapi/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/openapi/crd-to-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/openapi/crd-to-kcl.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/openapi/crd-to-kcl.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/openapi/crd-to-kcl.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/openapi/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/openapi/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/openapi/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/openapi/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/openapi/openapi-to-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/openapi/openapi-to-kcl.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/openapi/openapi-to-kcl.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/openapi/openapi-to-kcl.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/openapi/spec.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/openapi/spec.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/tools/cli/openapi/spec.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/openapi/spec.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/package-management/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/package-management/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/package-management/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/package-management/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/package-management/command-reference/1.init.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/package-management/command-reference/1.init.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/package-management/command-reference/1.init.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/package-management/command-reference/1.init.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/package-management/command-reference/10.help.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/package-management/command-reference/10.help.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/package-management/command-reference/10.help.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/package-management/command-reference/10.help.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/package-management/command-reference/2.add.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/package-management/command-reference/2.add.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/package-management/command-reference/2.add.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/package-management/command-reference/2.add.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/package-management/command-reference/3.pkg.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/package-management/command-reference/3.pkg.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/package-management/command-reference/3.pkg.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/package-management/command-reference/3.pkg.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/package-management/command-reference/4.metadata.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/package-management/command-reference/4.metadata.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/package-management/command-reference/4.metadata.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/package-management/command-reference/4.metadata.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/package-management/command-reference/6.login.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/package-management/command-reference/6.login.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/package-management/command-reference/6.login.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/package-management/command-reference/6.login.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/package-management/command-reference/7.logout.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/package-management/command-reference/7.logout.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/package-management/command-reference/7.logout.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/package-management/command-reference/7.logout.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/package-management/command-reference/8.push.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/package-management/command-reference/8.push.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/package-management/command-reference/8.push.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/package-management/command-reference/8.push.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/package-management/command-reference/9.pull.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/package-management/command-reference/9.pull.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/cli/package-management/command-reference/9.pull.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/package-management/command-reference/9.pull.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/package-management/command-reference/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/package-management/command-reference/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/tools/cli/package-management/command-reference/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/concepts/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/concepts/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/concepts/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/concepts/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/concepts/concepts.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/concepts/concepts.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/concepts/concepts.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/concepts/concepts.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/concepts/package-and-module.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/concepts/package-and-module.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/concepts/package-and-module.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/concepts/package-and-module.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/concepts/type-and-definition.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/concepts/type-and-definition.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/concepts/type-and-definition.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/concepts/type-and-definition.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/getting-started/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/getting-started/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/getting-started/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/getting-started/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/getting-started/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/getting-started/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/getting-started/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/getting-started/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/getting-started/install.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/getting-started/install.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/getting-started/install.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/getting-started/install.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/getting-started/intro.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/getting-started/intro.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/getting-started/intro.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/getting-started/intro.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/getting-started/kcl-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/getting-started/kcl-quick-start.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/getting-started/kcl-quick-start.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/getting-started/kcl-quick-start.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/abstraction.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/abstraction.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/abstraction.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/abstraction.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/automation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/automation.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/automation.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/automation.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/ci-integration/1-github-actions.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/ci-integration/1-github-actions.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/ci-integration/1-github-actions.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/ci-integration/1-github-actions.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/ci-integration/_2-gitlab-ci.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/ci-integration/_2-gitlab-ci.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/ci-integration/_2-gitlab-ci.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/ci-integration/_2-gitlab-ci.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/ci-integration/_3-jenkins-ci.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/ci-integration/_3-jenkins-ci.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/ci-integration/_3-jenkins-ci.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/ci-integration/_3-jenkins-ci.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/ci-integration/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/ci-integration/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/ci-integration/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/ci-integration/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/configuration.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/configuration.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/configuration.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/configuration.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/data-integration.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/data-integration.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/data-integration.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/data-integration.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/gitops/1-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/gitops/1-quick-start.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/gitops/1-quick-start.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/gitops/1-quick-start.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/gitops/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/gitops/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/gitops/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/gitops/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/package-management/3-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/package-management/3-quick-start.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/package-management/3-quick-start.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/package-management/3-quick-start.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/package-management/4-how-to/6-push_github_action.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/package-management/4-how-to/6-push_github_action.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/package-management/4-how-to/6-push_github_action.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/package-management/4-how-to/6-push_github_action.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/package-management/4-how-to/7-publish_pkg_to_ah.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/package-management/4-how-to/7-publish_pkg_to_ah.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/package-management/4-how-to/7-publish_pkg_to_ah.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/package-management/4-how-to/7-publish_pkg_to_ah.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/package-management/4-how-to/8-kcl_mod.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/package-management/4-how-to/8-kcl_mod.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/package-management/4-how-to/8-kcl_mod.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/package-management/4-how-to/8-kcl_mod.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/package-management/4-how-to/9-kpm_oci.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/package-management/4-how-to/9-kpm_oci.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/package-management/4-how-to/9-kpm_oci.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/package-management/4-how-to/9-kpm_oci.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/package-management/4-how-to/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/package-management/4-how-to/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/package-management/4-how-to/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/package-management/4-how-to/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/package-management/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/package-management/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/package-management/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/package-management/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/schema-definition.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/schema-definition.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/schema-definition.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/schema-definition.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/secret-management/1-vault.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/secret-management/1-vault.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/secret-management/1-vault.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/secret-management/1-vault.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/secret-management/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/secret-management/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/secret-management/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/secret-management/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/validation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/validation.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/validation.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/validation.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/0-overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-k8s/0-overview.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/0-overview.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-k8s/0-overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/4-publish-modules.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-k8s/4-publish-modules.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/4-publish-modules.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-k8s/4-publish-modules.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/_4-publish-modules.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-k8s/_4-publish-modules.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-k8s/_4-publish-modules.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-k8s/_4-publish-modules.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-k8s/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-k8s/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-k8s/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-k8s/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-k8s/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-konfig/1-overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-konfig/1-overview.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-konfig/1-overview.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-konfig/1-overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-konfig/2-structure.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-konfig/2-structure.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-konfig/2-structure.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-konfig/2-structure.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-konfig/3-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-konfig/3-quick-start.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-konfig/3-quick-start.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-konfig/3-quick-start.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-konfig/4-best-practice.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-konfig/4-best-practice.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-konfig/4-best-practice.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-konfig/4-best-practice.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-konfig/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-konfig/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-konfig/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-konfig/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-kubevela/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-kubevela/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-kubevela/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-kubevela/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-kubevela/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-kubevela/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-kubevela/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-kubevela/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-kusion/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-kusion/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-kusion/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-kusion/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-kusion/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-kusion/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/guides/working-with-kusion/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/guides/working-with-kusion/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/support/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/support/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/support/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/support/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/support/faq-cli.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/support/faq-cli.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/support/faq-cli.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/support/faq-cli.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/support/faq-install.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/support/faq-install.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/support/faq-install.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/support/faq-install.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/support/faq-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/support/faq-kcl.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/support/faq-kcl.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/support/faq-kcl.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/support/faq-yaml.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/support/faq-yaml.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/user_docs/support/faq-yaml.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/support/faq-yaml.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/support/support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/support/support.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/support/support.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7/user_docs/support/support.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/_category_.json deleted file mode 100644 index f763b5c8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "社区", - "position": 5 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/contribute/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/contribute/_category_.json deleted file mode 100644 index 131bb8e3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/contribute/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "贡献指南", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/contribute/contribute-code.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/contribute/contribute-code.md deleted file mode 100644 index 8e8392fe..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/contribute/contribute-code.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -sidebar_position: 2 ---- - -# 如何贡献代码? - -欢迎参与 KCL 共建贡献完善代码、完善代码文档和测试,同时也欢迎通过 Issue 提供反馈。本文主要针对修改和完善已有的代码,如果是希望增加 KCL 语言特性请通过 KEP 流程提交。 - -## 1. 代码和注释中的错别字 - -如果只是修改代码和注释中的错别字,不涉及代码逻辑的调整,那么可以直接在 Github 克隆仓库后直接修改并提交 PR。需要注意的是尽量保持代码风格一致。 - -## 2. 如何贡献 KCL 代码 - -- 先确保本地测试环境正常 -- 修改代码并补充测试 -- 本地测试通过后提交 PR - -## 3. 如何贡献 VS Code 插件代码 - -请参考 VS Code 插件仓库的相关文档 - -## 4. 开发流程相关代码 - -欢迎通过 Issue 和讨论组讨论。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/contribute/contribute-docs.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/contribute/contribute-docs.md deleted file mode 100644 index 7b846680..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/contribute/contribute-docs.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 如何贡献文档? - -本文主要针对已有的文档做局部修改。如果是投稿博客文章、添加新的文档或者调整文档目录结构请先联系团队成员。 - -KCL 文档分为用户指南、开发文档、内部文档、参考手册和博客文章等,他们的区别如下: - -- 用户指南:对应使用文档,是让用户以最小的代价快速使用 KCL 工具完整工作,不要涉及太多的内部原理和实现 -- 开发文档:内部是怎么实现的,主要针对希望了解 KCL 原理和参与贡献和开发的同学 -- 内部文档:针对企业用户的一些内部场景定制的文档 -- 参考手册:KCL 语言、工具和 IDE 等全部特性的文档,内容覆盖最广但比较琐碎 -- 博客文章:没有特别的限制,可以是针对某些具体的场景、某些技术点或者是整体发展展望等分享文章 - -在贡献不同类型的文档时,最好能够结合上面的定位对不同的内容做一些适当的裁剪,给读者最佳体验。 - -## 1. 基本规范 - -- 除标题外,内部小标题尽量带编号,便于阅读 -- 工具自动输出的文档需要由到源代码的链接,小标题可以不带编号 -- 尽量不要贴大段的代码(30行以内),代码最好给出文字解释和对应的参考链接 -- 有图有真相,但是不推荐过度复杂的架构图 -- 内部链接:采用 `/docs/user_docs/getting-started/intro` 绝对路径形式 - -**标点和空格** - -- 在中文的文档中优先使用中文的标点 -- 中文和英文之间需要增加 1 个空格 -- 中文和数字之间需要增加 1 个空格 -- 中文使用全角标点,标点前后均不添加空格 -- 英文内容使用半角标点,标点后面加 1 个空格 -- 链接前后需要保留一个空格,但是段落开头和中文全角标点附近不用添加空格。 - -**图片和资源文件名** - -- 文件名和目录名只能用数字、英文字母、下划线 `_` 和减号 `-` 组成 -- 当前文档的图片放在当前目录的 images 目录下 -- 矢量图片可以通过 [drawio 离线版](https://github.com/jgraph/drawio-desktop/releases) 绘制(并同时提交源文件),以 200% 分辨率导出 png 格式图片 - -## 2. 使用文档内容的基本模式 - -每个使用文档可以看作是一个相对完整的分享或博客文章(参考手册不再此类)。使用文档遵循以下模式组织内容: - -1. 概览:本文希望解决什么问题,达到什么效果,可以先放最终效果截图 -1. 依赖的环境:需要安装什么工具,并给出相关链接 -1. 引入本文构建资源的关系图或架构图 - - 需要用到的 Konfig 模型,给出模型参考页面链接,以及对应的上游原始模型的文档链接 -1. 具体的操作步骤 - - 尽量确保最小化代码,甚至可以刻意隐藏一些干扰代码,同时给出完整代码对应的链接 - - 列出每个步骤命令的概要输出信息,并配以文字描述 -1. 给出测试方式 - - 尽量采用社区通用的方式(比如kube、curl命令、或浏览器)测试 - - 给出测试结果的截图(和开头呼应) -1. 总结和展望 - - 简单回顾当前操作的流程,以及一些可以展开的地方(可以给出一些链接) - -## 3. 测试和提交 PR - -先克隆文档仓库,本地通过 `npm run start` 和 `npm run build` 命令测试查看效果,确保可以正常浏览后提交 PR 即可。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/contribute/contribute.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/contribute/contribute.md deleted file mode 100644 index 692df6ab..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/contribute/contribute.md +++ /dev/null @@ -1 +0,0 @@ -# 贡献指南 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/contribute/git-guideline.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/contribute/git-guideline.md deleted file mode 100644 index c475057d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/contribute/git-guideline.md +++ /dev/null @@ -1,132 +0,0 @@ -# Git 提交指南 - -本文介绍了 Git 提交变更时需要注意的事项,如果拒绝接受本文的内容会导致提交的变更无法被接受。 - -## 1. 关于 issue - -在提交一个 issue 之前,请先查阅已经关闭的 issue ,也许在关闭的 issue 中已经存在合适的解决方案。 - -如果没有找到合适的方案,我们提供了4种模版在创建 issue 的时候使用。 - -- Bug Report : 发现了一个 Bug,可以通过 Bug Report 模版创建 issue 与我们联系。 -- Enhancement : 开发者对工具进行了增强,可以通过 Enhancement 模版创建 issue 来介绍增加的内容。 -- Feature Request : 在使用的过程中想要为工具增加某些新的特性或者功能,可以通过 Feature Request 模版创建 issue 来描述新特性。 -- Ask a Question : 如果有任何的疑问,可以通过 Ask a Question 模版来创建一个 issue 与我们联系。 - -在选择合适的模版后,只需要填写模版上的要求填写的内容即可。如果在创建 issue 的时候发现没有模版,或者模版内容为空,可以通过微信群,钉钉群或者邮件向我们反馈这个问题。 - -## 2. 关于 Git 分支 - -要向 kcl-lang 贡献代码,您必须拥有一个 GitHub 帐户,以便您可以将代码推送到您自己的分支并创建拉取请求。我们推荐参考 [Angular 规范](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines) 为您自己的分支命名。 -推荐的格式如下: - -``` -{type}-{a_short_description} -``` - -分支名称主要包括两个字段,并通过 “-” 分割。其中: - -- {type} : 当前分支内容的类型。 -- {a_short_description}: 一个简短的描述,介绍这个分支的主要内容。 - -e.g. 张三首先 Fork 仓库到自己账户下,然后创建对应名称 `zhangsan:fix-output-fmt-bug` 的分支(冒号之前是张三的账号),用于修复输出格式化 bug。 - -## 3. 关于 Git Commit - -我们参考 [Commitizen](https://github.com/commitizen/cz-cli) 书写 Commit Message。 - -``` -注: 如果直接使用 Commitizen 生成 Commit Message,需要注意因为 Commitizen -是开发人员管理 commit 的工具,与项目本身无关联,因此由 Commitizen 生成的中间产物 -(如: node_modules 文件目录)可能没有在项目 .gitignore 文件中。 - -您可以 git add {filename} 选择要提交的文件而忽视中间产物。 -或者您可以向 .gitignore 文件中添加如下内容而自动忽视中间产物: -# commitizen -package.json -package-lock.json -node_modules/* -``` - -如果手动编写 Commit Message,我们也建议采用 [Commitizen](https://github.com/commitizen/cz-cli) 的 commit message 格式。 - -``` -{type} ( {component_or_file} ) {a_short_description} - {a_longer_description} - BREAKING CHANGE: {breaking_change_description}. - {linked issue} -``` - -其中主要包括6个字段: - -- {type} : 当前 commit 对应的分支的类型。 -- {component_or_file}: 当前 commit 改动的模块或者文件的名称。 -- {a_short_description}: 简短的描述介绍 commit 中的内容。 -- {a_longer_description}: 详细的描述用来介绍 commit 中的内容。 -- {breaking_change_description}: 如果 commit 中包含破环兼容性的改动,需要对兼容性改动产生的影响进行介绍。 -- {linked issue}: 与当前这个 commit 关联的 issue。 - -其中 {breaking_change_description} 和 {linked issue} 如果 commit 中不包含破坏兼容性的改动和关联的 issue,可以省略。 - -e.g. 张三在分支 `zhangsan:fix-output-fmt-bug` 中创建的 commit。 - -``` - - fix(kcl-printer): fix an output format bug in kcl-printer - - There is an output format bug in kcl-printer because ..., - So, The calling of method "XXX" is replaced by "HHHH"..., - ... - - -- 如果没有破坏兼容性的改动和关联的 issue 可以省略下面内容。 - - BREAKING CHANGE: This change maybe cause ....... - - fix #123 - -``` - -## 4. 关于 pull request - -在提交一个 PR 之前,可能需要优先考虑以下几个问题: - -- 请先查阅已经关闭的 PR ,也许在已经关闭的 PR 中,可能存在已经完成的解决方案。 -- 我们建议在提交变更之前,提交一个对应的 issue 描述变更中将要解决的问题,并将变更对应的 PR 与 issue 关联。 -- 在向我们提交 PR 之后,请签署 [Contributor License Agreement (CLA)](#cla) ,如果拒绝签署,我们将无法接受 PR。 -- 请确保每次改动都创建了一个新的分支,并根据上文中提到的规范为分支命名。 -- 一次 PR 请不要超过两个 commit ,请将多余的 commit 通过 squash 压缩,并根据上文中提到的规范,编写 commit message 。 -- 我们提供了 [PR 模版](https://github.com/kcl-lang/.github/blob/main/.github/PULL_REQUEST_TEMPLATE.md),只需要添加模版中要求的内容即可,如果在创建PR时发现没有模版或者模版内容为空,可以通过微信群,钉钉群或者邮件向我们反馈这个问题。 - -我们建议PR的标题与分支名、commit message 风格保持一致: - -``` -{type} ( {component_name_or_file_name} ) :{a_short_description} -``` - -e.g. 张三为分支`fix/zhangsan/fix_output_fmt_bug`创建的PR名称。 - -``` -fix(kcl-printer): fix an output format bug in kcl-printer. -``` - -## 5. 目前 type 支持的类型 - -参考[Angular 规范](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines),type 支持类型的类型如下: - -``` -- feat: -- 添加了新的功能特性。 -- fix: -- 进行了 Bug 的修复。 -- docs: -- 进行了文档部分的修改。 -- style: -- 对代码格式的修改,并不影响代码的功能,如:删除多余空格,代码缩进等。 -- refactor: -- 在不改变代码功能的基础上对代码进行了的重构。 -- perf: -- 对代码进行了性能优化。 -- test: -- 添加或者调整已有的测试用例。 -- build: -- 对构建系统或者外部依赖库进行了调整。 -- ci: -- 调整了 CI 的配置文件或者脚本。 -- chore: -- 对源代码和测试文件之外其他部分的调整。 -- revert: -- 对 commit 进行回滚。 -``` - -## 6. Contributor License Agreement (CLA) - -在第一次向我们提交 PR 之后,在 PR 中的 CLA 检查将会失败并提示签署 CLA。您可以通过自己的账户之间在 PR 回复 "I have read the CLA Document and I hereby sign the CLA" 表示同意签署 CLA,然后手动重启失败的 CLA 检查 Action 即可。当 PR 被成功合并之后将会被锁定不能再修改。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/intro/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/intro/_category_.json deleted file mode 100644 index e4cb1869..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/intro/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "简介", - "position": 1 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/intro/intro.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/intro/intro.md deleted file mode 100644 index af94bc33..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/intro/intro.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 社区 - -欢迎来到 KCL 开源社区,每个人的参与都是所有开源项目健康成长的动力!有很多方法可以参与开源。每个人都可以通过提交PR(Pull Request)来创建问题或修复 bug、改进文档或修改代码, - -可以查看[社区](https://github.com/kcl-lang/community)并加入我们。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/intro/license.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/intro/license.md deleted file mode 100644 index fe1db435..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/intro/license.md +++ /dev/null @@ -1,211 +0,0 @@ ---- -sidebar_position: 99 ---- - -# 许可 - -KCL 使用 [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0): - -``` - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2023 The KCL Authors. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/intro/support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/intro/support.md deleted file mode 100644 index 70ecd7e8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/intro/support.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 寻求帮助 - -KCL拥有一个由众多爱好者组成的开发者和用户社区。在此页面上,我们列出了您可以参与的KCL相关社区;有关其他在线和离线学习材料,请参阅本节的其他页面。 - -在加入 KCL 社区之前,请阅读[贡献者条款](https://www.contributor-covenant.org/version/2/0/code_of_conduct/),所有社区成员都需要遵守这些条款。 - -## 讨论 - -- 在 Github 上提交问题 -- 在 Github 讨论组中交流 -- 通过官方网站、Github、Twitter、微信和其他帐户获取 KCL 最新状态。可以查看[社区](https://github.com/kcl-lang/community)并加入我们。 - -## 新功能 - -请尽量避免提交新功能的拉取请求,我们可能已经有人在处理这些功能,或者这个功能已经是我们未来计划的一部分。总之,请在提交新功能之前与我们联系! diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/release-policy/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/release-policy/_category_.json deleted file mode 100644 index bf01a053..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/release-policy/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "发布策略", - "position": 3 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/release-policy/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/release-policy/index.md deleted file mode 100644 index a4a0bc3d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/release-policy/index.md +++ /dev/null @@ -1 +0,0 @@ -# 发布策略 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/release-policy/kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/release-policy/kcl.md deleted file mode 100644 index 0f9115b8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/release-policy/kcl.md +++ /dev/null @@ -1,39 +0,0 @@ -# KCL 发布策略 - -KCL 开发团队采用 [语义化版本](https://semver.org/lang/zh-CN/) 来简化管理。版本格式:主版本号.次版本号.修订号。版本号递增规则如下:主版本号对应不兼容的 API 修改,次版本号对应向下兼容的功能性新增,修订号对应向下兼容的问题修正。总体目标是每一个半月发布一个特性增强的次要版本,根据需要不定期发布其他版本的修订。 - -KCL 项目版本发布策略如下: - -- 主版本号:当进行重大的架构调整或者加入重大的新功能时,需要提升主版本号。对于 KCL 项目来说,目前的主版本号为 0。 -- 次版本号:当添加的功能和特性有较大的变化时,提升次版本号。目前的次版本号为 5,2023 年度会相继发布 0.5, 0.6, 0.7 版本。 -- 修订号:通过修复漏洞或者改进性能来更新程序时,会提升修订号,修订号从 0 开始计数以此加 1。 -- 发布周期:在未达到 v1.0.0 版本之前,计划每隔 3 个月发布一个新的次要版本。在此期间,需要持续收集用户反馈,并进行必要的修复和改进。 -- 发布流程:在发布新版本之前,需要进行严格的测试和审核,确保新版本的质量。封板并测试完成后,会在 Github 上发布新版本的源代码,二进制和镜像,并提供详细的文档和使用指南。 -- 版本支持:我们将对最新的版本提供长期支持,包括漏洞修复和安全更新。对于旧版本,我们将提供有限的支持,仅在必要时进行修复。 - -## 发布流程与规则 - -- 特性开发:main 分支主干开发,分支发布,block 用户使用的问题和严重的 bug, 安全隐患,高优先级解决,尽可能保持在一周内收敛,高于一般的功能研发。 -- 迭代周期:我们的迭代周期通常为 3 个月,即每 3 个月发布一个新的次要版本。 -- 版本规划:发版前两周产出 alpha 版本,前一周产出 beta 版本,alpha 版本仍可进行特性合并,beta 版本只合并错误修复,最终产出正式版本并打 tag 作为长期保存的 release 分支。 -- 发版计划:在每个发布周期开始时制定详细的发版计划(Github Milestone),包括发布日期、版本号、功能列表和测试计划等。需要尽可能地遵守发版计划,确保按时发布新版本。 -- 发布前测试:在发布新版本之前,需要进行全面的测试,包括单元测试、集成测试,模糊测试,压测,用户验收测试等。只有经过测试并无问题后,我们才会发布新版本。 -- 版本回滚:如果在发布后发现了严重的问题,需要立即回滚版本,并尽快修复问题。并通过邮件、社交媒体等渠道及时通知用户,并提供解决方案。 -- 发布文档:需要在发布时提供详细的文档,包括发布说明、更新日志、API 文档和使用指南等,帮助用户了解和使用新版本。在 KCL 中,我们统一在 KCL 网站进行维护。 -- 版本兼容性:在发布新版本时,需要尽可能保持兼容性,以确保用户无需进行过多的修改和适应。KCL 还没有达到 v1,暂时没有兼容性保证。KCL 的目标是尽可能少地进行重大更改,不应轻率地考虑对语言的更改,为了语言自身更好地演进和发展,一般认为更改具有重大好处时才会进行(较好地解决了目标场景的问题或者提升了绝大用户的使用体验)。对于可能引入兼容性问题的功能或变更,提供相应的提示和解决方案,同时会提供逐步升级的指南或提供自动迁移的工具,以帮助用户平滑地迁移到新版本。 - -## 发布组件 - -![](/img/docs/community/release-policy/kcl-components.png) - -每次版本发布时,KCL 相关所有组件保持一个依赖同一个 KCL 核心主要版本,整体采用树形结构组织依赖顺序发布并进行回归测试,直到发布测试完成,尽力避免三角依赖,禁止循环依赖。 - -## 一个 Feature 的生命周期 - -- 设计方案/文档:通过 Issue 回答清楚这个 feature 的动机是什么,它解决什么问题以及目标是什么,用户需求和用户故事是怎样的;这个 feature 做什么,如何做,难度怎样,需要多长时间,依赖项,需要做什么测试等。(Tips: 大的设计尽量拆分成小的设计,通过权衡和广泛的调研找到一个简单且可持续的解决方案,并且具备一定得到可扩展以适应未来的业务或技术变化,通过持续讨论和方案评审确定最终设计)。 -- 编写代码:通过高频小改动进行迭代、持续沟通和协作,提前设计单元测试、集成测试和 benchmark 等测试用例,确保编写代码 100% 测试覆盖,注释完整和逻辑清晰,并通过 Demo 演示持续收集反馈。 -- 文档撰写:在 [KCL 网站](https://kcl-lang.io) 中更新用户文档。 -- 测试和反馈:在发布功能之前,让一些同行/用户通过**随循文档**而不是口述来尝试和测试这些新功能。接收反馈并改进。 -- 发布和公告:撰写 Release Note, PR 文章,场景和新特性解读等以及渠道宣发等。 - -> 注:以上所有信息全是公开的,需要透出给所有社区研发者进行参与、讨论和贡献。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/_category_.json deleted file mode 100644 index 1910abe4..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "参考手册", - "position": 5 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/cheatsheets/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/cheatsheets/_category_.json deleted file mode 100644 index 7839b7a2..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/cheatsheets/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "备忘录", - "position": 10 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/cheatsheets/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/cheatsheets/index.md deleted file mode 100644 index 6bfb2e4c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/cheatsheets/index.md +++ /dev/null @@ -1,5 +0,0 @@ -# KCL 备忘录 - -![](/img/docs/reference/cheatsheets/cheatsheet.png) - -[Download PDF](https://github.com/kcl-lang/kcl-lang.io/blob/main/cheatsheet/cheatsheet.pdf) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/index.md deleted file mode 100644 index 9fd0c276..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/index.md +++ /dev/null @@ -1 +0,0 @@ -# 学习 KCL diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/_category_.json deleted file mode 100644 index 6066c82b..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KCL", - "position": 1 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/codelab/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/codelab/_category_.json deleted file mode 100644 index c0133443..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/codelab/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "代码实验室", - "position": 2 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/codelab/collaborative.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/codelab/collaborative.md deleted file mode 100644 index 883f4853..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/codelab/collaborative.md +++ /dev/null @@ -1,345 +0,0 @@ ---- -title: "使用配置操作分块编写配置" -linkTitle: "使用配置操作分块编写配置" -type: "docs" -weight: 2 -description: 使用配置操作分块编写配置 -sidebar_position: 3 ---- - -## 1. Introduction - -KCL 是一种简单易用的配置语言,用户可以简单地编写可重复使用的配置代码。 - -在这个教程中,我们将学习如何使用 KCL 配置操作(config operation)功能以协同的方式编写配置。 - -### 本节将会学习 - -1. 定义 schema 并组织项目目录。 -2. 通过KCL的配置操作功能创建多个环境配置。 -3. 配置编译参数和测试。 - -## 2. 定义 Schema 和 组织项目目录 - -### Schema 定义 - -假设我们想定义具有某些属性的服务器配置,我们可以通过创建一个 `server.k` 文件来创建一个简单的配置,我们可以填写以下代码来定义服务器配置的可重用模式: - -```python -import units - -type Unit = units.NumberMultiplier - -schema Server: - replicas: int = 1 - image: str - resource: Resource = {} - mainContainer: Main = {} - labels?: {str:str} - annotations?: {str:str} - -schema Main: - name: str = "main" - command?: [str] - args?: [str] - ports?: [Port] - -schema Resource: - cpu?: int = 1 - memory?: Unit = 1024Mi - disk?: Unit = 10Gi - -schema Port: - name?: str - protocol: "HTTP" | "TCP" - port: 80 | 443 - targetPort: int - - check: - targetPort > 1024, "targetPort must be larger than 1024" -``` - -在上面的代码中,我们定义了一个名为 Server 的 schema,该 schema 表示用户将要编写的配置类型,其中包含一些基本类型属性(例如`replicas`、`image` 等)和一些复合类型属性(例如 `resource`、`main` 等)。除了一些在 [schema codelab](./schema.md)中提到的基本类型之外,我们可以看到上面的代码中有两种类型 `Unit` 和 `units.NumberMultiplier`。其中,`units.NumberMultiplier` 表示 KCL 数字单位类型,意味着可以在 KCL 数字后添加自然单位或二进制单位,例如 `1K` 表示 `1000`,`1Ki` 表示 `1024`。 `Unit` 是 `units.NumberMultiplier` 的类型别名,用于简化类型注释的编写。 - -### 项目目录 - -为了完成协同的配置的开发,我们首先需要一个配置项目,其中包含测试应用程序的配置以及不同环境的差异化配置,因此我们正在创建以下项目目录: - -``` -. -├── appops -│ └── test_app -│ ├── base -│ │ └── base.k -│ ├── dev -│ │ ├── ci-test -│ │ │ └── stdout.golden.yaml -│ │ ├── kcl.yaml -│ │ └── main.k -│ └── prod -│ ├── ci-test -│ │ └── stdout.golden.yaml -│ ├── kcl.yaml -│ └── main.k -├── kcl.mod -└── pkg - └── sever.k -``` - -该项目目录主要包含三个部分: - -- `kcl.mod`:用于标识KCL项目的根目录的文件。 -- `pkg`:不同应用程序配置所共用的 `Server Schema` 结构。 -- `appops`:不同应用程序的 Server 配置,目前仅包含一个名为 `test_app` 的应用程序。 - - `base`:供所有环境使用的应用程序通用配置。 - - `dev`:供开发环境使用的应用程序配置。 - - `prod`:供生产环境使用的应用程序配置。 - -后续章节将会介绍`base.k`、`main.k`、`kcl.yaml` 和 `ci-test/stdout.golden.yaml` 的含义。 - -## 3. 通过 KCL 配置操作功能创建多个环境配置 - -### 创建基线配置 - -在组织好项目目录和基本的服务器配置模型之后,我们可以编写用户应用程序的配置。我们可以创建自己的测试应用程序文件夹 `test_app`,并将其放置在应用程序配置文件夹 `appops` 中。 - -对于应用程序的配置,我们通常将其分为基本配置和多个环境的差异化配置并进行合并。通过 KCL 的配置合并功能,我们可以轻松实现这一点。假设我们有开发环境和生产环境的两个配置,我们可以创建三个文件夹:`base`、`dev` 和 `prod` 分别存储基线、开发环境和生产环境的配置。首先,我们编写 `base/base.k` 的配置: - -```python -import pkg - -server: pkg.Server { - # 设置镜像的值为 "nginx:1.14.2" - image = "nginx:1.14.2" - # 添加 app label - labels.app = "test_app" - # 添加一个mainContainer配置,它的端口是 [{protocol = "HTTP", port = 80, targetPort = 1100}] - mainContainer.ports = [{ - protocol = "HTTP" - port = 80 - targetPort = 1100 - }] -} -``` - -正如上述代码中所示,我们使用 `import` 关键字在 `base.k` 中导入放置在 `pkg` 下的 `Server` schema,并使用它实例化一个名为`server` 的配置,在其中将 `image` 属性设置为 `"nginx:1.14.2"`,并添加一个带有值为 `test_app` 的标签 `app`。此外,我们还在 `ports` 属性中添加了主容器 `mainContainer` 的配置,其值为 `[{protocol = "HTTP", port = 80, targetPort = 1100}]`。 - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k -``` - -输出: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2 - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app -``` - -当前,我们已经有了一个基线配置。 - -### 创建多重环境配置 - -接下来我们将配置一个差异化的多环境配置。首先假设我们想在开发环境中使用自己的临时镜像 `nginx:1.14.2-dev`,然后使用它来覆盖基准中的服务器配置,我们可以在 `dev/main.k` 中编写以下配置: - -```python -import pkg - -server: pkg.Server { - # 覆盖 base 配置中的声明的镜像 - image = "nginx:1.14.2-dev" -} -``` - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -输出: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app -``` - -可以看出输出的 YAML 文件的 `image` 字段被覆盖为 `nginx:1.14.2-dev`。假设我们还想将一个具有键为 `env`,值为 `dev` 的标签添加到 `dev` 环境中,我们将以下代码添加到 `dev/main.k` 中: - -```python -import pkg - -server: pkg.Server { - # 覆盖 base 配置中的声明的镜像 - image = "nginx:1.14.2-dev" - # 将新标签 env 合并到 base 标签中 - labels.env = "dev" -} -``` - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app - env: dev -``` - -可以看到输出的 YAML 文件的 `labels` 字段中有两个标签。 - -此外,我们还可以使用 `+=` 运算符将新值添加到列表类型属性中,例如在基准环境中的 `mainContainer.ports` 配置,继续修改 `dev/main.k` 中的代码: - -```python -import pkg - -server: pkg.Server { - # 覆盖 base 配置中的声明的镜像 - image = "nginx:1.14.2-dev" - # 将新标签 env 合并到 base 标签中 - labels.env = "dev" - # 在 base ports配置中添加一个 port - mainContainer.ports += [{ - protocol = "TCP" - port = 443 - targetPort = 1100 - }] -} -``` - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -输出: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - - protocol: TCP - port: 443 - targetPort: 1100 - labels: - app: test_app - env: dev -``` - -使用相同的方法,我们可以构建生产配置,在 `dev/main.k` 文件中编写代码,并为其添加标签。 - -```python -import pkg - -server: pkg.Server { - # 将新标签 env 合并到 base 标签中 - labels.env = "prod" -} -``` - -KCL 命令: - -```bash -kcl appops/test_app/base/base.k appops/test_app/prod/main.k -``` - -输出: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2 - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app - env: prod -``` - -## 4. 配置编译参数和测试 - -在前面的章节中,我们通过代码构建了一个多环境配置。可以看出不同环境的 KCL 命令行编译参数相似,因此我们可以将这些编译参数配置到一个文件中,并将其输入到 KCL 命令行中进行调用。请将以下代码配置在 `dev/kcl.yaml`中: - -```yaml -kcl_cli_configs: - files: - - ../base/base.k - - main.k - output: ./ci-test/stdout.golden.yaml -``` - -然后我们可以使用以下命令在开发环境中编译配置: - -```bash -cd appops/test_app/dev && kcl -Y ./kcl.yaml -``` - -此外,我们已经在 `dev/kcl.yaml` 中配置了 `output` 字段,以将 YAML 输出到文件,以便进行后续配置分发或测试。您可以通过遍历每个环境中的 `kcl.yaml` 构建,并将其与 `./ci-test/stdout.golden.yaml` 进行比较,可以验证应用程序的配置是否符合预期。 - -## 5. 最后 - -恭喜! - -我们已经完成了关于 KCL 的第三课。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/codelab/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/codelab/index.md deleted file mode 100644 index 123c0878..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/codelab/index.md +++ /dev/null @@ -1 +0,0 @@ -# 代码实验室 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/codelab/schema.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/codelab/schema.md deleted file mode 100644 index 434e1f5c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/codelab/schema.md +++ /dev/null @@ -1,814 +0,0 @@ ---- -title: "使用 KCL Schema 编写复杂配置" -linkTitle: "使用 KCL Schema 编写复杂配置" -type: "docs" -weight: 2 -description: 使用 KCL Schema 编写复杂配置 -sidebar_position: 2 ---- - -## 1. 介绍 - -KCL 是一种简单易用的配置语言,用户可以简单地编写可重用的配置代码。 - -在本节教程中,我们将学习如何使用 KCL 编写定制配置,这样我们就可以定义一个架构并以协作方式编写配置。 - -### 本节将会学习 - -1. 定义一个简单的 schema -2. 为 schema 字段设置默认的不可变值 -3. 基于简单的 schema 创建配置 -4. 在 schema 中编写复杂的逻辑 -5. 通过 schema 的组合创建新的 schema -6. 使用 dict/map 创建具有深度嵌套 schema 的配置 -7. 通过 schema 继承创建新的 schema -8. 通过多个 mixin schema 创建新的 schema -9. 声明 schema 验证规则 -10. 配置 schema 的输出布局 -11. 共享和重用 schema - -## 2. 编写简单的 Schema - -假设我们希望定义一个具有特定属性的工作负载,我们可以通过创建一个 `my_config.k` 文件来创建一个简单的配置。我们可以按以下方式填写下面的代码,定义一个可重复使用的部署配置的 schema: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels: {str:str} -``` - -在上述代码中,`cpu` 和 `memory` 被定义为 int 值;`name`、`image` 和 `service` 是字符串;`command` 是由字符串构成的列表;`labels` 是字典类型,其键和值的类型均为字符串。 - -另外,每个属性都**必须**被赋予非 None 值作为 schema 实例,除非它被标记问号 **?** 而作为可选参数。 - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels?: {str:str} # labels 是一个可选的参数 -``` - -当存在继承关系时: - -- 如果在基 schema 中该属性为可选(optional)参数,则在子 schema 中它应该是可选的(optional)或必需的(required)。 -- 如果在基 schema 中该属性为必需(required)属性,则在子 schema 中它需要是必需的(required)。 - -## 3. Enhance Schema as Needed - -Suppose we need to set default values to service and replica, we can make them as below: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str = "my-service" # defaulting - replica: int = 1 # defaulting - command: [str] - labels?: {str:str} # labels is an optional attribute -``` - -And then we can set the service type annotation as the string literal type to make it immutable: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: "my-service" = "my-service" - replica: int = 1 - command: [str] - labels?: {str:str} -``` - -In the schema, type hint is a `must`, for example we can define cpu as `cpu: int`. - -Specially, we can define a string-interface dict as `{str:}`, and in case we want to define an object or interface, just define as `{:}`. - -## 4. 基于简单 Schema 创建配置 - -现在我们有了一个简单的 schema 定义,我们可以用它来定义配置: - -```python -nginx = Deployment { - name = "my-nginx" - cpu = 256 - memory = 512 - image = "nginx:1.14.2" - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python - kcl my_config.k -``` - -标准输出: - -```yaml -nginx: - name: my-nginx - cpu: 256 - memory: 512 - image: nginx:1.14.2 - service: my-service - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -> 有关集合数据类型和块的更多详细信息,请查看手册和规范。 - -此外,**配置选择器表达式**(config selector expressions)可以用于初始化 schema 实例,我们可以忽略配置表达式中行末的逗号。 - -```python -nginx = Deployment { - name = "my-nginx" - cpu = 256 - memory = 512 - image = "nginx:1.14.2" - command = ["nginx"] # 忽略行尾的逗号 - labels.run = "my-nginx" # schema 中的字典变量可以使用选择器表达式 - labels.env = "pre-prod" # schema 中的字典变量可以使用选择器表达式 -} -``` - -## 5. 在 Schema 中编写更为复杂的逻辑 - -假设我们有一些schema逻辑,我们可以将它包装进 schema 中: - -```python -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - image: str - service: "my-service" = "my-service" - replica: int = 1 - command: [str] - labels?: {str:str} - - _cpu = 2048 - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 -``` - -现在,我们可以通过创建 schema 实例来定义配置,并将优先级作为参数传递给模式: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl my_config.k -``` - -标准输出: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - image: nginx:1.14.2 - service: my-service - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 6. 通过 Schema 组合创建新 Schema - -现在我们想要定义一个详细的 schema,包括服务(service)和卷(volumes),我们可以按以下方式进行操作: - -```python -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - volumes?: [Volume] - image: str - service?: Service - replica: int = 1 - command: [str] - labels?: {str:str} - - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 - -schema Port: - name: str - protocol: str - port: int - targetPort: int - -schema Service: - name: "my-service" = "my-service" - ports: [Port] - -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -在这种情况下,Deployment 由 Service 和一系列 Volume 组成,而 Service 又由一系列 Port 组成。 - -## 7. 使用 dict/map 创建具有深度嵌套 schema 的配置 - -现在我们有一个新的 Deployment schema,但我们可能会注意到,它包含多层嵌套的结构,在复杂的结构定义中,这是非常常见的,我们通常必须编写命令式组装代码来生成最终结构。 - -使用 KCL,我们可以使用简单的字典声明创建配置,并具有完整的 schema 初始化和验证功能。例如,我们可以按照以下方式使用新的 Deployment schema简单地配置 nginx: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl my_config.k -``` - -标准输出: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -请注意,我们用于定义 Deployment 配置的字典必须与 schema 定义对齐,否则我们将会得到一个错误。例如,假设我们将服务端口的类型定义错误如下: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = [80] # 错误的数据类型,试图将 List 分配给 int - targetPort = 9376 - }] -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl my_config.k -``` - -标准错误输出: - -``` -The type got is inconsistent with the type expected: expect int, got [int(80)] -``` - -## 8. 声明 Schema 验证规则 - -现在我们已经看到了一个复杂的 schema,在其中每个字段都有一个类型提示,以使其更加不容错(error-prone)。 - -但是这还不够好,我们希望为我们的 schema 支持更多的增强验证,以便尽快发现 schema 和配置中的代码错误。许多验证规则,如 None 类型检查、范围检查、值检查、长度检查、正则表达式匹配、枚举检查已经被添加或陆续添加进来。以下是一段代码示例: - -```python -import regex - -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - volumes?: [Volume] - image: str - service?: Service - replica: int = 1 - command: [str] - labels?: {str:str} - - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 - - check: - multiplyof(cpu, 256), "cpu must be a multiplier of 256" - regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$"), "image name should be like 'nginx:1.14.2'" - 1 <= replica < 100, "replica should be in range (1, 100)" - len(labels) >= 2 if labels, "the length of labels should be large or equal to 2" - "env" in labels, "'env' must be in labels" - len(command) > 0, "the command list should be non-empty" - -schema Port: - name: str - protocol: str - port: int - targetPort: int - - check: - port in [80, 443], "we can only expose 80 and 443 port" - protocol in ["HTTP", "TCP"], "protocol must be either HTTP or TCP" - 1024 < targetPort, "targetPort must be larger than 1024" - -schema Service: - name: "my-service" = "my-service" - ports: [Port] - - check: - len(ports) > 0, "ports list must be non-empty" - -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -由于schema定义的属性默认是**必需的**(required),因此可以省略判断变量不能为 None/Undefined 的验证。 - -```python -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -现在我们可以基于新的 schema 编写配置,并及时暴露配置错误。例如,使用以下无效的配置: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1142" # 镜像值不匹配正则表达式 - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -每个字段都是类型有效的,但镜像名无效。 - -运行 KCL,我们将看到如下错误信息: - -KCL 命令: - -```python -kcl my_config.k -``` - -标准错误输出: - -``` -Schema check is failed to check condition: regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$"), "image name should be like 'nginx:1.14.2'" -``` - -> KCL 的验证功能涵盖了 Openapi 定义的验证,因此我们可以通过 KCL 编写任何 API 验证。 - -## 9. 通过 Schema 继承创建新 Schema - -现在,我们拥有了一个稳定的部署 schema 定义,可以用它来声明配置。 - -通常,部署 schema 将被用于多个场景中。我们可以直接使用 schema 在不同的用例中声明配置(见上文的部分),或者我们可以通过继承生成一个更具体的 schema 定义。 - -例如,我们可以使用部署 schema 作为基础,来定义 nginx 的基本 schema,并在每个场景中扩展定义。在这种情况下,我们定义了一些常用的属性。请注意,我们使用“final”关键字将名称标记为不可变,以防止被覆盖。 - -```python -schema Nginx(Deployment): - """ A base nginx schema """ - name: "my-nginx" = "my-nginx" - image: str = "nginx:1.14.2" - replica: int = 3 - command: [str] = ["nginx"] - -schema NginxProd(Nginx): - """ A prod nginx schema with stable configurations """ - volumes: [Volume] = [{ - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - """ A volume mapped to host path """ - service: Service = { - ports = [{ - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] - } - """ An 80 port to target backend server """ -``` - -现在我们有了一些 nginx 的静态配置。建议将我们认为是静态的配置声明在那里,并将更多的动态配置放在下面: - -```python -nginx = Nginx { - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -```python -nginx = NginxProd { - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -现在,我们只需要通过运行时标签值 “prod” 来简单定义 不那么静态的 nginx 生产环境配置。 - -实际上,在某些复杂情况下,我们可以将所有配置分为基本配置、业务配置和环境配置定义,并基于此实现团队成员之间的协作。 - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl prod_config.k -``` - -标准输出: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 3 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 10. Create New Schema by Multiple Protocol and Mixin Schemas Inheritance - -现在,我们可以通过 Deployment schema 完成服务器配置的声明。 - -然而,通常实际情况更为复杂,部署可能有各种可选变量附件。 - -例如,我们想要在现有 schema 中支持声明持久卷,作为可重用的 Kubernetes schema。在这种情况下,我们可以通过以下 `mixin` 和 `protocal` 进行包装: - -```python -import k8spkg.api.core.v1 - -protocol PVCProtocol: - pvc?: {str:} - -mixin PersistentVolumeClaimMixin for PVCProtocol: - """ - PersistentVolumeClaim (PVC) sample: - Link: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims - """ - - # Mix in a new attribute `kubernetesPVC` - kubernetesPVC?: v1.PersistentVolumeClaim - - if pvc: - kubernetesPVC = v1.PersistentVolumeClaim { - metadata.name = pvc.name - metadata.labels = pvc.labels - spec = { - accessModes = pvc.accessModes - resources = pvc.resources - storageClassName = pvc.storageClassName - } - } -``` - -有了 PersistentVolumeClaimMixin,我们使用清晰的用户界面(user interface)定义了一个 PVC schema,并使用 Kubernetes PVC 作为实现。然后,我们可以使用 Deployment schema 和 PVC mixin schema 定义一个 server schema。 - -```python -schema Server(Deployment): - mixin [PersistentVolumeClaimMixin] - pvc?: {str:} - """ pvc user interface data defined by PersistentVolumeClaimMixin """ -``` - -在 Server schema 中,Deployment schema 是基础 schema,而 PersistentVolumeClaimMixin 是一个可选附加项,其用户界面数据为`pvc?:{str:}`。 - -请注意,mixin 通常用于向宿主 schema 添加新属性,或修改宿主 schema 的现有属性。因此,mixin 可以使用宿主 schema 中的属性。由于其被设计为可重用,因此我们需要一个额外的协议来限制 mixin 中宿主 schema 中属性的名称和类型。 - -现在,如果我们想要使用 PVC 进行部署,只需声明用户界面: - -```python -server = Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] - pvc = { - name = "my_pvc" - accessModes = ["ReadWriteOnce"] - resources.requests.storage = "8Gi" - storageClassName = "slow" - } -} -``` - -使用以下 KCL 命令运行,我们应该能够看到生成的 yaml 文件作为输出,如下所示: - -KCL 命令: - -```python -kcl server.k -``` - -标准输出: - -```yaml -server: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod - pvc: - name: my_pvc - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 8Gi - storageClassName: slow ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: my_pvc -spec: - accessModes: - - ReadWriteOnce - storageClassName: slow - resources: - requests: - storage: 8Gi -``` - -如果我们不需要持久卷,只需删除 pvc 配置块。 - -## 11. 共享和重用 Schema - -可以通过导入来共享 Server schema,我们只需要将代码与 KCL 一起打包即可。 - -```python -import pkg - -server = pkg.Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -另一个关于共享代码的技巧是:在同一包下的模块不需要相互导入。 - -假设我们在 pkg 中有如下 models: - -``` -pkg/ - - deploy.k - - server.k - - pvc.k -``` - -在 `server.k` 中,我们可以只使用 `deploy.k` 中的 Deployment schema 和 `pvc.k` 中的 pvc schema 而无需导入: - -```python -# 无需 import -schema Server(Deployment): - mixin [PersistentVolumeClaimMixin] - pvc?: {str:} - """ pvc user interface data defined by PersistentVolumeClaimMixin """ -``` - -然后用户必须导入 pkg 才能作为一个整体使用它: - -```python -import pkg - -server = pkg.Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [pkg.Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } - service.ports = [pkg.Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -运行 KCL 命令: - -```python -kcl pkg_server.k -``` - -Output: - -```yaml -server: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 12. 最后 - -恭喜! - -我们已经完成了 KCL 的第二节课。我们使用 KCL 来替换我们的 key-value 文本文件,以便获得更好的可编程性。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/codelab/simple.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/codelab/simple.md deleted file mode 100644 index 32ad2612..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/codelab/simple.md +++ /dev/null @@ -1,495 +0,0 @@ ---- -title: "使用 KCL 编写简单配置" -linkTitle: "使用 KCL 编写简单配置" -type: "docs" -weight: 2 -description: 使用 KCL 编写简单配置 -sidebar_position: 1 ---- - -## 1. 介绍 - -KCL 是一种简单易用的配置语言,用户可以简单地编写可重用的配置代码。 - -在这个第一个教程中,我们将学习如何使用 KCL 编写一个简单的配置。 - -学习这个代码实验只需要基本的编程知识,如果你有 Python 经验,将会更容易上手。 - -### 本节将会学习 - -1. 用一种可编程的方式编写简单的 key-value 配置 -2. 使用 KCL 编写简单的逻辑 -3. 使用 KCL 编写集合(collections) -4. 使用 KCL 代码进行测试和调试 -5. 在 KCL 代码中使用内置(built-in)支持 -6. 共享和重用 KCL 代码 -7. 使用动态输入参数编写配置 - -## 2. 编写Key-Value键值对 - -通过创建 `my_config.k` 来生成一个简单的配置,我们可以填充下面的代码,并且不需要严格的格式描述部署的配置。 - -```python -cpu = 256 -memory = 512 -image = "nginx:1.14.2" -service = "my-service" -``` - -在上述代码中,cpu 和 memory 被声明为 int 类型的值,而 image 和 service 被声明为字符串字面值。 - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -KCL 命令: - -```bash -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -可导出变量(exported variable)默认情况下是不可变的,一旦声明,就不能在其他地方修改它。 - -## 3. 编写简单逻辑 - -有时候我们想在配置中编写一些逻辑,那么我们就可以使用: - -- 以 `_` 开头的非导出可变变量(mutable and non-exported variable) -- if-else 语句 - -非导出变量表示它不会出现在输出的 YAML 中,且它可以被多次赋值。 - -这是一个示例,显示如何根据条件调整资源。 - -KCL 命令: - -```python -kcl my_config.k -``` - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -image = "nginx:1.14.2" -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -```python -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -.. 注意:: -KCL 对运算符和字符串成员函数有丰富的支持,请阅读手册和规范以了解更多细节。 - -## 4. 编写集合 - -我们可以使用集合来表示复杂的数据类型。已支持的集合类型有: - -- list -- dict - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -command = ["nginx"] # 列表 -labels = {run = "my-nginx"} # a dict -image = "nginx:1.14.2" -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -KCL 命令: - -```bash -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx -image: nginx:1.14.2 -service: my-service -``` - -> 有关集合数据类型和成员函数的更多信息,请查阅手册和规范。 - -## 5. 在集合中添加元素 - -我们可以将逻辑表达式、推导式、切片、联合类型等特性组合起来,动态地将元素添加到集合中。 - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 -_env = "pre-prod" - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -_command = ["nginx"] # 列表 -_command = _command + ["-f", "file"] # 使用 + 运算符将元素附加到命令中以连接两个列表 -command = [c.lower() for c in _command] # # 将列表中的每个元素转为小写 -_labels = { - run = "my-nginx" - if _env: - env = _env # 当 _env 不是 None/Undefined 或为空时使用 if 表达式添加一个字典键值对 -} # 字典 -labels = _labels -image = "nginx:1.14.2" -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -```python -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 256 -memory: 512 -command: - - nginx - - -f - - file -labels: - run: my-nginx -image: nginx:1.14.2 -service: my-service -``` - -## 6. 编写断言 - -为了使代码可测试且健壮,我们可以使用断言(assertions)验证配置数据。 - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -command = ["nginx"] # 列表 -labels = {run = "my-nginx"} # 字典 -image = "nginx:1.14.2" -service = "my-service" -assert "env" in labels, "env label is a must" -assert cpu >= 256, "cpu cannot be less than 256" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -```bash -kcl my_config.k -``` - -标准错误输出: - -```bash -Assertion failure: env label is a must. -``` - -将 env:pre-prod 对添加到标签中后,我们将得到如下输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 7. 使用方便的内置支持 - -更重要的是,我们可以使用内置函数来帮助我们调试或简化编码。 - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -_name = "nginx" -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # 列表 -labels = { - run = "my-{}".format(_name) - env = "pre-prod" -} # a dict -image = "{}:1.14.2".format(_name) # 字符串格式 -service = "my-service" - -# debugging -print(labels) # 通过打印调式 - -# test -assert len(labels) > 0, "labels can't be empty" # 使用 len() 得到列表长度 -assert "env" in labels, "env label is a must" -assert cpu >= 256, "cpu cannot be less than 256" -``` - -此示例展示了我们如何使用 `format()`、`len()`、`print()` 函数来帮助自定义配置。 - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -KCL 命令: - -```bash -kcl my_config.k -``` - -标准输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -run: my-nginx -env: pre-prod -``` - -注意:更多的内置函数和模块可以在 spec/module 目录中查看。 - -## 8. 重用另一个模块的变量 - -为了使我们的代码得到良好的组织,我们可以将代码简单地分为 `my_config.k` 和 `my_config_test.k` 两个文件。 - -在 `my_config.k` 中定义配置数据: - -```python -_priority = 1 # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 -_name = "nginx" - -# 可导出变量 -cpu = _cpu -memory = _cpu * 2 -command = [_name] # 列表 -labels = { - run = "my-{}".format(_name) - env = "pre-prod" -} # a dict -image = "{}:1.14.2".format(_name) # 字符串格式 -service = "my-service" -``` - -而测试代码定义在 `my_config_test.k` 中,我们可以在其中导入 `my_config.k`: - -```python -import my_config - -# debugging -print(my_config.labels) # 通过打印调试 - -# test -assert len(my_config.labels) > 0, "labels can't be empty" # 使用 len() 得到列表长度 -assert "env" in my_config.labels, "env label is a must" -assert my_config.cpu >= 256, "cpu cannot be less than256" -``` - -## 9. 配置输入参数 - -有时我们需要获得通过从最终用户或平台动态获取的外部输入参数。 - -在这种情况下,我们可以按需传递 `priority` 和 `env` 参数: - -- 通过参数传递: `-D priority=1 -D env=pre-prod` -- 可以在 KCL 代码中使用 `option` 关键字获取这些值 - -```python -_priority = option("priority") # 非导出可变变量 -_env = option("env") # 非导出可变变量 -_cpu = 256 # 非导出可变变量 - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -_name = "nginx" -# 可导出变量 -cpu = _cpu -memory = _cpu * 2 -command = [_name] # 列表 -labels = { - run = "my-{}".format(_name) - env = _env -} # a dict -image = "{}:1.14.2".format(_name) # 字符串格式 -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -```bash -kcl my_config.k -D priority=2 -D env=pre-prod -``` - -标准输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 10. 使用 Dict 简化逻辑表达式 - -当我们需要编写复杂的逻辑时,可以使用dict来简化逻辑的编写。 - -```python -_priority = option("priority") # 非导出可变变量 -_env = option("env") # 非导出可变变量 -_priorityCpuMap = { - "1" = 256 - "2" = 512 - "3" = 1024 -} -# 使用字典简化逻辑,默认值为2048 -_cpu = _priorityCpuMap[_priority] or 2048 -_name = "nginx" -# 可导出变量 -cpu = _cpu -memory = _cpu * 2 -command = [_name] # 列表 -labels = { - run = "my-{}".format(_name) - env = _env -} # a dict -image = "{}:1.14.2".format(_name) # 字符串格式 -service = "my-service" -``` - -使用 KCL 运行上述代码,将会看到以 yaml 格式生成的如下数据: - -KCL 命令: - -```bash -kcl my_config.k -D priority=2 -D env=pre-prod -``` - -标准输出: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 11. 最后 - -恭喜! - -我们已经完成了关于 KCL 的第一课程,我们使用 KCL 来替换我们的键值文本文件,以获得更好的编程支持。 - -建议立即查看架构代码实验,以了解如何使用 KCL `schema` 机制协作编写高级配置。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/error/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/error/_category_.json deleted file mode 100644 index 4f285ced..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/error/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "错误与警告", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/error/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/error/index.md deleted file mode 100644 index e4f702ec..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/error/index.md +++ /dev/null @@ -1 +0,0 @@ -# 错误与警告 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/index.md deleted file mode 100644 index 66fd3dde..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/index.md +++ /dev/null @@ -1 +0,0 @@ -# KCL diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/_category_.json deleted file mode 100644 index c088e386..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "规范", - "position": 3 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/datatypes.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/datatypes.md deleted file mode 100644 index ef7ea71a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/datatypes.md +++ /dev/null @@ -1,452 +0,0 @@ ---- -title: "Data Types" -linkTitle: "Data Types" -type: "docs" -weight: 2 -description: Data Types ---- - -## Syntax - -### Bool - -Boolean values are the two constant objects `False` and `True`. They are used to represent truth values (although other values can also be considered false or true). The built-in function bool() can be used to convert any value to a Boolean, if the value can be interpreted as a truth value. - -### Int - -Int, or integer, is an arbitrarily sized integer, positive or negative, without decimals, of 64 binary digits precision(-9,223,372,036,854,775,808~9,223,372,036,854,775,807). Int is created by int literals or as the result of built-in functions and operators. Unadorned integer literals (including `hex`, `octal` and `binary` numbers) yield integers. The constructor int() can be used to produce int of a specific type. - -Besides, integer literals may have an `SI` or `IEC` multiplier. - -- `SI`: General integer or fixed-point number form: `P`, `T`, `G`, `M`, `K`, `k`, `m`, `u`, `n`. -- `IEC`: Corresponding power of 2: `Pi`, `Ti`, `Gi`, `Mi`, `Ki`. - -```python -a = 1 # positive integer: 1 -b = -1 # negative integer: -1 -c = 0x10 # hexadecimal literal: 16 -d = 0o10 # octal literal: 8, or the form `010` -e = 0b10 # binary literal: 2 -f = 10Ki # integer literal with IEC multiplier: 10240 -g = 1M # integer literal with SI multiplier: 1000000 -h = int("10") # int constructor: 10 -i = int("10Ki") # int constructor with multiplier: 10240 -``` - -Notes: - -- Report an error if unable to represent an integer value precisely. - -### Float - -Float, floating-point, approximation to real numbers, positive or negative, containing one or more decimals, of 64 bit IEEE 754 floats. The constructor float() can be used to produce int of a specific type. - -```python -a = 1.10 -b = 1.0 -c = -35.59 -d = 32.3+e18 -f = -90. -g = -32.54e100 -h = 70.2-E12 -i = float("112") # float constructor -``` - -Notes: - -- Report an error if unable to represent a floating-point value due to overflow -- Report a warning if unable to represent a floating-point value due to underflow. Round to the nearest representable value if unable to represent a floating-point value due to limits on precision. These requirements apply to the result of any expression except for built-in functions for which an unusual loss of precision must be explicitly documented. - -#### None - -In KCL, `None` can indicate that the value of the object is empty, which is similar to `nil` in Go or `null` in Java, and corresponds to `null` in YAML and JSON. - -```python -a = None -b = [1, 2, None] -c = {"key1" = "value1", "key2" = None} -``` - -Please note that `None` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + None # error -b = int(None) # error -c = not None # True -d = None == None # True -e = None or 1 # 1 -f = str(None) # None -``` - -#### Undefined - -`Undefined` is similar to None, but its semantics is that a variable is not assigned any value and will not be output to YAML or JSON. - -```python -a = Undefined -b = [1, 2, Undefined] -c = {"key1" = "value1", "key2" = Undefined} -``` - -Please note that `Undefined` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + Undefined # error -b = int(Undefined) # error -c = not Undefined # True -d = Undefined == Undefined # True -e = Undefined or 1 # 1 -f = str(Undefined) # Undefined -``` - -### Common Numeric Operations - -Int and Float support the following operations (see built-in proposal for built-in details): - -- `x + y`: sum of x and y. -- `x - y`: difference of x and y. -- `x * y`: product of x and y. -- `x / y`: quotient of x and y. -- `x // y`: floored quotient of x and y. -- `x % y`: remainder of x / y. -- `x ** y`: x to the power y. -- `-x`: x negated. -- `+x`: x unchanged. -- `~x`: x bitwise negation. -- `abs(x)`: absolute value or magnitude of x. -- `int(x)`: x converted to integer. -- `float(x)`: x converted to floating point. - -KCL supports mixed arithmetic: when a binary arithmetic operator has operands of different numeric types, the operand with the "narrower" type is widened to that of the other, where integer is narrower than floating-point. - -### String - -Strings are immutable sequences of Unicode characters. String literals are written in a variety of ways: - -```python -'allows embedded "double" quotes' # Single quotes -"allows embedded 'single' quotes" # Double quotes -'''Three single quotes''', """Three double quotes""" # Triple quoted -``` - -Triple quoted strings may span multiple lines. - -Indexing a string produces strings of length 1, for a non-empty string s, `s[0] == s[0:1]`. - -```python -a = "Hello, World!" -b = a[2:5] # "llo" -c = a[-5:-2] # "orl" -d = a[::-1] # "'!dlroW ,olleH'" -``` - -- `str(x=None) -> str` - -Return a string. If _x_ is not provided, raise a runtime error. - -```python -x = str(3.5) # "3.5" -``` - -#### Members - -Built-in function and members of a string - -- `str#len() -> int` - Return the number of characters in the string. -- `capitalize() -> str` - Return a copy of the string with its first character (if any) capitalized and the rest lowercased. -- `count(sub: str, start: int = 0, end: int = -1) -> int` - Returns the number of (non-overlapping) occurrences of substring sub in string, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `endswith(suffix: str, start: int = 0, end: int = -1) -> bool` - Returns `True` if the string ends with the specified suffix, otherwise return `False`, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `find(sub: str, start: int = 0, end: int = -1) -> int` - Returns the lowest index where substring sub is found, or -1 if no such index exists, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `format(*args, **kwargs) -> str` - Perform string interpolation. Format strings contain replacement fields surrounded by curly braces {}. Anything that is not contained in braces is considered literal text, which is copied unchanged to the output. If you need to include a bracket character in the literal text, it can be escaped by doubling: A replacement field can be either a name, a number or empty. Values are converted to strings using the str function. -- `index(sub: str, start: int = 0, end: int = -1) -> int` - Returns the first index where sub is found, or raises an error if no such index exists, optionally restricting to `[start:end]` start being inclusive and end being exclusive. -- `isalnum() -> bool` - Returns True if all characters in the string are alphanumeric (`[a-zA-Z0-9]`) and there is at least one character, False otherwise. -- `isalpha() -> bool` - Returns True if all characters in the string are alphabetic (`[a-zA-Z]`) and there is at least one character. -- `isdigit() -> bool` - Returns True if all characters in the string are digits (`[0-9]`) and there is at least one character. -- `islower() -> bool` - Returns True if all cased characters in the string are lowercase and there is at least one character. -- `isspace() -> bool` - Returns True if all characters are white space characters and the string contains at least one character. -- `istitle() -> bool` - Returns True if the string is in title case and it contains at least one character. This means that every uppercase character must follow an uncased one (e.g., whitespace) and every lowercase character must follow a cased one (e.g., uppercase or lowercase). -- `isupper() -> bool` - Returns True if all cased characters in the string are uppercase and there is at least one character. -- `join(iterable: list) -> str` - Return a string which is the concatenation of the strings in iterable. A TypeError will be raised if there are any non-string values in iterable. The separator between elements is the string providing this method. Example: - - ```python - >>> "|".join(["a", "b", "c"]) - "a|b|c" - ``` - -- `lower() -> str` - Returns a copy of the string with all the cased characters converted to lowercase. -- `lstrip(chars: str) -> str` - Return a copy of the string with leading characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.lstrip() - 'spacious ' - >>> 'www.example.com'.lstrip('cmowz.') - 'example.com' - ``` - -- `replace(old: str, new: str, count: int) -> str` - Return a copy of the string with all occurrences of substring old replaced by new. If the optional argument count is given, only the first count occurrences are replaced. -- `rfind(sub: str, start: int = 0, end: int = -1) -> int` - Return the highest index in the string where substring sub is found, such that sub is contained within s[start:end]. Optional arguments start and end are interpreted as in slice notation. Return -1 on failure. -- `rindex(sub: str, start: int = 0, end: int = -1) -> int` - Returns the last index where sub is found, or raises an ValueError if no such index exists, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `rsplit(sep: str, maxsplit: int = -1) -> list` - Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done, the rightmost ones. If sep is not specified or None, any whitespace string is a separator. Except for splitting from the right, rsplit() behaves like split() which is described in detail below. -- `rstrip(chars: str) -> str` - Return a copy of the string with trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a suffix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.rstrip() - ' spacious' - >>> 'mississippi'.rstrip('ipz') - 'mississ' - ``` - -- `split(sep: str, maxsplit: int) -> list` - Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done (thus, the list will have at most maxsplit+1 elements). If maxsplit is not specified or -1, then there is no limit on the number of splits (all possible splits are made). - - If sep is given, consecutive delimiters are not grouped together and are deemed to delimit empty strings (for example, `'1,,2'.split(',')` returns `['1', '', '2']`). The sep argument may consist of multiple characters (for example, `'1<>2<>3'.split('<>')` returns `['1', '2', '3']`). Splitting an empty string with a specified separator returns `['']`. - - For example: - - ```python - >>> '1,2,3'.split(',') - ['1', '2', '3'] - >>> '1,2,3'.split(',', maxsplit=1) - ['1', '2,3'] - >>> '1,2,,3,'.split(',') - ['1', '2', '', '3', ''] - ``` - - If sep is not specified or is None, a different splitting algorithm is applied: runs of consecutive whitespace are regarded as a single separator, and the result will contain no empty strings at the start or end if the string has leading or trailing whitespace. Consequently, splitting an empty string or a string consisting of just whitespace with a `None` separator returns `[]`. - - For example: - - ```python - >>> '1 2 3'.split() - ['1', '2', '3'] - >>> '1 2 3'.split(maxsplit=1) - ['1', '2 3'] - >>> ' 1 2 3 '.split() - ['1', '2', '3'] - ``` - -- `splitlines(keepends: str) -> list` - Return a list of the lines in the string, breaking at line boundaries('\n', '\r\n', '\r'). Line breaks are not included in the resulting list unless keepends is given and true. - - This method splits on the following line boundaries. In particular, the boundaries are a superset of universal newlines. - - For example: - - ```python - >>> 'ab c\n\nde fg\rkl\r\n'.splitlines() - ['ab c', '', 'de fg', 'kl'] - >>> 'ab c\n\nde fg\rkl\r\n'.splitlines(keepends=True) - ['ab c\n', '\n', 'de fg\r', 'kl\r\n'] - ``` - - Unlike `split()` when a delimiter string sep is given, this method returns an empty list for the empty string, and a terminal line break does not result in an extra line: - - ```python - >>> "".splitlines() - [] - >>> "One line\n".splitlines() - ['One line'] - ``` - - For comparison, `split('\n')` gives: - - ```python - >>> ''.split('\n') - [''] - >>> 'Two lines\n'.split('\n') - ['Two lines', ''] - ``` - -- `startswith(prefix: str, start: int = 0, end: int = -1) -> bool` - Return `True` if string starts with the prefix, otherwise return False. prefix can also be a list of prefixes to look for. With optional start, test string beginning at that position. With optional end, stop comparing string at that position. -- `strip(chars: str) -> str` - Return a copy of the string with the leading and trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix or suffix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.strip() - 'spacious' - >>> 'www.example.com'.strip('cmowz.') - 'example' - ``` - - The outermost leading and trailing chars argument values are stripped from the string. Characters are removed from the leading end until reaching a string character that is not contained in the set of characters in chars. A similar action takes place on the trailing end. For example: - - ```python - >>> comment_string = '#....... Section 3.2.1 Issue #32 .......' - >>> comment_string.strip('.#! ') - 'Section 3.2.1 Issue #32' - ``` - -- `title() -> str` - Return a titlecased version of the string where words start with an uppercase character and the remaining characters are lowercase. - - For example: - - ```python - >>> 'Hello world'.title() - 'Hello World' - ``` - - The algorithm uses a simple language-independent definition of a word as groups of consecutive letters. The definition works in many contexts but it means that apostrophes in contractions and possessives form word boundaries, which may not be the desired result: - - ```python - >>> "they're bill's friends from the UK".title() - "They'Re Bill'S Friends From The Uk" - ``` - -- `upper() -> str` - Return a copy of the string with all the cased characters 4 converted to uppercase. Note that `s.upper().isupper()` might be `False` if s contains uncased characters or if the Unicode category of the resulting character(s) is not “Lu” (Letter, uppercase), but e.g., “Lt” (Letter, titlecase). -- `removeprefix(prefix: str) -> str` - If the string starts with the prefix string, return string[len(prefix):]. Otherwise, return a copy of the original string. - ```python - >>> "prefix-data".removeprefix("prefix-") - "data" - ``` -- `rermovesuffix(suffix: str) -> str` - If the string ends with the suffix string and that suffix is not empty, return string[:-len(suffix)]. Otherwise, return a copy of the original string. - ```python - >>> "data-suffix".removesuffix("-suffix") - "data" - ``` - -### List - -Lists are immutable sequences, typically used to store collections of homogeneous items (where the precise degree of similarity will vary by application). - -Lists may be constructed in several ways: - -- Using a pair of square brackets to denote the empty list: `[]` -- Using square brackets, separating items with commas: `[a]`, `[a, b, c]` -- Using a list comprehension: `[x for x in iterable]` -- Using the type constructor: list() or list(iterable) - -The constructor builds a list whose items are the same and in the same order as iterable’s items.Iterable may be either a sequence, a container that supports iteration, or an iterator object. If iterable is already a list, a copy is made and returned, similar to `iterable[:]`. For example, `list('abc')` returns `['a', 'b', 'c']` and `list([1, 2, 3])` returns `[1, 2, 3]`. If no argument is given, the constructor creates a new empty list `[]`. - -Lists implement all of the common sequence operations. - -#### Members - -- `len()` - Return the number of items in the list. - -### Common Sequence Operations - -The operations in the following table are supported by List and Dict. - -This table lists the sequence operations sorted in ascending priority. In the table, s and t are sequences of the same type, n, i, j and k are integers and x is an arbitrary object that meets any type and value restrictions imposed by s. - -The `in` and `not in` operations have the same priorities as the comparison operations. The + -(concatenation) and \* (repetition) operations have the same priority as the corresponding numeric operations. - -| Operation | Result | Notes | -| ------------ | -------------------------------------------------- | ----- | -| `x in s` | `True` if an item of s is equal to x, else `False` | #1 | -| `x not in s` | `False` if an item of s is equal to x, else `True` | #1 | -| `s + t` | the concatenation of s and t | #5 | -| `s[i]` | ith item of s, origin 0 | #2 | -| `s[i:j]` | slice of s from i to j | #2 #3 | -| `s[i:j:k]` | slice of s from i to j with step k | #2 #4 | -| `min(s)` | smallest item of s | | -| `max(s)` | largest item of s | | - -Notes: - -- 1. While the in and not in operations are used only for simple containment testing in the - general case, some specialized sequences (str) also use them for subsequence testing: - -```python ->>> "gg" in "eggs" -True -``` - -- 2. If i or j is negative, the index is relative to the end of sequence s: `s.len() + i` or `s.len() + j` is substituted. But note that -0 is still 0. -- 3. The slice of s from i to j is defined as the sequence of items with index k such that `i <= k < j`. If i or j is greater than `s.len()`, use `s.len()`. If i is omitted or None, use 0. If j is omitted or None, use `s.len()`. If i is greater than or equal to j, the slice is empty. -- 4. The slice of s from i to j with step k is defined as the sequence of items with index `x = i + n*k` such that `0 <= n < (j-i)/k`. In other words, the indices are `i`, `i+k`, `i+2*k`, `i+3*k` and so on, stopping when j is reached (but never including j). When k is positive, i and j are reduced to s.len() if they are greater. When k is negative, i and j are reduced to s.len() - - - If they are greater. If i or j are omitted or None, they become “end” values (which end depends on the sign of k). Note, k cannot be zero. If k is None, it is treated like 1. - -- 5. Concatenating immutable sequences always results in a new object. This means that building up a sequence by repeated concatenation will have a quadratic runtime cost in the total sequence length. To get a linear runtime cost, you must switch to one of the alternatives below: - - - if concatenating str objects, you can build a list and use `str.join()` at the end - -- 6. `index` raises `ValueError` when x is not found in s. Not all implementations support passing the additional arguments i and j. These arguments allow efficient searching of subsections of the sequence. Passing the extra arguments is roughly equivalent to using `s[i:j].index(x)`, only without copying any data and with the returned index being relative to the start of the sequence rather than the start of the slice. - -### Dict - -Dict is an immutable mapping object maps hashable values to arbitrary objects. A dictionary’s keys are almost arbitrary values. Values that are not hashable, that is, values containing lists, dictionaries may not be used as keys. Numeric types used for keys obey the normal rules for numeric comparison: if two numbers compare equal (such as 1 and 1.0) then they can be used interchangeably to index the same dictionary entry. (Note however, that since computers store floating-point numbers as approximations it is usually unwise to use them as dictionary keys.) Dict is ordered. The order of the keys is the order of their declaration. - -Dictionaries can be created by placing a comma-separated list of keys: value pairs within braces, for example: `{'jack': 4098, 'sjoerd': 4127}` or `{4098: 'jack', 4127: 'sjoerd'}`, by the dict constructor, or list/dict comprehension. - -- `dict(obj)` - -Return a new dictionary initialized from an optional positional argument and a possibly empty set of keyword arguments.If no positional argument is given, an empty dictionary is created. If a positional argument is given and it is a mapping object, a dictionary is created with the same key-value pairs as the mapping object. Otherwise, the positional argument must be an iterable object. Each item in the iterable must itself be an iterable with exactly two objects. The first object of each item becomes a key in the new dictionary, and the second object the corresponding value. If a key occurs more than once, the last value for that key becomes the corresponding value in the new dictionary. If keyword arguments are given, the keyword arguments and their values are added to the dictionary created from the positional argument. If a key being added is already present, the value from the keyword argument replaces the value from the positional argument. To illustrate, the following examples all return a dictionary equal to `{"one": 1, "two": 2, "three": 3}`: - -```python ->>> a = {'two': 2, 'one': 1, 'three': 3} ->>> b = {'one': 1, 'two': 2, 'three': 3} ->>> c = {'three': 3, 'one': 1, 'two': 2} ->>> a == b == c -True -``` - -Providing keyword arguments as in the first example only works for keys that are valid KCL identifiers. Otherwise, any valid keys can be used. - -In the dict comprehension, key/value pairs yielded by the generator expression is set in the dictionary in the order yielded: the first occurrence of the key determines its insertion order, and the last determines the value associated to it. - -```python ->>> {str(i): 2 * i for i in range(3)} -{"0": 0, "1": 2, "2": 4} - ->>> a = {"one": 1, "two": 2, "three": 3} ->>> b = {k: v for k, v in a if v >= 2} -{two: 2, three: 3} -``` - -#### Operations & Members - -These are the operations that dictionaries the support. - -- `list(d)` - Return a list of all the keys used in the dictionary d. -- `len()` - Return the number of items in the dictionary d. -- `d[key]` - Return the item of d with key. Return Undefined if key is not in the map. -- `key in d` - Return True if d has a key, else False. -- `key not in d` - Equivalent to not key in d. -- `d.key` - Return the item of d with key. Return Undefined if key is not in the map. - -Dictionaries compare equal if and only if they have the same (key, value) pairs(keys' ordering matters). Order comparisons (‘<’, ‘<=’, ‘>=’, ‘>’) raise TypeError. - -```python ->>> d = {"one": 1, "two": 2, "three": 3, "four": 4} ->>> d -{'one': 1, 'two': 2, 'three': 3, 'four': 4} ->>> list(d) -['one', 'two', 'three', 'four'] -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/expressions.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/expressions.md deleted file mode 100644 index b52c10f3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/expressions.md +++ /dev/null @@ -1,915 +0,0 @@ ---- -title: "Expressions" -linkTitle: "Expressions" -type: "docs" -weight: 2 -description: Expressions ---- - -## Syntax - -In KCL, an expression specifies the computation of a value. - -The syntax is the following: - -```bnf -expression: test ("," test)* -test: if_expr | primary_expr | unary_expr | binary_expr -``` - -KCL expressions consist of `if` expression, `primary` expression, `unary` expression, and `binary` expression. - -### Primary Expressions - -Primary expressions are the operands for unary and binary expressions. - -Operands are self-delimiting. An **operand** may be followed by any number of selector dot, a function call, or slice suffixes, to form a primary expression. The grammar uses `expression`, where a multiple-component expression is allowed, and `test` where it accepts an expression of only a single component. - -Syntax: - -```bnf -primary_expr: operand | primary_expr select_suffix | primary_expr call_suffix | primary_expr subscript_suffix -``` - -### Operands - -Operand denotes the elementary value in an expression. An operand may be an identifier, a literal, or a parenthesized expression. - -Syntax: - -```bnf -operand: operand_name | number | string | "True" | "False" | "None" | "Undefined" | list_expr | list_comp | dict_expr | dict_comp | "(" expression ")" -operand_name: identifier | qualified_identifier -``` - -### Identifiers - -In KCL, an identifier is a name, may with selectors, that identifies a value. - -Syntax: - -```bnf -identifier: NAME -``` - -Examples: - -```python -x -a -_b -``` - -Use the `$` character prefix to define keyword identifiers. - -```python -$if = 1 -$else = "s" -``` - -Please note: whether the non-keyword identifier is prefixed with `$` has the same effect. - -```python -_a = 1 -$_a = 2 # equal to `_a = 2` -``` - -To simplify the definition of the qualified identifier, such as 'pkg.type', we additionally define `qualified_identifier`: - -Syntax: - -```bnf -qualified_identifier: identifier "." identifier -``` - -Examples: - -```python -pkg.a -``` - -The package name in qualified_identifier must be imported. - -### Basic Literals - -Basic literals supported in KCL are `int`, `float`, `string` and `bool` including `True` and `False`. Evaluation of basic literal yields a value of the given type with the given value. - -Syntax: - -```bnf -operand: number | string | "True" | "False" | "None" | "Undefined" -``` - -Examples: - -```python -1 -2.3 -"abc" -True -False -None -Undefined -``` - -See more details about **data type** spec. - -### Parenthesized Expressions - -An expression enclosed in parentheses yields the result of that expression. - -Syntax: - -```bnf -operand: '(' expression ')' -``` - -Examples: - -```python -x = (1 + 2) * (3 + 4) # 21 -``` - -### Dictionary Expressions - -A dictionary expression is a comma-separated immutable list of colon-separated key/value expression pairs, enclosed in curly brackets, and it yields a new dictionary object. An optional comma may follow the final pair. - -```bnf -config_expr: '{' config_entries '}' -config_entries: config_entry [config_entry*] -config_comp: '{' (config_entry comp_clause+) '}' -config_entry: expr (':' | '=' | '+=') expr | double_star_expr | if_entry -double_star_expr: "**" expression -if_entry: - 'if' expr ';' if_entry_exec_block - ('elif' expr ':' if_entry_exec_block)* - ('else' ':' if_entry_exec_block)? -NEWLINE: '/r?/n' -``` - -Examples: - -```python -{} -{"one": 1} -{"one": 1, "two": 2} -``` - -The key and value expressions are evaluated in left-to-right order. Evaluation fails if the same key is used multiple times. - -Only hashable values may be used as the keys of a dictionary. This includes all built-in types except dictionaries, and lists. - -We can ignore the comma `,` at the end of the line for writing dict key-value pairs in multiple lines: - -```python -data = { - "key1" = "value1" # Ignore the comma ',' at the end of line - "key2" = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -We can ignore the key quotation marks when we writing simple literals on the key. - -```python -data = { - key1 = "value1" # Ignore the comma ',' at the end of line - key2 = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -In addition, the **config selector expressions** can be used to init a schema instance. - -```python -person = { - base.count = 2 - base.value = "value" - labels.key = "value" -} # {"base": {"count": 2, "value": "value"}, "labels": {"key": "value"}} -``` - -We can **merge** dict using the dict unpacking operator `**` like this: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = {**_part1, **_part2} # {"a: "b", "c": "d"} -``` - -We can use `if expressions` to dynamically add elements to the dict element, elements that meet the conditions are added to the dict, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = { - key1 = "value1" - if a == 1: key2 = "value2" - if a > 0: key3 = "value3" - if a < 0: key4 = "value4" -} # {"key1": "value1", "key2": "value2", "key3": "value3"} -``` - -```python -a = 1 # 1 -data1 = { - key1 = "value1" - if a == 1: - key2 = "value2" - elif a > 0: - key3 = "value3" - else: - key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -data2 = { - key1 = "value1" - if a == 1: key2 = "value2" - elif a > 0: key3 = "value3" - else: key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -``` - -### List Expressions - -A list expression is a comma-separated immutable list of element expressions, enclosed in square brackets, and it yields a new list. An optional comma may follow the last element expression. - -```bnf -list_expr: '[' [list_item [',']] ']' -list_item: test | "*" primary_expr | if_expr -``` - -Element expressions are evaluated in left-to-right order. - -Examples: - -```python -[] # [], empty list -[1] # [1], a 1-element list -[1, 2, 3] # [1, 2, 3], a 3-element list -``` - -We can use `if expressions` to dynamically add elements to the list element, elements that meet the conditions are added to the list, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = [ - 1 - if a == 1: 2 - if a > 0: 3 - if a < 0: 4 -] # [1, 2, 3] -``` - -```python -a = 1 # 1 -data1 = [ - 1 - if a == 1: - 2 - elif a == 2: - 3 - else: - 3 -] # [1, 2] -data2 = [ - 1 - if a == 1: 2 - elif a == 2: 2 - else: 3 -] # [1, 2] -``` - -### Comprehensions - -A comprehension constructs a new list or dictionary value by looping over one or more iterables and evaluating a body expression that produces successive elements of the result. - -Syntax: - -```bnf -list_comp: '[' list_item comp_clause+ ']' . -dict_comp: '{' entry comp_clause+ '}' . - -comp_clause: 'for' loop_variables [","] 'in' test ['if' test] -loop_variables: primary_expr (',' primary_expr)* -``` - -A list comprehension consists of a single expression followed by one or more clauses, the first of which must be a `for` clause. Each `for` clause resembles a `for` statement, and specifies an iterable operand and a set of variables to be assigned by successive values of the iterable. An `if` cause resembles an `if` statement, and specifies a condition that must be met for the body expression to be evaluated. A sequence of `for` and `if` clauses acts like a nested sequence of `for` and `if` statements. - -Examples: - -```python -[x * x for x in range(5)] # [0, 1, 4, 9, 16] -[x * x for x in range(5) if x % 2 == 0] # [0, 4, 16] -[[x, y] for x in range(5) \ - if x % 2 == 0 \ - for y in range(5) \ - if y > x] # [[0, 1], [0, 2], [0, 3], [0, 4], [2, 3], [2, 4]] -``` - -Besides, we can use two variables in the list comprehension, the first variable denotes the list index and the second variable denotes the list item. - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use `_` to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -A dict comprehension resembles a list comprehension, but its body is a pair of expressions, key: value, separated by a colon, and its result is a dictionary containing the key/value pairs for which the body expression was evaluated. Evaluation fails if the value of any key is un-hashable. - -Besides, we can use two variables in the dict comprehension, the first variable denotes the dict key and the second variable denotes the dict value of the key. - -```python -data = {"key1" = "value1", "key2" = "value2"} -# Single variable loop -dataKeys1 = {k: k for k in data} # {"key1": "key1", "key2": "key2"} -dataValues1 = {k: data[k] for k in data} # {"key1": "value1", "key2": "value2"} -# Double variable loop -dataKeys2 = {k: k for k, v in data} # {"key1": "key1", "key2": "key2"} -dataValues2 = {v: v for k, v in data} # {"value1": "value1", "value2": "value2"} -dataFilter = {k: v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use `_` to ignore loop variables -dataKeys3 = {k: k for k, _ in data} # {"key1": "key1", "key2": "key2"} -dataValues3 = {v: v for _, v in data} # {"value1": "value1", "value2": "value2"} -``` - -As with a `for` loop, the loop variables may exploit compound assignment: - -```python -[x * y + z for [x, y], z in [[[2, 3], 5], [["o", 2], "!"]]] # [11, 'oo!'] -``` - -KCL does not accept an un-parenthesized list as the operand of a for clause: - -```python -[x * x for x in 1, 2, 3] # parse error: unexpected comma -``` - -Comprehensions defines a new lexical block, so assignments to loop variables have no effect on variables of the same name in an enclosing block: - -```python -x = 1 -_ = [x for x in [2]] # new variable x is local to the comprehension -print(x) # 1 -``` - -The operand of a comprehension's first clause (always a for) is resolved in the lexical block enclosing the comprehension. In the examples below, identifiers referring to the outer variable named x have been distinguished by subscript. - -```python -x0 = [1, 2, 3] -[x * x for x in x0] # [1, 4, 9] -[x * x for x in x0 if x % 2 == 0] # [4] -``` - -All subsequent for and if expressions are resolved within the comprehension's lexical block, as in this rather obscure example: - -```python -x0 = [[1, 2], [3, 4], [5, 6]] -[x * x for x in x0 for x in x if x % 2 == 0] # [4, 16, 36] -``` - -which would be more clearly rewritten as: - -```python -x = [[1, 2], [3, 4], [5, 6]] -[z * z for y in x for z in y if z % 2 == 0] # [4, 16, 36] -``` - -### Conditional Expressions - -A conditional expression has the form `a if cond else b`. It first evaluates the condition `cond`. If it's true, it evaluates `a` and yields its value; otherwise it yields the value of `b`. - -Syntax: - -```bnf -if_expr: test "if" test "else" test -``` - -Examples: - -```python -x = True if enabled else False # if enabled is -``` - -### Unary Expressions - -In KCL, supported unary operators are `+`, `-`, `~`, and `not`. - -Syntax: - -```bnf -unary_expr: ("+" | "-" | "~") primary_expr - | "not" test -``` - -Usage: - -```bnf -+ number unary positive (int, float) -- number unary negation (int, float) -~ number unary bitwise inversion (int) -not x logical negation (any type) -``` - -The `+` and `-` operators may be applied to any number (int or float) and return the number. -The `not` operator returns the negation of the truth value of its operand. - -Examples: - -```python -~1 # -2 -~-1 # 0 -~0 # -1 -not True # False -not 0 # True -``` - -### Binary Expressions - -In KCL, binary expressions consist of `comparisons`, `logical operations`, `arithmetic operations` and `membership tests`. - -Syntax: - -```bnf -binary_expr: test bin_op test -bin_op: 'or' - | 'and' - | '==' | '!=' | '<' | '>' | '<=' | '>=' - | 'in' | 'not' 'in' - | '|' - | '^' - | '&' - | '-' | '+' - | '*' | '%' | '/' | '//' - | '<<' | '>>' -``` - -#### Logical Operations - -The `or` and `and` operators yield the logical disjunction and conjunction of their arguments, which need not be Booleans. - -The expression `x or y` yields the value of `x` if its truth value is `True`, or the value of `y` otherwise. - -```python -False or False # False -False or True # True -True or True # True -1 or "hello" # 1 -``` - -Similarly, `x` and `y` yields the value of `x` if its truth value is `False`, or the value of `y` otherwise. - -```python -False and False # False -False and True # False -True and True # True -1 and "hello" # "hello" -``` - -These operators use "short circuit" evaluation, so the second expression is not evaluated if the value of the first expression has already determined the result, allowing constructions like these: - -```python -x and x[0] == 1 # x[0] is not evaluated if x is empty -len(x) == 0 or x[0] == "" -not x or not x[0] -``` - -#### Comparisons - -The `==` operator reports whether its operands are equal; the `!=` operator is its negation. - -The operators `<`, `>`, `<=`, and `>=` perform an ordered comparison of their operands. It is an error to apply these operators to operands of unequal type, unless one of the operands is an `int` and the other is a `float`. Of the built-in types, only the following support ordered comparison, using the ordering relation shown: - -```bnf -NoneType # None <= None -bool # False < True -int # mathematical -float # as defined by IEEE 754 -string # lexicographical -list # lexicographical -``` - -Comparison of floating-point values follows the IEEE 754 standard, which breaks several mathematical identities. For example, if `x` is a `NaN` value, the comparisons `x < y`, `x == y`, and `x > y` all yield false for all values of `y`. - -The remaining built-in types support only equality comparisons. Values of type `dict` and `schema` compare equal if their elements compare equal, and values of type function or `builtin_function_or_method` are equal only to themselves. - -```bnf -dict # equal contents -schema # equal exported-attributes -function # identity -builtin_function_or_method # identity -``` - -#### Arithmetic Operations - -The following table summarizes the binary arithmetic operations available for built-in types: - -```bnf -Arithmetic (int or float; result has type float unless both operands have type int) - number + number # addition - number - number # subtraction - number * number # multiplication - number / number # real division (result is always a float) - number // number # floored division - number % number # remainder of floored division - number ^ number # bitwise XOR - number << number # bitwise left shift - number >> number # bitwise right shift - -Concatenation - string + string - list + list - -Repetition (string/list) - int * sequence - sequence * int - -Union - int | int - list | list - dict | dict - schema | schema - schema | dict -basictype | basictype -``` - -The operands of the arithmetic operators `+`, `-`, `*`, `//`, and `%` must both be numbers (`int` or `float`) but need not have the same type. The type of the result has type `int` only if both operands have that type. The result of real division / always has type `float`. - -The `+` operator may be applied to non-numeric operands of the same type, such as two lists, or two strings, in which case it computes the concatenation of the two operands and yields a new value of the same type. - -```python -"Hello, " + "world" # "Hello, world" -[1, 2] + [3, 4] # [1, 2, 3, 4] -``` - -The `*` operator may be applied to an integer n and a value of type `string`, `list`, in which case it yields a new value of the same sequence type consisting of n repetitions of the original sequence. The order of the operands is immaterial. Negative values of n behave like zero. - -```python -'mur' * 2 # 'murmur' -3 * range(3) # [0, 1, 2, 0, 1, 2, 0, 1, 2] -``` - -The `&` operator requires two operands of the same type, such as `int`. For integers, it yields the bitwise intersection (AND) of its operands. - -The `|` operator likewise computes bitwise, unions basic types and unions collection and schema data, such as **list**, **dict** and **schema**. - -Computing bitwise examples: - -```python -0x12345678 | 0xFF # 0x123456FF -``` - -Unioning basic types examples: - -```python -schema x: - a: int | str # attribute a could be a int or string -``` - -A union type is used to define a schema attribute type. See more details in **schema** spec. -Supported types in a union type are `int`, `str`, `float`, `bool`, `list` and `dict`. - -Unioning collection and schema data: - -- Unioning List. Overwrite the list expression on the right side of the operator `|` to the list variable on the left side of the operator one by one according to the **index**. - -```python -_a = [1, 2, 3] -_b = [4, 5, 6, 7] -x = _a | _b # [4, 5, 6, 7] 4 -> 1; 5 -> 2; 6 -> 3; 7 -> None -``` - -Unioning to the specific index or all elements is still under discussion. - -- Unioning Dict. Union the dict expression on the right side of the operator `|` one by one to the dict variable on the left side of the operator according to the **key** - -```python -_a = {key1 = "value1"} -_b = {key1 = "overwrite", key2 = "value2"} -_c = _a | _b # {"key1": "overwrite", "key2": "value2"} -``` - -The union of collection and schema is a new one whose attributes are unioning b to a, preserving the order of the attributes of the operands, left before right. - -Unioning to the specific key or all keys is still under discussion. - -- Unioning Schema. - -The union operation for schema is similar to dict. - -Schema union could be done as: - -```bnf -schema Person: - firstName: str - lastName: str - -_a = Person { - firstName = "John" -} -_b = {lastName = "Doe"} -_a = _a | _b # {"firstName": "John", "lastName": "Doe"} -``` - -Unioning to a specific attribute is still under discussion. Unioning to all attributes is not applicable to schema instances. - -See **selector expression** in **expression** spec for more details. - -The `^` operator accepts operands of `int`. For integers, it yields the bitwise XOR (exclusive OR) of its operands. - -The `<<` and `>>` operators require operands of `int` type both. They shift the first operand to the left or right by the number of bits given by the second operand. It is a dynamic error if the second operand is negative. Implementations may impose a limit on the second operand of a left shift. - -```python -0x12345678 & 0xFF # 0x00000078 -0b01011101 ^ 0b110101101 # 0b111110000 -0b01011101 >> 2 # 0b010111 -0b01011101 << 2 # 0b0101110100 -``` - -#### Membership Tests - -Usage: - -```bnf - any in sequence (list, dict, schema, string) - any not in sequence -``` - -The `in` operator reports whether its first operand is a member of its second operand, which must be a list, dict, schema, or string. The `not in` operator is its negation. Both return a Boolean. - -The meaning of membership varies by the type of the second operand: the members of a list are its elements; the members of a dict are its keys; the members of a string are all its substrings. - -```python -1 in [1, 2, 3] # True - -d = {"one" = 1, "two" = 2} -"one" in d # True -"three" in d # False -1 in d # False -[] in d # False - -"nasty" in "dynasty" # True -"a" in "banana" # True -"f" not in "way" # True - -d = data {one = 1, two = 2} # data is a schema with attributes one and two -"one" in d # True -"three" in d # False -``` - -### Function Invocations - -KCL allows calling built-in functions and functions from built-in and system modules. Whether KCL allows defining new functions is under discussion. - -Syntax: - -```bnf -call_suffix: "(" [arguments [","]] ")" -arguments: argument ("," argument)* -argument: test | identifier "=" test | "*" test | "**" test -``` - -To call a function, the basic way is shown as the following code excerpt: - -```python -print("An argument") - -import math -# 2 powers 3 is 8. -a = math.pow(2, 3) -``` - -As you can see, arguments are separated with `,`. Arguments can only be passed in this way. KCL supports positional arguments and key-value arguments. - -Note that: - -- Some functions have parameters with default values. -- Some functions accept variadic arguments. - -When an argument is not supplied for a parameter without a default value, -an error will be reported. - -### Selector Expressions - -A selector expression selects the attribute or method of the value. - -#### Select Attributes - -Syntax: - -```bnf -select_suffix: ["?"] "." identifier -``` - -KCL provides a wealth of ways to identify or filter attributes. - -x.y - -- schema: it denotes the attribute value of a schema `x` identified by `y` -- package: it denotes the identifier of a package `x` identified by `y` - -Examples: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -name = person.name # "Alice" -age = person.age # 18 -``` - -x?.y - -If the x if None/Undefined or empty(empty list or dict), just return None, otherwise behave as x.y. - -Examples - -```python -noneData = None -data?.name # None - -emptyDict = {} -emptyDict?.name # None - -emptyList = [] -emptyList?[0] # None -``` - -As a supplementary of the `selector` expression in KCL code, the KCL compiler needs to provide corresponding identifying and filtering features through the command line and api form. - -#### Select Methods - -Syntax: - -```bnf -select_suffix: "." identifier -``` - -A `identifier` identifies method belongs to the built-in types `string`, `list`, `dict`, and `schema`. - -- A selector expression fails if the value does not have an attribute of the specified name. -- A selector expression that selects a method typically appears within a call expression, as in these examples: - -Examples: - -```python -["able", "baker", "charlie"].index("baker") # 1 -"banana".count("a") # 3 -"banana".reverse() # error: string has no .reverse field or method -Person.instances() # all instances of schema Person -``` - -But when not called immediately, the selector expression evaluates to a bound method, that is, a method coupled to a specific receiver value. A bound method can be called like an ordinary function, without a receiver argument: - -```bnf -f = "banana".count -f # -f("a") # 3 -f("n") # 2 -``` - -### Index Expressions - -An index expression `a[i]` yields the `i` th element of an indexable type such as a string or list. The index `i` must be an `int` value in the range `-n` ≤ `i` < `n`, where `n` is `len(a)`; any other index results in an error. - -Syntax: - -```bnf -subscript_suffix: "[" [test] "]" -``` - -A valid negative index `i` behaves like the non-negative index `n+i`, allowing for convenient indexing relative to the end of the sequence. - -```python -"abc"[0] # "a" -"abc"[1] # "b" -"abc"[-1] # "c" - -["zero", "one", "two"][0] # "zero" -["zero", "one", "two"][1] # "one" -["zero", "one", "two"][-1] # "two" -``` - -An index expression `d[key]` may also be applied to a dictionary `d`, to obtain the value associated with the specified key. It returns `Undefined` if the dictionary contains no such key. - -An index expression appearing on the left side of an assignment causes the specified list or dictionary element to be updated: - -```python -a = range(3) # a == [0, 1, 2] -b = a[2] # 2 - - -``` - -It is a dynamic error to attempt to update an element of an immutable type, such as a list or string, or a frozen value of a mutable type. - -### Slice Expressions - -A slice expression `a[start:stop:stride]` yields a new value containing a sub-sequence of `a`, which must be a string, or list. - -```bnf -subscript_suffix: "[" [test] [":" [test] [":" [test]]] "]" -``` - -Each of the `start`, `stop`, and `stride` operands is optional; if present, and not `None`, each must be an integer. -The `stride` value defaults to 1. If the stride is not specified, the colon preceding it may be omitted too. It is an error to specify a stride of zero. - -Conceptually, these operands specify a sequence of values `i` starting at start and successively adding `stride` until `i` reaches or passes `stop`. The result consists of the concatenation of values of `a[i]` for which `i` is valid.` - -The effective start and stop indices are computed from the three operands as follows. Let `n` be the length of the sequence. - -**If the stride is positive**: If the `start` operand was omitted, it defaults to -infinity. If the `end` operand was omitted, it defaults to +infinity. For either operand, if a negative value was supplied, `n` is added to it. The `start` and `end` values are then "clamped" to the nearest value in the range 0 to `n`, inclusive. - -**If the stride is negative**: If the `start` operand was omitted, it defaults to +infinity. If the `end` operand was omitted, it defaults to -infinity. For either operand, if a negative value was supplied, `n` is added to it. The `start` and `end` values are then "clamped" to the nearest value in the range -1 to `n`-1, inclusive. - -```python -"abc"[1:] # "bc" (remove first element) -"abc"[:-1] # "ab" (remove last element) -"abc"[1:-1] # "b" (remove first and last element) -"banana"[1::2] # "aaa" (select alternate elements starting at index 1) -"banana"[4::-2] # "nnb" (select alternate elements in reverse, starting at index 4) -``` - -It's not allowed to define a slice expression as a left value in KCL. -Cause list and string are immutable, re-slicing can directly operate to operand to ensure better performance. - -#### Quantifier Expressions - -Quantifier expressions act on collection: list or dict, generally used to obtain a certain result after processing the collection, mainly in the following four forms: - -```bnf -quant_expr: quant_op [ identifier ',' ] identifier 'in' quant_target '{' expr ['if' expr] '}' -quant_target: string | identifier | list_expr |list_comp | dict_expr | dict_comp -quant_op: 'all' | 'any' | 'filter' | 'map' -``` - -- **all** - - Used to detect that all elements in the collection satisfy the given logical expression, and return a boolean value as the result. - - Only when all elements in the collection satisfy the expression true, the `all` expression is true, otherwise it is false. - - If the original collection is empty, return true. - - Supports short-circuiting of logical expressions during expression execution. -- **any** - - Used to detect that at least one element in the collection satisfies the given logical expression, and returns a boolean value as the result. - - When at least one element in the collection satisfies the expression true, the `any` expression is true, otherwise it is false. - - If the original collection is empty, return false. - - Supports short-circuiting of logical expressions during expression execution. -- **map** - - Generate a new **list** by mapping the elements in the original collection. - - The length of the new list is exactly the same as the original collection. -- **filter** - - By logically judging and filtering the elements in the original collection, and returning the filtered sub-collection. - - Only when the element judges the expression to be true, it is added to the sub-collection. - - The type (list, dict and schema) of the new collection is exactly the same as the original collection, and the length range is `[0, len(original-collection)]`. - -**all** and **any** expression sample codes: - -```python -schema Config: - volumes: [{str:}] - services: [{str:}] - - check: - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - }, "invalid cluster ip" - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } -``` - -**map** and **filter** expression sample codes: - -```python -a = map e in [{name = "1", value = 1}, {name = "2", value = 2}] { - {name = e.name, value = int(e.value) ** 2} -} # [{"name": "1", value: 1}, {"name": "2", "value": 4}] - -b = map k, v in {a = "foo", b = "bar"} { v } # ["foo", "bar"] - -c = filter e in [{name = "1", value = 1}, {name = "2", value = 2}] { - int(e.value) > 1 -} # [{"name": "2", "value": 2}] - -d = filter _, v in {a = "foo", b = "bar"} { - v == "foo" -} # {"a": "foo"} -``` - -Please pay attention to distinguish the difference between any expression and any type. When `any` is used in type annotations, it means that the value of the variable is arbitrary, while the any expression means that one of the elements in a set satisfies the condition. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/index.md deleted file mode 100644 index c3ecc162..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/index.md +++ /dev/null @@ -1 +0,0 @@ -# KCL 语言规范 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/lexical.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/lexical.md deleted file mode 100644 index 773efecb..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/lexical.md +++ /dev/null @@ -1,213 +0,0 @@ ---- -title: "Lexical" -linkTitle: "Lexical" -type: "docs" -weight: 2 -description: Lexical ---- - -## Lexical Conventions - -This chapter covers the KCL lexical conventions including grammar notation, lines, comments and tokens. - -## Grammar Notation - -The syntax is specified using Extended Backus-Naur Form (EBNF), porting to lark parser ([https://github.com/lark-parser/lark](https://github.com/lark-parser/lark)). - -``` -- name grammar production -- NAME lexical token -- "x" lexical token -- () grouping -- | alternation -- [] option (0 or 1 times) -- ? option (0 or 1 times) -- * repetition (0 to n times) -- + repetition (1 to n times) -``` - -## Source File Encoding - -KCL source code is Unicode text encoded in **UTF-8**. - -The following are basic Unicode elements, which will be used in literal notations. - -``` -newline ::= U+000A -quota ::= singlequote | doublequote -singlequote ::= U+0027 -doublequote ::= U+0022 -source character ::= Unicode code point -``` - -The form a...b in literal notations represents the set of characters from a through b. - -## Line Structure - -The line structure of KCL programs is equivalent to that of Python. - -A KCL program is divided into a number of logical lines. Each logical line consists of one or more physical lines. - -A token named `NEWLINE` is used to divide logical lines. - -A physical line is a sequence of characters end with a line termination sequence, which can be the ASCII LF (linefeed) character, the ASCII sequence CR LF (return followed by linefeed), or the ASCII CR (return) character. - -### Explicit Line Joining - -To join multiple physical lines into one logical line, the `\` character can be used. The character should be the last none-space character in each physical line except the very last line. - -> **note** -> -> Any character except the ASCII space, tab (`\t`) and formfeed (`\f`) is considered a none-space character. - -- A line ending in a backslash cannot carry a comment (, which will be introduced shortly afterwards). -- A backslash does not continue a comment. -- A backslash does not continue a token except for string literals (i.e., tokens other than string literals cannot be split across physical lines using a backslash). -- A backslash is illegal elsewhere on a line outside a string literal. - -### Implicit Line Joining - -Expressions in parentheses, square brackets or curly braces can be split over more than one physical line without using backslashes. - -- Implicitly continued lines can carry comments. -- The indentation of the continuation lines is not important. -- Blank continuation lines are allowed. -- There is no `NEWLINE` token between implicit continuation lines. -- Implicitly continued lines can also occur within triple-quoted strings (see below); in that case they cannot carry comments. - -### Blank Lines - -### Indentation - -### Comments - -Starting with a `#` character that is not part of a string literal is a comment. A comment ends at the end of the physical line. - -A comment signifies the end of the logical line unless the implicit line joining rules are invoked. - -Comments are ignored by the syntax. - -### Identifiers and Keywords - -Identifiers (also referred to as names) are described by the following lexical definitions. - -Within the ASCII range (from `U+0001` to `U+007F`), the valid characters for identifiers are the uppercase and lowercase letters `A` through `Z`, the underscore `_` and, except for the first character, the digits `0` through `9`. - -Identifiers are unlimited in length. The case is significant. - -### Keywords - -The following identifiers are used as reserved words, or keywords of the language, and cannot be used as ordinary identifiers. They must be spelled exactly as written here: - -```python -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -The following tokens are not used, but they are reserved as possible future keywords: - -```python -pass return validate rule flow -def del raise except try -finally while from with yield -global nonlocal struct class final -``` - -### Literals - -Literals are notations for constant values of some built-in types. - -### String Literals - -String literals are described by the following lexical definitions: - -``` -stringliteral ::= [stringprefix](shortstring | longstring) -stringprefix ::= "r" | "R" -shortstring ::= "'" shortstringitem* "'" | '"' shortstringitem* '"' -longstring ::= "'''" longstringitem* "'''" | '"""' longstringitem* '"""' -shortstringitem ::= shortstringchar | stringescapeseq -longstringitem ::= longstringchar | stringescapeseq -shortstringchar ::= -longstringchar ::= -stringescapeseq ::= "\" -``` - -Multiple adjacent string or bytes literals (delimited by whitespace),possibly using different quoting conventions, are allowed, and their meaning is the same as their concatenation. - -### Numeric Literals - -There are two types of numeric literals: integers and floating-point numbers. - -Integer literals are described by the following lexical definitions: - -``` -integer ::= decinteger | bininteger | octinteger | hexinteger -decinteger ::= nonzerodigit (["_"] digit)* | "0"+ (["_"] "0")* -bininteger ::= "0" ("b" | "B") (["_"] bindigit)+ -octinteger ::= "0" ("o" | "O") (["_"] octdigit)+ -hexinteger ::= "0" ("x" | "X") (["_"] hexdigit)+ -nonzerodigit ::= "1"..."9" -digit ::= "0"..."9" -bindigit ::= "0" | "1" -octdigit ::= "0"..."7" -hexdigit ::= digit | "a"..."f" | "A"..."F" -``` - -Floating-point literals are described by the following lexical definitions: - -``` -floatnumber ::= pointfloat | exponentfloat -pointfloat ::= [digitpart] fraction | digitpart "." -exponentfloat ::= (digitpart | pointfloat) exponent -digitpart ::= digit (["_"] digit)* -fraction ::= "." digitpart -exponent ::= ("e" | "E") ["+" | "-"] digitpart -``` - -## Operators and Delimiters - -### Operators - -The following tokens are operators: - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != @ -``` - -### Delimiters - -The following tokens serve as delimiters in the grammar: - -```python -( ) [ ] { } -, : . ; = += --= *= **= /= //= %= -<<= >>= &= |= ^= -``` - -The period can also occur in floating-point literals. - -The following printing ASCII characters have special meaning as part of other tokens or are otherwise significant to the lexical analyzer: - -``` -' " # \ -``` - -The following printing ASCII characters are not used in KCL. Their occurrence outside string literals and comments is an unconditional error: - -``` -? ` -``` - -## Reference - -Since the lexical conventions of KCL is very similar to that of Python, we use the following document as the reference when writing this chapter. - -- [https://docs.python.org/3/reference/lexical_analysis.html](https://docs.python.org/3/reference/lexical_analysis.html) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/variables.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/variables.md deleted file mode 100644 index b3e1c539..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/variables.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: "Variables" -linkTitle: "Variable" -type: "docs" -weight: 2 -description: Variable ---- - -In KCL, variables can be defined using assign statements. For example, the following statement defines a variable `spam` to a string `"ham"`. - -```python -spam = "ham" -``` - -There are two types of variables, which are global variables and list comprehension local variables. - -- A global variable is defined not within any context. -- A comprehension local variable is defined inside a comprehension. - -A variable can be used after definition, until the end of the current scope. - -For a global variable, the scope is the module it is defined in. Note that a module can consists of multiple source files. - -For a list comprehension local variable, the scope is the list comprehension it is defined in. - -More information on modules, list comprehensions and scopes will be discussed in later chapters. - -## Immutability - -Global variables are immutable. In other words, once defined such a variable cannot be redefined (or, i.e., modified). - -The following code is illegal, and KCL will report an error during evaluation. - -```python -spam = "ham" -spam = "eggs" # Error: The immutability rule is violated! -``` - -- A variable starts with the `_` character is mutable. - -```python -_spam -cond = True -if cond: - _spam = "ham" -else: - _spam = "eggs" -``` - -## Variable Exporting - -As shown in the preview chapter, KCL is able to export evaluation results to the standard output according to a target data format. - -The rules are the followings: - -- Living global variables at the end of an evaluation will be dumped out. -- If the name of a variable starts with the `_` character, it will not be dumped out. - -## Uniqueness of Exported Variable Identifier - -Each exported variable identifier must be unique in its package, so that an exported variable could be located uniquely by package location path and variable identifier, such as 'a.b.c:var', in which 'a.b.c' locates a package. - -Two variable identifiers are different if: - -- they are spelled differently -- they are defined in different packages and are not compiled in a single execution - -Identifying an exported variable should be supported by the kcl compiler, which needs to provide corresponding identifying features through the command line and api form. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/types/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/types/_category_.json deleted file mode 100644 index a8f40915..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/types/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "类型系统", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/types/types.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/types/types.md deleted file mode 100644 index 182ffaf2..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/types/types.md +++ /dev/null @@ -1,1401 +0,0 @@ -# 类型系统 - -本文档描述 KCL 的类型系统,包括: - -- 类型规则 -- 类型检查 -- 类型转换 -- 类型推导 - -## 类型规则 - -### 基础定义 - -#### 断言 - -$S$ 的所有自由变量都定义在 $\Gamma$ 中 - -$$ -\Gamma \vdash S -$$ - -$\Gamma$ 是一个变量的类型声明环境(well-formed environment),如:$x_1:T_1$, ..., $x_n:T_n$ - -$S$ 的断言有三种形式: - -**环境断言** 断言表示 $\Gamma$ 是良构类型 (well-formed type) - -$$ -\Gamma \vdash ◇ -$$ - -**良构类型断言** 在环境 $\Gamma$ 下,$nat$ 是类型表达式 - -$$ -\Gamma \vdash nat -$$ - -**类型判断断言** 在环境 $\Gamma$ 下,$E$ 具有类型 $T$ - -$$ -\Gamma \vdash E: T -$$ - -#### 推理规则 - -表示法 - -$$ -\frac{\Gamma \vdash S_1, ..., \Gamma \vdash S_n}{\Gamma \vdash S} -$$ - -推理规则中的 $u$, $v$, $w$ 用于表示变量,$i$, $j$, $k$ 用于表示整数,$a$, $b$ 用于表示浮点数,$s$ 用于表示字符串,$c$ 代表常量(整数、浮点数、字符串、布尔)的字面值, $f$ 用于表示函数, $T$, $S$, $U$ 用于表示类型。 - -## 环境规则 - -Env ⌀ - -$$ -\frac{}{⌀ \vdash ◇ } -$$ - -## 类型定义 - -Type Bool - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash boolean} -$$ - -Type Int - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash integer} -$$ - -Type Float - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash float} -$$ - -Type String - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash string} -$$ - -Type Literal - -$$ -\frac{ c \in \{boolean, integer, float, string\}}{\Gamma \vdash literalof(c)} -$$ - -Type List - -$$ -\frac{\Gamma \vdash T \ T \neq Void}{\Gamma \vdash listof(T) } -$$ - -Type Dict - -$$ -\frac{\Gamma \vdash T_1 \ \Gamma \vdash T_2\ T_1 \neq Void \ \ T_2 \neq Void}{\Gamma \vdash dictof(T_k=T_1, T_v=T_2)} -$$ - -Type Struct - -$$ -\frac{\Gamma \vdash T_{1} \ ... \ \Gamma \vdash T_{n} \ \ T_i \neq Void \ K_1 \neq K_n}{\Gamma \vdash structof(K_1 : T_{1}, ... , K_n : T_{n})} -$$ - -Type Union - -$$ -\frac{\Gamma \vdash T_1 \ ... \ \Gamma \vdash T_n \ \ T_i \neq Void}{\Gamma \vdash unionof(T_1, ..., T_n)} -$$ - -Type None - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash None} -$$ - -Type Undefined - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Undefined} -$$ - -Type Void - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Void} -$$ - -Type Any - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Any} -$$ - -Type Nothing - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Nothing} -$$ - -## 类型判断规则 - -### Operand Expr - -Exp Truth - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash true: boolean} -$$ - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash false: boolean} -$$ - -Exp Int - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash int: integer} -$$ - -Exp Flt - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash flt: float} -$$ - -Exp Str - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash str: string} -$$ - -Exp None - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash none: none} -$$ - -Exp Undefined - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash undefined: undefined} -$$ - -Expr ListExp - -$$ -\frac{\Gamma \vdash E_1: T_1 \ E_2: T_2 \ ... \ E_n: T_n}{\Gamma \vdash [E_1, E_2, ..., E_n]: listof \ sup(T_1, T_2, ..., T_n)} -$$ - -Expr ListComp - -$$ -\frac{\Gamma \vdash E_1: T_1 \ \Gamma \vdash v: T \ \Gamma \vdash E_2: listof \ T \ \Gamma \vdash E_3: boolean}{\Gamma \vdash [E_1 \ for \ v \ in \ E_2 \ if \ E_3]: listof(T_1) } -$$ - -Expr DictExp - -$$ -\frac{\Gamma \vdash E_{k1}: T_{k1} \ \Gamma \vdash E_{v1}: T_{v1} \ ... \ \Gamma \vdash E_{kn}: T_{kN} \ \Gamma \vdash E_{vn}: T_{vN}}{\Gamma \vdash \{E_{k1}: E_{v1}, ..., E_{{kn}}: E_{vn}\}: dictof(T_{k}=sup(T_{k1}, T_{k2}, ... T_{kn}), \ T_{v}=sup(T_{v1}, T_{v2}, ..., T_{vn}))} -$$ - -Expr DictComp - -$$ -\frac{\Gamma \vdash E_1: T_{rki} \ \Gamma \vdash E_2: T_{rvi} \ \Gamma \vdash v_1: T_k \ \Gamma \vdash v_2: T_v \ \Gamma \vdash E_3: dictof(T_{k}, \ T_{v}) \ \Gamma \vdash E_4: boolean}{\Gamma \vdash \{E_1:E_2 \ for \ (v_1, v_2) \ in \ E_3 \ if \ E_4\}: dictof(T_{k}=sup(T_{rk1}, T_{rk2}, ..., T_{rkn}), T_{v}=sup(T_{rv1}, T_{rv2}, ..., T_{rvn})) } -$$ - -Expr StructExpr - -$$ -\frac{\Gamma \vdash E_{1}: T_{1} \ ... \ \Gamma \vdash E_{n}: T_{n} \ K_1 \neq K_n}{\Gamma \vdash \{K_{1} = E_{1}, ..., K_{{n}} = E_{n}\}: structof(K_1 : T_{1}, ... , K_n : T_{n})} -$$ - -Literal 类型是基础类型的值类型,Union 类型是类型的组合类型,Void、Any、Nothing 是特殊的类型指代,本身没有直接的值表达式对应关系。 - -### Primary Expr - -Expr Index - -$$ -\frac{\Gamma \vdash E: listof(T) \ \Gamma \vdash Index: integer}{\Gamma \vdash E[Index]: T} -$$ - -Expr Call - -$$ -\frac{\Gamma \vdash E_1: T_1 \rightarrow T_2 \ \Gamma \vdash E_2: T_1}{\Gamma \vdash E_1 \ (E_2): T_2} -$$ - -Expr List Selector - -$$ -\frac{\Gamma \vdash E: listof(T) \ \Gamma \vdash Index: integer}{\Gamma \vdash E.[Index]: T} -$$ - -Expr Dict Selector - -$$ -\frac{\Gamma \vdash E: dictof(T_k = T_1, T_v=T_2) \ \Gamma \vdash S_1: string \ ... \ \Gamma \vdash S_n: string}{\Gamma \vdash E.\{S_1, ..., S_n\}: dictof(T_k = T_1, T_v=T_2)} -$$ - -Expr Struct Selector - -$$ -\frac{\Gamma \vdash E: structof(K_1 : T_{1}, ... , K_n : T_{n}) \ \Gamma \vdash K_i: string}{\Gamma \vdash E.K_i: T_{i}} -$$ - -### Unary Expr - -Expr + - -$$ -\frac{\Gamma \vdash E: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash \ +E: T} -$$ - -Expr - - -$$ -\frac{\Gamma \vdash E: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash \ -E: T} -$$ - -Expr ~ - -$$ -\frac{\Gamma \vdash E: integer}{\Gamma \vdash \ ~E: integer} -$$ - -Expr not - -$$ -\frac{\Gamma \vdash E: boolean}{\Gamma \vdash \ not \ E: boolean} -$$ - -### Binary Expr - -算数运算符 - -Expr op, op $\in$ {-, /, %, \*\*, //} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash E_1 \ op \ E_2: T} -$$ - -Expr + - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, float, string, listof(T_1)\}}{\Gamma \vdash E_1 \ + \ E_2: T} -$$ - -Expr \* - -$$ -\frac{\Gamma \vdash E_1: T_1 \ \ \ \Gamma \vdash E_2: T_2 \ \ \ \ (T_1==T_2 \in \{integer, float\}) \ or \ (T_1 == interger \ and \ T_2 \ \in \ \{string, listof(T_3)\}) \ or \ (T_2 == interger \ and \ T_1 \ \in \ \{string, listof(T_3)\})} {\Gamma \vdash E_1 \ * \ E_2: T} -$$ - -示例 - -Expr % - -$$ -\frac{\Gamma \vdash E_1: interger \ \ \ \Gamma \vdash E_2: integer}{\Gamma \vdash E_1 \ \% \ E_2: interger} -$$ - -逻辑运算符 - -Expr op, op $\in$ \{or, and\} - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ op \ E_2: boolean} -$$ - -示例 - -Expr and - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ and \ E_2: boolean} -$$ - -比较运算符 - -Expr op, op $\in$ \{==, !=, <, >, <=, >=\} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T}{\Gamma \vdash E_1 \ op \ E_2: boolean} -$$ - -示例 - -Expr > - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ > \ E_2: boolean} -$$ - -位运算符 - -Expr op, op $\in$ {&, ^, ~, <<, >>} - -$$ -\frac{\Gamma \vdash E_1: integer \ \ \ \Gamma \vdash E_2: integer}{\Gamma \vdash E_1 \ op \ E_2: integer} -$$ - -Expr | - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, listof(T_1), dictof(T_k, T_v), structof(K_1=T_1, ..., K_n=T_n)\}}{\Gamma \vdash E_1 \ | \ E_2: T} -$$ - -成员运算符 - -Expr op, op $\in$ {in, not in} - -$$ -\frac{\Gamma \vdash E_1: string \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{dictof, structof\}}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -Expr op, op $\in$ {in, not in} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: listof(S), T \sqsubseteq S}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -身份运算符 - -Expr op $\in$ {is, is not} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -### IF Expr - -Expr If - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: T \ \ \ \Gamma \vdash E_3: T}{\Gamma \vdash if \ E_1 \ then \ E_2 \ else \ E_3: T} -$$ - -### Stmt - -Stmt If - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash S_1: Void \ \ \ \Gamma \vdash S_2: Void}{\Gamma \vdash if \ E_1 \ then \ S_1 \ else \ S_2: Void} -$$ - -Stmt Assign - -$$ -\frac{\Gamma \vdash id: T_0 \ \ \ \Gamma \vdash T_1 \ \ \ \Gamma \vdash E: T_2}{\Gamma \vdash id: T_1 \ = \ E : Void} -$$ - -Type Alias - -$$ -\frac{\Gamma \vdash id: T_0 \ \ \ \Gamma \vdash T_1}{\Gamma \vdash type \ id \ = \ T_1 : Void} -$$ - -## Union - -### Union 规则 - -List Union - -$$ -\frac{\Gamma \vdash \ listof(T) \ \ \ \Gamma \vdash \ listof(S)}{\Gamma \vdash \ listof(unionof(T, S))} -$$ - -Dict Union - -$$ -\frac{\Gamma \vdash \ dictof(T_1, T_2) \ \ \ \Gamma \vdash \ dictof(S_1, S_2)}{\Gamma \vdash \ dictof(unionof(T_1, S_1), unionof(T_2, S_2))} -$$ - -Struct Union - -给定两个结构体 $structof(K_{1}: T_{1}, ..., K_{n}: T_{n}),structof(H_{1}: S_{1}, ..., H_{m}: S_{n})$ - -定义他们的 union 类型: - -$$ -structof(J_{1}: U_{1}, ..., J_{p}: U_{n}) = structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \bigcup structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) -$$ - -例如: - -$$ -structof() \ \bigcup \ structof(H_{1}: T_{1}, ..., H_{m}: T_{n}) = structof(H_{1}: T_{1}, ..., H_{m}: T_{n}) -$$ - -$$ -structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \ \bigcup \ structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) = structof(K_1: T_1) :: (structof(K_{2}: T_{2}, ..., K_{n}: T_{n}) \ \bigcup \ structof(H_{1}: S_{1}, ..., H_{m}: S_{n})) -$$ - -其中把 "::" 表示把一个对偶加入到一个结构的操作,定义如下: - -$$ -structof(K_{1}: T_{1}) :: structof() = structof(K_{1}: T_{1}) -$$ - -$$ -structof(K_{1}: T_{1}) :: structof(K_{1}: T_{1}', ..., K_n: T_{n}) = structof(K_{1}: union\_op(T_{1}, T_{1}'), ..., K_{n}: T_{n}) -$$ - -$$ -structof(K_{1}: T_{1}) :: structof(K_{2}: T_{2}, ..., K_n: T_{n}) = structof(K_{2}: T_2) :: structof(K_{1}: T_1) :: structof(K_{3}: T_3, ..., K_{n}: T_{n}) -$$ - -基于此,两个 Struct 的 union 定义为: - -$$ -\frac{\Gamma \vdash structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \ \Gamma \vdash structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) \ structof(J_{1}: U_{1}, ..., J_{p}: U_{n}) = structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \bigcup structof(H_{1}: S_{1}, ..., H_{m}: S_{n})}{\Gamma \vdash structof(J_{1}: U_{1}, ..., J_{p}: U_{n}))} -$$ - -其中 $union\_op(T_1, T_2)$ 表示对相同 $K_i$ 的不同类型的判断操作: - -- 当 $T_1$ 与 $T_2$ 有偏序关系时, 如果 $T_1 \sqsubseteq T_2$ 时,返回 $T_2$,否则返回 $T_1$,即取最小上界 -- 当 $T_1$ 与 $T_2$ 不存在偏序关系时,有三种可选的处理逻辑: - - 结构体 union 失败,返回 type_error - - 返回后者的类型,此处为 $T_2$ - - 返回类型 $unionof(T_1, T_2)$ - -此处需要根据实际需求选择适当的处理方式。 - -结构体继承可以看做一种特殊的 union,整体逻辑与 union 相似,但在 $union\_op(T_1, T_2)$ 中对相同 $K_i$ 的不同类型的判断操作如下: - -- 当 $T_1$ 与 $T_2$ 有偏序关系且 $T_1 \sqsubseteq T_2$ 时,返回 $T_1$,即仅当 $T_1$ 是 $T_2$ 的下界时以下界 $T_1$ 为准 -- 否则返回 type_error - -通过这样的继承设计可以实现分层的、自下而上逐层收缩的类型定义。 - -## Operation - -KCL 支持对结构体属性进行如 `p op E` 形式的操作。 即对给定结构体 $A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})$, 对结构体中的路径 `p` 以 `E` 的值进行指定的操作(如 union,assign,insert 等)。 - -定义如下更新操作: - -$$ -\frac{{\Gamma\vdash A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})}  {\Gamma\vdash p \in (K_{1}, ..., K_{n})} \ {\Gamma\vdash e:T}   k \neq k_1, ..., k \neq k_n} -{ A \{p \ op \ e\}:\{K_1:T_1, ..., K_n:T_n\}∪\{p:T\}} -$$ - -即对路径 $p$ 进行操作本质上是对两个结构体的一种 union,对同名属性类型 union 时的规则根据情况而定。例如路径 $p$ 是一个可用作字段名的标识符 $p=k_1$,并且结构体 A 中字段名也是 $k_1$,它的类型为 $T_1$,并且表达式 $e$ 的类型也为 $T_1$ ,那么 - -$$ -\frac{{\Gamma\vdash A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})}  {\Gamma\vdash p = K_{1}} \ {\Gamma\vdash e:T_1}   k \neq k_1, ..., k \neq k_n} -{ A \{p \ op \ e\}:\{K_1:T_1, ..., K_n:T_n\}} -$$ - -注意: - -- 此处表达式 $e$ 的类型 $T_1$ 同原先同名属性 $K_1$ 的具有相同的类型。可根据实际情况需要适当放松,如 $e$ 的类型 $\sqsubseteq T_1$ 即可。 -- 对于多层结构体嵌套的操作,递归的使用以上规则即可。 - -## 类型偏序 - -### 基础类型 - -$$ -Type \ T \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ T -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Bool \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Int \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Float \sqsubseteq Type \ Any -$$ - -$$ -Type \ Int \sqsubseteq Type \ Float -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ String \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Literal \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ List \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Dict \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Struct \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ None \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Void \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Any -$$ - -### 字面值类型 - -$$ -Type \ Literal(Bool) \sqsubseteq Type \ Bool -$$ - -$$ -Type \ Literal(Int) \sqsubseteq Type \ Int -$$ - -$$ -Type \ Literal(Float) \sqsubseteq Type \ Float -$$ - -$$ -Type \ Literal(String) \sqsubseteq Type \ String -$$ - -### 联合类型 - -$$ -Type \ X \sqsubseteq Type \ Union(X, Y) -$$ - -### 自反 - -$$ -Type \ X \sqsubseteq Type \ X -$$ - -示例 - -$$ -Type \ Bool \sqsubseteq Type \ Bool -$$ - -$$ -Type \ Int \sqsubseteq Type \ Int -$$ - -$$ -Type \ Float \sqsubseteq Type \ Float -$$ - -$$ -Type \ String \sqsubseteq Type \ String -$$ - -$$ -Type \ List \sqsubseteq Type \ List -$$ - -$$ -Type \ Dict \sqsubseteq Type \ Dict -$$ - -$$ -Type \ Struct \sqsubseteq Type \ Struct -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Nothing -$$ - -$$ -Type \ Any \sqsubseteq Type \ Any -$$ - -$$ -Type \ Union(Type Int, Type Bool) \sqsubseteq Type \ Union(Type Int, Type Bool) -$$ - -### 传递 - -$$ -Type \ X \sqsubseteq Type \ Z \ if \ Type \ X \sqsubseteq Type \ Y \ and \ Type \ Y \sqsubseteq \ Type \ Z -$$ - -### 包含 - -$$ -Type \ List(T_1) \sqsubseteq Type \ List(T_2) \ if \ T_1 \sqsubseteq T_2 -$$ - -$$ -Type \ Dict(T_{k1}, T_{v1}) \sqsubseteq Type \ Dict(T_{k2}, T_{v2}) \ if \ T_{k1} \sqsubseteq T_{k2} \ and \ T_{v1} \sqsubseteq T_{v1} -$$ - -$$ -Type \ Structure(K_1: T_{a1}, K_2: T_{a2}, ..., K_n: T_{an}) \sqsubseteq Type \ Structure(K_1: T_{b1}, K_2: T_{b2}, ..., K_n: T_{bn}) \ if \ T_{a1} \sqsubseteq T_{b1} \ and \ T_{a2} \sqsubseteq T_{b2} \ and \ ... \ and \ T_{an} \sqsubseteq T_{bn} -$$ - -### 继承 - -$$ -Type \ Struct \ A \sqsubseteq Type \ Struct \ B \ if \ A \ inherits \ B -$$ - -### None - -$$ -Type \ None \sqsubseteq Type \ X, X \notin \{Type \ Nothing, \ Type \ Void\} -$$ - -### Undefined - -$$ -Type \ Undefined \sqsubseteq Type \ X, X \notin \{Type \ Nothing, \ Type \ Void\} -$$ - -## 相等性 - -交换律 - -$$ -Type \ Union(X, Y) == Type \ Union(Y, X) -$$ - -示例 - -$$ -Type \ Union(Int, Bool) == Type \ Union(Bool, Int) -$$ - -结合律 - -$$ -Type \ Union(Union(X, Y), Z) == Type \ Union(X, Union(Y, Z)) -$$ - -示例 - -$$ -Type \ Union(Union(Int, String), Bool) == Type \ Union(Int, Union(String, Bool)) -$$ - -幂等性 - -$$ -Type \ Union(X, X) == Type \ X -$$ - -示例 - -$$ -Type \ Union(Int, Int) == Type \ Int -$$ - -偏序推导 - -$$ -Type \ Union(X, Y) == Type \ Y \ if \ X \sqsubseteq Y -$$ - -示例 - -假设 Struct A 继承 Struct B - -$$ -Type \ Union(A, B) == Type \ B -$$ - -幂等性是偏序自反的一个特例 - -### List - -$$ -Type \ List(X) == Type \ List(Y) \ if \ X == Y -$$ - -### Dict - -$$ -Type \ Dict(T_k, T_v) == Type \ Dict(S_k, S_v) \ if \ T_k == S_k \ and \ T_v == S_v -$$ - -### Struct - -$$ -Type \ Struct(K_1: T_{1}, K_2: T_{2}, ..., K_n: T_{n}) == Type \ Struct(K_1: S_{1}, K_2: S_{2}, ..., K_n: S_{n}) \ if \ T_{1} == S_{1} \ and \ ... \ and \ T_{n} == S_{n} -$$ - -### 偏序检查 - -$$ -Type \ X == Type \ Y \ if \ Type \ X \sqsubseteq Type \ Y \ and \ Type \ Y \sqsubseteq \ Type \ X -$$ - -## 基础方法 - -- sup(t1: T, t2: T) -> T: 根据类型偏序计算两类型 t1, t2 的最小上界。需要动态创建 union type。 -- typeEqual(t1: T, t2: T) -> bool: 比较两类型 t1, t2 是否相等。 -- typeToString(t: T) -> string: 自顶向下递归解析并转化类型成对应的字符串类型。 - -### Sup Function - -- 暂不考虑类型参数,条件类型等特性 -- 使用一个有序集合存储 UnionType 的所有类型 -- 使用一个全局的 Map 根据 UnionType 的名称存储产生的所有 UnionType -- 根据偏序关系计算类型之间的包含关系 - -```go -// The Sup function returns the minimum supremum of all types in an array of types -func Sup(types: T[]) -> T { - typeOf(types, removeSubTypes=true) -} - -// Build a sup type from types [T1, T2, ... , Tn] -func typeOf(types: T[], removeSubTypes: bool = false) -> T { - assert isNotNullOrEmpty(types) - // 1. Initialize an ordered set to store the type array - typeSet: Set[T] = {} - // 2. Add the type array to the ordered set for sorting by the type id and de-duplication - addTypesToTypeSet(typeSet, types) - // 3. Remove sub types according to partial order relation rules e.g. sub schema types - if removeSubTypes { - removeSubTypes(typeSet) - } - if len(typeSet) == 1 { - // If the typeSet has only one type, return it - return typeSet[0] - } - // 4. Get or set the union type from the global union type map - id := getIdentifierFromTypeSet(typeSet) - unionType := globalUnionTypeMap.get(id) - if !unionType { - unionType = createUnionType(typeSet) // Build a new union type - globalUnionTypeMap.set(id, unionType) - } - return unionType -} - -// Add many types into the type set -func addTypesToTypeSet(typeSet: Set[T], types: T[]) -> void { - for type in types { - addTypeToTypeSet(typeSet, type) - } -} - -// Add one type into the type set -func addTypeToTypeSet(typeSet: Set[T], type: T) -> void { - if isUnion(type) { - return addTypesToTypeSet(typeSet, toUnionOf(type).types) - } - // Ignore the void type check - if !isVoid(type) { - // De-duplication according to the type of id - typeSet.add(type) - } -} - -func removeSubTypes(types: Set[T]) -> void { - for source in types { - for target in types { - if !typeEqual(source, target) { - // If the two types have an inheritance relationship, the base class is retained, or if the two types have a partial order relationship according to the relation table. - if (isPartialOrderRelatedTo(source, target)) { - types.remove(source) - } - } - } - } -} - -// isPartialOrderRelatedTo function Determine whether two types have a partial order relationship `source \sqsubseteq target` -// according to the partial order relationship table and rules -func isPartialOrderRelatedTo(source: T, target: T) -> bool { - assert isNotNullOrEmpty(source) - assert isNotNullOrEmpty(target) - if isNoneOrUndefined(source) and !isNothing(target) and !isVoid(target) { - return true - } - if isAny(target) { - return true - } - if typeEqual(source, target) { - return true - } - if isUnion(target) and source in target.types { - return true - } - // Literal Type - if (isStringLiteral(source) and isString(target)) or \ - (isBooleanLiteral(source) and isBool(target)) or \ - (isIntLiteral(source) and isInt(target)) or \ - (isFloatLiteral(source) and isFloat(target)) { - return true - } - if isInt(source) and isFloat(target) { - return true - } - if isList(source) and isList(target) { - return isPartialOrderRelatedTo(toListOf(source).eleType, toListOf(target).eleType - } - if isDict(source) and isDict(target) { - return isPartialOrderRelatedTo(toDictOf(source).keyType, toDictOf(target).keyType) and isPartialOrderRelatedTo(toDictOf(source).valueType, toDictOf(target).valueType) - } - if isStruct(source) and isStruct(target) { - if isTypeDerivedFrom(source, target) { - return true - } - // Empty Object - if len(target.keys) == 0 { - return true - } - if any([key Not in source.keys for key in target.keys]) { - return false - } - for key, sourceType in (source.keys, source.types) { - targetType = getKeyType(target, key) ? getKeyType(target, key) : anyTypeOf() - if !isPartialOrderRelatedTo(sourceType, targetType) { - return false - } - } - return true - } - return false -} -``` - -## 类型检查 - -### 类型检查器 - -类型检查器通过语法制导翻译的方式,自顶向下遍历语法树,并根据上下文有关的**定型规则**来判定程序构造是否为良类型程序。 - -类型检查器依赖类型规则,类型环境 $\Gamma$ 的信息记入符号表。对类型表达式采用抽象语法,如 listof(T)。类型检查失败时产生 type_error,并根据语法上下文产生错误信息。 - -### 基础方法 - -1. isUpperBound(t1, t2): supUnify(t1, t2) == t2 -2. supUnify(t1, t2): - -- 对于基础类型,根据偏序关系计算 sup(t1, t2) -- 对于 list、 dict、 Struct, 递归地对其中元素的类型进行 supUnify -- 不存在偏序关系时,返回 Nothing - -### 检查逻辑 - -#### Operand Expr - -$D \to id: T$ - -``` -env.addtype(id.entry, T.type) -``` - -$T \to boolean$ - -``` -T.type = boolean -``` - -$T \to integer$ - -``` -T.type = integer -``` - -$T \to float$ - -``` -T.type = float -``` - -$T \to string$ - -``` -T.type = string -``` - -$T \to c, \ c \in \{boolean, integer, float, string\}$ - -``` -T.type = literalof(c) -``` - -$T \to None$ - -``` -T.type = None -``` - -$T \to Undefined$ - -``` -T.type = Undefined -``` - -$T \to \ [T_1]$ - -``` -T.type = listof (T1.type) -``` - -$T \to { \{T_1: T_2\} }$ - -``` -T.type = dictof (T1.type: T2.type) -``` - -$T \to { \{N_1: T_1, N2: T_2, ..., N_n: T_n\} }$ - -``` -T.type = structof (N1: T1.type, N2: T2.type, ..., Nn: Tn.type) -``` - -$E \to id$ - -``` -E.type = env.lookup(id.entry) -``` - -$E \to [E_1, E_2, ..., E_n]$ - -``` -func listExpr(E) { - supe = sup([e.type for e in E]]) - E.type = listof(type) -} -``` - -$E \to [E_1 \ for \ E_2 \ in \ E_3 \ if \ E_4]$ - -``` -func listComp(E) { - if !typeEqual(E4.type, boolean) { - raise type_error - } - if !isUpperBound(listof(Any), E3.type) { - raise type_error(E) - } - if !isUpperBound(E3.type, E2.type) { - raise type_error(E) - } - E.type = listof(E1.type) -} -``` - -$E \to \{E_{k1}: E_{v1}, ..., E_{kn}: E_{vn}\}$ - -``` -func dictExpr(E) { - supk := sup([e.type for e in E.keys()]]) - supv := sup([e.type for e in E.values()]]) - E.type = dictof(supk, supv) -} -``` - -$E \to \{E_1:E_2 \ for \ (E_3, E_4) \ in \ E_5 \ if \ E_6\}$ - -``` -func dictComp(E) { - if !typeEqual(E6.type, boolean) { - raise type_error(E) - } - if !isUpperBound(dictof(Any, Any), E5.type) { - raise type_error(E) - } - if !isUpperBound(E5.type, dictof(E3.type, E4.type)) { - raise type_error(E) - } - E.type = dictof(E1.type, E2.type) -} -``` - -$E \to \{E_{k1}: E_{v1}, ..., E_{kn}: E_{vn}\}$ - -``` -func dictExpr(E) { - supk := sup(Ek1, ..., Ekn) - supv = sup(Ev1, ..., Evn) - E.type = dictof(supk, supv) -} -``` - -$E \to \{N_{1} = E_{1}, ..., N_{{n}} = E_{n}\}$ - -``` -func structExpr(E) { - Struct = structof() - for n, e in E { - Struct.add(n, e.type) - } - E.type = Struct -} -``` - -#### Primary Expr - -$E \to E_1[E_2]$ - -``` -func sliceSuffix(E) { - if !isUpperBound(listof(Any), E.E1.type) { - raise type_error(E) - } - if typeEqual(E.E2.type, integer) { - raise type_error(E) - } - E.type = E.E1.type.eleType -} -``` - -$E \to E_1(E_2)$ - -``` -func callSuffix(E) { - if !typeEqual(E.E1.type, func) { - raise type_error(E) - } - if !isUpperBound(listof(E.E1.arguType), E.E2.type) { - raise type_error(E) - } - E.type = E.E1.returnType -} -``` - -#### Unary Expr - -根据每条双目运算符的推理规则推导,以 '+' 为例 - -$E \to + E_1$ - -``` -func Plus(E) { - if !typeEqual(E.E1.type, [integer, float]) { - raise type_error(E) - } - E.type = E.E1.type -} -``` - -#### Binary Expr - -根据每条双目运算符的推理规则推导,以 '%' 为例 - -$E \to E_1 \ % \ E_2$ - -``` -func Mod(E) { - if !(typeEqual(E.E1.type, [integer, float]) && typeEqual(E.E2.type, [integer, float])) { - raise type_error(E) - } - E.type = E.E1.type -} -``` - -#### IF Binary Expr - -$E \to if E_1 \ then \ E_2 else \ E_3$ - -``` -func ifExpr(E) { - if !typeEqual(E.type, boolean) { - raise type_error(E) - } - if !typeEqual(E_2.type, E_3.type) { - raise type_error(E) - } - E.type = E_2.type -} -``` - -#### Stmt - -$S \to if \ E \ then \ S_1 \ else \ S_2$ - -``` -func ifStmt(S) { - if !typeEqual(S.E.type, boolean) { - raise type_error(E) - } - if !typeEqual(S.S1.type, S.S2.type) { - raise type_error(E) - } - S.type = S.S1.type -} -``` - -$S \to id: T = E$ - -$S \to id = T E$ - -``` -func assignStmt(S) { - tpe := env.lookup(id.entry) - if tpe != nil && tpe != S.T { - raise type_error(E) - } - if isUpperBound(tpe, E.type) { - raise type_error(E) - } - env.addtype(id.entry, T.type) -} -``` - -## 类型转换 - -### 基础定义 - -通过语法制导翻译的方式,根据运算符特征,对参与运算的值类型进行自动类型转换 - -### 转换规则 - -$E \to E_1 \ op \ E_2, , op \in \{+, -, *, /, \%, **, //\}$ - -``` -func binOp(E) { - if E.E1.type == integer and E.E2.type == integer { - E.type = integer - } else if E.E1.type == integer and E.E2.type == float { - E.type = float - } else if E.E1.type == float and E.E2.type == integer { - E.type = float - } else if E.E1.type == float and E.E2.type == float { - E.type = float - } -} -``` - -## 类型推导 - -### 基础定义 - -- 在类型信息不完全的情况下类型规则推导、重建类型 -- 自底向上推导并重建数程序中的数据结构类型,如基础类型,list, dict, Struct - -### 基础方法 - -1. typeOf(expr, subst): 输入为表达式和代换规则集合,返回 expr 的类型和新的代换规则集合 -2. unifier(t1, t2, subst, expr) 用 t1=t2 尝试代换,如果代换成功(未出现且无冲突),则将 t1=t2 加入 subst 并返回 subst。否则报错已出现或有冲突。 - -### 推导逻辑 - -$E \to id = E_1$ - -``` -func assignExpr(E, subst) { - return unifier(E.id.type, E.E_1.type, subst, E) -} -``` - -$unifier(t1, t2, subst, expr) \rightarrow subst$ - -``` -func unifier(t1, t2, subst, expr) { - t1 = applySubstToTypeEquation(t1, subst) - t2 = applySubstToTypeEquation(t2, subst) - - if t1 == t2 { - return subst - } - - if isTypeVar(t1) { - if isNoOccur(t1, t2) { - addTypeEquationToSubst(subst, t1, t2) - return subst - } else { - raise occurrence_violation_error(t1, t2, expr) - } - } - - if isTypeVar(t2) { - if isNoOccur(t2, t1) { - addTypeEquationToSubst(subst, t2, t1) - return subst - } else { - raise occurrence_violation_error(t2, t1, expr) - } - } - - if isList(t1) and isList(t2) { - return unifier(toListOf(t1).eleType, toListOf(t2).eleType, subst, expr) - } - if isDict(t1) and isDict(t2) { - dict1of := toDictOf(t1) - dict2of := toDictOf(t2) - subst = unifier(dict1of.keyType, dict2of.keyType, subst, expr) - subst = unifier(dict1of.valueType, dict2of.valueType, subst, expr) - return subst - } - if isStruct(t1) and isStruct(t2) { - Struct1of := tostructof(t1) - Struct2of := tostructof(t2) - for key, _ in Struct1of { - subst = unifier(t1[key].type, t2[key].type, subst, expr) - } - return subst - } - - raise unification_error(t1, t2, expr) -} - -func applySubstToTypeEquation(t, subst) { - // walks through the type t, replacing each type variable by its binding in the substitution -σ. If a variable is Not bound in the substitution, then it is left unchanged. - if isBasicType(t) { - return t - } - if isList(t) { - return listOf(applySubstToTypeEquation(toListOf(t).eleType, subst)) - } - if isDict(t) { - dictof := toDictOf(t) - kT := applySubstToTypeEquation(dictof.keyType, subst) - vT := applySubstToTypeEquation(dictof.valueType, subst) - return dictOf(kT, vT) - } - if isStruct(t) { - structof := tostructof(t) - s := structof() - for key, type in Struct1of { - kT := applySubstToTypeEquation(type, subst) - s.add(key, kT) - } - return s - } - if hasTypeVar(t) { - for tvar in t.vars { - if tvar in subst { - *tvar = subst[tvar] - } - } - } - return t -} - -func addTypeEquationToSubst(subst, tvar, t) { - // takes the substitution σ and adds the equation tv = t to it - for _, t in subst { - for tvar in t.vars { - tmp := applyOneSubst(tsvar, tvar, t) - *tvar = tmp - } - } - subst.add(tvar, t) -} - -func applyOneSubst(t0, tvar, t1) { - // substituting t1 for every occurrence of tv in t0. - if isBasicType(t0) { - return t0 - } - if isList(t0) { - return listOf(applyOneSubst(toListOf(t).eleType, tvar, t1)) - } - if isDict(t0) { - dictof := toDictOf(t) - kT := applyOneSubst(dictof.keyType, tvar, t1) - vT := applyOneSubst(dictof.valueType, tvar, t1) - return dictOf(kT, vT) - } - if isStruct(t0) { - structof := tostructof(t) - s := structof() - for key, type in Struct1of { - kT := applyOneSubst(type, tvar, t1) - s.add(key, kT) - } - return s - } - if t0 == tvar { - return t1 - } - return t0 -} - -func isNoOccur(tvar, t) { - // No variable bound in the substitution occurs in any of the right-hand sides of the substitution. - if isBasicType(t) { - return true - } - if isList(t) { - return isNoOccur(tvar, toListOf(t).eleType) - } - if isDict(t) { - dictof := toDictOf(t) - return isNoOccur(tvar, dictof.keyType) and isNoOccur(tvar, dictof.valueType) - } - if isStruct(t) { - structof := tostructof(t) - noOccur := true - for _, type in structof { - noOccur = noOccur and isNoOccur(tvar, type) - } - return noOccur - } - return tvar != t -} -``` - -### 示例 - -#### 正常推导 - -``` -T : { - a = 1 - b = "2" - c = a * 2 - d = { - d0 = [a, c] - } -} - -x: T = { - a = 10 -} -``` - -#### Occurrence Violation Error - -``` -T = { - a = a -} -``` - -#### Type Unification Error - -``` -T : { - a = 1 -} - -T : { - a = "1" -} -``` - -## Reference - -- [https://en.wikipedia.org/wiki/Type_system](https://en.wikipedia.org/wiki/Type_system) -- Pierce, Benjamin C. (2002). Types and Programming Languages. MIT Press. -- [https://www.cs.cornell.edu/courses/cs4110/2010fa/](https://www.cs.cornell.edu/courses/cs4110/2010fa/) -- [https://www.typescriptlang.org/docs/handbook/basic-types.html](https://www.typescriptlang.org/docs/handbook/basic-types.html) -- [https://www.typescriptlang.org/docs/handbook/advanced-types.html](https://www.typescriptlang.org/docs/handbook/advanced-types.html) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/_category_.json deleted file mode 100644 index 53e27fd4..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "模块系统", - "position": 2 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/base64.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/base64.md deleted file mode 100644 index 0db738f0..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/base64.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: "base64" -linkTitle: "base64" -type: "docs" -description: base64 编码解码 -weight: 100 ---- - -## encode - -`encode(value: str, encoding: str = "utf-8") -> str` - -使用注册的编码器对字符串 `value` 进行编码。 - -## decode - -`decode(value: str, encoding: str = "utf-8") -> str` - -使用注册的编码器对字符串 `value` 进行解码。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/builtin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/builtin.md deleted file mode 100644 index 44085174..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/builtin.md +++ /dev/null @@ -1,401 +0,0 @@ ---- -title: "builtin" -sidebar_position: 1 ---- - -KCL 提供了一个内置系统模块的列表,这些模块是自动加载的,无需提供任何模块名称即可直接使用。例如,`print` 就是一个广泛使用的内置模块提供的函数。 - -## 类型转换函数 - -KCL的 `bool`、`int`、`float`、`str`、`list`、`dict`等类型有内置同名的转换函数。其中 `int` 不仅仅可以用于截断浮点数,也可以用来将字符串转化为整数(解析时为10进制,也可以制定其他值)。 - -下面是类型相关函数常见的用法: - -```py -b1 = bool(1) # true -b2 = bool(1.5) # true -b3 = bool("true") # true -b4 = bool("") # false -b5 = bool([]) # false -b6 = bool({}) # false - -i1 = int("11") # 11 -i2 = int("11", base=8) # 9 -i3 = int("11", base=2) # 3 - -f1 = float(1) # 1.0 -f2 = float("1.5") # 1.5 - -s1 = str(1) # 1 - -l1 = list([1, 2, 3]) -``` - -## String 类型成员函数 - -参考 [String 文档](/docs/reference/lang/spec/datatypes) - -## print - -`print(*args:any, end:str='\n')` - -内置的打印函数,提供不同类型的可变参数打印,默认在结尾添加一个换行符号。以下上常见的用法: - -```python -print("hello KCL") -print() -print(None, end=':') -print(None) -print(True) -print(False) -print(123) -print(123.0) -print('abc ${123}') -print("abc ${456}") -print([1,'a', True]) -print(1,'a', True) -print({}) -print({a: 123}) -``` - -输出格式如下: - -```shell -hello KCL - -None:None -True -False -123 -123.0 -abc 123 -abc 456 -[1, 'a', True] -1 a True -{} -{'a': 123} -``` - -如果不希望在默认换行时,可以通过 `end=''` 命名参数重新指定结尾的字符串。 - -## multiplyof - -`multiplyof(a:int, b:int) -> bool` - -判断整数 `a` 是否为 `b` 的整数倍,返回布尔值: - -```python -print(multiplyof(2, 1)) # True -print(multiplyof(1, 2)) # False -print(multiplyof(0, 1)) # True -print(multiplyof(0, 2)) # True -print(multiplyof(1, 0)) # Error -``` - -`0` 是任何数的倍数。但是 `b` 不能为 `0`,否则将抛出异常。 - -## isunique - -`isunique(list: [any]) -> bool` - -判断数组中是否存在重复的元素,返回布尔值: - -```python -print(isunique([])) # True -print(isunique([1])) # True -print(isunique([1, 2])) # True - -print(isunique([1, 1])) # False -print(isunique([1, 1.0])) # False -print(isunique([1.1, 1.1])) # False - -print(isunique(['abc', "abc"])) # False -print(isunique(['abc', "a${'bc'}"])) # False -``` - -需要注意的是整数和浮点数会忽略类型差异,根据值是否相等判断。 - -## len - -`len(x: str | [any] | {:}) -> int` - -返回字符串、列表和数组的长度: - -```python -print(len([])) # 0 -print(len({})) # 0 - -print(len([1])) # 1 -print(len({abc:123})) # 1 - -print("abc") # 3 -``` - -注:不支持对 `schema` 对象计算长度。 - -## abs - -`abs(x: number) -> number` - -计算 `x` 的绝对值。 - -## all_true - -`all_true(x:str|[]|{:}) -> bool` - -判断列表或字典类全部元素为真,用法如下: - -```python -print(all_true([])) # True -print(all_true({})) # True - -print(all_true([True])) # True -print(all_true([1])) # True - -print(all_true([True, False])) # False -print(all_true([True, None])) # False -``` - -当列表为空时返回真。 - - - -## any_true - -`any_true(x:str|[]|{:}) -> bool` - -判断可迭代对象中至少有一个元素为真,用法如下: - -```python -print(any_true([])) # False -print(any_true([1])) # True -``` - -## bin - -`bin(x:number) -> str` - -返回整数的二进制表示的字符串,用法如下: - -```python -print(bin(8)) # 0b1000 -``` - -## hex - -`hex(number)` - -返回整数的十六进制表示的字符串,用法如下: - -```python -print(hex(18)) # 0x12 -``` - -## oct - -`oct(number)` - -返回整数的八进制表示的字符串,用法如下: - -```python -print(oct(10)) # 0o12 -``` - -## option - -`option(key:str, type:str='', required=False, default=None, help="") -> any` - -获取命令行参数输入的值。 - -## ord - -`ord(c) -> int` - -获取字符的 Unicode 码点值,用法如下: - -```python -print(ord('A')) # 65 -print(ord('B')) # 66 -print(ord('C')) # 67 -``` - -## sorted - -`sorted(x: []) -> []` - -返回排序后的列表,用法如下: - -```python -_a = [] -_b = [2, 1] - -_c = sorted(_a) -_d = sorted(_b) - -print(_a) # [] -print(_b) # [2, 1] -print(_c) # [] -print(_d) # [1, 2] -``` - -## range - -`range(start:int, end:int, step=1) -> [int]` - -产生迭代列表,用法如下: - -```python -print(range(1,5)) # [1, 2, 3, 4] -print(range(1,5, 2)) # [1, 3] -print(range(5, 1, -1)) # [5, 4, 3, 2] -``` - -## min - -`min(x:[number]) -> number` - -返回列表中最小的元素,用法如下: - -```python -print(min([1,2])) # 1 -print(min([2,1])) # 1 -``` - - - -## max - -`max(x:[number]) -> number` - -返回列表中最大的元素,用法如下: - -```python -print(max([1,2])) # 2 -print(max([2,1])) # 2 -``` - -## sum - -`sum(x:[number], init_value=0) -> number` - -返回列表中全部元素的和,用法如下: - -``` -print(sum([1,2])) # 3 -print(sum([2,1], 1000)) # 1003 -``` - -## pow - -`pow(x: number, y: number, z: number = None) -> number` - -计算 `x**y`,如果 `z` 非空则计算 `(x**y)%z`,支持整数和浮点数。 - -下面的常见的用法: - -```python -print(pow(2,3)) # 8 -print(pow(2, 3, 5)) # 8%5 == 3 - -print(pow(2, 0.5)) # 1.414 -``` - -## round - -`round(number: int|float, ndigits:int|None) -> float | int` - -返回 `number` 的四舍五入近似值。如果 `ndigits` 非 `None` 则返回浮点数并保留指定位数的小数(不能为负数),否则返回整数结构。 - -下面是常用的用法: - -```python -print(round(1)) # 1 -print(round(1.4)) # 1 -print(round(1.5)) # 2 - -print(round(1.5555, 1)) # 1.6 -print(round(1.5555, 2)) # 1.56 - -print(round(1.5555)) # 2 -print(round(1.5555, 0)) # 2.0 -``` - -需要注意的是,`ndigits` 为 `None` 和 `0` 的区别是前缀返回 `int` 类型、后者返回 `float` 类型。 - -## typeof - -`typeof(x: any, full_name: bool = False) -> str` - -输出 `x` 在运算时的类型。当 `full_name` 参数设置为 `True` 时,将返回 `pkg.schema` 形式的包前缀。 - -下面是常见的用法: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person{} -t3 = typeof(_x1) - -_x2 = pkg.Person{} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# 输出 -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -## zip - -`zip(*args: str|list|dict)` - -用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。 - -下面是常见的用法: - -```py -a = zip([0, 1, 2], [3, 4, 5]) -b = zip([0, 1], [3, 4, 5]) -c = zip([0, 1, 2], [3, 4, 5, 6]) - -# 输出 -# a: -# - - 0 -# - 3 -# - - 1 -# - 4 -# - - 2 -# - 5 -# b: -# - - 0 -# - 3 -# - - 1 -# - 4 -# c: -# - - 0 -# - 3 -# - - 1 -# - 4 -# - - 2 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/manifests.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/manifests.md deleted file mode 100644 index 5c54e9c7..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/manifests.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: "manifests" -linkTitle: "manifests" -type: "docs" -description: manifests system module -weight: 100 ---- - -## yaml_stream - -```python -yaml_stream(values: [any], opts: {str:} = { - sort_keys = False - ignore_private = True - ignore_none = False - sep = "---" -}) -``` - -这个函数的功能是将 KCL 对象列表序列化为带 `---` 分隔符的样式 YAML 输出,它具有两个参数: - -- `values` - 一个 KCL 对象列表 -- `opts` - YAML 序列化选项 - - `sort_keys`:是否按属性名称的字典序对序列化结果进行排序(默认为 `False`)。 - - `ignore_private`:是否忽略名称以 `_` 开头的属性序列化输出(默认为 `True`)。 - - `ignore_none`:是否忽略值为 `None` 的属性(默认为 `False`)。 - - `sep`:在多个 YAML 文档之间选择怎样的分隔符(默认为 `"---"`)。 - -下面我们通过一个例子来说明: - -```python -# 使用 `import` 关键词导入 `manifests` 模块 -import manifests - -# `Deployment` schema 定义 -schema Deployment: - apiVersion: str = "v1" - kind: str = "Deployment" - metadata: {str:} = { - name = "deploy" - } - spec: {str:} = { - replica = 2 - } - -# `Service` schema 定义 -schema Service: - apiVersion: str = "v1" - kind: str = "Service" - metadata: {str:} = { - name = "svc" - } - spec: {str:} = {} - -# 定义两个 `Deployment` 资源 -deployments = [Deployment {}, Deployment {}] -# 定义两个 `Service` 资源 -services = [Service {}, Service {}] -# 将它们放入 KCL 列表,并调用 `manifests.yaml_stream` 函数。 -manifests.yaml_stream(deployments + services) -``` - -首先我们通过 `import` 关键字导入 `manifests` 模块并定义 2 个 Deployment 以及 2 个 Service 资源,当我们想以 YAML stream 并以 `---` 作为分隔符的格式依次输出这 4 个资源时,我们可以将它们合并为一个 KCL 列表并作为 `manifests.yaml_stream` 函数的 `values` 形参进行传入 (如无特殊需求,opts 参数一般使用默认值即可),最终得到 YAML 输出为: - -```yaml -apiVersion: v1 -kind: Deployment -metadata: - name: deploy -spec: - replica: 2 ---- -apiVersion: v1 -kind: Deployment -metadata: - name: deploy -spec: - replica: 2 ---- -apiVersion: v1 -kind: Service -metadata: - name: svc ---- -apiVersion: v1 -kind: Service -metadata: - name: svc -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/math.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/math.md deleted file mode 100644 index 3b2ff0cc..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/math.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: "math" -linkTitle: "math" -type: "docs" -description: math 包 - 数学函数 -weight: 100 ---- - -## ceil - -`ceil(x) -> int` - -返回 `x` 向上取整得到的整数,这是大于等于 `x` 的最小整数。 - -## factorial - -`factorial(x) -> int` - -返回 `x` 的阶乘(即 `x!`),如果 `x` 是负数或者不是整数,则会引发一个错误。 - -## floor - -`floor(x) -> int` - -返回 `x` 向下取整得到的整数,这是小于等于 `x` 的最大整数。 - -## gcd - -`gcd(a: int, b: int) -> int` - -返回 `x` 和 `y` 的最大公约数。 - -## isfinite - -`isfinite(x) -> bool` - -如果 `x` 既不是无穷大也不是 `NaN` 返回 `True`,否则返回 `False`。 - -## isinf - -`isinf(x) -> bool` - -如果 `x` 是正无穷或负无穷返回 `True`,否则返回 `False`。 - -## isnan - -`isnan(x) -> bool` - -如果 `x` 是 `NaN` 返回 `True`,否则返回 `False`。 - -## modf - -`modf(x) -> List[float, float]` - -返回 `x` 的整数和小数部分,两个结果均与 `x` 的正负号相同,并且均为浮点数。 - -## exp - -`exp(x) -> float` - -返回以 `e` 为底数, `x` 的幂。 - -## expm1 - -`expm1(x) -> float` - -返回 `e` 的 `x` 次方减去 1,该函数能够避免由于直接计算 `exp(x) - 1` 而引起的精度损失。 - -## log - -`log(x, base=2.71828182845904523536028747135266250) -> float` - -返回以 `e` 为底数,`x` 的对数。 - -## log1p - -`log1p(x) -> float` - -返回以 `e` 为底数,`1 + x` 的自然对数,该函数能够在 `x` 靠近 0 时精确计算结果。 - -## log2 - -`log2(x) -> float` - -返回 `x` 的以 2 为底的对数。 - -## log10 - -`log10(x) -> float` - -返回 `x` 的以 10 为底的对数。 - -## pow - -`pow(x, y) -> float` - -返回 `x` 的 `y` 次幂(即 `x` 的 `y` 次方)。 - -## sqrt - -`sqrt(x) -> float` - -返回 `x` 的平方根。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/net.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/net.md deleted file mode 100644 index 1050d16d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/net.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: "net" -linkTitle: "net" -type: "docs" -description: net 包 - 网络IP处理 -weight: 100 ---- - -## split_host_port - -`split_host_port(ip_end_point: str) -> List[str]` - -从 `ip_end_point` 分离出 `host` 和 `port`。 - -## join_host_port - -`join_host_port(host, port) -> str` - -合并 `host` 和 `port`。 - -## fqdn - -`fqdn(name: str = '') -> str` - -返回完全限定域名(FQDN)。 - -## parse_IP - -`parse_IP(ip) -> str` - -将 `ip` 解析为真实的 IP 地址。 - -## to_IP4 - -`to_IP4(ip) -> str` - -获取 `ip` 的 IPv4 表示形式。 - -## to_IP16 - -`to_IP16(ip) -> int` - -获取 `ip` 的 IPv6 表示形式。 - -## IP_string - -`IP_string(ip: str | int) -> str` - -返回 IP 字符串。 - -## is_IPv4 - -`is_IPv4(ip: str) -> bool` - -判断 `ip` 是否为 IPv4。 - -## is_IP - -`is_IP(ip: str) -> bool` - -判断 `ip` 是否为有效的 IP 地址。 - -## is_loopback_IP - -`is_loopback_IP(ip: str) -> bool` - -判断 `ip` 是否为回环地址。 - -## is_multicast_IP - -`is_multicast_IP(ip: str) -> bool` - -判断 `ip` 是否为组播地址。 - -## is_interface_local_multicast_IP - -`is_interface_local_multicast_IP(ip: str) -> bool` - -判断 `ip` 是否为接口、本地和组播地址。 - -## is_link_local_multicast_IP - -`is_link_local_multicast_IP(ip: str) -> bool` - -判断 `ip` 是否为链路本地和组播地址。 - -## is_link_local_unicast_IP - -`is_link_local_unicast_IP(ip: str) -> bool` - -判断 `ip` 是否为链路本地和单播地址。 - -## is_global_unicast_IP - -`is_global_unicast_IP(ip: str) -> bool` - -判断 `ip` 是否为全局单播地址。 - -## is_unspecified_IP - -`is_unspecified_IP(ip: str) -> bool` - -判断 `ip` 是否为 `unspecified` 地址。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/regex.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/regex.md deleted file mode 100644 index e7b0c25c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/regex.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "regex" -linkTitle: "regex" -type: "docs" -description: regex 包 - 正则表达式 -weight: 100 ---- - -## replace - -`replace(string: str, pattern: str, replace: str, count=0) -> str` - -替换字符串 `string`中最左边、不重叠并且匹配模式 `pattern` 的部分替换为指定的字符串 `replace`,并返回替换后的字符串 - -## match - -`match(string: str, pattern: str) -> bool` - -尝试在字符串开头应用模式 `pattern`,找到了任何匹配项则返回 `True`,返回 `False` 表示没有找到匹配项 - -## compile - -`compile(pattern: str) -> bool` - -编译正则表达式模式 `pattern`,并返回一个布尔值,表示该模式是否有效 - -## findall - -`findall(string: str, pattern: str) -> List[str]` - -查找 `pattern` 在 `string` 中的所有非重叠匹配,并以字符串列表的形式返回 - -## search - -`search(string: str, pattern: str) -> bool` - -扫描字符串 `string` 以查找与模式匹配的项,如果找到任何匹配项,则返回布尔值 `True`,否则返回 `False` - -## split - -`split(string: str, pattern: str, maxsplit=0) -> List[str]` - -返回一个由字符串内单词组成的列表,使用 `pattern` 作为分隔字符串,最多进行 `maxsplit` 次拆分 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/units.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/units.md deleted file mode 100644 index 8c862d0e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/units.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: "units" -linkTitle: "units" -type: "docs" -description: units 包 - 单位处理 -weight: 100 ---- - -## 单位的常量 - -- 定点数: `n`, `u`, `m`, `k`, `K`, `G`, `T` 和 `P`. -- 2 的幂: `Ki`, `Mi`, `Gi`, `Ti` 和 `Pi`. - -## 函数列表 - -- `to_n(num: int) -> str` - 将 int 转换为以 `n` 作为后缀的字符串 -- `to_u(num: int) -> str` - 将 int 转换为以 `u` 作为后缀的字符串 -- `to_m(num: int) -> str` - 将 int 转换为以 `m` 作为后缀的字符串 -- `to_K(num: int) -> str` - 将 int 转换为以 `K` 作为后缀的字符串 -- `to_M(num: int) -> str` - 将 int 转换为以 `M` 作为后缀的字符串 -- `to_G(num: int) -> str` - 将 int 转换为以 `G` 作为后缀的字符串 -- `to_T(num: int) -> str` - 将 int 转换为以 `T` 作为后缀的字符串 -- `to_P(num: int) -> str` - 将 int 转换为以 `P` 作为后缀的字符串 -- `to_Ki(num: int) -> str` - 将 int 转换为以 `Ki` 作为后缀的字符串 -- `to_Mi(num: int) -> str` - 将 int 转换为以 `Mi` 作为后缀的字符串 -- `to_Gi(num: int) -> str` - 将 int 转换为以 `Gi` 作为后缀的字符串 -- `to_Ti(num: int) -> str` - 将 int 转换为以 `Ti` 作为后缀的字符串 -- `to_Pi(num: int) -> str` - 将 int 转换为以 `Pi` 作为后缀的字符串 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/plugin/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/plugin/_category_.json deleted file mode 100644 index 645deb88..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/plugin/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "插件系统", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/xlang-api/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/xlang-api/_category_.json deleted file mode 100644 index e26f646c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/xlang-api/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "多语言", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/xlang-api/java-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/xlang-api/java-api.md deleted file mode 100644 index 1cea9e49..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/xlang-api/java-api.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Java API - -目前 KCL Java SDK 还处于早期预览版本,后续 KCL 团队会持续更新并提供更丰富的功能,更多信息请参阅:[https://github.com/kcl-lang/kcl-java](https://github.com/kcl-lang/kcl-java)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/xlang-api/python-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/xlang-api/python-api.md deleted file mode 100644 index ad3ad867..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/xlang-api/python-api.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Python API - -目前 KCL Python SDK 还处于早期预览版本,后续 KCL 团队会持续更新并提供更丰富的功能,更多信息请参阅:[https://github.com/kcl-lang/kcl-py](https://github.com/kcl-lang/kcl-py)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/Ide/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/Ide/_category_.json deleted file mode 100644 index fcdc7f10..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/Ide/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "集成开发环境", - "position": 2 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/Ide/intellij.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/Ide/intellij.md deleted file mode 100644 index 45a16609..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/Ide/intellij.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -sidebar_position: 3 ---- - -# IntelliJ IDEA - -- IntelliJ KCL 插件: [https://github.com/kcl-lang/intellij-kcl](https://github.com/kcl-lang/intellij-kcl) - -![intellij](/img/docs/tools/Ide/intellij/overview.png) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/Ide/neovim.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/Ide/neovim.md deleted file mode 100644 index f8c5c358..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/Ide/neovim.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -sidebar_position: 2 ---- - -# NeoVim - -- NeoVim KCL 插件: [https://github.com/kcl-lang/kcl.nvim](https://github.com/kcl-lang/kcl.nvim) - -![kcl.nvim](/img/docs/tools/Ide/neovim/overview.png) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/_category_.json deleted file mode 100644 index 5170334a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "工具", - "position": 3 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/_category_.json deleted file mode 100644 index 8fac9ad8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "命令行工具", - "position": 1 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/index.md deleted file mode 100644 index f754b5ca..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# 命令行工具 - -KCL 提供了 IDE 插件、丰富的语言工具和 OpenAPI 工具。通过这些工具,可以提供一整套解决方案,包括配置语言、模型界面、自动化工具和最佳实践。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/kcl/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/kcl/_category_.json deleted file mode 100644 index b22440b7..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/kcl/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KCL 语言工具", - "position": 2 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/openapi/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/openapi/_category_.json deleted file mode 100644 index 5df621d8..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/openapi/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "OpenAPI 工具", - "position": 3 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/openapi/spec.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/openapi/spec.md deleted file mode 100644 index aee9fc92..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/openapi/spec.md +++ /dev/null @@ -1,424 +0,0 @@ -# KCL OpenAPI 规范 - -[OpenAPI](https://www.openapis.org/) 允许 API 提供方规范地描述 API 操作和模型,并基于它生成自动化工具和特定语言的客户端。 - -## KCL OpenAPI 文件结构 - -依据 OpenAPI 3.0 规范,OpenAPI 文件中应至少包含 openapi、components、 info、paths 四种根节点对象,KCL OpenAPI 聚焦于其中模型定义的部分,即 OpenAPI 文件中的 `definitions`,而描述操作的 Restful API 部分(即 OpenAPI 文件中的 `paths`)则不属于 KCL OpenAPI 定义的范畴。 -​ - -注:除以上列出的节点外,OpenAPI 官方规范还支持 servers、security、tags、externalDocs 四种可选的根节点,但都不是 KCL OpenAPI 所关心的,因此用户无需填写这部分内容,即使填写了也不会产生任何影响。 -​ - -| OpenAPI 顶层对象 | 类型 | 含义 | KCL OpenAPI 工具支持情况 | -| ---------------- | ----------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | -| swagger | string | openapi 版本信息 | 必填项,目前支持 openapi 2.0,即合法取值为 "2.0" | -| definitions | Definition Object | 模型定义 | 必填项 | -| info | Info Object | 当前 API 文件的元数据信息,例如标题、描述信息、版本、开源协议等 | 必填项,定义当前 OpenAPI 文件的基本信息,不会输出到 KCL 代码,但可用于 Swagger-UI 工具可视化展示 | - -为方便初学者快速理解,下面给出一个典型的 KCL OpenAPI 文件(截取自 swagger example [Petstore](https://petstore.swagger.io/))应包含的节点图示。KCL OpenAPI 工具重点关注其中的 definitions 节点,可以看到文件中定义了两个模型(Pet 和 Category),并且 Pet 模型中包含三个属性(name、id、category) - -## KCL schema - -KCL 中使用 schema 结构来定义配置数据的“类型”,关于 KCL schema,可参考文档:传送门 -在 definitions 节点下新增 definition 元素,即可定义 KCL schema. -示例: -下例在 KCL 代码中定义了 Pet、Category 两个 schema,同样地,其对应的 OpenAPI 也在 definitions 节点下包含这两个模型的描述。 - -```python -# KCL schema: -schema Pet: - name: str - id?: int - category?: Category - -schema Category: - name?: str - -# 对应的 OpenAPI 描述 -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "id": { - "type": "integer", - "format": "int64" - }, - "category": { - "$ref": "#/definitions/Category" - } - }, - "required": [ - "name" - ] - }, - "Category": { - "type": "object", - "properties": { - "name": { - "type": "string" - } - } - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -``` - -### schema 名称 - -在 KCL 中,schema 名称紧跟在 schema 关键字后声明,在 OpenAPI 中,模型的名称通过 definition 元素的 key 来定义。 - -### schema 类型 - -KCL schema 在 OpenAPI 中的类型为 "object". 例如上例中 "Pet" 的 "type" 值应为 "object". - -### schema 属性 - -KCL schema 中可以定义若干属性,属性的声明一般包含如下几部分: - -- 属性注解:可选,以 @ 开头,例如 @deprecated 注解表示属性被废弃 -- 属性名称:必须 -- 属性 optional 修饰符(?):可选,带问号表示当前属性为可选属性,可以不被赋值。反之,不带问号表示必填属性 -- 属性类型:必须,可以是基本数据类型,也可以是 schema 类型, 或者是前述两种类型的并集 -- 属性默认值:非必须 - -它们与 OpenAPI 规范的对应关系如下: - -| KCL schema 属性元素 | OpenAPI 元素 | -| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- | -| 属性注解 | 暂不支持,计划扩展一个 deprecate 字段用于描述 deprecated 注解 | | -| 属性名称 | properties 节点下,每个属性的 key 即为属性名称 | -| 属性 optional 修饰符(?) | 模型节点下,通过 required 字段列出该模型的所有必填属性的名称,未被列出的属性即为 optional | -| 属性类型 | 属性节点下,设置 type + format 可以标识属性的基本类型,如果是 schema 类型则用 $ref 字段表示,类型 union 则由扩展字段 x-kcl-types 来标识,此外,属性节点的 enum、pattern 也可以用于表示 KCL 类型。 | -| KCL-OpenAPI 关于类型的对照关系,详见“基本数据类型”小节 | | -| 属性默认值 | 属性节点下,设置 default 字段即可为属性设置默认值 | - -示例: -下例中 Pet 模型包含了 2 个属性:name(string 类型,必填属性,无注解,无默认值)、id(int64 类型,无注解,非必填,默认值为 -1) - -```python -# KCL schema Pet,包含两个属性 name 和 id -schema Pet: - name: str - id?: int = -1 - -# 对应的 OpenAPI 文档 -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - "id": { - "type": "integer", - "format": "int64", - "default": -1 - } - }, - "required": [ - "name" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### schema 索引签名 - -KCL schema 允许定义索引签名,用于定义属性名不固定的 dict,起到静态模板的作用。具体来说,KCL schema 索引签名包含如下几个元素: - -- 索引签名中 key 的类型:在方括号中声明,必须是基础类型 -- 索引签名中 value 的类型:在冒号后声明,可以是任意合法的 KCL 类型 -- 索引签名中的省略符:在方括号中,key 类型之前声明,使用"..."表示。如果带有该符号,表示该索引签名只用于约束未在 schema 中定义的属性;否则,表示 schema 中所有已定义和未定义属性都收到该索引签名的约束。 -- 索引签名中 key 的别名:在方括号中,紧随左方括号之后声明,使用名称 + 冒号表示,该别名可用于按名称引用索引签名 -- 索引签名的默认值:可以为索引签名设置默认值 - -在 OpenAPI 中,可以借助在模型节点的 `additionalProperties` 字段描述某些 key 为 string 的索引签名。但对于 KCL 索引签名中非 string 类型的 dict key、索引签名 key 的 check 校验,在 OpenAPI 规范没有对等的描述。它们与 OpenAPI 规范的对应关系如下: - -| KCL 索引签名元素 | OpenAPI 元素 | -| ----------------------- | ---------------------------------------------------------------------- | -| 索引签名中 key 的类型 | OpenAPI 仅支持 key 为 string 类型,无法自定义 | -| 索引签名中 value 的类型 | 模型节点的下 additionalProperties 下的 "type" 字段 | -| 索引签名中的省略符 | OpenAPI 中表示索引签名时,只能表示 KCL 中带有省略符的情况 | -| 索引签名中 key 的别名 | OpenAPI 中不支持为索引签名定义 key 别名,(预计通过扩展支持:x-alias) | -| 索引签名的默认值 | 目前不支持 | - -示例:下例中的 KCL schema Pet,包含两个预定义的属性 name 和 id,除此之外,还允许使用该 schema 的配置额外地赋值其他 key 为 string 类型,value 为 bool 类型的属性: - -```python -# KCL schema Pet,包含两个预定义的属性 name 和 id,允许额外给 key 为 string、value 为 bool 的属性赋值 -schema Pet: - name: str - id?: int - [...str]: bool - -# 对应的 OpenAPI 描述 -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - "id": { - "type": "integer", - "format": "int64", - } - }, - "additionalProperties": { - "type": "bool" - }, - "required": [ - "name" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### schema 继承关系 - -### 内联 schema - -OpenAPI 支持嵌套地定义 schema,但 KCL 目前暂不支持 schema 的内联。OpenAPI 中内联定义的 schema 将被转换为 KCL 中带名称的 schema,其名称的命名规则为:在该内联 schema 的上层 schema 名称的基础上,增加相应的后缀。在拼接后缀时,根据定义了该内联 schema 的外层 OpenAPI 元素类型,后缀内容如下: - -| OpenAPI 文档中定义内联 schema 的元素 | KCL schema 名称拼接规则 | -| ------------------------------------ | ------------------------------ | -| 某属性节点 | 增加该属性节点的名称为后缀 | -| AdditionalProperties 节点 | 增加"AdditionalProperties"后缀 | - -注:KCL 未来也可能会支持内联 schema,届时再更新这部分转换规则 -示例 1:下例中的模型 Deployment 包含有 kind、spec 两个属性,其中 deploymentSpec 属性的 schema 通过内联的方式定义: - -```python -# OpenAPI 文档 -{ - "definitions": { - "Deployment": { - "type": "object", - "properties": { - "kind": { - "type": "string", - }, - "spec": { - "type": "object", - "properties": { - "replicas": { - "type": "integer", - "format": "int64" - } - } - } - }, - "required": [ - "kind", - "spec" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -# 转换为 KCL Schema 如下: -schema Deployment: - kind: str - spec: DeploymentSpec - -schema DeploymentSpec: - replicas?: int -``` - -示例 2:下例中的模型 Person 中除固定属性 name 外,还允许包含额外的属性(additionalProperties),并且这部分额外属性的属性值的 schema 通过内联的方式定义: - -```python -# OpenAPI 文档 -{ - "definitions": { - "Person": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - }, - "required": [ - "name", - "spec" - ], - "additionalProperties": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "description": { - "type": "string" - } - }, - "required": [ - "name" - ] - }, - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -# 转换为 KCL Schema 如下: -schema Person: - name: str - [...str]: [PersonAdditionalProperties] - -schema PersonAdditionalProperties: - name: str - description?: str -``` - -## KCL 文档 - -KCL doc 规范请参考:[传送门](../kcl/docgen.md) -KCL 文档包含 module 文档、schema 文档两类,其中 schema 文档可以由 OpenAPI 转换得到。KCL schema 文档包含: - -- schema 描述信息:位于 schema 声明之后、schema 属性声明之前,是对 schema 的总体介绍 -- schema 属性信息:位于 shcema 描述信息之后,以 Attributes + 分割线分隔 -- schema 附加信息:位于 schema 属性信息之后,以 See Also + 分割线分隔 -- schema 示例信息:位于 schema 附加信息之后,以 Examples + 分割线分隔 - -它们与 OpenAPI 规范的对应关系如下: - -| KCL 文档元素 | OpenAPI 元素 | -| --------------- | ---------------------------------------------------- | -| schema 描述信息 | definitions 节点下,每个模型节点的 description 字段 | -| schema 属性信息 | properties 节点下,每个属性节点的 description 字段 | -| schema 附加信息 | definitions 节点下,每个模型节点的 externalDocs 字段 | -| schema 示例信息 | definitions 节点下,每个模型节点的 example 字段 | - -示例: -下例中为 Pet 模型定义了其 schema 描述文档 "The schema Pet definition";Pet 的两个属性 "name" 和 "id" 也分别定义了其属性文档 "The name of the pet" 及 "The id of the pet";Pet 的附加信息为 "Find more info here. [https://petstore.swagger.io/](https://petstore.swagger.io/)";此外,Pet 模型还提供了模型实例的示例写法。 - -```python -# KCL schema Pet,采用规范的 KCL 文档格式 -schema Pet: - """The schema Pet definition - - Attributes - ---------- - name : str, default is Undefined, required - The name of the pet - id : int, default is -1, optional - The age of the pet - - See Also - -------- - Find more info here. https://petstore.swagger.io/ - - Examples - -------- - pet = Pet { - name = "doggie" - id = 123 - } - """ - name: str - id?: int = -1 - -# 对应的 OpenAPI 文档 -{ - "definitions": { - "Pet": { - "description": "The schema Pet definition", - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "The name of the pet" - }, - "id": { - "type": "integer", - "format": "int64", - "default": -1, - "description": "The age of the pet" - } - }, - "required": [ - "name" - ], - "externalDocs": { - "description": "Find more info here", - "url": "https://petstore.swagger.io/" - }, - "example": { - "name": "doggie", - "id": 123 - } - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -​ - -## 基本数据类型 - -| JSON Schema type | swagger type | KCL type | comment | -| ---------------- | --------------------------- | --------------- | --------------------------------------------------------------------------- | -| boolean | boolean | bool | | -| number | number | float | | -| | number format double | **unsupported** | | -| | number format float | float | | -| integer | integer | int (32) | | -| | integer format int64 | **unsupported** | | -| | integer format int32 | int (32) | | -| string | string | str | | -| | string format byte | str | | -| | string format int-or-string | int | str | -| | string format binay | str | | -| | string format date | unsupported | As defined by full-date - [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) | -| | string format date-time | unsupported | As defined by date-time - [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) | -| | string format password | unsupported | for swagger: A hint to UIs to obscure input. | -| | datetime | datetime | | - -## Reference - -- openapi spec 2.0:[https://swagger.io/specification/v2/](https://swagger.io/specification/v2/) -- openapi spec 3.0:[https://spec.openapis.org/oas/v3.1.0](https://spec.openapis.org/oas/v3.1.0) -- openapi spec 3.0(swagger 版本):[https://swagger.io/specification/](https://swagger.io/specification/) -- openapi spec 2.0 #SchemaObject:[https://swagger.io/specification/v2/#schemaObject](https://swagger.io/specification/v2/#schemaObject) -- go swagger:[https://goswagger.io/use/models/schemas.html](https://goswagger.io/use/models/schemas.html) -- swagger data models:[https://swagger.io/docs/specification/data-models/](https://swagger.io/docs/specification/data-models/) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/package-management/command-reference/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/package-management/command-reference/_category_.json deleted file mode 100644 index abcc956a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/package-management/command-reference/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "命令参考", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/concepts/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/concepts/_category_.json deleted file mode 100644 index d3ae7a0a..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/concepts/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "核心概念", - "position": 5 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/concepts/package-and-module.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/concepts/package-and-module.md deleted file mode 100644 index fbde28f3..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/concepts/package-and-module.md +++ /dev/null @@ -1,156 +0,0 @@ -# 模块和包 - -本节主要介绍如何组织 KCL 中的文件。 - -## 概述 - -在一个**module**中,KCL 按**package**进行组织文件。package 可以在 module 内定义,也可以通过 KCL 包管理器 `kpm` 从外部导入。在后一种情况下,KCL 在专用位置中维护包的副本。 - -## Module - -KCL 模块按目录层次结构布置配置。它包含了确定 KCL 配置结果所需的一切。此目录的根标记为包含 `kcl.mod` 目录。此目录的内容大多由 kcl 工具(如 `kpm` 等)管理。从这个意义上讲,`kcl.mod` 类似于 `.git` 目录,标记着仓库的根目录,但它的内容主要由 git 工具管理。此外,KCL 模块是文件组织的最大单位,具有所有 KCL 文件和依赖项的固定位置。 - -> 注意: 使用 KCL 模块(例如 `kcl.mod`)是可选的,但如果您想使用语义版本管理、分发、共享和重用代码,则需要使用它。 - -### 创建一个 module - -可以通过在模块根目录中运行以下命令来创建模块: - -```bash -kpm init [module name] -``` - -模块名在需要在模块内导入另一个模块的包时是**必需的**。也可以通过手动设置 `kcl.mod` 文件来创建模块。 - -## Package - -在 KCL 中,一个包通常由包含 KCL 文件的“文件夹”组成。这个文件夹可以是实际的磁盘物理路径,也可以由多个 KCL 文件(通常是主包)组成。不同的包通过不同的包路径(如 `kubernetes.core.v1`)唯一地定位。 - -在同一个模块内,可以通过相对或绝对路径的 import 语句互相导入不同的包。在 KCL 解析过程中,相对 import 将被替换为绝对 import,并通过包路径找到相应的 KCL 代码。 - -### 相对导入路径 - -我们可以使用 `.` 运算符来实现 KCL 入口文件的相对路径导入。 - -main.k: - -```python -import .model1 # Current directory module -import ..service # Parent directory -import ...root # Parent of parent directory - -s = service.ImageService {} -m = root.Schema {} -``` - -### 绝对导入路径 - -KCL 语句`import a.b.c.d` 的语义是: - -1. 如果 `kcl.mod` 不存在,则将当前目录视为包根目录,并从当前目录搜索路径 `a/b/c/d`。 -2. 如果当前目录搜索失败,则从根路径 `ROOT_PATH/a/b/c/d` 搜索,否则引发导入错误。 - -根路径 `ROOT_PATH` 的定义是相对于 `kcl.mod` 文件的目录。 - -代码结构: - -```bash -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -### 内置包 - -KCL 有一系列内置包,例如 `math`,`regex` 等。要使用内置包,直接导入并使用其限定标识符调用函数。例如, - -```python -import regex - -image = "nginx:1.14.2" -is_match = regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$") - -``` - -输出的 YAML 为 - -```yaml -image: nginx:1.14.2 -is_match: true -``` - -### 插件包 - - - -KCL 还有一系列插件包,例如 `hello`,`project_context` 等。要使用插件包,需要用 `kcl_plugin.` 包路径前缀导入,并使用其限定标识符调用函数。例如, - -```python -import kcl_plugin.hello - -result = hello.add(1, 1) -``` - -输出的 YAML 为 - -```yaml -result: 2 -``` - -### 主包 - -在 KCL 中,主包的组成通常由编译器参数确定。这是因为KCL模式和约束可以在包中的文件中分隔,甚至可以在目录中组织,考虑将配置写入和维护在隔离块中的便利性。 - -#### 属于主包的文件 - -用户可以使用KCL命令行决定使用哪些配置和约束,例如, - -```bash -kcl file1.k file2.k -``` - -因此,主包包含两个名为 `file1.k` 和 `file2.k` 的 KCL 文件。 - -如果 KCL 被告知为特定目录加载文件,例如: - -```bash -kcl ./path/to/package -``` - -它将只查找 `.k` 后缀的 KCL 文件,并忽略 `_` 或 `_test.k` 前缀的 KCL 文件合并到主包中。此外,如果 `./path/to/package` 包含 `kcl.yaml` 文件,则 `kcl.yaml` 文件将被忽略。 - -此外,我们可以通过配置命令行编译设置文件(例如 `kcl.yaml`)来设置主包文件,如下所示: - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k -``` - -```bash -kcl -Y kcl.yaml -``` - -> 注意:如果没有为 KCL 指定任何输入文件,KCL 将从命令行执行路径查找默认的 `kcl.yaml` 文件读取输入文件。此外,如果我们告诉KCL输入文件和编译设置文件,KCL将把用户输入的输入文件作为最终值。 - -```bash -# 无论`kcl.yaml` 中是否配置 `files` 字段,输入文件的最终值为["file1.k", "file2.k"] -kcl -Y kcl.yaml file1.k file2.k -``` - -## kcl.mod 和 kcl.yaml 异同 - -首先,在 KCL 中,`kcl.mod` 和 `kcl.yaml` 都是可选的。它们之间的区别在于 `kcl.mod` 确定包路径的根路径以及 KCL 模块是否具有分发和重用要求,而 `kcl.yaml` 确定主包的 KCL 文件组成。 - -其次,对于仅用于外部使用的 kcl module,`kcl.yaml` 是可选的,但 `kcl.mod` 是必需的,因为 `kcl.mod` 需要声明 KCL 版本,模块版本,依赖关系和其他信息。 - -最后,对于 KCL IDE 插件,它需要知道主包信息才能形成完整的编译过程,因此它需要根据光标位置自动查找主包组成,因为没有人可以通过 KCL 命令行指定这些信息。一般的查询逻辑是查找 `kcl.yaml` 的存在性。如果找到了,主包由 `kcl.yaml` 中的文件属性组成,如果找不到,主包由当前文件组成。KCL IDE 插件会有选择地了解 `kcl.mod` 文件。当 `kcl.mod` 文件存在时,IDE 插件会读取所有包路径及其在外部依赖项中的实际路径的相应信息。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/concepts/type-and-definition.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/concepts/type-and-definition.md deleted file mode 100644 index 7331c007..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/concepts/type-and-definition.md +++ /dev/null @@ -1,94 +0,0 @@ -# 类型和定义 - -This section mainly covers the concepts related to types and definitions. - -## 类型 - -KCL features a **gradual static type system**, initially designed to consider scalability. Its aim is to significantly reduce the configuration writing difficulties for users while maintaining stability. Static typing enhances code quality, acts as documentation, and helps detect errors at an early stage when needed. For instance, defining a complete static type for data like JSON/YAML can be challenging, similar to how TypeScript adds complexity in handling type gymnastics due to the lack of runtime type checks for Javascript. In contrast, KCL incorporates a similar TypeScript type system while still retaining runtime type checks. Thus, type errors will always appear at runtime. Consequently, KCL has types, but they can be selectively used when necessary, and it handles interactions between typed and untyped code elegantly and securely. - -The configuration of attributes and types in KCL usually follows a simple pattern: - -$$ -k = (T) v -$$ - -where $k$ is the attribute name, $v$ is the attributes value, and $T$ is the type annotation. Since KCL has the ability of the type inference, $T$ is usually omitted. - -By default, KCL does not require type annotations and performs type checks at runtime. - -```python -name = "nginx" # The type of `name` is `str` -port = 80 # The type of `port` is `int` -``` - -As long as we operate on basic types such as integers and strings, it is generally sufficient to annotate the default type and directly write the configuration. KCL can infer the type of basic data. We recommend writing types for complex structures and function definitions, which will clearly provide a good input prompt for other users who use structures and functions. - -```python -# Types for schema -schema App: - name: str - domainType: "Standard" | "Customized" | "Global" - containerPort: int - volumes: [Volume] - services: [Service] - - check: - 1 <= containerPort <= 65535 - -schema Service: - clusterIP: str - $type: str - - check: - clusterIP == "None" if $type == "ClusterIP" - -schema Volume: - container: str = "*" # The default value of `container` is "*" - mountPath: str - - check: - mountPath not in ["/", "/boot", "/home", "dev", "/etc", "/root"] - -# Types for lambda -appFilterFunc = lambda apps: [App], name: str -> [App] { - [a for a in apps if a.name == name] -} -``` - -More formal definitions and usage of types are at the [type specification document](/docs/reference/lang/types/) and the [tour document of the type system](/docs/reference/lang/tour#type-system) - -**Schema** is the core type in KCL, just like a database schema, which defines the organization of configuration data. This includes logical constraints such as schema names, fields, data types, and the relationships between these entities. Patterns typically use visual representations to convey the architecture of a database, becoming the foundation for organizing configuration data. The process of designing schema patterns is also known as configuration modeling. KCL Schema typically serves various roles, such as application developers, DevOps platform administrators, and SRE, and provides them with a unified configuration interaction interface. - -In addition, the ability to enforce constraints from top to bottom is crucial for any large-scale configuration setting. Therefore, KCL not only provides the ability to define static types but also provides the rich ability to define constraints, which is to some extent equivalent to assertion statements in programming languages. To prevent assertions from constantly expanding, we place structural constraints together with structural type definitions and support custom error messages. - -In KCL, we can use schema to organize the configuration data to meet the requirements of model definition, abstraction, and templating. Schema is the core feature of KCL, which defines attributes, operations, and check-blocks. Usually, a formal form of KCL Schema can be written in the following form: - -$$ -S = \Sigma_{i = 1}^{N} \{s_i, T_i, \mathcal{T}[s_i]\}, -$$ - -where $N$ is the total number of attributes, $\mathcal{T}$ is the attribute constraint, $s_i$ and $T_i$ denotes the $i$-th attribute name and type. Simultaneously, to improve the reusability of the code and meet the needs of hierarchical definition, KCL draws on the experience of OOP and uses single inheritance to reuse and extend the schema. Schema inheritance can be regarded as a special type of partial order relationship, and satisfies - -$$ -unionof(T_1, T_2) = T_2 \Leftrightarrow T_1 \subseteq T_2, -$$ - -where $T_1$ and $T_2$ are both schema types. When the above equation is not satisfied, the KCL will throw a type check error. - -A typical schema with constraints is defined as follows: - -```python -import regex - -schema Secret: - name: str - # Data defines the keys and data that will be used by secret. - data?: {str:str} - - check: - all k in data { - regex.match(k, r"[A-Za-z0-9_.-]*") - } if data, "a valid secret data key must consist of alphanumeric characters, '-', '_' or '.'" -``` - -More specifications and usage of KCL schema and constraint is [here](/docs/reference/lang/spec/schema). diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/getting-started/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/getting-started/_category_.json deleted file mode 100644 index c826d665..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/getting-started/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "快速开始", - "position": 1 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/getting-started/kcl-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/getting-started/kcl-quick-start.md deleted file mode 100644 index 8d75e878..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/getting-started/kcl-quick-start.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -sidebar_position: 3 ---- - -# KCL 语言速览 - -KCL 是一个面相云原生配置策略领域的编程语言。KCL 设计之初受 Python3 启发,同时吸收了声明式、OOP 编程范式的设计理念,是一种专用于配置策略定义、校验的静态强类型的面相配置和策略场景的语言。本节我们将快速展示 KCL 语言的基本特性。 - -## 1. Hello KCL - -学习新语言的最佳途径是自己亲手写几个小程序,配置语言也是如此。KCL 作为一种配置策略语言,我们可以像写配置一样写 KCL 程序。 - -下面是一个简单的 `hello.k` 程序: - -```python -hello = "KCL" -``` - -将 `hello` 属性设置为 `"KCL"` 字符串。然后将代码保存到 `hello.k` 文件中。 - -如何执行这个程序取决于具体的开发环境,我们先假设本地的 macOS 或者是 Linux 系统已经安装了 `kcl` 命令(或者通过 `docker run --rm -it kcllang/kcl` 进入 Docker 环境测试)。然后在文件所在的目录命令行输入以下命令执行: - -```shell -kcl hello.k -``` - -输出为 - -```yaml -hello: KCL -``` - -命令行执行的效果如图所示: - -![](/img/docs/user_docs/getting-started/hello.gif) - -输出的是 YAML 格式的配置数据。这个程序虽然简单,但是我们可以通过执行 KCL 配置程序到输出结果验证了开发环境和 `kcl` 命令行的基本用法。 - -## 2. 再复杂一点的配置 - -常见的配置数据除了的普通的 key-value 对,还有嵌套的字典和列表类型,同时 value 基础类型除了字符串还有布尔和数值等类型。下面是更为复杂一点的 `server.k` 配置: - -```python -# This is a KCL document - -title = "KCL Example" - -owner = { - name = "The KCL Authors" - data = "2020-01-02T03:04:05" -} - -database = { - enabled = True - ports = [8000, 8001, 8002] - data = [["delta", "phi"], [3.14]] - temp_targets = {cpu = 79.5, case = 72.0} -} - -servers = [ - {ip = "10.0.0.1", role = "frontend"} - {ip = "10.0.0.2", role = "backend"} -] -``` - -其中 `#` 开头的表示行注释。`owner` 的 value 是一个字典,字典的面值通过 `{}` 方式包含的内容,字典内部的 key-value 和 `hello = "KCL"` 例子的写法类似。`database` 则是另一个字典,其中字典属性的 value 出现了布尔 `True`、列表 `[]` 和 `{}` 字典,其中列表和字典中还出现了数值类型的 value。 最后一个 `servers` 属性则是一个列表,列表内部嵌套着字典(字典和列表以及后续将要讲到的 `schema` 都可以相互嵌套)。 - -该配置输出的 YAML 结果如下: - -```yaml -$ kcl server.k -title: KCL Example -owner: - name: The KCL Authors - data: '2020-01-02T03:04:05' -database: - enabled: true - ports: - - 8000 - - 8001 - - 8002 - data: - - - delta - - phi - - - 3.14 - temp_targets: - cpu: 79.5 - case: 72.0 -servers: -- ip: 10.0.0.1 - role: frontend -- ip: 10.0.0.2 - role: backend -``` - -## 3. schema 定义配置的结构 - -KCL 通过 `schema` 语法结构为有着固定属性结构和默认值行为的属性提供抽象支持。 - -比如上面例子的中 `database` 的配置一般是用默认值即可。这样我们可以通过为数据库的默认配置定义一个结构: - -```python -schema DatabaseConfig: - enabled: bool = True - ports: [int] = [8000, 8001, 8002] - data: [[str|float]] = [["delta", "phi"], [3.14]] - temp_targets: {str: float} = {cpu = 79.5, case = 72.0} -``` - -`enabled` 是布尔类型;`ports` 为整数列表类型;`data` 为列表的列表,内层的列表元素是字符串或者浮点数类型;`temp_targets` 则是一个字典类型,字典的属性值是浮点数类型。并且 `DatabaseConfig` 的每个属性都定义了默认值。 - -然后通过 `database = DatabaseConfig {}` 就可以产生和默认值相同属性的结构。用户也可以修改默认值: - -```python -database = DatabaseConfig { - ports = [2020, 2021] -} -``` - -`schema DatabaseConfig` 不仅仅为属性提供了默认值,还为属性添加了类型信息。因此,如果用户不小心写错属性值类型的话,KCL 将会给出友好的错误提示,比如下面的例子将 `ports` 错误地写成了浮点数类型: - -```python -database = DatabaseConfig { - ports = [1.2, 1.3] -} -``` - -执行时将产生类似以下的错误(显示的文件路径和本地环境有关): - -```shell -kcl server.k -``` - -输出为 - -```shell -error[E2G22]: TypeError - --> /path/to/server.k:8:5 - | -8 | ports = [1.2, 1.3] - | ^ expected [int], got [float(1.2)|float(1.3)] - | - - --> /path/to/server.k:3:5 - | -3 | ports: [int] = [8000, 8001, 8002] - | ^ variable is defined here, its type is [int], but got [float(1.2)|float(1.3)] - | -``` - -类似地我们可以用以下的代码封装 `servers` 部分的属性: - -```python -schema ServerConfig: - ip: str - role: "frontend" | "backend" - -servers = [ - ServerConfig {ip = "10.0.0.1", role = "frontend"} - ServerConfig {ip = "10.0.0.2", role = "backend"} -] -``` - -其中 `ServerConfig` 的 `ip` 是字符串类型,并没有给出默认值。用户在生成 `ServerConfig` 类型的属性时必须手工添加 `ip` 属性的值,否则 KCL 将会报出缺少必填属性的错误。`role` 属性是 `"frontend" | "backend"` 枚举字符串类型。 - -此外,`schema` 还可以结合 `check`、`mixin`、可选属性、继承和扩展模块实现更为复杂的配置和策略数据的抽象,细节可以参考手册部分的文档。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/_category_.json deleted file mode 100644 index 1fdf894e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "用户手册", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/abstraction.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/abstraction.md deleted file mode 100644 index da590317..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/abstraction.md +++ /dev/null @@ -1,149 +0,0 @@ ---- -title: "抽象" -sidebar_position: 3 ---- - -## 什么是抽象 - -抽象是指一个实体的简化表示,它允许隐藏特定的具体细节,同时向程序员提供最相关的信息。每一个抽象都是为满足特定需求而定制的,并且可以极大地提高给定实体的可用性。在 KCL 的上下文中,抽象可以使代码更容易理解和维护,同时也可以简化用户界面。 - -需要注意的是,代码抽象并不是为了减少代码大小,而是为了提高代码的可维护性和可扩展性。在抽象代码的过程中,应考虑可重用性、可读性和可扩展性等因素,并根据需要对代码进行不断优化。 - -良好的抽象可以提供如下价值 - -1. 提供不同的焦点,不同角色和场景关注点分离。 -2. 屏蔽较低级别的细节,避免潜在的错误。 -3. 提升用户界面和自动化友好性。 - -KCL 自身可能不会评估用户定义模型抽象的合理性,但它提供了技术解决方案来帮助用户构建抽象。 - -## 使用 KCL 进行抽象 - -现在,让我们将 Docker Compose 和 Kubernetes 资源抽象为应用程序配置 - -`Docker Compose` 是一个用于定义和运行多容器 Docker 应用程序的工具。使用 Docker Compose,您可以在一个文件中定义应用程序的服务、网络和卷,然后使用它作为一个单元启动和停止应用程序。Docker Compose 通过处理网络、存储和其他基础设施问题的细节,简化了运行复杂的多容器应用程序的过程。 - -Kubernetes 清单是定义 Kubernete 对象(如 Pods、Deployments 和 Services)的 YAML 文件。清单提供了一种声明性的方法来定义应用程序的所需状态,包括副本数量、要使用的镜像和网络配置。Kubernetes 使用清单来创建和管理部署和运行应用程序所需的资源。 - -以下是一些参考资料,可以帮助了解更多关于 Docker Compose 和 Kubernetes 相关的信息: - -- [Docker Compose 文档](https://docs.docker.com/compose/) -- [Kubernetes 对象文档](https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/) - -以应用程序为中心的开发使开发人员能够专注于其工作负载的体系结构,而不是目标环境、基础设施或平台中的技术栈。我们用 `App` 结构定义了应用程序模型,然后使用 KCL CLI 将其翻译到多个平台,例如不同版本的 `Docker Compose` 或 `Kubernetes`。该应用程序模型旨在通过只需定义一个跨多个平台工作的 KCL 文件来减少开发人员的工作量和认知负荷。现在,让我们学习如何做到这一点。 - -### 0. 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. 获取示例 - -首先,我们执行 git 命令获得用例 - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/abstraction -``` - -我们可以运行以下命令来显示配置。 - -```bash -cat main.k -``` - -输出为 - -```python -import .app - -app.App { - name = "app" - containers.nginx = { - image = "nginx" - ports = [{containerPort = 80}] - } - service.ports = [{ port = 80 }] -} -``` - -在上面的代码中,我们使用 `App` schema 定义了一个配置,其中我们配置了一个 `nginx` 容器,并开启 `80` 端口配置。 - -此外,KCL 允许开发人员以声明式的方式定义应用程序所需的资源,并允许生成特定于平台的配置文件,如 `docker_compose.yaml` 或 Kubernetes `manifests.yaml` 文件。接下来,让我们生成相应的配置。 - -### 2. 将应用配置转换为 Docker Compose 配置 - -如果我们想将应用程序配置转换为 Docker Compose 配置,我们可以简单地运行如下命令: - -```shell -kcl main.k docker_compose_render.k -``` - -输出为 - -```yaml -services: - app: - image: nginx - ports: - - published: 80 - target: 80 - protocol: TCP -``` - -### 3. 将应用配置转换为 Kubernetes Deployment and Service 资源清单 - -如果我们想将应用程序配置转换为 Kubernetes 清单,我们可以简单地运行如下命令: - -```shell -kcl main.k kubernetes_render.k -``` - -输出为 - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: app - labels: - app: app -spec: - replicas: 1 - selector: - matchLabels: - app: app - template: - metadata: - labels: - app: app - spec: - containers: - - name: nginx - image: nginx - ports: - - protocol: TCP - containerPort: 80 ---- -apiVersion: v1 -kind: Service -metadata: - name: app - labels: - app: app -spec: - selector: - app: app - ports: - - port: 80 - protocol: TCP -``` - -如果您想了解有关应用程序模型的更多信息,可以参考[此处](https://github.com/kcl-lang/kcl-lang.io/tree/main/examples/abstraction). - -## 小结 - -通过使用 KCL,我们能够分离模型的抽象和实现细节,允许将抽象模型映射到各种基础设施或平台。这是通过不同实现之间的灵活切换和 KCL 组合编译来实现的,以屏蔽配置差异,减轻认知负担。 - -## 更多信息 - -除了手动维护配置外,我们还可以使用 KCL API 将**自动配置更改能力**集成到我们的应用程序中。有关 KCL 自动化能力的相关说明,请参阅[此处](/docs/user_docs/guides/automation)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/ci-integration/1-github-actions.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/ci-integration/1-github-actions.md deleted file mode 100644 index b93fdec9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/ci-integration/1-github-actions.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -id: github-actions -sidebar_label: Github Actions ---- - -# Github Actions 集成 - -## 简介 - -在 GitOps 章节,我们介绍了如何将 KCL 与 GitOps 进行集成。在本文中,我们将继续提供 KCL 和 CI 集成的示例方案,希望通过使用容器、用于生成的持续集成 (CI) 和用于持续部署 (CD) 的 GitOps 来实现端到端应用程序开发流程。在此方案中,我们使用一个 Flask 应用和 Github Actions 将用作示例。 - -> 注意:你可以在此方案中使用任何容器化应用以及不同的 CI 系统如 Gitlab CI,Jenkins CI 等。 - -整体工作流程如下: - -- 应用代码开发并提交到提交到 GitHub 存储库 -- GitHub Actions 从应用代码生成容器镜像,并将容器镜像推送到 docker.io 容器注册表 -- GitHub Actions 根据 docker.io 容器注册表中容器镜像的版本号并同步更新 KCL 清单部署文件 - -## 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -## 具体步骤 - -### 1. 获得示例 - -我们将业务源码和部署清单放在不同仓库,可以分不同角色进行分别维护,实现关注点分离。 - -- 获得业务源码 - -```shell -git clone https://github.com/kcl-lang/flask-demo.git/ -cd flask-demo -``` - -这是一个使用 Python 编写的 Web 应用,我们可以使用应用目录的 `Dockerfile` 来生成这个应用的容器镜像,同时可以通过 Github CI 自动构建 `flask_demo` 镜像,CI 配置如下 - -```yaml -# This is a basic workflow to help you get started with Actions - -name: CI - -# Controls when the workflow will run -on: - # Triggers the workflow on push or pull request events but only for the main branch - push: - branches: [main] - pull_request: - branches: [main] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "build" - build: - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - - - name: Docker Login - uses: docker/login-action@v1.10.0 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - logout: true - - # Runs a set of commands using the runners shell - - name: build image - run: | - make image - docker tag flask_demo:latest ${{ secrets.DOCKER_USERNAME }}/flask_demo:${{ github.sha }} - docker push ${{ secrets.DOCKER_USERNAME }}/flask_demo:${{ github.sha }} - - # Trigger KCL manifest - - name: Trigger CI - uses: InformaticsMatters/trigger-ci-action@1.0.1 - with: - ci-owner: kcl-lang - ci-repository: flask-demo-kcl-manifests - ci-ref: refs/heads/main - ci-user: kcl-bot - ci-user-token: ${{ secrets.DEPLOY_ACCESS_TOKEN }} - ci-name: CI - ci-inputs: >- - image=${{ secrets.DOCKER_USERNAME }}/flask_demo - sha-tag=${{ github.sha }} -``` - -我们需要源码仓库的工作流自动触发部署清单仓库中的工作流,此时需要创建具有 Github CI 操作权限的 `secrets.DEPLOY_ACCESS_TOKEN` 以及 Docker Hub 镜像推送的账号信息 `secrets.DOCKER_USERNAME` 和 `secrets.DOCKER_PASSWORD`, 这些可以在 Github 仓库的 `Secrets and variables` 设置中进行配置,如下图所示 - -![](/img/docs/user_docs/guides/ci-integration/github-secrets.png) - -### 2. 提交应用代码 - -flask-demo 仓库提交代码后,Github 会自动构建容器镜像,并将制品推送到 Docker hub 中,会再触发 flask-demo-kcl-manifests 仓库的 Action,[通过 KCL 自动化 API](/docs/user_docs/guides/automation) 修改部署清单仓库中的镜像地址。现在让我们为 flask-demo 仓库创建一个提交,我们可以看到代码提交后触发业务仓库 Github CI 流程 - -![](/img/docs/user_docs/guides/ci-integration/app-ci.png) - -### 3. 配置自动更新 - -当业务仓库 Github CI 流程执行完成后,会自动在存放 KCL 资源配置的仓库触发一个 CI 自动更新配置并提交到 flask-demo-kcl-manifests main 分支,commit 信息如下 - -![](/img/docs/user_docs/guides/ci-integration/image-auto-update.png) - -- 我们可以获得部署清单源码进行编译验证 - -```shell -git clone https://github.com/kcl-lang/flask-demo-kcl-manifests.git/ -cd flask-demo-kcl-manifests -git checkout main && git pull && kcl -``` - -输出 YAML 为 - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - replicas: 1 - selector: - matchLabels: - app: flask_demo - template: - metadata: - labels: - app: flask_demo - spec: - containers: - - name: flask_demo - image: "kcllang/flask_demo:6428cff4309afc8c1c40ad180bb9cfd82546be3e" - ports: - - protocol: TCP - containerPort: 5000 ---- -apiVersion: v1 -kind: Service -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - type: NodePort - selector: - app: flask_demo - ports: - - port: 5000 - protocol: TCP - targetPort: 5000 -``` - -从上述配置可以看出资源的镜像确实自动更新为了新构建的镜像内容。此外,我们还可以使用 Argo CD KCL 插件 自动从 Git 存储库同步或从中拉取数据并将应用部署到 Kubernetes 集群。 - -## 小结 - -通过将 KCL 和 Github CI 集成,我们能够将任意的业务代码的产出容器化镜像进行自动化修改并部署配置,以实现端到端应用程序开发流程并提升研发部署效率。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/ci-integration/_2-gitlab-ci.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/ci-integration/_2-gitlab-ci.md deleted file mode 100644 index 5ec96ce9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/ci-integration/_2-gitlab-ci.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -id: gitlab-ci -sidebar_label: Gitlab CI ---- - -Coming Soon - -## Introduction - -## How to - -## Summary diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/ci-integration/_3-jenkins-ci.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/ci-integration/_3-jenkins-ci.md deleted file mode 100644 index f85d231f..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/ci-integration/_3-jenkins-ci.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -id: github-ci -sidebar_label: Github CI ---- - -Coming Soon - -## Introduction - -## How to - -## Summary diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/ci-integration/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/ci-integration/_category_.json deleted file mode 100644 index 3145ed7f..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/ci-integration/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "CI Integration", - "position": 12 -} \ No newline at end of file diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/configuration.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/configuration.md deleted file mode 100644 index 127505c9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/configuration.md +++ /dev/null @@ -1,129 +0,0 @@ ---- -title: "配置" -sidebar_position: 1 ---- - -## 简介 - -配置是软件系统的一个重要方面,由于不断发展的业务需求、基础设施需求和其他因素,这些系统会不断发生变化。通常,快速改变这些系统的行为可能具有挑战性,尤其是当这样做需要昂贵且耗时的重建和重新部署过程时。在这种情况下,仅仅对业务代码进行更改可能是不够的。幸运的是,配置提供了一种低开销的方式来修改系统功能。 - -我们可以根据需要将静态配置存储在 JSON 或 YAML 等文件中。此外,配置也可以存储在高级语言中,从而实现更灵活的配置。这种语言可以进行编码、呈现和静态配置。KCL 是一种提供此类功能的配置语言。开发人员可以编写 KCL 代码来生成JSON/YAML 和其他配置。 - -## 使用 KCL 编写配置代码 - -KCL 的核心特性是其**建模**和**约束**能力,KCL 核心功能基本围绕 KCL 这个两个核心特性展开,对于代码而言(包括配置代码)都存在对配置数据约束的需求,比如类型约束、配置字段必选/可选约束、范围约束、不可变性约束等,这也是 KCL 致力于解决的核心问题之一。 - -现在我们已经了解了 KCL 的基本功能,让我们探索如何使用它来生成配置。 - -### 0. 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. 获取示例 - -首先,执行如下命令获取示例 - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/configuration -``` - -我们可以执行如下命令显示配置代码 - -```shell -cat nginx.k -``` - -输出为: - -```python -schema Nginx: - """Schema for Nginx configuration files""" - http: Http - -schema Http: - server: Server - -schema Server: - listen: int | str # The attribute `listen` can be int type or a string type. - location?: Location # Optional, but must be non-empty when specified - -schema Location: - root: str - index: str - -nginx = Nginx { - http.server = { - listen = 80 - location = { - root = "/var/www/html" - index = "index.html" - } - } -} -``` - -### 2. 使用 KCL 生成 YAML - -执行如下命令: - -```bash -kcl nginx.k -``` - -我们可以获得如下 YAML 输出 - -```yaml -nginx: - http: - server: - listen: 80 - location: - root: /var/www/html - index: index.html -``` - -### 3. 为配置添加动态参数 - -此外,我们可以通过 KCL 内置函数 `option` 动态接收外部参数。例如,对于下面的 KCL 文件(db.k),我们可以使用命令行 `-D` 标志来接收外部动态参数。 - -```python -env: str = option("env") or "dev" # The attribute `env` has a default value "den" -database: str = option("database") -hosts = { - dev = "postgres.dev" - stage = "postgres.stage" - prod = "postgres.prod" -} -dbConfig = { - host = hosts[env] - database = database - port = "2023" - conn = "postgres://${host}:${port}/${database}" -} -``` - -```bash -# Use the `-D` flag to input external parameters. -kcl db.k -D database="foo" -``` - -输出为 - -```yaml -env: dev -database: foo -hosts: - dev: postgres.dev - stage: postgres.stage - prod: postgres.prod -dbConfig: - host: postgres.dev - database: foo - port: "2023" - conn: "postgres://postgres.dev:2023/foo" -``` - -## 小结 - -通过使用KCL,我们可以生成更低低级别的数据配置。此外啊,我们通过 `-D` 标志设置动态参数以满足不同的场景需求。有关更多 KCL 的功能和教程,请参阅[此处](/docs/reference/lang/tour)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/data-integration.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/data-integration.md deleted file mode 100644 index 89511b2e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/data-integration.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: "数据集成" -sidebar_position: 4 ---- - -## 简介 - -在 KCL 中,不仅可以将 KCL 编写的配置代码编译输出为 YAML 格式的数据,还可以将 JSON/YAML 等数据直接嵌入到 KCL 语言当中。 - -## 使用 KCL 进行数据集成 - -### 0. 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. 获得示例 - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/data-integration -``` - -### 2. YAML 集成 - -我们可以运行以下命令来显示 KCL YAML 集成配置。 - -```bash -cat yaml.k -``` - -```python -import yaml - -schema Server: - ports: [int] - -server: Server = yaml.decode("""\ -ports: -- 80 -- 8080 -""") -server_yaml = yaml.encode({ - ports = [80, 8080] -}) -``` - -在上述代码中,我们通过 KCL 内置的 `yaml` 模块以及其中的 `yaml.decode` 直接完成 YAML 数据的集成,并且使用 `Server` schema 对集成的 YAML 数据直接进行校验。此外,我们可以使用 `yaml.encode` 完成 YAML 数据的序列化。 - -我们通过如下命令可以获得配置输出: - -```shell -kcl yaml.k -``` - -输出为 - -```yaml -server: - ports: - - 80 - - 8080 -server_yaml: | - ports: - - 80 - - 8080 -``` - -### 3. JSON 集成 - -同样的,对于 JSON 数据,我们可以使用 `json.encode` 和 `json.decode` 函数以同样的方式进行数据集成。 - -我们可以运行以下命令来显示 KCL JSON 集成配置。 - -```bash -cat json.k -``` - -```python -import json - -schema Server: - ports: [int] - -server: Server = json.decode('{"ports": [80, 8080]}') -server_json = json.encode({ - ports = [80, 8080] -}) -``` - -执行命令输出为: - -```shell -kcl json.k -``` - -```yaml -server: - ports: - - 80 - - 8080 -server_json: '{"ports": [80, 8080]}' -``` - -## 小结 - -本文介绍了如何在 KCL 中进行数据集成,使用 KCL 内置的 yaml 和 json 包将 YAML 和 JSON 数据直接集成到 KCL 语言中,并使用相应的解码和编码功能对其进行验证和序列化。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/gitops/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/gitops/_category_.json deleted file mode 100644 index 29a73c67..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/gitops/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "GitOps", - "position": 11 -} \ No newline at end of file diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md deleted file mode 100644 index 23dd53a5..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md +++ /dev/null @@ -1,73 +0,0 @@ -# 发布 KCL 包到 ghcr.io - -本文将指导您如何使用 kcl 包管理将您的 kcl 包推送到发布到 OCI Registry 中。kcl 包管理默认使用 [ghcr.io](https://ghcr.io) 作为 OCI Registry, 您可以通过修改 kcl 包管理配置文件来更改默认的 OCI Registry。关于如何修改 kcl 包管理配置文件的信息,请参阅 [kcl oci registry](https://github.com/kcl-lang/kpm/blob/main/docs/kpm_oci-zh.md#kpm-registry) - -下面是一个简单的步骤,指导您如何使用 kcl 包管理将您的 kcl 包推送到 ghcr.io。 - -## 步骤 1:安装 KCL CLI - -首先,您需要在您的计算机上安装 KCL CLI。您可以按照 [KCL CLI 安装文档](https://kcl-lang.io/zh-CN/docs/user_docs/getting-started/install)中的说明进行操作。 - -## 步骤 2:创建一个 ghcr.io 令牌 - -如果您使用默认的 OCI Registry, 要将 kcl 包推送到 ghcr.io,您需要创建一个用于身份验证的令牌。您可以参考以下文档。 - -- [创建 ghcr.io token](https://docs.github.com/zh/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic) - -## 步骤 3:登录 ghcr.io - -在安装了 kcl 包管理并创建了 ghcr.io 令牌后,您需要使用 kcl 包管理登录 ghcr.io。您可以使用以下命令进行操作: - -```shell -kcl registry login -u -p ghcr.io -``` - -其中 `` 是您的 GitHub 用户名,`` 是您在步骤 2 中创建的令牌。 - -关于如何使用 kcl 包管理登录 ghcr.io 的更多信息,请参阅 [kcl registry login](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/login)。 - -## 步骤 4:推送您的 kcl 包 - -现在,您可以使用 kcl 包管理将您的 kcl 包推送到 ghcr.io。 - -### 1. 一个合法的 kcl 包 - -首先,您需要确保您推送的内容是符合一个 kcl 包的规范,即必须包含合法的 kcl.mod 和 kcl.mod.lock 文件。 - -如果您不知道如何得到一个合法的 `kcl.mod` 和 `kcl.mod.lock`。您可以使用 `kcl mod init` 命令。 - -```shell -# 创建一个名为 my_package 的 kcl 包 -kcl mod init my_package -``` - -`kcl mod init my_package` 命令将会为您创建一个新的 kcl 包 `my_package`, 并为这个包创建 `kcl.mod` 和 `kcl.mod.lock` 文件。 - -如果您已经有了一个包含 kcl 文件的目录 `exist_kcl_package`,您可以使用以下命令将其转换为一个 kcl 包,并为其创建合法的 `kcl.mod` 和 `kcl.mod.lock`。 - -```shell -# 在 exist_kcl_package 目录下 -$ pwd -/home/user/exist_kcl_package - -# 执行 kcl 包管理init 命令来创建 kcl.mod 和 kcl.mod.lock -$ kcl mod init -``` - -关于如何使用 kcl 包管理init 的更多信息,请参阅 [kcl mod init](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/init)。 - -### 2. 推送 kcl 包 - -您可以在 `kcl` 包的根目录下使用以下命令进行操作: - -```shell -# 在 exist_kcl_package 包的根目录下 -$ pwd -/home/user/exist_kcl_package - -# 推送 kcl 包到默认的 OCI Registry -$ kcl mod push -``` - -完成上述步骤后,您就成功地将您的 kcl 包推送到了默认的 OCI Registry 中。 -关于如何使用 kcl mod push 的更多信息,请参阅 [kcl mod push](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/push)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md deleted file mode 100644 index 9bb9f1cc..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md +++ /dev/null @@ -1,65 +0,0 @@ -# 发布 KCL 包到 docker.io - -本文将指导您如何使用 kcl 包管理将您的 kcl 包推送到发布到 docker.io 中。 - -## 步骤 1:安装 KCL CLI - -首先,您需要在您的计算机上安装 KCL CLI。您可以按照 [KCL CLI 安装文档](https://kcl-lang.io/zh-CN/docs/user_docs/getting-started/install)中的说明进行操作。 - -## 步骤 2:创建一个 docker.io 账户 - -您需要创建一个 docker.io 账户以支持您的 kcl 包的推送。 - -## 步骤 3:登录 docker.io - -您可以直接使用 docker.io 的账户名和密码登录。 - -```shell -kcl registry login -u -p docker.io -``` - -其中 `` 是您的 docker.io 用户名,`` 是您 docker.io 账户的密码。 - -关于如何使用 KCL CLI 登录 docker.io 的更多信息,请参阅 [kcl registry login](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/login)。 - -## 步骤 4:推送您的 kcl 包 - -现在,您可以使用 KCL CLI 将您的 kcl 包推送到 docker.io。 - -### 1. 一个合法的 kcl 包 - -首先,您需要确保您推送的内容是符合一个 kcl 包的规范,即必须包含合法的 kcl.mod 和 kcl.mod.lock 文件。 - -如果您不知道如何得到一个合法的 `kcl.mod` 和 `kcl.mod.lock`。您可以使用 `kcl mod init` 命令。 - -例如:创建一个名为 my_package 的 kcl 包 - -```shell -# 创建一个名为 my_package 的 kcl 包 -kcl mod init my_package -``` - -`kcl mod init my_package` 命令将会为您创建一个新的 kcl 包 `my_package`, 并为这个包创建 `kcl.mod` 和 `kcl.mod.lock` 文件。 - -如果您已经有了一个包含 kcl 文件的目录 `exist_kcl_package`,您可以使用以下命令将其转换为一个 kcl 包,并为其创建合法的 `kcl.mod` 和 `kcl.mod.lock`。 - -在 `exist_kcl_package` 目录下执行: - -```shell -kcl mod init -``` - -关于如何使用 kpm init 的更多信息,请参阅 [kcl mod init](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/init)。 - -### 2. 推送 kcl 包 - -您可以在 `kcl` 包的根目录下使用以下命令进行操作: - -在 `exist_kcl_package` 包的根目录下, 执行 - -```shell -kcl mod push oci://docker.io//exist_kcl_package -``` - -完成上述步骤后,您就成功地将您的 kcl 包 `exist_kcl_package` 推送到了 docker.io 中。 -关于如何使用 kcl mod push 的更多信息,请参阅 [kcl mod push](https://kcl-lang.io/zh-CN/docs/tools/cli/package-management/command-reference/push)。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/package-management/4-how-to/6-push_github_action.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/package-management/4-how-to/6-push_github_action.md deleted file mode 100644 index 2f18b66f..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/package-management/4-how-to/6-push_github_action.md +++ /dev/null @@ -1,83 +0,0 @@ -# 如何在 github action 中使用 kcl 包管理发布您的 KCL 包 - -本文将指导您如何在 GitHub Action 中使用 kcl 包管理将您的 kcl 包推送到发布到 ghcr.io 中。 - -## 步骤 1:安装 KCL CLI - -首先,您需要在您的计算机上安装 KCL CLI。您可以按照 [KCL CLI 安装文档](https://kcl-lang.io/zh-CN/docs/user_docs/getting-started/install)中的说明进行操作。 - -## 步骤 2:创建一个 GitHub 账号 - -如果您已经有 GitHub 帐号了,您可以选择跳过这一步 - -[注册新的一个 GitHub 账号](https://docs.github.com/zh/get-started/signing-up-for-github/signing-up-for-a-new-github-account) - -## 步骤 3: 为您的 KCL 包创建一个 GitHub 仓库并进行相关配置 - -### 1. 为您的 KCL 程序包准备仓库 - -您需要为您的 KCL 程序包准备一个 GitHub 仓库。 - -[创建一个 GitHub 仓库](https://docs.github.com/zh/get-started/quickstart/create-a-repo) - -在这个仓库中添加您的 KCL 程序,以仓库 https://github.com/awesome-kusion/catalog.git 为例, - -```bash -├── .github -│ └── workflows -│ └── push.yaml # github action 文件 -├── LICENSE -├── README.md -├── kcl.mod # kcl.mod 将当前仓库内容定义为一个 kcl 包 -├── kcl.mod.lock # kcl.mod.lock 是 kcl 包管理工具自动生成的文件 -└── main.k # 您的 KCL 程序 -``` - -### 2. 为您的仓库设置 OCI Registry,账户和密码 - -以 docker.io 为例,您可以为您的仓库设置 secrets `REG`, `REG_ACCOUNT` 和 `REG_TOKEN`。`REG` 的值为 `docker.io`,`REG_ACCOUNT` 的值为您的 docker.io 账户, `REG_TOKEN` 为您的 `docker.io` 登录密码。 - -[为仓库添加 secrets](https://docs.github.com/zh/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) - -如果您使用 `ghcr.io` 作为 `Registry`, 您需要使用 GitHub token 作为 secrets。 - -[创建一个 GitHub Token](https://docs.github.com/zh/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#personal-access-tokens-classic) - -## 步骤 4: 将您的 KCL 包添加到仓库中并编写 github action workflow - -为这个仓库添加 github action 文件 `.github/workflows/push.yml`,内容如下: - -```yaml -name: KPM Push Workflow - -on: - push: - branches: - - main - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Set up Go 1.21 - uses: actions/setup-go@v2 - with: - go-version: 1.21 - - - name: Install KCL CLI - run: go install kcl-lang.io/cli/cmd/kcl@latest - - - name: Login and Push - env: - # 通过环境变量指定 OCI Registry 和账户 - KPM_REG: ${{ secrets.REG }} - KPM_REPO: ${{ secrets.REG_ACCOUNT }} - # kcl registry login 时使用 secrets.REG_TOKEN - run: kcl registry login -u ${{ secrets.REG_ACCOUNT }} -p ${{ secrets.REG_TOKEN }} ${{ secrets.REG }} && kcl mod push - - - name: Run KCL project from oci registry - run: kcl run oci://${{ secrets.REG }}/${{ secrets.REG_ACCOUNT }}/catalog --tag 0.0.1 -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/package-management/4-how-to/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/package-management/4-how-to/_category_.json deleted file mode 100644 index 370cb4e9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/package-management/4-how-to/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "如何使用", - "position": 4 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/schema-definition.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/schema-definition.md deleted file mode 100644 index 735667b9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/schema-definition.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -title: "模型定义" -sidebar_position: 3 ---- - -## 简介 - -KCL 的核心场景是写配置和校验,因此 KCL 被设计之初的一个核心特性就是**建模**,对应到 KCL 的关键字 `schema`,`schema` 可以被用于定义结构和约束,比如字段的类型,默认值,字段的范围和各种其他约束等内容。此外,使用 KCL schema 定义的结构可以反过来用于验证实现、验证输入(JSON、YAML 等结构化数据)或生成代码(生成多语言结构体、OpenAPI 等)。 - -## 使用 KCL 定义结构和约束 - -### 0. 先决条件 - -- 安装 [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. 获得示例 - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/definition -``` - -我们可以执行如下命令显示配置 - -```bash -cat main.k -``` - -输出为 - -```python -import .app_module # A relative path import - -app: app_module.App { - domainType = "Standard" - containerPort = 80 - volumes = [ - { - mountPath = "/tmp" - } - ] - services = [ - { - clusterIP = "None" - $type = "ClusterIP" - } - ] -} -``` - -我们将 `App` 模型放入单独的 `app_module.k` 中,在需要时我们可以在 `main.k` 中使用 `import` 关键字进行模块化管理,比如下面的文件结构 - -``` -. -├── app_module.k -└── main.k -``` - -其中 `app_module.k` 的内容为 - -```python -schema App: - domainType: "Standard" | "Customized" | "Global" - containerPort: int - volumes: [Volume] - services: [Service] - - check: - 1 <= containerPort <= 65535 - -schema Service: - clusterIP: str - $type: str - - check: - clusterIP == "None" if $type == "ClusterIP" - -schema Volume: - container: str = "*" # `container` 的默认值为 "*" - mountPath: str - - check: - mountPath not in ["/", "/boot", "/home", "dev", "/etc", "/root"] -``` - -在上面的文件中。在其中,我们使用 `schema` 关键字定义了三个模型 `App`,`Service` 和 `Volume`。并且 `App` 模型具有四个属性 `domainType`, `containerPort`, `volumes` 和 `services`,其中 - -- `domainType` 的类型为字符串字面值联合类型,与“枚举”类似,这表明 `domainType` 的值只能取 `"Standard"`, `"Customized"` 和 `"Global"` 中的一个 -- `containerPort` 的类型为整数 `int`, 此外我们使用 `check` 关键字定义了其取值范围 1 ~ 65535 -- `services` 的类型为 `Service` 列表类型,`Service`,并且我们用 `?` 标记了它是一个可选属性,这意味着我们可以不为其赋值。 -- `volumes` 的类型为 `Volume` 列表类型,并且我们用 `?` 标记了它是一个可选属性,这意味着我们可以不为其赋值。 - -### 2. 输出配置 - -我们可以使用如下命令行可以获得 `app` 实例的 YAML 输出 - -```shell -kcl main.k -``` - -输出为 - -```yaml -app: - domainType: Standard - containerPort: 80 - volumes: - - container: "*" - mountPath: /tmp - services: - - clusterIP: None - type: ClusterIP -``` - -## 小结 - -KCL 是一种用于定义配置和约束的语言,其核心功能是使用 schema 关键字进行建模,schema 允许定义具有属性、默认值、范围检查和其他约束的结构。使用 KCL schema 定义的结构可以用于验数据或生成代码。该文档演示了如何使用 schema 定义模型,使用 import 导入模型进行模块化管理,并使用 kcl 命令输出已定义结构实例的 YAML 配置。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/secret-management/1-vault.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/secret-management/1-vault.md deleted file mode 100644 index f070a784..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/secret-management/1-vault.md +++ /dev/null @@ -1,142 +0,0 @@ ---- -id: vault -sidebar_label: Vault ---- - -# Vault - -## 简介 - -This guide will show you that KCL solves the secret management problem by integrating [Vault](https://developer.hashicorp.com/vault) and [Vals](https://github.com/helmfile/vals). - -## 先决条件 - -- Install [KCL](/docs/user_docs/getting-started/install) -- Prepare a [Kubernetes Cluster](https://kubernetes.io/) -- Install [Vault](https://developer.hashicorp.com/vault/downloads) -- Install [Vals](https://github.com/helmfile/vals) - -## 具体步骤 - -### 1. 获得示例 - -We put the application source code and infrastructure deployment code in different repos, which can be maintained by different roles to achieve the separation of concerns. - -- Get the application code - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/secret-management/vault -``` - -- Show the config - -```shell -cat main.k -``` - -The output is - -```python -# Secret Management using Vault and Vals - -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" - annotations: { - "secret-store": "vault" - # Valid format: - # "ref+vault://PATH/TO/KV_BACKEND#/KEY" - "foo": "ref+vault://secret/foo#/foo" - "bar": "ref+vault://secret/bar#/bar" - } -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -The main.k file extends the configuration of the Nginx application and customizes annotations. Among them, the value of annotation `foo` and `bar` follow secret reference format (`ref+vault://PATH/TO/KV_BACKEND#/KEY`): - -- `ref+vault`: indicates that this is a secret reference, and the external storage service is `Vault`. -- `PATH/TO/KV_BACKEND`: specifies the path where a secret is stored. -- `KEY`: specifies the key to reading secret. - -The complete format is concatenated using a style similar to URI expressions, which can retrieve a secret stored externally. - -### 2. 预存敏感信息 - -Start the Vault Server - -```shell -vault server -dev -export VAULT_ADDR='http://127.0.0.1:8200' -# Note: Replace with your token -export VAULT_TOKEN=yourtoken -``` - -After Vault is started in development mode and unpacked, secrets are pre-stored, and the path and keys are consistent with `main.k`: - -```shell -vault kv put secret/foo foo=foo -vault kv put secret/bar bar=bar -``` - -### 3. 部署配置 - -Using the following command to apply the deployment manifest. - -```shell -kcl main.k | vals eval -f - | kubectl apply -f - -``` - -The expect output is - -```shell -deployment.apps/nginx created -``` - -### 4. 验证敏感信息 - -Next, verify that the secrets have been retrieved from Vault and replace the values of annotations of Nginx: - -- Verify the `foo` annotation - -```shell -kubectl get deploy nginx -o yaml | grep 'foo:' -``` - -The output is - -```yaml -foo: foo -``` - -- Verify the `bar` annotation - -```shell -kubectl get deploy nginx -o yaml | grep 'bar:' -``` - -The output is - -```yaml -bar: bar -``` - -So far, we have retrieved the secrets hosted in `Vault` and put them into use. - -## 小结 - -This guide introduces how KCL solves the secret management by integrating Vault and Vals. By following these steps, we can retrieve the secrets hosted in Vault and utilize them. diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/secret-management/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/secret-management/_category_.json deleted file mode 100644 index c57bb30e..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/secret-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Secret Management", - "position": 13 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md deleted file mode 100644 index 1981ae3d..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: "KPT KCL SDK" -sidebar_position: 4 ---- - -## 简介 - -[kpt](https://github.com/GoogleContainerTools/kpt) 是一个以包为中心的工具链,可实现配置原地编辑、自动化和交付,通过将声明性配置作为数据进行操作,从而简化 Kubernetes 平台和 KRM 驱动的基础设施(例如,Config Connector、Crossplane)的大规模管理,以实现 Kubernetes 配置编辑的自动化包括转换和验证。 - -KCL 可用于创建函数来转换和/或验证 YAML Kubernetes 资源模型 (KRM) 输入/输出格式,但我们提供 KPT KCL SDK 来简化函数编写过程。 - -## 先决条件 - -- 安装 [kpt](https://github.com/GoogleContainerTools/kpt) -- 安装 [Docker](https://www.docker.com/) - -## 快速开始 - -让我们编写一个仅向 Deployment 资源添加 annotation `managed-by=kpt` 的 KCL 函数 - -### 1. 获取示例 - -```bash -git clone https://github.com/kcl-lang/kpt-kcl-sdk.git/ -cd ./kpt-kcl-sdk/get-started/set-annotation -``` - -### 2. 显示 KRM - -```bash -kpt pkg tree -``` - -输出为 - -```bash -set-annotation -├── [kcl-fn-config.yaml] KCLRun set-annotation -└── data - ├── [resources.yaml] Deployment nginx-deployment - └── [resources.yaml] Service test -``` - -### 3. 显示和更新 KCL `FunctionConfig` - -```bash -cat ./kcl-fn-config.yaml -``` - -输出为 - -```yaml -# kcl-fn-config.yaml -apiVersion: krm.kcl.dev/v1alpha1 -kind: KCLRun -metadata: # kpt-merge: /set-annotation - name: set-annotation -spec: - # 编辑此源代码 - # 您在此的 KCL 代码将 `ResourceList` 预加载到 `option("resource_list")` - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "kpt"}} for resource in option("resource_list").items] -``` - -### 4. 测试和运行 - -通过 kpt 运行 KCL 代码 - -```bash -kpt fn eval ./data -i docker.io/kcllang/kpt-kcl:v0.2.0 --fn-config kcl-fn-config.yaml - -# 验证 annotation 是否添加到 `Deployment` 资源并且其他资源 `Service` 没有这个 annotation。 -cat ./data/resources.yaml | grep annotations -A1 -B0 -``` - -输出为 - -```bash - annotations: - managed-by: kpt -``` - -可以看出,我们确实成功添加了 `managed-by=kpt` 标签 - -## 更多文档和示例 - -- [KPT KCL SDK](https://github.com/kcl-lang/kpt-kcl-sdk) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json deleted file mode 100644 index 6e90c03c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Mutate or Validate Kubernetes Manifests", - "position": 3 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/_category_.json deleted file mode 100644 index 42681f2b..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Kubernetes", - "position": 9 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/index.md deleted file mode 100644 index 8d6340de..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/index.md +++ /dev/null @@ -1 +0,0 @@ -# Kubernetes diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-konfig/4-best-practice.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-konfig/4-best-practice.md deleted file mode 100644 index c4bf4b08..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-konfig/4-best-practice.md +++ /dev/null @@ -1,271 +0,0 @@ ---- -id: practice -sidebar_label: 最佳实践 ---- - -# 最佳实践 - -本文档旨在讲解新的业务模型接入 Konfig 大库以及 KCL 代码模型设计与编写的最佳实践,新业务模型一般采用前-后端模型分离的最佳实践进行设计与抽象,区分前端模型和后端模型的直接目的是将「用户界面」和「模型实现」进行分离,实现用户友好的简单的配置界面以及自动化配置增删改查接口。 - -## 工作流程 - -![](/img/docs/user_docs/guides/konfig/workflow.png) - -1. 首先使用 KCL OpenAPI 工具生成下游所需配置的 KCL 模型代码,对于 Kubernetes 模型;可以根据 CRD 或者 Swagger Model 生成,对于其他场景,可以使用 Terraform provider schema、Java Class 或者 Go Struct 生成相应 KCL Schema (建设中),作为后端模型并存放在 "基础配置代码" 中; -2. 使用 KCL 开发工具(包括 KCL 编译器、KCL format,doc,lint,test 等工具和 IDE 插件等),根据业务语义抽象前端模型; -3. 依据 Project & Stack 方式在 Konfig 仓库中组织用户侧配置代码(主要是对前端模型的实例化),Konfig 会自动根据 project.yaml 和 stack.yaml 文件进行测试; -4. 最后编译 KCL 代码生成 YAML,通过测试后,利用 CI/CD 流程完成配置的 diff 与分发。 - -## 模型结构 - -正如 web 应用会提供友好的用户界面,而在应用的后端对用户输入进行进一步推演得到最终落库的数据,类似地,使用 KCL 进行模型设计时同样遵循前后端分离的逻辑。此外当下游所需的数据内容发生变化时,我们仅需修改用户配置数据到后端模型的渲染/逻辑即可,从而避免了大规模修改用户配置的情况。以应用服务的 sidecar 配置为例,直接暴露给用户的只有 `user_sidecar_feature_gates`,而最终交给下游处理的数据中,则应是把 `user_sidecar_feature_gates` 作为 `sidecars` 配置的一部分包装起来的结果。比如如下代码: - -```python -# 用户可配的: -user_sidecar_feature_gates: str - -# 下游能处理的: -sidecars = [ - { - name = "sidecar_name" # sidecars 参数的额外模版参数,用户不需要进行配置 - feature_gates = user_sidecar_feature_gates - } -] -``` - -## Konfig 建模的一些最佳实践 - -### 使用一个属性代替配置模板 - -对于一些后端模型所需要填写的配置字段往往是大而全的设计,需要用户主动输入较为复杂的配置模版,并且不同用户对于该字段的填写内容基本一致,比如在下面示出的超卖逻辑的配置就需要用户填写大量的模板数据,心智成本较高。 - -对于此类常用复杂的模板一个简单的最佳实践是在前端模型中抽象为一个简单的 bool 类型的变量 overQuota,让用户做选择题而不是填空题,比如当 overQuota 变量为 True 时,后端模型才会渲染这个复杂逻辑。 - -- 前端模型属性 `overQuota` - -```python -overQuota: bool -``` - -- 后端模型 YAML 输出 - -```yaml -spec: - template: - spec: - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: k8s/is-over-quota - operator: In - values: - - "true" -``` - -此外也可以根据具体的业务场景设计不同的模版名称来填空,比如如下所示的代码设计一个属性 template 来辅助用户做模版的选择而不是直接填入模板内容。合法的 template 值可以为 "success_ratio" 或者 "service_cost", 当后端模型扩展更多的模版时,前端代码无需作出任何修改,仅需在后端模型中适配相应模板逻辑即可。 - -```python -schema SLI: - template: str = "success_ratio" -``` - -此外,尽量不采用复杂的结构直接作为前端模型属性,避免用户使用该模型时需要借助过多的 KCL 语法特性(比如解包、循环等特性)或者书写很多临时变量完成该结构的实例化。 - -### 使用字面值类型和联合类型 - -在上述小节提到了可以使用一个字符串属性表示不同的模板名称,更进一步地是可以使用字面值类型表述 template 可选的内容,比如可以进行如下改进。 - -```python -schema SLI: - template: "success_ratio" | "service_cost" = "success_ratio" -``` - -其中 template 的类型为两个字符串类型的联合,表示 template 只能为 "success_ratio" 或者 "service_cost",当用户填写了其他字符串的值时,KCL 编译器会进行报错。 - -除了对字面值类型使用联合类型外,KCL 还支持对复杂类型如 schema 类型的联合。对于这种后端 oneof 配置的支持,KCL 内置了复合结构的联合类型进行支持。比如我们可以针对多种种场景定义自己的 SLI 前端类型:CustomSliDataSource,PQLSLIDataSource 和 StackSLIDataSource。 - -```python -schema CustomSLIDataSource: - customPluginUrl: str - -schema PQLSLIDataSource: - total?: str - error?: str - success?: str - cost?: str - count?: str - -schema StackSLIDataSource: - stack: str - groupBy?: str - metric?: str - -# Simplify type definitions using type aliases -type DataSource = CustomSLIDataSource | PQLSLIDataSource | StackSLIDataSource - -schema DataConfiguration: - sources: {str: DataSource} -``` - -这样前端模型设计的好处是编译器可以静态地检查出用户书写的类型只能是某一种类型,如果直接使用后端模型无法从模型上直接获得不同类型 type 与需要填写字段的映射关系。 - -此外,前端模型的整体设计上也应该考虑横向扩展性,尽可能地采用联合类型,充分利用代码化的优势,避免对接不同后端或者后端模型发生改变时带来不必要的大量代码前端代码与用户代码重构与修改。此外,对于其他 GPL 语言中常用的工厂模式,在 KCL 中也可以使用联合类型代替,比如想要根据某个字符串内容获得某个类型的构造函数,可以直接使用联合类型进行优化。 - -KCL 中书写工厂模式 - -```python -schema DataA: - id?: int = 1 - value?: str = "value" - -schema DataB: - name?: str = "DataB" - -_dataFactory: {str:} = { - DataA = DataA - DataB = DataB -} -dataA = _dataFactory["DataA"]() -dataB = _dataFactory["DataB"]() -``` - -使用联合类型替换工厂模式 - -```python -schema DataA: - id?: int = 1 - value?: str = "value" - -schema DataB: - name?: str = "DataB" - -# 直接使用联合类型即可 -dataA: DataA | DataB = DataA() -dataB: DataA | DataB = DataB() -``` - -### 列表/数组属性字典化 - -为了便于作配置的原地修改或者程序自动化查询修改,尽量将列表/数组属性定义为字典类型方便索引,因为在大部分配置场景对于复杂结构的列表类型,列表的索引 0, 1, 2, ..., n 不具备任何业务含义,列表中元素的顺序对该列表配置无任何影响,此时采用字典类型而不是列表类型更方便数据的查询与修改。首先以一个简单例子举例: - -```python -schema Person: - name: str - age: int - -schema House: - persons: [Person] - -house = House { - persons = [ - Person { - name = "Alice" - age = 18 - } - Person { - name = "Bob" - age = 10 - } - ] -} -``` - -比如在上述例子中,想要查询 name 为 "Alice" 的年龄 age, 就需要在 house.persons 这个列表中作遍历才能很查询到 Alice 的 age。而将 persons 定义为如下代码所示的字典,不仅从代码上看起来更加简洁,并且可以通过 house.persons.Alice.age 直接获得 Alice 的 age,并且整个配置的信息完整且无冗余信息。 - -```python -schema Person: - age: int - -schema House: - persons: {str: Person} # 将 persons 定义为字典而不是数组 - -house = House { - persons = { - Alice = Person { age = 18 } - Bob = Person { age = 10 } - } -} -``` - -### 为模型书写校验表达式 - -对于前端模型,往往需要对用户填写的字段进行校验,此时可以使用 KCL 的 check 表达式与 KCL 的内置函数/语法/系统库进行配合对字段进行校验。对于前端模型的校验尽可能直接书写在前端模型的定义中进行校验前置,避免错误传递到后端模型中发生意想不到的错误。 - -使用 all/any 表达式与 check 表达式进行校验 - -```python -import regex - -schema ConfigMap: - name: str - data: {str:str} - configMounts?: [ConfigMount] - - check: - all k in data { - regex.match(k, r"[A-Za-z0-9_.-]*") - }, "a valid config key must consist of alphanumeric characters, '-', '_' or '.'" - -schema ConfigMount: - containerName: str - mountPath: str - subPath?: str - - check: - ":" not in mountPath, "mount path must not contain ':'" -``` - -### 使用数值单位类型 - -KCL 中带单位的数字具有一个内置的类型 units.NumberMultiplier, 不允许进行任意四则运算。 - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -x0: NumberMultiplier = 1M # Ok -x1: NumberMultiplier = x0 # Ok -x2 = x0 + x1 # Error: unsupported operand type(s) for +: 'number_multiplier(1M)' and 'number_multiplier(1M)' -``` - -可以使用 `int()/float()` 函数和 `str()` 函数将数字单位类型转换为整数类型或者字符串类型,产生的字符串保留原有数字单位类型的单位。 - -```python -a: int = int(1Ki) # 1024 -b: str = str(1Mi) # "1Mi" -``` - -对于在 Konfig 中的 Kubernetes Resource 资源相关的定义均可使用数值单位类型进行书写 - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -schema Resource: - cpu?: NumberMultiplier | int = 1 - memory?: NumberMultiplier = 1024Mi - disk?: NumberMultiplier = 10Gi - epchygontee?: int -``` - -### 前端模型实例的自动化修改 - -在 KCL,可以通过命令行和 API 界面实现对前端模型实例的自动化修改,比如想要修改某个应用(Konfig Stack Path: appops/nginx-example/dev)配置的镜像内容,可以直接执行如下指令修改镜像 - -```python -kcl -Y kcl.yaml ci-test/settings.yaml -o ci-test/stdout.golden.yaml -d -O :appConfiguration.image=\"test-image-v1\" -``` - -更多与自动化相关的使用文档请参考 [自动化](/docs/user_docs/guides/automation) 一节 - -### 为模型添加代码注释 - -为便于用户理解以及模型文档自动生成,需要对定义的模型编写注释,注释内容一般包括模型的解释,模型字段的解释,类型,默认值,使用样例等。详细的 KCL Schema 代码注释编写规范以及模型文档自动生成可以参考 [KCL 文档规范](/docs/tools/cli/kcl/docgen) - -## 后端模型 - -后端模型是「模型实现」,主要包括将前端模型映射为后端模型的逻辑代码。当编写完成前端模型后,我们可以使用前端模型 Schema 新建前端模型的实例 instance 并编写相应的后端映射/渲染代码将这些前端 instance 转换为后端模型,并且利用 KCL 多文件编译和 `Schema.instances()` 函数可以做到前端代码和后端代码的高度解耦,用户仅需关心前端的配置而不感知模型复杂的校验、逻辑判断等代码。 diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-konfig/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-konfig/_category_.json deleted file mode 100644 index a71426f9..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-konfig/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Konfig", - "position": 10 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-kusion/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-kusion/_category_.json deleted file mode 100644 index 9f914498..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-kusion/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KusionStack", - "position": 15 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-kusion/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-kusion/index.md deleted file mode 100644 index 2906ab83..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-kusion/index.md +++ /dev/null @@ -1,15 +0,0 @@ -# KusionStack - -**KusionStack 是开源的云原生可编程技术栈!** - -KusionStack 是一个可编程、高灵活性的应用交付及运维技术栈,灵感源于融合(Fusion)一词,旨在帮助企业构建的应用运维配置管理平面及 DevOps 生态。 - -1. 融合**专有云**,**混合云**,**多云**混合场景 -2. 融合以**云原生技术**为主,同时采用**多种平台技术**的混合平台技术选型 -3. 融合**多项目**、**多团队**、**多角色**、**多租户**、**多环境**的企业级诉求 - -基于 Platform as Code (平台服务即代码)理念,研发者可以快速收敛围绕**应用运维生命周期**的全量配置定义,面向**混合技术体系及云环境**,完成从应用运维研发到上线的**端到端工作流程**,真正做到**一处编写,随处交付**。 - -![](/img/docs/user_docs/intro/kusion-stack-1.png) - -更多文档请参考: [https://kusionstack.io/](https://kusionstack.io/) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/support/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/support/_category_.json deleted file mode 100644 index d670513b..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/support/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "常见问答", - "position": 6 -} diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/support/faq-cli.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/support/faq-cli.md deleted file mode 100644 index 035c021c..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/support/faq-cli.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -sidebar_position: 4 ---- - -# 命令行工具 - -## 1. Konfig 大库应用目录下的 settings.yaml 文件的作用是什么? - -KCL 中 settings.yaml 文件表示 KCL 命令行工具的配置参数文件,可以将编译的配置放入其中进行调用比如需要编译的文件,需要输入的 option 动态参数 `-d`,是否需要忽略掉空值 None `-n` 等配置。 - -比如对于如下的命令行运行参数 - -```shell -kcl main.k -D key=value -n -r -``` - -就可以使用如下的命令行参数和 settings.yaml 配置文件代替 - -```shell -kcl -Y settings.yaml -``` - -settings.yaml - -```yaml -kcl_cli_configs: - files: - - main.k - disable_none: true - strict_range_check: true -kcl_options: - - key: key - value: value -``` - -- `kcl_cli_configs` 表示可以配置的编译参数,`file` 用于配置编译的 KCL 文件,`disable_none` 表示是否使用 `-n` 参数,`strict_range_check` 表示是否使用 `-r` 参数。 -- `kcl_options` 表示可以配置的动态参数,`key` 表示动态参数的名称,`value` 表示动态参数的值 - -注意:settings.yaml 的文件名称可替换,只要其中的配置结构满足规定即可 - -## 2. 如何传入动态参数?如何在代码中获取命令行传入的动态参数? - -KCL 支持多种方式传入动态参数 - -- `-D`: 使用 KCL 命令行的-D 参数可以直接传入动态参数,支持基本数据类型 str/int/float/bool, 以及结构数据类型 list/dict - -```shell -kcl main.k -D env-type=TEST -D deploy-topology='[{"cluster":"my-cluster","idc":"my-idc","replicas":2,"workspace":"my-idc","zone":"my-zone"}]' -``` - -- `-Y`: 使用 KCL 命令行的-Y 参数可以间接通过配置文件传入动态参数: - -```yaml -kcl_options: - - key: env-type - value: TEST - - key: deploy-topology - value: - - cluster: my-cluster - idc: my-idc - replicas: 2 - workspace: my-workspace - zone: my-zone -``` - -在代码中使用内置的 option 函数获取即可 - -```python -env = option("env-type") -deploy_topology = option("deploy-topology") -``` - -输出 YAML - -```yaml -env: TEST -deploy_topology: - - cluster: my-cluster - idc: my-idc - replicas: 2 - workspace: my-workspace - zone: my-zone -``` - -## 3. 如何使用 kcl 的多文件编译特性? - -- 使用 KCL 命令行工具直接书写多文件编译 - -```shell -kcl file1.k file2.k file3.k -``` - -- 在配置文件中配置并配合 KCL 命令行工具参数 `-Y` 使用 - -settings.yaml - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - - file3.k -``` - -```shell -kcl -Y settings.yaml -``` diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/support/faq-yaml.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/support/faq-yaml.md deleted file mode 100644 index 4dd12c00..00000000 --- a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/support/faq-yaml.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -sidebar_position: 3 ---- - -# YAML 语法 - -## 1. YAML 字符串使用单引号和双引号的区别是什么? - -- YAML 双引号字符串是唯一能够表达任意字符串的样式,通过使用 `\` 转义字符,比如使用 `\"` 转义双引号 `"`,使用 `\\` 转义反斜杠 `\`,并且可以使用单个反斜杠 `\` 作为双引号字符串的续行符 -- YAML 单引号字符串与 YAML 双引号字符串不同的是可以自由地使用 `\` 和 `"` 而不需要转义,但是使用两个单引号 `''` 转义单引号 `'` 字符 - -比如对于如下的例子,三个字符串变量的内容是相同的 - -```yaml -string1: 'here '' s to "quotes"' -string2: 'here''s to "quotes"' -string3: here's to "quotes" -``` - -因此,KCL 输出 YAML 字符串的策略是当字符串内容出现单引号时,优先输出无引号字符串或双引号字符串,其他情况输出单引号字符串以避免理解上的负担。 - -更多细节可参考: [YAML 规范 v1.2](https://yaml.org/spec/1.2.1/) - -## 2. YAML 中出现的 | - + > 等符号是什么含义? - -在使用 KCL 多行字符串(使用三引号括起来的字符串),输出的 YAML 经常会携带一些特殊的记号,如 `|`,`-`,`+` 和 `>` 等,这些记号通常为 YAML 多行字符串的表示方法,比如对于如下 KCL 代码: - -```python -data = """This is a KCL multi line string (the first line) -This is a KCL multi line string (the second line) -This is a KCL multi line string (the third line) - - -""" -var = 1 -``` - -输出 YAML 为: - -```yaml -data: |+ - This is a KCL multi line string (the first line) - This is a KCL multi line string (the second line) - This is a KCL multi line string (the third line) - - -var: 1 -``` - -- `|` 表示**块字符串样式**,用于表示一个多行字符串,其中的所有换行符都表示字符串真实的换行; -- `>` 表示**块折叠样式**,在其中所有的换行符将被空格替换; -- `+` 和 `-` 用于控制在字符串末尾使用换行符的情况。默认情况为字符串末尾保留单个换行符,如果要删除所有换行符,可以在样式指示符 `|` 或 `>` 后面放置一个 `-` 来完成,如果要保留末尾的换行符,则需要在 `|` 或 `>` 后面放置一个 `+` - -更多细节可参考: [YAML 多行字符串](https://yaml-multiline.info/) 和 [YAML 规范 v1.2](https://yaml.org/spec/1.2.1/) - -## 3. YAML 中在 | - + > 等符号之后出现的数字是什么含义? - -数字表示 YAML 当中的**显式缩进指示符**。对于 YAML 中的长字符串,YAML 通常第一个非空行确定字符串的缩进级别,而当第一个非空行前面具有非前导字符时,比如换行符,YAML 要求必须使用**显式缩进指示符**来指定内容的缩进级别,比如 `|2` 和 `|1` 等 - -比如对于如下 KCL 代码: - -```python -longStringStartWithNewline = """ -This is the second line -This is the third line -""" - -``` - -```yaml -longStringStartWithNewline: |2 - - This is the second line - This is the third line -``` - -如果不需要长字符串开头的空行或换行符,则可以以如下两种方式进行 KCL 长字符串书写 - -- 长字符串从第 1 行开始书写 - -```python -longString = """This is the second line -This is the third line -""" -``` - -- 使用续行符 - -```python -longString = """\ -This is the second line -This is the third line -""" -``` - -以上两种方式输出的 YAML 均为: - -```yaml -longString: | - This is the second line - This is the third line -``` - -更多细节可参考: [YAML 规范 v1.2](https://yaml.org/spec/1.2.1/) diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/contribute/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/contribute/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/contribute/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/contribute/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/contribute/contribute-code.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/contribute/contribute-code.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/contribute/contribute-code.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/contribute/contribute-code.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/contribute/contribute-docs.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/contribute/contribute-docs.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/contribute/contribute-docs.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/contribute/contribute-docs.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/contribute/contribute.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/contribute/contribute.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/contribute/contribute.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/contribute/contribute.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/contribute/git-guideline.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/contribute/git-guideline.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/contribute/git-guideline.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/contribute/git-guideline.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/intro/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/intro/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/intro/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/intro/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/intro/intro.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/intro/intro.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/intro/intro.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/intro/intro.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/intro/license.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/intro/license.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/intro/license.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/intro/license.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/intro/support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/intro/support.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/intro/support.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/intro/support.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/release-policy/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/release-policy/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/release-policy/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/release-policy/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/release-policy/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/release-policy/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/release-policy/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/release-policy/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/release-policy/kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/release-policy/kcl.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/community/release-policy/kcl.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/release-policy/kcl.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/release-policy/roadmap.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/release-policy/roadmap.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/community/release-policy/roadmap.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/community/release-policy/roadmap.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/cheatsheets/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/cheatsheets/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/cheatsheets/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/cheatsheets/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/cheatsheets/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/cheatsheets/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/cheatsheets/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/cheatsheets/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/codelab/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/codelab/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/codelab/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/codelab/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/codelab/collaborative.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/codelab/collaborative.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/codelab/collaborative.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/codelab/collaborative.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/codelab/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/codelab/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/codelab/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/codelab/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/codelab/schema.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/codelab/schema.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/codelab/schema.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/codelab/schema.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/codelab/simple.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/codelab/simple.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/codelab/simple.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/codelab/simple.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/error/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/error/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/error/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/error/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/error/exception.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/error/exception.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/error/exception.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/error/exception.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/error/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/error/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/error/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/error/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/spec/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/spec/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/spec/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/spec/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/codestyle.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/spec/codestyle.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/codestyle.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/spec/codestyle.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/spec/datatypes.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/spec/datatypes.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/spec/datatypes.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/spec/datatypes.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/error.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/spec/error.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/error.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/spec/error.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/spec/expressions.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/spec/expressions.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/spec/expressions.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/spec/expressions.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/spec/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/spec/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/spec/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/spec/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/kcl-spec.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/spec/kcl-spec.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/kcl-spec.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/spec/kcl-spec.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/spec/lexical.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/spec/lexical.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/spec/lexical.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/spec/lexical.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/modules.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/spec/modules.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/modules.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/spec/modules.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/schema.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/spec/schema.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/schema.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/spec/schema.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/statements.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/spec/statements.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/spec/statements.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/spec/statements.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/spec/variables.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/spec/variables.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/spec/variables.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/spec/variables.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/tour.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/tour.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/lang/tour.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/tour.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/types/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/types/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/types/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/types/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/types/types.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/types/types.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/types/types.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/lang/types/types.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/base64.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/base64.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/base64.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/base64.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/builtin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/builtin.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/builtin.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/builtin.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/crypto.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/crypto.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/crypto.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/crypto.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/datetime.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/datetime.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/datetime.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/datetime.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/file.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/file.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/file.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/file.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/json.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/json.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/json.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/json.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/manifests.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/manifests.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/manifests.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/manifests.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/math.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/math.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/math.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/math.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/net.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/net.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/net.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/net.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/overview.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/overview.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/regex.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/regex.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/regex.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/regex.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/units.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/units.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/model/units.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/units.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/yaml.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/yaml.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/model/yaml.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/model/yaml.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/plugin/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/plugin/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/plugin/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/plugin/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/plugin/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/plugin/overview.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/plugin/overview.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/plugin/overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/xlang-api/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/xlang-api/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/xlang-api/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/xlang-api/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/xlang-api/go-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/xlang-api/go-api.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/xlang-api/go-api.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/xlang-api/go-api.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/xlang-api/java-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/xlang-api/java-api.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/xlang-api/java-api.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/xlang-api/java-api.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/xlang-api/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/xlang-api/overview.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/xlang-api/overview.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/xlang-api/overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/xlang-api/python-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/xlang-api/python-api.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/xlang-api/python-api.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/xlang-api/python-api.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/xlang-api/rest-api.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/xlang-api/rest-api.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/reference/xlang-api/rest-api.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/reference/xlang-api/rest-api.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/Ide/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/Ide/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/Ide/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/Ide/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/Ide/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/Ide/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/Ide/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/Ide/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/Ide/intellij.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/Ide/intellij.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/Ide/intellij.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/Ide/intellij.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/Ide/neovim.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/Ide/neovim.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/tools/Ide/neovim.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/Ide/neovim.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/Ide/vs-code.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/Ide/vs-code.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/Ide/vs-code.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/Ide/vs-code.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/kcl/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/kcl/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/kcl/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/kcl/docgen.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/kcl/docgen.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/kcl/docgen.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/kcl/docgen.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/kcl/fmt.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/kcl/fmt.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/kcl/fmt.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/kcl/fmt.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/kcl/import.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/kcl/import.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/kcl/import.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/kcl/import.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/kcl/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/kcl/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/kcl/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/kcl/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/kcl/lint.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/kcl/lint.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/kcl/lint.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/kcl/lint.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/kcl/overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/kcl/overview.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/kcl/overview.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/kcl/overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/kcl/run.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/kcl/run.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/kcl/run.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/kcl/run.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/kcl/test.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/kcl/test.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/kcl/test.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/kcl/test.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/kcl/vet.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/kcl/vet.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/kcl/vet.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/kcl/vet.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/openapi/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/openapi/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/openapi/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/openapi/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/openapi/crd-to-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/openapi/crd-to-kcl.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/openapi/crd-to-kcl.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/openapi/crd-to-kcl.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/openapi/openapi-to-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/openapi/openapi-to-kcl.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/openapi/openapi-to-kcl.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/openapi/openapi-to-kcl.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/openapi/spec.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/openapi/spec.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/tools/cli/openapi/spec.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/openapi/spec.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/package-management/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/package-management/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/package-management/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/package-management/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/package-management/command-reference/1.init.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/package-management/command-reference/1.init.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/package-management/command-reference/1.init.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/package-management/command-reference/1.init.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/package-management/command-reference/10.help.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/package-management/command-reference/10.help.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/package-management/command-reference/10.help.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/package-management/command-reference/10.help.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/package-management/command-reference/2.add.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/package-management/command-reference/2.add.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/package-management/command-reference/2.add.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/package-management/command-reference/2.add.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/package-management/command-reference/3.pkg.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/package-management/command-reference/3.pkg.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/package-management/command-reference/3.pkg.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/package-management/command-reference/3.pkg.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/package-management/command-reference/4.metadata.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/package-management/command-reference/4.metadata.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/package-management/command-reference/4.metadata.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/package-management/command-reference/4.metadata.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/package-management/command-reference/6.login.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/package-management/command-reference/6.login.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/package-management/command-reference/6.login.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/package-management/command-reference/6.login.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/package-management/command-reference/7.logout.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/package-management/command-reference/7.logout.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/package-management/command-reference/7.logout.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/package-management/command-reference/7.logout.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/package-management/command-reference/8.push.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/package-management/command-reference/8.push.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/package-management/command-reference/8.push.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/package-management/command-reference/8.push.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/package-management/command-reference/9.pull.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/package-management/command-reference/9.pull.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/tools/cli/package-management/command-reference/9.pull.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/package-management/command-reference/9.pull.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/package-management/command-reference/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/package-management/command-reference/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/tools/cli/package-management/command-reference/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/concepts/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/concepts/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/concepts/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/concepts/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/concepts/concepts.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/concepts/concepts.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/concepts/concepts.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/concepts/concepts.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/concepts/package-and-module.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/concepts/package-and-module.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/concepts/package-and-module.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/concepts/package-and-module.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/concepts/type-and-definition.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/concepts/type-and-definition.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/concepts/type-and-definition.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/concepts/type-and-definition.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/getting-started/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/getting-started/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/getting-started/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/getting-started/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/getting-started/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/getting-started/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/getting-started/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/getting-started/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/getting-started/install.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/getting-started/install.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/getting-started/install.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/getting-started/install.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/getting-started/intro.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/getting-started/intro.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/getting-started/intro.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/getting-started/intro.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/getting-started/kcl-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/getting-started/kcl-quick-start.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/getting-started/kcl-quick-start.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/getting-started/kcl-quick-start.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/abstraction.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/abstraction.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/abstraction.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/abstraction.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/automation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/automation.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/automation.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/automation.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/ci-integration/1-github-actions.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/ci-integration/1-github-actions.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/ci-integration/1-github-actions.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/ci-integration/1-github-actions.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/ci-integration/_2-gitlab-ci.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/ci-integration/_2-gitlab-ci.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/ci-integration/_2-gitlab-ci.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/ci-integration/_2-gitlab-ci.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/ci-integration/_3-jenkins-ci.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/ci-integration/_3-jenkins-ci.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/ci-integration/_3-jenkins-ci.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/ci-integration/_3-jenkins-ci.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/ci-integration/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/ci-integration/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/ci-integration/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/ci-integration/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/configuration.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/configuration.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/configuration.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/configuration.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/data-integration.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/data-integration.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/data-integration.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/data-integration.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/gitops/1-argocd.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/gitops/1-argocd.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/gitops/1-argocd.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/gitops/1-argocd.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/gitops/2-fluxcd.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/gitops/2-fluxcd.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/gitops/2-fluxcd.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/gitops/2-fluxcd.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/gitops/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/gitops/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/gitops/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/gitops/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/package-management/3-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/package-management/3-quick-start.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/package-management/3-quick-start.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/package-management/3-quick-start.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/package-management/4-how-to/6-push_github_action.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/package-management/4-how-to/6-push_github_action.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/package-management/4-how-to/6-push_github_action.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/package-management/4-how-to/6-push_github_action.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/package-management/4-how-to/7-publish_pkg_to_ah.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/package-management/4-how-to/7-publish_pkg_to_ah.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/package-management/4-how-to/7-publish_pkg_to_ah.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/package-management/4-how-to/7-publish_pkg_to_ah.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/package-management/4-how-to/8-kcl_mod.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/package-management/4-how-to/8-kcl_mod.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/package-management/4-how-to/8-kcl_mod.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/package-management/4-how-to/8-kcl_mod.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/package-management/4-how-to/9-kpm_oci.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/package-management/4-how-to/9-kpm_oci.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/package-management/4-how-to/9-kpm_oci.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/package-management/4-how-to/9-kpm_oci.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/package-management/4-how-to/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/package-management/4-how-to/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/package-management/4-how-to/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/package-management/4-how-to/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/package-management/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/package-management/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/package-management/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/package-management/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/schema-definition.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/schema-definition.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/schema-definition.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/schema-definition.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/secret-management/1-vault.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/secret-management/1-vault.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/secret-management/1-vault.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/secret-management/1-vault.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/secret-management/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/secret-management/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/secret-management/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/secret-management/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/validation.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/validation.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/validation.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/validation.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/0-overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-k8s/0-overview.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/0-overview.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-k8s/0-overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/4-publish-modules.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-k8s/4-publish-modules.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-k8s/4-publish-modules.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-k8s/4-publish-modules.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-k8s/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-k8s/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-k8s/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-k8s/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-k8s/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-konfig/1-overview.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-konfig/1-overview.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-konfig/1-overview.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-konfig/1-overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-konfig/2-structure.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-konfig/2-structure.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-konfig/2-structure.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-konfig/2-structure.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-konfig/3-quick-start.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-konfig/3-quick-start.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-konfig/3-quick-start.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-konfig/3-quick-start.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-konfig/4-best-practice.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-konfig/4-best-practice.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-konfig/4-best-practice.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-konfig/4-best-practice.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-konfig/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-konfig/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-konfig/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-konfig/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-kubevela/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-kubevela/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-kubevela/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-kubevela/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-kubevela/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-kubevela/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/guides/working-with-kubevela/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-kubevela/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-kusion/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-kusion/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-kusion/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-kusion/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-kusion/index.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-kusion/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/guides/working-with-kusion/index.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/guides/working-with-kusion/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/support/_category_.json b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/support/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/support/_category_.json rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/support/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/support/faq-cli.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/support/faq-cli.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/support/faq-cli.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/support/faq-cli.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/support/faq-install.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/support/faq-install.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/support/faq-install.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/support/faq-install.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/support/faq-kcl.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/support/faq-kcl.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/support/faq-kcl.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/support/faq-kcl.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/support/faq-yaml.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/support/faq-yaml.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/user_docs/support/faq-yaml.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/support/faq-yaml.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/support/support.md b/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/support/support.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8.0/user_docs/support/support.md rename to i18n/zh-CN/docusaurus-plugin-content-docs/version-0.8/user_docs/support/support.md diff --git a/package.json b/package.json index 8b5ea683..2726bd89 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "kcl-website", - "version": "0.7.0", + "version": "0.8.0", "private": true, "scripts": { "docusaurus": "docusaurus", diff --git a/static/stack/ci-test/settings.yaml b/static/stack/ci-test/settings.yaml deleted file mode 100644 index e69de29b..00000000 diff --git a/static/stack/ci-test/stdout.golden.yaml b/static/stack/ci-test/stdout.golden.yaml deleted file mode 100644 index f27eaf6f..00000000 --- a/static/stack/ci-test/stdout.golden.yaml +++ /dev/null @@ -1,24 +0,0 @@ -- id: apps/v1:Deployment:nginx - type: Kubernetes - attributes: - apiVersion: apps/v1 - kind: Deployment - metadata: - labels: - app: nginx - name: nginx - spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - image: nginx:1.14.2 - name: nginx - ports: - - containerPort: 80 diff --git a/static/stack/kcl.yaml b/static/stack/kcl.yaml deleted file mode 100644 index 98772271..00000000 --- a/static/stack/kcl.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kcl_cli_configs: - files: - - main.k diff --git a/static/stack/main.k b/static/stack/main.k deleted file mode 100644 index f7b05428..00000000 --- a/static/stack/main.k +++ /dev/null @@ -1,22 +0,0 @@ -id = "apps/v1:Deployment:nginx" -$type = "Kubernetes" -attributes = { - apiVersion = "apps/v1" - kind = "Deployment" - metadata = { - name = "nginx" - labels.app = "nginx" - } - spec = { - replicas = 3 - selector.matchLabels.app = "nginx" - template.metadata.labels.app = "nginx" - template.spec.containers = [ - { - name = "nginx" - image = "nginx:1.14.2" - ports = [{ containerPort = 80 }] - } - ] - } -} diff --git a/static/stack/project.yaml b/static/stack/project.yaml deleted file mode 100644 index 0717b13c..00000000 --- a/static/stack/project.yaml +++ /dev/null @@ -1,3 +0,0 @@ -name: project -generator: - type: KCL diff --git a/static/stack/stack.yaml b/static/stack/stack.yaml deleted file mode 100644 index 50ecbd40..00000000 --- a/static/stack/stack.yaml +++ /dev/null @@ -1 +0,0 @@ -name: stack diff --git a/versioned_docs/version-0.5.0/reference/lang/error/exception.md b/versioned_docs/version-0.5.0/reference/lang/error/exception.md deleted file mode 100644 index 92c527a6..00000000 --- a/versioned_docs/version-0.5.0/reference/lang/error/exception.md +++ /dev/null @@ -1,1427 +0,0 @@ ---- -title: "KCL Errors and Warnings" -linkTitle: "KCL Errors and Warnings" -type: "docs" -weight: 2 -description: KCL Errors and Warnings ---- - -The articles in this section of the documentation explain the diagnostic error and warning messages that are generated by the KCL. - -**Important:** -**The KCL can report many kinds of errors and warnings. After an error or warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not apply to your project. When you correct issues in your project, always start with the first error or warning that's reported and rebuild often. One fix may make many subsequent errors go away.** - -In the following sections you will find: - -[KCL Syntax Error (E1xxx)](#11-kcl-syntax-error-e1xxx) : The KCL may reports KCL syntax errors when illegal syntax is used in KCL program. - -[KCL Compile Error (E2xxx)](#12-kcl-compile-error-e2xxx): The KCL may reports KCL compile errors when the KCL program conforms to the KCL syntax but does not conform to the KCL semantics. - -[KCL Runtime Error (E3xxx)](#13-kcl-runtime-error-e3xxx): The KCL may report KCL runtime errors when the virtual machine executing a KCL program that passes the compilation. - -[KCL Compile Warning (W2xxx)](#14-kcl-compile-warning-w2xxx): When the compiler compiles KCL programs and finds possible potential errors, such warnings will be reported by KCL. - -## 1.1 KCL Syntax Error (E1xxx) - -This section mainly includes KCL errors: - -| ewcode | KCL exception | messages | -| ------ | ------------------------------------------------------------------- | ----------------------- | -| E1001 | [InvalidSyntaxError](#111-invalidsyntaxerror-e1001) | Invalid syntax | -| E1002 | [KCLTabError](#112-kcltaberror-e1002) | Tab Error | -| E1003 | [KCLIndentationError](#113-kclindentationerrore1003) | Indentation Error | -| E1I37 | [IllegalArgumentSyntaxError](#114-illegalargumentsyntaxerror-e1i37) | Illegal argument syntax | - -### 1.1.1 InvalidSyntaxError (E1001) - -KCL will report `InvalidSyntaxError` when KCL has a syntax error. - -The `ewcode` of `InvalidSyntaxError` is `E1001`. - -For example: - -```python -a, b = 1, 2 # Multiple assign is illegal in KCL syntax -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> /syntax_error/general/multiple_assign/case0/main.k:1:2 - | -1 | a, b = 1, 2 # Multiple assign is illegal in KCL syntax - | ^ expected statement - | -``` - -Possible resolution: - -- Check and fix KCL syntax errors based on the KCL Language Standard - -### 1.1.2 KCLTabError - -KCL will report `KCLTabError` when KCL has a tab and white space syntax error. - -In KCL, it is forbidden to mix tabs and four spaces in one indentation block. And we recommend only using white spaces or tabs for indentation in the entire KCL project, don’t mix them. - -For example: - -```python -schema Person: - name: str # begin with a tab - age: int # begin with four white spaces, - # and four white spaces != tab in the env -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> File /syntax_error/tab/tab_error_0/main.k:6:5 - | -3 | age: int = 1 - | ^ inconsistent use of tabs and spaces in indentation - | -``` - -Possible resolution: - -- Only use a tab or four white spaces in KCL, do not mix them. - -### 1.1.3 KCLIndentationError - -KCL will report `KCLIndentationError` when KCL has an indentation syntax error. - -The KCL syntax includes indentation. A tab or four white spaces in KCL represents an indentation. The other cases will be regarded as syntax errors by KCL. - -For example: - -```python -schema Person: - name: str # a tab or four white spaces is legal. - age: int # three white spaces are illegal - info: str # two white spaces is illegal -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> /syntax_error/indent/indent_error_0/main.k:3:4 - | -3 | age: int # three white spaces are illegal - | ^ unindent 3 does not match any outer indentation level - | -``` - -Possible resolution: - -- Only use a tab or four white spaces in the KCL program for indentation. - -### 1.1.4 IllegalArgumentSyntaxError (E1I37) - -KCL will report `IllegalArgumentSyntaxError` when KCL has an illegal argument in KCL syntax. - -For example: - -```python -# Parameters without default values -# must be in front of parameters with default values. -a = option(type="list", default={"key": "value"}, "key1") -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> /option/type_convert_fail_2/main.k:3:57 - | -3 | a = option(type="list", default={"key": "value"}, "key1") - | ^ positional argument follows keyword argument - | -``` - -Possible resolution: - -```python -func(input_1, ..., input_n, param_with_key_1 = input_with_key_1, ..., param_with_key_n = input_with_key_n) -``` - -## 1.2 KCL Compile Error (E2xxx) - -This section mainly includes KCL errors: - -| ewcode | KCL exception | messages | -| ------ | ---------------------------------------------------------------------- | --------------------------------------------------- | -| E2F04 | [CannotFindModule](#121-cannotfindmodulee2f04) | Cannot find the module | -| E2F05 | [FailedLoadModule](#122-failedloadmodulee2f05) | Failed to load module | -| E2H13 | [UnKnownDecoratorError](#123-unknowndecoratorerrore2h13) | UnKnown decorator | -| E2H14 | [InvalidDecoratorTargetError](#124-invaliddecoratortargeterrore2h14) | Invalid Decorator Target | -| E2C15 | [MixinNamingError](#125-mixinnamingerrore2c15) | Illegal mixin naming | -| E2C16 | [MixinStructureIllegal](#126-mixinstructureillegale2c16) | Illegal mixin structure | -| E2B17 | [CannotAddMembersComplieError](#127-cannotaddmemberscomplieerrore2b17) | Cannot add members to a schema | -| E2B20 | [IndexSignatureError](#128-indexsignatureerrore2b20) | Invalid index signature | -| E2G22 | [TypeComplieError](#129-typecomplieerrore2g22) | The type got is inconsistent with the type expected | -| E2L23 | [CompileError](#1210-compileerrore2l23) | A complie error occurs during compiling | -| E2L25 | [KCLNameError](#1211-kclnameerrore2l25) | Name Error | -| E2L26 | [KCLValueError](#1212-kclvalueerrore2l26) | Value Error | -| E2L27 | [KCLKeyError](#1213-kclkeyerrore2l27) | Key Error | -| E2L28 | [UniqueKeyError](#1214-uniquekeyerrore2l28) | Unique key error | -| E2A29 | [KCLAttributeComplieError](#1215-kclattributecomplieerrore2a29) | Attribute error occurs during compiling | -| E2D32 | [MultiInheritError](#1216-multiinheriterrore2d32) | Multiple inheritance is illegal | -| E2D34 | [IllegalInheritError](#1217-illegalinheriterrore2d34) | Illegal inheritance | -| E2I36 | [IllegalArgumentComplieError](#1218-illegalargumentcomplieerrore2i36) | Illegal argument during compiling | -| E3L41 | [ImmutableCompileError](#1219-immutablecompileerror-e3l41) | Immutable variable is modified | - -### 1.2.1 CannotFindModule(E2F04) - -KCL will report `CannotFindModule` when KCL imports a module that does not exist. - -The `ewcode` of `CannotFindModule` is `E2F04`. - -For example: - -```python -import .some0.pkg1 as some00 # some0 not found in package - -Name1 = some00.Name # some0.pkg1.name -``` - -The KCL program will cause the following error message. - -```shell -error[E2F04]: CannotFindModule - --> import_abs_fail_0/app-main/main.k:1:1 - | -1 | import .some0.pkg1 as some00 # some0 not found in package - | Cannot find the module .some0.pkg1 - | -``` - -Possible resolution: - -- Add the import module file under the import path. - -### 1.2.2 FailedLoadModule(E2F05) - -KCL will report `FailedLoadModule` when an error occurs during loading a KCL external package. - -The `ewcode` of `FailedLoadModule` is `E2F05`. - -Possible resolution: - -- Check whether the module file is readable. -- Check whether the module file is a KCL file. - -### 1.2.3 UnKnownDecoratorError(E2H13) - -KCL will report `UnKnownDecoratorError` when an unknown decorator is used in KCL. - -The `ewcode` of `UnKnownDecoratorError` is `E2H13`. - -For example: - -```python -@err_deprecated # It is an unknown decorator -schema Person: - firstName: str = "John" - lastName: str - name: str - -JohnDoe = Person { - name: "deprecated" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> deprecated/unknown_fail_1/main.k:1:2 - | -1 | @err_deprecated # 这是一个非法的装饰器 - | ^ UnKnown decorator err_deprecated - | -``` - -Possible resolution: - -- Check whether the decorator exists. - -### 1.2.4 InvalidDecoratorTargetError(E2H14) - -KCL will report `InvalidDecoratorTargetError` when the target cannot be the target of the decorator. - -The `ewcode` of `InvalidDecoratorTargetError` is `E2H14`. - -Possible resolution: - -- Check whether the decorator in KCL is illegal. - -### 1.2.5 MixinNamingError(E2C15) - -KCL will report `MixinNamingError` when a mixin name does not end with 'Mixin'. - -The `ewcode` of `MixinNamingError` is `E2C15`. - -For example: - -```python -schema Person: - firstName: str - lastName: str - fullName: str - -schema Fullname: # It is a mixin, but 'Fullname' is not end with 'Mixin - fullName = "{} {}".format(firstName, lastName) - -schema Scholar(Person): - mixin [Fullname] - school: str - -JohnDoe = Scholar { - "firstName": "John", - "lastName": "Doe", - "fullName": "Doe Jon" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2D34]: IllegalInheritError - --> mixin/invalid_name_failure/main.k:10:12 - | -10 | mixin [Fullname] - | ^ illegal schema mixin object type 'Fullname' - | -``` - -Possible resolution: - -- If the schema is a mixin, then the name of the schema should end with Mixin. - -### 1.2.6 MixinStructureIllegal(E2C16) - -KCL will report `MixinStructureIllegal` when the KCL structure is illegal. - -The `ewcode` of `MixinStructureIllegal` is `E2C16`. - -Possible resolution: - -- Check the structure of schema as Mixin. - -### 1.2.7 CannotAddMembersComplieError(E2B17) - -KCL will report `CannotAddMembersComplieError` when members that are not in the schema are used. - -The `ewcode` of `CannotAddMembersComplieError` is `E2B17`. - -For example: - -```python -schema Girl: - gender: str = "female" - -alice = Girl { - "first": "alice", # "first" can not be found in schema Girl - "last": " Green", # "last" can not be found in schema Girl - "age": 10 # "age" can not be found in schema Girl -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:5:5 - | -5 | "first": "alice", - | ^ Cannot add member 'first' to schema 'Girl' - | - -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:6:5 - | -6 | "last": " Green", - | ^ Cannot add member 'last' to schema 'Girl' - | - -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:7:5 - | -7 | "age": 10 - | ^ Cannot add member 'age' to schema 'Girl' - | -``` - -Possible resolution: - -- Add the members to the schema. -- Remove the using of the members not exists - -### 1.2.8 IndexSignatureError(E2B20) - -The `ewcode` of `IndexSignatureError` is `E2B20`. - -KCL will report `IndexSignatureError` when: - -1. Multiple index signatures in one schema. - -For example: - -```python -schema Data: - [str]: str - [str]: int # Multiple index signatures in one schema. - -data = Data { - name: "test" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError ----> index_signature/fail_1/main.k:3:5 - | -3 | [str]: int - | 5 ^ only one index signature is allowed in the schema - | -``` - -Possible resolution: - -- Remove the extra index signature in the schema. - -2. The name of index signature attributes has the same name that conflicts with other attributes in the schema. - -For example: - -```python -schema Data: - name: str # name - [name: str]: str # the same name with the above attribute - -data = Data { - name: "test" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: IndexSignatureError - --> index_signature/fail_2/main.k:3:5 - | -3 | [name: str]: str # the same name with the above attribute - | ^ index signature attribute name 'name' cannot have the same name as schema attributes - | -``` - -Possible resolution: - -- Remove attributes or index signatures that have conflicts with the same name in the schema, or change their names. - -3. Schema index signature value type has conflicts with the instance of schema. - -For example: - -```python -schema Data: - [str]: int - -data = Data { - name: "test" # Conflict with [str]:int, "test" is a string. -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> index_signature/fail_3/main.k:5:5 - | -5 | name: "test" # Conflict with [str]:int, "test" is a string. - | ^ expected int, got str(test) - | -``` - -Possible resolution: - -- Check that the type of schema index signature is consistent with the attribute type in the schema instance. - -4. Schema index signature has conflicts with schema. - -For example: - -```python -schema Data: - count: int # got int - [str]: str # except str - -data = Data { - count: 1 -} -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: IndexSignatureError - --> index_signature/fail_4/main.k:2:5 - | -2 | count: int - | ^ the type 'int' of schema attribute 'count' does not meet the index signature definition [str]: str - | -``` - -Possible resolution: - -- Change schema for index signature or change index signature for schema. - -### 1.2.9 TypeComplieError(E2G22) - -KCL will report `TypeComplieError` when a type error occurs in compiling type check. - -The `ewcode` of `TypeComplieError` is `E2G22`. - -For example: - -```python -schema Person: - firstName: str - lastName: int - -JohnDoe = Person { - "firstName": "John", - "lastName": "Doe" # Type Error,lastName: int,“Doe” is a string. -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> type/type_fail_0/main.k:7:5 - | -7 | "lastName": "Doe" # Type Error,lastName: int,“Doe” is a string. - | ^ expected int, got str(Doe) - | - - --> type/type_fail_0/main.k:3:5 - | -3 | lastName: int - | ^ variable is defined here, its type is int, but got str(Doe) - | -``` - -Possible resolution: - -- Check that the type of value assigned to a variable is consistent with the type of the variable. - -### 1.2.10 CompileError(E2L23) - -The `ewcode` of `CompileError` is `E2L23`. - -KCL will report `CompileError` when: - -1. unsupport type union. - -For example: - -```python -_data = [1, 2, 3] -_data |= "value" -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> union/fail/fail_1/main.k:2:1 - | -2 | _data |= "value" - | ^ unsupported operand type(s) for |: '[int]' and 'str(value)' - | -``` - -Possible resolution: - -1. unsupported operand type. - -For example: - -```python -a = None -b = 1 + None # Unsupport operand type + for int and None -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> operator/operator_fail_0/main.k:2:5 - | -2 | b = 1 + None # Unsupport operand type + for int and None - | ^ unsupported operand type(s) for +: 'int(1)' and 'NoneType' - | -``` - -Possible resolution: - -- Adjust the operator so that it supports both operand types. -- Adjust the operands so that they conform to the constraints of the operator at the same time. - -1. variable is not defined. - -For example: - -```python -a = 1 -b = "${c + 1}" # 'c' is not defined -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> var_not_define_fail_0/main.k:2:8 - | -2 | b = "${c + 1}" # 'c' is not defined - | ^ name 'c' is not defined - | -``` - -Possible resolution: - -- Define undefined variables. -- Remove the undefined variable from the expression. - -1. invalid assign expression. - -For example: - -```python -# pkg.k -a = 1 - -# main.k -import pkg -pkg.a |= 2 -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> pkg_inplace_modify_1/main.k:3:1 - | -6 | pkg |= 2 - | ^ unsupported operand type(s) for |: 'module 'pkg'' and 'int(2)' - | -``` - -Possible resolution: - -- Check the assignment expression. - -1. invalid string expression. - -For example: - -```python -a = 1 -b = "${b = a + 1}" # Invalid string interpolation expression -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> invalid_format_value_fail_0/main.k:2:5 - | -2 | b = "${b = a + 1}" - | 5 ^ invalid string interpolation expression 'b = a + 1' - | -``` - -Possible resolution: - -- Check the string expression. - -1. invalid loop variable. - -For example: - -```python -data = {"key1": "value1", "key2": "value2"} -dataLoop = [i for i, j, k in data] # the number of loop variables can only be 1 or 2 -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> dict/invalid_loop_var_fail_0/main.k:2:25 - | -2 | dataLoop = [i for i, j, k in data] # the number of loop variables can only be 1 or 2 - | ^ the number of loop variables is 3, which can only be 1 or 2 - | -``` - -### 1.2.11 KCLNameError(E2L25) - -KCL will report `KCLNameError` when a name error occurs in compiling. - -The `ewcode` of `KCLNameError` is `E2L25`. - -### 1.2.12 KCLValueError(E2L26) - -KCL will report `KCLValueError` will be raised when a value error occurs in compiling. - -The `ewcode` of `KCLValueError` is `E2L25`. - -### 1.2.13 KCLKeyError(E2L27) - -KCL will report `KCLKeyError` will be raised when a key error occurs in compiling. - -The `ewcode` of `KCLKeyError` is `E2L25`. - -### 1.2.14 UniqueKeyError(E2L28) - -KCL will report `UniqueKeyError` when duplicate names appear in the KCL code. - -The `ewcode` of `UniqueKeyError` is `E2L28`. - -For example: - -```python -schema Person: - name: str = "kcl" - age: int = 1 - -schema Person: - aa: int - -x0 = Person{} -x1 = Person{age:101} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L28]: UniqueKeyError - --> /schema/same_name/main.k:5:8 - | -5 | schema Person: - | ^ Unique key error name 'Person' - | - - --> /schema/same_name/main.k:1:8 - | -1 | schema Person: - | ^ The variable 'Person' is declared here - | -``` - -Possible resolution: - -- Check if the name with error has been used. - -### 1.2.15 KCLAttributeComplieError(E2A29) - -KCL will report `KCLAttributeComplieError` when KCL has an illegal attribute in the schema. - -The `ewcode` of `KCLAttributeComplieError` is `E2A29`. - -For example: - -```python -# pkg -schema A: - field_A: str - -# main -import pkg as p - -a = p.D + 1 -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> /import/module/no_module_attr_fail_0/main.k:4:5 - | -4 | a = p.D + 1 - | ^ module 'pkg' has no attribute D - | -``` - -Possible resolution: - -- Check for the existence of the schema attribute when using it. - -### 1.2.16 MultiInheritError(E2D32) - -KCL will report `MultiInheritError` when multiple inheritance appears in the schema. - -The `ewcode` of `MultiInheritError` is `E2D32`. - -For example: - -```python -schema Person: - firstName: str - lastName: str - -schema KnowledgeMixin: - firstName: int - subject: str - -schema Scholar(KnowledgeMixin, Person): - school: str -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> /schema/inherit/multi_inherit_fail_1/main.k:9:30 - | -9 | schema Scholar(KnowledgeMixin, Person): - | ^ expected one of [")"] got , - | -``` - -Possible resolution: - -- Check the inheritance structure of the program, and multi-inheritance is not supported in KCL. - -### 1.2.17 IllegalInheritError(E2D34) - -KCL will report `IllegalInheritError` when an illegal inheritance occurs in the schema. - -The `ewcode` of `IllegalInheritError` is `E2D34`. - -For example: - -```python -schema FullnameMixin: - fullName = "{} {}".format(firstName, lastName) - -schema Scholar(FullnameMixin): # mixin inheritance is illegal - school: str -``` - -The KCL program will cause the following error message. - -```shell -error[E2D34]: IllegalInheritError - --> /schema/inherit/inherit_mixin_fail/main.k:4:16 - | -4 | schema Scholar(FullnameMixin): - | ^ invalid schema inherit object type, expect schema, got 'FullnameMixin' - | -``` - -Possible resolution: - -- Schema supports single inheritance of schema in KCL. - -### 1.2.18 IllegalArgumentComplieError(E2I36) - -KCL will report `IllegalArgumentComplieError` when the argument of option in KCL is illegal. - -The `ewcode` of `IllegalArgumentComplieError` is `E2I36`. -For example: - -```python -a = option("key") - -# kcl main.k -D key=value= -# key=value= is an illegal expression -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError -Invalid value for top level arguments -``` - -Possible resolution: - -- Check whether the KCL option arguments are legal. - -### 1.2.19 ImmutableCompileError (E3L41) - -KCL will report `ImmutableCompileError` when the value of the immutable variable changes. - -The `ewcode` of `ImmutableCompileError` is `E3L41`. - -For example: - -```python -a = 2147483646 -a += 1 -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: ImmutableError - --> augment_assign/main.k:2:1 - | -2 | a += 1 - | ^ Immutable variable 'a' is modified during compiling - | - - --> augment_assign/main.k:1:1 - | -1 | a = 2147483646 - | ^ The variable 'a' is declared here firstly - | -note: change the variable name to '_a' to make it mutable -``` - -Possible resolution: - -- Set immutable variables changed to private or remove immutable variables. - -## 1.3 KCL Runtime Error (E3xxx) - -This section mainly includes KCL errors: - -| ewcode | KCL exception | messages | -| ------ | ---------------------------------------------------------------------- | --------------------------------------------------- | -| E3F06 | [RecursiveLoad](#131-recursiveload-e3f06) | Recursively loading module | -| E3K04 | [FloatOverflow](#132-floatoverflow-e3k04) | Float overflow | -| E3K09 | [IntOverflow](#133-intoverflow-e3k09) | Integer overflow | -| E3N11 | [DeprecatedError](#134-deprecatederror-e3n11) | Deprecated error | -| E3A30 | [KCLAttributeRuntimeError](#135-kclattributeruntimeerror-e3a30) | Attribute error occurs at runtime | -| E3G21 | [TypeRuntimeError](#136-typeruntimeerror-e3g21) | The type got is inconsistent with the type expected | -| E3B17 | [SchemaCheckFailure](#137-schemacheckfailure-e3b17) | Schema check is failed to check condition | -| E3B19 | [CannotAddMembersRuntimeError](#138-cannotaddmembersruntimeerrore3b19) | Cannot add members to a schema | -| E3M38 | [EvaluationError](#139-evaluationerrore3m38) | Evaluation failure | -| E3M39 | [InvalidFormatSpec](#1310-invalidformatspec-e3m39) | Invalid format specification | -| E3M40 | [KCLAssertionError](#1311-kclassertionerror-e3m40) | Assertion failure | -| E3M44 | [ImmutableRuntimeError](#1312-immutableruntimeerror-e3m44) | Immutable variable is modified | -| E2D33 | [CycleInheritError](#1313-cycleinheriterror-e2d33) | Cycle Inheritance is illegal | -| E3M42 | [KCLRecursionError](#1314-kclrecursionerror-e3m42) | Recursively reference | - -### 1.3.1 RecursiveLoad (E3F06) - -KCL will report `RecursiveLoad` when a cycle import of external packages occurs in KCL. - -The `ewcode` of `RecursiveLoad` is `E2F06`. - -For example: - -```python -# module.k -import main # module.k imports main.k - -print('module') - -# main.k -import module # main.k imports module.k - -print('main') -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /import/recursive_import_fail/main.k:4 - | -2 | import module # main.k imports module.k - | ^ There is a circular import reference between module main and module - | -``` - -Possible resolution: - -- Check whether there is a circle import in KCL. - -### 1.3.2 FloatOverflow (E3K04) - -KCL will report `FloatOverflow` when a floating-point number overflows in KCL. - -The `ewcode` of `FloatOverflow` is `E3K04`. - -For example: - -```python -uplimit = 3.402823466e+39 -epsilon = 2.220446049250313e-16 -a = uplimit * (1 + epsilon) - -# kcl main.k -r -d -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /range_check_float/overflow/number_0/main.k:3:1 - | -3 | a = uplimit * (1 + epsilon) - | 3.4028234660000003e+39: A 32-bit floating point number overflow - | -``` - -Possible resolution: - -- Check whether the value of the float is the float range supported by KCL. - -### 1.3.3 IntOverflow (E3K09) - -KCL will report `IntOverflow` when an integer number overflows in KCL. - -The `ewcode` of `IntOverflow` is `E3K09`. - -For example: - -```python -_a = 9223372036854775807 -_a += 1 - -# kcl test.k -d -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /range_check_int/augment_assign_fail_1/main.k:2:1 - | -2 | _a += 1 - | 9223372036854775808: A 64 bit integer overflow - | -``` - -Possible resolution: - -- Check whether the value of the integer is the integer range supported by KCL. - -### 1.3.4 DeprecatedError (E3N11) - -KCL will report `DeprecatedError` when a deprecated variable is used and the strict is True. - -The `ewcode` of `DeprecatedError` is `E3N11`. - -For example: - -```python -schema Person: - firstName: str = "John" - lastName: str - @deprecated(version="1.16", reason="use firstName and lastName instead", strict=True) - name: str - -JohnDoe = Person { - name: "deprecated" # name is deprecated and strict is True -} -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /range_check_float/overflow/number_0/main.k:7:1 - | -7 | JohnDoe = Person { - | name was deprecated since version 1.16, use firstName and lastName instead - | -``` - -Possible resolution: - -- When strict is set to True, using deprecated code will cause an error and stop KCL. -- You can set the strict to False which will cause a warning insteads of an error. -- Adjust the code without using deprecated code. - -### 1.3.5 KCLAttributeRuntimeError (E3A30) - -KCL will report `KCLAttributeRuntimeError`, if an error occurs during dynamically accessing schema attributes through variables at runtime. - -The `ewcode` of `KCLAttributeRuntimeError` is `E3A30`. - -For example: - -```python -import math - -a = math.err_func(1) # err_func is not found in math -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /import/module/no_module_attr_fail_2/main.k:3:5 - | -3 | a = math.err_func(1) # err_func is not found in math - | ^ module 'math' has no attribute err_func - | -``` - -Possible resolution: - -- Check whether the attributes of schema are correct. - -### 1.3.6 TypeRuntimeError (E3G21) - -KCL will report `TypeRuntimeError` when an type error occurs in the runtime type check. - -The `ewcode` of `TypeRuntimeError` is `E3G21`. - -For example: - -```python -schema Person: - name: str = "Alice" - -_personA = Person {} -_personA |= {"name" = 123.0} # name: str = "Alice" -personA = _personA -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /fail/fail_4/main.k:2:1 - | -2 | name: str = "Alice" - | expect str, got float - | -``` - -Possible resolution: - -- Stop the wrong type union or adjust to the type union supported by KCL. - -### 1.3.7 SchemaCheckFailure (E3B17) - -KCL will report `SchemaCheckFailure` when the schema check conditions are not met. - -The `ewcode` of `SchemaCheckFailure` is `E3B17`. - -For example: - -```python -schema Person: - lastName: str - age: int - check: - age < 140, "age is too large" - -JohnDoe = Person { - "lastName": "Doe", - "age": 1000 # the check condition: age < 140 -} -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /check_block/check_block_fail_1/main.k:7:11 - | -7 | JohnDoe = Person { - | ^ Instance check failed - | - - --> /check_block/check_block_fail_1/main.k:5:1 - | -5 | age < 140, "age is too large" - | Check failed on the condition - | -``` - -Possible resolution: - -- Check whether the attributes of schema can satisfy the conditions in check. - -### 1.3.8 CannotAddMembersRuntimeError(E3B19) - -KCL will report `CannotAddMembersRuntimeError` when members that are not in the schema are used. - -The `ewcode` of `CannotAddMembersRuntimeError` is `E3B19`. - -For example: - -```python -schema Name: - name: str - -schema Person: - name: Name - -person = Person { - name.err_name: "Alice" # err_name is not found in schema Name -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /nest_var/nest_var_fail_1/main.k:8:5 - | -8 | name.err_name: "Alice" # err_name is not found in schema Name - | ^ Cannot add member 'err_name' to schema 'Name' - | -``` - -Possible resolution: - -- Add a non-existent member to the schema. -- Access members that exist in the schema. - -### 1.3.9 EvaluationError(E3M38) - -KCL will report `EvaluationError` when an illegal evaluation occurs in KCL. - -The `ewcode` of `EvaluationError` is `E3M38`. - -For example: - -```python -_list1 = [1, 2, 3] # _list1 is a variable, and its type can only be known at runtime -_list2 = None # _list1 is a variable, and its type can only be known at runtime - -result2 = _list1 + _list2 # list + NoneType is illegal -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /datatype/list/add_None_fail/main.k:1 - | -4 | result2 = _list1 + _list2 # list + NoneType is illegal - | can only concatenate list (not "NoneType") to list - | -``` - -Possible resolution: - -- Check whether the evaluation of the expression is legal. - -### 1.3.10 InvalidFormatSpec (E3M39) - -KCL will report `InvalidFormatSpec` when an illegal string format appears in KCL. - -The `ewcode` of `InvalidFormatSpec` is `E3M39`. - -For example: - -```python -a = 1 -b = 1 -data = "${a: #js}" + " $$ " # #js is illegal string -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /datatype/str_interpolation/invalid_format_spec_fail_0/main.k:3 - | -3 | data = "${a: #js}" + " $$ " # #js is illegal string - | ^ #js is a invalid format spec - | -``` - -Possible resolution: - -- Adjust illegal String to String supported by KCL standards. - -### 1.3.11 KCLAssertionError (E3M40) - -KCL will report `KCLAssertionError` when assert False occurs in KCL. - -The `ewcode` of `KCLAssertionError` is `E3M40`. - -For example: - -```python -assert False -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /assert/invalid/fail_0/main.k:1 - | -1 | assert False - | - | -``` - -Possible resolution: - -- Check the condition of Assert, and when the Assert condition is False, such an error occurs, removing the Assert statement or changing the condition to True. - -### 1.3.12 ImmutableRuntimeError (E3M44) - -KCL will report `ImmutableRuntimeError` when the value of the immutable variable changes. - -The `ewcode` of `ImmutableRuntimeError` is `E3M44`. - -For example: - -```python -schema Person: - final firstName : str - lastName : str - -schema Scholar(Person): - firstName = "CBA" - -scholar = Scholar { - "firstName": "ABC" # firstName in schema Person is final. -} -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /final/fail_lazy_init_0/main.k:8:1 - | -8 | scholar = Scholar { - | attribute 'lastName' of Scholar is required and can't be None or Undefined - | -``` - -Possible resolution: - -- Check if the final variables have been assigned or other changes affect the values of the final variables. - -### 1.3.13 CycleInheritError (E2D33) - -KCL will report `CycleInheritError` when circle inheritance appeared in the schema. - -The `ewcode` of `CycleInheritError` is `E2D33`. - -For example: - -```python -schema Parent(Son): - parent_field: str - -schema Son(GrandSon): - son_field: str - -schema GrandSon(Parent): - grandson_field: str - -parent = Parent { - parent_field: "" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /inherit/cycle_inherit_fail_1/main.k:7:8 - | -7 | schema GrandSon(Parent): - | ^ There is a circular reference between schema GrandSon and Parent - | -``` - -Possible resolution: - -- Check schema inheritance relationship to avoid A inheritance B and B inheritance A at the same time. - -### 1.3.14 KCLRecursionError (E3M42) - -KCL will report `KCLRecursionError` when a circle reference appears in the program. - -The `ewcode` of `KCLRecursionError` is `E3M42`. - -For example: - -```python -schema Parent(Son): - parent_field: str - son: Son = Son { # Parent has attribute Son - parent: Parent { - parent_field: "123" - } - } - -schema Son: - son_field: str - parent: Parent = Parent { # Son has attribute Parent - son: Son { - son_field: "123" - } - } - -parent = Parent { - parent_field: "", -} -``` - -The KCL program will cause the following error message. - -```shell -thread 'main' has overflowed its stack -fatal runtime error: stack overflow -``` - -Possible resolution: - -- Check the members in the schema to avoid the problem of circle references. - -## 1.4 KCL Compile Warning (W2xxx) - -This section mainly includes KCL warnings: - -| ewcode | KCL exception | messages | -| ------ | ------------------------------------------------- | ------------------ | -| W2K04 | [FloatUnderflow](#141-floatunderflow-w2k04) | Float underflow | -| W2P10 | [InvalidDocstring](#142-invaliddocstring-w2p10) | Invalid docstring | -| W2N12 | [DeprecatedWarning](#143-deprecatedwarning-w2n12) | Deprecated warning | - -### 1.4.1 FloatUnderflow (W2K04) - -KCL will report `FloatUnderflow` when a floating-point number underflows in KCL. - -The `ewcode` of `FloatUnderflow` is `W2K08`. - -Possible resolution: - -- Check whether the value of the float number is in the range supported by KCL. - -### 1.4.2 InvalidDocstring (W2P10) - -KCL will report `InvalidDocstring` when a string is illegal in KCL doc. - -The `ewcode` of `InvalidDocstring` is `W2P10`. - -Possible resolution: - -- Please write doc according to KCL standards. - -### 1.4.3 DeprecatedWarning (W2N12) - -KCL will report `DeprecatedWarning` when a deprecated variable is used and the strict is False. - -The `ewcode` of `DeprecatedWarning` is `W2N12`. - -Possible resolution: - -- Try not to use deprecated code. If the strict is True, KCL will output the error and stop running. diff --git a/versioned_docs/version-0.5.0/reference/lang/spec/codestyle.md b/versioned_docs/version-0.5.0/reference/lang/spec/codestyle.md deleted file mode 100644 index dd40925e..00000000 --- a/versioned_docs/version-0.5.0/reference/lang/spec/codestyle.md +++ /dev/null @@ -1,608 +0,0 @@ ---- -title: "Code Style" -linkTitle: "Code Style" -type: "docs" -weight: 2 -description: Code Style ---- - -## Introduction - -This document gives the KCL code style conventions. Good code style can play a vital role in the development and maintenance of the project. We can learn the KCL code style by referring to the full text of the description and sample codes, and use KCL format and lint tools to help coding. - -## Source File Encoding - -KCL file encoding should always use **UTF-8**. - -## Code Layout - -### Indentation - -Use **4 spaces** per indentation level such as in the schema statement and if statement. - -```python -schema PersonA: - name: str # non-recommended - age: int - -schema PersonB: - name: str # recommended - age: int - -if True: - a = 1 # recommended -elif True: - b = 2 # non-recommended -else: - c = 3 # non-recommended -``` - -The closing brace/bracket/parenthesis on multiline constructs should line up under **first character** of the line that starts the multiline construct, as in: - -```python -# valid and recommended -my_list = [ - 1, 2, 3, - 4, 5, 6, -] -``` - -```python -# invalid -my_list = [ - 1, 2, 3, - 4, 5, 6, - ] -``` - -### Tabs or Spaces - -- Spaces are the preferred indentation method. -- Tabs should be used solely to remain consistent with code that is already indented with tabs. - -KCL disallows mixing the use of tabs and spaces for indentation and an error will be reported during the compile time. - -### Blank Lines - -- Surround top-level schema definitions with one blank line. -- Keep at most one blank line between two statements and remove redundant blank lines. -- Remove extra blank characters at the end of the line -- Remove extra blank characters in a blank line. -- There is no blank line in the header of the file, start writing from the first line. -- Only one blank line will be left at the end of the KCL file. - -```python -# Remove blank lines in the file header -a = 1 # Remove white space at the end of the line -# Keep at most one blank line between two statements - -b = 2 -# Only leave one blank line at the end of the file - -``` - -### Inline Expressions - -Write indentation of KCL `if`, `elif`, `else` and other conditions on different lines. - -```python -if True: print("") # non-recommended - -if True: # recommended - print("") -``` - -### Line Break and Continuation lines - -- For long expressions, use the line continuation symbol `\` and keep the left end of multiple expressions aligned. -- The 4-space rule is optional for continuation lines. - -```python -anotherString = "Too long expression " + \ - "Too long expression " # non-recommended - -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " # recommended -``` - -### When to Use Trailing Commas - -- Always use trailing commas. - -### Maximum Line Length - -- The general recommendation is **80 characters** but not absolute. - -### Symbol Break White Space - -Try to keep the spaces between different symbols, but not too many, usually one is good. - -```python -a = 1 # recommended -b = 1 + 2 # non-recommended -``` - -### Whitespace in Expressions and Statements - -Avoid extraneous whitespace in the following situations: - -- The parentheses `()`, brackets `[]` and braces `{}` in the expression have no spaces inside. - -```python -a = (1 + 2) # recommended -b = ( 1 + 2 ) # non-recommended - -c = [1, 2, 3] # recommended -d = [ 1, 2, 3 ] # non-recommended - -e = {key = "value"} # recommended -f = { key = "value" } # non-recommended -``` - -```python -spam(ham[1], {eggs = 2}) # recommended -spam( ham[ 1 ], { eggs = 2 } ) # non-recommended -``` - -- Between a trailing comma and a following close parenthesis. - -```python -foo = [0,] # recommended -bar = [0, ] # non-recommended -``` - -- Immediately before the open parenthesis that starts the argument list of a function call. - -```python -print(1) # recommended -print (1) # non-recommended -``` - -- Immediately before the open parenthesis that starts indexing or slicing. - -```python -dct = {key = "value"} -lst = [1, 2, 3] - -a = dct['key'] # recommended -b = dct ['key'] # non-recommended - -c = lst[0] # recommended -d = lst [1] # non-recommended -``` - -- More than one space around an assignment `=` (or other) operator to align it with another. - -```python -# recommended: -x = 1 -y = 2 -long_variable = 3 -``` - -```python -# non-recommended: -x = 1 -y = 2 -long_variable = 3 -``` - -- Always surround these binary operators with a single space on either side: assignment (`=`), augmented assignment (`+=`, `-=`, etc.), comparisons (`==`, `<`, `>`, `!=`, `<=`, `>=`, `in`, `not in`, `is`, `is not`), booleans (`and`, `or`, `not`). - -```python -# recommended: -i = i + 1 -submitted += 1 -x = x * 2 - 1 -hypot2 = x * x + y * y -c = (a + b) * (a - b) -``` - -```python -# non-recommended: -i = i+1 -submitted+=1 -x = x*2 - 1 -hypot2 = x*x + y*y -c = (a+b) * (a-b) -``` - -- Break one blank line between different statements e.g., import, schema and expression statements. - -```python -import math -import net - -schema Person: - name: str - -person = Person { - name = "Alice" -} -``` - -- Compound statements (multiple statements on the same line) are generally discouraged - -```python -# recommended: -if foo == 'blah': - do_blah_thing() -do_one() -do_two() -do_three() -``` - -```python -# non-recommended: -if foo == 'blah': do_blah_thing() -do_one(); do_two(); do_three() -``` - -## Naming Conventions - -### Naming Styles - -The following naming styles are commonly distinguished: - -- `b` (single lowercase letter) -- `B` (single uppercase letter) -- `lowercase` -- `lower_case_with_underscores` -- `UPPERCASE` -- `UPPER_CASE_WITH_UNDERSCORES` -- `CapitalizedWords` (capitalize all letters of the acronym in `CapitalizedWords` e.g., `HTTPServer`.) -- `mixedCase` (differs from `CapitalizedWords` by initial lowercase character) -- `Capitalized_Words_With_Underscores` (ugly and non-recommended) - -### Names to Avoid - -Never use the characters 'l' (lowercase letter el), 'O' (uppercase letter oh), or 'I' (uppercase letter eye) as single-character variable names. - -### Package and Module Names - -Package and module names should have short, all-lowercase names. - -### Schema Names - -Schema names should normally use the `CapWords` convention. - -### Constants - -Constants are usually defined on a module level and written in all capital letters with underscores separating words such as `MAX_OVERFLOW` and `TOTAL`. - -## Import - -- Imports should usually be on separate lines. -- Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants. -- Imports should be grouped in the following order and we should put a blank line between each group of imports. - 1. Standard library imports. - 2. Related third party plugin imports. - 3. Local application/library specific imports. -- Use an alias when we import a package name with a relatively long path. -- Leave only one space between the Import keyword and the package name. - -```python -import net # recommended -import math # non-recommended - -import ..pkg.internal_pkg as alias_pkg # recommended -``` - -## Comments - -- Comments should be complete sentences. The first word should be capitalized unless it is an identifier that begins with a lower-case letter (never alter the case of identifiers!). -- Block comments generally consist of one or more paragraphs built out of complete sentences, with each sentence ending in a period. -- Use two spaces after a sentence-ending period in multi-sentence comments, except after the final sentence. - -### Block Comments - -Block comments generally apply to some (or all) code that follows them, and are indented to the same level as that code. Each line of a block comment starts with a `#` and **a single space**(unless it is indented text inside the comment). - -Paragraphs inside a block comment are separated by a line containing a single `#`. - -```python -# This is a block comment -a = 1 -``` - -### Inline Comments - -Use inline comments sparingly. - -An inline comment is a comment on the same line as a statement. Inline comments should be separated by **at least two spaces** from the statement. They should start with a `#` and **a single space**. - -```python -a = 1 # This is an inline comment -``` - -### Documentation Strings - -Write doc strings for all public schema and schema attributes. - -```python -schema Person: - """ - Person schema doc string - """ - - name: str = "Alice" -``` - -## String - -- Single-quoted strings and double-quoted strings are the same in KCL. -- Use double-quoted string with lowercase prefix -- For triple-quoted strings, always use double quote characters to be consistent with the docstring convention. -- When a string contains single or double quote characters, use the other one to avoid backslashes in the string. - -```python -strC = "'123'" # recommended -strD = "\"123\"" # non-recommended -``` - -## Number - -- Use lowercase for the prefix of non-decimal numbers, and use uppercase for the number itself. - -```python -foo = 0xAB # recommended -bar = 0Xab # non-recommended -``` - -## Operators - -### Binary Operators - -- Leave only one space before and after the assignment `=`. -- Leave only one space before and after the binary operator in the expression. - -```python -a = 1 # recommended -b=2 # non-recommended -c= 3 # non-recommended -d =4 # non-recommended - -_value = (1 + 2 * 3) # recommended -_value = (1+2*3) # non-recommended -``` - -### Unary Operators - -- There is only no space after unary operators e.g., `~`, `+` and `-`. - -```python -_value = 1 + -2 * ~3 # recommended -_value = 1+ - 2 * ~ 3 # non-recommended -``` - -- There is no space after `**` and `*` in the dict/list deduction expressions and argument expressions. - -```python -_list = [1, 2, 3] -_list = [*_list, [4, 5 ,6]] # recommended -_list = [* _list, [4, 5 ,6]] # non-recommended - -_dict = {**{k = "v"}, **{k = "v"}} # recommended -_dict = {** {k = "v"}, ** {k = "v"}} # non-recommended -``` - -- Use `is not` operator rather than `not ... is`. - -```python -# recommended: -if foo is not None: - a = 1 -``` - -```python -# non-recommended: -if not foo is None: - a = 1 -``` - -## Dict - -- There is no space before the colon `:` at the instantiation of KCL dict and schema config, and a space after the colon `:`. - -```python -d1 = {labels: {k1 = "v1"}} # recommended -d2 = {labels : {k1 = "v1"}} # non-recommended -d3 = {labels :{k1 = "v1"}} # non-recommended -``` - -- Always surround the override attribute operator `=` and the insert attribute operator `+=` with a single space on either sid. - -```python -d1 = {key = "value"} # recommended -d2 = {key= "value"} # non-recommended -d3 = {key ="value"} # non-recommended -``` - -```python -d1 = {key += [0, 1, 2]} # recommended -d2 = {key+= [0, 1, 2]} # non-recommended -d3 = {key +=[0, 1, 2]} # non-recommended -``` - -- Remove all commas at the end of the line in the KCL multiline dict because the end commas of each line are optional. - -```python -d = { - key1 = "value1" - key2 = "value2" - key3 = "value3" - key4 = "value4" -} -``` - -## List - -- Keep only **one space** after the comma `,` separating elements in the list - -```python -a = [1, 2, 3] # recommended -b = [1,2,3] # non-recommended -``` - -- Keep only **one space** before and after the comprehension expression token `for` and `in` in the dict and list. - -```python -a = [i for i in range(10)] # recommended -b = [i for i in range(10)] # non-recommended -``` - -## Slice - -- Keep the same number of spaces before and after the colon `:` of the list slice. - -```python -l = [1, 2, 3] -a = l[0:2] # recommended -b = l[0 : 2] # non-recommended -c = l[0: 2] # non-recommended - -d = l[0 + 0 : 1 + 1] # recommended -e = l[0 + 0:1 + 1] # non-recommended -``` - -## Schema - -- Leave only one space before and after the schema attribute assignment `=`. -- Always add a doc string to a schema, which is a good programming habit. - -```python -schema Person: - """ - Schema doc string - """ - name: str = "Alice" # recommended - age : int=12 # non-recommended - -person = Person {} -``` - -- Keep **no spaces** around the schema inheritance operator `()` - -```python -schema Base: - name: str - -schema Person(Base): # recommended - age: int - -schema Schema ( Base ): # non-recommended - age: int -``` - -- Keep **only one space** between the brackets and the schema name of the config at schema instantiation. - -```python -schema Base: - name: str - -schema Person(Base): - age: int - -personA = Person{} # non-recommended -personB = Person {} # recommended -``` - -- Keep **only one space** between the **mixin** keyword and the following `[]` operator - -```python -schema NameMixin: - name: str = "name" - -schema Person: - mixin [NameMixin] # non-recommended - age: int - -schema Parent: - mixin [NameMixin] # recommended - age: int -``` - -### Attribute Annotations - -- Annotations for schema attributes should have a single space after the colon `:` and no space before the colon `:`. - -```python -# recommended: -schema Person: - name: str # No space before the colon `:` - age: int = 18 # Spaces around assignment`=` -``` - -```python -# non-recommended: -schema Person: - codeA:int # No space after the colon `:` - codeB : int # Space before the colon `:` - name: str="Alice" # No spaces around assignment`=` -``` - -- There are no spaces around the colon `:` in the dict type annotation. - -```python -schema Person: - labels: {str:str} # recommended - keyValues: {str : str} # non-recommended -``` - -### Arguments - -- There are no spaces around the assignment `=` in the function/schema/decorator keyword arguments (kwargs). - -```python -schema Person[nameVar]: - # Decorator kwargs - @deprecated(strict=False) # recommended - name: str = nameVar - - @deprecated(strict = False) # non-recommended - age: int - -# Schema kwargs -personA = Person(nameVar="Alice") {} # recommended -personB = Person(nameVar = "Bob") {} # non-recommended - -# Function kwargs -print("", end='') # recommended -print("", end = '') # non-recommended -``` - -## Keywords - -- Only one space is usually reserved around the keyword, such as `schema`, `mixin`, `is` and `not`, etc. - -```python -schema NameMixin: - check: - name not None - -schema Person: - """ - Person schema definition - """ - mixin [NameMixin] - - name: str = "Alice" - age: int - -person = Person { - age = 18 -} -``` - -## Function - -- There are no spaces around the function/package select operator `.` -- There are no spaces between the function name and the parentheses `()`. - -```python -import math - -print(math.log(10)) # recommended -print( math . log (10)) # non-recommended -``` diff --git a/versioned_docs/version-0.5.0/reference/lang/spec/datatypes.md b/versioned_docs/version-0.5.0/reference/lang/spec/datatypes.md deleted file mode 100644 index ef7ea71a..00000000 --- a/versioned_docs/version-0.5.0/reference/lang/spec/datatypes.md +++ /dev/null @@ -1,452 +0,0 @@ ---- -title: "Data Types" -linkTitle: "Data Types" -type: "docs" -weight: 2 -description: Data Types ---- - -## Syntax - -### Bool - -Boolean values are the two constant objects `False` and `True`. They are used to represent truth values (although other values can also be considered false or true). The built-in function bool() can be used to convert any value to a Boolean, if the value can be interpreted as a truth value. - -### Int - -Int, or integer, is an arbitrarily sized integer, positive or negative, without decimals, of 64 binary digits precision(-9,223,372,036,854,775,808~9,223,372,036,854,775,807). Int is created by int literals or as the result of built-in functions and operators. Unadorned integer literals (including `hex`, `octal` and `binary` numbers) yield integers. The constructor int() can be used to produce int of a specific type. - -Besides, integer literals may have an `SI` or `IEC` multiplier. - -- `SI`: General integer or fixed-point number form: `P`, `T`, `G`, `M`, `K`, `k`, `m`, `u`, `n`. -- `IEC`: Corresponding power of 2: `Pi`, `Ti`, `Gi`, `Mi`, `Ki`. - -```python -a = 1 # positive integer: 1 -b = -1 # negative integer: -1 -c = 0x10 # hexadecimal literal: 16 -d = 0o10 # octal literal: 8, or the form `010` -e = 0b10 # binary literal: 2 -f = 10Ki # integer literal with IEC multiplier: 10240 -g = 1M # integer literal with SI multiplier: 1000000 -h = int("10") # int constructor: 10 -i = int("10Ki") # int constructor with multiplier: 10240 -``` - -Notes: - -- Report an error if unable to represent an integer value precisely. - -### Float - -Float, floating-point, approximation to real numbers, positive or negative, containing one or more decimals, of 64 bit IEEE 754 floats. The constructor float() can be used to produce int of a specific type. - -```python -a = 1.10 -b = 1.0 -c = -35.59 -d = 32.3+e18 -f = -90. -g = -32.54e100 -h = 70.2-E12 -i = float("112") # float constructor -``` - -Notes: - -- Report an error if unable to represent a floating-point value due to overflow -- Report a warning if unable to represent a floating-point value due to underflow. Round to the nearest representable value if unable to represent a floating-point value due to limits on precision. These requirements apply to the result of any expression except for built-in functions for which an unusual loss of precision must be explicitly documented. - -#### None - -In KCL, `None` can indicate that the value of the object is empty, which is similar to `nil` in Go or `null` in Java, and corresponds to `null` in YAML and JSON. - -```python -a = None -b = [1, 2, None] -c = {"key1" = "value1", "key2" = None} -``` - -Please note that `None` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + None # error -b = int(None) # error -c = not None # True -d = None == None # True -e = None or 1 # 1 -f = str(None) # None -``` - -#### Undefined - -`Undefined` is similar to None, but its semantics is that a variable is not assigned any value and will not be output to YAML or JSON. - -```python -a = Undefined -b = [1, 2, Undefined] -c = {"key1" = "value1", "key2" = Undefined} -``` - -Please note that `Undefined` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + Undefined # error -b = int(Undefined) # error -c = not Undefined # True -d = Undefined == Undefined # True -e = Undefined or 1 # 1 -f = str(Undefined) # Undefined -``` - -### Common Numeric Operations - -Int and Float support the following operations (see built-in proposal for built-in details): - -- `x + y`: sum of x and y. -- `x - y`: difference of x and y. -- `x * y`: product of x and y. -- `x / y`: quotient of x and y. -- `x // y`: floored quotient of x and y. -- `x % y`: remainder of x / y. -- `x ** y`: x to the power y. -- `-x`: x negated. -- `+x`: x unchanged. -- `~x`: x bitwise negation. -- `abs(x)`: absolute value or magnitude of x. -- `int(x)`: x converted to integer. -- `float(x)`: x converted to floating point. - -KCL supports mixed arithmetic: when a binary arithmetic operator has operands of different numeric types, the operand with the "narrower" type is widened to that of the other, where integer is narrower than floating-point. - -### String - -Strings are immutable sequences of Unicode characters. String literals are written in a variety of ways: - -```python -'allows embedded "double" quotes' # Single quotes -"allows embedded 'single' quotes" # Double quotes -'''Three single quotes''', """Three double quotes""" # Triple quoted -``` - -Triple quoted strings may span multiple lines. - -Indexing a string produces strings of length 1, for a non-empty string s, `s[0] == s[0:1]`. - -```python -a = "Hello, World!" -b = a[2:5] # "llo" -c = a[-5:-2] # "orl" -d = a[::-1] # "'!dlroW ,olleH'" -``` - -- `str(x=None) -> str` - -Return a string. If _x_ is not provided, raise a runtime error. - -```python -x = str(3.5) # "3.5" -``` - -#### Members - -Built-in function and members of a string - -- `str#len() -> int` - Return the number of characters in the string. -- `capitalize() -> str` - Return a copy of the string with its first character (if any) capitalized and the rest lowercased. -- `count(sub: str, start: int = 0, end: int = -1) -> int` - Returns the number of (non-overlapping) occurrences of substring sub in string, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `endswith(suffix: str, start: int = 0, end: int = -1) -> bool` - Returns `True` if the string ends with the specified suffix, otherwise return `False`, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `find(sub: str, start: int = 0, end: int = -1) -> int` - Returns the lowest index where substring sub is found, or -1 if no such index exists, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `format(*args, **kwargs) -> str` - Perform string interpolation. Format strings contain replacement fields surrounded by curly braces {}. Anything that is not contained in braces is considered literal text, which is copied unchanged to the output. If you need to include a bracket character in the literal text, it can be escaped by doubling: A replacement field can be either a name, a number or empty. Values are converted to strings using the str function. -- `index(sub: str, start: int = 0, end: int = -1) -> int` - Returns the first index where sub is found, or raises an error if no such index exists, optionally restricting to `[start:end]` start being inclusive and end being exclusive. -- `isalnum() -> bool` - Returns True if all characters in the string are alphanumeric (`[a-zA-Z0-9]`) and there is at least one character, False otherwise. -- `isalpha() -> bool` - Returns True if all characters in the string are alphabetic (`[a-zA-Z]`) and there is at least one character. -- `isdigit() -> bool` - Returns True if all characters in the string are digits (`[0-9]`) and there is at least one character. -- `islower() -> bool` - Returns True if all cased characters in the string are lowercase and there is at least one character. -- `isspace() -> bool` - Returns True if all characters are white space characters and the string contains at least one character. -- `istitle() -> bool` - Returns True if the string is in title case and it contains at least one character. This means that every uppercase character must follow an uncased one (e.g., whitespace) and every lowercase character must follow a cased one (e.g., uppercase or lowercase). -- `isupper() -> bool` - Returns True if all cased characters in the string are uppercase and there is at least one character. -- `join(iterable: list) -> str` - Return a string which is the concatenation of the strings in iterable. A TypeError will be raised if there are any non-string values in iterable. The separator between elements is the string providing this method. Example: - - ```python - >>> "|".join(["a", "b", "c"]) - "a|b|c" - ``` - -- `lower() -> str` - Returns a copy of the string with all the cased characters converted to lowercase. -- `lstrip(chars: str) -> str` - Return a copy of the string with leading characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.lstrip() - 'spacious ' - >>> 'www.example.com'.lstrip('cmowz.') - 'example.com' - ``` - -- `replace(old: str, new: str, count: int) -> str` - Return a copy of the string with all occurrences of substring old replaced by new. If the optional argument count is given, only the first count occurrences are replaced. -- `rfind(sub: str, start: int = 0, end: int = -1) -> int` - Return the highest index in the string where substring sub is found, such that sub is contained within s[start:end]. Optional arguments start and end are interpreted as in slice notation. Return -1 on failure. -- `rindex(sub: str, start: int = 0, end: int = -1) -> int` - Returns the last index where sub is found, or raises an ValueError if no such index exists, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `rsplit(sep: str, maxsplit: int = -1) -> list` - Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done, the rightmost ones. If sep is not specified or None, any whitespace string is a separator. Except for splitting from the right, rsplit() behaves like split() which is described in detail below. -- `rstrip(chars: str) -> str` - Return a copy of the string with trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a suffix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.rstrip() - ' spacious' - >>> 'mississippi'.rstrip('ipz') - 'mississ' - ``` - -- `split(sep: str, maxsplit: int) -> list` - Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done (thus, the list will have at most maxsplit+1 elements). If maxsplit is not specified or -1, then there is no limit on the number of splits (all possible splits are made). - - If sep is given, consecutive delimiters are not grouped together and are deemed to delimit empty strings (for example, `'1,,2'.split(',')` returns `['1', '', '2']`). The sep argument may consist of multiple characters (for example, `'1<>2<>3'.split('<>')` returns `['1', '2', '3']`). Splitting an empty string with a specified separator returns `['']`. - - For example: - - ```python - >>> '1,2,3'.split(',') - ['1', '2', '3'] - >>> '1,2,3'.split(',', maxsplit=1) - ['1', '2,3'] - >>> '1,2,,3,'.split(',') - ['1', '2', '', '3', ''] - ``` - - If sep is not specified or is None, a different splitting algorithm is applied: runs of consecutive whitespace are regarded as a single separator, and the result will contain no empty strings at the start or end if the string has leading or trailing whitespace. Consequently, splitting an empty string or a string consisting of just whitespace with a `None` separator returns `[]`. - - For example: - - ```python - >>> '1 2 3'.split() - ['1', '2', '3'] - >>> '1 2 3'.split(maxsplit=1) - ['1', '2 3'] - >>> ' 1 2 3 '.split() - ['1', '2', '3'] - ``` - -- `splitlines(keepends: str) -> list` - Return a list of the lines in the string, breaking at line boundaries('\n', '\r\n', '\r'). Line breaks are not included in the resulting list unless keepends is given and true. - - This method splits on the following line boundaries. In particular, the boundaries are a superset of universal newlines. - - For example: - - ```python - >>> 'ab c\n\nde fg\rkl\r\n'.splitlines() - ['ab c', '', 'de fg', 'kl'] - >>> 'ab c\n\nde fg\rkl\r\n'.splitlines(keepends=True) - ['ab c\n', '\n', 'de fg\r', 'kl\r\n'] - ``` - - Unlike `split()` when a delimiter string sep is given, this method returns an empty list for the empty string, and a terminal line break does not result in an extra line: - - ```python - >>> "".splitlines() - [] - >>> "One line\n".splitlines() - ['One line'] - ``` - - For comparison, `split('\n')` gives: - - ```python - >>> ''.split('\n') - [''] - >>> 'Two lines\n'.split('\n') - ['Two lines', ''] - ``` - -- `startswith(prefix: str, start: int = 0, end: int = -1) -> bool` - Return `True` if string starts with the prefix, otherwise return False. prefix can also be a list of prefixes to look for. With optional start, test string beginning at that position. With optional end, stop comparing string at that position. -- `strip(chars: str) -> str` - Return a copy of the string with the leading and trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix or suffix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.strip() - 'spacious' - >>> 'www.example.com'.strip('cmowz.') - 'example' - ``` - - The outermost leading and trailing chars argument values are stripped from the string. Characters are removed from the leading end until reaching a string character that is not contained in the set of characters in chars. A similar action takes place on the trailing end. For example: - - ```python - >>> comment_string = '#....... Section 3.2.1 Issue #32 .......' - >>> comment_string.strip('.#! ') - 'Section 3.2.1 Issue #32' - ``` - -- `title() -> str` - Return a titlecased version of the string where words start with an uppercase character and the remaining characters are lowercase. - - For example: - - ```python - >>> 'Hello world'.title() - 'Hello World' - ``` - - The algorithm uses a simple language-independent definition of a word as groups of consecutive letters. The definition works in many contexts but it means that apostrophes in contractions and possessives form word boundaries, which may not be the desired result: - - ```python - >>> "they're bill's friends from the UK".title() - "They'Re Bill'S Friends From The Uk" - ``` - -- `upper() -> str` - Return a copy of the string with all the cased characters 4 converted to uppercase. Note that `s.upper().isupper()` might be `False` if s contains uncased characters or if the Unicode category of the resulting character(s) is not “Lu” (Letter, uppercase), but e.g., “Lt” (Letter, titlecase). -- `removeprefix(prefix: str) -> str` - If the string starts with the prefix string, return string[len(prefix):]. Otherwise, return a copy of the original string. - ```python - >>> "prefix-data".removeprefix("prefix-") - "data" - ``` -- `rermovesuffix(suffix: str) -> str` - If the string ends with the suffix string and that suffix is not empty, return string[:-len(suffix)]. Otherwise, return a copy of the original string. - ```python - >>> "data-suffix".removesuffix("-suffix") - "data" - ``` - -### List - -Lists are immutable sequences, typically used to store collections of homogeneous items (where the precise degree of similarity will vary by application). - -Lists may be constructed in several ways: - -- Using a pair of square brackets to denote the empty list: `[]` -- Using square brackets, separating items with commas: `[a]`, `[a, b, c]` -- Using a list comprehension: `[x for x in iterable]` -- Using the type constructor: list() or list(iterable) - -The constructor builds a list whose items are the same and in the same order as iterable’s items.Iterable may be either a sequence, a container that supports iteration, or an iterator object. If iterable is already a list, a copy is made and returned, similar to `iterable[:]`. For example, `list('abc')` returns `['a', 'b', 'c']` and `list([1, 2, 3])` returns `[1, 2, 3]`. If no argument is given, the constructor creates a new empty list `[]`. - -Lists implement all of the common sequence operations. - -#### Members - -- `len()` - Return the number of items in the list. - -### Common Sequence Operations - -The operations in the following table are supported by List and Dict. - -This table lists the sequence operations sorted in ascending priority. In the table, s and t are sequences of the same type, n, i, j and k are integers and x is an arbitrary object that meets any type and value restrictions imposed by s. - -The `in` and `not in` operations have the same priorities as the comparison operations. The + -(concatenation) and \* (repetition) operations have the same priority as the corresponding numeric operations. - -| Operation | Result | Notes | -| ------------ | -------------------------------------------------- | ----- | -| `x in s` | `True` if an item of s is equal to x, else `False` | #1 | -| `x not in s` | `False` if an item of s is equal to x, else `True` | #1 | -| `s + t` | the concatenation of s and t | #5 | -| `s[i]` | ith item of s, origin 0 | #2 | -| `s[i:j]` | slice of s from i to j | #2 #3 | -| `s[i:j:k]` | slice of s from i to j with step k | #2 #4 | -| `min(s)` | smallest item of s | | -| `max(s)` | largest item of s | | - -Notes: - -- 1. While the in and not in operations are used only for simple containment testing in the - general case, some specialized sequences (str) also use them for subsequence testing: - -```python ->>> "gg" in "eggs" -True -``` - -- 2. If i or j is negative, the index is relative to the end of sequence s: `s.len() + i` or `s.len() + j` is substituted. But note that -0 is still 0. -- 3. The slice of s from i to j is defined as the sequence of items with index k such that `i <= k < j`. If i or j is greater than `s.len()`, use `s.len()`. If i is omitted or None, use 0. If j is omitted or None, use `s.len()`. If i is greater than or equal to j, the slice is empty. -- 4. The slice of s from i to j with step k is defined as the sequence of items with index `x = i + n*k` such that `0 <= n < (j-i)/k`. In other words, the indices are `i`, `i+k`, `i+2*k`, `i+3*k` and so on, stopping when j is reached (but never including j). When k is positive, i and j are reduced to s.len() if they are greater. When k is negative, i and j are reduced to s.len() - - - If they are greater. If i or j are omitted or None, they become “end” values (which end depends on the sign of k). Note, k cannot be zero. If k is None, it is treated like 1. - -- 5. Concatenating immutable sequences always results in a new object. This means that building up a sequence by repeated concatenation will have a quadratic runtime cost in the total sequence length. To get a linear runtime cost, you must switch to one of the alternatives below: - - - if concatenating str objects, you can build a list and use `str.join()` at the end - -- 6. `index` raises `ValueError` when x is not found in s. Not all implementations support passing the additional arguments i and j. These arguments allow efficient searching of subsections of the sequence. Passing the extra arguments is roughly equivalent to using `s[i:j].index(x)`, only without copying any data and with the returned index being relative to the start of the sequence rather than the start of the slice. - -### Dict - -Dict is an immutable mapping object maps hashable values to arbitrary objects. A dictionary’s keys are almost arbitrary values. Values that are not hashable, that is, values containing lists, dictionaries may not be used as keys. Numeric types used for keys obey the normal rules for numeric comparison: if two numbers compare equal (such as 1 and 1.0) then they can be used interchangeably to index the same dictionary entry. (Note however, that since computers store floating-point numbers as approximations it is usually unwise to use them as dictionary keys.) Dict is ordered. The order of the keys is the order of their declaration. - -Dictionaries can be created by placing a comma-separated list of keys: value pairs within braces, for example: `{'jack': 4098, 'sjoerd': 4127}` or `{4098: 'jack', 4127: 'sjoerd'}`, by the dict constructor, or list/dict comprehension. - -- `dict(obj)` - -Return a new dictionary initialized from an optional positional argument and a possibly empty set of keyword arguments.If no positional argument is given, an empty dictionary is created. If a positional argument is given and it is a mapping object, a dictionary is created with the same key-value pairs as the mapping object. Otherwise, the positional argument must be an iterable object. Each item in the iterable must itself be an iterable with exactly two objects. The first object of each item becomes a key in the new dictionary, and the second object the corresponding value. If a key occurs more than once, the last value for that key becomes the corresponding value in the new dictionary. If keyword arguments are given, the keyword arguments and their values are added to the dictionary created from the positional argument. If a key being added is already present, the value from the keyword argument replaces the value from the positional argument. To illustrate, the following examples all return a dictionary equal to `{"one": 1, "two": 2, "three": 3}`: - -```python ->>> a = {'two': 2, 'one': 1, 'three': 3} ->>> b = {'one': 1, 'two': 2, 'three': 3} ->>> c = {'three': 3, 'one': 1, 'two': 2} ->>> a == b == c -True -``` - -Providing keyword arguments as in the first example only works for keys that are valid KCL identifiers. Otherwise, any valid keys can be used. - -In the dict comprehension, key/value pairs yielded by the generator expression is set in the dictionary in the order yielded: the first occurrence of the key determines its insertion order, and the last determines the value associated to it. - -```python ->>> {str(i): 2 * i for i in range(3)} -{"0": 0, "1": 2, "2": 4} - ->>> a = {"one": 1, "two": 2, "three": 3} ->>> b = {k: v for k, v in a if v >= 2} -{two: 2, three: 3} -``` - -#### Operations & Members - -These are the operations that dictionaries the support. - -- `list(d)` - Return a list of all the keys used in the dictionary d. -- `len()` - Return the number of items in the dictionary d. -- `d[key]` - Return the item of d with key. Return Undefined if key is not in the map. -- `key in d` - Return True if d has a key, else False. -- `key not in d` - Equivalent to not key in d. -- `d.key` - Return the item of d with key. Return Undefined if key is not in the map. - -Dictionaries compare equal if and only if they have the same (key, value) pairs(keys' ordering matters). Order comparisons (‘<’, ‘<=’, ‘>=’, ‘>’) raise TypeError. - -```python ->>> d = {"one": 1, "two": 2, "three": 3, "four": 4} ->>> d -{'one': 1, 'two': 2, 'three': 3, 'four': 4} ->>> list(d) -['one', 'two', 'three', 'four'] -``` diff --git a/versioned_docs/version-0.5.0/reference/lang/spec/error.md b/versioned_docs/version-0.5.0/reference/lang/spec/error.md deleted file mode 100644 index 2a58b553..00000000 --- a/versioned_docs/version-0.5.0/reference/lang/spec/error.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: "Errors" -linkTitle: "Errors" -type: "docs" -weight: 2 -description: Errors ---- - -When errors happen, developers should be able to detect the error and abort -execution. Thus, KCL introduce the `assert` syntax. - -In the previous topic of `schema` syntax. Errors can also be raised when a -schema is violated. - -## Syntax - -The syntax of the `assert` statement is the following. - -```bnf -assert_stmt: 'assert' test ['if' test] [',' test] -``` - -In the basic form, an `assert` statement evaluates an expression. If the -expression is evaluated to `False`, the assertion is failed, and an error -should be reported. - -In the extended form, an error message can be provided. The error message is -another expression. It is only evaluated when the expression to be evaluated -is evaluated to `False`. The evaluation result of the error message is printed -when reporting the error. - -The following is an example: - -```python -a = 1 -b = 3 -condition = False -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -# if condition is True, then assert `a == b`, if failed, the message "error message" will be printed. -assert a == b if condition, "error message" -``` - -## The Implementation - -When an error happens, no matter it is caused by the `assert` or the `schema` syntax, -the virtual machine should exit with an exit code greater than `0`. - -The virtual machine may choose to dump the back trace information, and it is strongly recommended to implement it. - -In practice, KCL can dump back trace by default, and an argument can be introduced to disable it. diff --git a/versioned_docs/version-0.5.0/reference/lang/spec/expressions.md b/versioned_docs/version-0.5.0/reference/lang/spec/expressions.md deleted file mode 100644 index b52c10f3..00000000 --- a/versioned_docs/version-0.5.0/reference/lang/spec/expressions.md +++ /dev/null @@ -1,915 +0,0 @@ ---- -title: "Expressions" -linkTitle: "Expressions" -type: "docs" -weight: 2 -description: Expressions ---- - -## Syntax - -In KCL, an expression specifies the computation of a value. - -The syntax is the following: - -```bnf -expression: test ("," test)* -test: if_expr | primary_expr | unary_expr | binary_expr -``` - -KCL expressions consist of `if` expression, `primary` expression, `unary` expression, and `binary` expression. - -### Primary Expressions - -Primary expressions are the operands for unary and binary expressions. - -Operands are self-delimiting. An **operand** may be followed by any number of selector dot, a function call, or slice suffixes, to form a primary expression. The grammar uses `expression`, where a multiple-component expression is allowed, and `test` where it accepts an expression of only a single component. - -Syntax: - -```bnf -primary_expr: operand | primary_expr select_suffix | primary_expr call_suffix | primary_expr subscript_suffix -``` - -### Operands - -Operand denotes the elementary value in an expression. An operand may be an identifier, a literal, or a parenthesized expression. - -Syntax: - -```bnf -operand: operand_name | number | string | "True" | "False" | "None" | "Undefined" | list_expr | list_comp | dict_expr | dict_comp | "(" expression ")" -operand_name: identifier | qualified_identifier -``` - -### Identifiers - -In KCL, an identifier is a name, may with selectors, that identifies a value. - -Syntax: - -```bnf -identifier: NAME -``` - -Examples: - -```python -x -a -_b -``` - -Use the `$` character prefix to define keyword identifiers. - -```python -$if = 1 -$else = "s" -``` - -Please note: whether the non-keyword identifier is prefixed with `$` has the same effect. - -```python -_a = 1 -$_a = 2 # equal to `_a = 2` -``` - -To simplify the definition of the qualified identifier, such as 'pkg.type', we additionally define `qualified_identifier`: - -Syntax: - -```bnf -qualified_identifier: identifier "." identifier -``` - -Examples: - -```python -pkg.a -``` - -The package name in qualified_identifier must be imported. - -### Basic Literals - -Basic literals supported in KCL are `int`, `float`, `string` and `bool` including `True` and `False`. Evaluation of basic literal yields a value of the given type with the given value. - -Syntax: - -```bnf -operand: number | string | "True" | "False" | "None" | "Undefined" -``` - -Examples: - -```python -1 -2.3 -"abc" -True -False -None -Undefined -``` - -See more details about **data type** spec. - -### Parenthesized Expressions - -An expression enclosed in parentheses yields the result of that expression. - -Syntax: - -```bnf -operand: '(' expression ')' -``` - -Examples: - -```python -x = (1 + 2) * (3 + 4) # 21 -``` - -### Dictionary Expressions - -A dictionary expression is a comma-separated immutable list of colon-separated key/value expression pairs, enclosed in curly brackets, and it yields a new dictionary object. An optional comma may follow the final pair. - -```bnf -config_expr: '{' config_entries '}' -config_entries: config_entry [config_entry*] -config_comp: '{' (config_entry comp_clause+) '}' -config_entry: expr (':' | '=' | '+=') expr | double_star_expr | if_entry -double_star_expr: "**" expression -if_entry: - 'if' expr ';' if_entry_exec_block - ('elif' expr ':' if_entry_exec_block)* - ('else' ':' if_entry_exec_block)? -NEWLINE: '/r?/n' -``` - -Examples: - -```python -{} -{"one": 1} -{"one": 1, "two": 2} -``` - -The key and value expressions are evaluated in left-to-right order. Evaluation fails if the same key is used multiple times. - -Only hashable values may be used as the keys of a dictionary. This includes all built-in types except dictionaries, and lists. - -We can ignore the comma `,` at the end of the line for writing dict key-value pairs in multiple lines: - -```python -data = { - "key1" = "value1" # Ignore the comma ',' at the end of line - "key2" = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -We can ignore the key quotation marks when we writing simple literals on the key. - -```python -data = { - key1 = "value1" # Ignore the comma ',' at the end of line - key2 = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -In addition, the **config selector expressions** can be used to init a schema instance. - -```python -person = { - base.count = 2 - base.value = "value" - labels.key = "value" -} # {"base": {"count": 2, "value": "value"}, "labels": {"key": "value"}} -``` - -We can **merge** dict using the dict unpacking operator `**` like this: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = {**_part1, **_part2} # {"a: "b", "c": "d"} -``` - -We can use `if expressions` to dynamically add elements to the dict element, elements that meet the conditions are added to the dict, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = { - key1 = "value1" - if a == 1: key2 = "value2" - if a > 0: key3 = "value3" - if a < 0: key4 = "value4" -} # {"key1": "value1", "key2": "value2", "key3": "value3"} -``` - -```python -a = 1 # 1 -data1 = { - key1 = "value1" - if a == 1: - key2 = "value2" - elif a > 0: - key3 = "value3" - else: - key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -data2 = { - key1 = "value1" - if a == 1: key2 = "value2" - elif a > 0: key3 = "value3" - else: key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -``` - -### List Expressions - -A list expression is a comma-separated immutable list of element expressions, enclosed in square brackets, and it yields a new list. An optional comma may follow the last element expression. - -```bnf -list_expr: '[' [list_item [',']] ']' -list_item: test | "*" primary_expr | if_expr -``` - -Element expressions are evaluated in left-to-right order. - -Examples: - -```python -[] # [], empty list -[1] # [1], a 1-element list -[1, 2, 3] # [1, 2, 3], a 3-element list -``` - -We can use `if expressions` to dynamically add elements to the list element, elements that meet the conditions are added to the list, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = [ - 1 - if a == 1: 2 - if a > 0: 3 - if a < 0: 4 -] # [1, 2, 3] -``` - -```python -a = 1 # 1 -data1 = [ - 1 - if a == 1: - 2 - elif a == 2: - 3 - else: - 3 -] # [1, 2] -data2 = [ - 1 - if a == 1: 2 - elif a == 2: 2 - else: 3 -] # [1, 2] -``` - -### Comprehensions - -A comprehension constructs a new list or dictionary value by looping over one or more iterables and evaluating a body expression that produces successive elements of the result. - -Syntax: - -```bnf -list_comp: '[' list_item comp_clause+ ']' . -dict_comp: '{' entry comp_clause+ '}' . - -comp_clause: 'for' loop_variables [","] 'in' test ['if' test] -loop_variables: primary_expr (',' primary_expr)* -``` - -A list comprehension consists of a single expression followed by one or more clauses, the first of which must be a `for` clause. Each `for` clause resembles a `for` statement, and specifies an iterable operand and a set of variables to be assigned by successive values of the iterable. An `if` cause resembles an `if` statement, and specifies a condition that must be met for the body expression to be evaluated. A sequence of `for` and `if` clauses acts like a nested sequence of `for` and `if` statements. - -Examples: - -```python -[x * x for x in range(5)] # [0, 1, 4, 9, 16] -[x * x for x in range(5) if x % 2 == 0] # [0, 4, 16] -[[x, y] for x in range(5) \ - if x % 2 == 0 \ - for y in range(5) \ - if y > x] # [[0, 1], [0, 2], [0, 3], [0, 4], [2, 3], [2, 4]] -``` - -Besides, we can use two variables in the list comprehension, the first variable denotes the list index and the second variable denotes the list item. - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use `_` to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -A dict comprehension resembles a list comprehension, but its body is a pair of expressions, key: value, separated by a colon, and its result is a dictionary containing the key/value pairs for which the body expression was evaluated. Evaluation fails if the value of any key is un-hashable. - -Besides, we can use two variables in the dict comprehension, the first variable denotes the dict key and the second variable denotes the dict value of the key. - -```python -data = {"key1" = "value1", "key2" = "value2"} -# Single variable loop -dataKeys1 = {k: k for k in data} # {"key1": "key1", "key2": "key2"} -dataValues1 = {k: data[k] for k in data} # {"key1": "value1", "key2": "value2"} -# Double variable loop -dataKeys2 = {k: k for k, v in data} # {"key1": "key1", "key2": "key2"} -dataValues2 = {v: v for k, v in data} # {"value1": "value1", "value2": "value2"} -dataFilter = {k: v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use `_` to ignore loop variables -dataKeys3 = {k: k for k, _ in data} # {"key1": "key1", "key2": "key2"} -dataValues3 = {v: v for _, v in data} # {"value1": "value1", "value2": "value2"} -``` - -As with a `for` loop, the loop variables may exploit compound assignment: - -```python -[x * y + z for [x, y], z in [[[2, 3], 5], [["o", 2], "!"]]] # [11, 'oo!'] -``` - -KCL does not accept an un-parenthesized list as the operand of a for clause: - -```python -[x * x for x in 1, 2, 3] # parse error: unexpected comma -``` - -Comprehensions defines a new lexical block, so assignments to loop variables have no effect on variables of the same name in an enclosing block: - -```python -x = 1 -_ = [x for x in [2]] # new variable x is local to the comprehension -print(x) # 1 -``` - -The operand of a comprehension's first clause (always a for) is resolved in the lexical block enclosing the comprehension. In the examples below, identifiers referring to the outer variable named x have been distinguished by subscript. - -```python -x0 = [1, 2, 3] -[x * x for x in x0] # [1, 4, 9] -[x * x for x in x0 if x % 2 == 0] # [4] -``` - -All subsequent for and if expressions are resolved within the comprehension's lexical block, as in this rather obscure example: - -```python -x0 = [[1, 2], [3, 4], [5, 6]] -[x * x for x in x0 for x in x if x % 2 == 0] # [4, 16, 36] -``` - -which would be more clearly rewritten as: - -```python -x = [[1, 2], [3, 4], [5, 6]] -[z * z for y in x for z in y if z % 2 == 0] # [4, 16, 36] -``` - -### Conditional Expressions - -A conditional expression has the form `a if cond else b`. It first evaluates the condition `cond`. If it's true, it evaluates `a` and yields its value; otherwise it yields the value of `b`. - -Syntax: - -```bnf -if_expr: test "if" test "else" test -``` - -Examples: - -```python -x = True if enabled else False # if enabled is -``` - -### Unary Expressions - -In KCL, supported unary operators are `+`, `-`, `~`, and `not`. - -Syntax: - -```bnf -unary_expr: ("+" | "-" | "~") primary_expr - | "not" test -``` - -Usage: - -```bnf -+ number unary positive (int, float) -- number unary negation (int, float) -~ number unary bitwise inversion (int) -not x logical negation (any type) -``` - -The `+` and `-` operators may be applied to any number (int or float) and return the number. -The `not` operator returns the negation of the truth value of its operand. - -Examples: - -```python -~1 # -2 -~-1 # 0 -~0 # -1 -not True # False -not 0 # True -``` - -### Binary Expressions - -In KCL, binary expressions consist of `comparisons`, `logical operations`, `arithmetic operations` and `membership tests`. - -Syntax: - -```bnf -binary_expr: test bin_op test -bin_op: 'or' - | 'and' - | '==' | '!=' | '<' | '>' | '<=' | '>=' - | 'in' | 'not' 'in' - | '|' - | '^' - | '&' - | '-' | '+' - | '*' | '%' | '/' | '//' - | '<<' | '>>' -``` - -#### Logical Operations - -The `or` and `and` operators yield the logical disjunction and conjunction of their arguments, which need not be Booleans. - -The expression `x or y` yields the value of `x` if its truth value is `True`, or the value of `y` otherwise. - -```python -False or False # False -False or True # True -True or True # True -1 or "hello" # 1 -``` - -Similarly, `x` and `y` yields the value of `x` if its truth value is `False`, or the value of `y` otherwise. - -```python -False and False # False -False and True # False -True and True # True -1 and "hello" # "hello" -``` - -These operators use "short circuit" evaluation, so the second expression is not evaluated if the value of the first expression has already determined the result, allowing constructions like these: - -```python -x and x[0] == 1 # x[0] is not evaluated if x is empty -len(x) == 0 or x[0] == "" -not x or not x[0] -``` - -#### Comparisons - -The `==` operator reports whether its operands are equal; the `!=` operator is its negation. - -The operators `<`, `>`, `<=`, and `>=` perform an ordered comparison of their operands. It is an error to apply these operators to operands of unequal type, unless one of the operands is an `int` and the other is a `float`. Of the built-in types, only the following support ordered comparison, using the ordering relation shown: - -```bnf -NoneType # None <= None -bool # False < True -int # mathematical -float # as defined by IEEE 754 -string # lexicographical -list # lexicographical -``` - -Comparison of floating-point values follows the IEEE 754 standard, which breaks several mathematical identities. For example, if `x` is a `NaN` value, the comparisons `x < y`, `x == y`, and `x > y` all yield false for all values of `y`. - -The remaining built-in types support only equality comparisons. Values of type `dict` and `schema` compare equal if their elements compare equal, and values of type function or `builtin_function_or_method` are equal only to themselves. - -```bnf -dict # equal contents -schema # equal exported-attributes -function # identity -builtin_function_or_method # identity -``` - -#### Arithmetic Operations - -The following table summarizes the binary arithmetic operations available for built-in types: - -```bnf -Arithmetic (int or float; result has type float unless both operands have type int) - number + number # addition - number - number # subtraction - number * number # multiplication - number / number # real division (result is always a float) - number // number # floored division - number % number # remainder of floored division - number ^ number # bitwise XOR - number << number # bitwise left shift - number >> number # bitwise right shift - -Concatenation - string + string - list + list - -Repetition (string/list) - int * sequence - sequence * int - -Union - int | int - list | list - dict | dict - schema | schema - schema | dict -basictype | basictype -``` - -The operands of the arithmetic operators `+`, `-`, `*`, `//`, and `%` must both be numbers (`int` or `float`) but need not have the same type. The type of the result has type `int` only if both operands have that type. The result of real division / always has type `float`. - -The `+` operator may be applied to non-numeric operands of the same type, such as two lists, or two strings, in which case it computes the concatenation of the two operands and yields a new value of the same type. - -```python -"Hello, " + "world" # "Hello, world" -[1, 2] + [3, 4] # [1, 2, 3, 4] -``` - -The `*` operator may be applied to an integer n and a value of type `string`, `list`, in which case it yields a new value of the same sequence type consisting of n repetitions of the original sequence. The order of the operands is immaterial. Negative values of n behave like zero. - -```python -'mur' * 2 # 'murmur' -3 * range(3) # [0, 1, 2, 0, 1, 2, 0, 1, 2] -``` - -The `&` operator requires two operands of the same type, such as `int`. For integers, it yields the bitwise intersection (AND) of its operands. - -The `|` operator likewise computes bitwise, unions basic types and unions collection and schema data, such as **list**, **dict** and **schema**. - -Computing bitwise examples: - -```python -0x12345678 | 0xFF # 0x123456FF -``` - -Unioning basic types examples: - -```python -schema x: - a: int | str # attribute a could be a int or string -``` - -A union type is used to define a schema attribute type. See more details in **schema** spec. -Supported types in a union type are `int`, `str`, `float`, `bool`, `list` and `dict`. - -Unioning collection and schema data: - -- Unioning List. Overwrite the list expression on the right side of the operator `|` to the list variable on the left side of the operator one by one according to the **index**. - -```python -_a = [1, 2, 3] -_b = [4, 5, 6, 7] -x = _a | _b # [4, 5, 6, 7] 4 -> 1; 5 -> 2; 6 -> 3; 7 -> None -``` - -Unioning to the specific index or all elements is still under discussion. - -- Unioning Dict. Union the dict expression on the right side of the operator `|` one by one to the dict variable on the left side of the operator according to the **key** - -```python -_a = {key1 = "value1"} -_b = {key1 = "overwrite", key2 = "value2"} -_c = _a | _b # {"key1": "overwrite", "key2": "value2"} -``` - -The union of collection and schema is a new one whose attributes are unioning b to a, preserving the order of the attributes of the operands, left before right. - -Unioning to the specific key or all keys is still under discussion. - -- Unioning Schema. - -The union operation for schema is similar to dict. - -Schema union could be done as: - -```bnf -schema Person: - firstName: str - lastName: str - -_a = Person { - firstName = "John" -} -_b = {lastName = "Doe"} -_a = _a | _b # {"firstName": "John", "lastName": "Doe"} -``` - -Unioning to a specific attribute is still under discussion. Unioning to all attributes is not applicable to schema instances. - -See **selector expression** in **expression** spec for more details. - -The `^` operator accepts operands of `int`. For integers, it yields the bitwise XOR (exclusive OR) of its operands. - -The `<<` and `>>` operators require operands of `int` type both. They shift the first operand to the left or right by the number of bits given by the second operand. It is a dynamic error if the second operand is negative. Implementations may impose a limit on the second operand of a left shift. - -```python -0x12345678 & 0xFF # 0x00000078 -0b01011101 ^ 0b110101101 # 0b111110000 -0b01011101 >> 2 # 0b010111 -0b01011101 << 2 # 0b0101110100 -``` - -#### Membership Tests - -Usage: - -```bnf - any in sequence (list, dict, schema, string) - any not in sequence -``` - -The `in` operator reports whether its first operand is a member of its second operand, which must be a list, dict, schema, or string. The `not in` operator is its negation. Both return a Boolean. - -The meaning of membership varies by the type of the second operand: the members of a list are its elements; the members of a dict are its keys; the members of a string are all its substrings. - -```python -1 in [1, 2, 3] # True - -d = {"one" = 1, "two" = 2} -"one" in d # True -"three" in d # False -1 in d # False -[] in d # False - -"nasty" in "dynasty" # True -"a" in "banana" # True -"f" not in "way" # True - -d = data {one = 1, two = 2} # data is a schema with attributes one and two -"one" in d # True -"three" in d # False -``` - -### Function Invocations - -KCL allows calling built-in functions and functions from built-in and system modules. Whether KCL allows defining new functions is under discussion. - -Syntax: - -```bnf -call_suffix: "(" [arguments [","]] ")" -arguments: argument ("," argument)* -argument: test | identifier "=" test | "*" test | "**" test -``` - -To call a function, the basic way is shown as the following code excerpt: - -```python -print("An argument") - -import math -# 2 powers 3 is 8. -a = math.pow(2, 3) -``` - -As you can see, arguments are separated with `,`. Arguments can only be passed in this way. KCL supports positional arguments and key-value arguments. - -Note that: - -- Some functions have parameters with default values. -- Some functions accept variadic arguments. - -When an argument is not supplied for a parameter without a default value, -an error will be reported. - -### Selector Expressions - -A selector expression selects the attribute or method of the value. - -#### Select Attributes - -Syntax: - -```bnf -select_suffix: ["?"] "." identifier -``` - -KCL provides a wealth of ways to identify or filter attributes. - -x.y - -- schema: it denotes the attribute value of a schema `x` identified by `y` -- package: it denotes the identifier of a package `x` identified by `y` - -Examples: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -name = person.name # "Alice" -age = person.age # 18 -``` - -x?.y - -If the x if None/Undefined or empty(empty list or dict), just return None, otherwise behave as x.y. - -Examples - -```python -noneData = None -data?.name # None - -emptyDict = {} -emptyDict?.name # None - -emptyList = [] -emptyList?[0] # None -``` - -As a supplementary of the `selector` expression in KCL code, the KCL compiler needs to provide corresponding identifying and filtering features through the command line and api form. - -#### Select Methods - -Syntax: - -```bnf -select_suffix: "." identifier -``` - -A `identifier` identifies method belongs to the built-in types `string`, `list`, `dict`, and `schema`. - -- A selector expression fails if the value does not have an attribute of the specified name. -- A selector expression that selects a method typically appears within a call expression, as in these examples: - -Examples: - -```python -["able", "baker", "charlie"].index("baker") # 1 -"banana".count("a") # 3 -"banana".reverse() # error: string has no .reverse field or method -Person.instances() # all instances of schema Person -``` - -But when not called immediately, the selector expression evaluates to a bound method, that is, a method coupled to a specific receiver value. A bound method can be called like an ordinary function, without a receiver argument: - -```bnf -f = "banana".count -f # -f("a") # 3 -f("n") # 2 -``` - -### Index Expressions - -An index expression `a[i]` yields the `i` th element of an indexable type such as a string or list. The index `i` must be an `int` value in the range `-n` ≤ `i` < `n`, where `n` is `len(a)`; any other index results in an error. - -Syntax: - -```bnf -subscript_suffix: "[" [test] "]" -``` - -A valid negative index `i` behaves like the non-negative index `n+i`, allowing for convenient indexing relative to the end of the sequence. - -```python -"abc"[0] # "a" -"abc"[1] # "b" -"abc"[-1] # "c" - -["zero", "one", "two"][0] # "zero" -["zero", "one", "two"][1] # "one" -["zero", "one", "two"][-1] # "two" -``` - -An index expression `d[key]` may also be applied to a dictionary `d`, to obtain the value associated with the specified key. It returns `Undefined` if the dictionary contains no such key. - -An index expression appearing on the left side of an assignment causes the specified list or dictionary element to be updated: - -```python -a = range(3) # a == [0, 1, 2] -b = a[2] # 2 - - -``` - -It is a dynamic error to attempt to update an element of an immutable type, such as a list or string, or a frozen value of a mutable type. - -### Slice Expressions - -A slice expression `a[start:stop:stride]` yields a new value containing a sub-sequence of `a`, which must be a string, or list. - -```bnf -subscript_suffix: "[" [test] [":" [test] [":" [test]]] "]" -``` - -Each of the `start`, `stop`, and `stride` operands is optional; if present, and not `None`, each must be an integer. -The `stride` value defaults to 1. If the stride is not specified, the colon preceding it may be omitted too. It is an error to specify a stride of zero. - -Conceptually, these operands specify a sequence of values `i` starting at start and successively adding `stride` until `i` reaches or passes `stop`. The result consists of the concatenation of values of `a[i]` for which `i` is valid.` - -The effective start and stop indices are computed from the three operands as follows. Let `n` be the length of the sequence. - -**If the stride is positive**: If the `start` operand was omitted, it defaults to -infinity. If the `end` operand was omitted, it defaults to +infinity. For either operand, if a negative value was supplied, `n` is added to it. The `start` and `end` values are then "clamped" to the nearest value in the range 0 to `n`, inclusive. - -**If the stride is negative**: If the `start` operand was omitted, it defaults to +infinity. If the `end` operand was omitted, it defaults to -infinity. For either operand, if a negative value was supplied, `n` is added to it. The `start` and `end` values are then "clamped" to the nearest value in the range -1 to `n`-1, inclusive. - -```python -"abc"[1:] # "bc" (remove first element) -"abc"[:-1] # "ab" (remove last element) -"abc"[1:-1] # "b" (remove first and last element) -"banana"[1::2] # "aaa" (select alternate elements starting at index 1) -"banana"[4::-2] # "nnb" (select alternate elements in reverse, starting at index 4) -``` - -It's not allowed to define a slice expression as a left value in KCL. -Cause list and string are immutable, re-slicing can directly operate to operand to ensure better performance. - -#### Quantifier Expressions - -Quantifier expressions act on collection: list or dict, generally used to obtain a certain result after processing the collection, mainly in the following four forms: - -```bnf -quant_expr: quant_op [ identifier ',' ] identifier 'in' quant_target '{' expr ['if' expr] '}' -quant_target: string | identifier | list_expr |list_comp | dict_expr | dict_comp -quant_op: 'all' | 'any' | 'filter' | 'map' -``` - -- **all** - - Used to detect that all elements in the collection satisfy the given logical expression, and return a boolean value as the result. - - Only when all elements in the collection satisfy the expression true, the `all` expression is true, otherwise it is false. - - If the original collection is empty, return true. - - Supports short-circuiting of logical expressions during expression execution. -- **any** - - Used to detect that at least one element in the collection satisfies the given logical expression, and returns a boolean value as the result. - - When at least one element in the collection satisfies the expression true, the `any` expression is true, otherwise it is false. - - If the original collection is empty, return false. - - Supports short-circuiting of logical expressions during expression execution. -- **map** - - Generate a new **list** by mapping the elements in the original collection. - - The length of the new list is exactly the same as the original collection. -- **filter** - - By logically judging and filtering the elements in the original collection, and returning the filtered sub-collection. - - Only when the element judges the expression to be true, it is added to the sub-collection. - - The type (list, dict and schema) of the new collection is exactly the same as the original collection, and the length range is `[0, len(original-collection)]`. - -**all** and **any** expression sample codes: - -```python -schema Config: - volumes: [{str:}] - services: [{str:}] - - check: - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - }, "invalid cluster ip" - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } -``` - -**map** and **filter** expression sample codes: - -```python -a = map e in [{name = "1", value = 1}, {name = "2", value = 2}] { - {name = e.name, value = int(e.value) ** 2} -} # [{"name": "1", value: 1}, {"name": "2", "value": 4}] - -b = map k, v in {a = "foo", b = "bar"} { v } # ["foo", "bar"] - -c = filter e in [{name = "1", value = 1}, {name = "2", value = 2}] { - int(e.value) > 1 -} # [{"name": "2", "value": 2}] - -d = filter _, v in {a = "foo", b = "bar"} { - v == "foo" -} # {"a": "foo"} -``` - -Please pay attention to distinguish the difference between any expression and any type. When `any` is used in type annotations, it means that the value of the variable is arbitrary, while the any expression means that one of the elements in a set satisfies the condition. diff --git a/versioned_docs/version-0.5.0/reference/lang/spec/kcl-spec.md b/versioned_docs/version-0.5.0/reference/lang/spec/kcl-spec.md deleted file mode 100644 index 63a9d6e7..00000000 --- a/versioned_docs/version-0.5.0/reference/lang/spec/kcl-spec.md +++ /dev/null @@ -1,343 +0,0 @@ ---- -title: "KCL Spec" -linkTitle: "KCL Spec" -type: "docs" -weight: 2 -description: KCL Spec ---- - -## Lexical rules - -### Keywords and reserved words - -The following are the keywords of the KCL: - -```python -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -The following are reserved words for the KCL: - -```python -pass return validate rule flow -def del raise except try -finally while from with yield -global nonlocal struct class final -``` - -### Line comment - -```python -# a comment -``` - -### Operators - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != = -+= -= *= **= /= //= %= -<<= >>= &= ^= -``` - -### Delimiters - -```python -( ) [ ] { } -, : . ; @ -``` - -### Operator precedence - -The following list of operators is ordered from **highest to lowest**: - -| Operator | Description | -| -------------------------------------------------------------------------------- | -------------------------------------------------------- | -| `**` | Exponentiation (highest priority) | -| `+x` `-x` `~x` | Positive, negative, bitwise NOT | -| `*` `/` `%` `//` | Multiplication, division, floor division and remainder | -| `+` `-` | Addition and subtraction | -| `<<` `>>` | Left and right shifts | -| `&` | Bitwise AND | -| `^` | Bitwise XOR | -| \| | Bitwise OR | -| `in`, `not in`, `is`, `is not`, `<`, `<=`, `>`, `>=`, `!=`, `==` | Comparisons, including membership and identity operators | -| `not` | Boolean NOT | -| `and` | Boolean AND | -| `or` | Boolean OR | -| `if – else` | Conditional expression = | -| `=`, `+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `=`, `^=`, `\*\*=`, `//=`, `<<=`, `>>=` | Assign | - -## Grammar - -KCL uses Python's [LarkParser](https://lark-parser.readthedocs.io/en/latest/) tool to describe the grammar, and the specification rules are as follows: - -```bnf -//////////// KCL grammar //////////// -start: (NEWLINE | statement)* - -statement: simple_stmt | compound_stmt -simple_stmt: (assign_stmt | unification_stmt | expr_stmt | assert_stmt | import_stmt | type_alias_stmt) NEWLINE -compound_stmt: if_stmt | schema_stmt | rule_stmt - -//////////// import_stmt //////////// -import_stmt: IMPORT dot_name (AS NAME)? -dot_name: (leading_dots identifier) | identifier -leading_dots: DOT+ - -/////////// assert_stmt //////////// -assert_stmt: ASSERT simple_expr (IF simple_expr)? (COMMA test)? - -//////////// if_stmt //////////// -if_stmt: IF test COLON execution_block (ELIF test COLON execution_block)* (ELSE COLON execution_block)? -execution_block: if_simple_stmt | NEWLINE _INDENT schema_init_stmt+ _DEDENT -if_simple_stmt: (simple_assign_stmt | unification_stmt | expr_stmt | assert_stmt) NEWLINE - -//////////// assign_stmt //////////// -assign_stmt: identifier [COLON type] (ASSIGN identifier)* ASSIGN test - | identifier (COMP_PLUS | COMP_MINUS | COMP_MULTIPLY | COMP_DOUBLE_STAR | COMP_DIVIDE - | COMP_DOUBLE_DIVIDE | COMP_MOD | COMP_AND | COMP_OR | COMP_XOR | COMP_SHIFT_LEFT - | COMP_SHIFT_RIGHT) test - -simple_assign_stmt: identifier ASSIGN test - | identifier (COMP_PLUS | COMP_MINUS | COMP_MULTIPLY | COMP_DOUBLE_STAR | COMP_DIVIDE - | COMP_DOUBLE_DIVIDE | COMP_MOD | COMP_AND | COMP_OR | COMP_XOR | COMP_SHIFT_LEFT - | COMP_SHIFT_RIGHT) test - -//////////// unification_stmt //////////// -unification_stmt: identifier COLON schema_expr - -//////////// schema_stmt //////////// -schema_stmt: [decorators] (SCHEMA|MIXIN|PROTOCOL) NAME [LEFT_BRACKETS [schema_arguments] RIGHT_BRACKETS] [LEFT_PARENTHESES identifier (COMMA identifier)* RIGHT_PARENTHESES] [for_host] COLON NEWLINE [schema_body] -schema_arguments: schema_argument (COMMA schema_argument)* -schema_argument: NAME [COLON type] [ASSIGN test] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt|schema_init_stmt|schema_index_signature)* [check_block] _DEDENT -schema_attribute_stmt: attribute_stmt NEWLINE -attribute_stmt: [decorators] identifier [QUESTION] COLON type [(ASSIGN|COMP_OR) test] -schema_init_stmt: if_simple_stmt | if_stmt -schema_index_signature: LEFT_BRACKETS [NAME COLON] [ELLIPSIS] basic_type RIGHT_BRACKETS COLON type [ASSIGN test] NEWLINE - -//////////// rule_stmt //////////// -rule_stmt: [decorators] RULE NAME [LEFT_BRACKETS [schema_arguments] RIGHT_BRACKETS] [LEFT_PARENTHESES identifier (COMMA identifier)* RIGHT_PARENTHESES] [for_host] COLON NEWLINE [rule_body] -rule_body: _INDENT (string NEWLINE)* check_expr+ _DEDENT - -for_host: FOR identifier - -/////////// decorators //////////// -decorators: (AT decorator_expr NEWLINE)+ -decorator_expr: identifier [call_suffix] - -//////////// type //////////// -type: type_element (OR type_element)* -type_element: schema_type | basic_type | compound_type | literal_type -schema_type: identifier -basic_type: STRING_TYPE | INT_TYPE | FLOAT_TYPE | BOOL_TYPE | ANY_TYPE -compound_type: list_type | dict_type -list_type: LEFT_BRACKETS (type)? RIGHT_BRACKETS -dict_type: LEFT_BRACE (type)? COLON (type)? RIGHT_BRACE -literal_type: string | number | TRUE | FALSE | NONE - -//////////// type alias //////////// -type_alias_stmt: TYPE NAME ASSIGN type - -//////////// check_stmt //////////// -check_block: CHECK COLON NEWLINE _INDENT check_expr+ _DEDENT -check_expr: simple_expr [IF simple_expr] [COMMA primary_expr] NEWLINE - -//////////// mixin_stmt //////////// -mixin_stmt: MIXIN LEFT_BRACKETS [mixins | multiline_mixins] RIGHT_BRACKETS NEWLINE -multiline_mixins: NEWLINE _INDENT mixins NEWLINE _DEDENT -mixins: identifier (COMMA (NEWLINE mixins | identifier))* - - -//////////// expression_stmt //////////// -expr_stmt: testlist_expr -testlist_expr: test (COMMA test)* -test: if_expr | simple_expr -if_expr: simple_expr IF simple_expr ELSE test - -simple_expr: unary_expr | binary_expr | primary_expr - -unary_expr: un_op simple_expr -binary_expr: simple_expr bin_op simple_expr - -bin_op: L_OR | L_AND - | OR | XOR | AND - | SHIFT_LEFT | SHIFT_RIGHT - | PLUS | MINUS | MULTIPLY | DIVIDE | MOD | DOUBLE_DIVIDE - | DOUBLE_STAR - | EQUAL_TO | NOT_EQUAL_TO - | LESS_THAN | GREATER_THAN | LESS_THAN_OR_EQUAL_TO | GREATER_THAN_OR_EQUAL_TO - | IN | L_NOT IN | IS | IS L_NOT | L_NOT | AS -un_op: L_NOT | PLUS | MINUS | NOT - -primary_expr: identifier call_suffix | operand | primary_expr select_suffix | primary_expr call_suffix | primary_expr slice_suffix -operand: identifier | number | string | constant | quant_expr | list_expr | list_comp | config_expr | dict_comp | schema_expr | lambda_expr | LEFT_PARENTHESES test RIGHT_PARENTHESES -select_suffix: [QUESTION] DOT NAME -call_suffix: LEFT_PARENTHESES [arguments [COMMA]] RIGHT_PARENTHESES -slice_suffix: [QUESTION] LEFT_BRACKETS (test | [test] COLON [test] [COLON [test]]) RIGHT_BRACKETS -arguments: argument (COMMA argument)* -argument: test | NAME ASSIGN test | MULTIPLY test | DOUBLE_STAR test - - -//////////// operand //////////// -identifier: NAME (DOT NAME)* -quant_expr: quant_op [ identifier COMMA ] identifier IN quant_target LEFT_BRACE (simple_expr [IF simple_expr] | NEWLINE _INDENT simple_expr [IF simple_expr] NEWLINE _DEDENT)? RIGHT_BRACE -quant_target: string | identifier | list_expr | list_comp | config_expr | dict_comp -quant_op: ALL | ANY | FILTER | MAP -list_expr: LEFT_BRACKETS [list_items | NEWLINE [_INDENT list_items _DEDENT]] RIGHT_BRACKETS -list_items: list_item ((COMMA [NEWLINE] | [NEWLINE]) list_item)* [COMMA] [NEWLINE] -list_item: test | star_expr | if_item -list_comp: LEFT_BRACKETS (list_item comp_clause+ | NEWLINE _INDENT list_item comp_clause+ _DEDENT) RIGHT_BRACKETS -dict_comp: LEFT_BRACE (entry comp_clause+ | NEWLINE _INDENT entry comp_clause+ _DEDENT) RIGHT_BRACE -entry: test (COLON | ASSIGN | COMP_PLUS) test -comp_clause: FOR loop_variables [COMMA] IN simple_expr [NEWLINE] [IF test [NEWLINE]] -if_entry: IF test COLON if_entry_exec_block (ELIF test COLON if_entry_exec_block)* (ELSE COLON if_entry_exec_block)? -if_entry_exec_block: (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry) [NEWLINE] | NEWLINE _INDENT (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry) ((COMMA [NEWLINE] | [NEWLINE]) (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry))* [COMMA] [NEWLINE] _DEDENT -if_item: IF test COLON if_item_exec_block (ELIF test COLON if_item_exec_block)* (ELSE COLON if_item_exec_block)? -if_item_exec_block: list_item [NEWLINE] | NEWLINE _INDENT list_item ((COMMA [NEWLINE] | NEWLINE) list_item)* [COMMA] [NEWLINE] _DEDENT - -star_expr: MULTIPLY test -double_star_expr: DOUBLE_STAR test -loop_variables: primary_expr (COMMA primary_expr)* -schema_expr: identifier (LEFT_PARENTHESES [arguments] RIGHT_PARENTHESES)? config_expr -config_expr: LEFT_BRACE [config_entries | NEWLINE [_INDENT config_entries _DEDENT]] RIGHT_BRACE -config_entries: config_entry ((COMMA [NEWLINE] | [NEWLINE]) config_entry)* [COMMA] [NEWLINE] -config_entry: test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry - -//////////// lambda_expr //////////// -lambda_expr: LAMBDA [schema_arguments] [RIGHT_ARROW type] LEFT_BRACE [expr_stmt | NEWLINE _INDENT schema_init_stmt+ _DEDENT] RIGHT_BRACE - -//////////// misc //////////// -number: DEC_NUMBER [multiplier] | HEX_NUMBER | BIN_NUMBER | OCT_NUMBER | FLOAT_NUMBER -multiplier: SI_N_L | SI_U_L | SI_M_L | SI_K_L | SI_K | SI_M | SI_G | SI_T | SI_P - | SI_K_IEC | SI_M_IEC | SI_G_IEC | SI_T_IEC | SI_P_IEC -string: STRING | LONG_STRING -constant : TRUE | FALSE | NONE | UNDEFINED -// Tokens - -ASSIGN: "=" -COLON: ":" -SEMI_COLON: ";" -COMMA: "," -QUESTION: "?" -ELLIPSIS: "..." -RIGHT_ARROW: "->" -LEFT_PARENTHESES: "(" -RIGHT_PARENTHESES: ")" -LEFT_BRACKETS: "[" -RIGHT_BRACKETS: "]" -LEFT_BRACE: "{" -RIGHT_BRACE: "}" -PLUS: "+" -MINUS: "-" -MULTIPLY: "*" -DIVIDE: "/" -MOD: "%" -DOT: "." -AND: "&" -OR: "|" -XOR: "^" -NOT: "~" -LESS_THAN: "<" -GREATER_THAN: ">" -EQUAL_TO: "==" -NOT_EQUAL_TO: "!=" -GREATER_THAN_OR_EQUAL_TO: ">=" -LESS_THAN_OR_EQUAL_TO: "<=" -DOUBLE_STAR: "**" -DOUBLE_DIVIDE: "//" -SHIFT_LEFT: "<<" -SHIFT_RIGHT: ">>" -AT: "@" - -COMP_PLUS: "+=" -COMP_MINUS: "-=" -COMP_MULTIPLY: "*=" -COMP_DIVIDE: "/=" -COMP_MOD: "%=" -COMP_AND: "&=" -COMP_OR: "|=" -COMP_XOR: "^=" -COMP_DOUBLE_STAR: "**=" -COMP_DOUBLE_DIVIDE: "//=" -COMP_SHIFT_LEFT: "<<=" -COMP_SHIFT_RIGHT: ">>=" - -// Special tokens -IMPORT: "import" -AS: "as" -RULE: "rule" -SCHEMA: "schema" -MIXIN: "mixin" -PROTOCOL: "protocol" -CHECK: "check" -FOR: "for" -ASSERT: "assert" -IF: "if" -ELIF: "elif" -ELSE: "else" -L_OR: "or" -L_AND: "and" -L_NOT: "not" -IN: "in" -IS: "is" -LAMBDA: "lambda" -ALL: "all" -ANY: "any" -FILTER: "filter" -MAP: "map" -TYPE: "type" - -ANY_TYPE: "any" -STRING_TYPE: "str" -INT_TYPE: "int" -FLOAT_TYPE: "float" -BOOL_TYPE: "bool" - -// Constant tokens -TRUE: "True" -FALSE: "False" -NONE: "None" -UNDEFINED: "Undefined" - -// Binary prefix -SI_N_L: "n" -SI_U_L: "u" -SI_M_L: "m" -SI_K_L: "k" -SI_K: "K" -SI_M: "M" -SI_G: "G" -SI_T: "T" -SI_P: "P" -SI_K_IEC: "Ki" -SI_M_IEC: "Mi" -SI_G_IEC: "Gi" -SI_T_IEC: "Ti" -SI_P_IEC: "Pi" -IEC: "i" - -NAME: /\$?[a-zA-Z_]\w*/ -COMMENT: /#[^\n]*/ -NEWLINE: ( /\r?\n[\t ]*/ | COMMENT )+ - -STRING: /r?("(?!"").*?(? [as ] -``` - -The rule to search with the module name is very simple: - -- **Step 1**: Searches the module name from the **standard system modules**, then **plugins modules**. - - See **standard system modules** and **plugins modules** for more details. If matched, the module is imported. Otherwise, continue to **Step 2**. -- **Step 2**. Whether a module name starts with a `.` is checked. If yes, the name is a so-called relative pathname, and we go to **Step 5**. Otherwise, continue to **Step 3**. -- **Step 3**: If the module name does not start with any `.`, then the compiler searches the nearest `root path` directory from this directory to the parent, and find the module according to the name just from the `root path`. If no `root path` is found, find the module according to the name from the folder the `.k` file including this `import` statement exists. - - **root path**: the directory contains a `kcl.mod` file. If matched, the module is imported. Otherwise, continue to **Step 4**. -- **Step 4**: Then the compiler checks if the name is the name of any library module that requires explicit loading. If matched, the library module is imported. Otherwise, continue to **Step 6**. -- **Step 5**. For relative importing, find the module according to the name from the folder the `.k` file including this `import` statement exists. Interpret leading dots using the following rule: -- One dot: Ignore. -- Tow or more dots: Suppose there are `n` leading dots, then the searching starts at `n - 1` levels above this folder. If matched, the module is imported. Otherwise, continue to **Step 6**. -- **Step 6**. Module not found, report an error. - -Do case-sensitive search when the operating system allows. If case-sensitive search is not allowed, search directories before regular files. - -In KCL, the `from <> import <>` is unsupported, and relative import is performed with the `import <>` syntax. - -### Uniqueness of Module - -Each module has a unique location path in its scope, so that a module or package could be located with a unique location path, such as `a.b.c`. - -Searching by location path should be supported by the kcl compiler, which needs to provide corresponding searching features through the command line and api form. - -## Standard System Packages - -KCL supports a few standard system modules. The following is the full list of these standard system modules: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PackageMember
datetimetoday
now
ticks
date
mathceil
exp
expm1
factorial
floor
gcd
isfinite
isinf
isnan
log
log1p
log2
log10
modf
pow
sqrt
regexreplace
match
compile
findall
search
split
unitsn
u
m
k
K
M
G
T
P
Ki
Mi
Gi
Ti
Pi
to_n
to_u
to_m
to_K
to_M
to_G
to_T
to_P
to_Ki
to_Mi
to_Gi
to_Ti
to_Pi
jsonencode
decode
dump_to_file
yamlencode
decode
dump_to_file
netsplit_host_port
join_host_port
fqdn
parse_IP
to_IP4
to_IP16
IP_string
is_IPv4
is_IP
is_loopback_IP
is_multicast_IP
is_interface_local_multicast_IP
is_link_local_multicast_IP
is_link_local_unicast_IP
is_global_unicast_IP
is_unspecified_IP
base64encode
decode
cryptomd5
sha1
sha224
sha256
sha384
sha512
- -- datetime - - ticks() -> float - Return the current time in seconds since the Epoch. Fractions of a second may be present if the system clock provides them. - - date() -> str - return the `%Y-%m-%d %H:%M:%S` format date. - - now() -> str - return the local time. e.g. `'Sat Jun 06 16:26:11 1998'` - - today() -> str - return the `%Y-%m-%d %H:%M:%S.%{ticks}` format date. -- math - - ceil(x) -> int - Return the ceiling of x as an Integral. This is the smallest integer >= x. - - factorial(x) -> int - Return x!. Raise a error if x is negative or non-integral. - - floor(x) -> int - Return the floor of x as an Integral. This is the largest integer <= x. - - gcd(a: int, b: int) -> int - Return the greatest common divisor of x and y - - isfinite(x) -> bool - Return True if x is neither an infinity nor a NaN, and False otherwise. - - isinf(x) -> bool - Return True if x is a positive or negative infinity, and False otherwise. - - isnan(x) -> bool - Return True if x is a NaN (not a number), and False otherwise. - - modf(x) -> Listfloat, float] - Return the fractional and integer parts of x. Both results carry the sign of x and are floats. - - exp(x) -> float - Return e raised to the power of x. - - expm1(x) -> float - Return exp(x)-1. This function avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small x. - - log(x, base=2.71828182845904523536028747135266250) -> float - Return the logarithm of x to the base e. - - log1p(x) -> float - Return the natural logarithm of 1+x (base e). The result is computed in a way which is accurate for x near zero. - - log2(x) -> float - Return the base 2 logarithm of x. - - log10(x) -> float - Return the base 10 logarithm of x. - - pow(x, y) -> float - Return x\*\*y (x to the power of y). - - sqrt(x) -> float - Return the square root of x. -- regex - - replace(string: str, pattern: str, replace: str, count=0) -> str - Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement. - - match(string: str, pattern: str) -> bool - Try to apply the pattern at the start of the string, returning a bool value True if any match was found, or False if no match was found. - - compile(pattern: str) -> bool - Compile a regular expression pattern, returning a bool value denoting whether the pattern is valid. - - findall(string: str, pattern: str) -> List[str] - Return a list of all non-overlapping matches in the string. - - search(string: str, pattern: str) -> bool - Scan through string looking for a match to the pattern, returning a bool value True if any match was found, or False if no match was found. - - split(string: str, pattern: str, maxsplit=0) -> List[str] - Scan through string looking for a match to the pattern, returning a Match object, or None if no match was found. -- units - - Unit constants - - Fixed point: `n`, `u`, `m`, `k`, `K`, `G`, `T` and `P`. - - Power of 2: `Ki`, `Mi`, `Gi`, `Ti` and `Pi`. - - Functions - - to_n(num: int) -> str - Int literal to string with `n` suffix - - to_u(num: int) -> str - Int literal to string with `u` suffix - - to_m(num: int) -> str - Int literal to string with `m` suffix - - to_K(num: int) -> str - Int literal to string with `K` suffix - - to_M(num: int) -> str - Int literal to string with `M` suffix - - to_G(num: int) -> str - Int literal to string with `G` suffix - - to_T(num: int) -> str - Int literal to string with `T` suffix - - to_P(num: int) -> str - Int literal to string with `P` suffix - - to_Ki(num: int) -> str - Int literal to string with `Ki` suffix - - to_Mi(num: int) -> str - Int literal to string with `Mi` suffix - - to_Gi(num: int) -> str - Int literal to string with `Gi` suffix - - to_Ti(num: int) -> str - Int literal to string with `Ti` suffix - - to_Pi(num: int) -> str - Int literal to string with `Pi` suffix -- json - - encode(data: any, sort_keys: bool = False, indent: int = None, ignore_private: bool = False, ignore_none: bool = False) -> str - Serialize a KCL object `data` to a JSON formatted str. - - decode(value: str) -> any - Deserialize `value` (a string instance containing a JSON document) to a KCL object. - - dump_to_file(data: any, filename: str, ignore_private: bool = False, ignore_none: bool = False) -> None - Serialize a KCL object `data` to a JSON formatted str and write it into the file `filename`. -- yaml - - encode(data: any, sort_keys: bool = False, ignore_private: bool = False, ignore_none: bool = False) -> str - Serialize a KCL object `data` to a YAML formatted str. - - decode(value: str) -> any - Deserialize `value` (a string instance containing a YAML document) to a KCL object. - - dump_to_file(data: any, filename: str, ignore_private: bool = False, ignore_none: bool = False) -> None - Serialize a KCL object `data` to a YAML formatted str and write it into the file `filename`. -- net - - split_host_port(ip_end_point: str) -> List[str] - Split the 'host' and 'port' from the ip end point. - - join_host_port(host, port) -> str - Merge the 'host' and 'port'. - - fqdn(name: str = '') -> str - Return Fully Qualified Domain Name (FQDN). - - parse_IP(ip) -> str - Parse 'ip' to a real IP address - - to_IP4(ip) -> str - Get the IP4 form of 'ip'. - - to_IP16(ip) -> int - Get the IP16 form of 'ip'. - - IP_string(ip: str | int) -> str - Get the IP string. - - is_IPv4(ip: str) -> bool - Whether 'ip' is a IPv4 one. - - is_IP(ip: str) -> bool - Whether ip is a valid ip address. - - is_loopback_IP(ip: str) -> bool - Whether 'ip' is a loopback one. - - is_multicast_IP(ip: str) -> bool - Whether 'ip' is a multicast one. - - is_interface_local_multicast_IP(ip: str) -> bool - Whether 'ip' is a interface, local and multicast one. - - is_link_local_multicast_IP(ip: str) -> bool - Whether 'ip' is a link local and multicast one. - - is_link_local_unicast_IP(ip: str) -> bool - Whether 'ip' is a link local and unicast one. - - is_global_unicast_IP(ip: str) -> bool - Whether 'ip' is a global and unicast one. - - is_unspecified_IP(ip: str) -> bool - Whether 'ip' is a unspecified one. -- base64 - - encode(value: str, encoding: str = "utf-8") -> str - Encode the string `value` using the codec registered for encoding. - - decode(value: str, encoding: str = "utf-8") -> str - Decode the string `value` using the codec registered for encoding. -- crypto - - md5(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `MD5` and the codec registered for encoding. - - sha1(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA1` and the codec registered for encoding. - - sha224(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA224` and the codec registered for encoding. - - sha256(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA256` and the codec registered for encoding. - - sha384(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA384` and the codec registered for encoding. - - sha512(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA512` and the codec registered for encoding. -- manifests - - `yaml_stream(values: [any], opts: {str:} = {sort_keys = False, ignore_private = True, ignore_none = False, sep = "---"}`. This function is used to serialize the KCL object list into YAML output with the `---` separator - -### The Built-in System Package - -KCL provides a list of built-in system modules, which are loaded automatically and can be directly used without providing any module name. For example, `print` is a widely used built-in module. - -The following is the full list of these built-in system modules: - -- print() - - The print function. -- multiplyof(a, b) - - Check if the modular result of a and b is 0 -- isunique(inval) - - Check if a list has duplicated elements -- len(inval) - Return the length of a value -- abs(x) - Return the absolute value of the argument. -- all(iterable) - Return True if bool(x) is True for all values x in the iterable. If the iterable is empty, return True. -- any(iterable) - Return True if bool(x) is True for any x in the iterable. If the iterable is empty, return False. -- bin(number) - Return the binary representation of an integer. -- hex(number) - Return the hexadecimal representation of an integer. -- oct(number) - Return the octal representation of an integer. -- ord(c) -> int - Return the Unicode code point for a one-character string. -- sorted(iterable) - Return a new list containing all items from the iterable in ascending order. A custom key function can be supplied to customize the sort order, and the reverse flag can be set to request the result in descending order. -- range(start, end, step=1) - Return the range of a value with start, end and step parameter. -- min(iterable) - With a single iterable argument, return its smallest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the smallest argument. -- max(iterable) - With a single iterable argument, return its biggest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the largest argument. -- sum(iterable, start) - Return the sum of a 'start' value (default: 0) plus an iterable of numbers. When the iterable is empty, return the start value. This function is intended specifically for use with numeric values and may reject non-numeric types. -- pow(x, y, z) - Equivalent to `x**y` (with two arguments) or `x**y % z` (with three arguments). Some types, such as ints, are able to use a more efficient algorithm when invoked using the three argument form. -- round(number, ndigits) - Round a number to a given precision in decimal digits. The return value is an integer if ndigits is omitted or None. Otherwise the return value has the same type as the number. ndigits may be negative. -- typeof(x: any, \*, full_name: bool = False) -> str - Return the type of the value 'x' at runtime. When the 'full_name' is 'True', return the full package type name such as `pkg.schema`. - -### Plugin Modules - -KCL compiler needs to provide the ability to dynamically expand and load plugin modules without modifying the compiler itself. KCL compiler needs to support flexible pluggable module extension mechanism, so that KCL users can use more abundant built-in function capabilities to simplify writing. - -KCL compiler needs to ensure the stability and safety of the expansion mechanism, without affecting the core of the compiler. - -Searching extended plugin module is performed after the standard system module. The standard system module has a higher priority in naming. If it exists a standard or built-in system module with the same name, the extended plugin module will be ignored. - -Importing and using the extended plugin module should be consistent with the standard or built-in system module. - -### Replacing Standard System Packages - -Replacing standard system modules is not allowed. - -## Examples - -We show more module features through an example. - -Suppose we have the following directories and files: - -``` - . - ├── mod1.k - ├── mod2.k - ├── pkg1 - │   ├── def1.k - │   ├── def2.k - │   └── def3init.k - └── pkg2 - ├── file2.k - └── subpkg3 - └── file3.k -``` - -From the structure we can see that `pkg1` and `pkg2` are two packages, `subpkg3` is a subpackage of `pkg2`, and `mod1.k` and `mod2.k` are regular modules. - -### Importing a Standard System Package - -The following statement can import the standard system module `math` - -```python -import math -``` - -This is the only way to import a standard system module. After importing a standard system module, functions, variables and schemas defined in it can be used. For example, the following statement uses the `log10` function -defined in `math` - -```python -a = math.log10(100) # a is 2 after computation. -``` - -### Importing a Regular Module - -In `mod1.k`, we can import `mod2` using one of the following syntaxes. - -```python -import mod2 -``` - -```python -import .mod2 -``` - -The difference is that in the first syntax, the KCL compiler will first try to check if `mod2` matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where `mod1.k` resists in, like what the second statement does. - -Suppose in `mod2.k` there is a definition of a variable:: - -```python -a = 100 -``` - -After importing `mod2`, we can access `a` in `mod1.k` using the following syntax - -```python -b = mod2.a -``` - -### Importing a Package - -In `mod1.k`, we can import `pkg1` using one of the following syntaxes. - -```python -import pkg1 -``` - -```python -import .pkg1 -``` - -The difference is that in the first syntax, the KCL compiler will first try to check if `pkg1` matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where `mod1.k` resists in, like what the second statement does. - -We can use similar statements to import `pkg2`. Note that importing `pkg2` will not import `subpkg3`. - -The name of the package is the name of the imported module. - -Suppose in `file2.k` that is inside `pkg2` there is a definition to variable `foo` - -```python -foo = 100 -``` - -This variable can be used in `mod1.k` after importing `pkg2` like the following - -```python -bar = pkg2.foo -``` - -### Importing a Subpackage - -To import `subpkg3` from `mod1.k`, one of the following statements can be used. - -```python -import pkg2.subpkg3 -``` - -```python -import .pkg2.subpkg3 -``` - -The behaviors of these statements are identical. - -The name of the subpackage is the name of the imported module. - -Suppose in `file3.k` that is inside `subpkg3` there is a definition to variable `foo` - -```python -foo = 100 -``` - -This variable can be used in `mod1.k` after importing `subpkg3` like the following - -```python -bar = subpkg3.foo -``` - -### Relative Importing - -Relative importing is useful when there is code trying to import modules that does not exist recursively inside the current directory. - -For example, the following statements, if written in `file3.k`, can be used to import `pkg2`, `pkg1` and `mod2` respectively. - -```python -import ...pkg2 # Go two levels up then import pkg2 -import ...pkg1 # Go two levels up then import pkg1 -import ...mod2 # Go two levels up then import mod2 -``` - -### Importing from a Root Path - -Suppose we have a `kcl.mod` file in the directory to mark it as a root path, then we have the following files: - -``` - . - |── kcl.mod - ├── mod1.k - ├── mod2.k - ├── pkg1 - │   ├── def1.k - │   ├── def2.k - │   └── def3init.k - └── pkg2 - ├── file2.k - └── subpkg3 - └── file3.k -``` - -In `pkg1` `def1.k`, we can import `pkg2.subpkg3` `file3` using the following syntaxes. - -```python -import pkg2.subpkg3.file3 -``` - -Importing from the root path is very convenient when the code is trying to import modules from a directory needs to look up multiple directories above this directory. At also, it is helpful to organize a large number of files in a root directory. - -### Importing a Module Inside a Package - -Note that `subpkg3` is only implemented with one file `file3.k`. The file can be regarded as a regular module and imported directly. - -In `mod1.k`, the importing statement would be:: - -```python -import pkg2.subpkg3.file3 -``` - -Different from importing `subpkg3`, now the name of the module is `file3`. We can access the variable `foo` defined in this module with the following -statement - -```python -bar = file3.foo -``` - -### Precedence of Importing - -When an import statement specifies a package to import, the virtual machine first looks for a directory named according to the import statement in the file system. - -If such a directory is not found, the virtual machine looks for a single file module. - -For example, when the statement `import a.b.c` appears, the virtual machine first looks for the directory `a/b/c` from the directory of the current file. If `a/b/c` is not found, the virtual machine looks for a file named `a/b/c.k`. If the file is also absent, an error is reported. - -### Package Implemented with Multiple Files - -Package `pkg1` is implemented with multiple KCL files. - -Multiple files can be used to define variables, schemas and functions, and they can access names defined in other files of this package. - -For example, suppose `def1.k` defines a variable `foo`, `def2.k` defines `bar`, and `def3init.k` defines a variable `baz`, when `pkg1` is imported by `mod1.k`, all these variable can be used - -```python -import pkg1 -a = pkg1.foo + pkg1.bar + pkg1.baz -``` - -Inside a module, names defined in a file can be accessed in another file without further importing. For example, suppose `bar` in `def2.k` would invoke `foo` defined in `def1.k`, it can directly use `foo` like the following - -```python -bar = foo + 1 -``` diff --git a/versioned_docs/version-0.5.0/reference/lang/spec/schema.md b/versioned_docs/version-0.5.0/reference/lang/spec/schema.md deleted file mode 100644 index c3d09f65..00000000 --- a/versioned_docs/version-0.5.0/reference/lang/spec/schema.md +++ /dev/null @@ -1,916 +0,0 @@ ---- -title: "Schema" -linkTitle: "Schema" -type: "docs" -weight: 2 -description: Schema ---- - -## Syntax - -### Schema Definition - -A schema is a language element to define a type of configuration data. - -To define a schema, the syntax is the following: - -```bnf -schema_stmt: [decorators] "schema" ["relaxed"] identifier ["[" [arguments] "]"] ["(" operand_name ")"] ":" NEWLINE [schema_body] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt | schema_index_signature | statement)* [check_block] _DEDENT -``` - -Attributes could be defined in a schema, the syntax is the following: - -```bnf -schema_attribute_stmt: [decorators] identifier ["?"] ":" type [(ASSIGN | augassign) test] NEWLINE -``` - -Index signature could be defined in a schema, the syntax is the following: - -```bnf -schema_index_signature: LEFT_BRACKETS [NAME COLON] [ELLIPSIS] basic_type RIGHT_BRACKETS COLON type [ASSIGN test] NEWLINE -``` - -Once defined, an attribute must have a valid type: - -```bnf -type: type_element ("|" type_element)* -type_element: schema_type | basic_type | list_type | dict_type -schema_type: operand_name -basic_type: "str" | "int" | "float" | "bool" -list_type: "[" (type)? "]" -dict_type: "{" (type)? COLON (type)? "}" -``` - -The followings are some basic examples: - -```python -# A person has a first name, a last name and an age. -schema person: - firstName: str - lastName: str - # fullName is generated by firstName and lastName - fullName: str = firstName + ' ' + lastName - # The default value of age is 0 - age: int = 0 - -# An employee IS a person, and has some additional information. -schema employee(person): - bankCard: int - nationality: str - -# A company has a name and many employees. -schema company: - name: str - employees: [employee] -``` - -More complex schema definitions will be elaborated after other concepts are -introduced. - -#### Optional Attribute - -Each attribute **must** be assigned with a not-None value as a schema instance unless it is modified by a question mark as an optional attribute. - -Examples: - -```bnf -schema employee(person): - bankCard?: int # bankCard is an optional attribute - nationality?: str # # nationality is an optional attribute -``` - -When there is an inheritance relationship: - -- If the attribute is optional in the base schema, it could be optional or required in the sub-schema. -- If the attribute is required in the base schema, it must be required in the sub-schema. - -### Configuration Definition - -A configuration is structured data stored in a dict-like structure. In KCL, we have introduced -the configuration definition syntax as a variant of dict definition syntax. - -```bnf -schema_expr: operand_name ("(" [arguments] ")")? dict_expr -``` - -As can be seen, apart from having an identifier as schema type, a configuration definition -is just an ordinary dict definition, and each key in the dict matches an attribute in the schema. - -To simplify configuration, schema attribute key is much easier to define as: - -- schema attribute key can be unquoted. When the attribute key has the same name as a variable, it must be quoted as a normal dict to avoid naming conflict. -- schema attribute key can be defined nested through `select expression`, such as `a.b.c`. - -The comma at the end of each line can be omitted. - -For example, we can define a `person` named `John Doe` using the following statement: - -```python -johnDoe = person { - # In the result, 'lastName' appears later than 'firstName', according the schema - lastName = 'Doe' - firstName = 'John' - # If we don't specify the 'age', the default value 0 is used. - # 'age': 20 -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' - 'age': 0 -} -``` - -Compared to the ordinary dict definition, a configuration definition has the following features: - -- Each attribute defined in the schema (or one of the schemas) could be configured, and config data has higher priority than the default value. -- When an attribute defined in the schema (or one of the schemas) is not configured in the configuration definition statement, and it has a default value, the default value is used. -- Unless the schema (or one of the schemas) is a **relaxed schema**, no more attributes can be defined. -- The quotation marks of dict key can be omitted. -- The comma at the end of each line can be omitted. -- Cases of **inheritance** will be discussed separately. - -For attributes of list, dict and schema types, the config data is added by **union** instead of reassignment. For instance: - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name = { - firstNam = "John" - lastName = "default" - } - -JohnDoe = Person { - name.lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' -} -``` - -#### Attribute Identify - -Each key identifier in the configuration expr identifies an element or a range of elements in a schema. The key identifier may consist of multiple attribute identifiers, and each attribute may be a basic type value, a list, a dict or schema. For example, the key identifier 'a.b.c' identifies the element 'c' in the 'A' schema: - -```python - -schema C: - c: int - -schema B: - b: C - -schema A: - a: B - -A { - a.b.c: 5 -} -``` - -To make the key identifier usage rules as clear as possible, we define the way of identifying with complex data types as follows. - -##### List - -Suppose we have a list attribute a. - -Identify an element in a: - -```python -a[0] # the first element -a[3] # the 4th element -a[-1] # the last element -a[-2] # the penultimate element -``` - -Identify a range of elements in the list: - -```python -a[2:5] # a slice of the third, 4th, and 5th elements -a[:5] # a slice of the first to 5th elements -``` - -#### Attribute Operator - -Once we identified the element(s), we can declare operation on it. It follows the pattern of `identifier op E`. - -#### Union - -Pattern: `identifier : E` - -The value of the expression `E` will be unioned into the element value. - -Examples: - -```python -a = A { - # union {d:4} into the element b.c, suppose c is a schema with an int type attribute d. - b.c : { - d : 4 - } -} -``` - -See 'union' in `expressions` spec for more details. - -#### Override - -Pattern: `identifier = E` - -The value of the expression `E` will override the element value. - -Examples: - -```python -a = A { - # override {c:4} to the element b, suppose b is a schema with an int type attribute c. - b = { - c: 4 - } -} -``` - -Unlike union, the override operation will reassign the element with a brand new value. -For basic type value, `union` and `override` have equivalent effects. - -Note: - -- Especially, we can "delete" its content by overriding the element to `Undefined`, such as `{ a = Undefined }`. - -#### Insert - -Pattern: `identifier += E` -Insert only works for list type `identifier`. - -List `E` will be inserted just after the specified index of the list `identifier`, and the following elements after the index will be automatically shifted. - -Examples: - -```python -a = A { - # insert {c:4} to the end position(just after index=1), suppose b is a list of schema with an int type attribute c. - b += { - c: 4 - } -} -``` - -If no index is specified, the last index will be used. - -The type of 'E' must be compatible with the type of list. See `types` for more details. - -#### Index Signature - -Index signatures can be defined in the KCL schema, and it means that the key-value constraints of the index signature can be used to construct a dict with the schema type, or additional checks can be added to the relaxed schema attributes to enhance the KCL type and semantic checks. - -- Use the form `[{attr_alias}: {key_type}]: {value_type}` to define an index signature in the schema, and `{attr_alias}` can be omitted. - -```python -schema Map: - """ - Map is a relaxed schema with a key of str type and a value of str type - """ - [str]: str # `{attr_alias}` can be omitted. - -data = Map { - key1 = "value1" - key2 = "value2" -} -``` - -- Mandatory all attributes of the schema key and value types - -```python -schema Person: - name: str - age: int # error, conflicts with the index signature definition `[str]: str` - [str]: str # The values of all attributes of the schema can only be strings -``` - -- Mandatory all attribute key and value types are defined in the schema, which is equivalent to restricting all attribute types except the relaxed attributes. - -```python -schema Person: - name: str - age: int - [...str]: str # Except for the `name` and `age` attributes, the key type of all other attributes of the schema must be `str`, and the value type must also be `str`. -``` - -- Define the index signature attribute alias and use it with the check block. - -```python -schema Data: - [dataName: str]: str - check: - dataName in ["Alice", "Bob", "John"] - -data = Data { - Alice = "10" - Bob = "12" - Jonn = "8" # error Jonn not in ["Alice", "Bob", "John"] -} -``` - -```python -import regex - -schema DataMap: - [attr: str]: str - check: - regex.match(attr, r'^[-._a-zA-Z0-9]+$') - -data = DataMap { - key1 = "value1" - "foo.bar" = "value2" # check error -} -``` - -### Schema Context - -The schema definition space can be regarded as a separate function context. - -Init statement could be defined inside the schema, the syntax is the following: - -```bnf -statement: small_stmt NEWLINE | if_stmt -``` - -The following is an example: - -```python -schema Person: - firstName: str = "John" - lastName: str - # fullName is generated by firstName and lastName in a separate init statement - fullName: str = firstName + ' ' + lastName - -JohnDoe = Person { - lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' -} -``` - -If statement, expr statement and assert statement are supported as a schema init -statement. See more in statement spec. - -- The attributes must be defined first, including inherited ones, and then used in the init statement. -- Statements in the schema context will be executed sequentially. -- The value of attributes referenced in the init statement will be evaluated at runtime. - See the **Configuration Definition** section for the assignment rules of non-referenced attributes. For example, `"fullName"` in Person is generated by `"firstName"` and `"lastName"` evaluated at runtime, in which firstName is 'John', and lastName is "Doe". - -The immutability of attributes in the schema context follows the same rules as the immutability of global variables: - -```python -schema Person: - age: int = 1 # Immutable attribute - _name: str = "Alice" # Mutable attribute - - age = 10 # Error - _name = "Bob" # Ok -``` - -#### Arguments - -Schema context can also have arguments. The following is an example. - -```python -schema Person[separator]: - firstName: str = "John" - lastName: str - fullName: str = firstName + separator + lastName - -JohnDoe = Person('_') { - lastName = "Doe" -} -``` - -The example is similar to the previous one, except that the separator character used in -the `"fullName"` member is passed in as an argument. The way to perform a schema generation -when the schema has an initialization function with arguments is demonstrated in the code. - -### Check Block - -Optionally, a check block can be added to a schema definition to allow -additional checking to be performed. - -The syntax is the following: - -```bnf -check_block: "check" ":" NEWLINE _INDENT check_expr+ _DEDENT -check_expr: test (IF test)? [":" primary_expr] NEWLINE -``` - -In terms of grammatical definition, a check block consists of a list of conditional expressions. The following is an example: - -```python -schema employee(person): - bankCard: int - gender: str - - check: - len(str(bankCard)) == 16 - gender in ['male', 'female'], "The gender {} is unsupported".format(gender) -``` - -The ability of KCL check expressions covers the abilities that can be defined by OpenAPI spec and is aligned with the ability of logical expressions. We consider further aligning the syntax with `CEL` spec. -Whether to support `lambda expressions` is still under discussion. - -Summary: - -- A check block consists of one or more logical **expressions**. -- When defining a configuration, the expressions in the check block are evaluated - in any order. If any of the expression is `False`, an error is reported. -- A custom error message can be provided after an expression. - -### Specifying Types - -Optionally, the type of any member of a schema can be specified. As previous examples have shown. - -A member can be of a basic type, such as a string (`str`), a floating-point number (`float`), a fixed-point number (`int`) or a boolean number (`bool`). - -A member can also be of a dictionary generated from another schema. In such a case, the name of the other schema is used as the type name. - -A member can also be a list or an ordinary dict: - -- A list with unspecified type of elements is `[]`. -- A list with elements of type `t` is `[t]`. Here `t` is another type. -- A dict with keys of type `kt` and values of type `vt` is `{kt:vt}`. -- `kt`, `vt` or both of them can be missing, like a list with unspecified type of elements. - -The followings are some more examples: - -- A list of lists of strings: `[[str]]`. -- A dict of keys with the type string and unspecified value types: `{str:}`. - -A member can be a **union type** defined by `|`, such as `a | b`, which means the type of the member could be a or b. - -A union type can include types of `int`, `str`, `float`, `bool`, `list` and `dict` and support type nesting e.g. `{str:str|int}` and `[[int|str]|str|float]`, etc. - -Examples: - -```python -schema x: - p: int | str # p could be defined as a int or string -``` - -### Immutability - -KCL pursues strict immutability of schema attributes. It's generally followed the rules: - -- For the attributes of the basic type, such as string, int and float, it's allowed to be reassigned - through the init statement in **schema context** or by the **configuration definition**. -- For the attributes of list, dict and schema type, it's allowed to be reassigned only by the init statement in **schema context**. The content of it is allowed to be operated in **schema context** or by the **configuration definition**. -- Any other attempt to reassign or modify schema attribute will report an error. - -#### Assign by Value - -When using a schema variable to assign the value to another variable, we can only get a deep copy of its value, not a pointer or reference. That is, modifying the assigned value will not change the assigned schema variable. - -```python -schema Person: - name: str - -person = { - name = "Alice" -} -personCopy = person # 'personCopy' is a deep copy of 'person' and modifying 'personCopy' will not affect 'person' -``` - -### Union Operator - -For list, dict and schema, we can union delta to existing data. For example: - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name = { - firstName = "John" - } - - # union a schema and a dict - name: Name { - lastName = "Doe" - } - -person = Person {} -``` - -The result is a **dict**: - -```python -{ - 'person': { - 'name': { - 'firstName': 'Jhon', - 'lastName': 'Doe' - } - } -} -``` - -### Other Operators - -Except for `assignment` and `union assignment`, it's not support other operators on schema type data. -Report an error if trying to use other operators on schema type data. - -### Deprecated - -The schema attribute can be marked as deprecated once it's considered invalid. - -```python -schema Person: - @deprecated(version="1.1.0", reason="use fullName instead", strict=True) - name: str - ... # Omitted contents - -person = Person { - # report an error on configing a deprecated attribute - name = "name" -} -``` - -- Deprecated attributes cannot be configured under any circumstances. Report an error or warning once the attribute is assigned. -- Define the expired version of the attribute through **version**, and define the reason for the attribute expired through **reason**. -- When strict is true, the attribute assignment will cause an error, otherwise it will report a warning and ignore the attribute assignment. - -### Composition - -The composition is a common way to define complex structures. KCL provides simplified means for the configuration definition of combined structures. - -Assuming we have the following schemas, which is defined by a combination of multiple schemas. - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name - age: int - -schema Group: - name: str - persons: [Person] -``` - -To config a group: - -```python -group = Group { - name = "group" - persons = [{ - name = { - firstName = "John" - lastName = "Doe" - } - age = 24 - }] -} -``` - -- Top-level schema name is required to config a schema. -- The schema of the attributes in the schema can be omitted. - -Multi-level nested schemas will make the configuration verbose. KCL supports defining attributes in the schema through `selector expression`. The selector form is **x.y.z**, see the following example: - -```python -group = Group { - name = "group" - persons = [{ - name.firstName = "John" - name.lastName = "Doe" - age = 24 - }] -} -``` - -- Selector can be used to represent attribute in a schema - -### Inheritance - -Inheritance is an effective means to define a hierarchical structure definition, and KCL supports limited **single inheritance** of the schema. - -```python -schema Person: - firstName: str - lastName: str - -# schema Scholar inherits schema Person -schema Scholar(Person): - fullName: str = firstName + '_' + lastName - subject: str - -JohnDoe = Scholar { - firstName = "John", - lastName = "Doe", - subject = "CS" -} -``` - -The result is a **dict**: - -```python -{ - 'JohnDoe': { - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' - 'subject': 'CS' - } -} -``` - -Each schema can be treated as a separated function context. Statements, including attribute statements and init statements, in the context of schemas will be evaluated from base schema to subschema according to the inheritance order. Each schema context is evaluated only once sequentially. The same goes for expressions in the check block. In the example, firstName and lastName are configured in the context of Person schema, and fullName is formed by splicing firstName and lastName in the context of Scholar schema. - -The default value can be modified in each schema. Value defined in **Configuration Definition** has a higher priority than the default value. Attributes with default values in any schema context ​​will eventually be unioned by configuration data. References to attributes in the schema context statements will use the value with unioned configuration data on evaluating at runtime. For example: - -```python -schema a: - x = 1 - y = x * 2 - -schema b(a): - x = 2 - -v = a { - x = 3 -} - -``` - -The result is a **dict**: - -```python -{ - 'v': { - 'x': 3 - 'y': 6 - } -} -``` - -Notes: - -- Report an error if inheriting more than one base schema. -- The type of the base schema attribute cannot be modified in the subschema. -- Report an error if inheriting a **mixin**. -- Report an error when a circular dependency occurs. - -Limitations: - -Since inheritance will derive some complex demands, we are cautious about these complex demands. There are still some restrictions on inheritance, and it's still under discussion. - -- KCL provides limited and deterministic polymorphism support, more complex and flexible polymorphism support, such as **self**, **super** keywords, are temporarily not included in the schema definition. -- Currently, KCL only supports the polymorphism of the inherited attributes of the schema, and does not support the polymorphism of the expressions in the check block. -- For the case of multiple levels of schema inheritance, the schema arguments can only be passed to the last level of sub-schema. - -### Mixin - -In addition to **composition** and **inheritance**, KCL supports declarative reuse of schema code through the **mixin** mechanism. To use a mixin, we only need to declare the **mixin** in the schema definition. - -The **mixin** syntax is the following: - -```bnf -//////////// mixin_stmt //////////// -mixin_stmt: "mixin" "[" [mixins | multiline_mixins] "]" "\n" -multiline_mixins: "\n" _INDENT mixins "\n" _DEDENT -mixins: operand_name ("," ("\n" mixins | operand_name))* -``` - -Here is a simple example: - -```python -schema Person: - mixin [FullNameMixin] - firstName: str = "default" - lastName: str - -schema FullNameMixin: - fullName: str = "{} {}".format(firstName, lastName) - -JohnDoe = Person { - firstName = "John" - lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'JohnDoe': { - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' - } -} -``` - -Multiple mixins can be added to a single schema, and mixins context will be evaluated after the host schema context at runtime. In the inheritance scenario, the mixin context can be regarded as a part of the host schema context, and the overall evaluation of schema context order is not affected. - -Notes: - -- The name of **mixin** schema must end with 'Mixin', otherwise an error will be reported. -- The attributes referenced in the **mixin** must be defined in the **mixin** itself or host schema, otherwise an error will be reported. - -### Protocol - -In addition to schema, an additional type definition method `protocol` is provided in KCL, and its properties are as follows: - -- In a protocol, only attributes and their types can be defined, complex logic and check expressions cannot be written, and mixins cannot be used. -- A protocol can only inherit or refer to other protocols, but cannot inherit or refer to other schemas. - -We can use **protocol** to add an optional host type to the dynamically inserted **mixin**. - -The **mixin** can define its host type through the `for` keyword, and internally it will query the type corresponding to the attribute from the host type. - -```python -protocol DataProtocol: # A mixin host type - data: str - -mixin DataMixin for DataProtocol: # Using the `for` keyword to define a mixin host type - x: int = data # The type of `data` is `str`, which is from `data` of `DataProtocol` -``` - -In `DataMixin`, the `data` attribute is obtained according to the `DataProtocol` host type as `str` type, and then a type error will occur when the value is assigned to `x` of type `int`: - -```python -protocol DataProtocol: - data: str - -mixin DataMixin for DataProtocol: - x: int = data # Error: expect int, got str - x: str = data # Error: can't change schema field type of 'x' from int to str -``` - -Please note that the host type **protocol** can only be used for **mixin** definitions (the suffix name is `Mixin`), otherwise an error will be reported. - -```python -protocol DataProtocol: - data: str - -schema Data for DataProtocol: # Error: only schema mixin can inherit from protocol - x: str = data -``` - -### Schema Context Evaluation - -The schema definition is composed of attribute statements, configuration data, init statements, mixins, and checks. In a separate schema context, the evaluation top-down order is as follows: - -``` -|------------------------------------------| -| attribute defaulting | -|------------------------------------------| -| configuration union | -|------------------------------------------| -| attribute templating | -|------------------------------------------| -| statements in declaration order | -|------------------------------------------| -| mixins in declaration order | -|------------------------------------------| -| check expressions in any order | -|------------------------------------------| -``` - -In the case of schema inheritance, each schema context is evaluated from the base schema in the order of inheritance, and each context is evaluated only once. -Suppose there are schemas a, b, and c, where c inherits b and b inherits a. Schema contexts will be evaluated in top-down order as: - -``` -|-----------------| -| schema a | -|-----------------| -| schema b | -|-----------------| -| schema c | -|-----------------| -``` - -### Members - -Built-in function and members of schema - -- instances() - Return the list of existing instances of a schema. - -### Irrelevant Order Calculation - -The irrelevant order calculation in the schema indicates the reference relationship between the internal attributes of the schema. For example, when we declare an expression of the form `a = b + 1`, the calculation of the value of `a` depends on the calculation of the value of `b`. When the compiler calculate the value of `a` and the value of `a` depends on the value of `b`, the compiler will choose to first calculate the value of `b`, and then calculate the value of a according to the expression `a = b + 1`, which is slightly different from the calculation method of traditional procedural language the difference. - -Since the calculation of values in the schema is based on dependencies, just like a directed acyclic graph traverses each node in the graph according to the order of topological sorting, the order of declaration of attributes in the schema is not so important, so the feature is called the irrelevant order calculation. - -Please note that there can be no circular references between different schema attribute values. - -We can see this feature through the following examples. - -```python -schema Person: - name?: str - age: int = _age - - _age = 10 - - if name == "Son": - _age = 18 - -schema Son(Person): - name: str = "Son" - -person = Person {} -son = Son {} -``` - -The output is - -```yaml -person: - name: null - age: 10 -son: - name: Son - age: 18 -``` - -Besides, we can achieve KCL polymorphism such as - -```python -schema Person: - name?: str - _age: int = _age - - _age = 10 - if name == "Son": - _age = 18 - elif name == "SonConf": - _age = 24 - -schema Son(Person): - name: str = "Son" - -person = Person() {} -son = Son() { - name = "SonConf" -} -``` - -The output is - -```yaml -person: - name: null - age: 10 -son: - name: SonConf - age: 24 -``` - -More examples: - -```python -schema Fib: - n1: int = n - 1 - n2: int = n1 - 1 - n: int - value: int = _value - - if n <= 2: - _value = 1 - else: - _value = (Fib {n = n1}).value + (Fib {n = n2}).value - -fib8 = (Fib {n = 8}).value -``` - -The output is - -```yaml -fib8: 21 -``` - -As in the above examples, we can see that in the schema, we only need to simply specify the dependency between attributes, and the compiler will automatically calculate the value based on the dependency, which can help us save a lot of boilerplate code and reduce configuration difficulty of writing. diff --git a/versioned_docs/version-0.5.0/reference/lang/spec/statements.md b/versioned_docs/version-0.5.0/reference/lang/spec/statements.md deleted file mode 100644 index b09488b9..00000000 --- a/versioned_docs/version-0.5.0/reference/lang/spec/statements.md +++ /dev/null @@ -1,185 +0,0 @@ ---- -title: "Statements" -linkTitle: "Statements" -type: "docs" -weight: 2 -description: Statements ---- - -## Syntax - -In KCL, statements consist of small statements and compound statements. The syntax is the following: - -```bnf -preamble_statement: preamble_small_stmt | preamble_compound_stmt -preamble_small_stmt: (small_stmt | import_stmt) NEWLINE -preamble_compound_stmt: compound_stmt | schema_stmt -statement: small_stmt NEWLINE | compound_stmt -compound_stmt: if_stmt -small_stmt: assign_stmt | expr_stmt | assert_stmt -``` - -The preamble statement is used to define the module level statements, consist of `statement`, `import_stmt`, and `schema_stmt`. The statement is used to define the block level statements, which are used in the `if` statement and `schema` statement. - -### Small Statements - -A small statement is comprised of a single logical line. Multiple statements in one-line are not allowed. - -#### Assignment Statements - -Generally, assign_stmt is divided into assignment and augmented assignment. The syntax is the following: - -```bnf -assign_stmt: target_primary ("=" target_primary)* "=" test | target_primary augassign test -augassign: "+=" | "-=" | "*=" | "**=" | "/=" | "//=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>=" | "or" | "and" -target_primary: identifier | target_primary DOT identifier -``` - -An assignment statement has the form `lhs = rhs`. It evaluates the expression on the right-hand side then assigns its value (or values) to the variable (or variables) on the left-hand side. - -The **target_primary** on the left-hand side is an `identifier` or an `identifier` followed by select dots. - -Note: When using **target_primary** will cause collisions, use **primary_expr** as an alternative. - -Examples: - -```python -k = 1 -a.b = "a.b" -``` - -To keep it simple, the compound target is not supported as **target_primary**. - -The right value of an assignment statement is a conditional expression, which is discussed separately. - -An augmented assignment, which has the form `lhs op= rhs` updates the variable `lhs` by applying a binary arithmetic operator op (one of +, -, \*, /, //, %, &, |, ^, <<, >>) to the previous value of `lhs` and the value of `rhs`. - -The **target_primary** on the left-hand side is the same as assignment statement. Examples: - -```python -_x -= 1 -_filename += ".k" -``` - -There is no concept of in-place modification in KCL. The `augassign` statement will modify a copy of the **target_primary** and assign the copy to **target_primary**. - -In particular, in KCL, the `|=` symbol represents the **union** operation, which is defined as follows: - -- The behavior of the **union** operation needs to be consistent with the behavior of the **configuration definition**. - -See **expressions** spec for more details of union operator in **Arithmetic Operations**. - -#### Expression Statements - -An expression statement evaluates an expression and discards its result. - -Syntax: - -```bnf -expr_stmt: expression -``` - -An expression statement supported in KCL is function invocation expression, which is discussed in **expression** spec. - -```python -print(k) # print a variable -``` - -#### Import Statements - -Import statements are used to **search** and **load** a module, and define a name or names in the local namespace for the scope where the import statement occurs. - -Syntax: - -```bnf -import_stmt: "import" dot_name ("as" NAME)? -dot_name: [leading_dots] identifier (DOT identifier)* -leading_dots: "."+ -``` - -Examples: - -```python -import math # import a built-in module math -import pkg # import pkg -import pkg.foo # import pkg.foo -import pkg.subpkg # import a subpkg in a pkg -import .pkg2.subpkg3 # import a subpkg in a pkg inside of current pkg -import ...pkg2 # Go two levels up then import pkg2 -``` - -See **module** spec for more details of module spec. - -#### Assert Statements - -Assert statements are a convenient way to insert debugging assertions into KCL code. - -The syntax is the following: - -``` -assert_stmt: ASSERT test ("," test)? -``` - -The conditional expression in assert will be evaluated and get a boolean. Report an error if returning a `False`. - -Examples: - -```python -assert: x > 1 # report an error on x <= 1 -``` - -#### Conditional Statements - -KCL allows using conditional statements to control the instructions to -be executed. They are also called the control-flow statements. - -The only type of control-flow syntax is the well-known `if-elif-else` syntax. - -The syntax of the `if-elif-else` statement is the following. - -```bnf -if_stmt: "if" test ":" suite ("elif" test ":" suite)* (ELSE ":" suite)? -suite: small_stmt | NEWLINE _INDENT statement+ _DEDENT -``` - -An `if` or `elif` statement evaluates a given expression. When the expression -is evaluated to `True`, a list of statements following `:` are executed. - -The following is an example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - print("maybe a is negative") -else: - print("a >= 100") -``` - -`if-elif-else` statements can be nested. For example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - if a < 0: - print("a is negative") - print("No matter a is negative or positive, this message is printed") -else: - print("a >= 100") -``` - -#### Schema Statements - -Schema statements are used to define a type of configuration data. The syntax is the following: - -```bnf -schema_stmt: [decorators] "schema" ["relaxed"] identifier ["[" [arguments] "]"] ["(" operand_name ")"] ":" NEWLINE [schema_body] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt | statement)* [check_block] _DEDENT -``` - -See **schema** spec for more details of schema spec. diff --git a/versioned_docs/version-0.5.0/reference/lang/spec/variables.md b/versioned_docs/version-0.5.0/reference/lang/spec/variables.md deleted file mode 100644 index b3e1c539..00000000 --- a/versioned_docs/version-0.5.0/reference/lang/spec/variables.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: "Variables" -linkTitle: "Variable" -type: "docs" -weight: 2 -description: Variable ---- - -In KCL, variables can be defined using assign statements. For example, the following statement defines a variable `spam` to a string `"ham"`. - -```python -spam = "ham" -``` - -There are two types of variables, which are global variables and list comprehension local variables. - -- A global variable is defined not within any context. -- A comprehension local variable is defined inside a comprehension. - -A variable can be used after definition, until the end of the current scope. - -For a global variable, the scope is the module it is defined in. Note that a module can consists of multiple source files. - -For a list comprehension local variable, the scope is the list comprehension it is defined in. - -More information on modules, list comprehensions and scopes will be discussed in later chapters. - -## Immutability - -Global variables are immutable. In other words, once defined such a variable cannot be redefined (or, i.e., modified). - -The following code is illegal, and KCL will report an error during evaluation. - -```python -spam = "ham" -spam = "eggs" # Error: The immutability rule is violated! -``` - -- A variable starts with the `_` character is mutable. - -```python -_spam -cond = True -if cond: - _spam = "ham" -else: - _spam = "eggs" -``` - -## Variable Exporting - -As shown in the preview chapter, KCL is able to export evaluation results to the standard output according to a target data format. - -The rules are the followings: - -- Living global variables at the end of an evaluation will be dumped out. -- If the name of a variable starts with the `_` character, it will not be dumped out. - -## Uniqueness of Exported Variable Identifier - -Each exported variable identifier must be unique in its package, so that an exported variable could be located uniquely by package location path and variable identifier, such as 'a.b.c:var', in which 'a.b.c' locates a package. - -Two variable identifiers are different if: - -- they are spelled differently -- they are defined in different packages and are not compiled in a single execution - -Identifying an exported variable should be supported by the kcl compiler, which needs to provide corresponding identifying features through the command line and api form. diff --git a/versioned_docs/version-0.5.0/reference/lang/tour.md b/versioned_docs/version-0.5.0/reference/lang/tour.md deleted file mode 100644 index d0ddaec8..00000000 --- a/versioned_docs/version-0.5.0/reference/lang/tour.md +++ /dev/null @@ -1,3317 +0,0 @@ ---- -title: "KCL Tour" -sidebar_position: 1 ---- - -This page shows how to use major KCL features, from variables and operators to schemas and libraries, with the assumption that you have already known how to program in another language. KCL is mainly inspired by Python, and knowing Python is very helpful for learning KCL. - -### Important Concepts - -As we learn about the KCL language, keep these facts and concepts in mind: - -- KCL is a configuration and policy language. It provides simplified and self-contained language design and library support for writing configurations and policies. It cannot be used for application development or other purposes supported by General Purpose Language (GPL). -- KCL absorbs classic **OOP** elements and provides simple, developer-friendly and reliable configuration writing practice with **type**, **reusing**, and **union**. -- KCL prefers **immutability** and recommend to add up incremental updates through the **union**. Immutability reduces side effects like unpredictable issues. -- KCL **schema** struct defines strict attributes, static types, and it also supports validation expressions. The **schema** struct is mainly composed of typed attributes, the schema context and the check block. -- KCL **config** is a **json**-like expression, by which we can reuse a full definition of the schema. KCL provides support for definition and configuration by separating schema and config. -- KCL **rule** is a structure for writing rule constraint expressions, which can be used for data verification and policy writing. -- KCL code files are managed as packages(directories) and modules(files). The schema types in the same package are visible to each other; the data cross packages need to be imported through the **import statement**. The package-level variables can be exported, but they are immutable for other packages. -- The KCL syntax definition mainly uses declarative expressions, and only provides a small number of necessary and imperative statements, such as import, if .. else, assert, assignment and schema. -- No main function, each `.k` file could be executed as a separate configuration. -- **Built-in functions** and **plugins** are supported to simplify coding. - -### Keywords - -The following table lists the words that the KCL language treats specially. - -```txt -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -### Identifiers - -In KCL, an identifier is a name, may with selectors, that identifies a value. - -- Identifiers consist of letters, numbers, underscores or the prefix `$`. -- Identifiers cannot be repeated with keywords unless they have a `$` prefix. -- Identifiers must not contain any embedded spaces or symbols. -- Letters and underscores can be used anywhere in the identifier. -- Numbers cannot be placed in the first place of the identifier. -- The `$` character can only be placed in the first position of the identifier. - -Examples: - -```python -x -a -b1 -b_2 -_c -$if -``` - -To simplify the definition of the qualified identifier, such as `pkg.type`, we additionally define `qualified identifier`: - -Examples: - -```python -pkg.a -``` - -The package name in `qualified identifier` must be imported. - -#### Identifier Prefix - -Use the `$` character prefix to define keyword identifiers. - -```python -$if = 1 -$else = "s" -``` - -Please note: whether the non-keyword identifier is prefixed with `$` has the same effect. - -```python -_a = 1 -$_a = 2 # equal to `_a = 2` -``` - -### Variables - -Here’s an example of how to create a variable and initialize it: - -```python -name = "Foo" # Declare a variable named `name` and its value is a string literal "Foo" -``` - -It corresponds to the following YAML output: - -```yaml -name: Foo -``` - -In KCL, we can export variables as config data by defining package-level variables. To make it direct, clear, and maintainable. Exported variables are immutable so that once we declare it, we can't modify it. For example, assume we have a config file named `example.k`, the variable `name` can't be modified after the declaration, just like the standard imperative language. - -```python -name = "Foo" # exported - -... - -name = "Bar" # error: a exported declaration variable can only be set once. -``` - -As a complement, we can define a non-exported variable in module level which is mutable, which won't show up in YAML output: - -```python -_name = "Foo" # _ variables are not output to YAML and are mutable -_name = "Bar" -``` - -Please note that the variable name cannot be one of `True`, `False`, `None`, `Undefined` because of ambiguity. - -```python -False = 1 # Error -True = False # Error -None = Undefined # Error -Undefined = None # Error -``` - -### Built-in Types - -The KCL language has special support for the following types: - -- number -- string -- boolean -- list -- dict - -#### Number - -KCL number comes into two flavors: - -- **Int**: 64 bits signed integer values. Values can be from -9223372036854775808~9223372036854775807. -- **Float**: 64-bit floating-point numbers, as specified by the IEEE 754 standard. We do not recommend using the float type in the configuration, we can use a string instead and parse it during runtime processing. - -Both int and float support basic operators such as `+`, `-`, `/`, and `*`, while complex operations, such as `abs()`, `ceil()`, and `floor()`, are supported through the built-in math library. - -Integers are numbers without a decimal point. Here are some examples of defining integer literals: - -```python -a = 1 -b = -1 -c = 0x10 # hexadecimal literal -d = 0o10 # octal literal -e = 010 # octal literal -f = 0b10 # binary literal -g = int("10") # int constructor -``` - -If a number includes a decimal point, it is a float number. Here are some examples of defining float literals: - -```python -a = 1.10 -b = 1.0 -c = -35.59 -d = 32.3e+18 -f = -90. -h = 70.2E-12 -i = float("112") # float constructor -``` - -Built-in math libraries can be used with numbers: - -```python -import math - -assert abs(-40) == 40 -assert round(70.23456) == 70 -assert min(80, 100, 1000) == 80 -assert max(80, 100, 1000) == 1000 -assert sum([0,1,2]) == 3 -assert math.ceil(100.12) == 101.0 -assert math.floor(100.12) == 100.0 -assert math.pow(100, 2) == 10000.0 -``` - -In addition, please note that the KCL number is 64-bit by default. We can perform a stricter 32-bit range check by adding the `-r` parameter to the KCL command-line tool. - -```bash -kcl main.k -r -d -``` - -Please note that the value range check is only enabled in `debug` mode - -##### Units - -In KCL, we can add a unit suffix to an integer denomination to indicate that it does not affect its true value as follows. - -- General integer or fixed-point number form: `P`, `T`, `G`, `M`, `K`, `k`, `m`, `u`, `n` -- Corresponding power of 2: `Pi`, `Ti`, `Gi`, `Mi`, `Ki` - -```python -# SI -n = 1n # 1e-09 -u = 1u # 1e-06 -m = 1m # 1e-03 -k = 1k # 1000 -K = 1K # 1000 -M = 1M # 1000000 -G = 1G # 1000000000 -T = 1T # 100000000000 -P = 1P # 1000000000000000 -# IEC -Ki = 1Ki # 1024 -Mi = 1Mi # 1024 ** 2 -Gi = 1Gi # 1024 ** 3 -Ti = 1Ti # 1024 ** 4 -Pi = 1Pi # 1024 ** 5 -``` - -Besides, And we can also use the unit constants defined in the `units` module as follows: - -```python -import units - -n = 1 * units.n # 1e-09 -u = 1 * units.u # 1e-06 -m = 1 * units.m # 1e-03 -k = 1 * units.k # 1000 -K = 1 * units.K # 1000 -M = 1 * units.M # 1000000 -G = 1 * units.G # 1000000000 -T = 1 * units.T # 1000000000000 -P = 1 * units.P # 1000000000000000 -# IEC -Ki = 1 * units.Ki # 1024 -Mi = 1 * units.Mi # 1024 ** 2 -Gi = 1 * units.Gi # 1024 ** 3 -Ti = 1 * units.Ti # 1024 ** 4 -Pi = 1 * units.Pi # 1024 ** 5 -``` - -We can also use the methods in the `units` module to convert between integers and unit strings. - -```python -import units -# SI -K = units.to_K(1000) # "1K" -M = units.to_M(1000000) # "1M" -G = units.to_G(1000000000) # "1G" -T = units.to_T(1000000000000) # "1T" -P = units.to_P(1000000000000000) # "1P" -# IEC -Ki = units.to_Ki(1024) # "1Ki" -Mi = units.to_Mi(1024 ** 2) # "1Mi" -Gi = units.to_Gi(1024 ** 3) # "1Gi" -Ti = units.to_Ti(1024 ** 4) # "1Ti" -Pi = units.to_Pi(1024 ** 5) # "1Pi" -``` - -```python -import units -# SI -K = units.to_K(int("1M")) # "1000K" -M = units.to_M(int("1G")) # "1000M" -G = units.to_G(int("1T")) # "1000G" -T = units.to_T(int("1P")) # "1000T" -P = units.to_P(int("10P")) # "10P" -# IEC -Ki = units.to_Ki(int("1Mi")) # "1024Ki" -Mi = units.to_Mi(int("1Gi")) # "1024Mi" -Gi = units.to_Gi(int("1Ti")) # "1024Gi" -Ti = units.to_Ti(int("1Pi")) # "1024Ti" -Pi = units.to_Pi(int("10Pi")) # "10Pi" -``` - -The unit value type is defined in the units module, and the unit value type does not allow any four calculations. - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -x0: NumberMultiplier = 1M # Ok -x1: NumberMultiplier = x0 # Ok -x2 = x0 + x1 # Error: unsupported operand type(s) for +: 'number_multiplier(1M)' and 'number_multiplier(1M)' -``` - -We can use the `int()`, `float()` function and `str()` function to convert the numeric unit type to the normal integer type and string type. - -```python -a: int = int(1Ki) # 1024 -b: float = float(1Ki) # 1024.0 -c: str = str(1Mi) # "1Mi" -``` - -#### String - -The string is an immutable sequence of Unicode characters. We can use either single or double quotes to create a string: - -```python -'allows embedded "double" quotes' # Single quotes -"allows embedded 'single' quotes" # Double quotes -'''Three single quotes''', """Three double quotes""" # Triple quoted -``` - -Triple quoted strings may span multiple lines. - -```python -"""This is a long triple quoted string -may span multiple lines. -""" -``` - -Please note that there is almost no difference in the use of KCL single-quoted and double-quoted strings. The only thing that can be simplified is that we don’t need to escape double quotes in single quoted strings, and we don’t need to escape single quotes in double quoted strings. - -```python -'This is my book named "foo"' # Don’t need to escape double quotes in single quoted strings. -"This is my book named 'foo'" # Don’t need to escape single quotes in double quoted strings. -``` - -We can concatenate strings using the `+` operator: - -```python -x = 'The + operator ' + 'works, as well.' -``` - -We can cast an int or float to a string using the built-in function `str`: - -```python -x = str(3.5) # "3.5" -``` - -A lot of handy built-in functions and members of a string could be used: - -```python -x = "length" -assert len(x) == 6 # True -assert x.capitalize() == "Length" -assert x.count("gt") == 1 -assert x.endswith("th") == True -assert x.find("gth") == 3 -assert "{} {}".format("hello", "world") == 'hello world' -assert x.index("gth") == 3 -assert x.isalnum() == True -assert x.isalpha() == True -assert "123456".isdigit() == True -assert x.islower() == True -assert " ".isspace() == True -assert "This Is Title Example".istitle() == True -assert x.isupper() == False -assert "|".join(["a", "b", "c"]) == "a|b|c" -assert "LENGTH".lower() == "length" -assert ' spacious '.lstrip() == 'spacious ' -assert x.replace("th", "ht") == "lenght" -assert "lengthlength".rfind("le") == 6 -assert "lengthlength".rindex("le") == 6 -assert "length length".rsplit() == ["length", "length"] -assert "length ".rstrip() == "length" -assert "length length".split() == ["length", "length"] -assert 'ab c\n\nde fg\rkl\r\n'.splitlines() == ['ab c', '', 'de fg', 'kl'] -assert "length".startswith('len') == True -assert "***length***".strip('*') == "length" -assert "length length".title() == "Length Length" -assert x.upper() == "LENGTH" -``` - -There are 2 different ways to format a string: to use the `"{}".format()` built-in function, or to specify the variable between the curly braces and use a `$` mark to tell KCL to extract its value. This is called **string interpolation** in KCL. In following example, both `a` and `b` will be assigned to string `"hello world"`. - -Besides, the variable to serialized can be extracted in special data format, such as YAML or JSON. In this case, a `#yaml` or `#json` can be included within the curly braces. - -Specifically, when the dollar sign `$` itself is needed in a **string interpolation**, it needs to be escaped and use `$$` instead. Or in another way, `+` can be used to concat the dollar sign with the **string interpolation** to avoid that escape. In following example, both `c` and `c2` will be assigned to string `$hello world$` - -```python -world = "world" -a = "hello {}".format(world) # "hello world" -b = "hello ${world}" # "hello world" -c = "$$hello ${world}$$" # "$hello world$" -c2 = "$" + "hello ${world}" + "$" # "$hello world$" - -myDict = { - "key1" = "value1" - "key2" = "value2" -} - -d = "here is myDict in json: ${myDict: #json}" -# d: 'here is myDict in json: {"key1": "value1", "key2": "value2"}' - -e = "here is myDict in yaml:\n${myDict: #yaml}" -# e: | -# here is myDict in yaml: -# key1: value1 -# key2: value2 -``` - -Besides, we can see some symbols in the example code output **YAML string** above such as `|`, `>`, `+`, `-`. - -- `|` denotes the **block literal style** that indicates how newlines inside the block should behave. -- `>` denotes the **block folded style** in the block scalar that the newlines will be replaced by spaces. -- `+` and `-` are the **block chomping indicators** that control what should happen with newlines at the end of the string. The default value **clip** puts a single newline at the end of the string. To remove all newlines, **strip** them by putting a `-` after the style indicators `|` or `>`. Both clip and strip ignore how many newlines are actually at the end of the block; to **keep** them all put a `+` after the style indicator. - -For example, a **strip block literal style** yaml string is - -```yaml -example: |- - Several lines of text, - with some "quotes" of various 'types', - and also a blank line: - - plus another line at the end. -``` - -The result is - -```plain -Several lines of text, -with some "quotes" of various 'types', -and also a blank line: - -plus another line at the end. -``` - -See [Yaml Multiline String](https://yaml-multiline.info/) and [YAML Specification v1.2](https://yaml.org/spec/1.2.1/) for more information. - -##### Raw String - -KCL raw string is created by prefixing a string literal with `'r'` or `'R'`. KCL raw string treats backslash (`\`) and string interpolation (`${}`) as a literal character. This is useful when we want to have a string that contains backslash, string interpolation and don’t want them to be treated as an escape character. - -- For backslash (`\`), the KCL code and output YAML are as follows: - -```python -s = "Hi\nHello" -raw_s = r"Hi\nHello" # This is a KCL raw string with the `r` prefix. -``` - -```yaml -s: |- - Hi - Hello -raw_s: Hi\nHello -``` - -- For string interpolation (`${}`), the KCL code and output YAML are as follows: - -```python -worldString = "world" -s = "Hello ${worldString}" -raw_s = r"Hello ${worldString}" # This is a KCL raw string with the `r` prefix. -``` - -```yaml -worldString: world -s: Hello world -raw_s: Hello ${worldString} -``` - -In addition, the most common scenario for raw strings is to be used with regular expressions: - -```python -import regex - -key = "key" -result = regex.match(key, r"[A-Za-z0-9_.-]*") # True -``` - -#### Boolean - -Boolean values are the two constant objects `False` and `True`. - -```python -a = True -b = False -``` - -#### List - -The list is a sequence, typically used to store collections of homogeneous items. Here’s a simple KCL list: - -```python -list = [1, 2, 3] -assert len(list) == 3 # True -assert list[0] == 1 # True -``` - -We can declare a list with list comprehension: - -```python -list = [ _x for _x in range(20) if _x % 2 == 0] -assert list == [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] # True -``` - -We can perform nested list comprehension: - -```python -matrix = [[1, 2], [3,4], [5,6], [7,8]] -transpose = [[row[_i] for row in matrix] for _i in range(2)] -assert transpose == [[1, 3, 5, 7], [2, 4, 6, 8]] # True -``` - -Besides, we can use two variables in the list comprehension, the first variable denotes the list index and the second variable denotes the list item. - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use `_` to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -We can merge list like this: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -joined_list = _list0 + _list1 # [1, 2, 3, 4, 5, 6] -``` - -We can also use the list unpacking operator `*` to merge multiple lists: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -union_list = [*_list0, *_list1] # [1, 2, 3, 4, 5, 6] -``` - -We can use `if expressions` to dynamically add elements to the list element, elements that meet the conditions are added to the list, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = [ - 1 - if a == 1: 2 - if a > 0: 3 - if a < 0: 4 -] # [1, 2, 3] -``` - -```python -a = 1 # 1 -data1 = [ - 1 - if a == 1: - 2 - elif a == 2: - 3 - else: - 3 -] # [1, 2] -data2 = [ - 1 - if a == 1: 2 - elif a == 2: 2 - else: 3 -] # [1, 2] -``` - -Please note that in the above `if expressions`, nested use is not supported. - -We can union two lists like this: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -union_list = _list0 | _list1 # [4, 5, 6] -``` - -We can use the expression `for k in list_var` to traverse a list. - -```python -data = [1, 2, 3] -dataAnother = [val * 2 for val in data] # [2, 4, 6] -``` - -#### Dict - -Dict is a mapping object that maps hashable values to arbitrary objects. Dict is ordered. The order of the keys follows the order of their declaration. - -Here are a couple of simple KCL dict, created using dict literals: - -```python -a = {"one" = 1, "two" = 2, "three" = 3} -b = {'one' = 1, 'two' = 2, 'three' = 3} -assert a == b # True -assert len(a) == 3 # True -``` - -We can ignore the comma `,` at the end of the line for writing dict key-value pairs in multiple lines: - -```python -data = { - "key1" = "value1" # Ignore the comma ',' at the end of line - "key2" = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -We can ignore the key quotation marks when we writing simple literals on the key. - -```python -data = { - key1 = "value1" # Ignore key quotation '"' - key2 = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -In addition, the **config selector expressions** can be used to init a dict instance with nested keys. - -```python -person = { - base.count = 2 - base.value = "value" - labels.key = "value" -} # {"base": {"count": 2, "value": "value"}, "labels": {"key": "value"}} -``` - -The output YAML is - -```yaml -person: - base: - count: 2 - value: value - labels: - key: value -``` - -In KCL, different fields in dict can be referenced, such as the following example. - -```python -config = { - name = "me" - metadata.name = name # Reference `name` with the value `"me"` in `config` directly. -} -``` - -The output YAML is - -```yaml -config: - name: me - metadata: - name: me -``` - -We can declare a dict with dict comprehension: - -```python -x = {str(i): 2 * i for i in range(3)} -assert x == {"0" = 0, "1" = 2, "2" = 4} -``` - -Besides, we can use two variables in the dict comprehension, the first variable denotes the dict key and the second variable denotes the dict value of the key. - -```python -data = {key1 = "value1", key2 = "value2"} -# Single variable loop -dataKeys1 = {k: k for k in data} # {"key1": "key1", "key2": "key2"} -dataValues1 = {k: data[k] for k in data} # {"key1": "value1", "key2": "value2"} -# Double variable loop -dataKeys2 = {k: k for k, v in data} # {"key1": "key1", "key2": "key2"} -dataValues2 = {v: v for k, v in data} # {"value1": "value1", "value2": "value2"} -dataFilter = {k: v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use `_` to ignore loop variables -dataKeys3 = {k: k for k, _ in data} # {"key1": "key1", "key2": "key2"} -dataValues3 = {v: v for _, v in data} # {"value1": "value1", "value2": "value2"} -``` - -We can **merge** dict using the dict unpacking operator `**` like this: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = {**_part1, **_part2} # {"a: "b", "c": "d"} -``` - -In addition, the same effect can be achieved by using the union operator `|`: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = _part1 | _part2 # {"a: "b", "c": "d"} -``` - -We can use `if expressions` to dynamically add elements to the dict element, elements that meet the conditions are added to the dict, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = { - key1 = "value1" - if a == 1: key2 = "value2" - if a > 0: key3 = "value3" - if a < 0: key4 = "value4" -} # {"key1": "value1", "key2": "value2", "key3": "value3"} -``` - -```python -a = 1 # 1 -data1 = { - key1 = "value1" - if a == 1: - key2 = "value2" - elif a > 0: - key3 = "value3" - else: - key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -data2 = { - key1 = "value1" - if a == 1: key2 = "value2" - elif a > 0: key3 = "value3" - else: key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -``` - -We can use the expression `for k in dict_var` to traverse a dict, and we can use the `in` operator to determine whether a dict contains a certain key - -```python -data = {key1 = "value1", key2 = "value2"} -dataAnother = {k: data[k] + "suffix" for k in data} # {"key1": "value1suffix", "key2": "value2suffix"} -containsKey1 = "key1" in data # True -containsKey2 = "key" in data # False -``` - -#### None - -In KCL, `None` can indicate that the value of the object is empty, which is similar to `nil` in Go or `null` in Java, and corresponds to `null` in YAML. - -```python -a = None -b = [1, 2, None] -c = {key1 = value1, key2 = None} -``` - -The output is as follows: - -```yaml -a: null -b: - - 1 - - 2 - - null -c: - key1: value1 - key2: null -``` - -Please note that `None` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + None # error -b = int(None) # error -c = not None # True -d = None == None # True -e = None or 1 # 1 -f = str(None) # None -``` - -#### Undefined - -`Undefined` is similar to `None`, but its semantics is that a variable is not assigned any value and will not be output to YAML - -```python -a = Undefined -b = [1, 2, Undefined] -c = {key1 = "value1", key2 = Undefined} -``` - -The output is as follows: - -```yaml -b: - - 1 - - 2 -c: - key1: value1 -``` - -Please note that `Undefined` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + Undefined # error -b = int(Undefined) # error -c = not Undefined # True -d = Undefined == Undefined # True -e = Undefined or 1 # 1 -f = str(Undefined) # Undefined -``` - -### Operators - -The following character sequences represent operators: - -```txt -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != @ \ -``` - -#### Arithmetic Operators - -KCL supports the common arithmetic operators: - -```python -assert 2 + 3 == 5 -assert 2 - 3 == -1 -assert 2 * 3 == 6 -assert 5 / 2 == 2.5 -assert 5 // 2 == 2 -assert 5 % 2 == 1 -``` - -#### Equality and Relational Operators - -KCL supports the meanings of equality and relational operators: - -```python -assert 2 == 2 -assert 2 != 3 -assert 3 > 2 -assert 2 < 3 -assert 3 >= 3 -assert 2 <= 3 -``` - -#### Logical Operators - -We can invert or combine boolean expressions using the logical operators e.g., `and` and `or`: - -```python -if not done and (col == 0 or col == 3): - # ...Do something... - -``` - -#### Bitwise and Shift Operators - -Here are examples of using bitwise and shift operators: - -```python -value = 0x22 -bitmask = 0x0f - -assert (value & bitmask) == 0x02 -assert (value & ~bitmask) == 0x20 -assert (value | bitmask) == 0x2f -assert (value ^ bitmask) == 0x2d -assert (value << 4) == 0x220 -assert (value >> 4) == 0x02 -``` - -The `|` operator likewise computes bitwise, unions basic types and unions collection and schema data, such as **list**, **dict** and **schema**. - -Computing bitwise examples: - -```python -0x12345678 | 0xFF # 0x123456FF -``` - -Unioning basic types examples: - -```python -schema x: - a: int | str # attribute a could be a int or string -``` - -#### Assignment Operators - -The following tokens serve as delimiters in the grammar: - -```bash - ( ) [ ] { } - , : . ; = -> - += -= *= /= //= %= - &= ^= >>= <<= **= -``` - -The following examples use assignment and argument assignment operators: - -```python -_a = 2 -_a *= 3 -_a += 1 -assert _a == 7 -``` - -#### Identity Operators - -The following keywords serve as identity operators in the grammar: - -```python -is, is not -``` - -The identity operators check whether the right hand side and the left hand side are the very same object. They are usually used to check if some variable is `None/Undefined/True/False`. Here are some examples: - -```python -empty_String = "" -empty_String is not None # True -``` - -#### Membership Operators - -The following keywords serve as membership operators in the grammar: - -```python -in, not in -``` - -- The `in` operator reports whether its first operand is a member of its second operand, which must be a list, dict, schema, or string. -- The `not in` operator is its negation. Both return a Boolean. - -The meaning of membership varies by the type of the second operand: the members of a list are its elements; the members of a dict are its keys; the members of a string are all its substrings. - -```python -1 in [1, 2, 3] # True - -d = {one = 1, two = 2} -"one" in d # True -"three" in d # False -1 in d # False -[] in d # False - -"nasty" in "dynasty" # True -"a" in "banana" # True -"f" not in "way" # True - -d = Data {one = 1, two = 2} # Data is a schema with attributes one and two -"one" in d # True -"three" in d # False -``` - -#### Comprehension - -A comprehension constructs a new list or dictionary value by looping over one or more iterables and evaluating a body expression that produces successive elements of the result. - -We can declare list and dict by comprehension as: - -```python -listVar = [_x for _x in range(20) if _x % 2 == 0] # list comprehension -dictVar = {str(_i): 2 * _i for _i in range(3)} # dict comprehension -``` - -#### Other Operators - -We can: - -- Represents a function call with **()**, like `"{} {}".format("hello", world)` -- Refers to the value at the specified index in the list with **[]** -- Define a type hint with **:** -- Refers to a member field with **.** -- Use the line continuation symbol `\` to write long expressions - -```python -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " -``` - -### Expressions - -#### Conditional Expressions - -A conditional expression has the form `a if cond else b`. It first evaluates the condition `cond`. If it's true, it evaluates `a` and yields its value; otherwise, it yields the value of `b`. - -Examples: - -```python -x = True if enabled else False # If enabled is True, x is True, otherwise x is False -``` - -#### Index Expressions - -An index expression `a[i]` yields the `i` th element of an indexable type such as a string or list. The index `i` must be an `int` value in the range `-n` ≤ `i` < `n`, where `n` is `len(a)`; any other index results in an error. - -A valid negative index `i` behaves like the non-negative index `n+i`, allowing for convenient indexing relative to the end of the sequence. - -```python -val = "abc" -list = ["zero", "one", "two"] -str_0 = val[0] # "a" -str_1 = val[1] # "b" -str_n1 = val[-1] # "c" - -list_0 = list[0] # "zero" -list_1 = list[1] # "one" -list_n1 = list[-1] # "two" -``` - -An index expression `d[key]` may also be applied to a dictionary `d`, to obtain the value associated with the specified key. It returns `Undefined` if the dictionary contains no such key. - -An index expression appearing on the left side of an assignment causes the specified list or dictionary element to be updated: - -```python -d = {key1 = "value1", key2 = "value2"} -key1value = d["key1"] # value1 -key2value = d["key2"] # value2 -``` - -It is a dynamic error to attempt to update an element of an immutable type, such as a list or string, or a frozen value of a mutable type. - -#### Slice Expressions - -A slice expression `a[start:stop:step]` yields a new value containing a sub-sequence of `a`, which must be a string, or list. - -Each of the `start`, `stop`, and `step` operands is optional; if present, each must be an integer. The `step` value defaults to 1. If the step is not specified, the colon preceding it may be omitted too. It is an error to specify a step of zero. - -Conceptually, these operands specify a sequence of values `i` starting at start and successively adding 'step' until `i` reaches or passes `stop`. The result consists of the concatenation of values of `a[i]` for which `i` is valid. - -The effective start and stop indices are computed from the three operands as follows. Let `n` be the length of the sequence. - -```python -val = "abc" -len = len(val) -a = val[1:len] # "bc" (remove first element) -b = val[0:-1] # "ab" (remove last element) -c = val[1:-1] # "b" (remove first and last element) -``` - -```python -"abc"[1:] # "bc" (remove first element) -"abc"[:-1] # "ab" (remove last element) -"abc"[1:-1] # "b" (remove first and last element) -"banana"[1::2] # "aaa" (select alternate elements starting at index 1) -"banana"[4::-2] # "nnb" (select alternate elements in reverse, starting at index 4) -``` - -It's not allowed to define a slice expression as a left value in KCL. Cause list and string are immutable, re-slicing can directly operate to operand to ensure better performance. - -#### Function Invocations - -KCL allows calling built-in functions and functions from built-in and system modules. - -To call a function, the basic way is shown as the following code excerpt: - -```python -import math - -a = math.pow(2, 3) # 2 powers 3 is 8. -b = len([1, 2, 3]) # the length of [1, 2, 3] is 3 -``` - -As you can see, arguments are separated with `,`, and KCL also supports positional arguments and key-value arguments. - -```python -print("hello world", end="") -``` - -Note that: - -- Some functions have parameters with default values. -- Some functions accept variadic arguments. - -When an argument is not supplied for a parameter without a default value, an error will be reported. - -#### Selector Expressions - -A selector expression selects the attribute or method of the value. KCL provides a wealth of ways to identify or filter attributes. - -`x.y` - -- dict: it denotes the value of the key `y` in the dict `x` -- schema: it denotes the attribute value of a schema `x` identified by `y` -- package: it denotes the identifier of a package `x` identified by `y` - -Examples: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -name = person.name # "Alice" -age = person.age # 18 - -myDict = { - key = "value" -} -result = myDict.key # "value" -``` - -`x?.y` - -`x` can be a schema instance or a dict. This is extremely helpful when the value of `x` might be `None` or when the key `y` might not exist in `x`. - -```python -# Example of dict: -data = {key = "value"} -a = data?.key # "value" -b = data?.name # Undefined - -# example of schema instance: -schema Company: - name: str - address: str - -schema Person: - name: str - job?: Company - -alice = Person { - name = "alice" -} - -if alice?.job?.name == "Group": - print("work in Group") -``` - -#### Quantifier Expressions - -Quantifier expressions act on collection: list or dict, generally used to obtain a certain result after processing the collection, mainly in the following four forms: - -- **all** - - Used to detect that all elements in the collection satisfy the given logical expression, and return a boolean value as the result. - - Only when all elements in the collection satisfy the expression true, the `all` expression is true, otherwise it is false. - - If the original collection is empty, return true. - - Supports short-circuiting of logical expressions during expression execution. -- **any** - - Used to detect that at least one element in the collection satisfies the given logical expression, and returns a boolean value as the result. - - When at least one element in the collection satisfies the expression true, the `any` expression is true, otherwise it is false. - - If the original collection is empty, return false. - - Supports short-circuiting of logical expressions during expression execution. -- **map** - - Generate a new **list** by mapping the elements in the original collection. - - The length of the new list is exactly the same as the original collection. -- **filter** - - By logically judging and filtering the elements in the original collection, and returning the filtered sub-collection. - - Only when the element judges the expression to be true, it is added to the sub-collection. - - The type (list, dict and schema) of the new collection is exactly the same as the original collection, and the length range is `[0, len(original-collection)]`. - -**all** and **any** expression sample codes: - -```python -schema Config: - volumes: [{str:}] - services: [{str:}] - - check: - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - }, "invalid cluster ip" - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } -``` - -**map** and **filter** expression sample codes: - -```python -a = map e in [{name = "1", value = 1}, {name = "2", value = 2}] { - {name = e.name, value = int(e.value) ** 2} -} # [{"name": "1", value: 1}, {"name": "2", "value": 4}] - -b = map k, v in {a = "foo", b = "bar"} { v } # ["foo", "bar"] - -c = filter e in [{name = "1", value = 1}, {name = "2", value = 2}] { - int(e.value) > 1 -} # [{"name": "2", "value": 2}] - -d = filter _, v in {a = "foo", b = "bar"} { - v == "foo" -} # {"a": "foo"} -``` - -Please pay attention to distinguish the difference between any expression and any type. When `any` is used in type annotations, it means that the value of the variable is arbitrary, while the any expression means that one of the elements in a set satisfies the condition. - -### Control Flow Statements - -#### If and Else - -KCL supports `if` statements with optional `elif` and `else` statements, as the next sample shows. - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - print("maybe a is negative") -else: - print("a >= 100") -``` - -The `elif` example: - -```python -_result = 0 -if condition == "one": - _result = 1 -elif condition == "two": - _result = 2 -elif condition == "three": - _result = 3 -else: - _result = 4 -``` - -`if-elif-else` statements can be nested. For example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - if a < 0: - print("a is negative") - print("No matter a is negative or positive, this message is printed") -else: - print("a >= 100") -``` - -In addition, for simple `if` statements as follows: - -```python -if success: - _result = "success" -else: - _result = "failed" -``` - -We can have it in one line using the ` if else ` pattern: - -```python -_result = "success" if success else "failed" -``` - -An `if` or `elif` statement evaluates a given expression. When the expression is evaluated to `True`, a list of statements following `:` are executed and when the expression is evaluated to `False` and statements will not be executed. - -Please note that the false name constant `False`, `None`, the zero number `0`, the empty list `[]`, the empty dict `{}` and the empty string `""` are all seen as `False` expressions. - -```python -_emptyStr = "" -_emptyList = [] -_emptyDict = {} -isEmptyStr = False if _emptyStr else True -isEmptyList = False if _emptyList else True -isEmptyDict = False if _emptyDict else True -``` - -The output is - -```yaml -isEmptyStr: true -isEmptyList: true -isEmptyDict: true -``` - -### Assert - -When errors happen, developers should be able to detect the error and abort execution. Thus, KCL introduce the `assert` syntax. The following is an example: - -```python -a = 1 -b = 3 -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -``` - -In addition, we can declare a condition for the assert statement and make an assertion when the condition is met. The usual way of writing is - -```python -a = None -if a: - assert a > 2: -``` - -In KCL, it can also be simplified to the following form using the **if** expression to compose more complex conditional assert logic: - -```python -a = None -assert a > 2 if a -``` - -### Function - -KCL supports using the lambda keyword to define a function. - -```python -func = lambda x: int, y: int -> int { - x + y -} -a = func(1, 1) # 2 -``` - -- The value of the last expression is used as the return value of the function, and the empty function body returns `None`. -- The return value type annotation can be omitted, and the return value type is the type of the last expression value. -- There is no order-independent feature in the function body, all expressions are executed in order. - -```python -_func = lambda x: int, y: int -> int { - x + y -} # Define a function using the lambda expression -_func = lambda x: int, y: int -> int { - x - y -} # Ok -_func = lambda x: int, y: int -> str { - str(x + y) -} # Error (int, int) -> str can't be assigned to (int, int) -> int -``` - -The function type variables cannot participate in any calculations and can only be used in assignment statements and call statements. - -```python -func = lambda x: int, y: int -> int { - x + y -} -x = func + 1 # Error: unsupported operand type(s) for +: 'function' and 'int(1)' -``` - -The lambda function supports the capture of external variables, which can be passed as parameters of other functions. - -```python -a = 1 -func = lambda x: int { - x + a -} -funcOther = lambda f, para: int { - f(para) -} -r0 = funcOther(func, 1) # 2 -r1 = funcOther(lambda x: int { - x + a -}, 1) # 2 -``` - -The output is - -```yaml -a: 1 -r: 2 -``` - -Further, we can define an anonymous function through lambda expression and call it. - -```python -result = (lambda x, y { - z = 2 * x - z + y -})(1, 1) # 3 -``` - -We can also use anonymous functions in the for loop. - -```python -result = [(lambda x, y { - x + y -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 3, 3, 4] -``` - -Note that the functions defined in the KCL are pure functions: - -- The return result of a function depends only on its arguments. -- There are no side effects in the function execution process. - -Therefore, KCL functions cannot modify external variables, but can only reference external variables. For example, the following code will cause an error: - -```python -globalVar = 1 -func = lambda { - x = globalVar # Ok - globalVar = 1 # Error -} -``` - -### Type System - -#### Type Annotation - -Type annotations can be used on top level variables, schema attributes and arguments. - -- An attribute can be of a basic type, such as a string (`str`), a floating-point number (`float`), a fixed-point number (`int`) or a boolean (`bool`). -- An attribute can be a literal type, such as a string literal (`"TCP"` and `"UDP"`), a number literal (`"1"` and `"1.2"`), a boolean literal (`True` and `False`) -- An attribute can also be a list or an ordinary dict: - - A list with unspecified type of elements is `[]`. - - A list with elements of type `t` is `[t]`. Here `t` is another type. - - A dict with keys of type `kt` and values of type `vt` is `{kt:vt}`. - - `kt`, `vt` or both of them can be missing, like a list with unspecified type of elements. -- An attribute can be a **union type** defined by `|`, such as `a | b`, which means the type of the member could be a or b. - - A union type can include any types of `int`, `str`, `float`, `bool`, `list`, `dict`, literal and schema type, and supports type nesting e.g. `{str:str|int}`, `[[int|str]|str|float]` and `2 | 4 | 6`, etc. -- An attribute can also be of a type generated from other schema. In such a case, the name of the other schema (including the package path prefix) is used as the type name. -- An attribute can annotated an any type e.g., `any`. - -Examples: - -- Basic type - -```python -"""Top level variable type annotation""" -a: int = 1 # Declare a variable `a` that has the type `int` and the value `1` -b: str = "s" # Declare a variable `b` that has the type `str` and the value `"s"` -c: float = 1.0 # Declare a variable `c` that has the type `float` and the value `1.0` -d: bool = True # Declare a variable `d` that has the type `bool` and the value `True` -``` - -- List/Dict/Schema Type - -```python -schema Person: - name: str = "Alice" - age: int = 10 - -a: [int] = [1, 2, 3] # Declare a variable `a` that has the list type `[int]` and the value `[1, 2, 3]` -b: {str:str} = {k1 = "v1", k2 = "v2"} # Declare a variable `b` that has the dict type `{str:str}` and the value `{k1 = "v1", k2 = "v2"}` -c: Person = Person {} # Declare a variable `c` that has the schema type `Person` and the value `Person {}` -``` - -- Union Type - -```python -# Basic union types -schema x[argc: int]: # Schema argument type annotation - p: int | str # Schema attribute type annotation -``` - -```python -# Literal union types -schema LiteralType: - # String literal union types, x_01 can be one of "TCP" and "UDP" - x_01: "TCP" | "UDP" - # Number literal union types, x_02 can be one of 2, 4, and 6 - x_02: 2 | 4 | 6 - # Unit union types, x_03 can be one of 1Gi, 2Gi and 4Gi - x_03: 1Gi | 2Gi | 4Gi - -x = LiteralType { - x_01 = "TCP" - x_02 = 2 - x_03 = 1Gi -} -``` - -The compiler throws an error when the value of a property does not conform to the union type definition: - -```python -# Literal union types -schema LiteralType: - # String literal union types, x_01 can be one of "TCP" and "UDP" - x_01: "TCP" | "UDP" - -x = LiteralType { - x_01 = "HTTP" # Error: the type got is inconsistent with the type expected, expect str(TCP)|str(UDP), got str(HTTP) -} -``` - -- Any Type - -```python -# Any type -schema Config: - literalConf: any = 1 - dictConf: {str:any} = {key = "value"} - listConf: [any] = [1, "2", True] - -config = Config {} -``` - -In KCL, changing the type of a variable is not allowed. If the type is not satisfied when reassigning the value, the type error will be raised. - -```python -_a = 1 # The type of `_a` is `int` -_a = "s" # Error: expect int, got str(s) -``` - -The type of a variable can be assigned to its upper bound type, but cannot be assigned to its specialized type. - -`None` and `Undefined` can be assigned to any type: - -- All types can be assigned to `any` type, `None` and `Undefined` can be assigned to `any` type. - -```python -a: int = None -b: str = Undefined -c: any = 1 -d: any = "s" -e: any = None -``` - -- The `int` type can be assigned to the `float` type, and the `float` type cannot be assigned to the `int` type. - -```python -a: float = 1 -b: int = 1.0 # Error: expect int, got float(1.0) -``` - -- The `int` type can be assigned to the `int|str` type, and the `int|str` type cannot be assigned to the `int` type. - -```python -a: int | str = 1 -b: int = 1 if a else "s" # Error: expect int, got int(1)|str(s) -``` - -Note that although the any type is provided in the KCl, it is still a static type, and the types of all variables are immutable during compilation. - -#### Type Inference - -If a variable or constant declaration in the top level or in the schema is not annotated explicitly with a type, the declaration's type is inferred from the initial value. - -- Integer literals are inferred to type `int`. - -```python -a = 1 # The variable `a` has the type `int` -``` - -- Float literals are inferred to type `float`. - -```python -a = 1.0 # The variable `a` has the type `float` -``` - -- String literals are inferred to type `str`. - -```python -a = "s" # The variable `a` has the type `str` -``` - -- Boolean literals are inferred to type `bool` - -```python -a = True # The variable `a` has the type `bool` -b = False # The variable `b` has the type `bool` -``` - -- `None` and `Undefined` are inferred to type `any` - -```python -a = None # The variable `a` has the type `any` -b = Undefined # The variable `b` has the type `any` -``` - -- List literals are inferred based on the elements of the literal, and to be variable-size. - -```python -a = [1, 2, 3] # The variable `a` has the type `[int]` -b = [1, 2, True] # The variable `b` has the list union type `[int|bool]` -c = ["s", 1] # The variable `c` has the list union type `[int|str]` -``` - -Please note that a empty list will be inferred to `[any]` - -```python -a = [] # The variable `a` has the type `[any]` -``` - -- Dict literals are inferred based on the keys and values of the literal, and to be variable-size. - -```python -a = {key = "value"} # The variable `a` has the type `{str:str}` -b = {key = 1} # The variable `b` has the type `{str:int}` -c = {key1 = 1, key2 = "s"} # The variable `c` has the type `{str:int|str}` -``` - -Please note that a empty dict will be inferred to `{any:any}` - -```python -a = {} # The variable `a` has the type `{any:any}` -``` - -- The type of the if conditional expression carrying the runtime value will be statically inferred as a union type of all possible results. - -```python -a: bool = True # The variable `a` has the type `bool` -b = 1 if a else "s" # The variable `b` has the type `int|str` -``` - -When a variable is deduced to a certain type, its type cannot be changed - -```python -_a = 1 -_a = "s" # Error: expect int, got str(1) -``` - -#### Type Alias - -We can use the `type` keyword to declare a type alias for all types in KCL to simplify the writing and use of complex types. - -```python -type Int = int -type String = str -type StringOrInt = String | Int -type IntList = [int] -type StringAnyDict = {str:} -``` - -We can import a type through import and define an alias for it. - -```py -import pkg - -type Data = pkg.Data -``` - -In addition, we can use type aliases and union types to achieve similar enumeration functions. - -```python -# A type alias of string literal union types -type Color = "Red" | "Yellow" | "Blue" - -schema Config: - color: Color = "Red" # The type of color is `"Red" | "Yellow" | "Blue"`, and it has an alias `Color`, whose default value is `"Red"` - -config = Config { - color = "Blue" -} -``` - -The output YAML is - -```yaml -config: - color: Blue -``` - -Please note that the type alias name cannot be one of `any`, `int`, `float`, `bool` and `str` because of ambiguity. - -```python -type any = int | str # Error -type int = str # Error -type float = int # Error -type bool = True # Error -type str = "A" | "B" | "C" # Error -``` - -#### Type Guards - -KCL supports the `typeof` function which can give very basic information about the type of values we have at runtime. In KCL, checking against the value returned by `typeof` is a type guard. KCL expects this to return a certain set of strings: - -Example: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person {} -t3 = typeof(_x1) - -_x2 = pkg.Person {} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# Output -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -In addition, we can use the `as` keyword in conjunction with type guards to complete defensive type conversion programming. - -Only types with partial order can be downcast converted, the use of the as keyword is as follows: - -- Basic types of partial order relations, e.g., `float -> int` -- Partial order relation of union type, e.g., `int | str -> str` and `[int | str] -> [str]` -- Contains the partial order relation of the upper bound of the type, e.g., `any -> int` -- Partial order relationship of structure type, e.g., `base-schema -> sub-schema` - -```python -schema Data1: - id?: int - -schema Data2: - name?: str - -data: Data1 | Data2 = Data1 {} - -if typeof(a) == "Data1": - data1 = data as Data1 # The type of `data1` is `Data1` -elif typeof(a) == "Data2": - data2 = data as Data2 # The type of `data2` is `Data2` -``` - -When a runtime error occurs in the `as` type conversion, a runtime error is thrown. - -```python -a: any = "s" -b: int = a as int # Error: The `str` type cannot be converted to the `int` type -``` - -If we don’t want to throw a runtime error, we can use the type guard for defensive coding with `if` expressions. - -```python -a: any = "s" -b = a as int if typeof(a) == "int" else None # The type of b is `int` -``` - -Note that the `as` conversion of literal type and union type is not supported, because they are not a certain runtime object, only int, float and other objects at runtime, there is no int literal, float literal object, and no union object. - -### Schema - -#### Overview - -A schema is a language element to define a complex configuration. -We can define typed attributes, initialization assignment, and verification rules. In addition, KCL supports schema single inheritance, mixin and protocol to realize the reuse of complex configuration. - -#### Basic - -##### Attribute - -The followings are some basic examples: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 -``` - -In KCL, we can use type annotations to define some attributes in the schema, each attribute can be set with an optional default value (such as the `age` attribute in the above code, its default value is `0`), attributes that are not set default values have an initial value of `Undefined`, which are not output in YAML. - -Note, the immutability of attributes in the schema follows the same rules as the immutability of global variables, only mutable attributes in the schema can be modified in the schema. - -```python -schema Person: - age: int = 1 # Immutable attribute - _name: str = "Alice" # Mutable attribute - - age = 10 # Error - _name = "Bob" # Ok -``` - -###### Optional Attribute - -Each attribute **must** be assigned with a not `None`/`Undefined` value as a schema instance unless it is modified by a question mark as an optional attribute. - -Examples: - -```python -schema Employee: - bankCard: int # bankCard is a required attribute, and it can NOT be None or Undefined - nationality?: str # nationality is an optional attribute, and it can be None or Undefined - -employee = Employee { - bankCard = None # Error, attribute 'bankCard' of Employee is required and can't be None or Undefined - nationality = None # Ok -} -``` - -##### Irrelevant Order Calculation - -The irrelevant order calculation in the schema indicates the reference relationship between the internal attributes of the schema. For example, when we declare an expression of the form `a = b + 1`, the calculation of the value of `a` depends on the calculation of the value of `b`. When the compiler calculate the value of `a` and the value of `a` depends on the value of `b`, the compiler will choose to first calculate the value of `b`, and then calculate the value of a according to the expression `a = b + 1`, which is slightly different from the calculation method of traditional procedural language the difference. - -Since the calculation of values in the schema is based on dependencies, just like a directed acyclic graph traverses each node in the graph according to the order of topological sorting, the order of declaration of attributes in the schema is not so important, so the feature is called the irrelevant order calculation. - -Please note that there can be no circular references between different schema attribute values. - -We can see this feature through the following examples. - -```python -schema Fib: - n1: int = n - 1 # Refers to the attribute `n` declared after `n1` - n2: int = n1 - 1 - n: int - value: int = 1 if n <= 2 else Fib {n = n1}.value + Fib {n = n2}.value - -fib8 = Fib {n = 8}.value -``` - -The output is - -```yaml -fib8: 21 -``` - -We can see that in the schema, we only need to simply specify the dependency between attributes, and the compiler will automatically calculate the value based on the dependency, which can help us save a lot of boilerplate code and reduce configuration difficulty of writing. - -##### Schema Context - -We can define the context of the schema to manage the attributes of the schema, and we can write schema parameters, temporary variables and expressions directly in the schema: - -```python -schema Person[_name: str]: # define a schema argument - name: str = _name # define a schema attribute - age: int = 10 # define a schema attribute with default value - hands: [int] = [i for i in [1, 2, 3]] # define a for statement -``` - -##### Validation - -In addition to using **static typing** (the type annotation) and **immutability** in KCL schema mentioned earlier to ensure code stability, a bunch of validation rules are supported in a simple **check** block (KCL supports almost all authentication capabilities of [OpenAPI](https://www.openapis.org/)): - -```python -import regex - -schema Sample: - foo: str - bar: int - fooList: [str] - - check: - bar > 0 # minimum, also support the exclusive case - bar < 100 # maximum, also support the exclusive case - len(fooList) > 0 # min length, also support exclusive case - len(fooList) < 100 # max length, also support exclusive case - regex.match(foo, "^The.*Foo$") # regex match - isunique(fooList) # unique - bar in range(100) # range - bar in [2, 4, 6, 8] # enum - multiplyof(bar, 2) # multipleOf -``` - -With the schema, all instances will be validated at compile time - -```python -# Ok -goodSample = Sample { - foo = "The Foo" - bar = 2 - fooList = ["foo0", "foo1"] -} - -# Error: validation failure: Check failed on check conditions: bar < 100. -badSample = Sample { - foo = "The Foo" - bar = 123 - fooList = ["foo0", "foo1"] -} -``` - -In addition, we can use **and**, **or**, **if** to compose more complex conditional check logic: - -```python -schema Sample: - bar: int - foo: str - doCheck: bool - - check: - regex.match(foo, "^The.*Foo$") and bar in [2, 4, 6, 8] if doCheck -``` - -In order to ensure that all check rules can play their corresponding roles well, we can test the rationality and correctness of different data combinations by writing KCL test cases, and run all test cases through the kcl test tool. - -##### Documents - -Usually after we write the schema model, we will write documentation comments for the schema, which can be completed by using a three-quoted string as follows: - -```python -schema Server: - """Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - - Attributes - ---------- - workloadType : str, default is Deployment - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - name : str, default is None - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - labels : {str:str}, optional, default is None - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - - Examples - ---------------------- - myCustomApp = AppConfiguration { - name = "componentName" - } - """ - workloadType: str = "Deployment" - name: str - labels?: {str:str} -``` - -##### Config - -Suppose we have the following schema definition: - -```python -schema Person: - firstName: str - lastName: str -``` - -A config could be defined with a JSON-like expression: - -```python -person = Person { - firstName = "firstName" - lastName = "lastName" -} -``` - -At the same time, the schema adheres to strict attribute definitions, -and configuring undefined attributes will trigger a compilation error. - -```python -person = Person { - firstName = "firstName" - lastName = "lastName" - fullName = "fullName" # Error: Cannot add member 'fullName' to schema 'Person', 'fullName' is not defined in schema 'Person' -} -``` - -We can use `if expressions` to dynamically add elements to the schema config, elements that meet the conditions are added to the schema config, and elements that do not meet the conditions are ignored. Besides, the **config selector expressions** can be used to init a schema instance. - -```python -schema Base: - count: int - value: str - -schema Person: - base: Base - labels: {str:str} - name?: str - -env = "prod" - -person1 = Person { - base.count = 2 # Config selector expression - base.value = "value" # A schema variable in schema can use selector expressions - labels.key = "value" # A dict variable in schema can use selector expressions -} - -person2 = Person { - base = { - count = 1 - value = "value" - } - labels.key = "value" - if env == "prod": - labels.env = env - else: - labels.env = "other" -} -``` - -The output YAML is - -```yaml -person1: - base: - count: 2 - value: value - labels: - key: value -person2: - base: - count: 1 - value: value - labels: - key: value - env: prod -``` - -When we instantiate a schema without config parameters, we can generate schema instances in the following three forms: - -```python -schema Data: - id: int = 1 - -data1 = Data {} -data2 = Data() {} -data3 = Data() -``` - -In addition to using a schema type to instantiate a schema, we can also use a schema instance to get a new instance using the config expression. - -```python -schema Config: - id: int - values: [int] - -configOrigin = Config { - id = 1 - values = [0, 1] -} -configNew = configOrigin { - id = 2 - values += [2, 3] -} -``` - -The output is - -```yaml -configOrigin: - id: 1 - values: - - 0 - - 1 -configNew: - id: 2 - values: - - 0 - - 1 - - 2 - - 3 -``` - -In addition, schema attribute default values can be modified by schema config. - -```python -schema Person: - age: int = 1 - name: str = "Alice" - - age = 2 # Error, can't change the default value of the attribute `age` in the schema context - -person = Person { - age = 3 # Ok, can change the default value of the attribute `age` in the schema config -} -``` - -#### Advanced - -##### Protocol & Mixin - -In addition to schema, an additional type definition method `protocol` is provided in KCL, and its properties are as follows: - -- In a protocol, only attributes and their types can be defined, complex logic and check expressions cannot be written, and mixins cannot be used. -- A protocol can only constrain properties that do not start with `_`. -- A protocol can only inherit or refer to other protocols, but cannot inherit or refer to other schemas. - -Besides, we can declare a complex assembly schema with optional **mixin** support and use **protocol** to add an optional host type to the dynamically inserted **mixin**.: - -```python -schema Person: - mixin [FullNameMixin] - - firstName: str # Required - lastName: str # Required - fullName?: str # Optional -``` - -A fullName mixin which generates a fullName as a simple sample: - -```python -protocol PersonProtocol: - firstName: str - lastName: str - fullName?: str - -mixin FullNameMixin for PersonProtocol: - fullName = "{} {}".format(firstName, lastName) -``` - -Then we can get the schema instance by: - -```python -person = Person { - firstName = "John" - lastName = "Doe" -} -``` - -The output is - -```yaml -person: - firstName: John - lastName: Doe - fullName: John Doe -``` - -Please note that the host type **protocol** can only be used for **mixin** definitions (the suffix name is `Mixin`), otherwise an error will be reported. - -```python -protocol DataProtocol: - data: str - -schema Data for DataProtocol: # Error: only schema mixin can inherit from protocol - x: str = data -``` - -##### Index Signature - -Index signatures can be defined in the KCL schema, and it means that the key-value constraints of the index signature can be used to construct a dict with the schema type, or additional checks can be added to the schema attributes to enhance the KCL type and semantic checks. - -- Use the form `[{attr_alias}: {key_type}]: {value_type}` to define an index signature in the schema, and `{attr_alias}` can be omitted. - -```python -schema Map: - """ - Map is a schema with a key of str type and a value of str type - """ - [str]: str # `{attr_alias}` can be omitted. - -data = Map { - key1 = "value1" - key2 = "value2" -} -``` - -- Mandatory all attributes of the schema key and value types - -```python -schema Person: - name: str - age: int # error, conflicts with the index signature definition `[str]: str` - [str]: str # The values of all attributes of the schema can only be strings -``` - -- Mandatory all attribute key and value types are defined in the schema, which is equivalent to restricting all attribute types except the additional attributes. - -```python -schema Person: - name: str - age: int - [...str]: str # Except for the `name` and `age` attributes, the key type of all other attributes of the schema must be `str`, and the value type must also be `str`. -``` - -- Define the index signature attribute alias and use it with the check block. - -```python -schema Data: - [dataName: str]: str - check: - dataName in ["Alice", "Bob", "John"] - -data = Data { - Alice = "10" - Bob = "12" - Jonn = "8" # Error: Jonn not in ["Alice", "Bob", "John"] -} -``` - -```python -import regex - -schema DataMap: - [attr: str]: str - check: - regex.match(attr, r'^[-._a-zA-Z0-9]+$') - -data = DataMap { - key1 = "value1" - "foo.bar" = "value2" # check error -} -``` - -##### Inheritance - -Like some other object-oriented languages, KCL provides fundamental but limited object-oriented support, such as **attribute reuse**, **private and public variables**, and **single inheritance**. Besides, KCL does NOT support multiple inheritances for the schema. - -The following is an example of schema inheritance: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 - -# An employee **is** a person, and has some additional information. -schema Employee(Person): - bankCard: int - nationality?: str - -employee = Employee { - firstName = "Bob" - lastName = "Green" - age = 18 - bankCard = 123456 -} -``` - -The output is - -```yaml -employee: - firstName: Bob - lastName: Green - age: 18 - bankCard: 123456 - nationality: null -``` - -Please note that KCL only allows **single inheritance** on schemas. - -In addition, when the schema has an inheritance relationship, the properties of optional attributes are as follows: - -- If the attribute is optional in the base schema, it could be optional or required in the sub-schema. -- If the attribute is required in the base schema, it must be required in the sub-schema. - -```python -schema Person: - bankCard?: int - nationality: str - -schema Employee(Person): - bankCard: int # Valid, both `bankCard: int` and `bankCard?: int` are allowed - nationality?: str # Error, only `nationality: str` is allowed -``` - -##### Schema Function - -Schema map very nicely onto functions; it can have any number of input and output parameters. For example, the Fibonacci function can be written as follows using the recursive schema config: - -```python -schema Fib[n: int]: - n1 = n - 1 - n2 = n - 2 - if n == 0: - value = 0 - elif n == 1: - value = 1 - else: - value = Fib(n1).value + Fib(n2).value - -fib8 = Fib(8).value # 21 -``` - -##### Decorators - -Just like Python, KCL supports the use of decorators on the schema. KCL Decorators dynamically alter the functionality of a schema without having to directly use sub schema or change the source code of the schema being decorated. And like a function call, the decorator supports passing in additional parameters. - -Built-in decorators of schema - -- `@deprecated` - Mark whether a schema or schema attribute is deprecated. The `@deprecated` decorator supports three parameters: - - **version** - string type, indicating the version information. The default value is empty. - - **reason** - string type, indicating the deprecated reason. The default value is empty. - - **strict** - bool type, indicating whether to report an error or warning. The default value is true. If `strict` is `True` and the error is thrown, the program will be interrupted. If `strict` is `False`, a warning will be output and the program will not be interrupted. - -Examples: - -```python -@deprecated -schema ObsoleteSchema: - attr: str - -schema Person: - name: str = "John" - attrs: ObsoleteSchema = { - attr = "value" - } - -person = Person {} # Error: ObsoleteSchema was deprecated -``` - -```python -schema Person: - firstName: str = "John" - lastName: str - @deprecated(version="1.16", reason="use firstName and lastName instead", strict=True) - name: str - -JohnDoe = Person { # Error: name was deprecated since version 1.16, use firstName and lastName instead - name = "deprecated" -} -``` - -Note that the current version of KCL does not yet support user-defined decorators. - -##### Members - -Built-in functions and members of schema - -- instances() - Return the list of existing instances of a schema. - -```python -schema Person: - name: str - age: int - -alice = Person { - name = "Alice" - age = 18 -} - -bob = Person { - name = "Bob" - age = 10 -} - -aliceAndBob = Person.instances() # Person is a schema type, instances() is its member method -``` - -The output is - -```yaml -alice: - name: Alice - age: 18 -bob: - name: Bob - age: 10 -aliceAndBob: - - name: Alice - age: 18 - - name: Bob - age: 10 -``` - -### Config Operations - -#### Config Unification - -##### | Operators - -In KCL, we can use the union operator `|` to achieve the merging of configurations, the types supported by the union operator are as follows: - -```txt -SchemaInstance | SchemaInstance -SchemaInstance | Dict -Dict | Dict -List | List -``` - -Unioning collection and schema data: - -- Unioning List. Overwrite the list expression on the right side of the operator `|` to the list variable on the left side of the operator one by one according to the **index**. - -```python -_a = [1, 2, 3] -_b = [4, 5, 6, 7] -x = _a | _b # [4, 5, 6, 7] 1 -> 4; 2 -> 5; 3 -> 6; Undefined -> 7 -``` - -Unioning to the specific index or all elements is still under discussion. - -- Unioning Dict. Union the dict expression on the right side of the operator `|` one by one to the dict variable on the left side of the operator according to the **key** - -```python -_a = {key1 = "value1"} -_b = {key1 = "overwrite", key2 = "value2"} -x = _a | _b # {"key1": "overwrite", "key2": "value2"} -``` - -The union of collection and schema is a new one whose attributes are unioning b to a, preserving the order of the attributes of the operands, left before right. - -- Unioning Schema. The union operation for schema is similar to dict. - -Schema union could be done as: - -```python -schema Person: - firstName?: str - lastName?: str - -_a = Person { - firstName = "John" -} -_b = {lastName = "Doe"} -_c = _a | _b # {"firstName": "John", "lastName": "Doe"} -_d = _a | None # {"firstName": "John"} -_e = _a | Undefined # {"firstName": "John"} -_f = None | _a # {"firstName": "John"} -_g = Undefined | _a # {"firstName": "John"} -``` - -Please note that when one of the left and right operands of the union operator is None, the other operand is returned immediately. - -```python -data1 = {key = "value"} | None # {"key": "value"} -data2 = None | [1, 2, 3] # [1, 2, 3] -data3 = None | None # None -``` - -The output is - -```yaml -data1: - key: value -data2: - - 1 - - 2 - - 3 -data3: null -``` - -##### : Operators - -Pattern: `identifier : E` or `identifier : T E` - -The value of the expression `E` with optional type annotation `T` will be unioned into the element value. - -Examples: - -```python -data = { - labels: {key1: "value1"} - # union {key2: "value2"} into the attribute labels. - labels: {key2: "value2"} -} -``` - -Output: - -```yaml -data: - labels: - key1: value1 - key2: value2 -``` - -In addition to using attribute operators on the schema config attributes, variables inside and outside the schema can use attribute operators to perform different operations on the configuration. - -- Using `:` outside the schema - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - data: Data - -# This is one configuration that will be merged. -config: Config { - data.d1 = 1 -} -# This is another configuration that will be merged. -config: Config { - data.d2 = 2 -} -``` - -Its equivalent configuration code can be expressed as - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - data: Data - -config: Config { - data.d1 = 1 - data.d2 = 1 -} -``` - -The output is - -```yaml -config: - data: - d1: 1 - d2: 1 -``` - -- Using `:` inside the schema - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - # This is one configuration that will be merged. - data: Data { - d1 = 1 - } - # This is another configuration that will be merged. - data: Data { - d2 = 1 - } - -config: Config {} -``` - -#### Config Override - -##### = Operators - -Pattern: `identifier = E` or `identifier : T = E` - -The value of the expression `E` with optional type annotation `T` will override the attribute value. - -Examples: - -```python -schema Data: - labels: {str:} = {key1 = "value1"} - -data = Data { - # override {key2: "value2"} into the attribute labels of the schema Data. - labels = {key2 = "value2"} -} -``` - -Output: - -```yaml -data: - labels: - key2: value2 -``` - -Note: - -- Especially, we can "delete" its content by overriding the attribute to `Undefined`, such as `{ a = Undefined }`. - -#### Insert - -##### += Operators - -Pattern: `identifier += E` or `identifier : T += E` - -Insert only works for list type `identifier`. - -`E` will be inserted just after the specified index of the list `identifier`, and the following attributes after the index will be automatically shifted. - -Examples: - -```python -schema Data: - labels: {str:} = {key1 = [0]} - -data = Data { - # insert [1] into the attribute labels.key1 of the schema Data. - labels: {key1 += [1]} -} -``` - -Output: - -```yaml -data: - labels: - key1: - - 0 - - 1 -``` - -If no index is specified, the last index will be used. - -#### Notice - -Please note that the calculations of the `=` and `+=` attribute operators of the same attribute are sequential, and the latter ones have a higher priority. - -```python -x = { - a = 1 # 1 -} | { - a = 2 # 1 -> 2 -} | { - a = 3 # 2 -> 3 -} # The final value of attribute `a` is 3 -``` - -Please note that the `:` attribute operator represents an idempotent merge operation, and an error will be thrown when the values that need to be merged conflict. - -Therefore, when we need a configuration to override or add and delete operations, it is best to use the `=` and `+=` operators - -```python -data0 = {id: 1} | {id: 2} # Error:conflicting values between {'id': 2} and {'id': 1} -data1 = {id: 1} | {id = 2} # Ok, the value of `data` is {"id": 2} -``` - -The check rules for `:` operator for KCL value conflicts are as follows: - -- For `None` and `Undefined` variables, they do not conflict with any value. - -```python -data0 = None | {id: 1} # Ok -``` - -- For `int`, `float`, `str` and `bool` types, when their values are different, they are considered as conflicts. - -```python -data0 = 1 | 1 # Ok -data1 = 1 | "s" # Error -``` - -- For list type - - When their lengths are not equal, they are regarded as conflicts. - - When their lengths are equal, as long as there is a conflict in the value of a child element, it is regarded as a conflict. - -```python -data0 = [1] | [1] # Ok -data1 = [1, 2] | [1] # Error -``` - -- For dict/schema type - - When the values of the same key conflict, they are regarded as conflicts - -```python -data0 = {id: 1} | {id: 1} # Ok -data1 = {id: 1} | {id: 2} # Error -data1 = {id: 1} | {idAnother: 1} # Ok -``` - -### Rule - -In addition to using the check keyword for verification and writing in the schema, KCL also supports the use of the `rule` keyword to define a set of rules for policy verification - -The KCL rule is the same as the schema/mixin/protocol and it is defined by indentation. We need write a rule per line and we can write if filter conditions and verification failure information for each rule. Different conditions are connected with logic `and` (similar to the way of writing in check block). - -```python -rule SomeRule: - age > 0, "rule check failure message" -``` - -We can call a KCL rule like instantiating a schema: - -```python -age = 1 -name = "Alice" - -rule SomeRule: - age > 0, "rule check failure message" - name == "Alice" - -rule1 = SomeRule() # Rule call -rule2 = SomeRule {} # Rule call -``` - -We can use protocol to implement type checking of rule structure: - -```python -# Schema definition -protocol Service: - clusterIp: str - $type: str - -# Schema definition -protocol Volume: - mountPath: [str] - -# Protocol -protocol SomeProtocol: - id: int - env: {str: any} - services: [Service] - volumes: [Volume] - -rule SomeChecker for SomeProtocol: - id > 0, "id must >0" - - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - } - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } - -# Call rule to check with config parameter -SomeChecker { - id = 1 - env = { - MY_ENV = "MY_ENV_VALUE" - } - services = [ - { - type = "ClusterIP" - clusterIP = "NONE" - } - ] - volumes = [ - { - mountPath = "/home/admin" - } - { - mountPath = "/home/myapp" - } - ] -} -``` - -Please note that the combination of `protocol` and `rule` can separate attributes from their constraint definitions. We can define different rules and protocols in different packages and combine them as needed. This is different from check expressions in schema, which can only be combined with schema attributes. - -Besides, the following two ways can be used to achieve the multiplexing of different Rules: - -- Inline Call - -```python -weather = "sunny" -day = "wednesday" - -rule IsSunny: - weather == "sunny" - -rule IsWednesday: - day == "wednesday" - -rule Main: - IsSunny() # Rule inline call - IsWednesday() # Rule inline call - -Main() # Rule call -``` - -- Inherit - -```python -weather = "sunny" -day = "wednesday" - -rule IsSunny: - weather == "sunny" - -rule IsWednesday: - day == "wednesday" - -rule Main(IsSunny, IsWednesday): - id == 1 - -Main() -``` - -We can obtain external data or input from the `option` function and the CLI parameter `-D` for verification: - -- A simple example - -```python -schema Day: - day: str - homework: str - -days: [Day] = option("days") - -rule Main: - filter d in days { - d.day not in ["saturday", "sunday"] and d.homework - } - -Main() -``` - -- A complex example - -```python -data = option("data") -input = option("input") - -rule Allow: - UserIsAdmin() - any grant in UserIsGranted() { - input.action == grant.action and input.type == grant.type - } - -rule UserIsAdmin: - any user in data.user_roles[input.user] { - user == "admin" - } - -rule UserIsGranted: - [ - grant - for role in data.user_roles[input.user] - for grant in data.role_grants[role] - ] - -allow = Allow() or False -``` - -Further, the above KCL rule code can be compiled into a target such as WASM and used at runtime. - -### Module - -KCL config files are organized as **modules**. A single KCL file is considered as a module, and a directory is considered as a package, which is a special module. - -The modules in the same package are visible and cross-package references need to be visible through import. - -Code structure: - -```bash -. -└── root - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -model1.k: - -```python -# schema CatalogItem in model1.k - -schema CatalogItem: - id: int - image: CatalogItemImage # CatalogItemImage is defined in the module of the same package e.g., model2.k in package model - title: str -``` - -service1.k: - -```python -import ..model as model # cross-package references - -schema ImageService: - image: model.CatalogItemImage # CatalogItemImage is imported from another package e.g., model2.k in package model - name: str -``` - -#### Relative Path Import - -We can use the operator `.` to realize the relative path import of KCL entry files. - -main.k: - -```python -import .model1 # Current directory module -import ..service # Parent directory -import ...root # Parent of parent directory - -s = service.ImageService {} -m = root.Schema {} -``` - -#### Absolute Path Import - -The semantics of `import a.b.c.d` is - -1. If `kcl.mod` not exist, regard the current directory as the package root and search the path `a/b/c/d` from the current directory. -2. If the current directory search fails, search from the root path `ROOT_PATH/a/b/c/d`, else raise an import error. - -The definition of the root path `ROOT_PATH` is the directory corresponding to the `kcl.mod` file from the current directory. - -Code structure: - -```bash -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -main.k: - -```python -import service # `root package` and `kcl.mod` are in the same directory -import mixin # `root package` and `kcl.mod` are in the same directory - -myModel = model.CatalogItem {} -``` - -Note that for the KCL entry file `main.k`, it cannot be imported into the folder where it is located, otherwise a recursive import error will occur: - -```python -import model # Error: recursively loading -``` - -### Top-Level Argument - -Assume some field need to be passed in dynamically like user input, we can define a top-level argument in a module: - -```python -bankCard = option("bankCard") # Get bankCard through the option function. -``` - -Then we can use the module as below: - -```bash -kcl employee.k -D bankCard=123 -``` - -Currently, supported types of top-level argument are number, string, bool, list and dict. - -```bash -kcl main.k -D list_key='[1,2,3]' -D dict_key='{"key":"value"}' -``` - -We need to pay attention to the escape of quotation marks `"` and other symbols in the command line - -#### Arguments with Setting Files - -In addition, it also supports inputting a YAML file as top-level arguments. - -```yaml -kcl_options: - - key: key_number - value: 1 - - key: key_dict - value: - innerDictKey: innerDictValue - - key: key_list - value: - - 1 - - 2 - - 3 - - key: bankCard - value: 123 -``` - -```bash -kcl -Y setting.yaml employee.k -``` - -In addition, the setting file also supports configuring command-line compilation parameters as follows: - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - disable_none: true - strict_range_check: true - debug: 1 - verbose: 1 - output: ./stdout.golden -kcl_options: - - key: image - value: docker.io/kcllang/kcl:latest -``` - -KCL CLI -Y parameters also support multi-file configuration, and support separate writing and merging of compilation parameters and option top level arguments parameter configuration. - -```bash -kcl -Y compile_setting.yaml option_setting.yaml -``` - -- `compile_setting.yaml` - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - disable_none: true - strict_range_check: true - debug: 1 - verbose: 1 - output: ./stdout.golden -``` - -- `option_setting.yaml` - -```yaml -kcl_options: - - key: image - value: docker.io/kcllang/kcl:latest -``` - -We can use the following command line to get the meaning of each configuration parameter or see KCL Quick Start - -```bash -kcl --help -``` - -#### Option Functions - -We can use the `option` function in the KCL code to get the top-level arguments. - -```python -value = option(key="key", type='str', default="default_value", required=True, help="Set key value") -``` - -Parameters - -- **key**: The argument key. -- **type**: The argument type to be converted. -- **default**: The argument default value when the key-value argument is not provided -- **required**: Report an error when the key-value argument is not provided and required is True. -- **help**: The help message. - -### Multi-file Compilation - -In addition to the above KCL single file execution, we can compile multiple KCL entry files at the same time using the following command: - -```bash -kcl main_1.k main_2.k ... main_n.k -``` - -main_1.k - -```python -a = 1 -b = 2 -``` - -main_2.k - -```python -c = 3 -d = 4 -``` - -The output is: - -```yaml -a: 1 -b: 2 -c: 3 -d: 4 -``` - -Taking advantage of the **multi-file combination**, we can assemble multiple KCL files without the need to use import management files. Let us see an example of combining **multi-file compilation** and **schema instance**. - -model.k - -```python -schema Model: - name: str - labels?: {str:} - annotations?: {str:} - replicas: int - -_model1 = Model { - name = "model1" - labels.key1 = "value1" - labels.key2 = "value2" - annotations.key = "value" - replicas = 2 -} - -_model2 = Model { - name = "model2" - replicas = 3 -} -``` - -backend.k - -```python -import yaml - -schema Backend: - apiVersion: str = "v1" - kind: str = "Deployment" - metadata: {str:} - spec: {str:} = { - minReadySeconds = 0 - paused = False - progressDeadlineSeconds = 600 - replicas = 1 - revisionHistoryLimit = 10 - selector = {} - } - -_backends = [Backend { - metadata.name = model.name - metadata.labels = model.labels - metadata.annotations = model.annotations - spec.selector.matchLabels: model.labels - spec.replicas = model.replicas -} for model in Model.instances()] # Schema Model is defined in model.k -print("---\n".join([yaml.encode(_b, ignore_private=True) for _b in _backends])) -``` - -The command is - -```bash -kcl model.k backend.k -``` - -The output is - -```yaml -apiVersion: v1 -kind: Deployment -metadata: - name: model1 - labels: - key1: value1 - key2: value2 - annotations: - key: value -spec: - minReadySeconds: 0 - paused: false - progressDeadlineSeconds: 600 - replicas: 2 - revisionHistoryLimit: 10 - selector: - matchLabels: - key1: value1 - key2: value2 ---- -apiVersion: v1 -kind: Deployment -metadata: - name: model2 -spec: - minReadySeconds: 0 - paused: false - progressDeadlineSeconds: 600 - replicas: 3 - revisionHistoryLimit: 10 - selector: {} -``` - -### KCL CLI Path Selector - -We can use KCL CLI `-S|--path-selector` parameter to select one or more values out of a KCL model. - -The path selector looks like this: - -`var.name` - -#### Examples - -Code structure: - -```bash -. -├── kcl.mod -└── main.k - └── pkg - └── model.k -``` - -pkg/model.k: - -```python -schema Person: - name: str - age: int - -var = Person { - name = "Alice" - age = 18 -} -``` - -main.k - -```python -import pkg - -var = pkg.Person { - name = "Bob" - age = 10 -} -``` - -The command is - -```bash -kcl main.k -S var -``` - -The output is - -```yaml -name: Alice -age: 18 -``` - -### KCL CLI Variable Override - -In addition to **Variable Selector**, KCL also allows us to directly modify the values in the configuration model through the KCL CLI `-O|--overrides` parameter. - -The use of **Variable Override** is similar to [**Variable Selector**](#variable-selector), and the parameter contains three parts e.g., `pkg`, `identifier`, `attribute` and `override_value`. - -```bash -kcl main.k -O override_spec -``` - -- `override_spec` represents a unified representation of the configuration model fields and values that need to be modified - -```txt -override_spec: [[pkgpath] ":"] identifier ("=" value | "-") -``` - -- `pkgpath`: Indicates the path of the package whose identifier needs to be modified, usually in the form of `a.b.c`. For the main package, `pkgpath` is expressed as `__main__`, which can be omitted. If omitted, it means the main package. -- `identifier`: Indicates the identifier that needs to modify the configuration, usually in the form of `a.b.c`. -- `value`: Indicates the value of the configuration that needs to be modified, which can be any legal KCL expression, such as number/string literal value, list/dict/schema expression, etc. -- `=`: means to modify the value of identifier. - - When the identifier exists, modify the value of the existing identifier to value. - - When identifier does not exist, add the identifier attribute and set its value to value. -- `-`: means to delete the identifier attribute. - - When the identifier exists, delete it directly. - - When the identifier does not exist, no modification is made to the configuration. - -Note: When `identifier` appears multiple times, modify/delete all `identifier` values - -#### Examples - -##### Override Update Sample - -KCL code: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -``` - -The command is - -```bash -kcl main.k -O :person.name=\"Bob\" -O :person.age=10 -``` - -The output is - -```yaml -person: - name: Bob - age: 10 -``` - -Besides, when we use KCL CLI `-d` argument, the KCL file will be modified to the following content at the same time - -```bash -kcl main.k -O :person.name=\"Bob\" -O :person.age=10 -d -``` - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Bob" - age = 10 -} -``` - -Another more complicated example: - -```python -schema Person: - name: str - age: int - ids?: [int] - -person = Person { - name = "Alice" - age = 10 -} -``` - -The command is - -```bash -kcl main.k -O :person.ids=\[1,2\] -``` - -The output is - -```yaml -person: - name: Alice - age: 10 - ids: - - 1 - - 2 -``` - -##### Override Delete Sample - -KCL code: - -```python -schema Config: - x?: int = 1 - y?: str = "s" - -config = Config { - x = 2 -} -``` - -The command is - -```bash -kcl main.k -O config.x- -``` - -The output is - -```yaml -config: - x: 1 - y: s -``` - -### Summary - -This page summarized the commonly used features in the KCL language. As a new language, KCL will gradually increase the functional features according to the requirements of the configuration scenario. - -For more information, please try further resources: - -- KCL codelabs -- KCL language specification -- KCL OpenAPI specification diff --git a/versioned_docs/version-0.5.0/reference/model/datetime.md b/versioned_docs/version-0.5.0/reference/model/datetime.md deleted file mode 100644 index 5b829890..00000000 --- a/versioned_docs/version-0.5.0/reference/model/datetime.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: "datetime" -linkTitle: "datetime" -type: "docs" -description: datetime system module -weight: 100 ---- - -## time - -`ticks() -> float` - -Return the current time in seconds since the Epoch. Fractions of a second may be present if the system clock provides them. - -## date - -`date() -> str` - -Return the `%Y-%m-%d %H:%M:%S` format date. - -## now - -`now() -> str` - -Return the local time. e.g. `'Sat Jun 06 16:26:11 1998'` - -## today - -`today() -> str` - -Return the `%Y-%m-%d %H:%M:%S.%{ticks}` format date. diff --git a/versioned_docs/version-0.5.0/reference/model/json.md b/versioned_docs/version-0.5.0/reference/model/json.md deleted file mode 100644 index 44ec8c73..00000000 --- a/versioned_docs/version-0.5.0/reference/model/json.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: "json" -linkTitle: "json" -type: "docs" -description: json system module -weight: 100 ---- - -## encode - -``` -encode( - data: any, - sort_keys: bool = False, - indent: int = None, - ignore_private: bool = False, - ignore_none: bool = False -) -> str -``` - -Serialize a KCL object `data` to a JSON formatted str. - -## decode - -`decode(value: str) -> any` - -Deserialize `value` (a string instance containing a JSON document) to a KCL object. - -## dump_to_file - -``` -dump_to_file( - data: any, - filename: str, - ignore_private: bool = False, - ignore_none: bool = False -) -> None -``` - -Serialize a KCL object `data` to a JSON formatted str and write it into the file `filename`. diff --git a/versioned_docs/version-0.5.0/reference/model/math.md b/versioned_docs/version-0.5.0/reference/model/math.md deleted file mode 100644 index dae369af..00000000 --- a/versioned_docs/version-0.5.0/reference/model/math.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: "math" -linkTitle: "math" -type: "docs" -description: math system module -weight: 100 ---- - -## ceil - -`ceil(x) -> int` - -Return the ceiling of `x` as an Integral. This is the smallest integer >= x. - -## factorial - -`factorial(x) -> int` - -Return `x!`. Raise a error if `x` is negative or non-integral. - -## floor - -`floor(x) -> int` - -Return the floor of `x` as an Integral. This is the largest integer <= x. - -## gcd - -`gcd(a: int, b: int) -> int` - -Return the greatest common divisor of `x` and `y` - -## isfinite - -`isfinite(x) -> bool` - -Return `True` if `x` is neither an infinity nor a `NaN`, and `False` otherwise. - -## isinf - -`isinf(x) -> bool` - -Return `True` if `x` is a positive or negative infinity, and `False` otherwise. - -## isnan - -`isnan(x) -> bool` - -Return `True` if `x` is a `NaN` (not a number), and `False` otherwise. - -## modf - -`modf(x) -> List[float, float]` - -Return the fractional and integer parts of `x`. Both results carry the sign of `x` and are floats. - -## exp - -`exp(x) -> float` - -Return `e` raised to the power of `x`. - -## expm1 - -`expm1(x) -> float` - -Return `exp(x) - 1`. This function avoids the loss of precision involved in the direct evaluation of `exp(x) - 1` for small `x`. - -## log - -`log(x, base=2.71828182845904523536028747135266250) -> float` - -Return the logarithm of `x` to the base `e`. - -## log1p - -`log1p(x) -> float` - -Return the natural logarithm of `1+x` (base `e`). The result is computed in a way which is accurate for `x` near zero. - -## log2 - -`log2(x) -> float` -Return the base 2 logarithm of `x`. - -## log10 - -`log10(x) -> float` - -Return the base 10 logarithm of `x`. - -## pow - -`pow(x, y) -> float` - -Return `x**y` (`x` to the power of `y`). - -## sqrt - -`sqrt(x) -> float` - -Return the square root of `x`. diff --git a/versioned_docs/version-0.5.0/reference/plugin/project_context.md b/versioned_docs/version-0.5.0/reference/plugin/project_context.md deleted file mode 100644 index 0be02e78..00000000 --- a/versioned_docs/version-0.5.0/reference/plugin/project_context.md +++ /dev/null @@ -1,59 +0,0 @@ -# project_context - -project_context extract base info from project.yaml&stack.yaml - -_version: 0.0.1_ - -## `get_project_current_path` - -return the relative path of first file - -Example: - -```py -import kcl_plugin.project_context as ctx - -path = ctx.get_project_current_path() -print(path) -``` - -## `get_project_input_file` - -return compiling file list - -Example: - -```py -import kcl_plugin.project_context as ctx - -input_file = ctx.get_project_input_file() -print(input_file) -``` - -## `get_project_context` - -return the current project context from project.yaml - -Example: - -```py -import kcl_plugin.project_context as ctx - -project = ctx.get_project_context() -# Get project name -print(project?.name) -``` - -## `get_stack_context` - -return the current stack context from stack.yaml - -Example: - -```py -import kcl_plugin.project_context as ctx - -stack = ctx.get_stack_context() -# Get stack name -print(stack?.name) -``` diff --git a/versioned_docs/version-0.5.0/reference/xlang-api/go-api.md b/versioned_docs/version-0.5.0/reference/xlang-api/go-api.md deleted file mode 100644 index 2a978250..00000000 --- a/versioned_docs/version-0.5.0/reference/xlang-api/go-api.md +++ /dev/null @@ -1,665 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Go API - -```go -import kcl "kcl-lang.io/kcl-go" -``` - -## KCL Go SDK - -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ kcl files │ │ KCL-Go-API │ │ KCLResultList │ -│ ┌───────────┐ │ │ │ │ │ -│ │ 1.k │ │ │ │ │ │ -│ └───────────┘ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ ┌───────────┐ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.Get("a.b.c") │ -│ │ 2.k │ │ │ │ Run(path) │ │ │ └───────────┘ │ └───────────────┘ -│ └───────────┘ │────┐ │ └───────────┘ │ │ │ -│ ┌───────────┐ │ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ │ 3.k │ │ │ │ │ │ │ KCLResult │──┼────────▶│x.Get("k", &v) │ -│ └───────────┘ │ │ │ │ │ └───────────┘ │ └───────────────┘ -│ ┌───────────┐ │ ├───▶│ ┌───────────┐ │──────────▶│ │ -│ │setting.yml│ │ │ │ │RunFiles() │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ └───────────┘ │ │ │ └───────────┘ │ │ │ KCLResult │──┼────────▶│x.JSONString() │ -└─────────────────┘ │ │ │ │ └───────────┘ │ └───────────────┘ - │ │ │ │ │ -┌─────────────────┐ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ Options │ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.YAMLString() │ -│WithOptions │ │ │ │MustRun() │ │ │ └───────────┘ │ └───────────────┘ -│WithOverrides │────┘ │ └───────────┘ │ │ │ -│WithWorkDir │ │ │ │ │ -│WithDisableNone │ │ │ │ │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ -``` - -
Example -

- -```go -{ - const k_code = ` -name = "kcl" -age = 1 - -two = 2 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {} -x1 = Person { - age = 101 -} -` - - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First().YAMLString() - fmt.Println(yaml) - - fmt.Println("----") - - result := kcl.MustRun("./testdata/main.k").First() - fmt.Println(result.JSONString()) - - fmt.Println("----") - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - - fmt.Println("----") - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x1", &person)) -} -``` - -

-
- -## Index - -- [Go API](#go-api) - - [KCL Go SDK](#kcl-go-sdk) - - [Index](#index) - - [Constants](#constants) - - [func FormatCode](#func-formatcode) - - [func FormatPath](#func-formatpath) - - [func InitKclvmPath](#func-initkclvmpath) - - [func InitKclvmRuntime](#func-initkclvmruntime) - - [func LintPath](#func-lintpath) - - [func ListDepFiles](#func-listdepfiles) - - [func ListDownStreamFiles](#func-listdownstreamfiles) - - [func ListUpStreamFiles](#func-listupstreamfiles) - - [func OverrideFile](#func-overridefile) - - [func ValidateCode](#func-validatecode) - - [type KCLResult](#type-kclresult) - - [type KCLResultList](#type-kclresultlist) - - [func MustRun](#func-mustrun) - - [func Run](#func-run) - - [func RunFiles](#func-runfiles) - - [type KclType](#type-kcltype) - - [func GetSchemaType](#func-getschematype) - - [type ListDepFilesOption](#type-listdepfilesoption) - - [type ListDepsOptions](#type-listdepsoptions) - - [type Option](#type-option) - - [func WithCode](#func-withcode) - - [func WithDisableNone](#func-withdisablenone) - - [func WithKFilenames](#func-withkfilenames) - - [func WithOptions](#func-withoptions) - - [func WithOverrides](#func-withoverrides) - - [func WithPrintOverridesAST](#func-withprintoverridesast) - - [func WithSettings](#func-withsettings) - - [func WithSortKeys](#func-withsortkeys) - - [func WithWorkDir](#func-withworkdir) - - [type ValidateOptions](#type-validateoptions) - -## Constants - -KclvmAbiVersion is the current kclvm ABI version. - -```go -const KclvmAbiVersion = scripts.KclvmAbiVersion -``` - -## func [FormatCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L110) - -```go -func FormatCode(code interface{}) ([]byte, error) -``` - -FormatCode returns the formatted code. - -
Example -

- -```go -{ - out, err := kcl.FormatCode(`a = 1+2`) - if err != nil { - log.Fatal(err) - } - fmt.Println(string(out)) - -} -``` - -``` -a = 1 + 2 -``` - -

-
- -## func [FormatPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L122) - -```go -func FormatPath(path string) (changedPaths []string, err error) -``` - -FormatPath formats files from the given path path: if path is \`.\` or empty string, all KCL files in current directory will be formatted, not recursively if path is \`path/file.k\`, the specified KCL file will be formatted if path is \`path/to/dir\`, all KCL files in the specified dir will be formatted, not recursively if path is \`path/to/dir/...\`, all KCL files in the specified dir will be formatted recursively - -the returned changedPaths are the changed file paths \(relative path\) - -
Example -

- -```go -{ - changedPaths, err := kcl.FormatPath("testdata/fmt") - if err != nil { - log.Fatal(err) - } - fmt.Println(changedPaths) -} -``` - -

-
- -## func [InitKclvmPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L54) - -```go -func InitKclvmPath(kclvmRoot string) -``` - -InitKclvmPath init kclvm path. - -## func [InitKclvmRuntime](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L59) - -```go -func InitKclvmRuntime(n int) -``` - -InitKclvmRuntime init kclvm process. - -## func [LintPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L142) - -```go -func LintPath(paths []string) (results []string, err error) -``` - -LintPath lint files from the given path - -
Example -

- -```go -{ - - results, err := kcl.LintPath([]string{"testdata/lint/import.k"}) - if err != nil { - log.Fatal(err) - } - for _, s := range results { - fmt.Println(s) - } - -} -``` - -``` -Module 'a' is reimported multiple times -Module 'a' imported but unused -``` - -

-
- -## func [ListDepFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L127) - -```go -func ListDepFiles(workDir string, opt *ListDepFilesOption) (files []string, err error) -``` - -ListDepFiles return the depend files from the given path - -## func [ListDownStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L137) - -```go -func ListDownStreamFiles(workDir string, opt *ListDepsOptions) ([]string, error) -``` - -ListDownStreamFiles return a list of downstream depend files from the given changed path list. - -## func [ListUpStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L132) - -```go -func ListUpStreamFiles(workDir string, opt *ListDepsOptions) (deps []string, err error) -``` - -ListUpStreamFiles return a list of upstream depend files from the given path list - -## func [OverrideFile](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L154) - -```go -func OverrideFile(file string, specs, importPaths []string) (bool, error) -``` - -OverrideFile rewrites a file with override spec file: string. The File that need to be overridden specs: \[\]string. List of specs that need to be overridden. - -``` -Each spec string satisfies the form: := or :- -When the pkgpath is '__main__', it can be omitted. -``` - -importPaths. List of import statements that need to be added - -## func [ValidateCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L159) - -```go -func ValidateCode(data, code string, opt *ValidateOptions) (ok bool, err error) -``` - -ValidateCode validate data match code - -## type [KCLResult](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L47) - -```go -type KCLResult = kcl.KCLResult -``` - -
Example -

- -```go -{ - const k_code = ` -name = "kcl" -age = 1 - -two = 2 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {name = "kcl-go"} -x1 = Person {age = 101} -` - - result := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First() - - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - -} -``` - -``` -x0.name: kcl-go -x1.age: 101 -``` - -

-
- -
Example ('et_struct) -

- -```go -{ - const k_code = ` -schema Person: - name: str = "kcl" - age: int = 1 - X: int = 2 - -x = { - "a": Person {age = 101} - "b": 123 -} -` - - result := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First() - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x.a", &person)) - fmt.Printf("person: %+v\n", person) - -} -``` - -``` -person: &{Name:kcl Age:101} -person: {Name:kcl Age:101} -``` - -

-
- -## type [KCLResultList](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L48) - -```go -type KCLResultList = kcl.KCLResultList -``` - -### func [MustRun](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L64) - -```go -func MustRun(path string, opts ...Option) *KCLResultList -``` - -MustRun is like Run but panics if return any error. - -
Example -

- -```go -{ - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(`name = "kcl"`)).First().YAMLString() - fmt.Println(yaml) - -} -``` - -``` -name: kcl -``` - -

-
- -
Example (Raw Yaml) -

- -```go -{ - const code = ` -b = 1 -a = 2 -` - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(code)).GetRawYamlResult() - fmt.Println(yaml) - - yaml_sorted := kcl.MustRun("testdata/main.k", kcl.WithCode(code), kcl.WithSortKeys(true)).GetRawYamlResult() - fmt.Println(yaml_sorted) - -} -``` - -``` -b: 1 -a: 2 -a: 2 -b: 1 -``` - -

-
- -
Example (Schema Type) -

- -```go -{ - const code = ` -schema Person: - name: str = "" - -x = Person() -` - json := kcl.MustRun("testdata/main.k", kcl.WithCode(code)).First().JSONString() - fmt.Println(json) - -} -``` - -``` -{ - "x": { - "name": "" - } -} -``` - -

-
- -
Example (Settings) -

- -```go -{ - yaml := kcl.MustRun("./testdata/app0/kcl.yaml").First().YAMLString() - fmt.Println(yaml) -} -``` - -

-
- -### func [Run](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L69) - -```go -func Run(path string, opts ...Option) (*KCLResultList, error) -``` - -Run evaluates the KCL program with path and opts, then returns the object list. - -
Example (Get Field) -

- -```go -{ - - x, err := kcl.Run("./testdata/app0/kcl.yaml") - assert(err == nil, err) - - fmt.Println(x.First().Get("deploy_topology.1.zone")) - -} -``` - -``` -R000A -``` - -

-
- -### func [RunFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L74) - -```go -func RunFiles(paths []string, opts ...Option) (*KCLResultList, error) -``` - -RunFiles evaluates the KCL program with multi file path and opts, then returns the object list. - -
Example -

- -```go -{ - result, _ := kcl.RunFiles([]string{"./testdata/app0/kcl.yaml"}) - fmt.Println(result.First().YAMLString()) -} -``` - -

-
- -## type [KclType](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L50) - -```go -type KclType = kcl.KclType -``` - -### func [GetSchemaType](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L176) - -```go -func GetSchemaType(file, code, schemaName string) ([]*KclType, error) -``` - -GetSchemaType returns schema types from a kcl file or code. - -file: string - -``` -The kcl filename -``` - -code: string - -``` -The kcl code string -``` - -schema_name: string - -``` -The schema name got, when the schema name is empty, all schemas are returned. -``` - -## type [ListDepFilesOption](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L45) - -```go -type ListDepFilesOption = list.Option -``` - -## type [ListDepsOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L44) - -```go -type ListDepsOptions = list.DepOptions -``` - -## type [Option](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L43) - -```go -type Option = kcl.Option -``` - -### func [WithCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L79) - -```go -func WithCode(codes ...string) Option -``` - -WithCode returns a Option which hold a kcl source code list. - -### func [WithDisableNone](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L97) - -```go -func WithDisableNone(disableNone bool) Option -``` - -WithDisableNone returns a Option which hold a disable none switch. - -### func [WithKFilenames](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L82) - -```go -func WithKFilenames(filenames ...string) Option -``` - -WithKFilenames returns a Option which hold a filenames list. - -### func [WithOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L85) - -```go -func WithOptions(key_value_list ...string) Option -``` - -WithOptions returns a Option which hold a key=value pair list for option function. - -
Example -

- -```go -{ - const code = ` -name = option("name") -age = option("age") -` - x, err := kcl.Run("hello.k", kcl.WithCode(code), - kcl.WithOptions("name=kcl", "age=1"), - ) - if err != nil { - log.Fatal(err) - } - - fmt.Println(x.First().YAMLString()) - -} -``` - -``` -age: 1 -name: kcl -``` - -

-
- -### func [WithOverrides](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L88) - -```go -func WithOverrides(override_list ...string) Option -``` - -WithOverrides returns a Option which hold a override list. - -### func [WithPrintOverridesAST](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L100) - -```go -func WithPrintOverridesAST(printOverridesAST bool) Option -``` - -WithPrintOverridesAST returns a Option which hold a printOverridesAST switch. - -### func [WithSettings](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L91) - -```go -func WithSettings(filename string) Option -``` - -WithSettings returns a Option which hold a settings file. - -### func [WithSortKeys](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L105) - -```go -func WithSortKeys(sortKeys bool) Option -``` - -WithSortKeys returns a Option which hold a sortKeys switch. - -### func [WithWorkDir](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L94) - -```go -func WithWorkDir(workDir string) Option -``` - -WithWorkDir returns a Option which hold a work dir. - -## type [ValidateOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L46) - -```go -type ValidateOptions = validate.ValidateOptions -``` diff --git a/versioned_docs/version-0.5.0/reference/xlang-api/rest-api.md b/versioned_docs/version-0.5.0/reference/xlang-api/rest-api.md deleted file mode 100644 index 4723280f..00000000 --- a/versioned_docs/version-0.5.0/reference/xlang-api/rest-api.md +++ /dev/null @@ -1,443 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Rest API - -## 1. Start REST Service - -The RestAPI service can be started in the following ways: - -```shell -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -or - -```shell -go install kcl-lang.io/kcl-go/cmds/kcl-go@main -kcl-go rest-server -``` - -The service can then be requested via the POST protocol: - -```shell -$ curl -X POST http://127.0.0.1:2021/api:protorpc/BuiltinService.Ping --data '{}' -{ - "error": "", - "result": {} -} -``` - -The POST request and the returned JSON data are consistent with the structure defined by Protobuf. - -## 2. `BuiltinService` - -Where the `/api:protorpc/BuiltinService.Ping` path represents the `Ping` method of the `BuiltinService` service. - -The complete `BuiltinService` is defined by Protobuf: - -```protobuf -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} -``` - -The `Ping` method can verify whether the service is normal, and the `ListMethod` method can query the list of all services and functions provided. - -## 3. `KclvmService` - -The `KclvmService` service is a service related to KCL functionality. The usage is the same as the `BuiltinService` service. - -For example, there is the following `Person` structure definition: - -```python -schema Person: - key: str - - check: - "value" in key # 'key' is required and 'key' must contain "value" -``` - -Then we want to use `Person` to verify the following JSON data: - -```json -{ "key": "value" } -``` - -This can be done through the `ValidateCode` method of the `KclvmService` service. Refer to the `ValidateCode_Args` structure of the `ValidateCode` method: - -```protobuf -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} -``` - -Construct the JSON data required by the POST request according to the `ValidateCode_Args` structure, which contains the `Person` definition and the JSON data to be verified: - -```json -{ - "code": "\nschema Person:\n key: str\n\n check:\n \"value\" in key # 'key' is required and 'key' must contain \"value\"\n", - "data": "{\"key\": \"value\"}" -} -``` - -Save this JSON data to the `vet-hello.json` file and verify it with the following command: - -```shell -$ curl -X POST \ - http://127.0.0.1:2021/api:protorpc/KclvmService.ValidateCode \ - -H "accept: application/json" \ - --data @./vet-hello.json -{ - "error": "", - "result": { - "success": true - } -} -``` - -## 4. Complete Protobuf Service Definition - -Cross-language APIs defined via Protobuf([https://github.com/kcl-lang/kcl-go/blob/main/pkg/spec/gpyrpc/gpyrpc.proto](https://github.com/kcl-lang/kcl-go/blob/main/pkg/spec/gpyrpc/gpyrpc.proto)): - -```protobuf -// Copyright 2023 The KCL Authors. All rights reserved. -// -// This file defines the request parameters and return structure of the KCL RPC server. -// We can use the following command to start a KCL RPC server. - -syntax = "proto3"; - -package gpyrpc; - -import "google/protobuf/any.proto"; -import "google/protobuf/descriptor.proto"; - -// ---------------------------------------------------------------------------- - -// kcl main.k -D name=value -message CmdArgSpec { - string name = 1; - string value = 2; -} - -// kcl main.k -O pkgpath:path.to.field=field_value -message CmdOverrideSpec { - string pkgpath = 1; - string field_path = 2; - string field_value = 3; - string action = 4; -} - -// ---------------------------------------------------------------------------- -// gpyrpc request/response/error types -// ---------------------------------------------------------------------------- - -message RestResponse { - google.protobuf.Any result = 1; - string error = 2; - KclError kcl_err = 3; -} - -message KclError { - string ewcode = 1; // See kclvm/kcl/error/kcl_err_msg.py - string name = 2; - string msg = 3; - repeated KclErrorInfo error_infos = 4; -} - -message KclErrorInfo { - string err_level = 1; - string arg_msg = 2; - string filename = 3; - string src_code = 4; - string line_no = 5; - string col_no = 6; -} - -// ---------------------------------------------------------------------------- -// service requset/response -// ---------------------------------------------------------------------------- - -// gpyrpc.BuiltinService -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -// gpyrpc.KclvmService -service KclvmService { - rpc Ping(Ping_Args) returns(Ping_Result); - - rpc ExecProgram(ExecProgram_Args) returns(ExecProgram_Result); - - rpc FormatCode(FormatCode_Args) returns(FormatCode_Result); - rpc FormatPath(FormatPath_Args) returns(FormatPath_Result); - rpc LintPath(LintPath_Args) returns(LintPath_Result); - rpc OverrideFile(OverrideFile_Args) returns (OverrideFile_Result); - - rpc GetSchemaType(GetSchemaType_Args) returns(GetSchemaType_Result); - rpc GetSchemaTypeMapping(GetSchemaTypeMapping_Args) returns(GetSchemaTypeMapping_Result); - rpc ValidateCode(ValidateCode_Args) returns(ValidateCode_Result); - - rpc ListDepFiles(ListDepFiles_Args) returns(ListDepFiles_Result); - rpc LoadSettingsFiles(LoadSettingsFiles_Args) returns(LoadSettingsFiles_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} - -message ParseFile_AST_Args { - string filename = 1; - string source_code = 2; -} -message ParseFile_AST_Result { - string ast_json = 1; // json value - KclError kcl_err = 2; -} - -message ParseProgram_AST_Args { - repeated string k_filename_list = 1; -} -message ParseProgram_AST_Result { - string ast_json = 1; // json value - KclError kcl_err = 2; -} - -message ExecProgram_Args { - string work_dir = 1; - - repeated string k_filename_list = 2; - repeated string k_code_list = 3; - - repeated CmdArgSpec args = 4; - repeated CmdOverrideSpec overrides = 5; - - bool disable_yaml_result = 6; - - bool print_override_ast = 7; - - // -r --strict-range-check - bool strict_range_check = 8; - - // -n --disable-none - bool disable_none = 9; - // -v --verbose - int32 verbose = 10; - - // -d --debug - int32 debug = 11; - - // yaml/json: sort keys - bool sort_keys = 12; - // include schema type path in JSON/YAML result - bool include_schema_type_path = 13; -} -message ExecProgram_Result { - string json_result = 1; - string yaml_result = 2; - - string escaped_time = 101; -} - -message ResetPlugin_Args { - string plugin_root = 1; -} -message ResetPlugin_Result { - // empty -} - -message FormatCode_Args { - string source = 1; -} - -message FormatCode_Result { - bytes formatted = 1; -} - -message FormatPath_Args { - string path = 1; -} - -message FormatPath_Result { - repeated string changed_paths = 1; -} - -message LintPath_Args { - repeated string paths = 1; -} - -message LintPath_Result { - repeated string results = 1; -} - -message OverrideFile_Args { - string file = 1; - repeated string specs = 2; - repeated string import_paths = 3; -} - -message OverrideFile_Result { - bool result = 1; -} - -message EvalCode_Args { - string code = 1; -} -message EvalCode_Result { - string json_result = 2; -} - -message ResolveCode_Args { - string code = 1; -} - -message ResolveCode_Result { - bool success = 1; -} - -message GetSchemaType_Args { - string file = 1; - string code = 2; - string schema_name = 3; -} -message GetSchemaType_Result { - repeated KclType schema_type_list = 1; -} - -message GetSchemaTypeMapping_Args { - string file = 1; - string code = 2; - string schema_name = 3; -} -message GetSchemaTypeMapping_Result { - map schema_type_mapping = 1; -} - -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} - -message ValidateCode_Result { - bool success = 1; - string err_message = 2; -} - -message Position { - int64 line = 1; - int64 column = 2; - string filename = 3; -} - -message ListDepFiles_Args { - string work_dir = 1; - bool use_abs_path = 2; - bool include_all = 3; - bool use_fast_parser = 4; -} - -message ListDepFiles_Result { - string pkgroot = 1; - string pkgpath = 2; - repeated string files = 3; -} - -// --------------------------------------------------------------------------------- -// LoadSettingsFiles API -// Input work dir and setting files and return the merged kcl singleton config. -// --------------------------------------------------------------------------------- - -message LoadSettingsFiles_Args { - string work_dir = 1; - repeated string files = 2; -} - -message LoadSettingsFiles_Result { - CliConfig kcl_cli_configs = 1; - repeated KeyValuePair kcl_options = 2; -} - -message CliConfig { - repeated string files = 1; - string output = 2; - repeated string overrides = 3; - repeated string path_selector = 4; - bool strict_range_check = 5; - bool disable_none = 6; - int64 verbose = 7; - bool debug = 8; -} - -message KeyValuePair { - string key = 1; - string value = 2; -} - -// ---------------------------------------------------------------------------- -// JSON Schema Lit -// ---------------------------------------------------------------------------- - -message KclType { - string type = 1; // schema, dict, list, str, int, float, bool, any, union, number_multiplier - repeated KclType union_types = 2 ; // union types - string default = 3; // default value - - string schema_name = 4; // schema name - string schema_doc = 5; // schema doc - map properties = 6; // schema properties - repeated string required = 7; // required schema properties, [property_name1, property_name2] - - KclType key = 8; // dict key type - KclType item = 9; // dict/list item type - - int32 line = 10; - - repeated Decorator decorators = 11; // schema decorators -} - -message Decorator { - string name = 1; - repeated string arguments = 2; - map keywords = 3; -} - -// ---------------------------------------------------------------------------- -// END -// ---------------------------------------------------------------------------- -``` diff --git a/versioned_docs/version-0.5.0/tools/Ide/intellij.md b/versioned_docs/version-0.5.0/tools/Ide/intellij.md deleted file mode 100644 index be637514..00000000 --- a/versioned_docs/version-0.5.0/tools/Ide/intellij.md +++ /dev/null @@ -1,3 +0,0 @@ -# IntelliJ IDEA - -- IntelliJ Plugin: https://github.com/kcl-lang/intellij-kcl diff --git a/versioned_docs/version-0.5.0/tools/Ide/vs-code.md b/versioned_docs/version-0.5.0/tools/Ide/vs-code.md deleted file mode 100644 index 6b00815c..00000000 --- a/versioned_docs/version-0.5.0/tools/Ide/vs-code.md +++ /dev/null @@ -1,55 +0,0 @@ -# KCL Extension for Visual Studio Code - -## Quick Start - -- **Step 1.** [Install KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) on your system. Please check that `kcl` and `kcl-language-server` are installed and have been added to your PATH: - - ```bash - which kcl - which kcl-language-server - ``` - -- **Step 2.** Install the [KCL extension](https://marketplace.visualstudio.com/items?itemName=kcl.kcl-vscode-extension) for Visual Studio Code. This extension requires the VS Code 1.50+. -- **Step 3.** Reopen VS Code and create a KCL file and begin your KCL tour! - -## Features - -This extension provides some coding assistance, including the following features: - -- **Syntax Highlight:** - ![Highlight](/img/docs/tools/Ide/vs-code/Highlight.png) -- **Goto Definition:** Goto definition of schema, variable, schema attribute, and import pkg. - ![Goto Definition](/img/docs/tools/Ide/vs-code/GotoDef.gif) -- **Completion:** Keywords completions and dot(`.`) completion. - ![Completion](/img/docs/tools/Ide/vs-code/Completion.gif) -- **Outline:** Main definition(schema def) and variables in KCL file. - ![Outline](/img/docs/tools/Ide/vs-code/Outline.gif) -- **Hover:** Identifier information (type and schema documentation). - ![Hover](/img/docs/tools/Ide/vs-code/Hover.gif) -- **Diagnostics:** Warnings and errors in KCL file. - - > Tips: You can enhance the effect of diagnostics by installing another plugin: [Error Lens](https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens). - - ![Diagnostics](/img/docs/tools/Ide/vs-code/Diagnostics.gif) - -Other useful features such as refactoring and testing are in development. - -## Dependencies - -We recommend that you use the latest version of KCL, but the minimum required version for this extension is 0.4.6. If you are using an earlier version, the extension may not work properly. - -## Known Issues - -See [here](https://github.com/kcl-lang/kcl/issues/524). - -## Ask for help - -If the extension isn't working as you expect, please contact us with [community](https://kcl-lang.io/docs/community/intro/support) for help. - -## Contributing - -We are working actively on improving the KCL development on VS Code. All kinds of contributions are welcomed. You can refer to our [contribution guide](https://kcl-lang.io/docs/community/contribute). It introduces how to build and run the extension locally, and describes the process of sending a contribution. - -## License - -Apache License 2.0 diff --git a/versioned_docs/version-0.5.0/tools/cli/kcl/fmt.md b/versioned_docs/version-0.5.0/tools/cli/kcl/fmt.md deleted file mode 100644 index eaf562cd..00000000 --- a/versioned_docs/version-0.5.0/tools/cli/kcl/fmt.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Format - -The KCL Format tool supports reformatting KCL files to the standard code style. This article demonstrates the KCL code style and how to use the KCL Format tool. - -## Code Style - -The KCL Format tool modifies the files according to the KCL code style: [Style Guide for KCL Code](/docs/reference/lang/spec/codestyle) - -## How to use - -- Formatting Single File - -```text -kcl-fmt your_config.k -``` - -- Formatting multiple files - -```text -kcl-fmt your_config_path -R -``` - -- Args - - `-R|--recursive` Whether to recursively traverse subfolders - - `-w|--fmt-output` Whether to output to STDOUT, without `-w` indicates in-place modification. - -## Display of formatting files - -- Before formatting - -```py -import math -mixin DeploymentMixin: - service:str ="my-service" -schema DeploymentBase: - name: str - image : str -schema Deployment[replicas] ( DeploymentBase ) : - mixin[DeploymentMixin] - replicas : int = replicas - command: [str ] - labels: {str: str} -deploy = Deployment(replicas = 3){} -``` - -- After formatting - -```py -import math - -mixin DeploymentMixin: - service: str = "my-service" - -schema DeploymentBase: - name: str - image: str - -schema Deployment[replicas](DeploymentBase): - mixin [DeploymentMixin] - replicas: int = replicas - command: [str] - labels: {str:str} - -deploy = Deployment(replicas=3) {} - -``` diff --git a/versioned_docs/version-0.5.0/tools/cli/kcl/lint.md b/versioned_docs/version-0.5.0/tools/cli/kcl/lint.md deleted file mode 100644 index 627177a9..00000000 --- a/versioned_docs/version-0.5.0/tools/cli/kcl/lint.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Lint - -The KCL Lint tool supports checking some warning-level defects in KCL code and supports multiple output formats. This document shows how to use the KCL Lint tool. - -## Example - -### Project Struct - -```text -. -└── Test - └── kcl.mod - └── a.k - └── b.k - └── dir - └── c.k - └── test.k -``` - -`a.k`, `b.k`, `c.k` and `test.k` are the kcl file to be checked. - -Args: - -```shell -kcl-lint your_config.k -``` - -or - -```shell -kcl-lint your_config_path -``` - -## KCL Lint Tool - -### Args - -```shell -USAGE: - kcl-lint [OPTIONS] [--] [input]... - -ARGS: - ... Sets the input file to use - -OPTIONS: - --emit_warning Emit warning message - -h, --help Print help information - -v, --verbose Print test information verbosely - -Y, --setting ... Sets the input file to use -``` - -- input: the path of a single `*.k` file or directory to be checked. Support the absolute path or relative path of the current directory. diff --git a/versioned_docs/version-0.5.0/tools/cli/kcl/overview.md b/versioned_docs/version-0.5.0/tools/cli/kcl/overview.md deleted file mode 100644 index 82941119..00000000 --- a/versioned_docs/version-0.5.0/tools/cli/kcl/overview.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Overview - -KCL toolchain is a toolset of KCL language, which aims to improve the efficiency of batch migration, writing, compiling and running of KCL. - -| | Name | Description | -| ---------- | ------------------------ | ------------------------------------------------------------------- | -| Main Tools | **kcl** | Provide support for KCL in coding, compiling and running | -| | kcl-test | Coming soon | -| | kcl-lint | Check code style for KCL | -| | kcl-doc | Parses the KCL code and generate documents | -| | kcl-fmt | Format the kcl code | -| | kcl-vet | Validate data files such as JSON and YAML using KCL | -| IDE Plugin | IntelliJ IDEA KCL plugin | Provide assistance for KCL in coding and compiling on IntelliJ IDEA | -| | VS Code KCL plugin | Provide assistance for KCL in coding and compiling on VS Code | diff --git a/versioned_docs/version-0.5.0/tools/cli/openapi/quick-start.md b/versioned_docs/version-0.5.0/tools/cli/openapi/quick-start.md deleted file mode 100644 index d5812e3a..00000000 --- a/versioned_docs/version-0.5.0/tools/cli/openapi/quick-start.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Quick Start - -## 1. Install KCLOpenAPI Tool - -The kcl-openapi tool can be installed in following ways: - -- [go install](#11-go-install) -- [curl|sh install (MacOS & Linux)](#12-curlsh-install-macos--linux) -- [download from release](#13-dowload-from-release) - -## 1.1 go install - -```shell -go install kcl-lang.io/kcl-openapi@latest -``` - -## 1.2 Curl|sh install (MacOS & Linux) - -If you don't have go, you can install the CLI with this one-liner: - -```shell -curl -fsSL https://kcl-lang.io/script/install-kcl-openapi.sh | /bin/bash -``` - -## 1.3 Download from release - -```shell -# 1. download the released binary from: -# https://github.com/kcl-lang/kcl-openapi/releases - -# 2. Unzip the package and add the binary location to PATH -export PATH=":$PATH" -``` - -## 1.4 Verify your installation - -```shell -➜ kcl-openapi -v -kcl-openapi 0.5.0 -``` - -## 2. Generate KCL Files - -- [OpenAPI to KCL](../openapi/openapi-to-kcl.md) -- [CRD to KCL](../openapi/crd-to-kcl.md) diff --git a/versioned_docs/version-0.5.0/tools/cli/openapi/spec.md b/versioned_docs/version-0.5.0/tools/cli/openapi/spec.md deleted file mode 100644 index 7a144e4c..00000000 --- a/versioned_docs/version-0.5.0/tools/cli/openapi/spec.md +++ /dev/null @@ -1,438 +0,0 @@ -# KCL OpenAPI Spec - -[OpenAPI](https://www.openapis.org/) defines the API Specification for API providers to describe their operations and models in a normative way and provides generating tools to automatically convert to client codes in specific languages. - -The KCL OpenAPI Spec describes the rules about how the OpenAPI definitions are translated to the KCL schemas. - -## The File Structure of the KCL OpenAPI - -According to the OpenAPI 3.0 specification, an OpenAPI file should at least contains four root objects: `openapi`, `components`, `info`, `paths`. The KCL OpenAPI focuses on the part in which the models are defined in the `definitions` object. Yet the `paths` part which describes the Restful API operations is not considered by the KCL OpenAPI Spec. - -:::info -Note: In addition to the objects listed above, the OpenAPI spec also supports `servers`, `security`, `tags`, and `externalDocs` as optional root objects, but none of them are concerned by KCL OpenAPI when generating model codes, so we do not need to fill in this section. Yet it won't make any difference if you do. -::: - -To put it more comprehensible for beginners, let's take a quick look at the root objects that forms the typical KCL OpenAPI file (snippets from swagger example [Petstore](https://petstore.swagger.io/). The KCL OpenAPI tool only focuses on the `definitions` object which describes two data models (`Pet` and `Category`), and the model `Pet` contains three attributes: `name`, `id`, and `category`) - -## KCL schema - -The KCL schema structure defines the "type" of configuration data. - -:::info -More information about KCL schema, see [KCL Language Tour#Schema](../../../reference/lang/tour.md) -::: - -In the OpenAPI spec, a KCL schema can be defined by adding a `definition` element within the `definitions` object. - -Example: -The following example defines two schemas in KCL: `Pet` and `Category`, followed by the corresponding data models defined in OpenAPI: - -```python -# KCL schema -schema Pet: - name: str - id?: int - category?: Category - -schema Category: - name?: str - -# The corresponding OpenAPI spec -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "id": { - "type": "integer", - "format": "int64" - }, - "category": { - "$ref": "#/definitions/Category" - } - }, - "required": [ - "name" - ] - }, - "Category": { - "type": "object", - "properties": { - "name": { - "type": "string" - } - } - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### Schema Name - -In KCL, the schema name is declared immediately after the schema keyword, and in OpenAPI, the name of the model is defined by the key of the definition element. - -### Schema Type - -The type of KCL schema in OpenAPI is always "object". As in the previous example, the value of the `type` object in `Pet` should be `object`. - -### Schema Attribute - -Zero or more attributes can be defined in the KCL schema. The declaration of attributes generally includes the following parts: - -- Attribute annotation: Optional, starting with `@`, such as `@deprecated` to indicate a deprecated attribute -- Attribute name: Required -- Attribute optional modifiers(`?`): Optional. A question mark indicates that the current attribute is optional and may not be assigned. Conversely, the absence of a question mark indicates a required attribute -- Attribute type: Required. The attribute can be a primitive data type, a schema type, or a combination of the two preceding types -- Attribute default value: Optional - -The mapping between them and the OpenAPI spec is as follows: - -| Elements of KCL Schema Attribute | Corresponding Elements in OpenAPI | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| attribute annotation | Not supported. We are planning to add an extension `deprecate` field to the KCL-OpenAPI | -| attribute name | The key of the property under the `property` object | -| attribute optional modifiers(`?`) | In each element in the `definition` object, here's an optional `required` field which lists the all the required attributes of that model, and the attributes not listed are optional | -| attribute type | The basic types can be declared by a combination of `type` and `format`, and the schema type is declared by a `$ref` to the schema definition. KCL-OpenAPI spec adds a `x-kcl-types` extension to indicate a type union. `enum` indicates a union of several literal types. For the type declaration in KCL-OpenAPI, see the chapter - [basic data types](#basic-data-types) | -| attribute default value | The value of the `default` field is used to set the default value for the attribute | - -Example: - -The following KCL code defines a Pet model which contains two attributes: name (`string` type, `required`, with no attribute annotation and no default value) and id (`int64` type, optional, with no attribute annotation, and the default value is -1). - -```python -# the KCL schema Pet defines two attributes: name, id -schema Pet: - name: str - id?: int = -1 - -# The corresponding OpenAPI spec -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - "id": { - "type": "integer", - "format": "int64", - "default": -1 - } - }, - "required": [ - "name" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### Schema Index Signature - -In the KCL schema, the index signatures can be used to define attributes with undefined attribute names. The KCL schema index signature contains the following elements: - -- Type of the key in the index signature: Declared in square brackets. It must be the basic type -- Type of value in the index signature: Declared after the colon in the square brackets. It can be any valid KCL type -- Ellipses(`...`) in the index signature: In the square brackets, before the type declaration of the key. It indicates that the index signature is only used to constrain attributes not defined in the schema. The absentation of the symbol indicates that all defined and undefined attributes in the schema are constrained by the index signature. -- Alias for key in index signature: Declared in square brackets, immediately after the left square bracket and takes the form of `:`. The alias can then be used to reference the index signature by name -- The default value of the index signature: Assign a value to the index signature as the default value - -The index signature with its key in `string` type can be described based on the field `additionalProperties`. Other index signatures with a key in types besides `string`, and the `check` expressions used to validate the index signature are not supported by the KCL OpenAPI spec. - -The mapping between them and the OpenAPI spec is as follows: - -| Elements of KCL Index Signature | Corresponding Elements in OpenAPI | -| -------------------------------------------- | ----------------------------------------------------------------------------------------------- | -| Type of the key in the KCL index signature | Only string type is allowed in OpenAPI | -| Type of the value in the KCL index signature | Declared by the `type` in the `additionalProperties` field | -| Ellipses(`...`) in the index signature | Only the corresponding meaning of the attendance of the `...` symbol is allowed in OpenAPI | -| Alias for key in index signature | Not supported in KCL-OpenAPI yet. We are planning to add an `x-alias` extension to support that | -| Default value of the index signature | Not supported in KCL-OpenAPI | - -Example: - -The following KCL code defines a Pet model which contains two pre-declared attributes(`name` and `id`) and allows users to add attributes with `string` type keys and `bool` type values. - -```python -# the KCL schema Pet. Besides the pre-declared attributes name and id, it allows to add attributes with key in string type and value in bool type -schema Pet: - name: str - id?: int - [...str]: bool - -# The corresponding OpenAPI spec -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - "id": { - "type": "integer", - "format": "int64", - } - }, - "additionalProperties": { - "type": "bool" - }, - "required": [ - "name" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### Schema Inherit - -working in progress - -### Inline schema - -OpenAPI supports models to be declared inline. But KCL currently does not support that. The model defined inline in OpenAPI will be converted to a schema with a name in KCL. And the naming convention will be: - -| element to define an inline schema in OpenAPI | the name of the corresponding KCL schema | -| --------------------------------------------- | -------------------------------------------------------------- | -| inline Property | add the Property name at the end of the outer schema Name | -| AdditionalProperties | add "AdditionalProperties" at the end of the outer schema Name | - -We are planning to support inline schema in KCL, and when supported, the naming convention will be updated then. - -Example-1: - -The following KCL code defines a `Deployment` model which contains two attributes(`kind` and `spec`). And the schema of the `spec` attribute is defined inline. - -```python -# The OpenAPI spec -{ - "definitions": { - "Deployment": { - "type": "object", - "properties": { - "kind": { - "type": "string", - }, - "spec": { - "type": "object", - "properties": { - "replicas": { - "type": "integer", - "format": "int64" - } - } - } - }, - "required": [ - "kind", - "spec" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -# The corresponding KCL schemas -schema Deployment: - kind: str - spec: DeploymentSpec - -schema DeploymentSpec: - replicas?: int -``` - -Example-2: - -The following KCL code defines a Person model which contains a pre-declared attribute(`name`) and allows some `additionalProperties` to be assigned by user. And the type of the values in the `additionalProperties` is defined inline. - -```python -# The OpenAPI spec -{ - "definitions": { - "Person": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - }, - "required": [ - "name", - "spec" - ], - "additionalProperties": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "description": { - "type": "string" - } - }, - "required": [ - "name" - ] - }, - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -# The corresponding KCL schemas -schema Person: - name: str - [...str]: [PersonAdditionalProperties] - -schema PersonAdditionalProperties: - name: str - description?: str -``` - -## KCL Doc - -:::info -More information about KCL doc specification, please refer to the [KCL Document Specification](../kcl/docgen.md) -::: - -KCL documents consist of module documents and schema documents. And only the schema documents can be extracted from OpenAPI. The KCL schema document contains four parts: - -- Schema Description: Declared right after the schema declaration and before the schema attribute declaration. It provides an overview of schemas -- Schema Attribute Doc: Declared right after the schema Description and separated by `Attributes` + `---` delimiters. It describes the attribute -- Additional information about the schema: Declared right after the schema attribute doc and separated by `See Also` + `---` delimiters -- Example information about the schema: Declared right after the schema additional information and separated by `Examples` + `---` delimiters - -The mapping between them and the OpenAPI spec is as follows: - -| Elements of KCL Schema Document | Corresponding Elements in OpenAPI | -| --------------------------------------- | ------------------------------------------------------- | -| Schema Description | The value of the `description` field of the data model | -| Schema Attribute Doc | The value of the `description` field of the property | -| Additional information about the schema | The value of the `externalDocs` field of the data model | -| Example information about the schema | The value of the `example` field of the data model | - -Example: - -The following KCL code defines a Pet model with a schema description `The schema Pet definition`, and two attributes `name` and `id` with their attribute doc `The name of the pet` and `The id of the pet`; The additional information about the Pet schema is [here](https://petstore.swagger.io/) and the example to use the Pet schema are provided, too. - -```python -# The KCL schema Pet, with doc following the KCL Document Specification -schema Pet: - """The schema Pet definition - - Attributes - ---------- - name : str, default is Undefined, required - The name of the pet - id : int, default is -1, optional - The age of the pet - - See Also - -------- - Find more info here. https://petstore.swagger.io/ - - Examples - -------- - pet = Pet { - name = "doggie" - id = 123 - } - """ - name: str - id?: int = -1 - -# The corresponding OpenAPI Spec -{ - "definitions": { - "Pet": { - "description": "The schema Pet definition", - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "The name of the pet" - }, - "id": { - "type": "integer", - "format": "int64", - "default": -1, - "description": "The age of the pet" - } - }, - "required": [ - "name" - ], - "externalDocs": { - "description": "Find more info here", - "url": "https://petstore.swagger.io/" - }, - "example": { - "name": "doggie", - "id": 123 - } - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -## Basic Data Types - -| JSON Schema type | swagger type | KCL type | comment | -| ---------------- | --------------------------- | --------------- | --------------------------------------------------------------------------- | -| boolean | boolean | bool | | -| number | number | float | | -| | number format double | **unsupported** | | -| | number format float | float | | -| integer | integer | int (32) | | -| | integer format int64 | **unsupported** | | -| | integer format int32 | int (32) | | -| string | string | str | | -| | string format byte | str | | -| | string format int-or-string | int \| str | | -| | string format binay | str | | -| | string format date | unsupported | As defined by full-date - [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) | -| | string format date-time | unsupported | As defined by date-time - [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) | -| | string format password | unsupported | for swagger: A hint to UIs to obscure input | -| | datetime | datetime | | - -## Reference - -- OpenAPI spec 2.0: [https://swagger.io/specification/v2/](https://swagger.io/specification/v2/) -- OpenAPI spec 3.0: [https://spec.openapis.org/oas/v3.1.0](https://spec.openapis.org/oas/v3.1.0) -- OpenAPI spec 3.0: [https://swagger.io/specification/](https://swagger.io/specification/) -- OpenAPI spec 2.0: [https://swagger.io/specification/v2/#schemaObject](https://swagger.io/specification/v2/#schemaObject) -- Go swagger: [https://goswagger.io/use/models/schemas.html](https://goswagger.io/use/models/schemas.html) -- Swagger data models: [https://swagger.io/docs/specification/data-models/](https://swagger.io/docs/specification/data-models/) diff --git a/versioned_docs/version-0.5.0/user_docs/getting-started/install.md b/versioned_docs/version-0.5.0/user_docs/getting-started/install.md deleted file mode 100644 index 261ab804..00000000 --- a/versioned_docs/version-0.5.0/user_docs/getting-started/install.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Installation - -## 1. Install KCL - -### From the Binary Releases - -Each release of KCL includes various OSes and architectures. These binary versions can be manually downloaded and installed from [Github](https://github.com/kcl-lang/kcl/releases/) or [Gitee](https://gitee.com/kusionstack/kcl/releases) and add `{install-location}/kclvm/bin` to the environment PATH. - -> ⚠️ If you cannot successfully access Github, you can also access Gitee to obtain binaries for installation. - -#### MacOS & Linux - -```bash -export PATH=$PATH:{install-location}/kclvm/bin -``` - -#### Windows - -```powershell -$env:PATH += ";{install-location}\kclvm\bin;" -``` - -### Using script to install the latest release - -#### MacOS - -Install or upgrade the latest darwin KCL to /usr/local/kclvm/bin - -```bash -curl -fsSL https://kcl-lang.io/script/install.sh | /bin/bash -``` - -#### Linux - -Install or upgrade the latest linux KCL to /usr/local/kclvm/bin - -```bash -wget -q https://kcl-lang.io/script/install.sh -O - | /bin/bash -``` - -#### Windows - -Install or upgrade the latest windows KCL to $Env:SystemDrive\kclvm\bin and add this directory to User PATH environment variable. - -```bash -powershell -Command "iwr -useb https://kcl-lang.io/script/install.ps1 | iex" -``` - -### Homebrew (MacOS) - -- Install - -```bash -brew install kcl-lang/tap/kcl -``` - -- Upgrade - -```bash -brew upgrade kcl-lang/tap/kcl -``` - -- Uninstall - -```bash -brew uninstall kcl-lang/tap/kcl -``` - -### Scoop (Windows) - -Install [Scoop](https://scoop.sh/) first, then add this bucket and install `kcl` by running: - -```bash -scoop bucket add kcl-lang https://github.com/kcl-lang/scoop-bucket.git -scoop install kcl-lang/kcl -``` - -### From Go - -Install `kcl` through the `Go` command (`Go` requires 1.18+). - -```bash -go install kcl-lang.io/kcl-go/cmds/kcl-go@main -``` - -Add an alias for the kcl command (optional). - -```bash -alias kcl='kcl-go run' -``` - -> Note: `kcl-go` does not rely on the installation of `kcl`, but if `kcl` exists in PATH, it will be used by `kcl-go` first. - -### From Docker - -- Command - -```bash -docker run --rm -it kcllang/kcl -``` - -- Update image - -```bash -docker pull kcllang/kcl -``` - -### Note - -We can execute the following command to ensure that KCL has been installed correctly. - -```bash -kcl -V -``` - -The output may looks like this: - -```bash -Version: {kcl version} -Platform: {your platform} -GitCommit: {git commit} -``` - -For all the above operating systems and installation methods, if you want to use [KCL Python Plugin](/docs/reference/plugin/overview), you need to ensure that Python 3.7+ is installed and add the python3 command to your PATH environment variable. - -## 2. Install KCL IDE Extension - -### VS Code - -The KCL Extension extension provides some coding assistance, e.g., highlight, goto definition, completion, hover, outline, and diagnostics. You can go [here](/docs/tools/Ide/vs-code) for more information about the installation. - -![Completion](/img/docs/tools/Ide/vs-code/Completion.gif) - -### IntelliJ IDEA - -Download the distribution from [here](https://github.com/kcl-lang/intellij-kcl/releases) and in IntelliJ IDEA, click Preference -> plugins -> install Plugin from Disk... -> select kcl-idea-plugin zip -> restart IDE. This plugin requires the IntelliJ IDEA 2020.2+ diff --git a/versioned_docs/version-0.5.0/user_docs/guides/abstraction.md b/versioned_docs/version-0.5.0/user_docs/guides/abstraction.md deleted file mode 100644 index 106f07a2..00000000 --- a/versioned_docs/version-0.5.0/user_docs/guides/abstraction.md +++ /dev/null @@ -1,147 +0,0 @@ ---- -title: "Abstraction" -sidebar_position: 3 ---- - -## Introduction - -Abstraction refers to a simplified representation of an entity, typically used in computing. It allows for the concealment of specific details while presenting the most relevant information to the programmer. Each abstraction is tailored to suit a specific need, and can greatly enhance the usability of a given entity. In the context of KCL, abstraction can make code easier to understand and maintain, while also simplifying the user interface. - -It should be noted that code abstraction is not meant to reduce code size, but rather to improve maintainability and extendability. During the process of abstracting code, factors such as reusability, readability, and scalability should be taken into consideration, and the code should be optimized as needed. - -The values of the good abstraction - -1. Provides distinct focal points for better comprehension for specific identities, roles, and scenarios. -2. Shields lower-level details to avoid potential errors. -3. Enhances user-friendliness and automation with better portability and good APIs. - -KCL may not assess the rationality of a user's abstraction, but it offers technical solutions to facilitate the process. - -## Use KCL for Abstraction - -**Now, let's begin to abstract Docker Compose and Kubernetes models into an application config.** - -Application centric development allows developers to focus on their workload's architecture rather than the tech stack in the target environment, infrastructure or platform. We define our application once with the `App` schema and then use the KCL CLI to translate it to multiple platforms, such as `Docker Compose` or `Kubernetes` with different versions. - -`Docker Compose` is a tool for defining and running multi-container Docker applications. With Docker Compose, you can define your application's services, networks, and volumes in a single file, and then use it to start and stop your application as a single unit. Docker Compose simplifies the process of running complex, multi-container applications by handling the details of networking, storage, and other infrastructure concerns. - -`Kubernetes manifests` are YAML files that define Kubernetes objects such as Pods, Deployments, and Services. Manifests provide a declarative way to define the desired state of your application, including the number of replicas, the image to use, and the network configuration. Kubernetes uses the manifests to create and manage the resources needed to deploy and run your application. - -Here are some references to learn more about Docker Compose and Kubernetes manifests: - -- [Docker Compose documentation](https://docs.docker.com/compose/) -- [Kubernetes manifest documentation](https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/) - -The application model aims to reduce developer toil and cognitive load by only having to define a single KCL file that works across multiple platforms, and it is designed to be applied to multiple environments to reduce the amount of configuration. Now, let's learn how to do this. - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/abstraction -``` - -We can run the following command to show the config. - -```bash -cat main.k -``` - -The output is - -```python -import .app - -app.App { - name = "app" - containers.nginx = { - image = "nginx" - ports = [{containerPort = 80}] - } - service.ports = [{ port = 80 }] -} -``` - -In the above code, we defined a configuration using the `App` schema, where we configured an `nginx` container and configured it with an `80` service port. - -Besides, KCL allows developers to define the resources required for their applications in a declarative manner and is tied to a platform such as Docker Compose or Kubernetes manifests and allows to generate a platform-specific configuration file such as `docker-compose.yaml` or a Kubernetes `manifests.yaml` file. Next, let's generate the corresponding configuration. - -### 2. Transform the Application Config into Docker Compose Config - -If we want to transform the application config into the docker compose config, we can run the command simply: - -```shell -kcl main.k docker_compose_render.k -``` - -The output is - -```yaml -services: - app: - image: nginx - ports: - - published: 80 - target: 80 - protocol: TCP -``` - -### 3. Transform the Application Config into Kubernetes Deployment and Service Manifests - -If we want to transform the application config into the Kubernetes manifests, we can run the command simply: - -```shell -kcl main.k kubernetes_render.k -``` - -The output is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: app - labels: - app: app -spec: - replicas: 1 - selector: - matchLabels: - app: app - template: - metadata: - labels: - app: app - spec: - containers: - - name: nginx - image: nginx - ports: - - protocol: TCP - containerPort: 80 ---- -apiVersion: v1 -kind: Service -metadata: - name: app - labels: - app: app -spec: - selector: - app: app - ports: - - port: 80 - protocol: TCP -``` - -Look, it's so simple. If you want to learn more information about the application model, you can refer to [here](https://github.com/kcl-lang/kcl-lang.io/tree/main/examples/abstraction). - -## Summary - -Through the use of KCL, we are able to separate the abstraction and implementation details of a model, allowing for the abstract model to be mapped to various infrastructures or platforms. This is achieved through flexible switching between different implementations and the combination of compilation, which shields configuration differences and ultimately reduces the cognitive burden. - -## Further Information - -In addition to manually maintaining the configuration, we can also use KCL APIs to integrate **automatic configuration changes** into our applications. For specific instructions, please refer to [here](/docs/user_docs/guides/automation). diff --git a/versioned_docs/version-0.5.0/user_docs/guides/automation.md b/versioned_docs/version-0.5.0/user_docs/guides/automation.md deleted file mode 100644 index 624e4b7e..00000000 --- a/versioned_docs/version-0.5.0/user_docs/guides/automation.md +++ /dev/null @@ -1,185 +0,0 @@ ---- -title: "Automation" -sidebar_position: 6 ---- - -## Introduction - -KCL provides many automation related capabilities, mainly including tools and multilingual APIs. Via `package_identifier : key_identifier` mode, KCL supports the indexing of any configured key value, thus completing the addition, deletion, modification and query of any key value. For example, the following figure shows that we can directly execute the following command to modify the image. The code diff before and after modification is also shown in the figure. - -![](/img/blog/2022-09-15-declarative-config-overview/14-kcl-image-update.png) - -In addition, the automation capability of KCL can be realized and integrated into CI/CD. - -![](/img/blog/2022-09-15-declarative-config-overview/15-kcl-automation.png) - -## Use KCL for Automation - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/automation -``` - -We can run the following command to show the config. - -```bash -cat main.k -``` - -The output is - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "app" - replicas = 1 - labels.key = "value" -} -``` - -We can run the command to get the config - -```bash -kcl main.k -``` - -The output is - -```yaml -app: - name: app - replicas: 1 - labels: - app: app - key: value -``` - -### 2. Use KCL CLI for Automation - -KCL allows us to directly modify the values in the configuration model through the KCL CLI `-O|--overrides` parameter. The parameter contains three parts e.g., `pkg`, `identifier`, `attribute` and `override_value`. - -```bash -kcl main.k -O override_spec -``` - -- `override_spec` represents a unified representation of the configuration model fields and values that need to be modified - -```bash -override_spec: [[pkgpath] ":"] identifier ("=" value | "-") -``` - -- `pkgpath`: indicates the package path where the identifier needs to be modified, usually in the form of `a.b.c`. For the main package,`pkgpath` is represented as `__ main__`. When omitted or not written, it indicates the main package -- `identifier` indicates the identifier that needs to modify the configuration, usually in the form of `a.b.c`. -- `value` indicates the value of the configuration that needs to be modified, which can be any legal KCL expression, such as number/string literal value, list/dict/schema expression, etc. -- `=` denotes modifying of the value of the identifier. -- `-` denotes deleting of the identifier. - -#### Override Configuration - -Run the command to update the application name. - -```bash -kcl main.k -O app.name='new_app' -``` - -The output is - -```yaml -app: - name: new_app - replicas: 1 - labels: - app: new_app - key: value -``` - -We can see the `name` attribute of the `app` config is updated to `new_app`. - -Besides, when we use KCL CLI `-d` argument, the KCL file will be modified to the following content at the same time. - -```bash -kcl main.k -O app.name='new_app' -d -``` - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "new_app" - replicas = 1 - labels: {key = "value"} -} -``` - -#### Delete Configuration - -Run the command to delete the `key` attribute of `labels`. - -```bash -kcl main.k -O app.labels.key- -``` - -The output is - -```yaml -app: - name: app - replicas: 1 - labels: - app: app -``` - -### 3. Use KCL API for Automation - -In addition, we can automatically modify the configuration attributes through the [multilingual API](/docs/reference/xlang-api/overview). - -Take the RestAPI as an example. The RestAPI service can be started in the following way: - -```bash -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -The service can then be requested via the POST protocol: - -```bash -curl -X POST http://127.0.0.1:2021/api:protorpc/KclvmService.OverrideFile -H 'content-type: accept/json' -d '{ - "file": "main.k", - "specs": ["app.name=\"nginx\""] -}' -``` - -After the service call is completed, main.k will be modified as follows: - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "nginx" - replicas = 1 - labels: { - "key" = "value" - } -} -``` - -## Summary - -The document introduces the automation capabilities of KCL, including tools and multilingual APIs. It supports indexing of any configured key value, allowing for the addition, deletion, modification, and querying of any key value. It can also be integrated into CI/CD. The document provides an example of using KCL to automate configuration management, including using the KCL CLI to override and delete configurations, and using the KCL API to modify configuration attributes. For more information about KCL automation and Override API, please refer to [here](/docs/reference/lang/tour#kcl-cli-variable-override). diff --git a/versioned_docs/version-0.5.0/user_docs/guides/ci-integration/1-github-actions.md b/versioned_docs/version-0.5.0/user_docs/guides/ci-integration/1-github-actions.md deleted file mode 100644 index 9da91d48..00000000 --- a/versioned_docs/version-0.5.0/user_docs/guides/ci-integration/1-github-actions.md +++ /dev/null @@ -1,162 +0,0 @@ ---- -id: github-actions -sidebar_label: Github Actions ---- - -# Github Actions Integration - -## Introduction - -In the GitOps section, we have introduced how to integrate KCL with GitOps. In this section, we will continue to provide sample solutions for KCL and CI integrations. We hope to implement the end-to-end application development process by using containers, Continuous Integration (CI) for generation, and GitOps for Continuous Deployment (CD). In this scheme, we use a **Flask application** and **Github Actions** as examples. - -> Note: You can use any containerized application and different CI systems such as **Gitlab CI**, **Jenkins CI**, etc. in this solution. - -The overall workflow is as follows: - -- Develop application code and submit it to the GitHub repository to trigger CI. -- GitHub Actions generate container images from application code and push them to the `docker.io` container registry. -- GitHub Actions automatically synchronizes and updates the KCL manifest deployment file based on the version of the container image in the docker.io container registry. - -## How to - -### 1. Get the Example - -We put the application source code and infrastructure deployment code in different repos, which can be maintained by different roles to achieve the separation of concerns. - -- Get the application code - -```shell -git clone https://github.com/kcl-lang/flask-demo.git/ -cd flask-demo -``` - -This is a web application written in Python. We can use the `Dockerfile` in the application directory to generate a container image of this application, and also use Github CI to automatically build a image named `flask_demo`, the CI configuration is as follows - -```yaml -# This is a basic workflow to help you get started with Actions - -name: CI - -# Controls when the workflow will run -on: - # Triggers the workflow on push or pull request events but only for the main branch - push: - branches: [main] - pull_request: - branches: [main] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "build" - build: - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - - - name: Docker Login - uses: docker/login-action@v1.10.0 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - logout: true - - # Runs a set of commands using the runners shell - - name: build image - run: | - make image - docker tag flask_demo:latest ${{ secrets.DOCKER_USERNAME }}/flask_demo:${{ github.sha }} - docker push ${{ secrets.DOCKER_USERNAME }}/flask_demo:${{ github.sha }} - - # Trigger KCL manifest - - name: Trigger CI - uses: InformaticsMatters/trigger-ci-action@1.0.1 - with: - ci-owner: kcl-lang - ci-repository: flask-demo-kcl-manifests - ci-ref: refs/heads/main - ci-user: kcl-bot - ci-user-token: ${{ secrets.DEPLOY_ACCESS_TOKEN }} - ci-name: CI - ci-inputs: >- - image=${{ secrets.DOCKER_USERNAME }}/flask_demo - sha-tag=${{ github.sha }} -``` - -We need the workflow in the source code repository to automatically trigger the workflow in the deployment manifest repository. At this point, we need to create a `secrets.DEPLOY_ACCESS_TOKEN` with Github CI operation permissions and **Docker Hub** image push account information `secrets.DOCKER_USERNAME` and `secrets.DOCKER_PASSWORD` can be configured in the `Secrets and variables` settings of the Github, as shown in the following figure - -![](/img/docs/user_docs/guides/ci-integration/github-secrets.png) - -### 2. Commit the Application Code - -After submitting in the `flask-demo` repository, Github will automatically build a container image and push it to the Docker hub. It will also then trigger the Action of the `flask-demo-kcl-manifest` repository and modify the image value in the deployment manifest repository through [KCL Automation API](/docs/user_docs/guides/automation). Now let's create a submission in the `flask-demo` repository, and we can see that the code submission triggers the Github CI process for the application repository. - -![](/img/docs/user_docs/guides/ci-integration/app-ci.png) - -### 3. Configuration Automatic Update - -After the Github CI process in the application repository is completed, an automatic update configuration CI will be triggered in the repository where the KCL configuration is stored and submitted to the main branch of the `flask-demo-kcl-manifests` repository. The commit information is as follows - -![](/img/docs/user_docs/guides/ci-integration/image-auto-update.png) - -- We can obtain the deployment manifest source code for compilation and validation - -```shell -git clone https://github.com/kcl-lang/flask-demo-kcl-manifests.git/ -cd flask-demo-kcl-manifests -git checkout main && git pull && kcl -``` - -The output YAML is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - replicas: 1 - selector: - matchLabels: - app: flask_demo - template: - metadata: - labels: - app: flask_demo - spec: - containers: - - name: flask_demo - image: "kcllang/flask_demo:6428cff4309afc8c1c40ad180bb9cfd82546be3e" - ports: - - protocol: TCP - containerPort: 5000 ---- -apiVersion: v1 -kind: Service -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - type: NodePort - selector: - app: flask_demo - ports: - - port: 5000 - protocol: TCP - targetPort: 5000 -``` - -From the above configuration, it can be seen that the image of the resource is indeed automatically updated to the newly constructed image value. In addition, we can also use the **Argo CD KCL plugin** to automatically synchronize data from the Git repository and deploy the application to the Kubernetes cluster. - -## Summary - -By integrating KCL and Github CI, we can integrate the container build and delivery workflow by automatically updating the image values in the configuration, in order to achieve end-to-end application development process and improve R&D deployment efficiency. diff --git a/versioned_docs/version-0.5.0/user_docs/guides/ci-integration/2-gitlab-ci.md b/versioned_docs/version-0.5.0/user_docs/guides/ci-integration/2-gitlab-ci.md deleted file mode 100644 index 8b928ec9..00000000 --- a/versioned_docs/version-0.5.0/user_docs/guides/ci-integration/2-gitlab-ci.md +++ /dev/null @@ -1,135 +0,0 @@ ---- -id: gitlab-ci -sidebar_label: Gitlab CI ---- - -# Gitlab CI Integration - -## Introduction - -In the GitOps section, we have introduced how to integrate KCL with GitOps. In this section, we will continue to provide sample solutions for KCL and CI integrations. We hope to implement the end-to-end application development process by using containers, Continuous Integration (CI) for generation, and GitOps for Continuous Deployment (CD). In this scheme, we use a **Flask application** and **Gitlab CI** as examples. - -> Note: You can use any containerized application and different CI systems such as **Github Actions**, **Jenkins CI**, etc. in this solution. - -The overall workflow is as follows: - -- Develop application code and submit it to the Gitlab repository to trigger CI. -- Gitlab generate container images from application code and push them to the `docker.io` container registry. -- Gitlab CI automatically synchronizes and updates the KCL manifest deployment file based on the version of the container image in the docker.io container registry. - -## How to - -We put the application source code and infrastructure deployment code in different repos, which can be maintained by different roles to achieve the separation of concerns. - -### 1. Get the Example - -- Get the application code - -```shell -git clone https://gitlab.com/kcl-lang/flask-demo.git/ -cd flask-demo -``` - -This is a web application written in Python. We can use the `Dockerfile` in the application directory to generate a container image of this application, and also use Gitlab CI to automatically build a image named `flask_demo`, the CI configuration is as follows - -```yaml -stages: - - publish - - deploy - -publish: - stage: publish - image: - name: cnych/kaniko-executor:v0.22.0 - entrypoint: [""] - script: - - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json - - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile ./Dockerfile --destination $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA - only: - - main - -deploy: - stage: deploy - image: cnych/kustomize:v1.0 - before_script: - - git remote set-url origin https://gitlab.com/kcl-lang/flask-demo - - git config --global user.email "gitlab@git.local" - - git config --global user.name "GitLab CI/CD" - # Install KCL - - wget -q https://kcl-lang.io/script/install.sh -O - | /bin/bash - script: - - git checkout -B main - - cd deployment - # Image auto update - - /usr/local/kclvm/bin/kcl -d -O config.containers.flask_demo.image="$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" - - git commit -am '[skip ci] image update to $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA' - - git push origin main - only: - - main -``` - -We need the workflow in the source code repository to automatically trigger the workflow in the deployment manifest repository. At this point, we need to config `Settings -> CI/CD -> Variables` including `CI_REGISTRY`, `CI_REGISTRY_IMAGE`, `CI_REGISTRY_USER`, `CI_REGISTRY_PASSWORD`, `CI_USERNAME` and `CI_PASSWORD` and update application code to trigger automation build and deploy. - -![](/img/docs/user_docs/guides/ci-integration/gitlab-ci-variables.jpg) - -### 2. Commit the Application Code - -After submitting in the `flask-demo` repository, Gitlab will automatically build a container image and push it to the Docker hub. It will also then trigger the Action of the `flask-demo-kcl-manifest` repository and modify the image value in the deployment manifest repository through [KCL Automation API](/docs/user_docs/guides/automation). Now let's create a submission in the `flask-demo` repository, and we can see that the code submission triggers the Gitlab CI process for the application repository `Build -> Pipelines` page. - -### 3. Configuration Automatic Update - -After the Gitlab CI process in the application repository is completed, an automatic update configuration CI will be triggered in the repository where the KCL configuration is stored and submitted to the main branch of the `flask-demo` repository. - -- We can obtain the deployment manifest source code for compilation and validation - -```shell -git checkout main && git pull && cd deploy && kcl -``` - -The output YAML is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - replicas: 1 - selector: - matchLabels: - app: flask_demo - template: - metadata: - labels: - app: flask_demo - spec: - containers: - - name: flask_demo - image: "kcllang/flask_demo:6428cff4309afc8c1c40ad180bb9cfd82546be3e" - ports: - - protocol: TCP - containerPort: 5000 ---- -apiVersion: v1 -kind: Service -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - type: NodePort - selector: - app: flask_demo - ports: - - port: 5000 - protocol: TCP - targetPort: 5000 -``` - -From the above configuration, it can be seen that the image of the resource is indeed automatically updated to the newly constructed image value. In addition, we can also use the **Argo CD KCL plugin** to automatically synchronize data from the Git repository and deploy the application to the Kubernetes cluster. - -## Summary - -By integrating KCL and Gitlab CI, we can integrate the container build and delivery workflow by automatically updating the image values in the configuration, in order to achieve end-to-end application development process and improve R&D deployment efficiency. diff --git a/versioned_docs/version-0.5.0/user_docs/guides/ci-integration/_2-gitlab-ci.md b/versioned_docs/version-0.5.0/user_docs/guides/ci-integration/_2-gitlab-ci.md deleted file mode 100644 index 5ec96ce9..00000000 --- a/versioned_docs/version-0.5.0/user_docs/guides/ci-integration/_2-gitlab-ci.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -id: gitlab-ci -sidebar_label: Gitlab CI ---- - -Coming Soon - -## Introduction - -## How to - -## Summary diff --git a/versioned_docs/version-0.5.0/user_docs/guides/ci-integration/_3-jenkins-ci.md b/versioned_docs/version-0.5.0/user_docs/guides/ci-integration/_3-jenkins-ci.md deleted file mode 100644 index f85d231f..00000000 --- a/versioned_docs/version-0.5.0/user_docs/guides/ci-integration/_3-jenkins-ci.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -id: github-ci -sidebar_label: Github CI ---- - -Coming Soon - -## Introduction - -## How to - -## Summary diff --git a/versioned_docs/version-0.5.0/user_docs/guides/ci-integration/_category_.json b/versioned_docs/version-0.5.0/user_docs/guides/ci-integration/_category_.json deleted file mode 100644 index 3145ed7f..00000000 --- a/versioned_docs/version-0.5.0/user_docs/guides/ci-integration/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "CI Integration", - "position": 12 -} \ No newline at end of file diff --git a/versioned_docs/version-0.5.0/user_docs/guides/configuration.md b/versioned_docs/version-0.5.0/user_docs/guides/configuration.md deleted file mode 100644 index 45846db3..00000000 --- a/versioned_docs/version-0.5.0/user_docs/guides/configuration.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -title: "Configuration" -sidebar_position: 1 ---- - -## Introduction - -Configuration is a vital aspect of software systems that are constantly in flux due to evolving business requirements, infrastructure demands, and other factors. Often, changing these systems' behavior quickly can be challenging, especially when doing so requires a costly and time-consuming reconstruction and redeployment process. In such cases, making changes to the business code may not be sufficient. Fortunately, the configuration provides a low-overhead way to modify system functions. For instance, many developers write JSON or YAML files to configure their systems. - -We can store the static configuration in JSON and YAML files as needed. Moreover, the configuration can also be stored in a high-level language that allows for more flexible configuration. This language can be coded, rendered, and statically configured. KCL is a configuration language that offers such functionality. Developers can write KCL code to generate JSON/YAML and other configurations. - -## Use KCL for Configuration - -KCL's core features are its modeling and constraint capabilities, and its basic functions revolve around these two key elements. Additionally, KCL follows a user-centric configuration concept when designing its basic functions. Configuration code has requirements for configuration data constraints, such as type constraints and required/optional constraints on configuration attributes, range constraints, and immutability constraints. These are also some of the core issues that KCL is committed to resolving. - -Now that we have an understanding of KCL's capabilities, let's explore how to use it to generate configurations. - -### 1. Get the Example - -Firstly, let's get the example. - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/configuration -``` - -We can run the following command to show the config. - -```bash -cat nginx.k -``` - -The output is - -```python -schema Nginx: - """Schema for Nginx configuration files""" - http: Http - -schema Http: - server: Server - -schema Server: - listen: int | str # The attribute `listen` can be int type or a string type. - location?: Location # Optional, but must be non-empty when specified - -schema Location: - root: str - index: str - -nginx = Nginx { - http.server = { - listen = 80 - location = { - root = "/var/www/html" - index = "index.html" - } - } -} -``` - -### 2. Generate YAML using KCL - -Run the following command - -```bash -kcl nginx.k -``` - -We can get the output YAML - -```yaml -nginx: - http: - server: - listen: 80 - location: - root: /var/www/html - index: index.html -``` - -### 3. Configuration with Dynamic Parameters - -Besides, we can dynamically receive external parameters through the KCL builtin function `option`. For example, for the following KCL file (db.k), we can use the KCL command line `-D` flag to receive an external dynamic parameter. - -```python -env: str = option("env") or "dev" # The attribute `env` has a default value "den" -database: str = option("database") -hosts = { - dev = "postgres.dev" - stage = "postgres.stage" - prod = "postgres.prod" -} -dbConfig = { - host = hosts[env] - database = database - port = "2023" - conn = "postgres://${host}:${port}/${database}" -} -``` - -```bash -# Use the `-D` flag to input external parameters. -kcl db.k -D database="foo" -``` - -The output is - -```yaml -env: dev -database: foo -hosts: - dev: postgres.dev - stage: postgres.stage - prod: postgres.prod -dbConfig: - host: postgres.dev - database: foo - port: "2023" - conn: "postgres://postgres.dev:2023/foo" -``` - -## Summary - -By using KCL, we can generate low-level data configurations. For different situations, we set dynamic parameters through the `-D` flag to meet the scene requirements. For more KCL features, please refer to [here](/docs/reference/lang/tour). diff --git a/versioned_docs/version-0.5.0/user_docs/guides/data-integration.md b/versioned_docs/version-0.5.0/user_docs/guides/data-integration.md deleted file mode 100644 index 6ba1f6e3..00000000 --- a/versioned_docs/version-0.5.0/user_docs/guides/data-integration.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: "Data Integration" -sidebar_position: 4 ---- - -## Introduction - -In KCL, we can not only compile and output the configuration code written by KCL into YAML format data, but also directly embed JSON/YAML and other data into the KCL language. - -## Use KCL for Data Integration - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/data-integration -``` - -### 2. YAML Integration - -We can run the following command to show the YAML integration config. - -```bash -cat yaml.k -``` - -```python -import yaml - -schema Server: - ports: [int] - -server: Server = yaml.decode("""\ -ports: -- 80 -- 8080 -""") -server_yaml = yaml.encode({ - ports = [80, 8080] -}) -``` - -In the above code, we use the built-in `yaml` module of KCL and its `yaml.decode` function directly integrates YAML data, and uses the `Server` schema to directly verify the integrated YAML data. In addition, we can use `yaml.encode` to serialize YAML data. We can obtain the configuration output through the following command: - -```shell -kcl yaml.k -``` - -The output is - -```yaml -server: - ports: - - 80 - - 8080 -server_yaml: | - ports: - - 80 - - 8080 -``` - -### 3. JSON Integration - -Similarly, for JSON data, we can use `json.encode` and `json.decode` function performs data integration in the same way. - -We can run the following command to show the JSON integration config. - -```bash -cat json.k -``` - -```python -import json - -schema Server: - ports: [int] - -server: Server = json.decode('{"ports": [80, 8080]}') -server_json = json.encode({ - ports = [80, 8080] -}) -``` - -The output of the execution command is: - -```shell -kcl json.k -``` - -```yaml -server: - ports: - - 80 - - 8080 -server_json: '{"ports": [80, 8080]}' -``` - -## Summary - -This document introduces how to perform data integration in KCL, using the built-in yaml and json modules to directly integrate YAML and JSON data into the KCL language, and verify and serialize it using the corresponding decoding and encoding functions. diff --git a/versioned_docs/version-0.5.0/user_docs/guides/gitops/1-quick-start.md b/versioned_docs/version-0.5.0/user_docs/guides/gitops/1-quick-start.md deleted file mode 100644 index 26231885..00000000 --- a/versioned_docs/version-0.5.0/user_docs/guides/gitops/1-quick-start.md +++ /dev/null @@ -1,159 +0,0 @@ ---- -id: gitops-quick-start -sidebar_label: Quick Start ---- - -# Quick Start - -## Introduction - -### What is GitOps - -GitOps is a modern way to do continuous delivery. Its core idea is to have a Git repository which contains environmental and application configurations. An automated process is also needed for sync the config to cluster. - -By changing the files in repository, developers can apply the applications automatically. The benefits of applying GitOps include: - -- Increased productivity. Continuous delivery can speed up the time of deployment. -- Lower the barrier for developer to deploy. By pushing code instead of container configuration, developers can easily deploy Kubernetes without knowing its internal implementation. -- Trace the change records. Managing the cluster with Git makes every change traceable, enhancing the audit trail. -- Recover the cluster with Git's rollback and branch. - -### GitOps with KCL - -Benefits of Using KCL and ArgoCD Together: - -- KCL can help us **simplify complex Kubernetes deployment configuration files**, reduce the error rate of manually writing YAML files, and improve code readability and maintainability. -- ArgoCD can **automate** the deployment of Kubernetes applications, achieve continuous deployment, and provide comprehensive monitoring and control functions. -- By combining KCL and ArgoCD, deployment efficiency can be improved, errors reduced, and management and monitoring of Kubernetes applications strengthened. -- The combination of KCL and ArgoCD can also help us achieve **Infrastructure as Code (IaC)**, simplify application deployment and management, and better implement DevOps principles. - -With GitOps, developer and operation teams can manage application deployment and configuration by modifying KCL code and generating YAML files. The GitOps toolchain will automatically synchronize the changes to the Kubernetes cluster, enabling continuous deployment and ensuring consistency. If there are issues, the GitOps toolchain can be used to quickly rollback. - -## How to - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/gitops -``` - -We can run the following command to show the config. - -```bash -cat config/main.k -``` - -The output is - -```python -import .app - -config = app.App { - name = "kcl-guestbook-ui" - containers.guestbook = { - image = "gcr.io/heptio-images/ks-guestbook-demo:0.2" - ports = [{containerPort = 80}] - } - service.ports = [{ port = 80 }] - service.type = "LoadBalancer" -} -``` - -In the above code, we defined a configuration using the `App` schema, where we configured an `gcr.io/heptio-images/ks-guestbook-demo:0.2` container and configured it with an `80` service port. - -### 2. Install Kubernetes and GitOps Tool - -#### Setup Kubernetes Cluster and ArgoCD Controllers - -- Install [K3d](https://github.com/k3d-io/k3d) to create a default cluster. - -```bash -k3d cluster create mycluster -``` - -- Install [ArgoCD](https://github.com/argoproj/argo-cd/releases/). - -```bash -kubectl create namespace argocd -kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml -``` - -- Enable ArgoCD KCL Plugin - -Write the patch YAML configuration file and update the ArgoCD configuration: - -```bash -kubectl apply -f ./install/kcl-cmp.yaml -``` - -After completing the first step, ArgoCD will recognize the KCL plugin, but the KCL plugin has not been loaded into the ArgoCD image. To implement configuration drift detection, we have to tune the Deployment of argocd-repo-server. - -```bash -kubectl -n argocd patch deploy/argocd-repo-server -p "$(cat ./install/patch-argocd-repo-server.yaml)" -``` - -Wait for the init container to complete execution (Running). - -```bash -kubectl get pod -n argocd -l app.kubernetes.io/name=argocd-repo-server -``` - -- To access the ArgoCD web UI - -```bash -kubectl port-forward svc/argocd-server -n argocd 8080:443 -``` - -- Open a browser and go to: `https://localhost:8080` - -- The username is "admin" and password get be obtained from the following command: - -```bash -kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d -``` - -#### Setup ArgoCD CLI - -- Install [ArgoCD CLI](https://github.com/argoproj/argo-cd/releases) - -Use "admin" and password to login to ArgoCD - -```bash -argocd login localhost:8080 -``` - -Create ArgoCD Application - -```bash -argocd app create guestbook \ ---repo https://github.com/kcl-lang/kcl-lang.io \ ---path examples/gitops/config \ ---dest-namespace default \ ---dest-server https://kubernetes.default.svc \ ---config-management-plugin kcl-v1.0 -``` - -If you are using a private repository, you need to configure the private repository access with private key credentials before executing the create command. - -Please refer [Private Repositories](https://argo-cd.readthedocs.io/en/stable/user-guide/private-repositories/#ssh-private-key-credential) for more details. - -After successfully creating, you can see the following output: - -```bash -application 'guestbook' created -``` - -Through the ArgoCD UI, you can see that the created applications have not been synchronized yet. Here, you can manually synchronize or set automatic synchronization. - -![](/img/docs/user_docs/guides/gitops/argocd-kcl-app.jpg) - -For more information on synchronization strategies, see [Sync Options](https://argo-cd.readthedocs.io/en/stable/user-guide/sync-options/) - -![](/img/docs/user_docs/guides/gitops/argocd-kcl-app-dashboard.jpg) - -## Summary - -With GitOps, you can easily manage your applications and configuration in your Kubernetes cluster with KCL, ensuring that your applications are always in the desired state. diff --git a/versioned_docs/version-0.5.0/user_docs/guides/gitops/_category_.json b/versioned_docs/version-0.5.0/user_docs/guides/gitops/_category_.json deleted file mode 100644 index 29a73c67..00000000 --- a/versioned_docs/version-0.5.0/user_docs/guides/gitops/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "GitOps", - "position": 11 -} \ No newline at end of file diff --git a/versioned_docs/version-0.5.0/user_docs/guides/package-management/2-installation.md b/versioned_docs/version-0.5.0/user_docs/guides/package-management/2-installation.md deleted file mode 100644 index 783cde90..00000000 --- a/versioned_docs/version-0.5.0/user_docs/guides/package-management/2-installation.md +++ /dev/null @@ -1,55 +0,0 @@ -# Installation - -## Install `kpm` - -Before installing and using kpm, ensure that KCL compiler has been installed successfully. - -[How to install KCL compiler.](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### Go install - -You can download kpm via go install. - -```shell -go install kcl-lang.io/kpm@latest -``` - -### Download from GITHUB release page - -You can get `kpm` from the [kpm github release](https://github.com/kcl-lang/kpm/releases) and set the `kpm` binary path to the environment variable PATH. - -```shell -# KPM_INSTALLATION_PATH is the path of the `kpm` binary. -export PATH=$KPM_INSTALLATION_PATH:$PATH -``` - -Use the following command to ensure that you install `kpm` successfully. - -```shell -kpm --help -``` - -If you get the following output, you have successfully installed `kpm` and you can proceed to the following steps. - -```shell -NAME: - kpm - kpm is a kcl package manager - -USAGE: - kpm [arguments]... - -COMMANDS: - init initialize new module in current directory - add add new dependency - pkg package a kcl package into tar - metadata output the resolved dependencies of a package - run compile kcl package. - login login to a registry - logout logout from a registry - push push kcl package to OCI registry. - pull pull kcl package from OCI registry. - help, h Shows a list of commands or help for one command - -GLOBAL OPTIONS: - --help, -h show help -``` diff --git a/versioned_docs/version-0.5.0/user_docs/guides/package-management/3-quick-start.md b/versioned_docs/version-0.5.0/user_docs/guides/package-management/3-quick-start.md deleted file mode 100644 index 732a20de..00000000 --- a/versioned_docs/version-0.5.0/user_docs/guides/package-management/3-quick-start.md +++ /dev/null @@ -1,108 +0,0 @@ -# Quick Start - -## 1. Init an Empty KCL Package - -Create a new kcl package named `my_package`. And after we have created the package `my_package`, we need to go inside the package by `cd my_package` to complete the following operations. - -```shell -kpm init my_package && cd my_package -``` - -![kpm_init](/img/docs/user_docs/guides/package-management/gifs/kpm_init.gif) - -`kpm` will create two kcl package configuration files: `kcl.mod` and `kcl.mod.lock` in the directory where you executed the command. - -```shell -- my_package - |- kcl.mod - |- kcl.mod.lock - |- # You can write your kcl program directly in this directory. -``` - -`kcl.mod.lock` is the file generated by `kpm` to fix the dependency version. Do not modify this file manually. - -`kpm` initializes `kcl.mod` for an empty project as shown below: - -```shell -[package] -name = "my_package" -edition = "0.0.1" -version = "0.0.1" -``` - -## 2. Add a Dependency from OCI Registry - -You can then add a dependency to the current kcl package using the `kpm add` command - -As shown below, taking the example of adding a package dependency named `k8s`, the version of the package is `1.27.2`. - -```shell -kpm add k8s:1.27.2 -``` - -![kpm_add_k8s](/img/docs/user_docs/guides/package-management/gifs/kpm_add_k8s.gif) - -You can see that `kpm` adds the dependency you just added to kcl.mod. - -```shell -[package] -name = "my_package" -edition = "0.0.1" -version = "0.0.1" - -[dependencies] -k8s = "1.27.2" # The dependency 'k8s' with version '1.27.2' -``` - -### Write a kcl program that uses the content in `k8s` - -Create the `main.k` file in the current package. - -```shell -- my_package - |- kcl.mod - |- kcl.mod.lock - |- main.k # Your KCL program. -``` - -And write the following into the `main.k` file. - -```kcl -# Import and use the contents of the external dependency 'k8s'. -import k8s.api.core.v1 as k8core - -k8core.Pod { - metadata.name = "web-app" - spec.containers = [{ - name = "main-container" - image = "nginx" - ports = [{containerPort = 80}] - }] -} - -``` - -## 3. Run the KCL Code - -In the `my_package` directory, you can use `kpm` to compile the `main.k` file you just wrote. - -```shell -kpm run -``` - -The output is - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: web-app -spec: - containers: - - image: nginx - name: main-container - ports: - - containerPort: 80 -``` - -![kpm_run](/img/docs/user_docs/guides/package-management/gifs/kpm_run.gif) diff --git a/versioned_docs/version-0.5.0/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md b/versioned_docs/version-0.5.0/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md deleted file mode 100644 index aa9c119d..00000000 --- a/versioned_docs/version-0.5.0/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md +++ /dev/null @@ -1,73 +0,0 @@ -# Share Your Package - -[kpm](https://github.com/kcl-lang/kpm) is a tool for managing kcl packages. This article will guide you on how to use kpm to push your kcl package to an OCI Registry for publication. kpm uses [ghcr.io](https://ghcr.io) as the default OCI Registry, and you can change the default OCI Registry by modifying the kpm configuration file. For information on how to modify the kpm configuration file, see [kpm oci registry](https://github.com/kcl-lang/kpm/blob/main/docs/kpm_oci.md#kpm-registry) - -Here is a simple step-by-step guide on how to use kpm to push your kcl package to ghcr.io. - -## Step 1: Install kpm - -First, you need to install kpm on your computer. You can follow the instructions in the [kpm installation documentation](https://kcl-lang.io/docs/user_docs/guides/package-management/installation). - -## Step 2: Create a ghcr.io token - -If you are using the default OCI Registry of kpm, to push a kcl package to ghcr.io, you need to create a token for authentication. You can follow the instruction. - -- [Creating a ghcr.io access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic) - -## Step 3: Log in to ghcr.io - -After installing kpm and creating a ghcr.io token, you need to log in to ghcr.io using kpm. You can do this using the following command: - -```shell -kpm login ghcr.io -u -p -``` - -Where `` is your GitHub username, `` is the token you created in step 2 - -For more information on how to log in to ghcr.io using kpm, see [kpm login](https://kcl-lang.io/docs/reference/package-management/command-reference/login). - -## Step 4: Push your kcl package - -Now, you can use kpm to push your kcl package to ghcr.io. - -### 1. A valid kcl package - -First, you need to make sure that what you are pushing conforms to the specifications of a kcl package, i.e., it must contain valid kcl.mod and kcl.mod.lock files. - -If you don't know how to get a valid kcl.mod and kcl.mod.lock, you can use the `kpm init` command. - -```shell -# Create a new kcl package named my_package -kpm init my_package -``` - -The `kpm init my_package` command will create a new kcl package `my_package` for you and create the `kcl.mod` and `kcl.mod.lock` files for this package. - -If you already have a directory containing kcl files `exist_kcl_package`, you can use the following command to convert it into a kcl package and create valid `kcl.mod` and `kcl.mod.lock` files for it. - -```shell -# In the exist_kcl_package directory -$ pwd -/home/user/exist_kcl_package - -# Run the `kpm init` command to create the `kcl.mod` and `kcl.mod.lock` files -$ kpm init -``` - -For more information on how to use `kpm init`, see [kpm init](https://kcl-lang.io/docs/reference/package-management/command-reference/init). - -### 2. Pushing the KCL Package - -You can use the following command in the root directory of your `kcl` package: - -```shell -# In the root directory of the exist_kcl_package package -$ pwd -/home/user/exist_kcl_package - -# Pushing the KCL Package to Default OCI Registry -$ kpm push -``` - -After completing these steps, you have successfully pushed your KCL Package to the default OCI Registry. -For more information on how to use `kpm push`, see [kpm push](https://kcl-lang.io/docs/reference/package-management/command-reference/push). diff --git a/versioned_docs/version-0.5.0/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md b/versioned_docs/version-0.5.0/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md deleted file mode 100644 index 3fa5aabe..00000000 --- a/versioned_docs/version-0.5.0/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md +++ /dev/null @@ -1,66 +0,0 @@ -# Share Your Package to docker.io - -[kpm](https://github.com/KusionStack/kpm) is a tool for managing kcl packages. This article will show you how to use kpm to push your kcl packages to docker.io. - -Here is a simple step-by-step guide on how to use kpm to push your kcl package to docker.io. - -## Step 1: Install kpm - -First, you need to install kpm on your computer. You can follow the instructions in the [kpm installation documentation](https://kcl-lang.io/docs/user_docs/guides/package-management/installation). - -## Step 2: Create a docker.io account - -If you want to use `docker.io` as the OCI registry to share your kcl package with others, you need to create a `docker.io` account to support the push of your kcl package. - -## Step 3: Log in to docker.io - -You can use the following command to log in to docker.io. - -```shell -kpm login -u -p docker.io -``` - -Where `` is your `docker.io` username, and `` is your `docker.io` password. - -For more information on how to log in to docker.io using kpm, see [kpm login](https://kcl-lang.io/docs/reference/package-management/command-reference/login). - -## Step 4: Push your kcl package - -Now, you can use kpm to push your kcl package to `docker.io`. - -### 1. A valid kcl package - -First, you need to make sure that what you are pushing conforms to the specifications of a kcl package, i.e., it must contain valid kcl.mod and kcl.mod.lock files. - -If you don't know how to get a valid kcl.mod and kcl.mod.lock, you can use the `kpm init` command. - -Create a new kcl package named `my_package`. - -```shell -kpm init my_package -``` - -The `kpm init my_package` command will create a new kcl package `my_package` for you and create the `kcl.mod` and `kcl.mod.lock` files for this package. - -If you already have a directory containing kcl files `exist_kcl_package`, you can use the following command to convert it into a kcl package and create valid `kcl.mod` and `kcl.mod.lock` files for it. - -Run the `kpm init` command under the `exist_kcl_package` directory. - -```shell -kpm init -``` - -For more information on how to use `kpm init`, see [kpm init](https://kcl-lang.io/docs/reference/package-management/command-reference/init). - -### 2. Pushing the KCL Package - -You can use the following command in the root directory of your `kcl` package: - -Run the `kpm push` command under the `exist_kcl_package` directory. - -```shell -kpm push oci://docker.io//exist_kcl_package -``` - -After completing these steps, you have successfully pushed your KCL Package `exist_kcl_package` to `docker.io`. -For more information on how to use `kpm push`, see [kpm push](https://kcl-lang.io/docs/reference/package-management/command-reference/push). diff --git a/versioned_docs/version-0.5.0/user_docs/guides/package-management/4-how-to/6-push_github_action.md b/versioned_docs/version-0.5.0/user_docs/guides/package-management/4-how-to/6-push_github_action.md deleted file mode 100644 index de88dbcf..00000000 --- a/versioned_docs/version-0.5.0/user_docs/guides/package-management/4-how-to/6-push_github_action.md +++ /dev/null @@ -1,81 +0,0 @@ -# Push Your KCL Package by GitHub Action - -[kpm](https://github.com/KusionStack/kpm) is a tool for managing kcl packages. This article will guide you how to use kpm in GitHub Action to push your kcl package to OCI registry. - -## Step 1: Install kpm - -At first, you need to install kpm on your computer. You can follow [kpm installation document](https://kcl-lang.io/docs/user_docs/guides/package-management/installation). - -## Step 2: Create a GitHub account - -If you already have a GitHub account, you can skip this step. - -[Sign up for a new GitHub account](https://docs.github.com/en/get-started/signing-up-for-github/signing-up-for-a-new-github-account) - -## Step 3: Create a GitHub repository for your KCL package - -### 1. Prepare a GitHub repository for your KCL package - -You need to prepare a GitHub repository for your KCL package. - -[Create a GitHub repository](https://docs.github.com/en/get-started/quickstart/create-a-repo) - -In this repository, add your KCL program, take the repository https://github.com/awesome-kusion/catalog.git as an example, - -```bash -├── .github -│ └── workflows -│ └── push.yaml # github action workflow -├── LICENSE -├── README.md -├── kcl.mod # kcl.mod to define your kcl package -├── kcl.mod.lock # kcl.mod.lock generated by kpm -└── main.k # Your KCL program -``` - -### 2. Set OCI Registry, account and password for your Github repository - -Take docker.io as an example, you can set secrets `REG`, `REG_ACCOUNT` and `REG_TOKEN` for your repository. The value of `REG` is `docker.io`, the value of `REG_ACCOUNT` is your `docker.io` account, and the value of `REG_TOKEN` is your `docker.io` login password. - -[Add secrets to the repository](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) - -If you use `ghcr.io` as `Registry`, you need to use GitHub token as secrets. - -[Create a GitHub Token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token#personal-access-tokens-classic) - -## Step 4: Add your KCL package to the repository and write github action workflow - -Add github action file `.github/workflows/push.yml` to this repository, the content is as follows: - -```yaml -name: KPM Push Workflow - -on: - push: - branches: - - main - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Set up Go 1.21 - uses: actions/setup-go@v2 - with: - go-version: 1.21 - - - name: Install kpm - run: go install kcl-lang.io/kpm@latest - - - name: Login and Push - env: - KPM_REG: ${{ secrets.REG }} - KPM_REPO: ${{ secrets.REG_ACCOUNT }} - run: kpm login -u ${{ secrets.REG_ACCOUNT }} -p ${{ secrets.REG_TOKEN }} ${{ secrets.REG }} && kpm push - - - name: Run kpm project from oci registry - run: kpm run oci://${{ secrets.REG }}/${{ secrets.REG_ACCOUNT }}/catalog --tag 0.0.1 -``` diff --git a/versioned_docs/version-0.5.0/user_docs/guides/schema-definition.md b/versioned_docs/version-0.5.0/user_docs/guides/schema-definition.md deleted file mode 100644 index 6ad910b8..00000000 --- a/versioned_docs/version-0.5.0/user_docs/guides/schema-definition.md +++ /dev/null @@ -1,135 +0,0 @@ ---- -title: "Schema Definition" -sidebar_position: 3 ---- - -## Introduction - -The core scenario of KCL is write configurations and constraints. and a core feature of KCL is **modeling**. The keyword `schema` in KCL can be used to define structures and constraints, such as attribute types, default values, range check, and various other constraints. In addition, structures defined with KCL schema can be used in turn to verify implementation, validate input (JSON, YAML and other structured data) or generate code (multilingual structures, OpenAPI, and so on). - -## Use KCL for Defining Structures and Constraints - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/definition -``` - -We can run the following command to show the config. - -```bash -cat main.k -``` - -The output is - -```python -import .app_module # A relative path import - -app: app_module.App { - domainType = "Standard" - containerPort = 80 - volumes = [ - { - mountPath = "/tmp" - } - ] - services = [ - { - clusterIP = "None" - $type = "ClusterIP" - } - ] -} -``` - -We put the `app` model into a separate `app_module.k`, then we can use the `import` keyword in `main.k` for modular management, such as the following file structure - -``` -. -├── app_module.k -└── main.k -``` - -The content of `app_module.k` is - -```python -schema App: - domainType: "Standard" | "Customized" | "Global" - containerPort: int - volumes: [Volume] - services: [Service] - - check: - 1 <= containerPort <= 65535 - -schema Service: - clusterIP: str - $type: str - - check: - clusterIP == "None" if $type == "ClusterIP" - -schema Volume: - container: str = "*" # The default value of `container` is "*" - mountPath: str - - check: - mountPath not in ["/", "/boot", "/home", "dev", "/etc", "/root"] -``` - -In the above file, we use the `schema` keyword to define three models `App`, `Service` and `Volume`. The `App` model has four attributes `domainType`, `containerPort`, `volumes` and `services`, where - -- The type of `domainType` is a string literal union type, similar to an "enumeration", which means that the value of `domainType` can only take one of `"Standard"`, `"Customized"` and `"Global"`. -- The type of `containerPort` is an integer (`int`). In addition, we use the `check` keyword to define its value range from 1 to 65535. -- The type of `services` is `Service` schema list type, and we use `?` to mark it as an optional attribute. -- The type of `volumes` is a `Volume` schema list type, and we use `?` to mark it as an optional attribute. - -We can get the YAML output of the `app` instance by using the following command line - -```shell -kcl main.k -``` - -The output is - -```yaml -app: - domainType: Standard - containerPort: 80 - volumes: - - container: "*" - mountPath: /tmp - services: - - clusterIP: None - type: ClusterIP -``` - -### 2. Output Configuration - -We can still get the YAML output of the `app` instance by using the following command line - -```shell -kcl main.k -``` - -The output is - -```yaml -app: - domainType: Standard - containerPort: 80 - volumes: - - container: "*" - mountPath: /tmp - services: - - clusterIP: None - type: ClusterIP -``` - -## Summary - -KCL is a language for defining configurations and constraints, with a core feature of modeling using the schema keyword. This allows for the definition of structures with attributes, default values, range checks, and other constraints. Structures defined using KCL schema can be used to validate data, or generate code. The example demonstrates how to define models using schema, import them for modular management, and output the YAML configuration of an instance of the defined structure using the kcl command. diff --git a/versioned_docs/version-0.5.0/user_docs/guides/validation.md b/versioned_docs/version-0.5.0/user_docs/guides/validation.md deleted file mode 100644 index 486fa619..00000000 --- a/versioned_docs/version-0.5.0/user_docs/guides/validation.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: "Validation" -sidebar_position: 2 ---- - -## Introduction - -Validation is the process of verifying that data is accurate, reliable, and meets certain requirements or constraints. This includes checking the data for completeness, consistency, accuracy, and relevance. Data validation is performed to ensure that the data is fit for its intended purpose and that it can be used effectively and efficiently. - -We can use KCL and its vet tools to manually or automatically perform data validation to ensure data consistency. - -## Use KCL for Validation - -In addition to using KCL code to generate configuration formats such as JSON/YAML, KCL also supports format validation of JSON/YAML data. As a configuration language, KCL covers almost all features of [OpenAPI](https://www.openapis.org/). - -In KCL, a structure definition can be used to validate configuration data. At the same time, it supports user-defined constraint rules through the check block, and writes validation expressions in the schema to check and validate the attributes defined by the schema. It is very clear and simple to check whether the input JSON/YAML satisfies the corresponding schema structure definition and constraints. - -### 1. Get the Example - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/validation -``` - -We can run the following command to show the config. - -```bash -cat schema.k -``` - -```python -schema User: - name: str - age: int - message?: str - data: Data - labels: {str:} - hc: [int] - - check: - age > 10, "age must > 10" - -schema Data: - id: int - value: str -``` - -In the schema, we can use the `check` keyword to write the validation rules of every schema attribute. Each line in the check block corresponds to a conditional expression. When the condition is satisfied, the validation is successful. The conditional expression can be followed by `, "check error message"` to indicate the message to be displayed when the check fails. - -To sum up, the validation kinds supported in KCL schema are: - -| Kind | Method | -| ----------------- | ----------------------------------------------------------------------------------------- | -| Range | Using comparison operators such as `<`, `>` | -| Regex | Using methods such as `match` from the `regex` system module | -| Length | Using the `len` built-in function to get the length of a variable of type `list/dict/str` | -| Enum | Using literal union types | -| Optional/Required | Using optional/required attributes of schema | -| Condition | Using the check if conditional expression | - -### 2. Validate the Data - -There is a JSON format file `data.json`: - -```json -{ - "name": "Alice", - "age": 18, - "message": "This is Alice", - "data": { - "id": 1, - "value": "value1" - }, - "labels": { - "key": "value" - }, - "hc": [1, 2, 3] -} -``` - -Execute the following command: - -```bash -kcl-vet data.json schema.k -``` - -## Summary - -KCL is a configuration language that supports data validation through its structure definition and user-defined constraint rules. Validation kinds supported in KCL schema include range, regex, length, enum, optional/required, and condition. To validate data, a schema is defined with validation rules written using the check keyword, and the data is validated using the validation tool or a visualization product built on top of it. - -## Further Information - -The improvement of KCL validation capabilities will gradually focus on the "static" aspect, that is, at compile time, combined with the ability of formal validation, it can directly analyze whether the data meets the constraints, whether the constraints conflict with each other, etc., and can be exposed in real-time through the IDE. - -We also expect that KCL models and constraints can be managed as a package (this package has only KCL files). For example, the Kubernetes models and constraints can be used out of the box. Users can generate configurations or verify existing configurations, and can simply extend the models and constraints users want through KCL inheritance. diff --git a/versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md b/versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md deleted file mode 100644 index 47bcd213..00000000 --- a/versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: "Adopt From Kubernetes" -sidebar_position: 1 ---- - -## Introduction - -KCL provides many out of the box support for Kubernetes configuration. Through KCL tools, we can integrate Kubernetes Schema and configuration into KCL. This section will introduce how to use KCL to integrate Kubernetes. - -## Quick Start - -### 1. Kubernetes OpenAPI Spec - -Starting from Kubernetes 1.4, the alpha support for the OpenAPI specification (known as Swagger 2.0 before it was donated to the OpenAPI Initiative) was introduced, and the API descriptions follow the [OpenAPI Spec 2.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md). And since Kubernetes 1.5, Kubernetes supports [directly extracting models from source code and then generating the OpenAPI spec file](https://github.com/kubernetes/kube-openapi) to automatically keep the specifications and documents up to date with the operation and models. - -In addition, Kubernetes CRD uses [OpenAPI V3.0 validation](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation) to describe a custom schema (in addition to the built-in attributes apiVersion, Kind, and metadata), that APIServer uses to validate the CR during the resource creation and update phases. - -### 2. KCL OpenAPI Support - -The `kcl-openapi` tool supports extracting and generating KCL schemas from Kubernetes OpenAPI/CRD. the [KCL OpenAPI Spec](/docs/tools/cli/openapi/spec) defines the mapping between the OpenAPI specification and the KCL language features. - -### 3. Migrate From Kubernetes To KCL - -#### 3.1 Write configurations based on the Kusion_Models package - -``We provide an out-of-the-box `kusion_models` package for you to quickly start. It contains a well-designed frontend model called [`Server schema`](https://github.com/KusionStack/konfig/blob/main/base/pkg/kusion_models/kube/frontend/server.k). You can declare the configurations by initializing the `Server schema`. For the description and usage of the schema and its attributes, please refer to the [Server schema documentation](https://kusionstack.io/docs/reference/model/kusion_models/kube/frontend/doc_server).`` - -#### 3.2 Build Your Custom Frontend Models - -The existing KCL Models may not meet your specific business requirements, then you can also design your custom frontend model package. You can design your custom models based on the pre-generated Kubernetes KCL models among all versions. And you can also develop your custom scripts to migrate your configuration data as what `kube2kcl` tool does. - -##### 3.2.1 Get the k8s package - -The [Kubernetes KCL models](https://github.com/orgs/KusionStack/packages/container/package/k8s) among all versions are pre-generated, you get it by executing `kpm add k8s:` under your project. For detailed information about kpm usage, please refer to [kpm quick start guide](https://github.com/kcl-lang/kpm#quick-start). - -Alternatively, if you may want to generate them yourself, please refer to [Generate KCL Packages from Kubernetes OpenAPI Specs](https://github.com/kcl-lang/kcl-openapi/blob/main/docs/generate_from_k8s_spec.md). - -##### 3.2.2 Design Custom Frontend Models - -Since the Kubernetes built-in models are atomistic and kind of complex to beginners, we recommend taking the native model of Kubernetes as the backend output model and designing a batch of frontend models which could become a more abstract, friendlier and simpler interface to the user. You can refer to the design pattern in the [`Server Schema in the Konfig repo`](https://github.com/KusionStack/konfig/blob/main/base/pkg/kusion_models/kube/frontend/server.k). - -##### 3.2.3 Migrate The Configuration Data - -You can develop your custom scripts to migrate your configuration data automatically. KCL will later provide writing scaffolding and writing guidelines for this script. - -### 4. Migrate From Kubernetes CRD - -If you developed CRDs, you can generate the KCL version of the CRD schemas and declare CRs based on that. - -- Generate KCL Schema from CRD - - ``` - kcl-openapi generate model --crd --skip-validation -f - ``` - -- Define CR based on CRDs in KCL - - You can initialize the CRD schema to define a CR, or further, you can use the generated schema as a backend model and design a frontend interface for users to initialize. The practice is similar to what `KCL Models` does on Kubernetes built-in models. - -## Summary - -This section provides a quick start guide for using KCL with OpenAPI and Custom Resource Definitions (CRD). KCL also supports OpenAPI through the `kcl-openapi tool`, which maps OpenAPI specifications to KCL language features. diff --git a/versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md b/versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md deleted file mode 100644 index a312933b..00000000 --- a/versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -title: "Kustomize KCL Plugin" -sidebar_position: 3 ---- - -## Introduction - -[Kustomize](https://github.com/kubernetes-sigs/kustomize) lets you customize raw, template-free YAML files for multiple purposes, leaving the original YAML untouched and usable as is. - -KCL can be used to create functions to mutate and/or validate the YAML Kubernetes Resource Model (KRM) input/output format, and we provide Kustomize KCL functions to simplify the function authoring process. - -## Prerequisites - -- Install [kustomize](https://github.com/kubernetes-sigs/kustomize) - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=kustomize-kcl` only to Deployment resources. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/kustomize-kcl.git -cd ./kustomize-kcl/examples/set-annotation/ -``` - -### 2. Test and Run - -```bash -kustomize fn run ./local-resource/ --dry-run -``` - -The output YAML is - -```yaml -apiVersion: krm.kcl.dev/v1alpha1 -kind: KCLRun -metadata: - name: set-annotation - annotations: - config.kubernetes.io/function: | - container: - image: docker.io/kcllang/kustomize-kcl:v0.2.0 - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml -# EDIT THE SOURCE! -# This should be your KCL code which preloads the `ResourceList` to `option("resource_list") -spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "kustomize-kcl"}} for resource in option("resource_list").items] ---- -apiVersion: v1 -kind: Service -metadata: - name: test - annotations: - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml -spec: - selector: - app: MyApp - ports: - - protocol: TCP - port: 80 - targetPort: 9376 ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx - annotations: - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml - managed-by: kustomize-kcl -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Kustomize KCL Plugin](https://github.com/kcl-lang/kustomize-kcl) diff --git a/versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md b/versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md deleted file mode 100644 index fb879992..00000000 --- a/versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: "Helmfile KCL Plugin" -sidebar_position: 5 ---- - -## Introduction - -[Helmfile](https://github.com/helmfile/helmfile) is a declarative spec for deploying helm charts. It lets you... - -- Keep a directory of chart value files and maintain changes in version control. -- Apply CI/CD to configuration changes. -- Periodically sync to avoid skew in environments. - -KCL can be used to create functions to mutate and/or validate the YAML Kubernetes Resource Model (KRM) input/output format, and we provide Kustomize KCL functions to simplify the function authoring process. - -## Prerequisites - -- Install [helmfile](https://github.com/helmfile/helmfile) -- Prepare a Kubernetes cluster - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=helmfile-kcl` only to Deployment resources. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/helmfile-kcl.git -cd ./helmfile-kcl/examples/hello-world/ -``` - -We can execute the command to show config - -```bash -cat helmfile.yaml -``` - -The output is - -```yaml -repositories: - - name: prometheus-community - url: https://prometheus-community.github.io/helm-charts - -releases: - - name: prom-norbac-ubuntu - namespace: prometheus - chart: prometheus-community/prometheus - set: - - name: rbac.create - value: false - transformers: - # Use KCL Plugin to mutate or validate Kubernetes manifests. - - apiVersion: krm.kcl.dev/v1alpha1 - kind: KCLRun - metadata: - name: "set-annotation" - annotations: - config.kubernetes.io/function: | - container: - image: docker.io/kcllang/kustomize-kcl:v0.2.0 - spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "helmfile-kcl"}} for resource in option("resource_list").items] -``` - -In the above config, we use a `KCLRun` plugin to assign the `transfomer` field. This means that we will add annotations to all deployment resources in the prometheus helm chart. - -### 2. Test and Run - -```bash -helmfile apply -``` - -The output is - -```bash -Adding repo prometheus-community https://prometheus-community.github.io/helm-charts -"prometheus-community" has been added to your repositories - -... -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Kustomize KCL Plugin](https://github.com/kcl-lang/kustomize-kcl) diff --git a/versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json b/versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json deleted file mode 100644 index 6e90c03c..00000000 --- a/versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Mutate or Validate Kubernetes Manifests", - "position": 3 -} diff --git a/versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/_category_.json b/versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/_category_.json deleted file mode 100644 index 42681f2b..00000000 --- a/versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Kubernetes", - "position": 9 -} diff --git a/versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/index.md b/versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/index.md deleted file mode 100644 index 8d6340de..00000000 --- a/versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/index.md +++ /dev/null @@ -1 +0,0 @@ -# Kubernetes diff --git a/versioned_docs/version-0.5.0/user_docs/guides/working-with-konfig/_category_.json b/versioned_docs/version-0.5.0/user_docs/guides/working-with-konfig/_category_.json deleted file mode 100644 index a71426f9..00000000 --- a/versioned_docs/version-0.5.0/user_docs/guides/working-with-konfig/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Konfig", - "position": 10 -} diff --git a/versioned_docs/version-0.5.0/user_docs/guides/working-with-kusion/_category_.json b/versioned_docs/version-0.5.0/user_docs/guides/working-with-kusion/_category_.json deleted file mode 100644 index 89134bd9..00000000 --- a/versioned_docs/version-0.5.0/user_docs/guides/working-with-kusion/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KusionStack", - "position": 13 -} diff --git a/versioned_docs/version-0.5.1/reference/lang/error/exception.md b/versioned_docs/version-0.5.1/reference/lang/error/exception.md deleted file mode 100644 index 92c527a6..00000000 --- a/versioned_docs/version-0.5.1/reference/lang/error/exception.md +++ /dev/null @@ -1,1427 +0,0 @@ ---- -title: "KCL Errors and Warnings" -linkTitle: "KCL Errors and Warnings" -type: "docs" -weight: 2 -description: KCL Errors and Warnings ---- - -The articles in this section of the documentation explain the diagnostic error and warning messages that are generated by the KCL. - -**Important:** -**The KCL can report many kinds of errors and warnings. After an error or warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not apply to your project. When you correct issues in your project, always start with the first error or warning that's reported and rebuild often. One fix may make many subsequent errors go away.** - -In the following sections you will find: - -[KCL Syntax Error (E1xxx)](#11-kcl-syntax-error-e1xxx) : The KCL may reports KCL syntax errors when illegal syntax is used in KCL program. - -[KCL Compile Error (E2xxx)](#12-kcl-compile-error-e2xxx): The KCL may reports KCL compile errors when the KCL program conforms to the KCL syntax but does not conform to the KCL semantics. - -[KCL Runtime Error (E3xxx)](#13-kcl-runtime-error-e3xxx): The KCL may report KCL runtime errors when the virtual machine executing a KCL program that passes the compilation. - -[KCL Compile Warning (W2xxx)](#14-kcl-compile-warning-w2xxx): When the compiler compiles KCL programs and finds possible potential errors, such warnings will be reported by KCL. - -## 1.1 KCL Syntax Error (E1xxx) - -This section mainly includes KCL errors: - -| ewcode | KCL exception | messages | -| ------ | ------------------------------------------------------------------- | ----------------------- | -| E1001 | [InvalidSyntaxError](#111-invalidsyntaxerror-e1001) | Invalid syntax | -| E1002 | [KCLTabError](#112-kcltaberror-e1002) | Tab Error | -| E1003 | [KCLIndentationError](#113-kclindentationerrore1003) | Indentation Error | -| E1I37 | [IllegalArgumentSyntaxError](#114-illegalargumentsyntaxerror-e1i37) | Illegal argument syntax | - -### 1.1.1 InvalidSyntaxError (E1001) - -KCL will report `InvalidSyntaxError` when KCL has a syntax error. - -The `ewcode` of `InvalidSyntaxError` is `E1001`. - -For example: - -```python -a, b = 1, 2 # Multiple assign is illegal in KCL syntax -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> /syntax_error/general/multiple_assign/case0/main.k:1:2 - | -1 | a, b = 1, 2 # Multiple assign is illegal in KCL syntax - | ^ expected statement - | -``` - -Possible resolution: - -- Check and fix KCL syntax errors based on the KCL Language Standard - -### 1.1.2 KCLTabError - -KCL will report `KCLTabError` when KCL has a tab and white space syntax error. - -In KCL, it is forbidden to mix tabs and four spaces in one indentation block. And we recommend only using white spaces or tabs for indentation in the entire KCL project, don’t mix them. - -For example: - -```python -schema Person: - name: str # begin with a tab - age: int # begin with four white spaces, - # and four white spaces != tab in the env -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> File /syntax_error/tab/tab_error_0/main.k:6:5 - | -3 | age: int = 1 - | ^ inconsistent use of tabs and spaces in indentation - | -``` - -Possible resolution: - -- Only use a tab or four white spaces in KCL, do not mix them. - -### 1.1.3 KCLIndentationError - -KCL will report `KCLIndentationError` when KCL has an indentation syntax error. - -The KCL syntax includes indentation. A tab or four white spaces in KCL represents an indentation. The other cases will be regarded as syntax errors by KCL. - -For example: - -```python -schema Person: - name: str # a tab or four white spaces is legal. - age: int # three white spaces are illegal - info: str # two white spaces is illegal -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> /syntax_error/indent/indent_error_0/main.k:3:4 - | -3 | age: int # three white spaces are illegal - | ^ unindent 3 does not match any outer indentation level - | -``` - -Possible resolution: - -- Only use a tab or four white spaces in the KCL program for indentation. - -### 1.1.4 IllegalArgumentSyntaxError (E1I37) - -KCL will report `IllegalArgumentSyntaxError` when KCL has an illegal argument in KCL syntax. - -For example: - -```python -# Parameters without default values -# must be in front of parameters with default values. -a = option(type="list", default={"key": "value"}, "key1") -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> /option/type_convert_fail_2/main.k:3:57 - | -3 | a = option(type="list", default={"key": "value"}, "key1") - | ^ positional argument follows keyword argument - | -``` - -Possible resolution: - -```python -func(input_1, ..., input_n, param_with_key_1 = input_with_key_1, ..., param_with_key_n = input_with_key_n) -``` - -## 1.2 KCL Compile Error (E2xxx) - -This section mainly includes KCL errors: - -| ewcode | KCL exception | messages | -| ------ | ---------------------------------------------------------------------- | --------------------------------------------------- | -| E2F04 | [CannotFindModule](#121-cannotfindmodulee2f04) | Cannot find the module | -| E2F05 | [FailedLoadModule](#122-failedloadmodulee2f05) | Failed to load module | -| E2H13 | [UnKnownDecoratorError](#123-unknowndecoratorerrore2h13) | UnKnown decorator | -| E2H14 | [InvalidDecoratorTargetError](#124-invaliddecoratortargeterrore2h14) | Invalid Decorator Target | -| E2C15 | [MixinNamingError](#125-mixinnamingerrore2c15) | Illegal mixin naming | -| E2C16 | [MixinStructureIllegal](#126-mixinstructureillegale2c16) | Illegal mixin structure | -| E2B17 | [CannotAddMembersComplieError](#127-cannotaddmemberscomplieerrore2b17) | Cannot add members to a schema | -| E2B20 | [IndexSignatureError](#128-indexsignatureerrore2b20) | Invalid index signature | -| E2G22 | [TypeComplieError](#129-typecomplieerrore2g22) | The type got is inconsistent with the type expected | -| E2L23 | [CompileError](#1210-compileerrore2l23) | A complie error occurs during compiling | -| E2L25 | [KCLNameError](#1211-kclnameerrore2l25) | Name Error | -| E2L26 | [KCLValueError](#1212-kclvalueerrore2l26) | Value Error | -| E2L27 | [KCLKeyError](#1213-kclkeyerrore2l27) | Key Error | -| E2L28 | [UniqueKeyError](#1214-uniquekeyerrore2l28) | Unique key error | -| E2A29 | [KCLAttributeComplieError](#1215-kclattributecomplieerrore2a29) | Attribute error occurs during compiling | -| E2D32 | [MultiInheritError](#1216-multiinheriterrore2d32) | Multiple inheritance is illegal | -| E2D34 | [IllegalInheritError](#1217-illegalinheriterrore2d34) | Illegal inheritance | -| E2I36 | [IllegalArgumentComplieError](#1218-illegalargumentcomplieerrore2i36) | Illegal argument during compiling | -| E3L41 | [ImmutableCompileError](#1219-immutablecompileerror-e3l41) | Immutable variable is modified | - -### 1.2.1 CannotFindModule(E2F04) - -KCL will report `CannotFindModule` when KCL imports a module that does not exist. - -The `ewcode` of `CannotFindModule` is `E2F04`. - -For example: - -```python -import .some0.pkg1 as some00 # some0 not found in package - -Name1 = some00.Name # some0.pkg1.name -``` - -The KCL program will cause the following error message. - -```shell -error[E2F04]: CannotFindModule - --> import_abs_fail_0/app-main/main.k:1:1 - | -1 | import .some0.pkg1 as some00 # some0 not found in package - | Cannot find the module .some0.pkg1 - | -``` - -Possible resolution: - -- Add the import module file under the import path. - -### 1.2.2 FailedLoadModule(E2F05) - -KCL will report `FailedLoadModule` when an error occurs during loading a KCL external package. - -The `ewcode` of `FailedLoadModule` is `E2F05`. - -Possible resolution: - -- Check whether the module file is readable. -- Check whether the module file is a KCL file. - -### 1.2.3 UnKnownDecoratorError(E2H13) - -KCL will report `UnKnownDecoratorError` when an unknown decorator is used in KCL. - -The `ewcode` of `UnKnownDecoratorError` is `E2H13`. - -For example: - -```python -@err_deprecated # It is an unknown decorator -schema Person: - firstName: str = "John" - lastName: str - name: str - -JohnDoe = Person { - name: "deprecated" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> deprecated/unknown_fail_1/main.k:1:2 - | -1 | @err_deprecated # 这是一个非法的装饰器 - | ^ UnKnown decorator err_deprecated - | -``` - -Possible resolution: - -- Check whether the decorator exists. - -### 1.2.4 InvalidDecoratorTargetError(E2H14) - -KCL will report `InvalidDecoratorTargetError` when the target cannot be the target of the decorator. - -The `ewcode` of `InvalidDecoratorTargetError` is `E2H14`. - -Possible resolution: - -- Check whether the decorator in KCL is illegal. - -### 1.2.5 MixinNamingError(E2C15) - -KCL will report `MixinNamingError` when a mixin name does not end with 'Mixin'. - -The `ewcode` of `MixinNamingError` is `E2C15`. - -For example: - -```python -schema Person: - firstName: str - lastName: str - fullName: str - -schema Fullname: # It is a mixin, but 'Fullname' is not end with 'Mixin - fullName = "{} {}".format(firstName, lastName) - -schema Scholar(Person): - mixin [Fullname] - school: str - -JohnDoe = Scholar { - "firstName": "John", - "lastName": "Doe", - "fullName": "Doe Jon" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2D34]: IllegalInheritError - --> mixin/invalid_name_failure/main.k:10:12 - | -10 | mixin [Fullname] - | ^ illegal schema mixin object type 'Fullname' - | -``` - -Possible resolution: - -- If the schema is a mixin, then the name of the schema should end with Mixin. - -### 1.2.6 MixinStructureIllegal(E2C16) - -KCL will report `MixinStructureIllegal` when the KCL structure is illegal. - -The `ewcode` of `MixinStructureIllegal` is `E2C16`. - -Possible resolution: - -- Check the structure of schema as Mixin. - -### 1.2.7 CannotAddMembersComplieError(E2B17) - -KCL will report `CannotAddMembersComplieError` when members that are not in the schema are used. - -The `ewcode` of `CannotAddMembersComplieError` is `E2B17`. - -For example: - -```python -schema Girl: - gender: str = "female" - -alice = Girl { - "first": "alice", # "first" can not be found in schema Girl - "last": " Green", # "last" can not be found in schema Girl - "age": 10 # "age" can not be found in schema Girl -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:5:5 - | -5 | "first": "alice", - | ^ Cannot add member 'first' to schema 'Girl' - | - -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:6:5 - | -6 | "last": " Green", - | ^ Cannot add member 'last' to schema 'Girl' - | - -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:7:5 - | -7 | "age": 10 - | ^ Cannot add member 'age' to schema 'Girl' - | -``` - -Possible resolution: - -- Add the members to the schema. -- Remove the using of the members not exists - -### 1.2.8 IndexSignatureError(E2B20) - -The `ewcode` of `IndexSignatureError` is `E2B20`. - -KCL will report `IndexSignatureError` when: - -1. Multiple index signatures in one schema. - -For example: - -```python -schema Data: - [str]: str - [str]: int # Multiple index signatures in one schema. - -data = Data { - name: "test" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError ----> index_signature/fail_1/main.k:3:5 - | -3 | [str]: int - | 5 ^ only one index signature is allowed in the schema - | -``` - -Possible resolution: - -- Remove the extra index signature in the schema. - -2. The name of index signature attributes has the same name that conflicts with other attributes in the schema. - -For example: - -```python -schema Data: - name: str # name - [name: str]: str # the same name with the above attribute - -data = Data { - name: "test" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: IndexSignatureError - --> index_signature/fail_2/main.k:3:5 - | -3 | [name: str]: str # the same name with the above attribute - | ^ index signature attribute name 'name' cannot have the same name as schema attributes - | -``` - -Possible resolution: - -- Remove attributes or index signatures that have conflicts with the same name in the schema, or change their names. - -3. Schema index signature value type has conflicts with the instance of schema. - -For example: - -```python -schema Data: - [str]: int - -data = Data { - name: "test" # Conflict with [str]:int, "test" is a string. -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> index_signature/fail_3/main.k:5:5 - | -5 | name: "test" # Conflict with [str]:int, "test" is a string. - | ^ expected int, got str(test) - | -``` - -Possible resolution: - -- Check that the type of schema index signature is consistent with the attribute type in the schema instance. - -4. Schema index signature has conflicts with schema. - -For example: - -```python -schema Data: - count: int # got int - [str]: str # except str - -data = Data { - count: 1 -} -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: IndexSignatureError - --> index_signature/fail_4/main.k:2:5 - | -2 | count: int - | ^ the type 'int' of schema attribute 'count' does not meet the index signature definition [str]: str - | -``` - -Possible resolution: - -- Change schema for index signature or change index signature for schema. - -### 1.2.9 TypeComplieError(E2G22) - -KCL will report `TypeComplieError` when a type error occurs in compiling type check. - -The `ewcode` of `TypeComplieError` is `E2G22`. - -For example: - -```python -schema Person: - firstName: str - lastName: int - -JohnDoe = Person { - "firstName": "John", - "lastName": "Doe" # Type Error,lastName: int,“Doe” is a string. -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> type/type_fail_0/main.k:7:5 - | -7 | "lastName": "Doe" # Type Error,lastName: int,“Doe” is a string. - | ^ expected int, got str(Doe) - | - - --> type/type_fail_0/main.k:3:5 - | -3 | lastName: int - | ^ variable is defined here, its type is int, but got str(Doe) - | -``` - -Possible resolution: - -- Check that the type of value assigned to a variable is consistent with the type of the variable. - -### 1.2.10 CompileError(E2L23) - -The `ewcode` of `CompileError` is `E2L23`. - -KCL will report `CompileError` when: - -1. unsupport type union. - -For example: - -```python -_data = [1, 2, 3] -_data |= "value" -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> union/fail/fail_1/main.k:2:1 - | -2 | _data |= "value" - | ^ unsupported operand type(s) for |: '[int]' and 'str(value)' - | -``` - -Possible resolution: - -1. unsupported operand type. - -For example: - -```python -a = None -b = 1 + None # Unsupport operand type + for int and None -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> operator/operator_fail_0/main.k:2:5 - | -2 | b = 1 + None # Unsupport operand type + for int and None - | ^ unsupported operand type(s) for +: 'int(1)' and 'NoneType' - | -``` - -Possible resolution: - -- Adjust the operator so that it supports both operand types. -- Adjust the operands so that they conform to the constraints of the operator at the same time. - -1. variable is not defined. - -For example: - -```python -a = 1 -b = "${c + 1}" # 'c' is not defined -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> var_not_define_fail_0/main.k:2:8 - | -2 | b = "${c + 1}" # 'c' is not defined - | ^ name 'c' is not defined - | -``` - -Possible resolution: - -- Define undefined variables. -- Remove the undefined variable from the expression. - -1. invalid assign expression. - -For example: - -```python -# pkg.k -a = 1 - -# main.k -import pkg -pkg.a |= 2 -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> pkg_inplace_modify_1/main.k:3:1 - | -6 | pkg |= 2 - | ^ unsupported operand type(s) for |: 'module 'pkg'' and 'int(2)' - | -``` - -Possible resolution: - -- Check the assignment expression. - -1. invalid string expression. - -For example: - -```python -a = 1 -b = "${b = a + 1}" # Invalid string interpolation expression -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> invalid_format_value_fail_0/main.k:2:5 - | -2 | b = "${b = a + 1}" - | 5 ^ invalid string interpolation expression 'b = a + 1' - | -``` - -Possible resolution: - -- Check the string expression. - -1. invalid loop variable. - -For example: - -```python -data = {"key1": "value1", "key2": "value2"} -dataLoop = [i for i, j, k in data] # the number of loop variables can only be 1 or 2 -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> dict/invalid_loop_var_fail_0/main.k:2:25 - | -2 | dataLoop = [i for i, j, k in data] # the number of loop variables can only be 1 or 2 - | ^ the number of loop variables is 3, which can only be 1 or 2 - | -``` - -### 1.2.11 KCLNameError(E2L25) - -KCL will report `KCLNameError` when a name error occurs in compiling. - -The `ewcode` of `KCLNameError` is `E2L25`. - -### 1.2.12 KCLValueError(E2L26) - -KCL will report `KCLValueError` will be raised when a value error occurs in compiling. - -The `ewcode` of `KCLValueError` is `E2L25`. - -### 1.2.13 KCLKeyError(E2L27) - -KCL will report `KCLKeyError` will be raised when a key error occurs in compiling. - -The `ewcode` of `KCLKeyError` is `E2L25`. - -### 1.2.14 UniqueKeyError(E2L28) - -KCL will report `UniqueKeyError` when duplicate names appear in the KCL code. - -The `ewcode` of `UniqueKeyError` is `E2L28`. - -For example: - -```python -schema Person: - name: str = "kcl" - age: int = 1 - -schema Person: - aa: int - -x0 = Person{} -x1 = Person{age:101} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L28]: UniqueKeyError - --> /schema/same_name/main.k:5:8 - | -5 | schema Person: - | ^ Unique key error name 'Person' - | - - --> /schema/same_name/main.k:1:8 - | -1 | schema Person: - | ^ The variable 'Person' is declared here - | -``` - -Possible resolution: - -- Check if the name with error has been used. - -### 1.2.15 KCLAttributeComplieError(E2A29) - -KCL will report `KCLAttributeComplieError` when KCL has an illegal attribute in the schema. - -The `ewcode` of `KCLAttributeComplieError` is `E2A29`. - -For example: - -```python -# pkg -schema A: - field_A: str - -# main -import pkg as p - -a = p.D + 1 -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> /import/module/no_module_attr_fail_0/main.k:4:5 - | -4 | a = p.D + 1 - | ^ module 'pkg' has no attribute D - | -``` - -Possible resolution: - -- Check for the existence of the schema attribute when using it. - -### 1.2.16 MultiInheritError(E2D32) - -KCL will report `MultiInheritError` when multiple inheritance appears in the schema. - -The `ewcode` of `MultiInheritError` is `E2D32`. - -For example: - -```python -schema Person: - firstName: str - lastName: str - -schema KnowledgeMixin: - firstName: int - subject: str - -schema Scholar(KnowledgeMixin, Person): - school: str -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> /schema/inherit/multi_inherit_fail_1/main.k:9:30 - | -9 | schema Scholar(KnowledgeMixin, Person): - | ^ expected one of [")"] got , - | -``` - -Possible resolution: - -- Check the inheritance structure of the program, and multi-inheritance is not supported in KCL. - -### 1.2.17 IllegalInheritError(E2D34) - -KCL will report `IllegalInheritError` when an illegal inheritance occurs in the schema. - -The `ewcode` of `IllegalInheritError` is `E2D34`. - -For example: - -```python -schema FullnameMixin: - fullName = "{} {}".format(firstName, lastName) - -schema Scholar(FullnameMixin): # mixin inheritance is illegal - school: str -``` - -The KCL program will cause the following error message. - -```shell -error[E2D34]: IllegalInheritError - --> /schema/inherit/inherit_mixin_fail/main.k:4:16 - | -4 | schema Scholar(FullnameMixin): - | ^ invalid schema inherit object type, expect schema, got 'FullnameMixin' - | -``` - -Possible resolution: - -- Schema supports single inheritance of schema in KCL. - -### 1.2.18 IllegalArgumentComplieError(E2I36) - -KCL will report `IllegalArgumentComplieError` when the argument of option in KCL is illegal. - -The `ewcode` of `IllegalArgumentComplieError` is `E2I36`. -For example: - -```python -a = option("key") - -# kcl main.k -D key=value= -# key=value= is an illegal expression -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError -Invalid value for top level arguments -``` - -Possible resolution: - -- Check whether the KCL option arguments are legal. - -### 1.2.19 ImmutableCompileError (E3L41) - -KCL will report `ImmutableCompileError` when the value of the immutable variable changes. - -The `ewcode` of `ImmutableCompileError` is `E3L41`. - -For example: - -```python -a = 2147483646 -a += 1 -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: ImmutableError - --> augment_assign/main.k:2:1 - | -2 | a += 1 - | ^ Immutable variable 'a' is modified during compiling - | - - --> augment_assign/main.k:1:1 - | -1 | a = 2147483646 - | ^ The variable 'a' is declared here firstly - | -note: change the variable name to '_a' to make it mutable -``` - -Possible resolution: - -- Set immutable variables changed to private or remove immutable variables. - -## 1.3 KCL Runtime Error (E3xxx) - -This section mainly includes KCL errors: - -| ewcode | KCL exception | messages | -| ------ | ---------------------------------------------------------------------- | --------------------------------------------------- | -| E3F06 | [RecursiveLoad](#131-recursiveload-e3f06) | Recursively loading module | -| E3K04 | [FloatOverflow](#132-floatoverflow-e3k04) | Float overflow | -| E3K09 | [IntOverflow](#133-intoverflow-e3k09) | Integer overflow | -| E3N11 | [DeprecatedError](#134-deprecatederror-e3n11) | Deprecated error | -| E3A30 | [KCLAttributeRuntimeError](#135-kclattributeruntimeerror-e3a30) | Attribute error occurs at runtime | -| E3G21 | [TypeRuntimeError](#136-typeruntimeerror-e3g21) | The type got is inconsistent with the type expected | -| E3B17 | [SchemaCheckFailure](#137-schemacheckfailure-e3b17) | Schema check is failed to check condition | -| E3B19 | [CannotAddMembersRuntimeError](#138-cannotaddmembersruntimeerrore3b19) | Cannot add members to a schema | -| E3M38 | [EvaluationError](#139-evaluationerrore3m38) | Evaluation failure | -| E3M39 | [InvalidFormatSpec](#1310-invalidformatspec-e3m39) | Invalid format specification | -| E3M40 | [KCLAssertionError](#1311-kclassertionerror-e3m40) | Assertion failure | -| E3M44 | [ImmutableRuntimeError](#1312-immutableruntimeerror-e3m44) | Immutable variable is modified | -| E2D33 | [CycleInheritError](#1313-cycleinheriterror-e2d33) | Cycle Inheritance is illegal | -| E3M42 | [KCLRecursionError](#1314-kclrecursionerror-e3m42) | Recursively reference | - -### 1.3.1 RecursiveLoad (E3F06) - -KCL will report `RecursiveLoad` when a cycle import of external packages occurs in KCL. - -The `ewcode` of `RecursiveLoad` is `E2F06`. - -For example: - -```python -# module.k -import main # module.k imports main.k - -print('module') - -# main.k -import module # main.k imports module.k - -print('main') -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /import/recursive_import_fail/main.k:4 - | -2 | import module # main.k imports module.k - | ^ There is a circular import reference between module main and module - | -``` - -Possible resolution: - -- Check whether there is a circle import in KCL. - -### 1.3.2 FloatOverflow (E3K04) - -KCL will report `FloatOverflow` when a floating-point number overflows in KCL. - -The `ewcode` of `FloatOverflow` is `E3K04`. - -For example: - -```python -uplimit = 3.402823466e+39 -epsilon = 2.220446049250313e-16 -a = uplimit * (1 + epsilon) - -# kcl main.k -r -d -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /range_check_float/overflow/number_0/main.k:3:1 - | -3 | a = uplimit * (1 + epsilon) - | 3.4028234660000003e+39: A 32-bit floating point number overflow - | -``` - -Possible resolution: - -- Check whether the value of the float is the float range supported by KCL. - -### 1.3.3 IntOverflow (E3K09) - -KCL will report `IntOverflow` when an integer number overflows in KCL. - -The `ewcode` of `IntOverflow` is `E3K09`. - -For example: - -```python -_a = 9223372036854775807 -_a += 1 - -# kcl test.k -d -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /range_check_int/augment_assign_fail_1/main.k:2:1 - | -2 | _a += 1 - | 9223372036854775808: A 64 bit integer overflow - | -``` - -Possible resolution: - -- Check whether the value of the integer is the integer range supported by KCL. - -### 1.3.4 DeprecatedError (E3N11) - -KCL will report `DeprecatedError` when a deprecated variable is used and the strict is True. - -The `ewcode` of `DeprecatedError` is `E3N11`. - -For example: - -```python -schema Person: - firstName: str = "John" - lastName: str - @deprecated(version="1.16", reason="use firstName and lastName instead", strict=True) - name: str - -JohnDoe = Person { - name: "deprecated" # name is deprecated and strict is True -} -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /range_check_float/overflow/number_0/main.k:7:1 - | -7 | JohnDoe = Person { - | name was deprecated since version 1.16, use firstName and lastName instead - | -``` - -Possible resolution: - -- When strict is set to True, using deprecated code will cause an error and stop KCL. -- You can set the strict to False which will cause a warning insteads of an error. -- Adjust the code without using deprecated code. - -### 1.3.5 KCLAttributeRuntimeError (E3A30) - -KCL will report `KCLAttributeRuntimeError`, if an error occurs during dynamically accessing schema attributes through variables at runtime. - -The `ewcode` of `KCLAttributeRuntimeError` is `E3A30`. - -For example: - -```python -import math - -a = math.err_func(1) # err_func is not found in math -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /import/module/no_module_attr_fail_2/main.k:3:5 - | -3 | a = math.err_func(1) # err_func is not found in math - | ^ module 'math' has no attribute err_func - | -``` - -Possible resolution: - -- Check whether the attributes of schema are correct. - -### 1.3.6 TypeRuntimeError (E3G21) - -KCL will report `TypeRuntimeError` when an type error occurs in the runtime type check. - -The `ewcode` of `TypeRuntimeError` is `E3G21`. - -For example: - -```python -schema Person: - name: str = "Alice" - -_personA = Person {} -_personA |= {"name" = 123.0} # name: str = "Alice" -personA = _personA -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /fail/fail_4/main.k:2:1 - | -2 | name: str = "Alice" - | expect str, got float - | -``` - -Possible resolution: - -- Stop the wrong type union or adjust to the type union supported by KCL. - -### 1.3.7 SchemaCheckFailure (E3B17) - -KCL will report `SchemaCheckFailure` when the schema check conditions are not met. - -The `ewcode` of `SchemaCheckFailure` is `E3B17`. - -For example: - -```python -schema Person: - lastName: str - age: int - check: - age < 140, "age is too large" - -JohnDoe = Person { - "lastName": "Doe", - "age": 1000 # the check condition: age < 140 -} -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /check_block/check_block_fail_1/main.k:7:11 - | -7 | JohnDoe = Person { - | ^ Instance check failed - | - - --> /check_block/check_block_fail_1/main.k:5:1 - | -5 | age < 140, "age is too large" - | Check failed on the condition - | -``` - -Possible resolution: - -- Check whether the attributes of schema can satisfy the conditions in check. - -### 1.3.8 CannotAddMembersRuntimeError(E3B19) - -KCL will report `CannotAddMembersRuntimeError` when members that are not in the schema are used. - -The `ewcode` of `CannotAddMembersRuntimeError` is `E3B19`. - -For example: - -```python -schema Name: - name: str - -schema Person: - name: Name - -person = Person { - name.err_name: "Alice" # err_name is not found in schema Name -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /nest_var/nest_var_fail_1/main.k:8:5 - | -8 | name.err_name: "Alice" # err_name is not found in schema Name - | ^ Cannot add member 'err_name' to schema 'Name' - | -``` - -Possible resolution: - -- Add a non-existent member to the schema. -- Access members that exist in the schema. - -### 1.3.9 EvaluationError(E3M38) - -KCL will report `EvaluationError` when an illegal evaluation occurs in KCL. - -The `ewcode` of `EvaluationError` is `E3M38`. - -For example: - -```python -_list1 = [1, 2, 3] # _list1 is a variable, and its type can only be known at runtime -_list2 = None # _list1 is a variable, and its type can only be known at runtime - -result2 = _list1 + _list2 # list + NoneType is illegal -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /datatype/list/add_None_fail/main.k:1 - | -4 | result2 = _list1 + _list2 # list + NoneType is illegal - | can only concatenate list (not "NoneType") to list - | -``` - -Possible resolution: - -- Check whether the evaluation of the expression is legal. - -### 1.3.10 InvalidFormatSpec (E3M39) - -KCL will report `InvalidFormatSpec` when an illegal string format appears in KCL. - -The `ewcode` of `InvalidFormatSpec` is `E3M39`. - -For example: - -```python -a = 1 -b = 1 -data = "${a: #js}" + " $$ " # #js is illegal string -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /datatype/str_interpolation/invalid_format_spec_fail_0/main.k:3 - | -3 | data = "${a: #js}" + " $$ " # #js is illegal string - | ^ #js is a invalid format spec - | -``` - -Possible resolution: - -- Adjust illegal String to String supported by KCL standards. - -### 1.3.11 KCLAssertionError (E3M40) - -KCL will report `KCLAssertionError` when assert False occurs in KCL. - -The `ewcode` of `KCLAssertionError` is `E3M40`. - -For example: - -```python -assert False -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /assert/invalid/fail_0/main.k:1 - | -1 | assert False - | - | -``` - -Possible resolution: - -- Check the condition of Assert, and when the Assert condition is False, such an error occurs, removing the Assert statement or changing the condition to True. - -### 1.3.12 ImmutableRuntimeError (E3M44) - -KCL will report `ImmutableRuntimeError` when the value of the immutable variable changes. - -The `ewcode` of `ImmutableRuntimeError` is `E3M44`. - -For example: - -```python -schema Person: - final firstName : str - lastName : str - -schema Scholar(Person): - firstName = "CBA" - -scholar = Scholar { - "firstName": "ABC" # firstName in schema Person is final. -} -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /final/fail_lazy_init_0/main.k:8:1 - | -8 | scholar = Scholar { - | attribute 'lastName' of Scholar is required and can't be None or Undefined - | -``` - -Possible resolution: - -- Check if the final variables have been assigned or other changes affect the values of the final variables. - -### 1.3.13 CycleInheritError (E2D33) - -KCL will report `CycleInheritError` when circle inheritance appeared in the schema. - -The `ewcode` of `CycleInheritError` is `E2D33`. - -For example: - -```python -schema Parent(Son): - parent_field: str - -schema Son(GrandSon): - son_field: str - -schema GrandSon(Parent): - grandson_field: str - -parent = Parent { - parent_field: "" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /inherit/cycle_inherit_fail_1/main.k:7:8 - | -7 | schema GrandSon(Parent): - | ^ There is a circular reference between schema GrandSon and Parent - | -``` - -Possible resolution: - -- Check schema inheritance relationship to avoid A inheritance B and B inheritance A at the same time. - -### 1.3.14 KCLRecursionError (E3M42) - -KCL will report `KCLRecursionError` when a circle reference appears in the program. - -The `ewcode` of `KCLRecursionError` is `E3M42`. - -For example: - -```python -schema Parent(Son): - parent_field: str - son: Son = Son { # Parent has attribute Son - parent: Parent { - parent_field: "123" - } - } - -schema Son: - son_field: str - parent: Parent = Parent { # Son has attribute Parent - son: Son { - son_field: "123" - } - } - -parent = Parent { - parent_field: "", -} -``` - -The KCL program will cause the following error message. - -```shell -thread 'main' has overflowed its stack -fatal runtime error: stack overflow -``` - -Possible resolution: - -- Check the members in the schema to avoid the problem of circle references. - -## 1.4 KCL Compile Warning (W2xxx) - -This section mainly includes KCL warnings: - -| ewcode | KCL exception | messages | -| ------ | ------------------------------------------------- | ------------------ | -| W2K04 | [FloatUnderflow](#141-floatunderflow-w2k04) | Float underflow | -| W2P10 | [InvalidDocstring](#142-invaliddocstring-w2p10) | Invalid docstring | -| W2N12 | [DeprecatedWarning](#143-deprecatedwarning-w2n12) | Deprecated warning | - -### 1.4.1 FloatUnderflow (W2K04) - -KCL will report `FloatUnderflow` when a floating-point number underflows in KCL. - -The `ewcode` of `FloatUnderflow` is `W2K08`. - -Possible resolution: - -- Check whether the value of the float number is in the range supported by KCL. - -### 1.4.2 InvalidDocstring (W2P10) - -KCL will report `InvalidDocstring` when a string is illegal in KCL doc. - -The `ewcode` of `InvalidDocstring` is `W2P10`. - -Possible resolution: - -- Please write doc according to KCL standards. - -### 1.4.3 DeprecatedWarning (W2N12) - -KCL will report `DeprecatedWarning` when a deprecated variable is used and the strict is False. - -The `ewcode` of `DeprecatedWarning` is `W2N12`. - -Possible resolution: - -- Try not to use deprecated code. If the strict is True, KCL will output the error and stop running. diff --git a/versioned_docs/version-0.5.1/reference/lang/spec/codestyle.md b/versioned_docs/version-0.5.1/reference/lang/spec/codestyle.md deleted file mode 100644 index dd40925e..00000000 --- a/versioned_docs/version-0.5.1/reference/lang/spec/codestyle.md +++ /dev/null @@ -1,608 +0,0 @@ ---- -title: "Code Style" -linkTitle: "Code Style" -type: "docs" -weight: 2 -description: Code Style ---- - -## Introduction - -This document gives the KCL code style conventions. Good code style can play a vital role in the development and maintenance of the project. We can learn the KCL code style by referring to the full text of the description and sample codes, and use KCL format and lint tools to help coding. - -## Source File Encoding - -KCL file encoding should always use **UTF-8**. - -## Code Layout - -### Indentation - -Use **4 spaces** per indentation level such as in the schema statement and if statement. - -```python -schema PersonA: - name: str # non-recommended - age: int - -schema PersonB: - name: str # recommended - age: int - -if True: - a = 1 # recommended -elif True: - b = 2 # non-recommended -else: - c = 3 # non-recommended -``` - -The closing brace/bracket/parenthesis on multiline constructs should line up under **first character** of the line that starts the multiline construct, as in: - -```python -# valid and recommended -my_list = [ - 1, 2, 3, - 4, 5, 6, -] -``` - -```python -# invalid -my_list = [ - 1, 2, 3, - 4, 5, 6, - ] -``` - -### Tabs or Spaces - -- Spaces are the preferred indentation method. -- Tabs should be used solely to remain consistent with code that is already indented with tabs. - -KCL disallows mixing the use of tabs and spaces for indentation and an error will be reported during the compile time. - -### Blank Lines - -- Surround top-level schema definitions with one blank line. -- Keep at most one blank line between two statements and remove redundant blank lines. -- Remove extra blank characters at the end of the line -- Remove extra blank characters in a blank line. -- There is no blank line in the header of the file, start writing from the first line. -- Only one blank line will be left at the end of the KCL file. - -```python -# Remove blank lines in the file header -a = 1 # Remove white space at the end of the line -# Keep at most one blank line between two statements - -b = 2 -# Only leave one blank line at the end of the file - -``` - -### Inline Expressions - -Write indentation of KCL `if`, `elif`, `else` and other conditions on different lines. - -```python -if True: print("") # non-recommended - -if True: # recommended - print("") -``` - -### Line Break and Continuation lines - -- For long expressions, use the line continuation symbol `\` and keep the left end of multiple expressions aligned. -- The 4-space rule is optional for continuation lines. - -```python -anotherString = "Too long expression " + \ - "Too long expression " # non-recommended - -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " # recommended -``` - -### When to Use Trailing Commas - -- Always use trailing commas. - -### Maximum Line Length - -- The general recommendation is **80 characters** but not absolute. - -### Symbol Break White Space - -Try to keep the spaces between different symbols, but not too many, usually one is good. - -```python -a = 1 # recommended -b = 1 + 2 # non-recommended -``` - -### Whitespace in Expressions and Statements - -Avoid extraneous whitespace in the following situations: - -- The parentheses `()`, brackets `[]` and braces `{}` in the expression have no spaces inside. - -```python -a = (1 + 2) # recommended -b = ( 1 + 2 ) # non-recommended - -c = [1, 2, 3] # recommended -d = [ 1, 2, 3 ] # non-recommended - -e = {key = "value"} # recommended -f = { key = "value" } # non-recommended -``` - -```python -spam(ham[1], {eggs = 2}) # recommended -spam( ham[ 1 ], { eggs = 2 } ) # non-recommended -``` - -- Between a trailing comma and a following close parenthesis. - -```python -foo = [0,] # recommended -bar = [0, ] # non-recommended -``` - -- Immediately before the open parenthesis that starts the argument list of a function call. - -```python -print(1) # recommended -print (1) # non-recommended -``` - -- Immediately before the open parenthesis that starts indexing or slicing. - -```python -dct = {key = "value"} -lst = [1, 2, 3] - -a = dct['key'] # recommended -b = dct ['key'] # non-recommended - -c = lst[0] # recommended -d = lst [1] # non-recommended -``` - -- More than one space around an assignment `=` (or other) operator to align it with another. - -```python -# recommended: -x = 1 -y = 2 -long_variable = 3 -``` - -```python -# non-recommended: -x = 1 -y = 2 -long_variable = 3 -``` - -- Always surround these binary operators with a single space on either side: assignment (`=`), augmented assignment (`+=`, `-=`, etc.), comparisons (`==`, `<`, `>`, `!=`, `<=`, `>=`, `in`, `not in`, `is`, `is not`), booleans (`and`, `or`, `not`). - -```python -# recommended: -i = i + 1 -submitted += 1 -x = x * 2 - 1 -hypot2 = x * x + y * y -c = (a + b) * (a - b) -``` - -```python -# non-recommended: -i = i+1 -submitted+=1 -x = x*2 - 1 -hypot2 = x*x + y*y -c = (a+b) * (a-b) -``` - -- Break one blank line between different statements e.g., import, schema and expression statements. - -```python -import math -import net - -schema Person: - name: str - -person = Person { - name = "Alice" -} -``` - -- Compound statements (multiple statements on the same line) are generally discouraged - -```python -# recommended: -if foo == 'blah': - do_blah_thing() -do_one() -do_two() -do_three() -``` - -```python -# non-recommended: -if foo == 'blah': do_blah_thing() -do_one(); do_two(); do_three() -``` - -## Naming Conventions - -### Naming Styles - -The following naming styles are commonly distinguished: - -- `b` (single lowercase letter) -- `B` (single uppercase letter) -- `lowercase` -- `lower_case_with_underscores` -- `UPPERCASE` -- `UPPER_CASE_WITH_UNDERSCORES` -- `CapitalizedWords` (capitalize all letters of the acronym in `CapitalizedWords` e.g., `HTTPServer`.) -- `mixedCase` (differs from `CapitalizedWords` by initial lowercase character) -- `Capitalized_Words_With_Underscores` (ugly and non-recommended) - -### Names to Avoid - -Never use the characters 'l' (lowercase letter el), 'O' (uppercase letter oh), or 'I' (uppercase letter eye) as single-character variable names. - -### Package and Module Names - -Package and module names should have short, all-lowercase names. - -### Schema Names - -Schema names should normally use the `CapWords` convention. - -### Constants - -Constants are usually defined on a module level and written in all capital letters with underscores separating words such as `MAX_OVERFLOW` and `TOTAL`. - -## Import - -- Imports should usually be on separate lines. -- Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants. -- Imports should be grouped in the following order and we should put a blank line between each group of imports. - 1. Standard library imports. - 2. Related third party plugin imports. - 3. Local application/library specific imports. -- Use an alias when we import a package name with a relatively long path. -- Leave only one space between the Import keyword and the package name. - -```python -import net # recommended -import math # non-recommended - -import ..pkg.internal_pkg as alias_pkg # recommended -``` - -## Comments - -- Comments should be complete sentences. The first word should be capitalized unless it is an identifier that begins with a lower-case letter (never alter the case of identifiers!). -- Block comments generally consist of one or more paragraphs built out of complete sentences, with each sentence ending in a period. -- Use two spaces after a sentence-ending period in multi-sentence comments, except after the final sentence. - -### Block Comments - -Block comments generally apply to some (or all) code that follows them, and are indented to the same level as that code. Each line of a block comment starts with a `#` and **a single space**(unless it is indented text inside the comment). - -Paragraphs inside a block comment are separated by a line containing a single `#`. - -```python -# This is a block comment -a = 1 -``` - -### Inline Comments - -Use inline comments sparingly. - -An inline comment is a comment on the same line as a statement. Inline comments should be separated by **at least two spaces** from the statement. They should start with a `#` and **a single space**. - -```python -a = 1 # This is an inline comment -``` - -### Documentation Strings - -Write doc strings for all public schema and schema attributes. - -```python -schema Person: - """ - Person schema doc string - """ - - name: str = "Alice" -``` - -## String - -- Single-quoted strings and double-quoted strings are the same in KCL. -- Use double-quoted string with lowercase prefix -- For triple-quoted strings, always use double quote characters to be consistent with the docstring convention. -- When a string contains single or double quote characters, use the other one to avoid backslashes in the string. - -```python -strC = "'123'" # recommended -strD = "\"123\"" # non-recommended -``` - -## Number - -- Use lowercase for the prefix of non-decimal numbers, and use uppercase for the number itself. - -```python -foo = 0xAB # recommended -bar = 0Xab # non-recommended -``` - -## Operators - -### Binary Operators - -- Leave only one space before and after the assignment `=`. -- Leave only one space before and after the binary operator in the expression. - -```python -a = 1 # recommended -b=2 # non-recommended -c= 3 # non-recommended -d =4 # non-recommended - -_value = (1 + 2 * 3) # recommended -_value = (1+2*3) # non-recommended -``` - -### Unary Operators - -- There is only no space after unary operators e.g., `~`, `+` and `-`. - -```python -_value = 1 + -2 * ~3 # recommended -_value = 1+ - 2 * ~ 3 # non-recommended -``` - -- There is no space after `**` and `*` in the dict/list deduction expressions and argument expressions. - -```python -_list = [1, 2, 3] -_list = [*_list, [4, 5 ,6]] # recommended -_list = [* _list, [4, 5 ,6]] # non-recommended - -_dict = {**{k = "v"}, **{k = "v"}} # recommended -_dict = {** {k = "v"}, ** {k = "v"}} # non-recommended -``` - -- Use `is not` operator rather than `not ... is`. - -```python -# recommended: -if foo is not None: - a = 1 -``` - -```python -# non-recommended: -if not foo is None: - a = 1 -``` - -## Dict - -- There is no space before the colon `:` at the instantiation of KCL dict and schema config, and a space after the colon `:`. - -```python -d1 = {labels: {k1 = "v1"}} # recommended -d2 = {labels : {k1 = "v1"}} # non-recommended -d3 = {labels :{k1 = "v1"}} # non-recommended -``` - -- Always surround the override attribute operator `=` and the insert attribute operator `+=` with a single space on either sid. - -```python -d1 = {key = "value"} # recommended -d2 = {key= "value"} # non-recommended -d3 = {key ="value"} # non-recommended -``` - -```python -d1 = {key += [0, 1, 2]} # recommended -d2 = {key+= [0, 1, 2]} # non-recommended -d3 = {key +=[0, 1, 2]} # non-recommended -``` - -- Remove all commas at the end of the line in the KCL multiline dict because the end commas of each line are optional. - -```python -d = { - key1 = "value1" - key2 = "value2" - key3 = "value3" - key4 = "value4" -} -``` - -## List - -- Keep only **one space** after the comma `,` separating elements in the list - -```python -a = [1, 2, 3] # recommended -b = [1,2,3] # non-recommended -``` - -- Keep only **one space** before and after the comprehension expression token `for` and `in` in the dict and list. - -```python -a = [i for i in range(10)] # recommended -b = [i for i in range(10)] # non-recommended -``` - -## Slice - -- Keep the same number of spaces before and after the colon `:` of the list slice. - -```python -l = [1, 2, 3] -a = l[0:2] # recommended -b = l[0 : 2] # non-recommended -c = l[0: 2] # non-recommended - -d = l[0 + 0 : 1 + 1] # recommended -e = l[0 + 0:1 + 1] # non-recommended -``` - -## Schema - -- Leave only one space before and after the schema attribute assignment `=`. -- Always add a doc string to a schema, which is a good programming habit. - -```python -schema Person: - """ - Schema doc string - """ - name: str = "Alice" # recommended - age : int=12 # non-recommended - -person = Person {} -``` - -- Keep **no spaces** around the schema inheritance operator `()` - -```python -schema Base: - name: str - -schema Person(Base): # recommended - age: int - -schema Schema ( Base ): # non-recommended - age: int -``` - -- Keep **only one space** between the brackets and the schema name of the config at schema instantiation. - -```python -schema Base: - name: str - -schema Person(Base): - age: int - -personA = Person{} # non-recommended -personB = Person {} # recommended -``` - -- Keep **only one space** between the **mixin** keyword and the following `[]` operator - -```python -schema NameMixin: - name: str = "name" - -schema Person: - mixin [NameMixin] # non-recommended - age: int - -schema Parent: - mixin [NameMixin] # recommended - age: int -``` - -### Attribute Annotations - -- Annotations for schema attributes should have a single space after the colon `:` and no space before the colon `:`. - -```python -# recommended: -schema Person: - name: str # No space before the colon `:` - age: int = 18 # Spaces around assignment`=` -``` - -```python -# non-recommended: -schema Person: - codeA:int # No space after the colon `:` - codeB : int # Space before the colon `:` - name: str="Alice" # No spaces around assignment`=` -``` - -- There are no spaces around the colon `:` in the dict type annotation. - -```python -schema Person: - labels: {str:str} # recommended - keyValues: {str : str} # non-recommended -``` - -### Arguments - -- There are no spaces around the assignment `=` in the function/schema/decorator keyword arguments (kwargs). - -```python -schema Person[nameVar]: - # Decorator kwargs - @deprecated(strict=False) # recommended - name: str = nameVar - - @deprecated(strict = False) # non-recommended - age: int - -# Schema kwargs -personA = Person(nameVar="Alice") {} # recommended -personB = Person(nameVar = "Bob") {} # non-recommended - -# Function kwargs -print("", end='') # recommended -print("", end = '') # non-recommended -``` - -## Keywords - -- Only one space is usually reserved around the keyword, such as `schema`, `mixin`, `is` and `not`, etc. - -```python -schema NameMixin: - check: - name not None - -schema Person: - """ - Person schema definition - """ - mixin [NameMixin] - - name: str = "Alice" - age: int - -person = Person { - age = 18 -} -``` - -## Function - -- There are no spaces around the function/package select operator `.` -- There are no spaces between the function name and the parentheses `()`. - -```python -import math - -print(math.log(10)) # recommended -print( math . log (10)) # non-recommended -``` diff --git a/versioned_docs/version-0.5.1/reference/lang/spec/datatypes.md b/versioned_docs/version-0.5.1/reference/lang/spec/datatypes.md deleted file mode 100644 index ef7ea71a..00000000 --- a/versioned_docs/version-0.5.1/reference/lang/spec/datatypes.md +++ /dev/null @@ -1,452 +0,0 @@ ---- -title: "Data Types" -linkTitle: "Data Types" -type: "docs" -weight: 2 -description: Data Types ---- - -## Syntax - -### Bool - -Boolean values are the two constant objects `False` and `True`. They are used to represent truth values (although other values can also be considered false or true). The built-in function bool() can be used to convert any value to a Boolean, if the value can be interpreted as a truth value. - -### Int - -Int, or integer, is an arbitrarily sized integer, positive or negative, without decimals, of 64 binary digits precision(-9,223,372,036,854,775,808~9,223,372,036,854,775,807). Int is created by int literals or as the result of built-in functions and operators. Unadorned integer literals (including `hex`, `octal` and `binary` numbers) yield integers. The constructor int() can be used to produce int of a specific type. - -Besides, integer literals may have an `SI` or `IEC` multiplier. - -- `SI`: General integer or fixed-point number form: `P`, `T`, `G`, `M`, `K`, `k`, `m`, `u`, `n`. -- `IEC`: Corresponding power of 2: `Pi`, `Ti`, `Gi`, `Mi`, `Ki`. - -```python -a = 1 # positive integer: 1 -b = -1 # negative integer: -1 -c = 0x10 # hexadecimal literal: 16 -d = 0o10 # octal literal: 8, or the form `010` -e = 0b10 # binary literal: 2 -f = 10Ki # integer literal with IEC multiplier: 10240 -g = 1M # integer literal with SI multiplier: 1000000 -h = int("10") # int constructor: 10 -i = int("10Ki") # int constructor with multiplier: 10240 -``` - -Notes: - -- Report an error if unable to represent an integer value precisely. - -### Float - -Float, floating-point, approximation to real numbers, positive or negative, containing one or more decimals, of 64 bit IEEE 754 floats. The constructor float() can be used to produce int of a specific type. - -```python -a = 1.10 -b = 1.0 -c = -35.59 -d = 32.3+e18 -f = -90. -g = -32.54e100 -h = 70.2-E12 -i = float("112") # float constructor -``` - -Notes: - -- Report an error if unable to represent a floating-point value due to overflow -- Report a warning if unable to represent a floating-point value due to underflow. Round to the nearest representable value if unable to represent a floating-point value due to limits on precision. These requirements apply to the result of any expression except for built-in functions for which an unusual loss of precision must be explicitly documented. - -#### None - -In KCL, `None` can indicate that the value of the object is empty, which is similar to `nil` in Go or `null` in Java, and corresponds to `null` in YAML and JSON. - -```python -a = None -b = [1, 2, None] -c = {"key1" = "value1", "key2" = None} -``` - -Please note that `None` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + None # error -b = int(None) # error -c = not None # True -d = None == None # True -e = None or 1 # 1 -f = str(None) # None -``` - -#### Undefined - -`Undefined` is similar to None, but its semantics is that a variable is not assigned any value and will not be output to YAML or JSON. - -```python -a = Undefined -b = [1, 2, Undefined] -c = {"key1" = "value1", "key2" = Undefined} -``` - -Please note that `Undefined` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + Undefined # error -b = int(Undefined) # error -c = not Undefined # True -d = Undefined == Undefined # True -e = Undefined or 1 # 1 -f = str(Undefined) # Undefined -``` - -### Common Numeric Operations - -Int and Float support the following operations (see built-in proposal for built-in details): - -- `x + y`: sum of x and y. -- `x - y`: difference of x and y. -- `x * y`: product of x and y. -- `x / y`: quotient of x and y. -- `x // y`: floored quotient of x and y. -- `x % y`: remainder of x / y. -- `x ** y`: x to the power y. -- `-x`: x negated. -- `+x`: x unchanged. -- `~x`: x bitwise negation. -- `abs(x)`: absolute value or magnitude of x. -- `int(x)`: x converted to integer. -- `float(x)`: x converted to floating point. - -KCL supports mixed arithmetic: when a binary arithmetic operator has operands of different numeric types, the operand with the "narrower" type is widened to that of the other, where integer is narrower than floating-point. - -### String - -Strings are immutable sequences of Unicode characters. String literals are written in a variety of ways: - -```python -'allows embedded "double" quotes' # Single quotes -"allows embedded 'single' quotes" # Double quotes -'''Three single quotes''', """Three double quotes""" # Triple quoted -``` - -Triple quoted strings may span multiple lines. - -Indexing a string produces strings of length 1, for a non-empty string s, `s[0] == s[0:1]`. - -```python -a = "Hello, World!" -b = a[2:5] # "llo" -c = a[-5:-2] # "orl" -d = a[::-1] # "'!dlroW ,olleH'" -``` - -- `str(x=None) -> str` - -Return a string. If _x_ is not provided, raise a runtime error. - -```python -x = str(3.5) # "3.5" -``` - -#### Members - -Built-in function and members of a string - -- `str#len() -> int` - Return the number of characters in the string. -- `capitalize() -> str` - Return a copy of the string with its first character (if any) capitalized and the rest lowercased. -- `count(sub: str, start: int = 0, end: int = -1) -> int` - Returns the number of (non-overlapping) occurrences of substring sub in string, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `endswith(suffix: str, start: int = 0, end: int = -1) -> bool` - Returns `True` if the string ends with the specified suffix, otherwise return `False`, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `find(sub: str, start: int = 0, end: int = -1) -> int` - Returns the lowest index where substring sub is found, or -1 if no such index exists, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `format(*args, **kwargs) -> str` - Perform string interpolation. Format strings contain replacement fields surrounded by curly braces {}. Anything that is not contained in braces is considered literal text, which is copied unchanged to the output. If you need to include a bracket character in the literal text, it can be escaped by doubling: A replacement field can be either a name, a number or empty. Values are converted to strings using the str function. -- `index(sub: str, start: int = 0, end: int = -1) -> int` - Returns the first index where sub is found, or raises an error if no such index exists, optionally restricting to `[start:end]` start being inclusive and end being exclusive. -- `isalnum() -> bool` - Returns True if all characters in the string are alphanumeric (`[a-zA-Z0-9]`) and there is at least one character, False otherwise. -- `isalpha() -> bool` - Returns True if all characters in the string are alphabetic (`[a-zA-Z]`) and there is at least one character. -- `isdigit() -> bool` - Returns True if all characters in the string are digits (`[0-9]`) and there is at least one character. -- `islower() -> bool` - Returns True if all cased characters in the string are lowercase and there is at least one character. -- `isspace() -> bool` - Returns True if all characters are white space characters and the string contains at least one character. -- `istitle() -> bool` - Returns True if the string is in title case and it contains at least one character. This means that every uppercase character must follow an uncased one (e.g., whitespace) and every lowercase character must follow a cased one (e.g., uppercase or lowercase). -- `isupper() -> bool` - Returns True if all cased characters in the string are uppercase and there is at least one character. -- `join(iterable: list) -> str` - Return a string which is the concatenation of the strings in iterable. A TypeError will be raised if there are any non-string values in iterable. The separator between elements is the string providing this method. Example: - - ```python - >>> "|".join(["a", "b", "c"]) - "a|b|c" - ``` - -- `lower() -> str` - Returns a copy of the string with all the cased characters converted to lowercase. -- `lstrip(chars: str) -> str` - Return a copy of the string with leading characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.lstrip() - 'spacious ' - >>> 'www.example.com'.lstrip('cmowz.') - 'example.com' - ``` - -- `replace(old: str, new: str, count: int) -> str` - Return a copy of the string with all occurrences of substring old replaced by new. If the optional argument count is given, only the first count occurrences are replaced. -- `rfind(sub: str, start: int = 0, end: int = -1) -> int` - Return the highest index in the string where substring sub is found, such that sub is contained within s[start:end]. Optional arguments start and end are interpreted as in slice notation. Return -1 on failure. -- `rindex(sub: str, start: int = 0, end: int = -1) -> int` - Returns the last index where sub is found, or raises an ValueError if no such index exists, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `rsplit(sep: str, maxsplit: int = -1) -> list` - Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done, the rightmost ones. If sep is not specified or None, any whitespace string is a separator. Except for splitting from the right, rsplit() behaves like split() which is described in detail below. -- `rstrip(chars: str) -> str` - Return a copy of the string with trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a suffix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.rstrip() - ' spacious' - >>> 'mississippi'.rstrip('ipz') - 'mississ' - ``` - -- `split(sep: str, maxsplit: int) -> list` - Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done (thus, the list will have at most maxsplit+1 elements). If maxsplit is not specified or -1, then there is no limit on the number of splits (all possible splits are made). - - If sep is given, consecutive delimiters are not grouped together and are deemed to delimit empty strings (for example, `'1,,2'.split(',')` returns `['1', '', '2']`). The sep argument may consist of multiple characters (for example, `'1<>2<>3'.split('<>')` returns `['1', '2', '3']`). Splitting an empty string with a specified separator returns `['']`. - - For example: - - ```python - >>> '1,2,3'.split(',') - ['1', '2', '3'] - >>> '1,2,3'.split(',', maxsplit=1) - ['1', '2,3'] - >>> '1,2,,3,'.split(',') - ['1', '2', '', '3', ''] - ``` - - If sep is not specified or is None, a different splitting algorithm is applied: runs of consecutive whitespace are regarded as a single separator, and the result will contain no empty strings at the start or end if the string has leading or trailing whitespace. Consequently, splitting an empty string or a string consisting of just whitespace with a `None` separator returns `[]`. - - For example: - - ```python - >>> '1 2 3'.split() - ['1', '2', '3'] - >>> '1 2 3'.split(maxsplit=1) - ['1', '2 3'] - >>> ' 1 2 3 '.split() - ['1', '2', '3'] - ``` - -- `splitlines(keepends: str) -> list` - Return a list of the lines in the string, breaking at line boundaries('\n', '\r\n', '\r'). Line breaks are not included in the resulting list unless keepends is given and true. - - This method splits on the following line boundaries. In particular, the boundaries are a superset of universal newlines. - - For example: - - ```python - >>> 'ab c\n\nde fg\rkl\r\n'.splitlines() - ['ab c', '', 'de fg', 'kl'] - >>> 'ab c\n\nde fg\rkl\r\n'.splitlines(keepends=True) - ['ab c\n', '\n', 'de fg\r', 'kl\r\n'] - ``` - - Unlike `split()` when a delimiter string sep is given, this method returns an empty list for the empty string, and a terminal line break does not result in an extra line: - - ```python - >>> "".splitlines() - [] - >>> "One line\n".splitlines() - ['One line'] - ``` - - For comparison, `split('\n')` gives: - - ```python - >>> ''.split('\n') - [''] - >>> 'Two lines\n'.split('\n') - ['Two lines', ''] - ``` - -- `startswith(prefix: str, start: int = 0, end: int = -1) -> bool` - Return `True` if string starts with the prefix, otherwise return False. prefix can also be a list of prefixes to look for. With optional start, test string beginning at that position. With optional end, stop comparing string at that position. -- `strip(chars: str) -> str` - Return a copy of the string with the leading and trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix or suffix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.strip() - 'spacious' - >>> 'www.example.com'.strip('cmowz.') - 'example' - ``` - - The outermost leading and trailing chars argument values are stripped from the string. Characters are removed from the leading end until reaching a string character that is not contained in the set of characters in chars. A similar action takes place on the trailing end. For example: - - ```python - >>> comment_string = '#....... Section 3.2.1 Issue #32 .......' - >>> comment_string.strip('.#! ') - 'Section 3.2.1 Issue #32' - ``` - -- `title() -> str` - Return a titlecased version of the string where words start with an uppercase character and the remaining characters are lowercase. - - For example: - - ```python - >>> 'Hello world'.title() - 'Hello World' - ``` - - The algorithm uses a simple language-independent definition of a word as groups of consecutive letters. The definition works in many contexts but it means that apostrophes in contractions and possessives form word boundaries, which may not be the desired result: - - ```python - >>> "they're bill's friends from the UK".title() - "They'Re Bill'S Friends From The Uk" - ``` - -- `upper() -> str` - Return a copy of the string with all the cased characters 4 converted to uppercase. Note that `s.upper().isupper()` might be `False` if s contains uncased characters or if the Unicode category of the resulting character(s) is not “Lu” (Letter, uppercase), but e.g., “Lt” (Letter, titlecase). -- `removeprefix(prefix: str) -> str` - If the string starts with the prefix string, return string[len(prefix):]. Otherwise, return a copy of the original string. - ```python - >>> "prefix-data".removeprefix("prefix-") - "data" - ``` -- `rermovesuffix(suffix: str) -> str` - If the string ends with the suffix string and that suffix is not empty, return string[:-len(suffix)]. Otherwise, return a copy of the original string. - ```python - >>> "data-suffix".removesuffix("-suffix") - "data" - ``` - -### List - -Lists are immutable sequences, typically used to store collections of homogeneous items (where the precise degree of similarity will vary by application). - -Lists may be constructed in several ways: - -- Using a pair of square brackets to denote the empty list: `[]` -- Using square brackets, separating items with commas: `[a]`, `[a, b, c]` -- Using a list comprehension: `[x for x in iterable]` -- Using the type constructor: list() or list(iterable) - -The constructor builds a list whose items are the same and in the same order as iterable’s items.Iterable may be either a sequence, a container that supports iteration, or an iterator object. If iterable is already a list, a copy is made and returned, similar to `iterable[:]`. For example, `list('abc')` returns `['a', 'b', 'c']` and `list([1, 2, 3])` returns `[1, 2, 3]`. If no argument is given, the constructor creates a new empty list `[]`. - -Lists implement all of the common sequence operations. - -#### Members - -- `len()` - Return the number of items in the list. - -### Common Sequence Operations - -The operations in the following table are supported by List and Dict. - -This table lists the sequence operations sorted in ascending priority. In the table, s and t are sequences of the same type, n, i, j and k are integers and x is an arbitrary object that meets any type and value restrictions imposed by s. - -The `in` and `not in` operations have the same priorities as the comparison operations. The + -(concatenation) and \* (repetition) operations have the same priority as the corresponding numeric operations. - -| Operation | Result | Notes | -| ------------ | -------------------------------------------------- | ----- | -| `x in s` | `True` if an item of s is equal to x, else `False` | #1 | -| `x not in s` | `False` if an item of s is equal to x, else `True` | #1 | -| `s + t` | the concatenation of s and t | #5 | -| `s[i]` | ith item of s, origin 0 | #2 | -| `s[i:j]` | slice of s from i to j | #2 #3 | -| `s[i:j:k]` | slice of s from i to j with step k | #2 #4 | -| `min(s)` | smallest item of s | | -| `max(s)` | largest item of s | | - -Notes: - -- 1. While the in and not in operations are used only for simple containment testing in the - general case, some specialized sequences (str) also use them for subsequence testing: - -```python ->>> "gg" in "eggs" -True -``` - -- 2. If i or j is negative, the index is relative to the end of sequence s: `s.len() + i` or `s.len() + j` is substituted. But note that -0 is still 0. -- 3. The slice of s from i to j is defined as the sequence of items with index k such that `i <= k < j`. If i or j is greater than `s.len()`, use `s.len()`. If i is omitted or None, use 0. If j is omitted or None, use `s.len()`. If i is greater than or equal to j, the slice is empty. -- 4. The slice of s from i to j with step k is defined as the sequence of items with index `x = i + n*k` such that `0 <= n < (j-i)/k`. In other words, the indices are `i`, `i+k`, `i+2*k`, `i+3*k` and so on, stopping when j is reached (but never including j). When k is positive, i and j are reduced to s.len() if they are greater. When k is negative, i and j are reduced to s.len() - - - If they are greater. If i or j are omitted or None, they become “end” values (which end depends on the sign of k). Note, k cannot be zero. If k is None, it is treated like 1. - -- 5. Concatenating immutable sequences always results in a new object. This means that building up a sequence by repeated concatenation will have a quadratic runtime cost in the total sequence length. To get a linear runtime cost, you must switch to one of the alternatives below: - - - if concatenating str objects, you can build a list and use `str.join()` at the end - -- 6. `index` raises `ValueError` when x is not found in s. Not all implementations support passing the additional arguments i and j. These arguments allow efficient searching of subsections of the sequence. Passing the extra arguments is roughly equivalent to using `s[i:j].index(x)`, only without copying any data and with the returned index being relative to the start of the sequence rather than the start of the slice. - -### Dict - -Dict is an immutable mapping object maps hashable values to arbitrary objects. A dictionary’s keys are almost arbitrary values. Values that are not hashable, that is, values containing lists, dictionaries may not be used as keys. Numeric types used for keys obey the normal rules for numeric comparison: if two numbers compare equal (such as 1 and 1.0) then they can be used interchangeably to index the same dictionary entry. (Note however, that since computers store floating-point numbers as approximations it is usually unwise to use them as dictionary keys.) Dict is ordered. The order of the keys is the order of their declaration. - -Dictionaries can be created by placing a comma-separated list of keys: value pairs within braces, for example: `{'jack': 4098, 'sjoerd': 4127}` or `{4098: 'jack', 4127: 'sjoerd'}`, by the dict constructor, or list/dict comprehension. - -- `dict(obj)` - -Return a new dictionary initialized from an optional positional argument and a possibly empty set of keyword arguments.If no positional argument is given, an empty dictionary is created. If a positional argument is given and it is a mapping object, a dictionary is created with the same key-value pairs as the mapping object. Otherwise, the positional argument must be an iterable object. Each item in the iterable must itself be an iterable with exactly two objects. The first object of each item becomes a key in the new dictionary, and the second object the corresponding value. If a key occurs more than once, the last value for that key becomes the corresponding value in the new dictionary. If keyword arguments are given, the keyword arguments and their values are added to the dictionary created from the positional argument. If a key being added is already present, the value from the keyword argument replaces the value from the positional argument. To illustrate, the following examples all return a dictionary equal to `{"one": 1, "two": 2, "three": 3}`: - -```python ->>> a = {'two': 2, 'one': 1, 'three': 3} ->>> b = {'one': 1, 'two': 2, 'three': 3} ->>> c = {'three': 3, 'one': 1, 'two': 2} ->>> a == b == c -True -``` - -Providing keyword arguments as in the first example only works for keys that are valid KCL identifiers. Otherwise, any valid keys can be used. - -In the dict comprehension, key/value pairs yielded by the generator expression is set in the dictionary in the order yielded: the first occurrence of the key determines its insertion order, and the last determines the value associated to it. - -```python ->>> {str(i): 2 * i for i in range(3)} -{"0": 0, "1": 2, "2": 4} - ->>> a = {"one": 1, "two": 2, "three": 3} ->>> b = {k: v for k, v in a if v >= 2} -{two: 2, three: 3} -``` - -#### Operations & Members - -These are the operations that dictionaries the support. - -- `list(d)` - Return a list of all the keys used in the dictionary d. -- `len()` - Return the number of items in the dictionary d. -- `d[key]` - Return the item of d with key. Return Undefined if key is not in the map. -- `key in d` - Return True if d has a key, else False. -- `key not in d` - Equivalent to not key in d. -- `d.key` - Return the item of d with key. Return Undefined if key is not in the map. - -Dictionaries compare equal if and only if they have the same (key, value) pairs(keys' ordering matters). Order comparisons (‘<’, ‘<=’, ‘>=’, ‘>’) raise TypeError. - -```python ->>> d = {"one": 1, "two": 2, "three": 3, "four": 4} ->>> d -{'one': 1, 'two': 2, 'three': 3, 'four': 4} ->>> list(d) -['one', 'two', 'three', 'four'] -``` diff --git a/versioned_docs/version-0.5.1/reference/lang/spec/error.md b/versioned_docs/version-0.5.1/reference/lang/spec/error.md deleted file mode 100644 index 2a58b553..00000000 --- a/versioned_docs/version-0.5.1/reference/lang/spec/error.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: "Errors" -linkTitle: "Errors" -type: "docs" -weight: 2 -description: Errors ---- - -When errors happen, developers should be able to detect the error and abort -execution. Thus, KCL introduce the `assert` syntax. - -In the previous topic of `schema` syntax. Errors can also be raised when a -schema is violated. - -## Syntax - -The syntax of the `assert` statement is the following. - -```bnf -assert_stmt: 'assert' test ['if' test] [',' test] -``` - -In the basic form, an `assert` statement evaluates an expression. If the -expression is evaluated to `False`, the assertion is failed, and an error -should be reported. - -In the extended form, an error message can be provided. The error message is -another expression. It is only evaluated when the expression to be evaluated -is evaluated to `False`. The evaluation result of the error message is printed -when reporting the error. - -The following is an example: - -```python -a = 1 -b = 3 -condition = False -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -# if condition is True, then assert `a == b`, if failed, the message "error message" will be printed. -assert a == b if condition, "error message" -``` - -## The Implementation - -When an error happens, no matter it is caused by the `assert` or the `schema` syntax, -the virtual machine should exit with an exit code greater than `0`. - -The virtual machine may choose to dump the back trace information, and it is strongly recommended to implement it. - -In practice, KCL can dump back trace by default, and an argument can be introduced to disable it. diff --git a/versioned_docs/version-0.5.1/reference/lang/spec/expressions.md b/versioned_docs/version-0.5.1/reference/lang/spec/expressions.md deleted file mode 100644 index b52c10f3..00000000 --- a/versioned_docs/version-0.5.1/reference/lang/spec/expressions.md +++ /dev/null @@ -1,915 +0,0 @@ ---- -title: "Expressions" -linkTitle: "Expressions" -type: "docs" -weight: 2 -description: Expressions ---- - -## Syntax - -In KCL, an expression specifies the computation of a value. - -The syntax is the following: - -```bnf -expression: test ("," test)* -test: if_expr | primary_expr | unary_expr | binary_expr -``` - -KCL expressions consist of `if` expression, `primary` expression, `unary` expression, and `binary` expression. - -### Primary Expressions - -Primary expressions are the operands for unary and binary expressions. - -Operands are self-delimiting. An **operand** may be followed by any number of selector dot, a function call, or slice suffixes, to form a primary expression. The grammar uses `expression`, where a multiple-component expression is allowed, and `test` where it accepts an expression of only a single component. - -Syntax: - -```bnf -primary_expr: operand | primary_expr select_suffix | primary_expr call_suffix | primary_expr subscript_suffix -``` - -### Operands - -Operand denotes the elementary value in an expression. An operand may be an identifier, a literal, or a parenthesized expression. - -Syntax: - -```bnf -operand: operand_name | number | string | "True" | "False" | "None" | "Undefined" | list_expr | list_comp | dict_expr | dict_comp | "(" expression ")" -operand_name: identifier | qualified_identifier -``` - -### Identifiers - -In KCL, an identifier is a name, may with selectors, that identifies a value. - -Syntax: - -```bnf -identifier: NAME -``` - -Examples: - -```python -x -a -_b -``` - -Use the `$` character prefix to define keyword identifiers. - -```python -$if = 1 -$else = "s" -``` - -Please note: whether the non-keyword identifier is prefixed with `$` has the same effect. - -```python -_a = 1 -$_a = 2 # equal to `_a = 2` -``` - -To simplify the definition of the qualified identifier, such as 'pkg.type', we additionally define `qualified_identifier`: - -Syntax: - -```bnf -qualified_identifier: identifier "." identifier -``` - -Examples: - -```python -pkg.a -``` - -The package name in qualified_identifier must be imported. - -### Basic Literals - -Basic literals supported in KCL are `int`, `float`, `string` and `bool` including `True` and `False`. Evaluation of basic literal yields a value of the given type with the given value. - -Syntax: - -```bnf -operand: number | string | "True" | "False" | "None" | "Undefined" -``` - -Examples: - -```python -1 -2.3 -"abc" -True -False -None -Undefined -``` - -See more details about **data type** spec. - -### Parenthesized Expressions - -An expression enclosed in parentheses yields the result of that expression. - -Syntax: - -```bnf -operand: '(' expression ')' -``` - -Examples: - -```python -x = (1 + 2) * (3 + 4) # 21 -``` - -### Dictionary Expressions - -A dictionary expression is a comma-separated immutable list of colon-separated key/value expression pairs, enclosed in curly brackets, and it yields a new dictionary object. An optional comma may follow the final pair. - -```bnf -config_expr: '{' config_entries '}' -config_entries: config_entry [config_entry*] -config_comp: '{' (config_entry comp_clause+) '}' -config_entry: expr (':' | '=' | '+=') expr | double_star_expr | if_entry -double_star_expr: "**" expression -if_entry: - 'if' expr ';' if_entry_exec_block - ('elif' expr ':' if_entry_exec_block)* - ('else' ':' if_entry_exec_block)? -NEWLINE: '/r?/n' -``` - -Examples: - -```python -{} -{"one": 1} -{"one": 1, "two": 2} -``` - -The key and value expressions are evaluated in left-to-right order. Evaluation fails if the same key is used multiple times. - -Only hashable values may be used as the keys of a dictionary. This includes all built-in types except dictionaries, and lists. - -We can ignore the comma `,` at the end of the line for writing dict key-value pairs in multiple lines: - -```python -data = { - "key1" = "value1" # Ignore the comma ',' at the end of line - "key2" = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -We can ignore the key quotation marks when we writing simple literals on the key. - -```python -data = { - key1 = "value1" # Ignore the comma ',' at the end of line - key2 = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -In addition, the **config selector expressions** can be used to init a schema instance. - -```python -person = { - base.count = 2 - base.value = "value" - labels.key = "value" -} # {"base": {"count": 2, "value": "value"}, "labels": {"key": "value"}} -``` - -We can **merge** dict using the dict unpacking operator `**` like this: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = {**_part1, **_part2} # {"a: "b", "c": "d"} -``` - -We can use `if expressions` to dynamically add elements to the dict element, elements that meet the conditions are added to the dict, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = { - key1 = "value1" - if a == 1: key2 = "value2" - if a > 0: key3 = "value3" - if a < 0: key4 = "value4" -} # {"key1": "value1", "key2": "value2", "key3": "value3"} -``` - -```python -a = 1 # 1 -data1 = { - key1 = "value1" - if a == 1: - key2 = "value2" - elif a > 0: - key3 = "value3" - else: - key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -data2 = { - key1 = "value1" - if a == 1: key2 = "value2" - elif a > 0: key3 = "value3" - else: key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -``` - -### List Expressions - -A list expression is a comma-separated immutable list of element expressions, enclosed in square brackets, and it yields a new list. An optional comma may follow the last element expression. - -```bnf -list_expr: '[' [list_item [',']] ']' -list_item: test | "*" primary_expr | if_expr -``` - -Element expressions are evaluated in left-to-right order. - -Examples: - -```python -[] # [], empty list -[1] # [1], a 1-element list -[1, 2, 3] # [1, 2, 3], a 3-element list -``` - -We can use `if expressions` to dynamically add elements to the list element, elements that meet the conditions are added to the list, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = [ - 1 - if a == 1: 2 - if a > 0: 3 - if a < 0: 4 -] # [1, 2, 3] -``` - -```python -a = 1 # 1 -data1 = [ - 1 - if a == 1: - 2 - elif a == 2: - 3 - else: - 3 -] # [1, 2] -data2 = [ - 1 - if a == 1: 2 - elif a == 2: 2 - else: 3 -] # [1, 2] -``` - -### Comprehensions - -A comprehension constructs a new list or dictionary value by looping over one or more iterables and evaluating a body expression that produces successive elements of the result. - -Syntax: - -```bnf -list_comp: '[' list_item comp_clause+ ']' . -dict_comp: '{' entry comp_clause+ '}' . - -comp_clause: 'for' loop_variables [","] 'in' test ['if' test] -loop_variables: primary_expr (',' primary_expr)* -``` - -A list comprehension consists of a single expression followed by one or more clauses, the first of which must be a `for` clause. Each `for` clause resembles a `for` statement, and specifies an iterable operand and a set of variables to be assigned by successive values of the iterable. An `if` cause resembles an `if` statement, and specifies a condition that must be met for the body expression to be evaluated. A sequence of `for` and `if` clauses acts like a nested sequence of `for` and `if` statements. - -Examples: - -```python -[x * x for x in range(5)] # [0, 1, 4, 9, 16] -[x * x for x in range(5) if x % 2 == 0] # [0, 4, 16] -[[x, y] for x in range(5) \ - if x % 2 == 0 \ - for y in range(5) \ - if y > x] # [[0, 1], [0, 2], [0, 3], [0, 4], [2, 3], [2, 4]] -``` - -Besides, we can use two variables in the list comprehension, the first variable denotes the list index and the second variable denotes the list item. - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use `_` to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -A dict comprehension resembles a list comprehension, but its body is a pair of expressions, key: value, separated by a colon, and its result is a dictionary containing the key/value pairs for which the body expression was evaluated. Evaluation fails if the value of any key is un-hashable. - -Besides, we can use two variables in the dict comprehension, the first variable denotes the dict key and the second variable denotes the dict value of the key. - -```python -data = {"key1" = "value1", "key2" = "value2"} -# Single variable loop -dataKeys1 = {k: k for k in data} # {"key1": "key1", "key2": "key2"} -dataValues1 = {k: data[k] for k in data} # {"key1": "value1", "key2": "value2"} -# Double variable loop -dataKeys2 = {k: k for k, v in data} # {"key1": "key1", "key2": "key2"} -dataValues2 = {v: v for k, v in data} # {"value1": "value1", "value2": "value2"} -dataFilter = {k: v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use `_` to ignore loop variables -dataKeys3 = {k: k for k, _ in data} # {"key1": "key1", "key2": "key2"} -dataValues3 = {v: v for _, v in data} # {"value1": "value1", "value2": "value2"} -``` - -As with a `for` loop, the loop variables may exploit compound assignment: - -```python -[x * y + z for [x, y], z in [[[2, 3], 5], [["o", 2], "!"]]] # [11, 'oo!'] -``` - -KCL does not accept an un-parenthesized list as the operand of a for clause: - -```python -[x * x for x in 1, 2, 3] # parse error: unexpected comma -``` - -Comprehensions defines a new lexical block, so assignments to loop variables have no effect on variables of the same name in an enclosing block: - -```python -x = 1 -_ = [x for x in [2]] # new variable x is local to the comprehension -print(x) # 1 -``` - -The operand of a comprehension's first clause (always a for) is resolved in the lexical block enclosing the comprehension. In the examples below, identifiers referring to the outer variable named x have been distinguished by subscript. - -```python -x0 = [1, 2, 3] -[x * x for x in x0] # [1, 4, 9] -[x * x for x in x0 if x % 2 == 0] # [4] -``` - -All subsequent for and if expressions are resolved within the comprehension's lexical block, as in this rather obscure example: - -```python -x0 = [[1, 2], [3, 4], [5, 6]] -[x * x for x in x0 for x in x if x % 2 == 0] # [4, 16, 36] -``` - -which would be more clearly rewritten as: - -```python -x = [[1, 2], [3, 4], [5, 6]] -[z * z for y in x for z in y if z % 2 == 0] # [4, 16, 36] -``` - -### Conditional Expressions - -A conditional expression has the form `a if cond else b`. It first evaluates the condition `cond`. If it's true, it evaluates `a` and yields its value; otherwise it yields the value of `b`. - -Syntax: - -```bnf -if_expr: test "if" test "else" test -``` - -Examples: - -```python -x = True if enabled else False # if enabled is -``` - -### Unary Expressions - -In KCL, supported unary operators are `+`, `-`, `~`, and `not`. - -Syntax: - -```bnf -unary_expr: ("+" | "-" | "~") primary_expr - | "not" test -``` - -Usage: - -```bnf -+ number unary positive (int, float) -- number unary negation (int, float) -~ number unary bitwise inversion (int) -not x logical negation (any type) -``` - -The `+` and `-` operators may be applied to any number (int or float) and return the number. -The `not` operator returns the negation of the truth value of its operand. - -Examples: - -```python -~1 # -2 -~-1 # 0 -~0 # -1 -not True # False -not 0 # True -``` - -### Binary Expressions - -In KCL, binary expressions consist of `comparisons`, `logical operations`, `arithmetic operations` and `membership tests`. - -Syntax: - -```bnf -binary_expr: test bin_op test -bin_op: 'or' - | 'and' - | '==' | '!=' | '<' | '>' | '<=' | '>=' - | 'in' | 'not' 'in' - | '|' - | '^' - | '&' - | '-' | '+' - | '*' | '%' | '/' | '//' - | '<<' | '>>' -``` - -#### Logical Operations - -The `or` and `and` operators yield the logical disjunction and conjunction of their arguments, which need not be Booleans. - -The expression `x or y` yields the value of `x` if its truth value is `True`, or the value of `y` otherwise. - -```python -False or False # False -False or True # True -True or True # True -1 or "hello" # 1 -``` - -Similarly, `x` and `y` yields the value of `x` if its truth value is `False`, or the value of `y` otherwise. - -```python -False and False # False -False and True # False -True and True # True -1 and "hello" # "hello" -``` - -These operators use "short circuit" evaluation, so the second expression is not evaluated if the value of the first expression has already determined the result, allowing constructions like these: - -```python -x and x[0] == 1 # x[0] is not evaluated if x is empty -len(x) == 0 or x[0] == "" -not x or not x[0] -``` - -#### Comparisons - -The `==` operator reports whether its operands are equal; the `!=` operator is its negation. - -The operators `<`, `>`, `<=`, and `>=` perform an ordered comparison of their operands. It is an error to apply these operators to operands of unequal type, unless one of the operands is an `int` and the other is a `float`. Of the built-in types, only the following support ordered comparison, using the ordering relation shown: - -```bnf -NoneType # None <= None -bool # False < True -int # mathematical -float # as defined by IEEE 754 -string # lexicographical -list # lexicographical -``` - -Comparison of floating-point values follows the IEEE 754 standard, which breaks several mathematical identities. For example, if `x` is a `NaN` value, the comparisons `x < y`, `x == y`, and `x > y` all yield false for all values of `y`. - -The remaining built-in types support only equality comparisons. Values of type `dict` and `schema` compare equal if their elements compare equal, and values of type function or `builtin_function_or_method` are equal only to themselves. - -```bnf -dict # equal contents -schema # equal exported-attributes -function # identity -builtin_function_or_method # identity -``` - -#### Arithmetic Operations - -The following table summarizes the binary arithmetic operations available for built-in types: - -```bnf -Arithmetic (int or float; result has type float unless both operands have type int) - number + number # addition - number - number # subtraction - number * number # multiplication - number / number # real division (result is always a float) - number // number # floored division - number % number # remainder of floored division - number ^ number # bitwise XOR - number << number # bitwise left shift - number >> number # bitwise right shift - -Concatenation - string + string - list + list - -Repetition (string/list) - int * sequence - sequence * int - -Union - int | int - list | list - dict | dict - schema | schema - schema | dict -basictype | basictype -``` - -The operands of the arithmetic operators `+`, `-`, `*`, `//`, and `%` must both be numbers (`int` or `float`) but need not have the same type. The type of the result has type `int` only if both operands have that type. The result of real division / always has type `float`. - -The `+` operator may be applied to non-numeric operands of the same type, such as two lists, or two strings, in which case it computes the concatenation of the two operands and yields a new value of the same type. - -```python -"Hello, " + "world" # "Hello, world" -[1, 2] + [3, 4] # [1, 2, 3, 4] -``` - -The `*` operator may be applied to an integer n and a value of type `string`, `list`, in which case it yields a new value of the same sequence type consisting of n repetitions of the original sequence. The order of the operands is immaterial. Negative values of n behave like zero. - -```python -'mur' * 2 # 'murmur' -3 * range(3) # [0, 1, 2, 0, 1, 2, 0, 1, 2] -``` - -The `&` operator requires two operands of the same type, such as `int`. For integers, it yields the bitwise intersection (AND) of its operands. - -The `|` operator likewise computes bitwise, unions basic types and unions collection and schema data, such as **list**, **dict** and **schema**. - -Computing bitwise examples: - -```python -0x12345678 | 0xFF # 0x123456FF -``` - -Unioning basic types examples: - -```python -schema x: - a: int | str # attribute a could be a int or string -``` - -A union type is used to define a schema attribute type. See more details in **schema** spec. -Supported types in a union type are `int`, `str`, `float`, `bool`, `list` and `dict`. - -Unioning collection and schema data: - -- Unioning List. Overwrite the list expression on the right side of the operator `|` to the list variable on the left side of the operator one by one according to the **index**. - -```python -_a = [1, 2, 3] -_b = [4, 5, 6, 7] -x = _a | _b # [4, 5, 6, 7] 4 -> 1; 5 -> 2; 6 -> 3; 7 -> None -``` - -Unioning to the specific index or all elements is still under discussion. - -- Unioning Dict. Union the dict expression on the right side of the operator `|` one by one to the dict variable on the left side of the operator according to the **key** - -```python -_a = {key1 = "value1"} -_b = {key1 = "overwrite", key2 = "value2"} -_c = _a | _b # {"key1": "overwrite", "key2": "value2"} -``` - -The union of collection and schema is a new one whose attributes are unioning b to a, preserving the order of the attributes of the operands, left before right. - -Unioning to the specific key or all keys is still under discussion. - -- Unioning Schema. - -The union operation for schema is similar to dict. - -Schema union could be done as: - -```bnf -schema Person: - firstName: str - lastName: str - -_a = Person { - firstName = "John" -} -_b = {lastName = "Doe"} -_a = _a | _b # {"firstName": "John", "lastName": "Doe"} -``` - -Unioning to a specific attribute is still under discussion. Unioning to all attributes is not applicable to schema instances. - -See **selector expression** in **expression** spec for more details. - -The `^` operator accepts operands of `int`. For integers, it yields the bitwise XOR (exclusive OR) of its operands. - -The `<<` and `>>` operators require operands of `int` type both. They shift the first operand to the left or right by the number of bits given by the second operand. It is a dynamic error if the second operand is negative. Implementations may impose a limit on the second operand of a left shift. - -```python -0x12345678 & 0xFF # 0x00000078 -0b01011101 ^ 0b110101101 # 0b111110000 -0b01011101 >> 2 # 0b010111 -0b01011101 << 2 # 0b0101110100 -``` - -#### Membership Tests - -Usage: - -```bnf - any in sequence (list, dict, schema, string) - any not in sequence -``` - -The `in` operator reports whether its first operand is a member of its second operand, which must be a list, dict, schema, or string. The `not in` operator is its negation. Both return a Boolean. - -The meaning of membership varies by the type of the second operand: the members of a list are its elements; the members of a dict are its keys; the members of a string are all its substrings. - -```python -1 in [1, 2, 3] # True - -d = {"one" = 1, "two" = 2} -"one" in d # True -"three" in d # False -1 in d # False -[] in d # False - -"nasty" in "dynasty" # True -"a" in "banana" # True -"f" not in "way" # True - -d = data {one = 1, two = 2} # data is a schema with attributes one and two -"one" in d # True -"three" in d # False -``` - -### Function Invocations - -KCL allows calling built-in functions and functions from built-in and system modules. Whether KCL allows defining new functions is under discussion. - -Syntax: - -```bnf -call_suffix: "(" [arguments [","]] ")" -arguments: argument ("," argument)* -argument: test | identifier "=" test | "*" test | "**" test -``` - -To call a function, the basic way is shown as the following code excerpt: - -```python -print("An argument") - -import math -# 2 powers 3 is 8. -a = math.pow(2, 3) -``` - -As you can see, arguments are separated with `,`. Arguments can only be passed in this way. KCL supports positional arguments and key-value arguments. - -Note that: - -- Some functions have parameters with default values. -- Some functions accept variadic arguments. - -When an argument is not supplied for a parameter without a default value, -an error will be reported. - -### Selector Expressions - -A selector expression selects the attribute or method of the value. - -#### Select Attributes - -Syntax: - -```bnf -select_suffix: ["?"] "." identifier -``` - -KCL provides a wealth of ways to identify or filter attributes. - -x.y - -- schema: it denotes the attribute value of a schema `x` identified by `y` -- package: it denotes the identifier of a package `x` identified by `y` - -Examples: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -name = person.name # "Alice" -age = person.age # 18 -``` - -x?.y - -If the x if None/Undefined or empty(empty list or dict), just return None, otherwise behave as x.y. - -Examples - -```python -noneData = None -data?.name # None - -emptyDict = {} -emptyDict?.name # None - -emptyList = [] -emptyList?[0] # None -``` - -As a supplementary of the `selector` expression in KCL code, the KCL compiler needs to provide corresponding identifying and filtering features through the command line and api form. - -#### Select Methods - -Syntax: - -```bnf -select_suffix: "." identifier -``` - -A `identifier` identifies method belongs to the built-in types `string`, `list`, `dict`, and `schema`. - -- A selector expression fails if the value does not have an attribute of the specified name. -- A selector expression that selects a method typically appears within a call expression, as in these examples: - -Examples: - -```python -["able", "baker", "charlie"].index("baker") # 1 -"banana".count("a") # 3 -"banana".reverse() # error: string has no .reverse field or method -Person.instances() # all instances of schema Person -``` - -But when not called immediately, the selector expression evaluates to a bound method, that is, a method coupled to a specific receiver value. A bound method can be called like an ordinary function, without a receiver argument: - -```bnf -f = "banana".count -f # -f("a") # 3 -f("n") # 2 -``` - -### Index Expressions - -An index expression `a[i]` yields the `i` th element of an indexable type such as a string or list. The index `i` must be an `int` value in the range `-n` ≤ `i` < `n`, where `n` is `len(a)`; any other index results in an error. - -Syntax: - -```bnf -subscript_suffix: "[" [test] "]" -``` - -A valid negative index `i` behaves like the non-negative index `n+i`, allowing for convenient indexing relative to the end of the sequence. - -```python -"abc"[0] # "a" -"abc"[1] # "b" -"abc"[-1] # "c" - -["zero", "one", "two"][0] # "zero" -["zero", "one", "two"][1] # "one" -["zero", "one", "two"][-1] # "two" -``` - -An index expression `d[key]` may also be applied to a dictionary `d`, to obtain the value associated with the specified key. It returns `Undefined` if the dictionary contains no such key. - -An index expression appearing on the left side of an assignment causes the specified list or dictionary element to be updated: - -```python -a = range(3) # a == [0, 1, 2] -b = a[2] # 2 - - -``` - -It is a dynamic error to attempt to update an element of an immutable type, such as a list or string, or a frozen value of a mutable type. - -### Slice Expressions - -A slice expression `a[start:stop:stride]` yields a new value containing a sub-sequence of `a`, which must be a string, or list. - -```bnf -subscript_suffix: "[" [test] [":" [test] [":" [test]]] "]" -``` - -Each of the `start`, `stop`, and `stride` operands is optional; if present, and not `None`, each must be an integer. -The `stride` value defaults to 1. If the stride is not specified, the colon preceding it may be omitted too. It is an error to specify a stride of zero. - -Conceptually, these operands specify a sequence of values `i` starting at start and successively adding `stride` until `i` reaches or passes `stop`. The result consists of the concatenation of values of `a[i]` for which `i` is valid.` - -The effective start and stop indices are computed from the three operands as follows. Let `n` be the length of the sequence. - -**If the stride is positive**: If the `start` operand was omitted, it defaults to -infinity. If the `end` operand was omitted, it defaults to +infinity. For either operand, if a negative value was supplied, `n` is added to it. The `start` and `end` values are then "clamped" to the nearest value in the range 0 to `n`, inclusive. - -**If the stride is negative**: If the `start` operand was omitted, it defaults to +infinity. If the `end` operand was omitted, it defaults to -infinity. For either operand, if a negative value was supplied, `n` is added to it. The `start` and `end` values are then "clamped" to the nearest value in the range -1 to `n`-1, inclusive. - -```python -"abc"[1:] # "bc" (remove first element) -"abc"[:-1] # "ab" (remove last element) -"abc"[1:-1] # "b" (remove first and last element) -"banana"[1::2] # "aaa" (select alternate elements starting at index 1) -"banana"[4::-2] # "nnb" (select alternate elements in reverse, starting at index 4) -``` - -It's not allowed to define a slice expression as a left value in KCL. -Cause list and string are immutable, re-slicing can directly operate to operand to ensure better performance. - -#### Quantifier Expressions - -Quantifier expressions act on collection: list or dict, generally used to obtain a certain result after processing the collection, mainly in the following four forms: - -```bnf -quant_expr: quant_op [ identifier ',' ] identifier 'in' quant_target '{' expr ['if' expr] '}' -quant_target: string | identifier | list_expr |list_comp | dict_expr | dict_comp -quant_op: 'all' | 'any' | 'filter' | 'map' -``` - -- **all** - - Used to detect that all elements in the collection satisfy the given logical expression, and return a boolean value as the result. - - Only when all elements in the collection satisfy the expression true, the `all` expression is true, otherwise it is false. - - If the original collection is empty, return true. - - Supports short-circuiting of logical expressions during expression execution. -- **any** - - Used to detect that at least one element in the collection satisfies the given logical expression, and returns a boolean value as the result. - - When at least one element in the collection satisfies the expression true, the `any` expression is true, otherwise it is false. - - If the original collection is empty, return false. - - Supports short-circuiting of logical expressions during expression execution. -- **map** - - Generate a new **list** by mapping the elements in the original collection. - - The length of the new list is exactly the same as the original collection. -- **filter** - - By logically judging and filtering the elements in the original collection, and returning the filtered sub-collection. - - Only when the element judges the expression to be true, it is added to the sub-collection. - - The type (list, dict and schema) of the new collection is exactly the same as the original collection, and the length range is `[0, len(original-collection)]`. - -**all** and **any** expression sample codes: - -```python -schema Config: - volumes: [{str:}] - services: [{str:}] - - check: - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - }, "invalid cluster ip" - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } -``` - -**map** and **filter** expression sample codes: - -```python -a = map e in [{name = "1", value = 1}, {name = "2", value = 2}] { - {name = e.name, value = int(e.value) ** 2} -} # [{"name": "1", value: 1}, {"name": "2", "value": 4}] - -b = map k, v in {a = "foo", b = "bar"} { v } # ["foo", "bar"] - -c = filter e in [{name = "1", value = 1}, {name = "2", value = 2}] { - int(e.value) > 1 -} # [{"name": "2", "value": 2}] - -d = filter _, v in {a = "foo", b = "bar"} { - v == "foo" -} # {"a": "foo"} -``` - -Please pay attention to distinguish the difference between any expression and any type. When `any` is used in type annotations, it means that the value of the variable is arbitrary, while the any expression means that one of the elements in a set satisfies the condition. diff --git a/versioned_docs/version-0.5.1/reference/lang/spec/kcl-spec.md b/versioned_docs/version-0.5.1/reference/lang/spec/kcl-spec.md deleted file mode 100644 index 63a9d6e7..00000000 --- a/versioned_docs/version-0.5.1/reference/lang/spec/kcl-spec.md +++ /dev/null @@ -1,343 +0,0 @@ ---- -title: "KCL Spec" -linkTitle: "KCL Spec" -type: "docs" -weight: 2 -description: KCL Spec ---- - -## Lexical rules - -### Keywords and reserved words - -The following are the keywords of the KCL: - -```python -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -The following are reserved words for the KCL: - -```python -pass return validate rule flow -def del raise except try -finally while from with yield -global nonlocal struct class final -``` - -### Line comment - -```python -# a comment -``` - -### Operators - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != = -+= -= *= **= /= //= %= -<<= >>= &= ^= -``` - -### Delimiters - -```python -( ) [ ] { } -, : . ; @ -``` - -### Operator precedence - -The following list of operators is ordered from **highest to lowest**: - -| Operator | Description | -| -------------------------------------------------------------------------------- | -------------------------------------------------------- | -| `**` | Exponentiation (highest priority) | -| `+x` `-x` `~x` | Positive, negative, bitwise NOT | -| `*` `/` `%` `//` | Multiplication, division, floor division and remainder | -| `+` `-` | Addition and subtraction | -| `<<` `>>` | Left and right shifts | -| `&` | Bitwise AND | -| `^` | Bitwise XOR | -| \| | Bitwise OR | -| `in`, `not in`, `is`, `is not`, `<`, `<=`, `>`, `>=`, `!=`, `==` | Comparisons, including membership and identity operators | -| `not` | Boolean NOT | -| `and` | Boolean AND | -| `or` | Boolean OR | -| `if – else` | Conditional expression = | -| `=`, `+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `=`, `^=`, `\*\*=`, `//=`, `<<=`, `>>=` | Assign | - -## Grammar - -KCL uses Python's [LarkParser](https://lark-parser.readthedocs.io/en/latest/) tool to describe the grammar, and the specification rules are as follows: - -```bnf -//////////// KCL grammar //////////// -start: (NEWLINE | statement)* - -statement: simple_stmt | compound_stmt -simple_stmt: (assign_stmt | unification_stmt | expr_stmt | assert_stmt | import_stmt | type_alias_stmt) NEWLINE -compound_stmt: if_stmt | schema_stmt | rule_stmt - -//////////// import_stmt //////////// -import_stmt: IMPORT dot_name (AS NAME)? -dot_name: (leading_dots identifier) | identifier -leading_dots: DOT+ - -/////////// assert_stmt //////////// -assert_stmt: ASSERT simple_expr (IF simple_expr)? (COMMA test)? - -//////////// if_stmt //////////// -if_stmt: IF test COLON execution_block (ELIF test COLON execution_block)* (ELSE COLON execution_block)? -execution_block: if_simple_stmt | NEWLINE _INDENT schema_init_stmt+ _DEDENT -if_simple_stmt: (simple_assign_stmt | unification_stmt | expr_stmt | assert_stmt) NEWLINE - -//////////// assign_stmt //////////// -assign_stmt: identifier [COLON type] (ASSIGN identifier)* ASSIGN test - | identifier (COMP_PLUS | COMP_MINUS | COMP_MULTIPLY | COMP_DOUBLE_STAR | COMP_DIVIDE - | COMP_DOUBLE_DIVIDE | COMP_MOD | COMP_AND | COMP_OR | COMP_XOR | COMP_SHIFT_LEFT - | COMP_SHIFT_RIGHT) test - -simple_assign_stmt: identifier ASSIGN test - | identifier (COMP_PLUS | COMP_MINUS | COMP_MULTIPLY | COMP_DOUBLE_STAR | COMP_DIVIDE - | COMP_DOUBLE_DIVIDE | COMP_MOD | COMP_AND | COMP_OR | COMP_XOR | COMP_SHIFT_LEFT - | COMP_SHIFT_RIGHT) test - -//////////// unification_stmt //////////// -unification_stmt: identifier COLON schema_expr - -//////////// schema_stmt //////////// -schema_stmt: [decorators] (SCHEMA|MIXIN|PROTOCOL) NAME [LEFT_BRACKETS [schema_arguments] RIGHT_BRACKETS] [LEFT_PARENTHESES identifier (COMMA identifier)* RIGHT_PARENTHESES] [for_host] COLON NEWLINE [schema_body] -schema_arguments: schema_argument (COMMA schema_argument)* -schema_argument: NAME [COLON type] [ASSIGN test] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt|schema_init_stmt|schema_index_signature)* [check_block] _DEDENT -schema_attribute_stmt: attribute_stmt NEWLINE -attribute_stmt: [decorators] identifier [QUESTION] COLON type [(ASSIGN|COMP_OR) test] -schema_init_stmt: if_simple_stmt | if_stmt -schema_index_signature: LEFT_BRACKETS [NAME COLON] [ELLIPSIS] basic_type RIGHT_BRACKETS COLON type [ASSIGN test] NEWLINE - -//////////// rule_stmt //////////// -rule_stmt: [decorators] RULE NAME [LEFT_BRACKETS [schema_arguments] RIGHT_BRACKETS] [LEFT_PARENTHESES identifier (COMMA identifier)* RIGHT_PARENTHESES] [for_host] COLON NEWLINE [rule_body] -rule_body: _INDENT (string NEWLINE)* check_expr+ _DEDENT - -for_host: FOR identifier - -/////////// decorators //////////// -decorators: (AT decorator_expr NEWLINE)+ -decorator_expr: identifier [call_suffix] - -//////////// type //////////// -type: type_element (OR type_element)* -type_element: schema_type | basic_type | compound_type | literal_type -schema_type: identifier -basic_type: STRING_TYPE | INT_TYPE | FLOAT_TYPE | BOOL_TYPE | ANY_TYPE -compound_type: list_type | dict_type -list_type: LEFT_BRACKETS (type)? RIGHT_BRACKETS -dict_type: LEFT_BRACE (type)? COLON (type)? RIGHT_BRACE -literal_type: string | number | TRUE | FALSE | NONE - -//////////// type alias //////////// -type_alias_stmt: TYPE NAME ASSIGN type - -//////////// check_stmt //////////// -check_block: CHECK COLON NEWLINE _INDENT check_expr+ _DEDENT -check_expr: simple_expr [IF simple_expr] [COMMA primary_expr] NEWLINE - -//////////// mixin_stmt //////////// -mixin_stmt: MIXIN LEFT_BRACKETS [mixins | multiline_mixins] RIGHT_BRACKETS NEWLINE -multiline_mixins: NEWLINE _INDENT mixins NEWLINE _DEDENT -mixins: identifier (COMMA (NEWLINE mixins | identifier))* - - -//////////// expression_stmt //////////// -expr_stmt: testlist_expr -testlist_expr: test (COMMA test)* -test: if_expr | simple_expr -if_expr: simple_expr IF simple_expr ELSE test - -simple_expr: unary_expr | binary_expr | primary_expr - -unary_expr: un_op simple_expr -binary_expr: simple_expr bin_op simple_expr - -bin_op: L_OR | L_AND - | OR | XOR | AND - | SHIFT_LEFT | SHIFT_RIGHT - | PLUS | MINUS | MULTIPLY | DIVIDE | MOD | DOUBLE_DIVIDE - | DOUBLE_STAR - | EQUAL_TO | NOT_EQUAL_TO - | LESS_THAN | GREATER_THAN | LESS_THAN_OR_EQUAL_TO | GREATER_THAN_OR_EQUAL_TO - | IN | L_NOT IN | IS | IS L_NOT | L_NOT | AS -un_op: L_NOT | PLUS | MINUS | NOT - -primary_expr: identifier call_suffix | operand | primary_expr select_suffix | primary_expr call_suffix | primary_expr slice_suffix -operand: identifier | number | string | constant | quant_expr | list_expr | list_comp | config_expr | dict_comp | schema_expr | lambda_expr | LEFT_PARENTHESES test RIGHT_PARENTHESES -select_suffix: [QUESTION] DOT NAME -call_suffix: LEFT_PARENTHESES [arguments [COMMA]] RIGHT_PARENTHESES -slice_suffix: [QUESTION] LEFT_BRACKETS (test | [test] COLON [test] [COLON [test]]) RIGHT_BRACKETS -arguments: argument (COMMA argument)* -argument: test | NAME ASSIGN test | MULTIPLY test | DOUBLE_STAR test - - -//////////// operand //////////// -identifier: NAME (DOT NAME)* -quant_expr: quant_op [ identifier COMMA ] identifier IN quant_target LEFT_BRACE (simple_expr [IF simple_expr] | NEWLINE _INDENT simple_expr [IF simple_expr] NEWLINE _DEDENT)? RIGHT_BRACE -quant_target: string | identifier | list_expr | list_comp | config_expr | dict_comp -quant_op: ALL | ANY | FILTER | MAP -list_expr: LEFT_BRACKETS [list_items | NEWLINE [_INDENT list_items _DEDENT]] RIGHT_BRACKETS -list_items: list_item ((COMMA [NEWLINE] | [NEWLINE]) list_item)* [COMMA] [NEWLINE] -list_item: test | star_expr | if_item -list_comp: LEFT_BRACKETS (list_item comp_clause+ | NEWLINE _INDENT list_item comp_clause+ _DEDENT) RIGHT_BRACKETS -dict_comp: LEFT_BRACE (entry comp_clause+ | NEWLINE _INDENT entry comp_clause+ _DEDENT) RIGHT_BRACE -entry: test (COLON | ASSIGN | COMP_PLUS) test -comp_clause: FOR loop_variables [COMMA] IN simple_expr [NEWLINE] [IF test [NEWLINE]] -if_entry: IF test COLON if_entry_exec_block (ELIF test COLON if_entry_exec_block)* (ELSE COLON if_entry_exec_block)? -if_entry_exec_block: (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry) [NEWLINE] | NEWLINE _INDENT (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry) ((COMMA [NEWLINE] | [NEWLINE]) (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry))* [COMMA] [NEWLINE] _DEDENT -if_item: IF test COLON if_item_exec_block (ELIF test COLON if_item_exec_block)* (ELSE COLON if_item_exec_block)? -if_item_exec_block: list_item [NEWLINE] | NEWLINE _INDENT list_item ((COMMA [NEWLINE] | NEWLINE) list_item)* [COMMA] [NEWLINE] _DEDENT - -star_expr: MULTIPLY test -double_star_expr: DOUBLE_STAR test -loop_variables: primary_expr (COMMA primary_expr)* -schema_expr: identifier (LEFT_PARENTHESES [arguments] RIGHT_PARENTHESES)? config_expr -config_expr: LEFT_BRACE [config_entries | NEWLINE [_INDENT config_entries _DEDENT]] RIGHT_BRACE -config_entries: config_entry ((COMMA [NEWLINE] | [NEWLINE]) config_entry)* [COMMA] [NEWLINE] -config_entry: test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry - -//////////// lambda_expr //////////// -lambda_expr: LAMBDA [schema_arguments] [RIGHT_ARROW type] LEFT_BRACE [expr_stmt | NEWLINE _INDENT schema_init_stmt+ _DEDENT] RIGHT_BRACE - -//////////// misc //////////// -number: DEC_NUMBER [multiplier] | HEX_NUMBER | BIN_NUMBER | OCT_NUMBER | FLOAT_NUMBER -multiplier: SI_N_L | SI_U_L | SI_M_L | SI_K_L | SI_K | SI_M | SI_G | SI_T | SI_P - | SI_K_IEC | SI_M_IEC | SI_G_IEC | SI_T_IEC | SI_P_IEC -string: STRING | LONG_STRING -constant : TRUE | FALSE | NONE | UNDEFINED -// Tokens - -ASSIGN: "=" -COLON: ":" -SEMI_COLON: ";" -COMMA: "," -QUESTION: "?" -ELLIPSIS: "..." -RIGHT_ARROW: "->" -LEFT_PARENTHESES: "(" -RIGHT_PARENTHESES: ")" -LEFT_BRACKETS: "[" -RIGHT_BRACKETS: "]" -LEFT_BRACE: "{" -RIGHT_BRACE: "}" -PLUS: "+" -MINUS: "-" -MULTIPLY: "*" -DIVIDE: "/" -MOD: "%" -DOT: "." -AND: "&" -OR: "|" -XOR: "^" -NOT: "~" -LESS_THAN: "<" -GREATER_THAN: ">" -EQUAL_TO: "==" -NOT_EQUAL_TO: "!=" -GREATER_THAN_OR_EQUAL_TO: ">=" -LESS_THAN_OR_EQUAL_TO: "<=" -DOUBLE_STAR: "**" -DOUBLE_DIVIDE: "//" -SHIFT_LEFT: "<<" -SHIFT_RIGHT: ">>" -AT: "@" - -COMP_PLUS: "+=" -COMP_MINUS: "-=" -COMP_MULTIPLY: "*=" -COMP_DIVIDE: "/=" -COMP_MOD: "%=" -COMP_AND: "&=" -COMP_OR: "|=" -COMP_XOR: "^=" -COMP_DOUBLE_STAR: "**=" -COMP_DOUBLE_DIVIDE: "//=" -COMP_SHIFT_LEFT: "<<=" -COMP_SHIFT_RIGHT: ">>=" - -// Special tokens -IMPORT: "import" -AS: "as" -RULE: "rule" -SCHEMA: "schema" -MIXIN: "mixin" -PROTOCOL: "protocol" -CHECK: "check" -FOR: "for" -ASSERT: "assert" -IF: "if" -ELIF: "elif" -ELSE: "else" -L_OR: "or" -L_AND: "and" -L_NOT: "not" -IN: "in" -IS: "is" -LAMBDA: "lambda" -ALL: "all" -ANY: "any" -FILTER: "filter" -MAP: "map" -TYPE: "type" - -ANY_TYPE: "any" -STRING_TYPE: "str" -INT_TYPE: "int" -FLOAT_TYPE: "float" -BOOL_TYPE: "bool" - -// Constant tokens -TRUE: "True" -FALSE: "False" -NONE: "None" -UNDEFINED: "Undefined" - -// Binary prefix -SI_N_L: "n" -SI_U_L: "u" -SI_M_L: "m" -SI_K_L: "k" -SI_K: "K" -SI_M: "M" -SI_G: "G" -SI_T: "T" -SI_P: "P" -SI_K_IEC: "Ki" -SI_M_IEC: "Mi" -SI_G_IEC: "Gi" -SI_T_IEC: "Ti" -SI_P_IEC: "Pi" -IEC: "i" - -NAME: /\$?[a-zA-Z_]\w*/ -COMMENT: /#[^\n]*/ -NEWLINE: ( /\r?\n[\t ]*/ | COMMENT )+ - -STRING: /r?("(?!"").*?(? [as ] -``` - -The rule to search with the module name is very simple: - -- **Step 1**: Searches the module name from the **standard system modules**, then **plugins modules**. - - See **standard system modules** and **plugins modules** for more details. If matched, the module is imported. Otherwise, continue to **Step 2**. -- **Step 2**. Whether a module name starts with a `.` is checked. If yes, the name is a so-called relative pathname, and we go to **Step 5**. Otherwise, continue to **Step 3**. -- **Step 3**: If the module name does not start with any `.`, then the compiler searches the nearest `root path` directory from this directory to the parent, and find the module according to the name just from the `root path`. If no `root path` is found, find the module according to the name from the folder the `.k` file including this `import` statement exists. - - **root path**: the directory contains a `kcl.mod` file. If matched, the module is imported. Otherwise, continue to **Step 4**. -- **Step 4**: Then the compiler checks if the name is the name of any library module that requires explicit loading. If matched, the library module is imported. Otherwise, continue to **Step 6**. -- **Step 5**. For relative importing, find the module according to the name from the folder the `.k` file including this `import` statement exists. Interpret leading dots using the following rule: -- One dot: Ignore. -- Tow or more dots: Suppose there are `n` leading dots, then the searching starts at `n - 1` levels above this folder. If matched, the module is imported. Otherwise, continue to **Step 6**. -- **Step 6**. Module not found, report an error. - -Do case-sensitive search when the operating system allows. If case-sensitive search is not allowed, search directories before regular files. - -In KCL, the `from <> import <>` is unsupported, and relative import is performed with the `import <>` syntax. - -### Uniqueness of Module - -Each module has a unique location path in its scope, so that a module or package could be located with a unique location path, such as `a.b.c`. - -Searching by location path should be supported by the kcl compiler, which needs to provide corresponding searching features through the command line and api form. - -## Standard System Packages - -KCL supports a few standard system modules. The following is the full list of these standard system modules: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PackageMember
datetimetoday
now
ticks
date
mathceil
exp
expm1
factorial
floor
gcd
isfinite
isinf
isnan
log
log1p
log2
log10
modf
pow
sqrt
regexreplace
match
compile
findall
search
split
unitsn
u
m
k
K
M
G
T
P
Ki
Mi
Gi
Ti
Pi
to_n
to_u
to_m
to_K
to_M
to_G
to_T
to_P
to_Ki
to_Mi
to_Gi
to_Ti
to_Pi
jsonencode
decode
dump_to_file
yamlencode
decode
dump_to_file
netsplit_host_port
join_host_port
fqdn
parse_IP
to_IP4
to_IP16
IP_string
is_IPv4
is_IP
is_loopback_IP
is_multicast_IP
is_interface_local_multicast_IP
is_link_local_multicast_IP
is_link_local_unicast_IP
is_global_unicast_IP
is_unspecified_IP
base64encode
decode
cryptomd5
sha1
sha224
sha256
sha384
sha512
- -- datetime - - ticks() -> float - Return the current time in seconds since the Epoch. Fractions of a second may be present if the system clock provides them. - - date() -> str - return the `%Y-%m-%d %H:%M:%S` format date. - - now() -> str - return the local time. e.g. `'Sat Jun 06 16:26:11 1998'` - - today() -> str - return the `%Y-%m-%d %H:%M:%S.%{ticks}` format date. -- math - - ceil(x) -> int - Return the ceiling of x as an Integral. This is the smallest integer >= x. - - factorial(x) -> int - Return x!. Raise a error if x is negative or non-integral. - - floor(x) -> int - Return the floor of x as an Integral. This is the largest integer <= x. - - gcd(a: int, b: int) -> int - Return the greatest common divisor of x and y - - isfinite(x) -> bool - Return True if x is neither an infinity nor a NaN, and False otherwise. - - isinf(x) -> bool - Return True if x is a positive or negative infinity, and False otherwise. - - isnan(x) -> bool - Return True if x is a NaN (not a number), and False otherwise. - - modf(x) -> Listfloat, float] - Return the fractional and integer parts of x. Both results carry the sign of x and are floats. - - exp(x) -> float - Return e raised to the power of x. - - expm1(x) -> float - Return exp(x)-1. This function avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small x. - - log(x, base=2.71828182845904523536028747135266250) -> float - Return the logarithm of x to the base e. - - log1p(x) -> float - Return the natural logarithm of 1+x (base e). The result is computed in a way which is accurate for x near zero. - - log2(x) -> float - Return the base 2 logarithm of x. - - log10(x) -> float - Return the base 10 logarithm of x. - - pow(x, y) -> float - Return x\*\*y (x to the power of y). - - sqrt(x) -> float - Return the square root of x. -- regex - - replace(string: str, pattern: str, replace: str, count=0) -> str - Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement. - - match(string: str, pattern: str) -> bool - Try to apply the pattern at the start of the string, returning a bool value True if any match was found, or False if no match was found. - - compile(pattern: str) -> bool - Compile a regular expression pattern, returning a bool value denoting whether the pattern is valid. - - findall(string: str, pattern: str) -> List[str] - Return a list of all non-overlapping matches in the string. - - search(string: str, pattern: str) -> bool - Scan through string looking for a match to the pattern, returning a bool value True if any match was found, or False if no match was found. - - split(string: str, pattern: str, maxsplit=0) -> List[str] - Scan through string looking for a match to the pattern, returning a Match object, or None if no match was found. -- units - - Unit constants - - Fixed point: `n`, `u`, `m`, `k`, `K`, `G`, `T` and `P`. - - Power of 2: `Ki`, `Mi`, `Gi`, `Ti` and `Pi`. - - Functions - - to_n(num: int) -> str - Int literal to string with `n` suffix - - to_u(num: int) -> str - Int literal to string with `u` suffix - - to_m(num: int) -> str - Int literal to string with `m` suffix - - to_K(num: int) -> str - Int literal to string with `K` suffix - - to_M(num: int) -> str - Int literal to string with `M` suffix - - to_G(num: int) -> str - Int literal to string with `G` suffix - - to_T(num: int) -> str - Int literal to string with `T` suffix - - to_P(num: int) -> str - Int literal to string with `P` suffix - - to_Ki(num: int) -> str - Int literal to string with `Ki` suffix - - to_Mi(num: int) -> str - Int literal to string with `Mi` suffix - - to_Gi(num: int) -> str - Int literal to string with `Gi` suffix - - to_Ti(num: int) -> str - Int literal to string with `Ti` suffix - - to_Pi(num: int) -> str - Int literal to string with `Pi` suffix -- json - - encode(data: any, sort_keys: bool = False, indent: int = None, ignore_private: bool = False, ignore_none: bool = False) -> str - Serialize a KCL object `data` to a JSON formatted str. - - decode(value: str) -> any - Deserialize `value` (a string instance containing a JSON document) to a KCL object. - - dump_to_file(data: any, filename: str, ignore_private: bool = False, ignore_none: bool = False) -> None - Serialize a KCL object `data` to a JSON formatted str and write it into the file `filename`. -- yaml - - encode(data: any, sort_keys: bool = False, ignore_private: bool = False, ignore_none: bool = False) -> str - Serialize a KCL object `data` to a YAML formatted str. - - decode(value: str) -> any - Deserialize `value` (a string instance containing a YAML document) to a KCL object. - - dump_to_file(data: any, filename: str, ignore_private: bool = False, ignore_none: bool = False) -> None - Serialize a KCL object `data` to a YAML formatted str and write it into the file `filename`. -- net - - split_host_port(ip_end_point: str) -> List[str] - Split the 'host' and 'port' from the ip end point. - - join_host_port(host, port) -> str - Merge the 'host' and 'port'. - - fqdn(name: str = '') -> str - Return Fully Qualified Domain Name (FQDN). - - parse_IP(ip) -> str - Parse 'ip' to a real IP address - - to_IP4(ip) -> str - Get the IP4 form of 'ip'. - - to_IP16(ip) -> int - Get the IP16 form of 'ip'. - - IP_string(ip: str | int) -> str - Get the IP string. - - is_IPv4(ip: str) -> bool - Whether 'ip' is a IPv4 one. - - is_IP(ip: str) -> bool - Whether ip is a valid ip address. - - is_loopback_IP(ip: str) -> bool - Whether 'ip' is a loopback one. - - is_multicast_IP(ip: str) -> bool - Whether 'ip' is a multicast one. - - is_interface_local_multicast_IP(ip: str) -> bool - Whether 'ip' is a interface, local and multicast one. - - is_link_local_multicast_IP(ip: str) -> bool - Whether 'ip' is a link local and multicast one. - - is_link_local_unicast_IP(ip: str) -> bool - Whether 'ip' is a link local and unicast one. - - is_global_unicast_IP(ip: str) -> bool - Whether 'ip' is a global and unicast one. - - is_unspecified_IP(ip: str) -> bool - Whether 'ip' is a unspecified one. -- base64 - - encode(value: str, encoding: str = "utf-8") -> str - Encode the string `value` using the codec registered for encoding. - - decode(value: str, encoding: str = "utf-8") -> str - Decode the string `value` using the codec registered for encoding. -- crypto - - md5(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `MD5` and the codec registered for encoding. - - sha1(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA1` and the codec registered for encoding. - - sha224(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA224` and the codec registered for encoding. - - sha256(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA256` and the codec registered for encoding. - - sha384(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA384` and the codec registered for encoding. - - sha512(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA512` and the codec registered for encoding. -- manifests - - `yaml_stream(values: [any], opts: {str:} = {sort_keys = False, ignore_private = True, ignore_none = False, sep = "---"}`. This function is used to serialize the KCL object list into YAML output with the `---` separator - -### The Built-in System Package - -KCL provides a list of built-in system modules, which are loaded automatically and can be directly used without providing any module name. For example, `print` is a widely used built-in module. - -The following is the full list of these built-in system modules: - -- print() - - The print function. -- multiplyof(a, b) - - Check if the modular result of a and b is 0 -- isunique(inval) - - Check if a list has duplicated elements -- len(inval) - Return the length of a value -- abs(x) - Return the absolute value of the argument. -- all(iterable) - Return True if bool(x) is True for all values x in the iterable. If the iterable is empty, return True. -- any(iterable) - Return True if bool(x) is True for any x in the iterable. If the iterable is empty, return False. -- bin(number) - Return the binary representation of an integer. -- hex(number) - Return the hexadecimal representation of an integer. -- oct(number) - Return the octal representation of an integer. -- ord(c) -> int - Return the Unicode code point for a one-character string. -- sorted(iterable) - Return a new list containing all items from the iterable in ascending order. A custom key function can be supplied to customize the sort order, and the reverse flag can be set to request the result in descending order. -- range(start, end, step=1) - Return the range of a value with start, end and step parameter. -- min(iterable) - With a single iterable argument, return its smallest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the smallest argument. -- max(iterable) - With a single iterable argument, return its biggest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the largest argument. -- sum(iterable, start) - Return the sum of a 'start' value (default: 0) plus an iterable of numbers. When the iterable is empty, return the start value. This function is intended specifically for use with numeric values and may reject non-numeric types. -- pow(x, y, z) - Equivalent to `x**y` (with two arguments) or `x**y % z` (with three arguments). Some types, such as ints, are able to use a more efficient algorithm when invoked using the three argument form. -- round(number, ndigits) - Round a number to a given precision in decimal digits. The return value is an integer if ndigits is omitted or None. Otherwise the return value has the same type as the number. ndigits may be negative. -- typeof(x: any, \*, full_name: bool = False) -> str - Return the type of the value 'x' at runtime. When the 'full_name' is 'True', return the full package type name such as `pkg.schema`. - -### Plugin Modules - -KCL compiler needs to provide the ability to dynamically expand and load plugin modules without modifying the compiler itself. KCL compiler needs to support flexible pluggable module extension mechanism, so that KCL users can use more abundant built-in function capabilities to simplify writing. - -KCL compiler needs to ensure the stability and safety of the expansion mechanism, without affecting the core of the compiler. - -Searching extended plugin module is performed after the standard system module. The standard system module has a higher priority in naming. If it exists a standard or built-in system module with the same name, the extended plugin module will be ignored. - -Importing and using the extended plugin module should be consistent with the standard or built-in system module. - -### Replacing Standard System Packages - -Replacing standard system modules is not allowed. - -## Examples - -We show more module features through an example. - -Suppose we have the following directories and files: - -``` - . - ├── mod1.k - ├── mod2.k - ├── pkg1 - │   ├── def1.k - │   ├── def2.k - │   └── def3init.k - └── pkg2 - ├── file2.k - └── subpkg3 - └── file3.k -``` - -From the structure we can see that `pkg1` and `pkg2` are two packages, `subpkg3` is a subpackage of `pkg2`, and `mod1.k` and `mod2.k` are regular modules. - -### Importing a Standard System Package - -The following statement can import the standard system module `math` - -```python -import math -``` - -This is the only way to import a standard system module. After importing a standard system module, functions, variables and schemas defined in it can be used. For example, the following statement uses the `log10` function -defined in `math` - -```python -a = math.log10(100) # a is 2 after computation. -``` - -### Importing a Regular Module - -In `mod1.k`, we can import `mod2` using one of the following syntaxes. - -```python -import mod2 -``` - -```python -import .mod2 -``` - -The difference is that in the first syntax, the KCL compiler will first try to check if `mod2` matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where `mod1.k` resists in, like what the second statement does. - -Suppose in `mod2.k` there is a definition of a variable:: - -```python -a = 100 -``` - -After importing `mod2`, we can access `a` in `mod1.k` using the following syntax - -```python -b = mod2.a -``` - -### Importing a Package - -In `mod1.k`, we can import `pkg1` using one of the following syntaxes. - -```python -import pkg1 -``` - -```python -import .pkg1 -``` - -The difference is that in the first syntax, the KCL compiler will first try to check if `pkg1` matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where `mod1.k` resists in, like what the second statement does. - -We can use similar statements to import `pkg2`. Note that importing `pkg2` will not import `subpkg3`. - -The name of the package is the name of the imported module. - -Suppose in `file2.k` that is inside `pkg2` there is a definition to variable `foo` - -```python -foo = 100 -``` - -This variable can be used in `mod1.k` after importing `pkg2` like the following - -```python -bar = pkg2.foo -``` - -### Importing a Subpackage - -To import `subpkg3` from `mod1.k`, one of the following statements can be used. - -```python -import pkg2.subpkg3 -``` - -```python -import .pkg2.subpkg3 -``` - -The behaviors of these statements are identical. - -The name of the subpackage is the name of the imported module. - -Suppose in `file3.k` that is inside `subpkg3` there is a definition to variable `foo` - -```python -foo = 100 -``` - -This variable can be used in `mod1.k` after importing `subpkg3` like the following - -```python -bar = subpkg3.foo -``` - -### Relative Importing - -Relative importing is useful when there is code trying to import modules that does not exist recursively inside the current directory. - -For example, the following statements, if written in `file3.k`, can be used to import `pkg2`, `pkg1` and `mod2` respectively. - -```python -import ...pkg2 # Go two levels up then import pkg2 -import ...pkg1 # Go two levels up then import pkg1 -import ...mod2 # Go two levels up then import mod2 -``` - -### Importing from a Root Path - -Suppose we have a `kcl.mod` file in the directory to mark it as a root path, then we have the following files: - -``` - . - |── kcl.mod - ├── mod1.k - ├── mod2.k - ├── pkg1 - │   ├── def1.k - │   ├── def2.k - │   └── def3init.k - └── pkg2 - ├── file2.k - └── subpkg3 - └── file3.k -``` - -In `pkg1` `def1.k`, we can import `pkg2.subpkg3` `file3` using the following syntaxes. - -```python -import pkg2.subpkg3.file3 -``` - -Importing from the root path is very convenient when the code is trying to import modules from a directory needs to look up multiple directories above this directory. At also, it is helpful to organize a large number of files in a root directory. - -### Importing a Module Inside a Package - -Note that `subpkg3` is only implemented with one file `file3.k`. The file can be regarded as a regular module and imported directly. - -In `mod1.k`, the importing statement would be:: - -```python -import pkg2.subpkg3.file3 -``` - -Different from importing `subpkg3`, now the name of the module is `file3`. We can access the variable `foo` defined in this module with the following -statement - -```python -bar = file3.foo -``` - -### Precedence of Importing - -When an import statement specifies a package to import, the virtual machine first looks for a directory named according to the import statement in the file system. - -If such a directory is not found, the virtual machine looks for a single file module. - -For example, when the statement `import a.b.c` appears, the virtual machine first looks for the directory `a/b/c` from the directory of the current file. If `a/b/c` is not found, the virtual machine looks for a file named `a/b/c.k`. If the file is also absent, an error is reported. - -### Package Implemented with Multiple Files - -Package `pkg1` is implemented with multiple KCL files. - -Multiple files can be used to define variables, schemas and functions, and they can access names defined in other files of this package. - -For example, suppose `def1.k` defines a variable `foo`, `def2.k` defines `bar`, and `def3init.k` defines a variable `baz`, when `pkg1` is imported by `mod1.k`, all these variable can be used - -```python -import pkg1 -a = pkg1.foo + pkg1.bar + pkg1.baz -``` - -Inside a module, names defined in a file can be accessed in another file without further importing. For example, suppose `bar` in `def2.k` would invoke `foo` defined in `def1.k`, it can directly use `foo` like the following - -```python -bar = foo + 1 -``` diff --git a/versioned_docs/version-0.5.1/reference/lang/spec/schema.md b/versioned_docs/version-0.5.1/reference/lang/spec/schema.md deleted file mode 100644 index c3d09f65..00000000 --- a/versioned_docs/version-0.5.1/reference/lang/spec/schema.md +++ /dev/null @@ -1,916 +0,0 @@ ---- -title: "Schema" -linkTitle: "Schema" -type: "docs" -weight: 2 -description: Schema ---- - -## Syntax - -### Schema Definition - -A schema is a language element to define a type of configuration data. - -To define a schema, the syntax is the following: - -```bnf -schema_stmt: [decorators] "schema" ["relaxed"] identifier ["[" [arguments] "]"] ["(" operand_name ")"] ":" NEWLINE [schema_body] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt | schema_index_signature | statement)* [check_block] _DEDENT -``` - -Attributes could be defined in a schema, the syntax is the following: - -```bnf -schema_attribute_stmt: [decorators] identifier ["?"] ":" type [(ASSIGN | augassign) test] NEWLINE -``` - -Index signature could be defined in a schema, the syntax is the following: - -```bnf -schema_index_signature: LEFT_BRACKETS [NAME COLON] [ELLIPSIS] basic_type RIGHT_BRACKETS COLON type [ASSIGN test] NEWLINE -``` - -Once defined, an attribute must have a valid type: - -```bnf -type: type_element ("|" type_element)* -type_element: schema_type | basic_type | list_type | dict_type -schema_type: operand_name -basic_type: "str" | "int" | "float" | "bool" -list_type: "[" (type)? "]" -dict_type: "{" (type)? COLON (type)? "}" -``` - -The followings are some basic examples: - -```python -# A person has a first name, a last name and an age. -schema person: - firstName: str - lastName: str - # fullName is generated by firstName and lastName - fullName: str = firstName + ' ' + lastName - # The default value of age is 0 - age: int = 0 - -# An employee IS a person, and has some additional information. -schema employee(person): - bankCard: int - nationality: str - -# A company has a name and many employees. -schema company: - name: str - employees: [employee] -``` - -More complex schema definitions will be elaborated after other concepts are -introduced. - -#### Optional Attribute - -Each attribute **must** be assigned with a not-None value as a schema instance unless it is modified by a question mark as an optional attribute. - -Examples: - -```bnf -schema employee(person): - bankCard?: int # bankCard is an optional attribute - nationality?: str # # nationality is an optional attribute -``` - -When there is an inheritance relationship: - -- If the attribute is optional in the base schema, it could be optional or required in the sub-schema. -- If the attribute is required in the base schema, it must be required in the sub-schema. - -### Configuration Definition - -A configuration is structured data stored in a dict-like structure. In KCL, we have introduced -the configuration definition syntax as a variant of dict definition syntax. - -```bnf -schema_expr: operand_name ("(" [arguments] ")")? dict_expr -``` - -As can be seen, apart from having an identifier as schema type, a configuration definition -is just an ordinary dict definition, and each key in the dict matches an attribute in the schema. - -To simplify configuration, schema attribute key is much easier to define as: - -- schema attribute key can be unquoted. When the attribute key has the same name as a variable, it must be quoted as a normal dict to avoid naming conflict. -- schema attribute key can be defined nested through `select expression`, such as `a.b.c`. - -The comma at the end of each line can be omitted. - -For example, we can define a `person` named `John Doe` using the following statement: - -```python -johnDoe = person { - # In the result, 'lastName' appears later than 'firstName', according the schema - lastName = 'Doe' - firstName = 'John' - # If we don't specify the 'age', the default value 0 is used. - # 'age': 20 -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' - 'age': 0 -} -``` - -Compared to the ordinary dict definition, a configuration definition has the following features: - -- Each attribute defined in the schema (or one of the schemas) could be configured, and config data has higher priority than the default value. -- When an attribute defined in the schema (or one of the schemas) is not configured in the configuration definition statement, and it has a default value, the default value is used. -- Unless the schema (or one of the schemas) is a **relaxed schema**, no more attributes can be defined. -- The quotation marks of dict key can be omitted. -- The comma at the end of each line can be omitted. -- Cases of **inheritance** will be discussed separately. - -For attributes of list, dict and schema types, the config data is added by **union** instead of reassignment. For instance: - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name = { - firstNam = "John" - lastName = "default" - } - -JohnDoe = Person { - name.lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' -} -``` - -#### Attribute Identify - -Each key identifier in the configuration expr identifies an element or a range of elements in a schema. The key identifier may consist of multiple attribute identifiers, and each attribute may be a basic type value, a list, a dict or schema. For example, the key identifier 'a.b.c' identifies the element 'c' in the 'A' schema: - -```python - -schema C: - c: int - -schema B: - b: C - -schema A: - a: B - -A { - a.b.c: 5 -} -``` - -To make the key identifier usage rules as clear as possible, we define the way of identifying with complex data types as follows. - -##### List - -Suppose we have a list attribute a. - -Identify an element in a: - -```python -a[0] # the first element -a[3] # the 4th element -a[-1] # the last element -a[-2] # the penultimate element -``` - -Identify a range of elements in the list: - -```python -a[2:5] # a slice of the third, 4th, and 5th elements -a[:5] # a slice of the first to 5th elements -``` - -#### Attribute Operator - -Once we identified the element(s), we can declare operation on it. It follows the pattern of `identifier op E`. - -#### Union - -Pattern: `identifier : E` - -The value of the expression `E` will be unioned into the element value. - -Examples: - -```python -a = A { - # union {d:4} into the element b.c, suppose c is a schema with an int type attribute d. - b.c : { - d : 4 - } -} -``` - -See 'union' in `expressions` spec for more details. - -#### Override - -Pattern: `identifier = E` - -The value of the expression `E` will override the element value. - -Examples: - -```python -a = A { - # override {c:4} to the element b, suppose b is a schema with an int type attribute c. - b = { - c: 4 - } -} -``` - -Unlike union, the override operation will reassign the element with a brand new value. -For basic type value, `union` and `override` have equivalent effects. - -Note: - -- Especially, we can "delete" its content by overriding the element to `Undefined`, such as `{ a = Undefined }`. - -#### Insert - -Pattern: `identifier += E` -Insert only works for list type `identifier`. - -List `E` will be inserted just after the specified index of the list `identifier`, and the following elements after the index will be automatically shifted. - -Examples: - -```python -a = A { - # insert {c:4} to the end position(just after index=1), suppose b is a list of schema with an int type attribute c. - b += { - c: 4 - } -} -``` - -If no index is specified, the last index will be used. - -The type of 'E' must be compatible with the type of list. See `types` for more details. - -#### Index Signature - -Index signatures can be defined in the KCL schema, and it means that the key-value constraints of the index signature can be used to construct a dict with the schema type, or additional checks can be added to the relaxed schema attributes to enhance the KCL type and semantic checks. - -- Use the form `[{attr_alias}: {key_type}]: {value_type}` to define an index signature in the schema, and `{attr_alias}` can be omitted. - -```python -schema Map: - """ - Map is a relaxed schema with a key of str type and a value of str type - """ - [str]: str # `{attr_alias}` can be omitted. - -data = Map { - key1 = "value1" - key2 = "value2" -} -``` - -- Mandatory all attributes of the schema key and value types - -```python -schema Person: - name: str - age: int # error, conflicts with the index signature definition `[str]: str` - [str]: str # The values of all attributes of the schema can only be strings -``` - -- Mandatory all attribute key and value types are defined in the schema, which is equivalent to restricting all attribute types except the relaxed attributes. - -```python -schema Person: - name: str - age: int - [...str]: str # Except for the `name` and `age` attributes, the key type of all other attributes of the schema must be `str`, and the value type must also be `str`. -``` - -- Define the index signature attribute alias and use it with the check block. - -```python -schema Data: - [dataName: str]: str - check: - dataName in ["Alice", "Bob", "John"] - -data = Data { - Alice = "10" - Bob = "12" - Jonn = "8" # error Jonn not in ["Alice", "Bob", "John"] -} -``` - -```python -import regex - -schema DataMap: - [attr: str]: str - check: - regex.match(attr, r'^[-._a-zA-Z0-9]+$') - -data = DataMap { - key1 = "value1" - "foo.bar" = "value2" # check error -} -``` - -### Schema Context - -The schema definition space can be regarded as a separate function context. - -Init statement could be defined inside the schema, the syntax is the following: - -```bnf -statement: small_stmt NEWLINE | if_stmt -``` - -The following is an example: - -```python -schema Person: - firstName: str = "John" - lastName: str - # fullName is generated by firstName and lastName in a separate init statement - fullName: str = firstName + ' ' + lastName - -JohnDoe = Person { - lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' -} -``` - -If statement, expr statement and assert statement are supported as a schema init -statement. See more in statement spec. - -- The attributes must be defined first, including inherited ones, and then used in the init statement. -- Statements in the schema context will be executed sequentially. -- The value of attributes referenced in the init statement will be evaluated at runtime. - See the **Configuration Definition** section for the assignment rules of non-referenced attributes. For example, `"fullName"` in Person is generated by `"firstName"` and `"lastName"` evaluated at runtime, in which firstName is 'John', and lastName is "Doe". - -The immutability of attributes in the schema context follows the same rules as the immutability of global variables: - -```python -schema Person: - age: int = 1 # Immutable attribute - _name: str = "Alice" # Mutable attribute - - age = 10 # Error - _name = "Bob" # Ok -``` - -#### Arguments - -Schema context can also have arguments. The following is an example. - -```python -schema Person[separator]: - firstName: str = "John" - lastName: str - fullName: str = firstName + separator + lastName - -JohnDoe = Person('_') { - lastName = "Doe" -} -``` - -The example is similar to the previous one, except that the separator character used in -the `"fullName"` member is passed in as an argument. The way to perform a schema generation -when the schema has an initialization function with arguments is demonstrated in the code. - -### Check Block - -Optionally, a check block can be added to a schema definition to allow -additional checking to be performed. - -The syntax is the following: - -```bnf -check_block: "check" ":" NEWLINE _INDENT check_expr+ _DEDENT -check_expr: test (IF test)? [":" primary_expr] NEWLINE -``` - -In terms of grammatical definition, a check block consists of a list of conditional expressions. The following is an example: - -```python -schema employee(person): - bankCard: int - gender: str - - check: - len(str(bankCard)) == 16 - gender in ['male', 'female'], "The gender {} is unsupported".format(gender) -``` - -The ability of KCL check expressions covers the abilities that can be defined by OpenAPI spec and is aligned with the ability of logical expressions. We consider further aligning the syntax with `CEL` spec. -Whether to support `lambda expressions` is still under discussion. - -Summary: - -- A check block consists of one or more logical **expressions**. -- When defining a configuration, the expressions in the check block are evaluated - in any order. If any of the expression is `False`, an error is reported. -- A custom error message can be provided after an expression. - -### Specifying Types - -Optionally, the type of any member of a schema can be specified. As previous examples have shown. - -A member can be of a basic type, such as a string (`str`), a floating-point number (`float`), a fixed-point number (`int`) or a boolean number (`bool`). - -A member can also be of a dictionary generated from another schema. In such a case, the name of the other schema is used as the type name. - -A member can also be a list or an ordinary dict: - -- A list with unspecified type of elements is `[]`. -- A list with elements of type `t` is `[t]`. Here `t` is another type. -- A dict with keys of type `kt` and values of type `vt` is `{kt:vt}`. -- `kt`, `vt` or both of them can be missing, like a list with unspecified type of elements. - -The followings are some more examples: - -- A list of lists of strings: `[[str]]`. -- A dict of keys with the type string and unspecified value types: `{str:}`. - -A member can be a **union type** defined by `|`, such as `a | b`, which means the type of the member could be a or b. - -A union type can include types of `int`, `str`, `float`, `bool`, `list` and `dict` and support type nesting e.g. `{str:str|int}` and `[[int|str]|str|float]`, etc. - -Examples: - -```python -schema x: - p: int | str # p could be defined as a int or string -``` - -### Immutability - -KCL pursues strict immutability of schema attributes. It's generally followed the rules: - -- For the attributes of the basic type, such as string, int and float, it's allowed to be reassigned - through the init statement in **schema context** or by the **configuration definition**. -- For the attributes of list, dict and schema type, it's allowed to be reassigned only by the init statement in **schema context**. The content of it is allowed to be operated in **schema context** or by the **configuration definition**. -- Any other attempt to reassign or modify schema attribute will report an error. - -#### Assign by Value - -When using a schema variable to assign the value to another variable, we can only get a deep copy of its value, not a pointer or reference. That is, modifying the assigned value will not change the assigned schema variable. - -```python -schema Person: - name: str - -person = { - name = "Alice" -} -personCopy = person # 'personCopy' is a deep copy of 'person' and modifying 'personCopy' will not affect 'person' -``` - -### Union Operator - -For list, dict and schema, we can union delta to existing data. For example: - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name = { - firstName = "John" - } - - # union a schema and a dict - name: Name { - lastName = "Doe" - } - -person = Person {} -``` - -The result is a **dict**: - -```python -{ - 'person': { - 'name': { - 'firstName': 'Jhon', - 'lastName': 'Doe' - } - } -} -``` - -### Other Operators - -Except for `assignment` and `union assignment`, it's not support other operators on schema type data. -Report an error if trying to use other operators on schema type data. - -### Deprecated - -The schema attribute can be marked as deprecated once it's considered invalid. - -```python -schema Person: - @deprecated(version="1.1.0", reason="use fullName instead", strict=True) - name: str - ... # Omitted contents - -person = Person { - # report an error on configing a deprecated attribute - name = "name" -} -``` - -- Deprecated attributes cannot be configured under any circumstances. Report an error or warning once the attribute is assigned. -- Define the expired version of the attribute through **version**, and define the reason for the attribute expired through **reason**. -- When strict is true, the attribute assignment will cause an error, otherwise it will report a warning and ignore the attribute assignment. - -### Composition - -The composition is a common way to define complex structures. KCL provides simplified means for the configuration definition of combined structures. - -Assuming we have the following schemas, which is defined by a combination of multiple schemas. - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name - age: int - -schema Group: - name: str - persons: [Person] -``` - -To config a group: - -```python -group = Group { - name = "group" - persons = [{ - name = { - firstName = "John" - lastName = "Doe" - } - age = 24 - }] -} -``` - -- Top-level schema name is required to config a schema. -- The schema of the attributes in the schema can be omitted. - -Multi-level nested schemas will make the configuration verbose. KCL supports defining attributes in the schema through `selector expression`. The selector form is **x.y.z**, see the following example: - -```python -group = Group { - name = "group" - persons = [{ - name.firstName = "John" - name.lastName = "Doe" - age = 24 - }] -} -``` - -- Selector can be used to represent attribute in a schema - -### Inheritance - -Inheritance is an effective means to define a hierarchical structure definition, and KCL supports limited **single inheritance** of the schema. - -```python -schema Person: - firstName: str - lastName: str - -# schema Scholar inherits schema Person -schema Scholar(Person): - fullName: str = firstName + '_' + lastName - subject: str - -JohnDoe = Scholar { - firstName = "John", - lastName = "Doe", - subject = "CS" -} -``` - -The result is a **dict**: - -```python -{ - 'JohnDoe': { - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' - 'subject': 'CS' - } -} -``` - -Each schema can be treated as a separated function context. Statements, including attribute statements and init statements, in the context of schemas will be evaluated from base schema to subschema according to the inheritance order. Each schema context is evaluated only once sequentially. The same goes for expressions in the check block. In the example, firstName and lastName are configured in the context of Person schema, and fullName is formed by splicing firstName and lastName in the context of Scholar schema. - -The default value can be modified in each schema. Value defined in **Configuration Definition** has a higher priority than the default value. Attributes with default values in any schema context ​​will eventually be unioned by configuration data. References to attributes in the schema context statements will use the value with unioned configuration data on evaluating at runtime. For example: - -```python -schema a: - x = 1 - y = x * 2 - -schema b(a): - x = 2 - -v = a { - x = 3 -} - -``` - -The result is a **dict**: - -```python -{ - 'v': { - 'x': 3 - 'y': 6 - } -} -``` - -Notes: - -- Report an error if inheriting more than one base schema. -- The type of the base schema attribute cannot be modified in the subschema. -- Report an error if inheriting a **mixin**. -- Report an error when a circular dependency occurs. - -Limitations: - -Since inheritance will derive some complex demands, we are cautious about these complex demands. There are still some restrictions on inheritance, and it's still under discussion. - -- KCL provides limited and deterministic polymorphism support, more complex and flexible polymorphism support, such as **self**, **super** keywords, are temporarily not included in the schema definition. -- Currently, KCL only supports the polymorphism of the inherited attributes of the schema, and does not support the polymorphism of the expressions in the check block. -- For the case of multiple levels of schema inheritance, the schema arguments can only be passed to the last level of sub-schema. - -### Mixin - -In addition to **composition** and **inheritance**, KCL supports declarative reuse of schema code through the **mixin** mechanism. To use a mixin, we only need to declare the **mixin** in the schema definition. - -The **mixin** syntax is the following: - -```bnf -//////////// mixin_stmt //////////// -mixin_stmt: "mixin" "[" [mixins | multiline_mixins] "]" "\n" -multiline_mixins: "\n" _INDENT mixins "\n" _DEDENT -mixins: operand_name ("," ("\n" mixins | operand_name))* -``` - -Here is a simple example: - -```python -schema Person: - mixin [FullNameMixin] - firstName: str = "default" - lastName: str - -schema FullNameMixin: - fullName: str = "{} {}".format(firstName, lastName) - -JohnDoe = Person { - firstName = "John" - lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'JohnDoe': { - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' - } -} -``` - -Multiple mixins can be added to a single schema, and mixins context will be evaluated after the host schema context at runtime. In the inheritance scenario, the mixin context can be regarded as a part of the host schema context, and the overall evaluation of schema context order is not affected. - -Notes: - -- The name of **mixin** schema must end with 'Mixin', otherwise an error will be reported. -- The attributes referenced in the **mixin** must be defined in the **mixin** itself or host schema, otherwise an error will be reported. - -### Protocol - -In addition to schema, an additional type definition method `protocol` is provided in KCL, and its properties are as follows: - -- In a protocol, only attributes and their types can be defined, complex logic and check expressions cannot be written, and mixins cannot be used. -- A protocol can only inherit or refer to other protocols, but cannot inherit or refer to other schemas. - -We can use **protocol** to add an optional host type to the dynamically inserted **mixin**. - -The **mixin** can define its host type through the `for` keyword, and internally it will query the type corresponding to the attribute from the host type. - -```python -protocol DataProtocol: # A mixin host type - data: str - -mixin DataMixin for DataProtocol: # Using the `for` keyword to define a mixin host type - x: int = data # The type of `data` is `str`, which is from `data` of `DataProtocol` -``` - -In `DataMixin`, the `data` attribute is obtained according to the `DataProtocol` host type as `str` type, and then a type error will occur when the value is assigned to `x` of type `int`: - -```python -protocol DataProtocol: - data: str - -mixin DataMixin for DataProtocol: - x: int = data # Error: expect int, got str - x: str = data # Error: can't change schema field type of 'x' from int to str -``` - -Please note that the host type **protocol** can only be used for **mixin** definitions (the suffix name is `Mixin`), otherwise an error will be reported. - -```python -protocol DataProtocol: - data: str - -schema Data for DataProtocol: # Error: only schema mixin can inherit from protocol - x: str = data -``` - -### Schema Context Evaluation - -The schema definition is composed of attribute statements, configuration data, init statements, mixins, and checks. In a separate schema context, the evaluation top-down order is as follows: - -``` -|------------------------------------------| -| attribute defaulting | -|------------------------------------------| -| configuration union | -|------------------------------------------| -| attribute templating | -|------------------------------------------| -| statements in declaration order | -|------------------------------------------| -| mixins in declaration order | -|------------------------------------------| -| check expressions in any order | -|------------------------------------------| -``` - -In the case of schema inheritance, each schema context is evaluated from the base schema in the order of inheritance, and each context is evaluated only once. -Suppose there are schemas a, b, and c, where c inherits b and b inherits a. Schema contexts will be evaluated in top-down order as: - -``` -|-----------------| -| schema a | -|-----------------| -| schema b | -|-----------------| -| schema c | -|-----------------| -``` - -### Members - -Built-in function and members of schema - -- instances() - Return the list of existing instances of a schema. - -### Irrelevant Order Calculation - -The irrelevant order calculation in the schema indicates the reference relationship between the internal attributes of the schema. For example, when we declare an expression of the form `a = b + 1`, the calculation of the value of `a` depends on the calculation of the value of `b`. When the compiler calculate the value of `a` and the value of `a` depends on the value of `b`, the compiler will choose to first calculate the value of `b`, and then calculate the value of a according to the expression `a = b + 1`, which is slightly different from the calculation method of traditional procedural language the difference. - -Since the calculation of values in the schema is based on dependencies, just like a directed acyclic graph traverses each node in the graph according to the order of topological sorting, the order of declaration of attributes in the schema is not so important, so the feature is called the irrelevant order calculation. - -Please note that there can be no circular references between different schema attribute values. - -We can see this feature through the following examples. - -```python -schema Person: - name?: str - age: int = _age - - _age = 10 - - if name == "Son": - _age = 18 - -schema Son(Person): - name: str = "Son" - -person = Person {} -son = Son {} -``` - -The output is - -```yaml -person: - name: null - age: 10 -son: - name: Son - age: 18 -``` - -Besides, we can achieve KCL polymorphism such as - -```python -schema Person: - name?: str - _age: int = _age - - _age = 10 - if name == "Son": - _age = 18 - elif name == "SonConf": - _age = 24 - -schema Son(Person): - name: str = "Son" - -person = Person() {} -son = Son() { - name = "SonConf" -} -``` - -The output is - -```yaml -person: - name: null - age: 10 -son: - name: SonConf - age: 24 -``` - -More examples: - -```python -schema Fib: - n1: int = n - 1 - n2: int = n1 - 1 - n: int - value: int = _value - - if n <= 2: - _value = 1 - else: - _value = (Fib {n = n1}).value + (Fib {n = n2}).value - -fib8 = (Fib {n = 8}).value -``` - -The output is - -```yaml -fib8: 21 -``` - -As in the above examples, we can see that in the schema, we only need to simply specify the dependency between attributes, and the compiler will automatically calculate the value based on the dependency, which can help us save a lot of boilerplate code and reduce configuration difficulty of writing. diff --git a/versioned_docs/version-0.5.1/reference/lang/spec/statements.md b/versioned_docs/version-0.5.1/reference/lang/spec/statements.md deleted file mode 100644 index b09488b9..00000000 --- a/versioned_docs/version-0.5.1/reference/lang/spec/statements.md +++ /dev/null @@ -1,185 +0,0 @@ ---- -title: "Statements" -linkTitle: "Statements" -type: "docs" -weight: 2 -description: Statements ---- - -## Syntax - -In KCL, statements consist of small statements and compound statements. The syntax is the following: - -```bnf -preamble_statement: preamble_small_stmt | preamble_compound_stmt -preamble_small_stmt: (small_stmt | import_stmt) NEWLINE -preamble_compound_stmt: compound_stmt | schema_stmt -statement: small_stmt NEWLINE | compound_stmt -compound_stmt: if_stmt -small_stmt: assign_stmt | expr_stmt | assert_stmt -``` - -The preamble statement is used to define the module level statements, consist of `statement`, `import_stmt`, and `schema_stmt`. The statement is used to define the block level statements, which are used in the `if` statement and `schema` statement. - -### Small Statements - -A small statement is comprised of a single logical line. Multiple statements in one-line are not allowed. - -#### Assignment Statements - -Generally, assign_stmt is divided into assignment and augmented assignment. The syntax is the following: - -```bnf -assign_stmt: target_primary ("=" target_primary)* "=" test | target_primary augassign test -augassign: "+=" | "-=" | "*=" | "**=" | "/=" | "//=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>=" | "or" | "and" -target_primary: identifier | target_primary DOT identifier -``` - -An assignment statement has the form `lhs = rhs`. It evaluates the expression on the right-hand side then assigns its value (or values) to the variable (or variables) on the left-hand side. - -The **target_primary** on the left-hand side is an `identifier` or an `identifier` followed by select dots. - -Note: When using **target_primary** will cause collisions, use **primary_expr** as an alternative. - -Examples: - -```python -k = 1 -a.b = "a.b" -``` - -To keep it simple, the compound target is not supported as **target_primary**. - -The right value of an assignment statement is a conditional expression, which is discussed separately. - -An augmented assignment, which has the form `lhs op= rhs` updates the variable `lhs` by applying a binary arithmetic operator op (one of +, -, \*, /, //, %, &, |, ^, <<, >>) to the previous value of `lhs` and the value of `rhs`. - -The **target_primary** on the left-hand side is the same as assignment statement. Examples: - -```python -_x -= 1 -_filename += ".k" -``` - -There is no concept of in-place modification in KCL. The `augassign` statement will modify a copy of the **target_primary** and assign the copy to **target_primary**. - -In particular, in KCL, the `|=` symbol represents the **union** operation, which is defined as follows: - -- The behavior of the **union** operation needs to be consistent with the behavior of the **configuration definition**. - -See **expressions** spec for more details of union operator in **Arithmetic Operations**. - -#### Expression Statements - -An expression statement evaluates an expression and discards its result. - -Syntax: - -```bnf -expr_stmt: expression -``` - -An expression statement supported in KCL is function invocation expression, which is discussed in **expression** spec. - -```python -print(k) # print a variable -``` - -#### Import Statements - -Import statements are used to **search** and **load** a module, and define a name or names in the local namespace for the scope where the import statement occurs. - -Syntax: - -```bnf -import_stmt: "import" dot_name ("as" NAME)? -dot_name: [leading_dots] identifier (DOT identifier)* -leading_dots: "."+ -``` - -Examples: - -```python -import math # import a built-in module math -import pkg # import pkg -import pkg.foo # import pkg.foo -import pkg.subpkg # import a subpkg in a pkg -import .pkg2.subpkg3 # import a subpkg in a pkg inside of current pkg -import ...pkg2 # Go two levels up then import pkg2 -``` - -See **module** spec for more details of module spec. - -#### Assert Statements - -Assert statements are a convenient way to insert debugging assertions into KCL code. - -The syntax is the following: - -``` -assert_stmt: ASSERT test ("," test)? -``` - -The conditional expression in assert will be evaluated and get a boolean. Report an error if returning a `False`. - -Examples: - -```python -assert: x > 1 # report an error on x <= 1 -``` - -#### Conditional Statements - -KCL allows using conditional statements to control the instructions to -be executed. They are also called the control-flow statements. - -The only type of control-flow syntax is the well-known `if-elif-else` syntax. - -The syntax of the `if-elif-else` statement is the following. - -```bnf -if_stmt: "if" test ":" suite ("elif" test ":" suite)* (ELSE ":" suite)? -suite: small_stmt | NEWLINE _INDENT statement+ _DEDENT -``` - -An `if` or `elif` statement evaluates a given expression. When the expression -is evaluated to `True`, a list of statements following `:` are executed. - -The following is an example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - print("maybe a is negative") -else: - print("a >= 100") -``` - -`if-elif-else` statements can be nested. For example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - if a < 0: - print("a is negative") - print("No matter a is negative or positive, this message is printed") -else: - print("a >= 100") -``` - -#### Schema Statements - -Schema statements are used to define a type of configuration data. The syntax is the following: - -```bnf -schema_stmt: [decorators] "schema" ["relaxed"] identifier ["[" [arguments] "]"] ["(" operand_name ")"] ":" NEWLINE [schema_body] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt | statement)* [check_block] _DEDENT -``` - -See **schema** spec for more details of schema spec. diff --git a/versioned_docs/version-0.5.1/reference/lang/spec/variables.md b/versioned_docs/version-0.5.1/reference/lang/spec/variables.md deleted file mode 100644 index b3e1c539..00000000 --- a/versioned_docs/version-0.5.1/reference/lang/spec/variables.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: "Variables" -linkTitle: "Variable" -type: "docs" -weight: 2 -description: Variable ---- - -In KCL, variables can be defined using assign statements. For example, the following statement defines a variable `spam` to a string `"ham"`. - -```python -spam = "ham" -``` - -There are two types of variables, which are global variables and list comprehension local variables. - -- A global variable is defined not within any context. -- A comprehension local variable is defined inside a comprehension. - -A variable can be used after definition, until the end of the current scope. - -For a global variable, the scope is the module it is defined in. Note that a module can consists of multiple source files. - -For a list comprehension local variable, the scope is the list comprehension it is defined in. - -More information on modules, list comprehensions and scopes will be discussed in later chapters. - -## Immutability - -Global variables are immutable. In other words, once defined such a variable cannot be redefined (or, i.e., modified). - -The following code is illegal, and KCL will report an error during evaluation. - -```python -spam = "ham" -spam = "eggs" # Error: The immutability rule is violated! -``` - -- A variable starts with the `_` character is mutable. - -```python -_spam -cond = True -if cond: - _spam = "ham" -else: - _spam = "eggs" -``` - -## Variable Exporting - -As shown in the preview chapter, KCL is able to export evaluation results to the standard output according to a target data format. - -The rules are the followings: - -- Living global variables at the end of an evaluation will be dumped out. -- If the name of a variable starts with the `_` character, it will not be dumped out. - -## Uniqueness of Exported Variable Identifier - -Each exported variable identifier must be unique in its package, so that an exported variable could be located uniquely by package location path and variable identifier, such as 'a.b.c:var', in which 'a.b.c' locates a package. - -Two variable identifiers are different if: - -- they are spelled differently -- they are defined in different packages and are not compiled in a single execution - -Identifying an exported variable should be supported by the kcl compiler, which needs to provide corresponding identifying features through the command line and api form. diff --git a/versioned_docs/version-0.5.1/reference/lang/tour.md b/versioned_docs/version-0.5.1/reference/lang/tour.md deleted file mode 100644 index f7acf49c..00000000 --- a/versioned_docs/version-0.5.1/reference/lang/tour.md +++ /dev/null @@ -1,3324 +0,0 @@ ---- -title: "KCL Tour" -sidebar_position: 1 ---- - -This page shows how to use major KCL features, from variables and operators to schemas and libraries, with the assumption that you have already known how to program in another language. KCL is mainly inspired by Python, and knowing Python is very helpful for learning KCL. - -### Important Concepts - -As we learn about the KCL language, keep these facts and concepts in mind: - -- KCL is a configuration and policy language. It provides simplified and self-contained language design and library support for writing configurations and policies. It cannot be used for application development or other purposes supported by General Purpose Language (GPL). -- KCL absorbs classic **OOP** elements and provides simple, developer-friendly and reliable configuration writing practice with **type**, **reusing**, and **union**. -- KCL prefers **immutability** and recommend to add up incremental updates through the **union**. Immutability reduces side effects like unpredictable issues. -- KCL **schema** struct defines strict attributes, static types, and it also supports validation expressions. The **schema** struct is mainly composed of typed attributes, the schema context and the check block. -- KCL **config** is a **json**-like expression, by which we can reuse a full definition of the schema. KCL provides support for definition and configuration by separating schema and config. -- KCL **rule** is a structure for writing rule constraint expressions, which can be used for data verification and policy writing. -- KCL code files are managed as packages(directories) and modules(files). The schema types in the same package are visible to each other; the data cross packages need to be imported through the **import statement**. The package-level variables can be exported, but they are immutable for other packages. -- The KCL syntax definition mainly uses declarative expressions, and only provides a small number of necessary and imperative statements, such as import, if .. else, assert, assignment and schema. -- No main function, each `.k` file could be executed as a separate configuration. -- **Built-in functions** and **plugins** are supported to simplify coding. - -### Keywords - -The following table lists the words that the KCL language treats specially. - -```txt -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -### Identifiers - -In KCL, an identifier is a name, may with selectors, that identifies a value. - -- Identifiers consist of letters, numbers, underscores or the prefix `$`. -- Identifiers cannot be repeated with keywords unless they have a `$` prefix. -- Identifiers must not contain any embedded spaces or symbols. -- Letters and underscores can be used anywhere in the identifier. -- Numbers cannot be placed in the first place of the identifier. -- The `$` character can only be placed in the first position of the identifier. - -Examples: - -```python -x -a -b1 -b_2 -_c -$if -``` - -To simplify the definition of the qualified identifier, such as `pkg.type`, we additionally define `qualified identifier`: - -Examples: - -```python -pkg.a -``` - -The package name in `qualified identifier` must be imported. - -#### Identifier Prefix - -Use the `$` character prefix to define keyword identifiers. - -```python -$if = 1 -$else = "s" -``` - -Please note: whether the non-keyword identifier is prefixed with `$` has the same effect. - -```python -_a = 1 -$_a = 2 # equal to `_a = 2` -``` - -### Variables - -Here’s an example of how to create a variable and initialize it: - -```python -name = "Foo" # Declare a variable named `name` and its value is a string literal "Foo" -``` - -It corresponds to the following YAML output: - -```yaml -name: Foo -``` - -In KCL, we can export variables as config data by defining package-level variables. To make it direct, clear, and maintainable. Exported variables are immutable so that once we declare it, we can't modify it. For example, assume we have a config file named `example.k`, the variable `name` can't be modified after the declaration, just like the standard imperative language. - -```python -name = "Foo" # exported - -... - -name = "Bar" # error: a exported declaration variable can only be set once. -``` - -As a complement, we can define a non-exported variable in module level which is mutable, which won't show up in YAML output: - -```python -_name = "Foo" # _ variables are not output to YAML and are mutable -_name = "Bar" -``` - -Please note that the variable name cannot be one of `True`, `False`, `None`, `Undefined` because of ambiguity. - -```python -False = 1 # Error -True = False # Error -None = Undefined # Error -Undefined = None # Error -``` - -### Built-in Types - -The KCL language has special support for the following types: - -- number -- string -- boolean -- list -- dict - -#### Number - -KCL number comes into two flavors: - -- **Int**: 64 bits signed integer values. Values can be from -9223372036854775808~9223372036854775807. -- **Float**: 64-bit floating-point numbers, as specified by the IEEE 754 standard. We do not recommend using the float type in the configuration, we can use a string instead and parse it during runtime processing. - -Both int and float support basic operators such as `+`, `-`, `/`, and `*`, while complex operations, such as `abs()`, `ceil()`, and `floor()`, are supported through the built-in math library. - -Integers are numbers without a decimal point. Here are some examples of defining integer literals: - -```python -a = 1 -b = -1 -c = 0x10 # hexadecimal literal -d = 0o10 # octal literal -e = 010 # octal literal -f = 0b10 # binary literal -g = int("10") # int constructor -``` - -If a number includes a decimal point, it is a float number. Here are some examples of defining float literals: - -```python -a = 1.10 -b = 1.0 -c = -35.59 -d = 32.3e+18 -f = -90. -h = 70.2E-12 -i = float("112") # float constructor -``` - -Built-in math libraries can be used with numbers: - -```python -import math - -assert abs(-40) == 40 -assert round(70.23456) == 70 -assert min(80, 100, 1000) == 80 -assert max(80, 100, 1000) == 1000 -assert sum([0,1,2]) == 3 -assert math.ceil(100.12) == 101.0 -assert math.floor(100.12) == 100.0 -assert math.pow(100, 2) == 10000.0 -``` - -In addition, please note that the KCL number is 64-bit by default. We can perform a stricter 32-bit range check by adding the `-r` parameter to the KCL command-line tool. - -```bash -kcl main.k -r -d -``` - -Please note that the value range check is only enabled in `debug` mode - -##### Units - -In KCL, we can add a unit suffix to an integer denomination to indicate that it does not affect its true value as follows. - -- General integer or fixed-point number form: `P`, `T`, `G`, `M`, `K`, `k`, `m`, `u`, `n` -- Corresponding power of 2: `Pi`, `Ti`, `Gi`, `Mi`, `Ki` - -```python -# SI -n = 1n # 1e-09 -u = 1u # 1e-06 -m = 1m # 1e-03 -k = 1k # 1000 -K = 1K # 1000 -M = 1M # 1000000 -G = 1G # 1000000000 -T = 1T # 100000000000 -P = 1P # 1000000000000000 -# IEC -Ki = 1Ki # 1024 -Mi = 1Mi # 1024 ** 2 -Gi = 1Gi # 1024 ** 3 -Ti = 1Ti # 1024 ** 4 -Pi = 1Pi # 1024 ** 5 -``` - -Besides, And we can also use the unit constants defined in the `units` module as follows: - -```python -import units - -n = 1 * units.n # 1e-09 -u = 1 * units.u # 1e-06 -m = 1 * units.m # 1e-03 -k = 1 * units.k # 1000 -K = 1 * units.K # 1000 -M = 1 * units.M # 1000000 -G = 1 * units.G # 1000000000 -T = 1 * units.T # 1000000000000 -P = 1 * units.P # 1000000000000000 -# IEC -Ki = 1 * units.Ki # 1024 -Mi = 1 * units.Mi # 1024 ** 2 -Gi = 1 * units.Gi # 1024 ** 3 -Ti = 1 * units.Ti # 1024 ** 4 -Pi = 1 * units.Pi # 1024 ** 5 -``` - -We can also use the methods in the `units` module to convert between integers and unit strings. - -```python -import units -# SI -K = units.to_K(1000) # "1K" -M = units.to_M(1000000) # "1M" -G = units.to_G(1000000000) # "1G" -T = units.to_T(1000000000000) # "1T" -P = units.to_P(1000000000000000) # "1P" -# IEC -Ki = units.to_Ki(1024) # "1Ki" -Mi = units.to_Mi(1024 ** 2) # "1Mi" -Gi = units.to_Gi(1024 ** 3) # "1Gi" -Ti = units.to_Ti(1024 ** 4) # "1Ti" -Pi = units.to_Pi(1024 ** 5) # "1Pi" -``` - -```python -import units -# SI -K = units.to_K(int("1M")) # "1000K" -M = units.to_M(int("1G")) # "1000M" -G = units.to_G(int("1T")) # "1000G" -T = units.to_T(int("1P")) # "1000T" -P = units.to_P(int("10P")) # "10P" -# IEC -Ki = units.to_Ki(int("1Mi")) # "1024Ki" -Mi = units.to_Mi(int("1Gi")) # "1024Mi" -Gi = units.to_Gi(int("1Ti")) # "1024Gi" -Ti = units.to_Ti(int("1Pi")) # "1024Ti" -Pi = units.to_Pi(int("10Pi")) # "10Pi" -``` - -The unit value type is defined in the units module, and the unit value type does not allow any four calculations. - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -x0: NumberMultiplier = 1M # Ok -x1: NumberMultiplier = x0 # Ok -x2 = x0 + x1 # Error: unsupported operand type(s) for +: 'number_multiplier(1M)' and 'number_multiplier(1M)' -``` - -We can use the `int()`, `float()` function and `str()` function to convert the numeric unit type to the normal integer type and string type. - -```python -a: int = int(1Ki) # 1024 -b: float = float(1Ki) # 1024.0 -c: str = str(1Mi) # "1Mi" -``` - -#### String - -The string is an immutable sequence of Unicode characters. We can use either single or double quotes to create a string: - -```python -'allows embedded "double" quotes' # Single quotes -"allows embedded 'single' quotes" # Double quotes -'''Three single quotes''', """Three double quotes""" # Triple quoted -``` - -Triple quoted strings may span multiple lines. - -```python -"""This is a long triple quoted string -may span multiple lines. -""" -``` - -Please note that there is almost no difference in the use of KCL single-quoted and double-quoted strings. The only thing that can be simplified is that we don’t need to escape double quotes in single quoted strings, and we don’t need to escape single quotes in double quoted strings. - -```python -'This is my book named "foo"' # Don’t need to escape double quotes in single quoted strings. -"This is my book named 'foo'" # Don’t need to escape single quotes in double quoted strings. -``` - -We can concatenate strings using the `+` operator: - -```python -x = 'The + operator ' + 'works, as well.' -``` - -We can cast an int or float to a string using the built-in function `str`: - -```python -x = str(3.5) # "3.5" -``` - -A lot of handy built-in functions and members of a string could be used: - -```python -x = "length" -assert len(x) == 6 # True -assert x.capitalize() == "Length" -assert x.count("gt") == 1 -assert x.endswith("th") == True -assert x.find("gth") == 3 -assert "{} {}".format("hello", "world") == 'hello world' -assert x.index("gth") == 3 -assert x.isalnum() == True -assert x.isalpha() == True -assert "123456".isdigit() == True -assert x.islower() == True -assert " ".isspace() == True -assert "This Is Title Example".istitle() == True -assert x.isupper() == False -assert "|".join(["a", "b", "c"]) == "a|b|c" -assert "LENGTH".lower() == "length" -assert ' spacious '.lstrip() == 'spacious ' -assert x.replace("th", "ht") == "lenght" -assert "lengthlength".rfind("le") == 6 -assert "lengthlength".rindex("le") == 6 -assert "length length".rsplit() == ["length", "length"] -assert "length ".rstrip() == "length" -assert "length length".split() == ["length", "length"] -assert 'ab c\n\nde fg\rkl\r\n'.splitlines() == ['ab c', '', 'de fg', 'kl'] -assert "length".startswith('len') == True -assert "***length***".strip('*') == "length" -assert "length length".title() == "Length Length" -assert x.upper() == "LENGTH" -``` - -There are 2 different ways to format a string: to use the `"{}".format()` built-in function, or to specify the variable between the curly braces and use a `$` mark to tell KCL to extract its value. This is called **string interpolation** in KCL. In following example, both `a` and `b` will be assigned to string `"hello world"`. - -Besides, the variable to serialized can be extracted in special data format, such as YAML or JSON. In this case, a `#yaml` or `#json` can be included within the curly braces. - -Specifically, when the dollar sign `$` itself is needed in a **string interpolation**, it needs to be escaped and use `$$` instead. Or in another way, `+` can be used to concat the dollar sign with the **string interpolation** to avoid that escape. In following example, both `c` and `c2` will be assigned to string `$hello world$` - -```python -world = "world" -a = "hello {}".format(world) # "hello world" -b = "hello ${world}" # "hello world" -c = "$$hello ${world}$$" # "$hello world$" -c2 = "$" + "hello ${world}" + "$" # "$hello world$" - -myDict = { - "key1" = "value1" - "key2" = "value2" -} - -d = "here is myDict in json: ${myDict: #json}" -# d: 'here is myDict in json: {"key1": "value1", "key2": "value2"}' - -e = "here is myDict in yaml:\n${myDict: #yaml}" -# e: | -# here is myDict in yaml: -# key1: value1 -# key2: value2 -``` - -Besides, we can see some symbols in the example code output **YAML string** above such as `|`, `>`, `+`, `-`. - -- `|` denotes the **block literal style** that indicates how newlines inside the block should behave. -- `>` denotes the **block folded style** in the block scalar that the newlines will be replaced by spaces. -- `+` and `-` are the **block chomping indicators** that control what should happen with newlines at the end of the string. The default value **clip** puts a single newline at the end of the string. To remove all newlines, **strip** them by putting a `-` after the style indicators `|` or `>`. Both clip and strip ignore how many newlines are actually at the end of the block; to **keep** them all put a `+` after the style indicator. - -For example, a **strip block literal style** yaml string is - -```yaml -example: |- - Several lines of text, - with some "quotes" of various 'types', - and also a blank line: - - plus another line at the end. -``` - -The result is - -```plain -Several lines of text, -with some "quotes" of various 'types', -and also a blank line: - -plus another line at the end. -``` - -See [Yaml Multiline String](https://yaml-multiline.info/) and [YAML Specification v1.2](https://yaml.org/spec/1.2.1/) for more information. - -##### Raw String - -KCL raw string is created by prefixing a string literal with `'r'` or `'R'`. KCL raw string treats backslash (`\`) and string interpolation (`${}`) as a literal character. This is useful when we want to have a string that contains backslash, string interpolation and don’t want them to be treated as an escape character. - -- For backslash (`\`), the KCL code and output YAML are as follows: - -```python -s = "Hi\nHello" -raw_s = r"Hi\nHello" # This is a KCL raw string with the `r` prefix. -``` - -```yaml -s: |- - Hi - Hello -raw_s: Hi\nHello -``` - -- For string interpolation (`${}`), the KCL code and output YAML are as follows: - -```python -worldString = "world" -s = "Hello ${worldString}" -raw_s = r"Hello ${worldString}" # This is a KCL raw string with the `r` prefix. -``` - -```yaml -worldString: world -s: Hello world -raw_s: Hello ${worldString} -``` - -In addition, the most common scenario for raw strings is to be used with regular expressions: - -```python -import regex - -key = "key" -result = regex.match(key, r"[A-Za-z0-9_.-]*") # True -``` - -#### Boolean - -Boolean values are the two constant objects `False` and `True`. - -```python -a = True -b = False -``` - -#### List - -The list is a sequence, typically used to store collections of homogeneous items. Here’s a simple KCL list: - -```python -list = [1, 2, 3] -assert len(list) == 3 # True -assert list[0] == 1 # True -``` - -We can declare a list with list comprehension: - -```python -list = [ _x for _x in range(20) if _x % 2 == 0] -assert list == [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] # True -``` - -We can perform nested list comprehension: - -```python -matrix = [[1, 2], [3,4], [5,6], [7,8]] -transpose = [[row[_i] for row in matrix] for _i in range(2)] -assert transpose == [[1, 3, 5, 7], [2, 4, 6, 8]] # True -``` - -Besides, we can use two variables in the list comprehension, the first variable denotes the list index and the second variable denotes the list item. - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use `_` to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -We can merge list like this: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -joined_list = _list0 + _list1 # [1, 2, 3, 4, 5, 6] -``` - -We can also use the list unpacking operator `*` to merge multiple lists: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -union_list = [*_list0, *_list1] # [1, 2, 3, 4, 5, 6] -``` - -We can use `if expressions` to dynamically add elements to the list element, elements that meet the conditions are added to the list, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = [ - 1 - if a == 1: 2 - if a > 0: 3 - if a < 0: 4 -] # [1, 2, 3] -``` - -```python -a = 1 # 1 -data1 = [ - 1 - if a == 1: - 2 - elif a == 2: - 3 - else: - 3 -] # [1, 2] -data2 = [ - 1 - if a == 1: 2 - elif a == 2: 2 - else: 3 -] # [1, 2] -``` - -Please note that in the above `if expressions`, nested use is not supported. - -We can union two lists like this: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -union_list = _list0 | _list1 # [4, 5, 6] -``` - -We can use the expression `for k in list_var` to traverse a list. - -```python -data = [1, 2, 3] -dataAnother = [val * 2 for val in data] # [2, 4, 6] -``` - -#### Dict - -Dict is a mapping object that maps hashable values to arbitrary objects. Dict is ordered. The order of the keys follows the order of their declaration. - -Here are a couple of simple KCL dict, created using dict literals: - -```python -a = {"one" = 1, "two" = 2, "three" = 3} -b = {'one' = 1, 'two' = 2, 'three' = 3} -assert a == b # True -assert len(a) == 3 # True -``` - -We can ignore the comma `,` at the end of the line for writing dict key-value pairs in multiple lines: - -```python -data = { - "key1" = "value1" # Ignore the comma ',' at the end of line - "key2" = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -We can ignore the key quotation marks when we writing simple literals on the key. - -```python -data = { - key1 = "value1" # Ignore key quotation '"' - key2 = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -In addition, the **config selector expressions** can be used to init a dict instance with nested keys. - -```python -person = { - base.count = 2 - base.value = "value" - labels.key = "value" -} # {"base": {"count": 2, "value": "value"}, "labels": {"key": "value"}} -``` - -The output YAML is - -```yaml -person: - base: - count: 2 - value: value - labels: - key: value -``` - -In KCL, different fields in dict can be referenced, such as the following example. - -```python -config = { - name = "me" - metadata.name = name # Reference `name` with the value `"me"` in `config` directly. -} -``` - -The output YAML is - -```yaml -config: - name: me - metadata: - name: me -``` - -We can declare a dict with dict comprehension: - -```python -x = {str(i): 2 * i for i in range(3)} -assert x == {"0" = 0, "1" = 2, "2" = 4} -``` - -Besides, we can use two variables in the dict comprehension, the first variable denotes the dict key and the second variable denotes the dict value of the key. - -```python -data = {key1 = "value1", key2 = "value2"} -# Single variable loop -dataKeys1 = {k: k for k in data} # {"key1": "key1", "key2": "key2"} -dataValues1 = {k: data[k] for k in data} # {"key1": "value1", "key2": "value2"} -# Double variable loop -dataKeys2 = {k: k for k, v in data} # {"key1": "key1", "key2": "key2"} -dataValues2 = {v: v for k, v in data} # {"value1": "value1", "value2": "value2"} -dataFilter = {k: v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use `_` to ignore loop variables -dataKeys3 = {k: k for k, _ in data} # {"key1": "key1", "key2": "key2"} -dataValues3 = {v: v for _, v in data} # {"value1": "value1", "value2": "value2"} -``` - -We can **merge** dict using the dict unpacking operator `**` like this: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = {**_part1, **_part2} # {"a: "b", "c": "d"} -``` - -In addition, the same effect can be achieved by using the union operator `|`: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = _part1 | _part2 # {"a: "b", "c": "d"} -``` - -We can use `if expressions` to dynamically add elements to the dict element, elements that meet the conditions are added to the dict, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = { - key1 = "value1" - if a == 1: key2 = "value2" - if a > 0: key3 = "value3" - if a < 0: key4 = "value4" -} # {"key1": "value1", "key2": "value2", "key3": "value3"} -``` - -```python -a = 1 # 1 -data1 = { - key1 = "value1" - if a == 1: - key2 = "value2" - elif a > 0: - key3 = "value3" - else: - key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -data2 = { - key1 = "value1" - if a == 1: key2 = "value2" - elif a > 0: key3 = "value3" - else: key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -``` - -We can use the expression `for k in dict_var` to traverse a dict, and we can use the `in` operator to determine whether a dict contains a certain key - -```python -data = {key1 = "value1", key2 = "value2"} -dataAnother = {k: data[k] + "suffix" for k in data} # {"key1": "value1suffix", "key2": "value2suffix"} -containsKey1 = "key1" in data # True -containsKey2 = "key" in data # False -``` - -#### None - -In KCL, `None` can indicate that the value of the object is empty, which is similar to `nil` in Go or `null` in Java, and corresponds to `null` in YAML. - -```python -a = None -b = [1, 2, None] -c = {key1 = value1, key2 = None} -``` - -The output is as follows: - -```yaml -a: null -b: - - 1 - - 2 - - null -c: - key1: value1 - key2: null -``` - -Please note that `None` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + None # error -b = int(None) # error -c = not None # True -d = None == None # True -e = None or 1 # 1 -f = str(None) # None -``` - -#### Undefined - -`Undefined` is similar to `None`, but its semantics is that a variable is not assigned any value and will not be output to YAML - -```python -a = Undefined -b = [1, 2, Undefined] -c = {key1 = "value1", key2 = Undefined} -``` - -The output is as follows: - -```yaml -b: - - 1 - - 2 -c: - key1: value1 -``` - -Please note that `Undefined` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + Undefined # error -b = int(Undefined) # error -c = not Undefined # True -d = Undefined == Undefined # True -e = Undefined or 1 # 1 -f = str(Undefined) # Undefined -``` - -### Operators - -The following character sequences represent operators: - -```txt -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != @ \ -``` - -#### Arithmetic Operators - -KCL supports the common arithmetic operators: - -```python -assert 2 + 3 == 5 -assert 2 - 3 == -1 -assert 2 * 3 == 6 -assert 5 / 2 == 2.5 -assert 5 // 2 == 2 -assert 5 % 2 == 1 -``` - -#### Equality and Relational Operators - -KCL supports the meanings of equality and relational operators: - -```python -assert 2 == 2 -assert 2 != 3 -assert 3 > 2 -assert 2 < 3 -assert 3 >= 3 -assert 2 <= 3 -``` - -#### Logical Operators - -We can invert or combine boolean expressions using the logical operators e.g., `and` and `or`: - -```python -if not done and (col == 0 or col == 3): - # ...Do something... - -``` - -#### Bitwise and Shift Operators - -Here are examples of using bitwise and shift operators: - -```python -value = 0x22 -bitmask = 0x0f - -assert (value & bitmask) == 0x02 -assert (value & ~bitmask) == 0x20 -assert (value | bitmask) == 0x2f -assert (value ^ bitmask) == 0x2d -assert (value << 4) == 0x220 -assert (value >> 4) == 0x02 -``` - -The `|` operator likewise computes bitwise, unions basic types and unions collection and schema data, such as **list**, **dict** and **schema**. - -Computing bitwise examples: - -```python -0x12345678 | 0xFF # 0x123456FF -``` - -Unioning basic types examples: - -```python -schema x: - a: int | str # attribute a could be a int or string -``` - -#### Assignment Operators - -The following tokens serve as delimiters in the grammar: - -```bash - ( ) [ ] { } - , : . ; = -> - += -= *= /= //= %= - &= ^= >>= <<= **= -``` - -The following examples use assignment and argument assignment operators: - -```python -_a = 2 -_a *= 3 -_a += 1 -assert _a == 7 -``` - -#### Identity Operators - -The following keywords serve as identity operators in the grammar: - -```python -is, is not -``` - -The identity operators check whether the right hand side and the left hand side are the very same object. They are usually used to check if some variable is `None/Undefined/True/False`. Here are some examples: - -```python -empty_String = "" -empty_String is not None # True -``` - -#### Membership Operators - -The following keywords serve as membership operators in the grammar: - -```python -in, not in -``` - -- The `in` operator reports whether its first operand is a member of its second operand, which must be a list, dict, schema, or string. -- The `not in` operator is its negation. Both return a Boolean. - -The meaning of membership varies by the type of the second operand: the members of a list are its elements; the members of a dict are its keys; the members of a string are all its substrings. - -```python -1 in [1, 2, 3] # True - -d = {one = 1, two = 2} -"one" in d # True -"three" in d # False -1 in d # False -[] in d # False - -"nasty" in "dynasty" # True -"a" in "banana" # True -"f" not in "way" # True - -d = Data {one = 1, two = 2} # Data is a schema with attributes one and two -"one" in d # True -"three" in d # False -``` - -#### Comprehension - -A comprehension constructs a new list or dictionary value by looping over one or more iterables and evaluating a body expression that produces successive elements of the result. - -We can declare list and dict by comprehension as: - -```python -listVar = [_x for _x in range(20) if _x % 2 == 0] # list comprehension -dictVar = {str(_i): 2 * _i for _i in range(3)} # dict comprehension -``` - -#### Other Operators - -We can: - -- Represents a function call with **()**, like `"{} {}".format("hello", world)` -- Refers to the value at the specified index in the list with **[]** -- Define a type hint with **:** -- Refers to a member field with **.** -- Use the line continuation symbol `\` to write long expressions - -```python -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " -``` - -### Expressions - -#### Conditional Expressions - -A conditional expression has the form `a if cond else b`. It first evaluates the condition `cond`. If it's true, it evaluates `a` and yields its value; otherwise, it yields the value of `b`. - -Examples: - -```python -x = True if enabled else False # If enabled is True, x is True, otherwise x is False -``` - -#### Index Expressions - -An index expression `a[i]` yields the `i` th element of an indexable type such as a string or list. The index `i` must be an `int` value in the range `-n` ≤ `i` < `n`, where `n` is `len(a)`; any other index results in an error. - -A valid negative index `i` behaves like the non-negative index `n+i`, allowing for convenient indexing relative to the end of the sequence. - -```python -val = "abc" -list = ["zero", "one", "two"] -str_0 = val[0] # "a" -str_1 = val[1] # "b" -str_n1 = val[-1] # "c" - -list_0 = list[0] # "zero" -list_1 = list[1] # "one" -list_n1 = list[-1] # "two" -``` - -An index expression `d[key]` may also be applied to a dictionary `d`, to obtain the value associated with the specified key. It returns `Undefined` if the dictionary contains no such key. - -An index expression appearing on the left side of an assignment causes the specified list or dictionary element to be updated: - -```python -d = {key1 = "value1", key2 = "value2"} -key1value = d["key1"] # value1 -key2value = d["key2"] # value2 -``` - -It is a dynamic error to attempt to update an element of an immutable type, such as a list or string, or a frozen value of a mutable type. - -#### Slice Expressions - -A slice expression `a[start:stop:step]` yields a new value containing a sub-sequence of `a`, which must be a string, or list. - -Each of the `start`, `stop`, and `step` operands is optional; if present, each must be an integer. The `step` value defaults to 1. If the step is not specified, the colon preceding it may be omitted too. It is an error to specify a step of zero. - -Conceptually, these operands specify a sequence of values `i` starting at start and successively adding 'step' until `i` reaches or passes `stop`. The result consists of the concatenation of values of `a[i]` for which `i` is valid. - -The effective start and stop indices are computed from the three operands as follows. Let `n` be the length of the sequence. - -```python -val = "abc" -len = len(val) -a = val[1:len] # "bc" (remove first element) -b = val[0:-1] # "ab" (remove last element) -c = val[1:-1] # "b" (remove first and last element) -``` - -```python -"abc"[1:] # "bc" (remove first element) -"abc"[:-1] # "ab" (remove last element) -"abc"[1:-1] # "b" (remove first and last element) -"banana"[1::2] # "aaa" (select alternate elements starting at index 1) -"banana"[4::-2] # "nnb" (select alternate elements in reverse, starting at index 4) -``` - -It's not allowed to define a slice expression as a left value in KCL. Cause list and string are immutable, re-slicing can directly operate to operand to ensure better performance. - -#### Function Invocations - -KCL allows calling built-in functions and functions from built-in and system modules. - -To call a function, the basic way is shown as the following code excerpt: - -```python -import math - -a = math.pow(2, 3) # 2 powers 3 is 8. -b = len([1, 2, 3]) # the length of [1, 2, 3] is 3 -``` - -As you can see, arguments are separated with `,`, and KCL also supports positional arguments and key-value arguments. - -```python -print("hello world", end="") -``` - -Note that: - -- Some functions have parameters with default values. -- Some functions accept variadic arguments. - -When an argument is not supplied for a parameter without a default value, an error will be reported. - -#### Selector Expressions - -A selector expression selects the attribute or method of the value. KCL provides a wealth of ways to identify or filter attributes. - -`x.y` - -- dict: it denotes the value of the key `y` in the dict `x` -- schema: it denotes the attribute value of a schema `x` identified by `y` -- package: it denotes the identifier of a package `x` identified by `y` - -Examples: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -name = person.name # "Alice" -age = person.age # 18 - -myDict = { - key = "value" -} -result = myDict.key # "value" -``` - -`x?.y` - -`x` can be a schema instance or a dict. This is extremely helpful when the value of `x` might be `None` or when the key `y` might not exist in `x`. - -```python -# Example of dict: -data = {key = "value"} -a = data?.key # "value" -b = data?.name # Undefined - -# example of schema instance: -schema Company: - name: str - address: str - -schema Person: - name: str - job?: Company - -alice = Person { - name = "alice" -} - -if alice?.job?.name == "Group": - print("work in Group") -``` - -#### Quantifier Expressions - -Quantifier expressions act on collection: list or dict, generally used to obtain a certain result after processing the collection, mainly in the following four forms: - -- **all** - - Used to detect that all elements in the collection satisfy the given logical expression, and return a boolean value as the result. - - Only when all elements in the collection satisfy the expression true, the `all` expression is true, otherwise it is false. - - If the original collection is empty, return true. - - Supports short-circuiting of logical expressions during expression execution. -- **any** - - Used to detect that at least one element in the collection satisfies the given logical expression, and returns a boolean value as the result. - - When at least one element in the collection satisfies the expression true, the `any` expression is true, otherwise it is false. - - If the original collection is empty, return false. - - Supports short-circuiting of logical expressions during expression execution. -- **map** - - Generate a new **list** by mapping the elements in the original collection. - - The length of the new list is exactly the same as the original collection. -- **filter** - - By logically judging and filtering the elements in the original collection, and returning the filtered sub-collection. - - Only when the element judges the expression to be true, it is added to the sub-collection. - - The type (list, dict and schema) of the new collection is exactly the same as the original collection, and the length range is `[0, len(original-collection)]`. - -**all** and **any** expression sample codes: - -```python -schema Config: - volumes: [{str:}] - services: [{str:}] - - check: - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - }, "invalid cluster ip" - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } -``` - -**map** and **filter** expression sample codes: - -```python -a = map e in [{name = "1", value = 1}, {name = "2", value = 2}] { - {name = e.name, value = int(e.value) ** 2} -} # [{"name": "1", value: 1}, {"name": "2", "value": 4}] - -b = map k, v in {a = "foo", b = "bar"} { v } # ["foo", "bar"] - -c = filter e in [{name = "1", value = 1}, {name = "2", value = 2}] { - int(e.value) > 1 -} # [{"name": "2", "value": 2}] - -d = filter _, v in {a = "foo", b = "bar"} { - v == "foo" -} # {"a": "foo"} -``` - -Please pay attention to distinguish the difference between any expression and any type. When `any` is used in type annotations, it means that the value of the variable is arbitrary, while the any expression means that one of the elements in a set satisfies the condition. - -### Control Flow Statements - -#### If and Else - -KCL supports `if` statements with optional `elif` and `else` statements, as the next sample shows. - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - print("maybe a is negative") -else: - print("a >= 100") -``` - -The `elif` example: - -```python -_result = 0 -if condition == "one": - _result = 1 -elif condition == "two": - _result = 2 -elif condition == "three": - _result = 3 -else: - _result = 4 -``` - -`if-elif-else` statements can be nested. For example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - if a < 0: - print("a is negative") - print("No matter a is negative or positive, this message is printed") -else: - print("a >= 100") -``` - -In addition, for simple `if` statements as follows: - -```python -if success: - _result = "success" -else: - _result = "failed" -``` - -We can have it in one line using the ` if else ` pattern: - -```python -_result = "success" if success else "failed" -``` - -An `if` or `elif` statement evaluates a given expression. When the expression is evaluated to `True`, a list of statements following `:` are executed and when the expression is evaluated to `False` and statements will not be executed. - -Please note that the false name constant `False`, `None`, the zero number `0`, the empty list `[]`, the empty dict `{}` and the empty string `""` are all seen as `False` expressions. - -```python -_emptyStr = "" -_emptyList = [] -_emptyDict = {} -isEmptyStr = False if _emptyStr else True -isEmptyList = False if _emptyList else True -isEmptyDict = False if _emptyDict else True -``` - -The output is - -```yaml -isEmptyStr: true -isEmptyList: true -isEmptyDict: true -``` - -### Assert - -When errors happen, developers should be able to detect the error and abort execution. Thus, KCL introduce the `assert` syntax. The following is an example: - -```python -a = 1 -b = 3 -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -``` - -In addition, we can declare a condition for the assert statement and make an assertion when the condition is met. The usual way of writing is - -```python -a = None -if a: - assert a > 2: -``` - -In KCL, it can also be simplified to the following form using the **if** expression to compose more complex conditional assert logic: - -```python -a = None -assert a > 2 if a -``` - -### Function - -KCL supports using the lambda keyword to define a function. - -```python -func = lambda x: int, y: int -> int { - x + y -} -a = func(1, 1) # 2 -``` - -- The value of the last expression is used as the return value of the function, and the empty function body returns `None`. -- The return value type annotation can be omitted, and the return value type is the type of the last expression value. -- There is no order-independent feature in the function body, all expressions are executed in order. - -```python -_func = lambda x: int, y: int -> int { - x + y -} # Define a function using the lambda expression -_func = lambda x: int, y: int -> int { - x - y -} # Ok -_func = lambda x: int, y: int -> str { - str(x + y) -} # Error (int, int) -> str can't be assigned to (int, int) -> int -``` - -The function type variables cannot participate in any calculations and can only be used in assignment statements and call statements. - -```python -func = lambda x: int, y: int -> int { - x + y -} -x = func + 1 # Error: unsupported operand type(s) for +: 'function' and 'int(1)' -``` - -The lambda function supports the capture of external variables, which can be passed as parameters of other functions. - -```python -a = 1 -func = lambda x: int { - x + a -} -funcOther = lambda f, para: int { - f(para) -} -r0 = funcOther(func, 1) # 2 -r1 = funcOther(lambda x: int { - x + a -}, 1) # 2 -``` - -The output is - -```yaml -a: 1 -r: 2 -``` - -Further, we can define an anonymous function through lambda expression and call it. - -```python -result = (lambda x, y { - z = 2 * x - z + y -})(1, 1) # 3 -``` - -We can also use anonymous functions in the for loop. - -```python -result = [(lambda x, y { - x + y -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 3, 3, 4] -``` - -Note that the functions defined in the KCL are pure functions: - -- The return result of a function depends only on its arguments. -- There are no side effects in the function execution process. - -Therefore, KCL functions cannot modify external variables, but can only reference external variables. For example, the following code will cause an error: - -```python -globalVar = 1 -func = lambda { - x = globalVar # Ok - globalVar = 1 # Error -} -``` - -### Type System - -#### Type Annotation - -Type annotations can be used on top level variables, schema attributes and arguments. - -- An attribute can be of a basic type, such as a string (`str`), a floating-point number (`float`), a fixed-point number (`int`) or a boolean (`bool`). -- An attribute can be a literal type, such as a string literal (`"TCP"` and `"UDP"`), a number literal (`"1"` and `"1.2"`), a boolean literal (`True` and `False`) -- An attribute can also be a list or an ordinary dict: - - A list with unspecified type of elements is `[]`. - - A list with elements of type `t` is `[t]`. Here `t` is another type. - - A dict with keys of type `kt` and values of type `vt` is `{kt:vt}`. - - `kt`, `vt` or both of them can be missing, like a list with unspecified type of elements. -- An attribute can be a **union type** defined by `|`, such as `a | b`, which means the type of the member could be a or b. - - A union type can include any types of `int`, `str`, `float`, `bool`, `list`, `dict`, literal and schema type, and supports type nesting e.g. `{str:str|int}`, `[[int|str]|str|float]` and `2 | 4 | 6`, etc. -- An attribute can also be of a type generated from other schema. In such a case, the name of the other schema (including the package path prefix) is used as the type name. -- An attribute can annotated an any type e.g., `any`. - -Examples: - -- Basic type - -```python -"""Top level variable type annotation""" -a: int = 1 # Declare a variable `a` that has the type `int` and the value `1` -b: str = "s" # Declare a variable `b` that has the type `str` and the value `"s"` -c: float = 1.0 # Declare a variable `c` that has the type `float` and the value `1.0` -d: bool = True # Declare a variable `d` that has the type `bool` and the value `True` -``` - -- List/Dict/Schema Type - -```python -schema Person: - name: str = "Alice" - age: int = 10 - -a: [int] = [1, 2, 3] # Declare a variable `a` that has the list type `[int]` and the value `[1, 2, 3]` -b: {str:str} = {k1 = "v1", k2 = "v2"} # Declare a variable `b` that has the dict type `{str:str}` and the value `{k1 = "v1", k2 = "v2"}` -c: Person = Person {} # Declare a variable `c` that has the schema type `Person` and the value `Person {}` -``` - -- Union Type - -```python -# Basic union types -schema x[argc: int]: # Schema argument type annotation - p: int | str # Schema attribute type annotation -``` - -```python -# Literal union types -schema LiteralType: - # String literal union types, x_01 can be one of "TCP" and "UDP" - x_01: "TCP" | "UDP" - # Number literal union types, x_02 can be one of 2, 4, and 6 - x_02: 2 | 4 | 6 - # Unit union types, x_03 can be one of 1Gi, 2Gi and 4Gi - x_03: 1Gi | 2Gi | 4Gi - -x = LiteralType { - x_01 = "TCP" - x_02 = 2 - x_03 = 1Gi -} -``` - -The compiler throws an error when the value of a property does not conform to the union type definition: - -```python -# Literal union types -schema LiteralType: - # String literal union types, x_01 can be one of "TCP" and "UDP" - x_01: "TCP" | "UDP" - -x = LiteralType { - x_01 = "HTTP" # Error: the type got is inconsistent with the type expected, expect str(TCP)|str(UDP), got str(HTTP) -} -``` - -- Any Type - -```python -# Any type -schema Config: - literalConf: any = 1 - dictConf: {str:any} = {key = "value"} - listConf: [any] = [1, "2", True] - -config = Config {} -``` - -In KCL, changing the type of a variable is not allowed. If the type is not satisfied when reassigning the value, the type error will be raised. - -```python -_a = 1 # The type of `_a` is `int` -_a = "s" # Error: expect int, got str(s) -``` - -The type of a variable can be assigned to its upper bound type, but cannot be assigned to its specialized type. - -`None` and `Undefined` can be assigned to any type: - -- All types can be assigned to `any` type, `None` and `Undefined` can be assigned to `any` type. - -```python -a: int = None -b: str = Undefined -c: any = 1 -d: any = "s" -e: any = None -``` - -- The `int` type can be assigned to the `float` type, and the `float` type cannot be assigned to the `int` type. - -```python -a: float = 1 -b: int = 1.0 # Error: expect int, got float(1.0) -``` - -- The `int` type can be assigned to the `int|str` type, and the `int|str` type cannot be assigned to the `int` type. - -```python -a: int | str = 1 -b: int = 1 if a else "s" # Error: expect int, got int(1)|str(s) -``` - -Note that although the any type is provided in the KCl, it is still a static type, and the types of all variables are immutable during compilation. - -#### Type Inference - -If a variable or constant declaration in the top level or in the schema is not annotated explicitly with a type, the declaration's type is inferred from the initial value. - -- Integer literals are inferred to type `int`. - -```python -a = 1 # The variable `a` has the type `int` -``` - -- Float literals are inferred to type `float`. - -```python -a = 1.0 # The variable `a` has the type `float` -``` - -- String literals are inferred to type `str`. - -```python -a = "s" # The variable `a` has the type `str` -``` - -- Boolean literals are inferred to type `bool` - -```python -a = True # The variable `a` has the type `bool` -b = False # The variable `b` has the type `bool` -``` - -- `None` and `Undefined` are inferred to type `any` - -```python -a = None # The variable `a` has the type `any` -b = Undefined # The variable `b` has the type `any` -``` - -- List literals are inferred based on the elements of the literal, and to be variable-size. - -```python -a = [1, 2, 3] # The variable `a` has the type `[int]` -b = [1, 2, True] # The variable `b` has the list union type `[int|bool]` -c = ["s", 1] # The variable `c` has the list union type `[int|str]` -``` - -Please note that a empty list will be inferred to `[any]` - -```python -a = [] # The variable `a` has the type `[any]` -``` - -- Dict literals are inferred based on the keys and values of the literal, and to be variable-size. - -```python -a = {key = "value"} # The variable `a` has the type `{str:str}` -b = {key = 1} # The variable `b` has the type `{str:int}` -c = {key1 = 1, key2 = "s"} # The variable `c` has the type `{str:int|str}` -``` - -Please note that a empty dict will be inferred to `{any:any}` - -```python -a = {} # The variable `a` has the type `{any:any}` -``` - -- The type of the if conditional expression carrying the runtime value will be statically inferred as a union type of all possible results. - -```python -a: bool = True # The variable `a` has the type `bool` -b = 1 if a else "s" # The variable `b` has the type `int|str` -``` - -When a variable is deduced to a certain type, its type cannot be changed - -```python -_a = 1 -_a = "s" # Error: expect int, got str(1) -``` - -#### Type Alias - -We can use the `type` keyword to declare a type alias for all types in KCL to simplify the writing and use of complex types. - -```python -type Int = int -type String = str -type StringOrInt = String | Int -type IntList = [int] -type StringAnyDict = {str:} -``` - -We can import a type through import and define an alias for it. - -```py -import pkg - -type Data = pkg.Data -``` - -In addition, we can use type aliases and union types to achieve similar enumeration functions. - -```python -# A type alias of string literal union types -type Color = "Red" | "Yellow" | "Blue" - -schema Config: - color: Color = "Red" # The type of color is `"Red" | "Yellow" | "Blue"`, and it has an alias `Color`, whose default value is `"Red"` - -config = Config { - color = "Blue" -} -``` - -The output YAML is - -```yaml -config: - color: Blue -``` - -Please note that the type alias name cannot be one of `any`, `int`, `float`, `bool` and `str` because of ambiguity. - -```python -type any = int | str # Error -type int = str # Error -type float = int # Error -type bool = True # Error -type str = "A" | "B" | "C" # Error -``` - -#### Type Guards - -KCL supports the `typeof` function which can give very basic information about the type of values we have at runtime. In KCL, checking against the value returned by `typeof` is a type guard. KCL expects this to return a certain set of strings: - -Example: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person {} -t3 = typeof(_x1) - -_x2 = pkg.Person {} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# Output -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -In addition, we can use the `as` keyword in conjunction with type guards to complete defensive type conversion programming. - -Only types with partial order can be downcast converted, the use of the as keyword is as follows: - -- Basic types of partial order relations, e.g., `float -> int` -- Partial order relation of union type, e.g., `int | str -> str` and `[int | str] -> [str]` -- Contains the partial order relation of the upper bound of the type, e.g., `any -> int` -- Partial order relationship of structure type, e.g., `base-schema -> sub-schema` - -```python -schema Data1: - id?: int - -schema Data2: - name?: str - -data: Data1 | Data2 = Data1 {} - -if typeof(a) == "Data1": - data1 = data as Data1 # The type of `data1` is `Data1` -elif typeof(a) == "Data2": - data2 = data as Data2 # The type of `data2` is `Data2` -``` - -When a runtime error occurs in the `as` type conversion, a runtime error is thrown. - -```python -a: any = "s" -b: int = a as int # Error: The `str` type cannot be converted to the `int` type -``` - -If we don’t want to throw a runtime error, we can use the type guard for defensive coding with `if` expressions. - -```python -a: any = "s" -b = a as int if typeof(a) == "int" else None # The type of b is `int` -``` - -Note that the `as` conversion of literal type and union type is not supported, because they are not a certain runtime object, only int, float and other objects at runtime, there is no int literal, float literal object, and no union object. - -### Schema - -#### Overview - -A schema is a language element to define a complex configuration. -We can define typed attributes, initialization assignment, and verification rules. In addition, KCL supports schema single inheritance, mixin and protocol to realize the reuse of complex configuration. - -#### Basic - -##### Attribute - -The followings are some basic examples: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 -``` - -In KCL, we can use type annotations to define some attributes in the schema, each attribute can be set with an optional default value (such as the `age` attribute in the above code, its default value is `0`), attributes that are not set default values have an initial value of `Undefined`, which are not output in YAML. - -Note, the immutability of attributes in the schema follows the same rules as the immutability of global variables, only mutable attributes in the schema can be modified in the schema. - -```python -schema Person: - age: int = 1 # Immutable attribute - _name: str = "Alice" # Mutable attribute - - age = 10 # Error - _name = "Bob" # Ok -``` - -###### Optional Attribute - -Each attribute **must** be assigned with a not `None`/`Undefined` value as a schema instance unless it is modified by a question mark as an optional attribute. - -Examples: - -```python -schema Employee: - bankCard: int # bankCard is a required attribute, and it can NOT be None or Undefined - nationality?: str # nationality is an optional attribute, and it can be None or Undefined - -employee = Employee { - bankCard = None # Error, attribute 'bankCard' of Employee is required and can't be None or Undefined - nationality = None # Ok -} -``` - -##### Irrelevant Order Calculation - -The irrelevant order calculation in the schema indicates the reference relationship between the internal attributes of the schema. For example, when we declare an expression of the form `a = b + 1`, the calculation of the value of `a` depends on the calculation of the value of `b`. When the compiler calculate the value of `a` and the value of `a` depends on the value of `b`, the compiler will choose to first calculate the value of `b`, and then calculate the value of a according to the expression `a = b + 1`, which is slightly different from the calculation method of traditional procedural language the difference. - -Since the calculation of values in the schema is based on dependencies, just like a directed acyclic graph traverses each node in the graph according to the order of topological sorting, the order of declaration of attributes in the schema is not so important, so the feature is called the irrelevant order calculation. - -Please note that there can be no circular references between different schema attribute values. - -We can see this feature through the following examples. - -```python -schema Fib: - n1: int = n - 1 # Refers to the attribute `n` declared after `n1` - n2: int = n1 - 1 - n: int - value: int = 1 if n <= 2 else Fib {n = n1}.value + Fib {n = n2}.value - -fib8 = Fib {n = 8}.value -``` - -The output is - -```yaml -fib8: 21 -``` - -We can see that in the schema, we only need to simply specify the dependency between attributes, and the compiler will automatically calculate the value based on the dependency, which can help us save a lot of boilerplate code and reduce configuration difficulty of writing. - -##### Schema Context - -We can define the context of the schema to manage the attributes of the schema, and we can write schema parameters, temporary variables and expressions directly in the schema: - -```python -schema Person[_name: str]: # define a schema argument - name: str = _name # define a schema attribute - age: int = 10 # define a schema attribute with default value - hands: [int] = [i for i in [1, 2, 3]] # define a for statement -``` - -##### Validation - -In addition to using **static typing** (the type annotation) and **immutability** in KCL schema mentioned earlier to ensure code stability, a bunch of validation rules are supported in a simple **check** block (KCL supports almost all authentication capabilities of [OpenAPI](https://www.openapis.org/)): - -```python -import regex - -schema Sample: - foo: str - bar: int - fooList: [str] - - check: - bar > 0 # minimum, also support the exclusive case - bar < 100 # maximum, also support the exclusive case - len(fooList) > 0 # min length, also support exclusive case - len(fooList) < 100 # max length, also support exclusive case - regex.match(foo, "^The.*Foo$") # regex match - isunique(fooList) # unique - bar in range(100) # range - bar in [2, 4, 6, 8] # enum - multiplyof(bar, 2) # multipleOf -``` - -With the schema, all instances will be validated at compile time - -```python -# Ok -goodSample = Sample { - foo = "The Foo" - bar = 2 - fooList = ["foo0", "foo1"] -} - -# Error: validation failure: Check failed on check conditions: bar < 100. -badSample = Sample { - foo = "The Foo" - bar = 123 - fooList = ["foo0", "foo1"] -} -``` - -In addition, we can use **and**, **or**, **if** to compose more complex conditional check logic: - -```python -schema Sample: - bar: int - foo: str - doCheck: bool - - check: - regex.match(foo, "^The.*Foo$") and bar in [2, 4, 6, 8] if doCheck -``` - -In order to ensure that all check rules can play their corresponding roles well, we can test the rationality and correctness of different data combinations by writing KCL test cases, and run all test cases through the kcl test tool. - -##### Documents - -Usually after we write the schema model, we will write documentation comments for the schema, which can be completed by using a three-quoted string as follows: - -```python -schema Server: - """Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - - Attributes - ---------- - workloadType : str, default is Deployment - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - name : str, default is None - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - labels : {str:str}, optional, default is None - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - - Examples - ---------------------- - myCustomApp = AppConfiguration { - name = "componentName" - } - """ - workloadType: str = "Deployment" - name: str - labels?: {str:str} -``` - -##### Config - -Suppose we have the following schema definition: - -```python -schema Person: - firstName: str - lastName: str -``` - -A config could be defined with a JSON-like expression: - -```python -person = Person { - firstName = "firstName" - lastName = "lastName" -} -``` - -At the same time, the schema adheres to strict attribute definitions, -and configuring undefined attributes will trigger a compilation error. - -```python -person = Person { - firstName = "firstName" - lastName = "lastName" - fullName = "fullName" # Error: Cannot add member 'fullName' to schema 'Person', 'fullName' is not defined in schema 'Person' -} -``` - -We can use `if expressions` to dynamically add elements to the schema config, elements that meet the conditions are added to the schema config, and elements that do not meet the conditions are ignored. Besides, the **config selector expressions** can be used to init a schema instance. - -```python -schema Base: - count: int - value: str - -schema Person: - base: Base - labels: {str:str} - name?: str - -env = "prod" - -person1 = Person { - base.count = 2 # Config selector expression - base.value = "value" # A schema variable in schema can use selector expressions - labels.key = "value" # A dict variable in schema can use selector expressions -} - -person2 = Person { - base = { - count = 1 - value = "value" - } - labels.key = "value" - if env == "prod": - labels.env = env - else: - labels.env = "other" -} -``` - -The output YAML is - -```yaml -person1: - base: - count: 2 - value: value - labels: - key: value -person2: - base: - count: 1 - value: value - labels: - key: value - env: prod -``` - -When we instantiate a schema without config parameters, we can generate schema instances in the following three forms: - -```python -schema Data: - id: int = 1 - -data1 = Data {} -data2 = Data() {} -data3 = Data() -``` - -In addition to using a schema type to instantiate a schema, we can also use a schema instance to get a new instance using the config expression. - -```python -schema Config: - id: int - values: [int] - -configOrigin = Config { - id = 1 - values = [0, 1] -} -configNew = configOrigin { - id = 2 - values += [2, 3] -} -``` - -The output is - -```yaml -configOrigin: - id: 1 - values: - - 0 - - 1 -configNew: - id: 2 - values: - - 0 - - 1 - - 2 - - 3 -``` - -In addition, schema attribute default values can be modified by schema config. - -```python -schema Person: - age: int = 1 - name: str = "Alice" - - age = 2 # Error, can't change the default value of the attribute `age` in the schema context - -person = Person { - age = 3 # Ok, can change the default value of the attribute `age` in the schema config -} -``` - -#### Advanced - -##### Protocol & Mixin - -In addition to schema, an additional type definition method `protocol` is provided in KCL, and its properties are as follows: - -- In a protocol, only attributes and their types can be defined, complex logic and check expressions cannot be written, and mixins cannot be used. -- A protocol can only constrain properties that do not start with `_`. -- A protocol can only inherit or refer to other protocols, but cannot inherit or refer to other schemas. - -Besides, we can declare a complex assembly schema with optional **mixin** support and use **protocol** to add an optional host type to the dynamically inserted **mixin**.: - -```python -schema Person: - mixin [FullNameMixin] - - firstName: str # Required - lastName: str # Required - fullName?: str # Optional -``` - -A fullName mixin which generates a fullName as a simple sample: - -```python -protocol PersonProtocol: - firstName: str - lastName: str - fullName?: str - -mixin FullNameMixin for PersonProtocol: - fullName = "{} {}".format(firstName, lastName) -``` - -Then we can get the schema instance by: - -```python -person = Person { - firstName = "John" - lastName = "Doe" -} -``` - -The output is - -```yaml -person: - firstName: John - lastName: Doe - fullName: John Doe -``` - -Please note that the host type **protocol** can only be used for **mixin** definitions (the suffix name is `Mixin`), otherwise an error will be reported. - -```python -protocol DataProtocol: - data: str - -schema Data for DataProtocol: # Error: only schema mixin can inherit from protocol - x: str = data -``` - -##### Index Signature - -Index signatures can be defined in the KCL schema, and it means that the key-value constraints of the index signature can be used to construct a dict with the schema type, or additional checks can be added to the schema attributes to enhance the KCL type and semantic checks. - -- Use the form `[{attr_alias}: {key_type}]: {value_type}` to define an index signature in the schema, and `{attr_alias}` can be omitted. - -```python -schema Map: - """ - Map is a schema with a key of str type and a value of str type - """ - [str]: str # `{attr_alias}` can be omitted. - -data = Map { - key1 = "value1" - key2 = "value2" -} -``` - -- Mandatory all attributes of the schema key and value types - -```python -schema Person: - name: str - age: int # error, conflicts with the index signature definition `[str]: str` - [str]: str # The values of all attributes of the schema can only be strings -``` - -- Mandatory all attribute key and value types are defined in the schema, which is equivalent to restricting all attribute types except the additional attributes. - -```python -schema Person: - name: str - age: int - [...str]: str # Except for the `name` and `age` attributes, the key type of all other attributes of the schema must be `str`, and the value type must also be `str`. -``` - -- Define the index signature attribute alias and use it with the check block. - -```python -schema Data: - [dataName: str]: str - check: - dataName in ["Alice", "Bob", "John"] - -data = Data { - Alice = "10" - Bob = "12" - Jonn = "8" # Error: Jonn not in ["Alice", "Bob", "John"] -} -``` - -```python -import regex - -schema DataMap: - [attr: str]: str - check: - regex.match(attr, r'^[-._a-zA-Z0-9]+$') - -data = DataMap { - key1 = "value1" - "foo.bar" = "value2" # check error -} -``` - -##### Inheritance - -Like some other object-oriented languages, KCL provides fundamental but limited object-oriented support, such as **attribute reuse**, **private and public variables**, and **single inheritance**. Besides, KCL does NOT support multiple inheritances for the schema. - -The following is an example of schema inheritance: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 - -# An employee **is** a person, and has some additional information. -schema Employee(Person): - bankCard: int - nationality?: str - -employee = Employee { - firstName = "Bob" - lastName = "Green" - age = 18 - bankCard = 123456 -} -``` - -The output is - -```yaml -employee: - firstName: Bob - lastName: Green - age: 18 - bankCard: 123456 - nationality: null -``` - -Please note that KCL only allows **single inheritance** on schemas. - -In addition, when the schema has an inheritance relationship, the properties of optional attributes are as follows: - -- If the attribute is optional in the base schema, it could be optional or required in the sub-schema. -- If the attribute is required in the base schema, it must be required in the sub-schema. - -```python -schema Person: - bankCard?: int - nationality: str - -schema Employee(Person): - bankCard: int # Valid, both `bankCard: int` and `bankCard?: int` are allowed - nationality?: str # Error, only `nationality: str` is allowed -``` - -##### Schema Function - -Schema map very nicely onto functions; it can have any number of input and output parameters. For example, the Fibonacci function can be written as follows using the recursive schema config: - -```python -schema Fib[n: int]: - n1 = n - 1 - n2 = n - 2 - if n == 0: - value = 0 - elif n == 1: - value = 1 - else: - value = Fib(n1).value + Fib(n2).value - -fib8 = Fib(8).value # 21 -``` - -##### Decorators - -Just like Python, KCL supports the use of decorators on the schema. KCL Decorators dynamically alter the functionality of a schema without having to directly use sub schema or change the source code of the schema being decorated. And like a function call, the decorator supports passing in additional parameters. - -Built-in decorators of schema - -- `@deprecated` - Mark whether a schema or schema attribute is deprecated. The `@deprecated` decorator supports three parameters: - - **version** - string type, indicating the version information. The default value is empty. - - **reason** - string type, indicating the deprecated reason. The default value is empty. - - **strict** - bool type, indicating whether to report an error or warning. The default value is true. If `strict` is `True` and the error is thrown, the program will be interrupted. If `strict` is `False`, a warning will be output and the program will not be interrupted. - -Examples: - -```python -@deprecated -schema ObsoleteSchema: - attr: str - -schema Person: - name: str = "John" - attrs: ObsoleteSchema = { - attr = "value" - } - -person = Person {} # Error: ObsoleteSchema was deprecated -``` - -```python -schema Person: - firstName: str = "John" - lastName: str - @deprecated(version="1.16", reason="use firstName and lastName instead", strict=True) - name: str - -JohnDoe = Person { # Error: name was deprecated since version 1.16, use firstName and lastName instead - name = "deprecated" -} -``` - -Note that the current version of KCL does not yet support user-defined decorators. - -##### Members - -Built-in functions and members of schema - -- instances() - Return the list of existing instances of a schema. - -```python -schema Person: - name: str - age: int - -alice = Person { - name = "Alice" - age = 18 -} - -bob = Person { - name = "Bob" - age = 10 -} - -aliceAndBob = Person.instances() # Person is a schema type, instances() is its member method -``` - -The output is - -```yaml -alice: - name: Alice - age: 18 -bob: - name: Bob - age: 10 -aliceAndBob: - - name: Alice - age: 18 - - name: Bob - age: 10 -``` - -### Config Operations - -#### Config Unification - -##### | Operators - -In KCL, we can use the union operator `|` to achieve the merging of configurations, the types supported by the union operator are as follows: - -```txt -SchemaInstance | SchemaInstance -SchemaInstance | Dict -Dict | Dict -List | List -``` - -Unioning collection and schema data: - -- Unioning List. Overwrite the list expression on the right side of the operator `|` to the list variable on the left side of the operator one by one according to the **index**. - -```python -_a = [1, 2, 3] -_b = [4, 5, 6, 7] -x = _a | _b # [4, 5, 6, 7] 1 -> 4; 2 -> 5; 3 -> 6; Undefined -> 7 -``` - -Unioning to the specific index or all elements is still under discussion. - -- Unioning Dict. Union the dict expression on the right side of the operator `|` one by one to the dict variable on the left side of the operator according to the **key** - -```python -_a = {key1 = "value1"} -_b = {key1 = "overwrite", key2 = "value2"} -x = _a | _b # {"key1": "overwrite", "key2": "value2"} -``` - -The union of collection and schema is a new one whose attributes are unioning b to a, preserving the order of the attributes of the operands, left before right. - -- Unioning Schema. The union operation for schema is similar to dict. - -Schema union could be done as: - -```python -schema Person: - firstName?: str - lastName?: str - -_a = Person { - firstName = "John" -} -_b = {lastName = "Doe"} -_c = _a | _b # {"firstName": "John", "lastName": "Doe"} -_d = _a | None # {"firstName": "John"} -_e = _a | Undefined # {"firstName": "John"} -_f = None | _a # {"firstName": "John"} -_g = Undefined | _a # {"firstName": "John"} -``` - -Please note that when one of the left and right operands of the union operator is None, the other operand is returned immediately. - -```python -data1 = {key = "value"} | None # {"key": "value"} -data2 = None | [1, 2, 3] # [1, 2, 3] -data3 = None | None # None -``` - -The output is - -```yaml -data1: - key: value -data2: - - 1 - - 2 - - 3 -data3: null -``` - -##### : Operators - -Pattern: `identifier : E` or `identifier : T E` - -The value of the expression `E` with optional type annotation `T` will be unioned into the element value. - -Examples: - -```python -data = { - labels: {key1: "value1"} - # union {key2: "value2"} into the attribute labels. - labels: {key2: "value2"} -} -``` - -Output: - -```yaml -data: - labels: - key1: value1 - key2: value2 -``` - -In addition to using attribute operators on the schema config attributes, variables inside and outside the schema can use attribute operators to perform different operations on the configuration. - -- Using `:` outside the schema - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - data: Data - -# This is one configuration that will be merged. -config: Config { - data.d1 = 1 -} -# This is another configuration that will be merged. -config: Config { - data.d2 = 2 -} -``` - -Its equivalent configuration code can be expressed as - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - data: Data - -config: Config { - data.d1 = 1 - data.d2 = 1 -} -``` - -The output is - -```yaml -config: - data: - d1: 1 - d2: 1 -``` - -- Using `:` inside the schema - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - # This is one configuration that will be merged. - data: Data { - d1 = 1 - } - # This is another configuration that will be merged. - data: Data { - d2 = 1 - } - -config: Config {} -``` - -#### Config Override - -##### = Operators - -Pattern: `identifier = E` or `identifier : T = E` - -The value of the expression `E` with optional type annotation `T` will override the attribute value. - -Examples: - -```python -schema Data: - labels: {str:} = {key1 = "value1"} - -data = Data { - # override {key2: "value2"} into the attribute labels of the schema Data. - labels = {key2 = "value2"} -} -``` - -Output: - -```yaml -data: - labels: - key2: value2 -``` - -Note: - -- Especially, we can "delete" its content by overriding the attribute to `Undefined`, such as `{ a = Undefined }`. - -#### Insert - -##### += Operators - -Pattern: `identifier += E` or `identifier : T += E` - -Insert only works for list type `identifier`. - -`E` will be inserted just after the specified index of the list `identifier`, and the following attributes after the index will be automatically shifted. - -Examples: - -```python -schema Data: - labels: {str:} = {key1 = [0]} - -data = Data { - # insert [1] into the attribute labels.key1 of the schema Data. - labels: {key1 += [1]} -} -``` - -Output: - -```yaml -data: - labels: - key1: - - 0 - - 1 -``` - -If no index is specified, the last index will be used. - -#### Notice - -Please note that the calculations of the `=` and `+=` attribute operators of the same attribute are sequential, and the latter ones have a higher priority. - -```python -x = { - a = 1 # 1 -} | { - a = 2 # 1 -> 2 -} | { - a = 3 # 2 -> 3 -} # The final value of attribute `a` is 3 -``` - -Please note that the `:` attribute operator represents an idempotent merge operation, and an error will be thrown when the values that need to be merged conflict. - -Therefore, when we need a configuration to override or add and delete operations, it is best to use the `=` and `+=` operators - -```python -data0 = {id: 1} | {id: 2} # Error:conflicting values between {'id': 2} and {'id': 1} -data1 = {id: 1} | {id = 2} # Ok, the value of `data` is {"id": 2} -``` - -The check rules for `:` operator for KCL value conflicts are as follows: - -- For `None` and `Undefined` variables, they do not conflict with any value. - -```python -data0 = None | {id: 1} # Ok -``` - -- For `int`, `float`, `str` and `bool` types, when their values are different, they are considered as conflicts. - -```python -data0 = 1 | 1 # Ok -data1 = 1 | "s" # Error -``` - -- For list type - - When their lengths are not equal, they are regarded as conflicts. - - When their lengths are equal, as long as there is a conflict in the value of a child element, it is regarded as a conflict. - -```python -data0 = [1] | [1] # Ok -data1 = [1, 2] | [1] # Error -``` - -- For dict/schema type - - When the values of the same key conflict, they are regarded as conflicts - -```python -data0 = {id: 1} | {id: 1} # Ok -data1 = {id: 1} | {id: 2} # Error -data1 = {id: 1} | {idAnother: 1} # Ok -``` - -### Rule - -In addition to using the check keyword for verification and writing in the schema, KCL also supports the use of the `rule` keyword to define a set of rules for policy verification - -The KCL rule is the same as the schema/mixin/protocol and it is defined by indentation. We need write a rule per line and we can write if filter conditions and verification failure information for each rule. Different conditions are connected with logic `and` (similar to the way of writing in check block). - -```python -rule SomeRule: - age > 0, "rule check failure message" -``` - -We can call a KCL rule like instantiating a schema: - -```python -age = 1 -name = "Alice" - -rule SomeRule: - age > 0, "rule check failure message" - name == "Alice" - -rule1 = SomeRule() # Rule call -rule2 = SomeRule {} # Rule call -``` - -We can use protocol to implement type checking of rule structure: - -```python -# Schema definition -protocol Service: - clusterIp: str - $type: str - -# Schema definition -protocol Volume: - mountPath: [str] - -# Protocol -protocol SomeProtocol: - id: int - env: {str: any} - services: [Service] - volumes: [Volume] - -rule SomeChecker for SomeProtocol: - id > 0, "id must >0" - - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - } - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } - -# Call rule to check with config parameter -SomeChecker { - id = 1 - env = { - MY_ENV = "MY_ENV_VALUE" - } - services = [ - { - type = "ClusterIP" - clusterIP = "NONE" - } - ] - volumes = [ - { - mountPath = "/home/admin" - } - { - mountPath = "/home/myapp" - } - ] -} -``` - -Please note that the combination of `protocol` and `rule` can separate attributes from their constraint definitions. We can define different rules and protocols in different packages and combine them as needed. This is different from check expressions in schema, which can only be combined with schema attributes. - -Besides, the following two ways can be used to achieve the multiplexing of different Rules: - -- Inline Call - -```python -weather = "sunny" -day = "wednesday" - -rule IsSunny: - weather == "sunny" - -rule IsWednesday: - day == "wednesday" - -rule Main: - IsSunny() # Rule inline call - IsWednesday() # Rule inline call - -Main() # Rule call -``` - -- Inherit - -```python -weather = "sunny" -day = "wednesday" - -rule IsSunny: - weather == "sunny" - -rule IsWednesday: - day == "wednesday" - -rule Main(IsSunny, IsWednesday): - id == 1 - -Main() -``` - -We can obtain external data or input from the `option` function and the CLI parameter `-D` for verification: - -- A simple example - -```python -schema Day: - day: str - homework: str - -days: [Day] = option("days") - -rule Main: - filter d in days { - d.day not in ["saturday", "sunday"] and d.homework - } - -Main() -``` - -- A complex example - -```python -data = option("data") -input = option("input") - -rule Allow: - UserIsAdmin() - any grant in UserIsGranted() { - input.action == grant.action and input.type == grant.type - } - -rule UserIsAdmin: - any user in data.user_roles[input.user] { - user == "admin" - } - -rule UserIsGranted: - [ - grant - for role in data.user_roles[input.user] - for grant in data.role_grants[role] - ] - -allow = Allow() or False -``` - -Further, the above KCL rule code can be compiled into a target such as WASM and used at runtime. - -### Module - -KCL config files are organized as **modules**. A single KCL file is considered as a module, and a directory is considered as a package, which is a special module. - -The modules in the same package are visible and cross-package references need to be visible through import. - -Code structure: - -```bash -. -└── root - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -model1.k: - -```python -# schema CatalogItem in model1.k - -schema CatalogItem: - id: int - image: CatalogItemImage # CatalogItemImage is defined in the module of the same package e.g., model2.k in package model - title: str -``` - -service1.k: - -```python -import ..model as model # cross-package references - -schema ImageService: - image: model.CatalogItemImage # CatalogItemImage is imported from another package e.g., model2.k in package model - name: str -``` - -#### Relative Path Import - -We can use the operator `.` to realize the relative path import of KCL entry files. - -main.k: - -```python -import .model1 # Current directory module -import ..service # Parent directory -import ...root # Parent of parent directory - -s = service.ImageService {} -m = root.Schema {} -``` - -#### Absolute Path Import - -The semantics of `import a.b.c.d` is - -1. If `kcl.mod` not exist, regard the current directory as the package root and search the path `a/b/c/d` from the current directory. -2. If the current directory search fails, search from the root path `ROOT_PATH/a/b/c/d`, else raise an import error. - -The definition of the root path `ROOT_PATH` is the directory corresponding to the `kcl.mod` file from the current directory. - -Code structure: - -```bash -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -main.k: - -```python -import service # `root package` and `kcl.mod` are in the same directory -import mixin # `root package` and `kcl.mod` are in the same directory - -myModel = model.CatalogItem {} -``` - -Note that for the KCL entry file `main.k`, it cannot be imported into the folder where it is located, otherwise a recursive import error will occur: - -```python -import model # Error: recursively loading -``` - -### Top-Level Argument - -Assume some field need to be passed in dynamically like user input, we can define a top-level argument in a module: - -```python -bankCard = option("bankCard") # Get bankCard through the option function. -``` - -Then we can use the module as below: - -```bash -kcl employee.k -D bankCard=123 -``` - -Currently, supported types of top-level argument are number, string, bool, list and dict. - -```bash -kcl main.k -D list_key='[1,2,3]' -D dict_key='{"key":"value"}' -``` - -We need to pay attention to the escape of quotation marks `"` and other symbols in the command line - -#### Arguments with Setting Files - -In addition, it also supports inputting a YAML file as top-level arguments. - -```yaml -kcl_options: - - key: key_number - value: 1 - - key: key_dict - value: - innerDictKey: innerDictValue - - key: key_list - value: - - 1 - - 2 - - 3 - - key: bankCard - value: 123 -``` - -```bash -kcl -Y setting.yaml employee.k -``` - -In addition, the setting file also supports configuring command-line compilation parameters as follows: - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - disable_none: true - strict_range_check: true - debug: 1 - verbose: 1 - sort_keys: true - output: ./stdout.golden - overrides: - - app.image=new_image - path_selector: - - config - package_maps: - k8s: /Users/.kcl/kpm/k8s_1.24 -kcl_options: - - key: image - value: docker.io/kcllang/kcl:latest -``` - -KCL CLI -Y parameters also support multi-file configuration, and support separate writing and merging of compilation parameters and option top level arguments parameter configuration. - -```bash -kcl -Y compile_setting.yaml option_setting.yaml -``` - -- `compile_setting.yaml` - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - disable_none: true - strict_range_check: true - debug: 1 - verbose: 1 - output: ./stdout.golden -``` - -- `option_setting.yaml` - -```yaml -kcl_options: - - key: image - value: docker.io/kcllang/kcl:latest -``` - -We can use the following command line to get the meaning of each configuration parameter or see KCL Quick Start - -```bash -kcl --help -``` - -#### Option Functions - -We can use the `option` function in the KCL code to get the top-level arguments. - -```python -value = option(key="key", type='str', default="default_value", required=True, help="Set key value") -``` - -Parameters - -- **key**: The argument key. -- **type**: The argument type to be converted. -- **default**: The argument default value when the key-value argument is not provided -- **required**: Report an error when the key-value argument is not provided and required is True. -- **help**: The help message. - -### Multi-file Compilation - -In addition to the above KCL single file execution, we can compile multiple KCL entry files at the same time using the following command: - -```bash -kcl main_1.k main_2.k ... main_n.k -``` - -main_1.k - -```python -a = 1 -b = 2 -``` - -main_2.k - -```python -c = 3 -d = 4 -``` - -The output is: - -```yaml -a: 1 -b: 2 -c: 3 -d: 4 -``` - -Taking advantage of the **multi-file combination**, we can assemble multiple KCL files without the need to use import management files. Let us see an example of combining **multi-file compilation** and **schema instance**. - -model.k - -```python -schema Model: - name: str - labels?: {str:} - annotations?: {str:} - replicas: int - -_model1 = Model { - name = "model1" - labels.key1 = "value1" - labels.key2 = "value2" - annotations.key = "value" - replicas = 2 -} - -_model2 = Model { - name = "model2" - replicas = 3 -} -``` - -backend.k - -```python -import yaml - -schema Backend: - apiVersion: str = "v1" - kind: str = "Deployment" - metadata: {str:} - spec: {str:} = { - minReadySeconds = 0 - paused = False - progressDeadlineSeconds = 600 - replicas = 1 - revisionHistoryLimit = 10 - selector = {} - } - -_backends = [Backend { - metadata.name = model.name - metadata.labels = model.labels - metadata.annotations = model.annotations - spec.selector.matchLabels: model.labels - spec.replicas = model.replicas -} for model in Model.instances()] # Schema Model is defined in model.k -print("---\n".join([yaml.encode(_b, ignore_private=True) for _b in _backends])) -``` - -The command is - -```bash -kcl model.k backend.k -``` - -The output is - -```yaml -apiVersion: v1 -kind: Deployment -metadata: - name: model1 - labels: - key1: value1 - key2: value2 - annotations: - key: value -spec: - minReadySeconds: 0 - paused: false - progressDeadlineSeconds: 600 - replicas: 2 - revisionHistoryLimit: 10 - selector: - matchLabels: - key1: value1 - key2: value2 ---- -apiVersion: v1 -kind: Deployment -metadata: - name: model2 -spec: - minReadySeconds: 0 - paused: false - progressDeadlineSeconds: 600 - replicas: 3 - revisionHistoryLimit: 10 - selector: {} -``` - -### KCL CLI Path Selector - -We can use KCL CLI `-S|--path-selector` parameter to select one or more values out of a KCL model. - -The path selector looks like this: - -`var.name` - -#### Examples - -Code structure: - -```bash -. -├── kcl.mod -└── main.k - └── pkg - └── model.k -``` - -pkg/model.k: - -```python -schema Person: - name: str - age: int - -var = Person { - name = "Alice" - age = 18 -} -``` - -main.k - -```python -import pkg - -var = pkg.Person { - name = "Bob" - age = 10 -} -``` - -The command is - -```bash -kcl main.k -S var -``` - -The output is - -```yaml -name: Alice -age: 18 -``` - -### KCL CLI Variable Override - -In addition to **Variable Selector**, KCL also allows us to directly modify the values in the configuration model through the KCL CLI `-O|--overrides` parameter. - -The use of **Variable Override** is similar to [**Variable Selector**](#variable-selector), and the parameter contains three parts e.g., `pkg`, `identifier`, `attribute` and `override_value`. - -```bash -kcl main.k -O override_spec -``` - -- `override_spec` represents a unified representation of the configuration model fields and values that need to be modified - -```txt -override_spec: [[pkgpath] ":"] identifier ("=" value | "-") -``` - -- `pkgpath`: Indicates the path of the package whose identifier needs to be modified, usually in the form of `a.b.c`. For the main package, `pkgpath` is expressed as `__main__`, which can be omitted. If omitted, it means the main package. -- `identifier`: Indicates the identifier that needs to modify the configuration, usually in the form of `a.b.c`. -- `value`: Indicates the value of the configuration that needs to be modified, which can be any legal KCL expression, such as number/string literal value, list/dict/schema expression, etc. -- `=`: means to modify the value of identifier. - - When the identifier exists, modify the value of the existing identifier to value. - - When identifier does not exist, add the identifier attribute and set its value to value. -- `-`: means to delete the identifier attribute. - - When the identifier exists, delete it directly. - - When the identifier does not exist, no modification is made to the configuration. - -Note: When `identifier` appears multiple times, modify/delete all `identifier` values - -#### Examples - -##### Override Update Sample - -KCL code: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -``` - -The command is - -```bash -kcl main.k -O :person.name=\"Bob\" -O :person.age=10 -``` - -The output is - -```yaml -person: - name: Bob - age: 10 -``` - -Besides, when we use KCL CLI `-d` argument, the KCL file will be modified to the following content at the same time - -```bash -kcl main.k -O :person.name=\"Bob\" -O :person.age=10 -d -``` - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Bob" - age = 10 -} -``` - -Another more complicated example: - -```python -schema Person: - name: str - age: int - ids?: [int] - -person = Person { - name = "Alice" - age = 10 -} -``` - -The command is - -```bash -kcl main.k -O :person.ids=\[1,2\] -``` - -The output is - -```yaml -person: - name: Alice - age: 10 - ids: - - 1 - - 2 -``` - -##### Override Delete Sample - -KCL code: - -```python -schema Config: - x?: int = 1 - y?: str = "s" - -config = Config { - x = 2 -} -``` - -The command is - -```bash -kcl main.k -O config.x- -``` - -The output is - -```yaml -config: - x: 1 - y: s -``` - -### Summary - -This page summarized the commonly used features in the KCL language. As a new language, KCL will gradually increase the functional features according to the requirements of the configuration scenario. - -For more information, please try further resources: - -- KCL codelabs -- KCL language specification -- KCL OpenAPI specification diff --git a/versioned_docs/version-0.5.1/reference/model/datetime.md b/versioned_docs/version-0.5.1/reference/model/datetime.md deleted file mode 100644 index 5b829890..00000000 --- a/versioned_docs/version-0.5.1/reference/model/datetime.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: "datetime" -linkTitle: "datetime" -type: "docs" -description: datetime system module -weight: 100 ---- - -## time - -`ticks() -> float` - -Return the current time in seconds since the Epoch. Fractions of a second may be present if the system clock provides them. - -## date - -`date() -> str` - -Return the `%Y-%m-%d %H:%M:%S` format date. - -## now - -`now() -> str` - -Return the local time. e.g. `'Sat Jun 06 16:26:11 1998'` - -## today - -`today() -> str` - -Return the `%Y-%m-%d %H:%M:%S.%{ticks}` format date. diff --git a/versioned_docs/version-0.5.1/reference/model/json.md b/versioned_docs/version-0.5.1/reference/model/json.md deleted file mode 100644 index 44ec8c73..00000000 --- a/versioned_docs/version-0.5.1/reference/model/json.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: "json" -linkTitle: "json" -type: "docs" -description: json system module -weight: 100 ---- - -## encode - -``` -encode( - data: any, - sort_keys: bool = False, - indent: int = None, - ignore_private: bool = False, - ignore_none: bool = False -) -> str -``` - -Serialize a KCL object `data` to a JSON formatted str. - -## decode - -`decode(value: str) -> any` - -Deserialize `value` (a string instance containing a JSON document) to a KCL object. - -## dump_to_file - -``` -dump_to_file( - data: any, - filename: str, - ignore_private: bool = False, - ignore_none: bool = False -) -> None -``` - -Serialize a KCL object `data` to a JSON formatted str and write it into the file `filename`. diff --git a/versioned_docs/version-0.5.1/reference/model/math.md b/versioned_docs/version-0.5.1/reference/model/math.md deleted file mode 100644 index dae369af..00000000 --- a/versioned_docs/version-0.5.1/reference/model/math.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: "math" -linkTitle: "math" -type: "docs" -description: math system module -weight: 100 ---- - -## ceil - -`ceil(x) -> int` - -Return the ceiling of `x` as an Integral. This is the smallest integer >= x. - -## factorial - -`factorial(x) -> int` - -Return `x!`. Raise a error if `x` is negative or non-integral. - -## floor - -`floor(x) -> int` - -Return the floor of `x` as an Integral. This is the largest integer <= x. - -## gcd - -`gcd(a: int, b: int) -> int` - -Return the greatest common divisor of `x` and `y` - -## isfinite - -`isfinite(x) -> bool` - -Return `True` if `x` is neither an infinity nor a `NaN`, and `False` otherwise. - -## isinf - -`isinf(x) -> bool` - -Return `True` if `x` is a positive or negative infinity, and `False` otherwise. - -## isnan - -`isnan(x) -> bool` - -Return `True` if `x` is a `NaN` (not a number), and `False` otherwise. - -## modf - -`modf(x) -> List[float, float]` - -Return the fractional and integer parts of `x`. Both results carry the sign of `x` and are floats. - -## exp - -`exp(x) -> float` - -Return `e` raised to the power of `x`. - -## expm1 - -`expm1(x) -> float` - -Return `exp(x) - 1`. This function avoids the loss of precision involved in the direct evaluation of `exp(x) - 1` for small `x`. - -## log - -`log(x, base=2.71828182845904523536028747135266250) -> float` - -Return the logarithm of `x` to the base `e`. - -## log1p - -`log1p(x) -> float` - -Return the natural logarithm of `1+x` (base `e`). The result is computed in a way which is accurate for `x` near zero. - -## log2 - -`log2(x) -> float` -Return the base 2 logarithm of `x`. - -## log10 - -`log10(x) -> float` - -Return the base 10 logarithm of `x`. - -## pow - -`pow(x, y) -> float` - -Return `x**y` (`x` to the power of `y`). - -## sqrt - -`sqrt(x) -> float` - -Return the square root of `x`. diff --git a/versioned_docs/version-0.5.1/reference/plugin/project_context.md b/versioned_docs/version-0.5.1/reference/plugin/project_context.md deleted file mode 100644 index 0be02e78..00000000 --- a/versioned_docs/version-0.5.1/reference/plugin/project_context.md +++ /dev/null @@ -1,59 +0,0 @@ -# project_context - -project_context extract base info from project.yaml&stack.yaml - -_version: 0.0.1_ - -## `get_project_current_path` - -return the relative path of first file - -Example: - -```py -import kcl_plugin.project_context as ctx - -path = ctx.get_project_current_path() -print(path) -``` - -## `get_project_input_file` - -return compiling file list - -Example: - -```py -import kcl_plugin.project_context as ctx - -input_file = ctx.get_project_input_file() -print(input_file) -``` - -## `get_project_context` - -return the current project context from project.yaml - -Example: - -```py -import kcl_plugin.project_context as ctx - -project = ctx.get_project_context() -# Get project name -print(project?.name) -``` - -## `get_stack_context` - -return the current stack context from stack.yaml - -Example: - -```py -import kcl_plugin.project_context as ctx - -stack = ctx.get_stack_context() -# Get stack name -print(stack?.name) -``` diff --git a/versioned_docs/version-0.5.1/reference/xlang-api/go-api.md b/versioned_docs/version-0.5.1/reference/xlang-api/go-api.md deleted file mode 100644 index 2a978250..00000000 --- a/versioned_docs/version-0.5.1/reference/xlang-api/go-api.md +++ /dev/null @@ -1,665 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Go API - -```go -import kcl "kcl-lang.io/kcl-go" -``` - -## KCL Go SDK - -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ kcl files │ │ KCL-Go-API │ │ KCLResultList │ -│ ┌───────────┐ │ │ │ │ │ -│ │ 1.k │ │ │ │ │ │ -│ └───────────┘ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ ┌───────────┐ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.Get("a.b.c") │ -│ │ 2.k │ │ │ │ Run(path) │ │ │ └───────────┘ │ └───────────────┘ -│ └───────────┘ │────┐ │ └───────────┘ │ │ │ -│ ┌───────────┐ │ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ │ 3.k │ │ │ │ │ │ │ KCLResult │──┼────────▶│x.Get("k", &v) │ -│ └───────────┘ │ │ │ │ │ └───────────┘ │ └───────────────┘ -│ ┌───────────┐ │ ├───▶│ ┌───────────┐ │──────────▶│ │ -│ │setting.yml│ │ │ │ │RunFiles() │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ └───────────┘ │ │ │ └───────────┘ │ │ │ KCLResult │──┼────────▶│x.JSONString() │ -└─────────────────┘ │ │ │ │ └───────────┘ │ └───────────────┘ - │ │ │ │ │ -┌─────────────────┐ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ Options │ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.YAMLString() │ -│WithOptions │ │ │ │MustRun() │ │ │ └───────────┘ │ └───────────────┘ -│WithOverrides │────┘ │ └───────────┘ │ │ │ -│WithWorkDir │ │ │ │ │ -│WithDisableNone │ │ │ │ │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ -``` - -
Example -

- -```go -{ - const k_code = ` -name = "kcl" -age = 1 - -two = 2 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {} -x1 = Person { - age = 101 -} -` - - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First().YAMLString() - fmt.Println(yaml) - - fmt.Println("----") - - result := kcl.MustRun("./testdata/main.k").First() - fmt.Println(result.JSONString()) - - fmt.Println("----") - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - - fmt.Println("----") - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x1", &person)) -} -``` - -

-
- -## Index - -- [Go API](#go-api) - - [KCL Go SDK](#kcl-go-sdk) - - [Index](#index) - - [Constants](#constants) - - [func FormatCode](#func-formatcode) - - [func FormatPath](#func-formatpath) - - [func InitKclvmPath](#func-initkclvmpath) - - [func InitKclvmRuntime](#func-initkclvmruntime) - - [func LintPath](#func-lintpath) - - [func ListDepFiles](#func-listdepfiles) - - [func ListDownStreamFiles](#func-listdownstreamfiles) - - [func ListUpStreamFiles](#func-listupstreamfiles) - - [func OverrideFile](#func-overridefile) - - [func ValidateCode](#func-validatecode) - - [type KCLResult](#type-kclresult) - - [type KCLResultList](#type-kclresultlist) - - [func MustRun](#func-mustrun) - - [func Run](#func-run) - - [func RunFiles](#func-runfiles) - - [type KclType](#type-kcltype) - - [func GetSchemaType](#func-getschematype) - - [type ListDepFilesOption](#type-listdepfilesoption) - - [type ListDepsOptions](#type-listdepsoptions) - - [type Option](#type-option) - - [func WithCode](#func-withcode) - - [func WithDisableNone](#func-withdisablenone) - - [func WithKFilenames](#func-withkfilenames) - - [func WithOptions](#func-withoptions) - - [func WithOverrides](#func-withoverrides) - - [func WithPrintOverridesAST](#func-withprintoverridesast) - - [func WithSettings](#func-withsettings) - - [func WithSortKeys](#func-withsortkeys) - - [func WithWorkDir](#func-withworkdir) - - [type ValidateOptions](#type-validateoptions) - -## Constants - -KclvmAbiVersion is the current kclvm ABI version. - -```go -const KclvmAbiVersion = scripts.KclvmAbiVersion -``` - -## func [FormatCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L110) - -```go -func FormatCode(code interface{}) ([]byte, error) -``` - -FormatCode returns the formatted code. - -
Example -

- -```go -{ - out, err := kcl.FormatCode(`a = 1+2`) - if err != nil { - log.Fatal(err) - } - fmt.Println(string(out)) - -} -``` - -``` -a = 1 + 2 -``` - -

-
- -## func [FormatPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L122) - -```go -func FormatPath(path string) (changedPaths []string, err error) -``` - -FormatPath formats files from the given path path: if path is \`.\` or empty string, all KCL files in current directory will be formatted, not recursively if path is \`path/file.k\`, the specified KCL file will be formatted if path is \`path/to/dir\`, all KCL files in the specified dir will be formatted, not recursively if path is \`path/to/dir/...\`, all KCL files in the specified dir will be formatted recursively - -the returned changedPaths are the changed file paths \(relative path\) - -
Example -

- -```go -{ - changedPaths, err := kcl.FormatPath("testdata/fmt") - if err != nil { - log.Fatal(err) - } - fmt.Println(changedPaths) -} -``` - -

-
- -## func [InitKclvmPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L54) - -```go -func InitKclvmPath(kclvmRoot string) -``` - -InitKclvmPath init kclvm path. - -## func [InitKclvmRuntime](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L59) - -```go -func InitKclvmRuntime(n int) -``` - -InitKclvmRuntime init kclvm process. - -## func [LintPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L142) - -```go -func LintPath(paths []string) (results []string, err error) -``` - -LintPath lint files from the given path - -
Example -

- -```go -{ - - results, err := kcl.LintPath([]string{"testdata/lint/import.k"}) - if err != nil { - log.Fatal(err) - } - for _, s := range results { - fmt.Println(s) - } - -} -``` - -``` -Module 'a' is reimported multiple times -Module 'a' imported but unused -``` - -

-
- -## func [ListDepFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L127) - -```go -func ListDepFiles(workDir string, opt *ListDepFilesOption) (files []string, err error) -``` - -ListDepFiles return the depend files from the given path - -## func [ListDownStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L137) - -```go -func ListDownStreamFiles(workDir string, opt *ListDepsOptions) ([]string, error) -``` - -ListDownStreamFiles return a list of downstream depend files from the given changed path list. - -## func [ListUpStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L132) - -```go -func ListUpStreamFiles(workDir string, opt *ListDepsOptions) (deps []string, err error) -``` - -ListUpStreamFiles return a list of upstream depend files from the given path list - -## func [OverrideFile](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L154) - -```go -func OverrideFile(file string, specs, importPaths []string) (bool, error) -``` - -OverrideFile rewrites a file with override spec file: string. The File that need to be overridden specs: \[\]string. List of specs that need to be overridden. - -``` -Each spec string satisfies the form: := or :- -When the pkgpath is '__main__', it can be omitted. -``` - -importPaths. List of import statements that need to be added - -## func [ValidateCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L159) - -```go -func ValidateCode(data, code string, opt *ValidateOptions) (ok bool, err error) -``` - -ValidateCode validate data match code - -## type [KCLResult](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L47) - -```go -type KCLResult = kcl.KCLResult -``` - -
Example -

- -```go -{ - const k_code = ` -name = "kcl" -age = 1 - -two = 2 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {name = "kcl-go"} -x1 = Person {age = 101} -` - - result := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First() - - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - -} -``` - -``` -x0.name: kcl-go -x1.age: 101 -``` - -

-
- -
Example ('et_struct) -

- -```go -{ - const k_code = ` -schema Person: - name: str = "kcl" - age: int = 1 - X: int = 2 - -x = { - "a": Person {age = 101} - "b": 123 -} -` - - result := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First() - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x.a", &person)) - fmt.Printf("person: %+v\n", person) - -} -``` - -``` -person: &{Name:kcl Age:101} -person: {Name:kcl Age:101} -``` - -

-
- -## type [KCLResultList](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L48) - -```go -type KCLResultList = kcl.KCLResultList -``` - -### func [MustRun](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L64) - -```go -func MustRun(path string, opts ...Option) *KCLResultList -``` - -MustRun is like Run but panics if return any error. - -
Example -

- -```go -{ - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(`name = "kcl"`)).First().YAMLString() - fmt.Println(yaml) - -} -``` - -``` -name: kcl -``` - -

-
- -
Example (Raw Yaml) -

- -```go -{ - const code = ` -b = 1 -a = 2 -` - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(code)).GetRawYamlResult() - fmt.Println(yaml) - - yaml_sorted := kcl.MustRun("testdata/main.k", kcl.WithCode(code), kcl.WithSortKeys(true)).GetRawYamlResult() - fmt.Println(yaml_sorted) - -} -``` - -``` -b: 1 -a: 2 -a: 2 -b: 1 -``` - -

-
- -
Example (Schema Type) -

- -```go -{ - const code = ` -schema Person: - name: str = "" - -x = Person() -` - json := kcl.MustRun("testdata/main.k", kcl.WithCode(code)).First().JSONString() - fmt.Println(json) - -} -``` - -``` -{ - "x": { - "name": "" - } -} -``` - -

-
- -
Example (Settings) -

- -```go -{ - yaml := kcl.MustRun("./testdata/app0/kcl.yaml").First().YAMLString() - fmt.Println(yaml) -} -``` - -

-
- -### func [Run](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L69) - -```go -func Run(path string, opts ...Option) (*KCLResultList, error) -``` - -Run evaluates the KCL program with path and opts, then returns the object list. - -
Example (Get Field) -

- -```go -{ - - x, err := kcl.Run("./testdata/app0/kcl.yaml") - assert(err == nil, err) - - fmt.Println(x.First().Get("deploy_topology.1.zone")) - -} -``` - -``` -R000A -``` - -

-
- -### func [RunFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L74) - -```go -func RunFiles(paths []string, opts ...Option) (*KCLResultList, error) -``` - -RunFiles evaluates the KCL program with multi file path and opts, then returns the object list. - -
Example -

- -```go -{ - result, _ := kcl.RunFiles([]string{"./testdata/app0/kcl.yaml"}) - fmt.Println(result.First().YAMLString()) -} -``` - -

-
- -## type [KclType](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L50) - -```go -type KclType = kcl.KclType -``` - -### func [GetSchemaType](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L176) - -```go -func GetSchemaType(file, code, schemaName string) ([]*KclType, error) -``` - -GetSchemaType returns schema types from a kcl file or code. - -file: string - -``` -The kcl filename -``` - -code: string - -``` -The kcl code string -``` - -schema_name: string - -``` -The schema name got, when the schema name is empty, all schemas are returned. -``` - -## type [ListDepFilesOption](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L45) - -```go -type ListDepFilesOption = list.Option -``` - -## type [ListDepsOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L44) - -```go -type ListDepsOptions = list.DepOptions -``` - -## type [Option](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L43) - -```go -type Option = kcl.Option -``` - -### func [WithCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L79) - -```go -func WithCode(codes ...string) Option -``` - -WithCode returns a Option which hold a kcl source code list. - -### func [WithDisableNone](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L97) - -```go -func WithDisableNone(disableNone bool) Option -``` - -WithDisableNone returns a Option which hold a disable none switch. - -### func [WithKFilenames](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L82) - -```go -func WithKFilenames(filenames ...string) Option -``` - -WithKFilenames returns a Option which hold a filenames list. - -### func [WithOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L85) - -```go -func WithOptions(key_value_list ...string) Option -``` - -WithOptions returns a Option which hold a key=value pair list for option function. - -
Example -

- -```go -{ - const code = ` -name = option("name") -age = option("age") -` - x, err := kcl.Run("hello.k", kcl.WithCode(code), - kcl.WithOptions("name=kcl", "age=1"), - ) - if err != nil { - log.Fatal(err) - } - - fmt.Println(x.First().YAMLString()) - -} -``` - -``` -age: 1 -name: kcl -``` - -

-
- -### func [WithOverrides](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L88) - -```go -func WithOverrides(override_list ...string) Option -``` - -WithOverrides returns a Option which hold a override list. - -### func [WithPrintOverridesAST](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L100) - -```go -func WithPrintOverridesAST(printOverridesAST bool) Option -``` - -WithPrintOverridesAST returns a Option which hold a printOverridesAST switch. - -### func [WithSettings](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L91) - -```go -func WithSettings(filename string) Option -``` - -WithSettings returns a Option which hold a settings file. - -### func [WithSortKeys](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L105) - -```go -func WithSortKeys(sortKeys bool) Option -``` - -WithSortKeys returns a Option which hold a sortKeys switch. - -### func [WithWorkDir](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L94) - -```go -func WithWorkDir(workDir string) Option -``` - -WithWorkDir returns a Option which hold a work dir. - -## type [ValidateOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L46) - -```go -type ValidateOptions = validate.ValidateOptions -``` diff --git a/versioned_docs/version-0.5.1/reference/xlang-api/rest-api.md b/versioned_docs/version-0.5.1/reference/xlang-api/rest-api.md deleted file mode 100644 index 4723280f..00000000 --- a/versioned_docs/version-0.5.1/reference/xlang-api/rest-api.md +++ /dev/null @@ -1,443 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Rest API - -## 1. Start REST Service - -The RestAPI service can be started in the following ways: - -```shell -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -or - -```shell -go install kcl-lang.io/kcl-go/cmds/kcl-go@main -kcl-go rest-server -``` - -The service can then be requested via the POST protocol: - -```shell -$ curl -X POST http://127.0.0.1:2021/api:protorpc/BuiltinService.Ping --data '{}' -{ - "error": "", - "result": {} -} -``` - -The POST request and the returned JSON data are consistent with the structure defined by Protobuf. - -## 2. `BuiltinService` - -Where the `/api:protorpc/BuiltinService.Ping` path represents the `Ping` method of the `BuiltinService` service. - -The complete `BuiltinService` is defined by Protobuf: - -```protobuf -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} -``` - -The `Ping` method can verify whether the service is normal, and the `ListMethod` method can query the list of all services and functions provided. - -## 3. `KclvmService` - -The `KclvmService` service is a service related to KCL functionality. The usage is the same as the `BuiltinService` service. - -For example, there is the following `Person` structure definition: - -```python -schema Person: - key: str - - check: - "value" in key # 'key' is required and 'key' must contain "value" -``` - -Then we want to use `Person` to verify the following JSON data: - -```json -{ "key": "value" } -``` - -This can be done through the `ValidateCode` method of the `KclvmService` service. Refer to the `ValidateCode_Args` structure of the `ValidateCode` method: - -```protobuf -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} -``` - -Construct the JSON data required by the POST request according to the `ValidateCode_Args` structure, which contains the `Person` definition and the JSON data to be verified: - -```json -{ - "code": "\nschema Person:\n key: str\n\n check:\n \"value\" in key # 'key' is required and 'key' must contain \"value\"\n", - "data": "{\"key\": \"value\"}" -} -``` - -Save this JSON data to the `vet-hello.json` file and verify it with the following command: - -```shell -$ curl -X POST \ - http://127.0.0.1:2021/api:protorpc/KclvmService.ValidateCode \ - -H "accept: application/json" \ - --data @./vet-hello.json -{ - "error": "", - "result": { - "success": true - } -} -``` - -## 4. Complete Protobuf Service Definition - -Cross-language APIs defined via Protobuf([https://github.com/kcl-lang/kcl-go/blob/main/pkg/spec/gpyrpc/gpyrpc.proto](https://github.com/kcl-lang/kcl-go/blob/main/pkg/spec/gpyrpc/gpyrpc.proto)): - -```protobuf -// Copyright 2023 The KCL Authors. All rights reserved. -// -// This file defines the request parameters and return structure of the KCL RPC server. -// We can use the following command to start a KCL RPC server. - -syntax = "proto3"; - -package gpyrpc; - -import "google/protobuf/any.proto"; -import "google/protobuf/descriptor.proto"; - -// ---------------------------------------------------------------------------- - -// kcl main.k -D name=value -message CmdArgSpec { - string name = 1; - string value = 2; -} - -// kcl main.k -O pkgpath:path.to.field=field_value -message CmdOverrideSpec { - string pkgpath = 1; - string field_path = 2; - string field_value = 3; - string action = 4; -} - -// ---------------------------------------------------------------------------- -// gpyrpc request/response/error types -// ---------------------------------------------------------------------------- - -message RestResponse { - google.protobuf.Any result = 1; - string error = 2; - KclError kcl_err = 3; -} - -message KclError { - string ewcode = 1; // See kclvm/kcl/error/kcl_err_msg.py - string name = 2; - string msg = 3; - repeated KclErrorInfo error_infos = 4; -} - -message KclErrorInfo { - string err_level = 1; - string arg_msg = 2; - string filename = 3; - string src_code = 4; - string line_no = 5; - string col_no = 6; -} - -// ---------------------------------------------------------------------------- -// service requset/response -// ---------------------------------------------------------------------------- - -// gpyrpc.BuiltinService -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -// gpyrpc.KclvmService -service KclvmService { - rpc Ping(Ping_Args) returns(Ping_Result); - - rpc ExecProgram(ExecProgram_Args) returns(ExecProgram_Result); - - rpc FormatCode(FormatCode_Args) returns(FormatCode_Result); - rpc FormatPath(FormatPath_Args) returns(FormatPath_Result); - rpc LintPath(LintPath_Args) returns(LintPath_Result); - rpc OverrideFile(OverrideFile_Args) returns (OverrideFile_Result); - - rpc GetSchemaType(GetSchemaType_Args) returns(GetSchemaType_Result); - rpc GetSchemaTypeMapping(GetSchemaTypeMapping_Args) returns(GetSchemaTypeMapping_Result); - rpc ValidateCode(ValidateCode_Args) returns(ValidateCode_Result); - - rpc ListDepFiles(ListDepFiles_Args) returns(ListDepFiles_Result); - rpc LoadSettingsFiles(LoadSettingsFiles_Args) returns(LoadSettingsFiles_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} - -message ParseFile_AST_Args { - string filename = 1; - string source_code = 2; -} -message ParseFile_AST_Result { - string ast_json = 1; // json value - KclError kcl_err = 2; -} - -message ParseProgram_AST_Args { - repeated string k_filename_list = 1; -} -message ParseProgram_AST_Result { - string ast_json = 1; // json value - KclError kcl_err = 2; -} - -message ExecProgram_Args { - string work_dir = 1; - - repeated string k_filename_list = 2; - repeated string k_code_list = 3; - - repeated CmdArgSpec args = 4; - repeated CmdOverrideSpec overrides = 5; - - bool disable_yaml_result = 6; - - bool print_override_ast = 7; - - // -r --strict-range-check - bool strict_range_check = 8; - - // -n --disable-none - bool disable_none = 9; - // -v --verbose - int32 verbose = 10; - - // -d --debug - int32 debug = 11; - - // yaml/json: sort keys - bool sort_keys = 12; - // include schema type path in JSON/YAML result - bool include_schema_type_path = 13; -} -message ExecProgram_Result { - string json_result = 1; - string yaml_result = 2; - - string escaped_time = 101; -} - -message ResetPlugin_Args { - string plugin_root = 1; -} -message ResetPlugin_Result { - // empty -} - -message FormatCode_Args { - string source = 1; -} - -message FormatCode_Result { - bytes formatted = 1; -} - -message FormatPath_Args { - string path = 1; -} - -message FormatPath_Result { - repeated string changed_paths = 1; -} - -message LintPath_Args { - repeated string paths = 1; -} - -message LintPath_Result { - repeated string results = 1; -} - -message OverrideFile_Args { - string file = 1; - repeated string specs = 2; - repeated string import_paths = 3; -} - -message OverrideFile_Result { - bool result = 1; -} - -message EvalCode_Args { - string code = 1; -} -message EvalCode_Result { - string json_result = 2; -} - -message ResolveCode_Args { - string code = 1; -} - -message ResolveCode_Result { - bool success = 1; -} - -message GetSchemaType_Args { - string file = 1; - string code = 2; - string schema_name = 3; -} -message GetSchemaType_Result { - repeated KclType schema_type_list = 1; -} - -message GetSchemaTypeMapping_Args { - string file = 1; - string code = 2; - string schema_name = 3; -} -message GetSchemaTypeMapping_Result { - map schema_type_mapping = 1; -} - -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} - -message ValidateCode_Result { - bool success = 1; - string err_message = 2; -} - -message Position { - int64 line = 1; - int64 column = 2; - string filename = 3; -} - -message ListDepFiles_Args { - string work_dir = 1; - bool use_abs_path = 2; - bool include_all = 3; - bool use_fast_parser = 4; -} - -message ListDepFiles_Result { - string pkgroot = 1; - string pkgpath = 2; - repeated string files = 3; -} - -// --------------------------------------------------------------------------------- -// LoadSettingsFiles API -// Input work dir and setting files and return the merged kcl singleton config. -// --------------------------------------------------------------------------------- - -message LoadSettingsFiles_Args { - string work_dir = 1; - repeated string files = 2; -} - -message LoadSettingsFiles_Result { - CliConfig kcl_cli_configs = 1; - repeated KeyValuePair kcl_options = 2; -} - -message CliConfig { - repeated string files = 1; - string output = 2; - repeated string overrides = 3; - repeated string path_selector = 4; - bool strict_range_check = 5; - bool disable_none = 6; - int64 verbose = 7; - bool debug = 8; -} - -message KeyValuePair { - string key = 1; - string value = 2; -} - -// ---------------------------------------------------------------------------- -// JSON Schema Lit -// ---------------------------------------------------------------------------- - -message KclType { - string type = 1; // schema, dict, list, str, int, float, bool, any, union, number_multiplier - repeated KclType union_types = 2 ; // union types - string default = 3; // default value - - string schema_name = 4; // schema name - string schema_doc = 5; // schema doc - map properties = 6; // schema properties - repeated string required = 7; // required schema properties, [property_name1, property_name2] - - KclType key = 8; // dict key type - KclType item = 9; // dict/list item type - - int32 line = 10; - - repeated Decorator decorators = 11; // schema decorators -} - -message Decorator { - string name = 1; - repeated string arguments = 2; - map keywords = 3; -} - -// ---------------------------------------------------------------------------- -// END -// ---------------------------------------------------------------------------- -``` diff --git a/versioned_docs/version-0.5.1/tools/Ide/index.md b/versioned_docs/version-0.5.1/tools/Ide/index.md deleted file mode 100644 index aec7245a..00000000 --- a/versioned_docs/version-0.5.1/tools/Ide/index.md +++ /dev/null @@ -1,6 +0,0 @@ -# IDE - -We have provided two simple kinds of plugins for KCL. You can get more help information at the following link: - -- IntelliJ Plugin: https://github.com/kcl-lang/intellij-kcl -- VSCode Plugin: https://github.com/kcl-lang/vscode-kcl diff --git a/versioned_docs/version-0.5.1/tools/Ide/intellij.md b/versioned_docs/version-0.5.1/tools/Ide/intellij.md deleted file mode 100644 index be637514..00000000 --- a/versioned_docs/version-0.5.1/tools/Ide/intellij.md +++ /dev/null @@ -1,3 +0,0 @@ -# IntelliJ IDEA - -- IntelliJ Plugin: https://github.com/kcl-lang/intellij-kcl diff --git a/versioned_docs/version-0.5.1/tools/Ide/vs-code.md b/versioned_docs/version-0.5.1/tools/Ide/vs-code.md deleted file mode 100644 index 6b00815c..00000000 --- a/versioned_docs/version-0.5.1/tools/Ide/vs-code.md +++ /dev/null @@ -1,55 +0,0 @@ -# KCL Extension for Visual Studio Code - -## Quick Start - -- **Step 1.** [Install KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) on your system. Please check that `kcl` and `kcl-language-server` are installed and have been added to your PATH: - - ```bash - which kcl - which kcl-language-server - ``` - -- **Step 2.** Install the [KCL extension](https://marketplace.visualstudio.com/items?itemName=kcl.kcl-vscode-extension) for Visual Studio Code. This extension requires the VS Code 1.50+. -- **Step 3.** Reopen VS Code and create a KCL file and begin your KCL tour! - -## Features - -This extension provides some coding assistance, including the following features: - -- **Syntax Highlight:** - ![Highlight](/img/docs/tools/Ide/vs-code/Highlight.png) -- **Goto Definition:** Goto definition of schema, variable, schema attribute, and import pkg. - ![Goto Definition](/img/docs/tools/Ide/vs-code/GotoDef.gif) -- **Completion:** Keywords completions and dot(`.`) completion. - ![Completion](/img/docs/tools/Ide/vs-code/Completion.gif) -- **Outline:** Main definition(schema def) and variables in KCL file. - ![Outline](/img/docs/tools/Ide/vs-code/Outline.gif) -- **Hover:** Identifier information (type and schema documentation). - ![Hover](/img/docs/tools/Ide/vs-code/Hover.gif) -- **Diagnostics:** Warnings and errors in KCL file. - - > Tips: You can enhance the effect of diagnostics by installing another plugin: [Error Lens](https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens). - - ![Diagnostics](/img/docs/tools/Ide/vs-code/Diagnostics.gif) - -Other useful features such as refactoring and testing are in development. - -## Dependencies - -We recommend that you use the latest version of KCL, but the minimum required version for this extension is 0.4.6. If you are using an earlier version, the extension may not work properly. - -## Known Issues - -See [here](https://github.com/kcl-lang/kcl/issues/524). - -## Ask for help - -If the extension isn't working as you expect, please contact us with [community](https://kcl-lang.io/docs/community/intro/support) for help. - -## Contributing - -We are working actively on improving the KCL development on VS Code. All kinds of contributions are welcomed. You can refer to our [contribution guide](https://kcl-lang.io/docs/community/contribute). It introduces how to build and run the extension locally, and describes the process of sending a contribution. - -## License - -Apache License 2.0 diff --git a/versioned_docs/version-0.5.1/tools/cli/kcl/fmt.md b/versioned_docs/version-0.5.1/tools/cli/kcl/fmt.md deleted file mode 100644 index eaf562cd..00000000 --- a/versioned_docs/version-0.5.1/tools/cli/kcl/fmt.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Format - -The KCL Format tool supports reformatting KCL files to the standard code style. This article demonstrates the KCL code style and how to use the KCL Format tool. - -## Code Style - -The KCL Format tool modifies the files according to the KCL code style: [Style Guide for KCL Code](/docs/reference/lang/spec/codestyle) - -## How to use - -- Formatting Single File - -```text -kcl-fmt your_config.k -``` - -- Formatting multiple files - -```text -kcl-fmt your_config_path -R -``` - -- Args - - `-R|--recursive` Whether to recursively traverse subfolders - - `-w|--fmt-output` Whether to output to STDOUT, without `-w` indicates in-place modification. - -## Display of formatting files - -- Before formatting - -```py -import math -mixin DeploymentMixin: - service:str ="my-service" -schema DeploymentBase: - name: str - image : str -schema Deployment[replicas] ( DeploymentBase ) : - mixin[DeploymentMixin] - replicas : int = replicas - command: [str ] - labels: {str: str} -deploy = Deployment(replicas = 3){} -``` - -- After formatting - -```py -import math - -mixin DeploymentMixin: - service: str = "my-service" - -schema DeploymentBase: - name: str - image: str - -schema Deployment[replicas](DeploymentBase): - mixin [DeploymentMixin] - replicas: int = replicas - command: [str] - labels: {str:str} - -deploy = Deployment(replicas=3) {} - -``` diff --git a/versioned_docs/version-0.5.1/tools/cli/kcl/lint.md b/versioned_docs/version-0.5.1/tools/cli/kcl/lint.md deleted file mode 100644 index 627177a9..00000000 --- a/versioned_docs/version-0.5.1/tools/cli/kcl/lint.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Lint - -The KCL Lint tool supports checking some warning-level defects in KCL code and supports multiple output formats. This document shows how to use the KCL Lint tool. - -## Example - -### Project Struct - -```text -. -└── Test - └── kcl.mod - └── a.k - └── b.k - └── dir - └── c.k - └── test.k -``` - -`a.k`, `b.k`, `c.k` and `test.k` are the kcl file to be checked. - -Args: - -```shell -kcl-lint your_config.k -``` - -or - -```shell -kcl-lint your_config_path -``` - -## KCL Lint Tool - -### Args - -```shell -USAGE: - kcl-lint [OPTIONS] [--] [input]... - -ARGS: - ... Sets the input file to use - -OPTIONS: - --emit_warning Emit warning message - -h, --help Print help information - -v, --verbose Print test information verbosely - -Y, --setting ... Sets the input file to use -``` - -- input: the path of a single `*.k` file or directory to be checked. Support the absolute path or relative path of the current directory. diff --git a/versioned_docs/version-0.5.1/tools/cli/openapi/quick-start.md b/versioned_docs/version-0.5.1/tools/cli/openapi/quick-start.md deleted file mode 100644 index d5812e3a..00000000 --- a/versioned_docs/version-0.5.1/tools/cli/openapi/quick-start.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Quick Start - -## 1. Install KCLOpenAPI Tool - -The kcl-openapi tool can be installed in following ways: - -- [go install](#11-go-install) -- [curl|sh install (MacOS & Linux)](#12-curlsh-install-macos--linux) -- [download from release](#13-dowload-from-release) - -## 1.1 go install - -```shell -go install kcl-lang.io/kcl-openapi@latest -``` - -## 1.2 Curl|sh install (MacOS & Linux) - -If you don't have go, you can install the CLI with this one-liner: - -```shell -curl -fsSL https://kcl-lang.io/script/install-kcl-openapi.sh | /bin/bash -``` - -## 1.3 Download from release - -```shell -# 1. download the released binary from: -# https://github.com/kcl-lang/kcl-openapi/releases - -# 2. Unzip the package and add the binary location to PATH -export PATH=":$PATH" -``` - -## 1.4 Verify your installation - -```shell -➜ kcl-openapi -v -kcl-openapi 0.5.0 -``` - -## 2. Generate KCL Files - -- [OpenAPI to KCL](../openapi/openapi-to-kcl.md) -- [CRD to KCL](../openapi/crd-to-kcl.md) diff --git a/versioned_docs/version-0.5.1/tools/cli/openapi/spec.md b/versioned_docs/version-0.5.1/tools/cli/openapi/spec.md deleted file mode 100644 index 7a144e4c..00000000 --- a/versioned_docs/version-0.5.1/tools/cli/openapi/spec.md +++ /dev/null @@ -1,438 +0,0 @@ -# KCL OpenAPI Spec - -[OpenAPI](https://www.openapis.org/) defines the API Specification for API providers to describe their operations and models in a normative way and provides generating tools to automatically convert to client codes in specific languages. - -The KCL OpenAPI Spec describes the rules about how the OpenAPI definitions are translated to the KCL schemas. - -## The File Structure of the KCL OpenAPI - -According to the OpenAPI 3.0 specification, an OpenAPI file should at least contains four root objects: `openapi`, `components`, `info`, `paths`. The KCL OpenAPI focuses on the part in which the models are defined in the `definitions` object. Yet the `paths` part which describes the Restful API operations is not considered by the KCL OpenAPI Spec. - -:::info -Note: In addition to the objects listed above, the OpenAPI spec also supports `servers`, `security`, `tags`, and `externalDocs` as optional root objects, but none of them are concerned by KCL OpenAPI when generating model codes, so we do not need to fill in this section. Yet it won't make any difference if you do. -::: - -To put it more comprehensible for beginners, let's take a quick look at the root objects that forms the typical KCL OpenAPI file (snippets from swagger example [Petstore](https://petstore.swagger.io/). The KCL OpenAPI tool only focuses on the `definitions` object which describes two data models (`Pet` and `Category`), and the model `Pet` contains three attributes: `name`, `id`, and `category`) - -## KCL schema - -The KCL schema structure defines the "type" of configuration data. - -:::info -More information about KCL schema, see [KCL Language Tour#Schema](../../../reference/lang/tour.md) -::: - -In the OpenAPI spec, a KCL schema can be defined by adding a `definition` element within the `definitions` object. - -Example: -The following example defines two schemas in KCL: `Pet` and `Category`, followed by the corresponding data models defined in OpenAPI: - -```python -# KCL schema -schema Pet: - name: str - id?: int - category?: Category - -schema Category: - name?: str - -# The corresponding OpenAPI spec -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "id": { - "type": "integer", - "format": "int64" - }, - "category": { - "$ref": "#/definitions/Category" - } - }, - "required": [ - "name" - ] - }, - "Category": { - "type": "object", - "properties": { - "name": { - "type": "string" - } - } - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### Schema Name - -In KCL, the schema name is declared immediately after the schema keyword, and in OpenAPI, the name of the model is defined by the key of the definition element. - -### Schema Type - -The type of KCL schema in OpenAPI is always "object". As in the previous example, the value of the `type` object in `Pet` should be `object`. - -### Schema Attribute - -Zero or more attributes can be defined in the KCL schema. The declaration of attributes generally includes the following parts: - -- Attribute annotation: Optional, starting with `@`, such as `@deprecated` to indicate a deprecated attribute -- Attribute name: Required -- Attribute optional modifiers(`?`): Optional. A question mark indicates that the current attribute is optional and may not be assigned. Conversely, the absence of a question mark indicates a required attribute -- Attribute type: Required. The attribute can be a primitive data type, a schema type, or a combination of the two preceding types -- Attribute default value: Optional - -The mapping between them and the OpenAPI spec is as follows: - -| Elements of KCL Schema Attribute | Corresponding Elements in OpenAPI | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| attribute annotation | Not supported. We are planning to add an extension `deprecate` field to the KCL-OpenAPI | -| attribute name | The key of the property under the `property` object | -| attribute optional modifiers(`?`) | In each element in the `definition` object, here's an optional `required` field which lists the all the required attributes of that model, and the attributes not listed are optional | -| attribute type | The basic types can be declared by a combination of `type` and `format`, and the schema type is declared by a `$ref` to the schema definition. KCL-OpenAPI spec adds a `x-kcl-types` extension to indicate a type union. `enum` indicates a union of several literal types. For the type declaration in KCL-OpenAPI, see the chapter - [basic data types](#basic-data-types) | -| attribute default value | The value of the `default` field is used to set the default value for the attribute | - -Example: - -The following KCL code defines a Pet model which contains two attributes: name (`string` type, `required`, with no attribute annotation and no default value) and id (`int64` type, optional, with no attribute annotation, and the default value is -1). - -```python -# the KCL schema Pet defines two attributes: name, id -schema Pet: - name: str - id?: int = -1 - -# The corresponding OpenAPI spec -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - "id": { - "type": "integer", - "format": "int64", - "default": -1 - } - }, - "required": [ - "name" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### Schema Index Signature - -In the KCL schema, the index signatures can be used to define attributes with undefined attribute names. The KCL schema index signature contains the following elements: - -- Type of the key in the index signature: Declared in square brackets. It must be the basic type -- Type of value in the index signature: Declared after the colon in the square brackets. It can be any valid KCL type -- Ellipses(`...`) in the index signature: In the square brackets, before the type declaration of the key. It indicates that the index signature is only used to constrain attributes not defined in the schema. The absentation of the symbol indicates that all defined and undefined attributes in the schema are constrained by the index signature. -- Alias for key in index signature: Declared in square brackets, immediately after the left square bracket and takes the form of `:`. The alias can then be used to reference the index signature by name -- The default value of the index signature: Assign a value to the index signature as the default value - -The index signature with its key in `string` type can be described based on the field `additionalProperties`. Other index signatures with a key in types besides `string`, and the `check` expressions used to validate the index signature are not supported by the KCL OpenAPI spec. - -The mapping between them and the OpenAPI spec is as follows: - -| Elements of KCL Index Signature | Corresponding Elements in OpenAPI | -| -------------------------------------------- | ----------------------------------------------------------------------------------------------- | -| Type of the key in the KCL index signature | Only string type is allowed in OpenAPI | -| Type of the value in the KCL index signature | Declared by the `type` in the `additionalProperties` field | -| Ellipses(`...`) in the index signature | Only the corresponding meaning of the attendance of the `...` symbol is allowed in OpenAPI | -| Alias for key in index signature | Not supported in KCL-OpenAPI yet. We are planning to add an `x-alias` extension to support that | -| Default value of the index signature | Not supported in KCL-OpenAPI | - -Example: - -The following KCL code defines a Pet model which contains two pre-declared attributes(`name` and `id`) and allows users to add attributes with `string` type keys and `bool` type values. - -```python -# the KCL schema Pet. Besides the pre-declared attributes name and id, it allows to add attributes with key in string type and value in bool type -schema Pet: - name: str - id?: int - [...str]: bool - -# The corresponding OpenAPI spec -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - "id": { - "type": "integer", - "format": "int64", - } - }, - "additionalProperties": { - "type": "bool" - }, - "required": [ - "name" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### Schema Inherit - -working in progress - -### Inline schema - -OpenAPI supports models to be declared inline. But KCL currently does not support that. The model defined inline in OpenAPI will be converted to a schema with a name in KCL. And the naming convention will be: - -| element to define an inline schema in OpenAPI | the name of the corresponding KCL schema | -| --------------------------------------------- | -------------------------------------------------------------- | -| inline Property | add the Property name at the end of the outer schema Name | -| AdditionalProperties | add "AdditionalProperties" at the end of the outer schema Name | - -We are planning to support inline schema in KCL, and when supported, the naming convention will be updated then. - -Example-1: - -The following KCL code defines a `Deployment` model which contains two attributes(`kind` and `spec`). And the schema of the `spec` attribute is defined inline. - -```python -# The OpenAPI spec -{ - "definitions": { - "Deployment": { - "type": "object", - "properties": { - "kind": { - "type": "string", - }, - "spec": { - "type": "object", - "properties": { - "replicas": { - "type": "integer", - "format": "int64" - } - } - } - }, - "required": [ - "kind", - "spec" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -# The corresponding KCL schemas -schema Deployment: - kind: str - spec: DeploymentSpec - -schema DeploymentSpec: - replicas?: int -``` - -Example-2: - -The following KCL code defines a Person model which contains a pre-declared attribute(`name`) and allows some `additionalProperties` to be assigned by user. And the type of the values in the `additionalProperties` is defined inline. - -```python -# The OpenAPI spec -{ - "definitions": { - "Person": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - }, - "required": [ - "name", - "spec" - ], - "additionalProperties": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "description": { - "type": "string" - } - }, - "required": [ - "name" - ] - }, - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -# The corresponding KCL schemas -schema Person: - name: str - [...str]: [PersonAdditionalProperties] - -schema PersonAdditionalProperties: - name: str - description?: str -``` - -## KCL Doc - -:::info -More information about KCL doc specification, please refer to the [KCL Document Specification](../kcl/docgen.md) -::: - -KCL documents consist of module documents and schema documents. And only the schema documents can be extracted from OpenAPI. The KCL schema document contains four parts: - -- Schema Description: Declared right after the schema declaration and before the schema attribute declaration. It provides an overview of schemas -- Schema Attribute Doc: Declared right after the schema Description and separated by `Attributes` + `---` delimiters. It describes the attribute -- Additional information about the schema: Declared right after the schema attribute doc and separated by `See Also` + `---` delimiters -- Example information about the schema: Declared right after the schema additional information and separated by `Examples` + `---` delimiters - -The mapping between them and the OpenAPI spec is as follows: - -| Elements of KCL Schema Document | Corresponding Elements in OpenAPI | -| --------------------------------------- | ------------------------------------------------------- | -| Schema Description | The value of the `description` field of the data model | -| Schema Attribute Doc | The value of the `description` field of the property | -| Additional information about the schema | The value of the `externalDocs` field of the data model | -| Example information about the schema | The value of the `example` field of the data model | - -Example: - -The following KCL code defines a Pet model with a schema description `The schema Pet definition`, and two attributes `name` and `id` with their attribute doc `The name of the pet` and `The id of the pet`; The additional information about the Pet schema is [here](https://petstore.swagger.io/) and the example to use the Pet schema are provided, too. - -```python -# The KCL schema Pet, with doc following the KCL Document Specification -schema Pet: - """The schema Pet definition - - Attributes - ---------- - name : str, default is Undefined, required - The name of the pet - id : int, default is -1, optional - The age of the pet - - See Also - -------- - Find more info here. https://petstore.swagger.io/ - - Examples - -------- - pet = Pet { - name = "doggie" - id = 123 - } - """ - name: str - id?: int = -1 - -# The corresponding OpenAPI Spec -{ - "definitions": { - "Pet": { - "description": "The schema Pet definition", - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "The name of the pet" - }, - "id": { - "type": "integer", - "format": "int64", - "default": -1, - "description": "The age of the pet" - } - }, - "required": [ - "name" - ], - "externalDocs": { - "description": "Find more info here", - "url": "https://petstore.swagger.io/" - }, - "example": { - "name": "doggie", - "id": 123 - } - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -## Basic Data Types - -| JSON Schema type | swagger type | KCL type | comment | -| ---------------- | --------------------------- | --------------- | --------------------------------------------------------------------------- | -| boolean | boolean | bool | | -| number | number | float | | -| | number format double | **unsupported** | | -| | number format float | float | | -| integer | integer | int (32) | | -| | integer format int64 | **unsupported** | | -| | integer format int32 | int (32) | | -| string | string | str | | -| | string format byte | str | | -| | string format int-or-string | int \| str | | -| | string format binay | str | | -| | string format date | unsupported | As defined by full-date - [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) | -| | string format date-time | unsupported | As defined by date-time - [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) | -| | string format password | unsupported | for swagger: A hint to UIs to obscure input | -| | datetime | datetime | | - -## Reference - -- OpenAPI spec 2.0: [https://swagger.io/specification/v2/](https://swagger.io/specification/v2/) -- OpenAPI spec 3.0: [https://spec.openapis.org/oas/v3.1.0](https://spec.openapis.org/oas/v3.1.0) -- OpenAPI spec 3.0: [https://swagger.io/specification/](https://swagger.io/specification/) -- OpenAPI spec 2.0: [https://swagger.io/specification/v2/#schemaObject](https://swagger.io/specification/v2/#schemaObject) -- Go swagger: [https://goswagger.io/use/models/schemas.html](https://goswagger.io/use/models/schemas.html) -- Swagger data models: [https://swagger.io/docs/specification/data-models/](https://swagger.io/docs/specification/data-models/) diff --git a/versioned_docs/version-0.5.1/user_docs/getting-started/install.md b/versioned_docs/version-0.5.1/user_docs/getting-started/install.md deleted file mode 100644 index 261ab804..00000000 --- a/versioned_docs/version-0.5.1/user_docs/getting-started/install.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Installation - -## 1. Install KCL - -### From the Binary Releases - -Each release of KCL includes various OSes and architectures. These binary versions can be manually downloaded and installed from [Github](https://github.com/kcl-lang/kcl/releases/) or [Gitee](https://gitee.com/kusionstack/kcl/releases) and add `{install-location}/kclvm/bin` to the environment PATH. - -> ⚠️ If you cannot successfully access Github, you can also access Gitee to obtain binaries for installation. - -#### MacOS & Linux - -```bash -export PATH=$PATH:{install-location}/kclvm/bin -``` - -#### Windows - -```powershell -$env:PATH += ";{install-location}\kclvm\bin;" -``` - -### Using script to install the latest release - -#### MacOS - -Install or upgrade the latest darwin KCL to /usr/local/kclvm/bin - -```bash -curl -fsSL https://kcl-lang.io/script/install.sh | /bin/bash -``` - -#### Linux - -Install or upgrade the latest linux KCL to /usr/local/kclvm/bin - -```bash -wget -q https://kcl-lang.io/script/install.sh -O - | /bin/bash -``` - -#### Windows - -Install or upgrade the latest windows KCL to $Env:SystemDrive\kclvm\bin and add this directory to User PATH environment variable. - -```bash -powershell -Command "iwr -useb https://kcl-lang.io/script/install.ps1 | iex" -``` - -### Homebrew (MacOS) - -- Install - -```bash -brew install kcl-lang/tap/kcl -``` - -- Upgrade - -```bash -brew upgrade kcl-lang/tap/kcl -``` - -- Uninstall - -```bash -brew uninstall kcl-lang/tap/kcl -``` - -### Scoop (Windows) - -Install [Scoop](https://scoop.sh/) first, then add this bucket and install `kcl` by running: - -```bash -scoop bucket add kcl-lang https://github.com/kcl-lang/scoop-bucket.git -scoop install kcl-lang/kcl -``` - -### From Go - -Install `kcl` through the `Go` command (`Go` requires 1.18+). - -```bash -go install kcl-lang.io/kcl-go/cmds/kcl-go@main -``` - -Add an alias for the kcl command (optional). - -```bash -alias kcl='kcl-go run' -``` - -> Note: `kcl-go` does not rely on the installation of `kcl`, but if `kcl` exists in PATH, it will be used by `kcl-go` first. - -### From Docker - -- Command - -```bash -docker run --rm -it kcllang/kcl -``` - -- Update image - -```bash -docker pull kcllang/kcl -``` - -### Note - -We can execute the following command to ensure that KCL has been installed correctly. - -```bash -kcl -V -``` - -The output may looks like this: - -```bash -Version: {kcl version} -Platform: {your platform} -GitCommit: {git commit} -``` - -For all the above operating systems and installation methods, if you want to use [KCL Python Plugin](/docs/reference/plugin/overview), you need to ensure that Python 3.7+ is installed and add the python3 command to your PATH environment variable. - -## 2. Install KCL IDE Extension - -### VS Code - -The KCL Extension extension provides some coding assistance, e.g., highlight, goto definition, completion, hover, outline, and diagnostics. You can go [here](/docs/tools/Ide/vs-code) for more information about the installation. - -![Completion](/img/docs/tools/Ide/vs-code/Completion.gif) - -### IntelliJ IDEA - -Download the distribution from [here](https://github.com/kcl-lang/intellij-kcl/releases) and in IntelliJ IDEA, click Preference -> plugins -> install Plugin from Disk... -> select kcl-idea-plugin zip -> restart IDE. This plugin requires the IntelliJ IDEA 2020.2+ diff --git a/versioned_docs/version-0.5.1/user_docs/getting-started/intro.md b/versioned_docs/version-0.5.1/user_docs/getting-started/intro.md deleted file mode 100644 index c4515840..00000000 --- a/versioned_docs/version-0.5.1/user_docs/getting-started/intro.md +++ /dev/null @@ -1,199 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Introduction - -## What is KCL? - -[KCL](https://github.com/kcl-lang/kcl) is an open-source, constraint-based record and functional language that enhances the writing of complex configurations, including those for cloud-native scenarios. With its advanced programming language technology and practices, KCL is dedicated to promoting better modularity, scalability, and stability for configurations. It enables simpler logic writing and offers ease of automation APIs and integration with homegrown systems. - -## Why Use KCL? - -KCL expects to solve the following problems: - -- Hide infrastructure and platform details by defining more appropriate **API abstractions** to reduce the burden of developers. -- **Mutate** and **validate** existing config files or manifests. -- Manage large-scale configuration data across teams without side effects through configuration language. - - Use **production level high-performance programming language** to **write code** to improve the flexibility of configuration, such as conditional statements, loops, functions, package management and other features to improve the ability of configuration reuse. - - Improve the ability of **configuration semantic verification** at the code level, such as optional/required fields, types, ranges, and other configuration checks. - - Provide the **ability to write, combine and abstract configuration blocks**, such as structure definition, structure inheritance, constraint definition, etc. - -You can use KCL to - -- **Generate** low-level static configuration data like JSON, YAML, etc. -- Reduce boilerplate in configuration data with the **schema modeling**. -- Define transformers and constraints for configuration data and templates and **mutate/validate** them automatically. -- Organize, simplify, unify and manage large configurations scalably without side effects. -- Used as a platform engineering language to deliver modern app with [KusionStack](https://kusionstack.io/). - -In addition to the language itself, KCL also provides many additional tools, such as formatting, testing, document, package management, to help users use, understand and check the configuration or policy they write. We can reduce the cost of configuration writing and sharing through IDE extensions such as VS Code, playground and package manage tools. In addition, through KCL Rust, Go, and Python multilingual SDKs, the configuration can be automatically managed and executed. - -![](/img/docs/user_docs/intro/kcl-overview.png) - -Besides, KCL is a modern high-level domain language, which is a compiled, static and strongly typed language. It provides developers with the ability to write **configuration (config)**, **modeling abstraction (schema)**, **logic (lambda)**, and **policies (rule)** as the core elements through recording and functional language design. - -![](/img/docs/user_docs/intro/kcl-concepts.png) - -KCL tries to provide runtime-independent programmability and does not natively provide system functions such as threads and IO, but supports functions for cloud-native operation scenarios, and tries to provide stable, secure, low-noise, low-side effect, easy-to-automate and easy-to-govern programming support for solving domain problems. - -In summary, KCL has the following characteristics: - -- **Easy-to-use**: Originated from high-level languages ​​such as Python and Golang, incorporating functional language features with low side effects. -- **Well-designed**: Independent Spec-driven syntax, semantics, runtime and system modules design. -- **Quick modeling**: [Schema](https://kcl-lang.github.io/docs/reference/lang/tour#schema)-centric configuration types and modular abstraction. -- **Rich capabilities**: Configuration with type, logic and policy based on [Config](https://kcl-lang.github.io/docs/reference/lang/codelab/simple), [Schema](https://kcl-lang.github.io/docs/reference/lang/tour/#schema), [Lambda](https://kcl-lang.github.io/docs/reference/lang/tour/#function), [Rule](https://kcl-lang.github.io/docs/reference/lang/tour/#rule). -- **Stability**: Configuration stability built on [static type system](https://kcl-lang.github.io/docs/reference/lang/tour/#type-system), [constraints](https://kcl-lang.github.io/docs/reference/lang/tour/#validation), and [rules](https://kcl-lang.github.io/docs/reference/lang/tour#rule). -- **Scalability**: High scalability through [automatic merge mechanism](https://kcl-lang.github.io/docs/reference/lang/tour/#-operators-1) of isolated config blocks. -- **Fast automation**: Gradient automation scheme of [CRUD APIs](https://kcl-lang.github.io/docs/reference/lang/tour/#kcl-cli-variable-override), [multilingual SDKs](https://kcl-lang.github.io/docs/reference/xlang-api/overview), [language plugin](https://kcl-lang.github.io/docs/reference/plugin/overview) -- **High performance**: High compile time and runtime performance using Rust & C and [LLVM](https://llvm.org/), and support compilation to native code and [WASM](https://webassembly.org/). -- **API affinity**: Native support API ecological specifications such as [OpenAPI](https://kcl-lang.github.io/docs/tools/cli/openapi/), Kubernetes CRD, Kubernetes YAML spec. -- **Development friendly**: Friendly development experiences with rich [language tools](https://kcl-lang.github.io/docs/tools/cli/kcl/overview) (Format, Lint, Test, Vet, Doc, etc.) and [IDE extensions](https://kcl-lang.github.io/docs/tools/Ide/). -- **Safety & maintainable**: Domain-oriented, no system-level functions such as native threads and IO, low noise and security risk, easy maintenance and governance. -- **Rich multi-language SDK**: [Go](https://kcl-lang.io/docs/reference/xlang-api/go-api), [Python](https://kcl-lang.io/docs/reference/xlang-api/python-api), [Java](https://kcl-lang.io/docs/reference/xlang-api/java-api) and [REST APIs](https://kcl-lang.io/docs/reference/xlang-api/rest-api) meet different scenarios and application use prelude. -- **Kubernetes Integrations**: External mutation and validation plugins including [Kustomize KCL Plugin](https://github.com/kcl-lang/kustomize-kcl), [Helm KCL Plugin](https://github.com/kcl-lang/helm-kcl), [KPT KCL SDK](https://github.com/kcl-lang/kpt-kcl-sdk), [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) to separate data and logic. -- **Production-ready**: Widely used in production practice of platform engineering and automation at Ant Group. - -Although KCL is not a general language, it has corresponding application scenarios. Developers can write **config**, **schema**, **function** and **rule** through KCL, where config is used to define data, schema is used to describe the model definition of data, rule is used to validate data, and schema and rule can also be combined to use models and constraints that fully describe data, In addition, we can also use the lambda pure function in KCL to organize data code, encapsulate common code, and call it directly when needed. - -The configuration of attributes in KCL usually meets the simple pattern: - -$$ -k = (T) v -$$ - -where $k$ is the attribute name, $v$ is the attributes value, and $T$ is the type annotation. Since KCL has the ability of the type inference, $T$ is usually omitted. - -This is an example of generating kubernetes manifests. - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = name -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -We can use the KCL code to generate a Kubernetes YAML manifest. - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## How to Choose? - -Communities have been making significant efforts to improve their configuration technologies, which can be categorized into three groups: - -- Low-level data format-based tools that utilize external tools for enhancing reuse and validation, specifically for templating, patching, and validation. -- Domain-Specific Languages (DSLs) and Configuration Languages (CLs), which enhance language abilities. -- General Purpose Language (GPL)-based solutions that utilize Cloud-Development Kit (CDK) or framework to define the configuration. - -To simplify, here are some recommended options: - -- YAML/JSON/Kustomize/Helm are recommended if you need to write structured key-value pairs, or use Kubernetes native tools. -- HCL is recommended if you want to use programming language convenience to remove boilerplate with good human readability, or if you are already a Terraform user. -- CUE is recommended if you want to use type system to improve stability and maintain scalable configurations. -- KCL is recommended if you want types and modeling like a modern language, scalable configurations, in-house pure functions and rules, and production-ready performance and automation. - -### vs. YAML/JSON - -YAML/JSON configurations are suitable for small-scale configuration scenarios. However, if you require frequent modifications in large-scale cloud-native configuration scenarios, KCL is more appropriate. The primary difference between the two is the abstraction of configuration data and deployment. - -The advantages of using KCL for configuration are numerous. First, abstracting one layer for static data provides deployment flexibility, allowing various configuration environments, tenants, and runtime to have distinct requirements for static data. Additionally, different organizations may have different specifications and product requirements. By leveraging KCL, administrators can expose the most important and frequently modified configurations to users. - -### vs. Jsonnet/GCL - -GCL is a declarative configuration programming language implemented in Python, providing necessary language capabilities for template abstraction. However, the compiler itself is written in Python, and the language runs with interpretation, leading to poor performance for large template instances, such as the Kubernetes model. - -On the other hand, Jsonnet is a data template language implemented in C++/Go, suitable for application and tool developers. It can generate configuration data and organize, simplify, and manage large configurations without any side effects. - -Both Jsonnet and GCL are excellent at reducing boilerplate, using code to generate configuration, so engineers can write advanced GPL code instead of manually writing error-prone and difficult-to-understand server binary code. Despite reducing some of the complexities of GCL, Jsonnet largely falls into the same category. Both have runtime errors, insufficient type-checking and constraint capacity. - -### vs. HCL - -HCL is a configuration language implemented in Go that is structured and inspired by the syntax of libucl and nginx configurations. It is designed to be both human and machine-friendly, primarily for use in devops tools, server configurations, and resource configurations as a [Terraform language](https://www.terraform.io/language). - -The user interface of HCL is not readily apparent in the Terraform provider Schema definition and can be cumbersome when defining complex object and required/optional fields. Dynamic parameters are constrained by the condition field of the variable, and resource constraints must be defined either by the provider schema or through the use of Sentinel/Rego and other policy languages. The language itself may not be self-contained. - -### vs. CUE - -CUE can be utilized for modeling through structures without the need for inheritance or other features. This can lead to high abstraction as long as there are no conflicts with model definitions. However, since CUE performs all constraint checks at runtime, there may be performance bottlenecks in large-scale modeling scenarios. Despite this, CUE simplifies constraint writing through various syntax options, eliminating the need for generic types and enumerations. Additionally, configuration merging is supported but is completely idempotent, which may not be suitable for complex multi-tenant and multi-environment configuration scenarios. Writing complex loop and constraint scenarios can be challenging and cumbersome for accurately modifying configurations. - -On the other hand, KCL conducts modeling through the schema and achieves high model abstraction through language-level engineering and some object-oriented features, such as single inheritance. KCL is a statically compiled language with low overhead for large-scale modeling scenarios. Additionally, KCL provides a richer declarative constraint syntax, making it easier to write. Compared to CUE, KCL offers more if guard combination constraints, all/any/map/filter, and other collection constraint writing methods, which simplify configuration field combination constraints. - -### vs. Dhall - -Dhall is a functional, programmable configuration language that incorporates JSON, functions, types and imports. If you have experience with languages like Haskell, you may find Dhall familiar. KCL also offers similar functionality for programmability and abstraction, but has made greater advancements in areas such as modeling, constraint checking, automation and package management for sharing models. KCL's syntax and semantics are more aligned with object-oriented languages, making it more approachable than pure functional styles in some cases. - -### vs. Nickel - -Nickel is the cheap configuration language. Its purpose is to automate the generation of static configuration files and it is in essence JSON with functions and types. - -KCL and Nickel both have a similar gradual type system (static + dynamic), merge strategy, function and constraint definition. The difference is that KCL is a Python-like language, while Nickel is a JSON-like language. In addition, KCL provides the schema keyword to distinguish between configuration definitions and configuration data to avoid mixed use. - -### vs. Starlark - -Starlark is the language of Bazel, which is a dialect of Python. It does not have types and recursion is forbidden. - -KCL can also be regarded as a variant of Python to some extent, but it greatly enhances the design related to static typing and configuration extensibility, and is a compiled language, which is essentially different from Starlark. - -### vs. Kustomize - -The key feature of Kustomize is its ability to overlay files at a granular level. However, it faces challenges with multiple overlay chains as a specific attribute value may not be the final value, as it can be overridden by another value elsewhere. Retrieving the inheritance chain of Kustomize files can be less convenient than retrieving the inheritance chain of KCL code, particularly for complex scenarios where careful consideration of the specified configuration file overwrite order is necessary. Additionally, Kustomize does not address issues related to YAML configuration writing, constraint verification, model abstraction, and development, making it more suited for simpler configuration scenarios. - -In contrast, KCL offers fine-grained configuration merge operations for each attribute in the code, with flexible merge strategy settings that are not limited to overall resources. KCL also allows for static analysis of configuration dependencies through import statements. - -### vs. Helm - -The idea behind Helm can be traced back to the package management system used in operating systems. It is a package management tool that relies on templated YAML files to execute and manage resources within packages. - -KCL provides a greater range of capabilities than Helm, making it a viable alternative. Users who have already adopted Helm can still utilize KCL by packaging the stack compilation results in a Helm format or by using the Helm-KCL plugin to programmatically extend existing Helm charts. - -### vs. CDK - -CDK's high-level language integrates well into application projects, effectively becoming part of the client runtime. In contrast, KCL decouples external configurations and policies written using KCL from the client runtime. - -General-purpose languages can often be over-engineered, going beyond the requirements of the problem being solved. These languages can also present various security issues, such as problems with the ability boundary, such as accessing I/O, network, code infinite looping, and other security risks. In specialized fields, such as music, there are special notes used to communicate effectively, which cannot be expressed clearly in general-purpose languages. - -Furthermore, general-purpose languages come in a variety of styles, which can create challenges in terms of unified maintenance, management, and automation. These languages are generally better suited to writing the client runtime, which is a continuation of the server runtime. They are not ideal for writing configurations that are independent of the runtime, as they are compiled into binaries and started from the process, making stability and scalability challenging to control. In contrast, configuration languages are often used to write data combined with simple logic, and they describe the expected final result, which is then consumed by the compiler or engine. - -### vs. OPA/Rego - -While not originally intended as a data definition language, Rego, the language used for Open Policy Agent (OPA), can also address the issue of adding constraints from multiple sources. - -Rego has its roots in logic programming and is based on Datalog, a restricted form of Prolog. In contrast, KCL is based on a static type structure. Typed-feature structures were developed to address the limitations of Prolog in encoding human languages. Using a Datalog variant for a constraint validation task may seem unusual. Datalog excels as a query language, but it can be cumbersome for constraint enforcement, in that values must be queried before applying constraints. - -KCL's approach to constraint validation is more conducive to finding normalized and simplified representations of constraints, making it well-suited for creating structures generated from OpenAPI. diff --git a/versioned_docs/version-0.5.1/user_docs/guides/abstraction.md b/versioned_docs/version-0.5.1/user_docs/guides/abstraction.md deleted file mode 100644 index 106f07a2..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/abstraction.md +++ /dev/null @@ -1,147 +0,0 @@ ---- -title: "Abstraction" -sidebar_position: 3 ---- - -## Introduction - -Abstraction refers to a simplified representation of an entity, typically used in computing. It allows for the concealment of specific details while presenting the most relevant information to the programmer. Each abstraction is tailored to suit a specific need, and can greatly enhance the usability of a given entity. In the context of KCL, abstraction can make code easier to understand and maintain, while also simplifying the user interface. - -It should be noted that code abstraction is not meant to reduce code size, but rather to improve maintainability and extendability. During the process of abstracting code, factors such as reusability, readability, and scalability should be taken into consideration, and the code should be optimized as needed. - -The values of the good abstraction - -1. Provides distinct focal points for better comprehension for specific identities, roles, and scenarios. -2. Shields lower-level details to avoid potential errors. -3. Enhances user-friendliness and automation with better portability and good APIs. - -KCL may not assess the rationality of a user's abstraction, but it offers technical solutions to facilitate the process. - -## Use KCL for Abstraction - -**Now, let's begin to abstract Docker Compose and Kubernetes models into an application config.** - -Application centric development allows developers to focus on their workload's architecture rather than the tech stack in the target environment, infrastructure or platform. We define our application once with the `App` schema and then use the KCL CLI to translate it to multiple platforms, such as `Docker Compose` or `Kubernetes` with different versions. - -`Docker Compose` is a tool for defining and running multi-container Docker applications. With Docker Compose, you can define your application's services, networks, and volumes in a single file, and then use it to start and stop your application as a single unit. Docker Compose simplifies the process of running complex, multi-container applications by handling the details of networking, storage, and other infrastructure concerns. - -`Kubernetes manifests` are YAML files that define Kubernetes objects such as Pods, Deployments, and Services. Manifests provide a declarative way to define the desired state of your application, including the number of replicas, the image to use, and the network configuration. Kubernetes uses the manifests to create and manage the resources needed to deploy and run your application. - -Here are some references to learn more about Docker Compose and Kubernetes manifests: - -- [Docker Compose documentation](https://docs.docker.com/compose/) -- [Kubernetes manifest documentation](https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/) - -The application model aims to reduce developer toil and cognitive load by only having to define a single KCL file that works across multiple platforms, and it is designed to be applied to multiple environments to reduce the amount of configuration. Now, let's learn how to do this. - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/abstraction -``` - -We can run the following command to show the config. - -```bash -cat main.k -``` - -The output is - -```python -import .app - -app.App { - name = "app" - containers.nginx = { - image = "nginx" - ports = [{containerPort = 80}] - } - service.ports = [{ port = 80 }] -} -``` - -In the above code, we defined a configuration using the `App` schema, where we configured an `nginx` container and configured it with an `80` service port. - -Besides, KCL allows developers to define the resources required for their applications in a declarative manner and is tied to a platform such as Docker Compose or Kubernetes manifests and allows to generate a platform-specific configuration file such as `docker-compose.yaml` or a Kubernetes `manifests.yaml` file. Next, let's generate the corresponding configuration. - -### 2. Transform the Application Config into Docker Compose Config - -If we want to transform the application config into the docker compose config, we can run the command simply: - -```shell -kcl main.k docker_compose_render.k -``` - -The output is - -```yaml -services: - app: - image: nginx - ports: - - published: 80 - target: 80 - protocol: TCP -``` - -### 3. Transform the Application Config into Kubernetes Deployment and Service Manifests - -If we want to transform the application config into the Kubernetes manifests, we can run the command simply: - -```shell -kcl main.k kubernetes_render.k -``` - -The output is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: app - labels: - app: app -spec: - replicas: 1 - selector: - matchLabels: - app: app - template: - metadata: - labels: - app: app - spec: - containers: - - name: nginx - image: nginx - ports: - - protocol: TCP - containerPort: 80 ---- -apiVersion: v1 -kind: Service -metadata: - name: app - labels: - app: app -spec: - selector: - app: app - ports: - - port: 80 - protocol: TCP -``` - -Look, it's so simple. If you want to learn more information about the application model, you can refer to [here](https://github.com/kcl-lang/kcl-lang.io/tree/main/examples/abstraction). - -## Summary - -Through the use of KCL, we are able to separate the abstraction and implementation details of a model, allowing for the abstract model to be mapped to various infrastructures or platforms. This is achieved through flexible switching between different implementations and the combination of compilation, which shields configuration differences and ultimately reduces the cognitive burden. - -## Further Information - -In addition to manually maintaining the configuration, we can also use KCL APIs to integrate **automatic configuration changes** into our applications. For specific instructions, please refer to [here](/docs/user_docs/guides/automation). diff --git a/versioned_docs/version-0.5.1/user_docs/guides/automation.md b/versioned_docs/version-0.5.1/user_docs/guides/automation.md deleted file mode 100644 index 624e4b7e..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/automation.md +++ /dev/null @@ -1,185 +0,0 @@ ---- -title: "Automation" -sidebar_position: 6 ---- - -## Introduction - -KCL provides many automation related capabilities, mainly including tools and multilingual APIs. Via `package_identifier : key_identifier` mode, KCL supports the indexing of any configured key value, thus completing the addition, deletion, modification and query of any key value. For example, the following figure shows that we can directly execute the following command to modify the image. The code diff before and after modification is also shown in the figure. - -![](/img/blog/2022-09-15-declarative-config-overview/14-kcl-image-update.png) - -In addition, the automation capability of KCL can be realized and integrated into CI/CD. - -![](/img/blog/2022-09-15-declarative-config-overview/15-kcl-automation.png) - -## Use KCL for Automation - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/automation -``` - -We can run the following command to show the config. - -```bash -cat main.k -``` - -The output is - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "app" - replicas = 1 - labels.key = "value" -} -``` - -We can run the command to get the config - -```bash -kcl main.k -``` - -The output is - -```yaml -app: - name: app - replicas: 1 - labels: - app: app - key: value -``` - -### 2. Use KCL CLI for Automation - -KCL allows us to directly modify the values in the configuration model through the KCL CLI `-O|--overrides` parameter. The parameter contains three parts e.g., `pkg`, `identifier`, `attribute` and `override_value`. - -```bash -kcl main.k -O override_spec -``` - -- `override_spec` represents a unified representation of the configuration model fields and values that need to be modified - -```bash -override_spec: [[pkgpath] ":"] identifier ("=" value | "-") -``` - -- `pkgpath`: indicates the package path where the identifier needs to be modified, usually in the form of `a.b.c`. For the main package,`pkgpath` is represented as `__ main__`. When omitted or not written, it indicates the main package -- `identifier` indicates the identifier that needs to modify the configuration, usually in the form of `a.b.c`. -- `value` indicates the value of the configuration that needs to be modified, which can be any legal KCL expression, such as number/string literal value, list/dict/schema expression, etc. -- `=` denotes modifying of the value of the identifier. -- `-` denotes deleting of the identifier. - -#### Override Configuration - -Run the command to update the application name. - -```bash -kcl main.k -O app.name='new_app' -``` - -The output is - -```yaml -app: - name: new_app - replicas: 1 - labels: - app: new_app - key: value -``` - -We can see the `name` attribute of the `app` config is updated to `new_app`. - -Besides, when we use KCL CLI `-d` argument, the KCL file will be modified to the following content at the same time. - -```bash -kcl main.k -O app.name='new_app' -d -``` - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "new_app" - replicas = 1 - labels: {key = "value"} -} -``` - -#### Delete Configuration - -Run the command to delete the `key` attribute of `labels`. - -```bash -kcl main.k -O app.labels.key- -``` - -The output is - -```yaml -app: - name: app - replicas: 1 - labels: - app: app -``` - -### 3. Use KCL API for Automation - -In addition, we can automatically modify the configuration attributes through the [multilingual API](/docs/reference/xlang-api/overview). - -Take the RestAPI as an example. The RestAPI service can be started in the following way: - -```bash -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -The service can then be requested via the POST protocol: - -```bash -curl -X POST http://127.0.0.1:2021/api:protorpc/KclvmService.OverrideFile -H 'content-type: accept/json' -d '{ - "file": "main.k", - "specs": ["app.name=\"nginx\""] -}' -``` - -After the service call is completed, main.k will be modified as follows: - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "nginx" - replicas = 1 - labels: { - "key" = "value" - } -} -``` - -## Summary - -The document introduces the automation capabilities of KCL, including tools and multilingual APIs. It supports indexing of any configured key value, allowing for the addition, deletion, modification, and querying of any key value. It can also be integrated into CI/CD. The document provides an example of using KCL to automate configuration management, including using the KCL CLI to override and delete configurations, and using the KCL API to modify configuration attributes. For more information about KCL automation and Override API, please refer to [here](/docs/reference/lang/tour#kcl-cli-variable-override). diff --git a/versioned_docs/version-0.5.1/user_docs/guides/ci-integration/1-github-actions.md b/versioned_docs/version-0.5.1/user_docs/guides/ci-integration/1-github-actions.md deleted file mode 100644 index 9da91d48..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/ci-integration/1-github-actions.md +++ /dev/null @@ -1,162 +0,0 @@ ---- -id: github-actions -sidebar_label: Github Actions ---- - -# Github Actions Integration - -## Introduction - -In the GitOps section, we have introduced how to integrate KCL with GitOps. In this section, we will continue to provide sample solutions for KCL and CI integrations. We hope to implement the end-to-end application development process by using containers, Continuous Integration (CI) for generation, and GitOps for Continuous Deployment (CD). In this scheme, we use a **Flask application** and **Github Actions** as examples. - -> Note: You can use any containerized application and different CI systems such as **Gitlab CI**, **Jenkins CI**, etc. in this solution. - -The overall workflow is as follows: - -- Develop application code and submit it to the GitHub repository to trigger CI. -- GitHub Actions generate container images from application code and push them to the `docker.io` container registry. -- GitHub Actions automatically synchronizes and updates the KCL manifest deployment file based on the version of the container image in the docker.io container registry. - -## How to - -### 1. Get the Example - -We put the application source code and infrastructure deployment code in different repos, which can be maintained by different roles to achieve the separation of concerns. - -- Get the application code - -```shell -git clone https://github.com/kcl-lang/flask-demo.git/ -cd flask-demo -``` - -This is a web application written in Python. We can use the `Dockerfile` in the application directory to generate a container image of this application, and also use Github CI to automatically build a image named `flask_demo`, the CI configuration is as follows - -```yaml -# This is a basic workflow to help you get started with Actions - -name: CI - -# Controls when the workflow will run -on: - # Triggers the workflow on push or pull request events but only for the main branch - push: - branches: [main] - pull_request: - branches: [main] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "build" - build: - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - - - name: Docker Login - uses: docker/login-action@v1.10.0 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - logout: true - - # Runs a set of commands using the runners shell - - name: build image - run: | - make image - docker tag flask_demo:latest ${{ secrets.DOCKER_USERNAME }}/flask_demo:${{ github.sha }} - docker push ${{ secrets.DOCKER_USERNAME }}/flask_demo:${{ github.sha }} - - # Trigger KCL manifest - - name: Trigger CI - uses: InformaticsMatters/trigger-ci-action@1.0.1 - with: - ci-owner: kcl-lang - ci-repository: flask-demo-kcl-manifests - ci-ref: refs/heads/main - ci-user: kcl-bot - ci-user-token: ${{ secrets.DEPLOY_ACCESS_TOKEN }} - ci-name: CI - ci-inputs: >- - image=${{ secrets.DOCKER_USERNAME }}/flask_demo - sha-tag=${{ github.sha }} -``` - -We need the workflow in the source code repository to automatically trigger the workflow in the deployment manifest repository. At this point, we need to create a `secrets.DEPLOY_ACCESS_TOKEN` with Github CI operation permissions and **Docker Hub** image push account information `secrets.DOCKER_USERNAME` and `secrets.DOCKER_PASSWORD` can be configured in the `Secrets and variables` settings of the Github, as shown in the following figure - -![](/img/docs/user_docs/guides/ci-integration/github-secrets.png) - -### 2. Commit the Application Code - -After submitting in the `flask-demo` repository, Github will automatically build a container image and push it to the Docker hub. It will also then trigger the Action of the `flask-demo-kcl-manifest` repository and modify the image value in the deployment manifest repository through [KCL Automation API](/docs/user_docs/guides/automation). Now let's create a submission in the `flask-demo` repository, and we can see that the code submission triggers the Github CI process for the application repository. - -![](/img/docs/user_docs/guides/ci-integration/app-ci.png) - -### 3. Configuration Automatic Update - -After the Github CI process in the application repository is completed, an automatic update configuration CI will be triggered in the repository where the KCL configuration is stored and submitted to the main branch of the `flask-demo-kcl-manifests` repository. The commit information is as follows - -![](/img/docs/user_docs/guides/ci-integration/image-auto-update.png) - -- We can obtain the deployment manifest source code for compilation and validation - -```shell -git clone https://github.com/kcl-lang/flask-demo-kcl-manifests.git/ -cd flask-demo-kcl-manifests -git checkout main && git pull && kcl -``` - -The output YAML is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - replicas: 1 - selector: - matchLabels: - app: flask_demo - template: - metadata: - labels: - app: flask_demo - spec: - containers: - - name: flask_demo - image: "kcllang/flask_demo:6428cff4309afc8c1c40ad180bb9cfd82546be3e" - ports: - - protocol: TCP - containerPort: 5000 ---- -apiVersion: v1 -kind: Service -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - type: NodePort - selector: - app: flask_demo - ports: - - port: 5000 - protocol: TCP - targetPort: 5000 -``` - -From the above configuration, it can be seen that the image of the resource is indeed automatically updated to the newly constructed image value. In addition, we can also use the **Argo CD KCL plugin** to automatically synchronize data from the Git repository and deploy the application to the Kubernetes cluster. - -## Summary - -By integrating KCL and Github CI, we can integrate the container build and delivery workflow by automatically updating the image values in the configuration, in order to achieve end-to-end application development process and improve R&D deployment efficiency. diff --git a/versioned_docs/version-0.5.1/user_docs/guides/ci-integration/2-gitlab-ci.md b/versioned_docs/version-0.5.1/user_docs/guides/ci-integration/2-gitlab-ci.md deleted file mode 100644 index 8b928ec9..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/ci-integration/2-gitlab-ci.md +++ /dev/null @@ -1,135 +0,0 @@ ---- -id: gitlab-ci -sidebar_label: Gitlab CI ---- - -# Gitlab CI Integration - -## Introduction - -In the GitOps section, we have introduced how to integrate KCL with GitOps. In this section, we will continue to provide sample solutions for KCL and CI integrations. We hope to implement the end-to-end application development process by using containers, Continuous Integration (CI) for generation, and GitOps for Continuous Deployment (CD). In this scheme, we use a **Flask application** and **Gitlab CI** as examples. - -> Note: You can use any containerized application and different CI systems such as **Github Actions**, **Jenkins CI**, etc. in this solution. - -The overall workflow is as follows: - -- Develop application code and submit it to the Gitlab repository to trigger CI. -- Gitlab generate container images from application code and push them to the `docker.io` container registry. -- Gitlab CI automatically synchronizes and updates the KCL manifest deployment file based on the version of the container image in the docker.io container registry. - -## How to - -We put the application source code and infrastructure deployment code in different repos, which can be maintained by different roles to achieve the separation of concerns. - -### 1. Get the Example - -- Get the application code - -```shell -git clone https://gitlab.com/kcl-lang/flask-demo.git/ -cd flask-demo -``` - -This is a web application written in Python. We can use the `Dockerfile` in the application directory to generate a container image of this application, and also use Gitlab CI to automatically build a image named `flask_demo`, the CI configuration is as follows - -```yaml -stages: - - publish - - deploy - -publish: - stage: publish - image: - name: cnych/kaniko-executor:v0.22.0 - entrypoint: [""] - script: - - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json - - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile ./Dockerfile --destination $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA - only: - - main - -deploy: - stage: deploy - image: cnych/kustomize:v1.0 - before_script: - - git remote set-url origin https://gitlab.com/kcl-lang/flask-demo - - git config --global user.email "gitlab@git.local" - - git config --global user.name "GitLab CI/CD" - # Install KCL - - wget -q https://kcl-lang.io/script/install.sh -O - | /bin/bash - script: - - git checkout -B main - - cd deployment - # Image auto update - - /usr/local/kclvm/bin/kcl -d -O config.containers.flask_demo.image="$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" - - git commit -am '[skip ci] image update to $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA' - - git push origin main - only: - - main -``` - -We need the workflow in the source code repository to automatically trigger the workflow in the deployment manifest repository. At this point, we need to config `Settings -> CI/CD -> Variables` including `CI_REGISTRY`, `CI_REGISTRY_IMAGE`, `CI_REGISTRY_USER`, `CI_REGISTRY_PASSWORD`, `CI_USERNAME` and `CI_PASSWORD` and update application code to trigger automation build and deploy. - -![](/img/docs/user_docs/guides/ci-integration/gitlab-ci-variables.jpg) - -### 2. Commit the Application Code - -After submitting in the `flask-demo` repository, Gitlab will automatically build a container image and push it to the Docker hub. It will also then trigger the Action of the `flask-demo-kcl-manifest` repository and modify the image value in the deployment manifest repository through [KCL Automation API](/docs/user_docs/guides/automation). Now let's create a submission in the `flask-demo` repository, and we can see that the code submission triggers the Gitlab CI process for the application repository `Build -> Pipelines` page. - -### 3. Configuration Automatic Update - -After the Gitlab CI process in the application repository is completed, an automatic update configuration CI will be triggered in the repository where the KCL configuration is stored and submitted to the main branch of the `flask-demo` repository. - -- We can obtain the deployment manifest source code for compilation and validation - -```shell -git checkout main && git pull && cd deploy && kcl -``` - -The output YAML is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - replicas: 1 - selector: - matchLabels: - app: flask_demo - template: - metadata: - labels: - app: flask_demo - spec: - containers: - - name: flask_demo - image: "kcllang/flask_demo:6428cff4309afc8c1c40ad180bb9cfd82546be3e" - ports: - - protocol: TCP - containerPort: 5000 ---- -apiVersion: v1 -kind: Service -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - type: NodePort - selector: - app: flask_demo - ports: - - port: 5000 - protocol: TCP - targetPort: 5000 -``` - -From the above configuration, it can be seen that the image of the resource is indeed automatically updated to the newly constructed image value. In addition, we can also use the **Argo CD KCL plugin** to automatically synchronize data from the Git repository and deploy the application to the Kubernetes cluster. - -## Summary - -By integrating KCL and Gitlab CI, we can integrate the container build and delivery workflow by automatically updating the image values in the configuration, in order to achieve end-to-end application development process and improve R&D deployment efficiency. diff --git a/versioned_docs/version-0.5.1/user_docs/guides/ci-integration/_3-jenkins-ci.md b/versioned_docs/version-0.5.1/user_docs/guides/ci-integration/_3-jenkins-ci.md deleted file mode 100644 index f85d231f..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/ci-integration/_3-jenkins-ci.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -id: github-ci -sidebar_label: Github CI ---- - -Coming Soon - -## Introduction - -## How to - -## Summary diff --git a/versioned_docs/version-0.5.1/user_docs/guides/ci-integration/_category_.json b/versioned_docs/version-0.5.1/user_docs/guides/ci-integration/_category_.json deleted file mode 100644 index 3145ed7f..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/ci-integration/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "CI Integration", - "position": 12 -} \ No newline at end of file diff --git a/versioned_docs/version-0.5.1/user_docs/guides/configuration.md b/versioned_docs/version-0.5.1/user_docs/guides/configuration.md deleted file mode 100644 index 45846db3..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/configuration.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -title: "Configuration" -sidebar_position: 1 ---- - -## Introduction - -Configuration is a vital aspect of software systems that are constantly in flux due to evolving business requirements, infrastructure demands, and other factors. Often, changing these systems' behavior quickly can be challenging, especially when doing so requires a costly and time-consuming reconstruction and redeployment process. In such cases, making changes to the business code may not be sufficient. Fortunately, the configuration provides a low-overhead way to modify system functions. For instance, many developers write JSON or YAML files to configure their systems. - -We can store the static configuration in JSON and YAML files as needed. Moreover, the configuration can also be stored in a high-level language that allows for more flexible configuration. This language can be coded, rendered, and statically configured. KCL is a configuration language that offers such functionality. Developers can write KCL code to generate JSON/YAML and other configurations. - -## Use KCL for Configuration - -KCL's core features are its modeling and constraint capabilities, and its basic functions revolve around these two key elements. Additionally, KCL follows a user-centric configuration concept when designing its basic functions. Configuration code has requirements for configuration data constraints, such as type constraints and required/optional constraints on configuration attributes, range constraints, and immutability constraints. These are also some of the core issues that KCL is committed to resolving. - -Now that we have an understanding of KCL's capabilities, let's explore how to use it to generate configurations. - -### 1. Get the Example - -Firstly, let's get the example. - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/configuration -``` - -We can run the following command to show the config. - -```bash -cat nginx.k -``` - -The output is - -```python -schema Nginx: - """Schema for Nginx configuration files""" - http: Http - -schema Http: - server: Server - -schema Server: - listen: int | str # The attribute `listen` can be int type or a string type. - location?: Location # Optional, but must be non-empty when specified - -schema Location: - root: str - index: str - -nginx = Nginx { - http.server = { - listen = 80 - location = { - root = "/var/www/html" - index = "index.html" - } - } -} -``` - -### 2. Generate YAML using KCL - -Run the following command - -```bash -kcl nginx.k -``` - -We can get the output YAML - -```yaml -nginx: - http: - server: - listen: 80 - location: - root: /var/www/html - index: index.html -``` - -### 3. Configuration with Dynamic Parameters - -Besides, we can dynamically receive external parameters through the KCL builtin function `option`. For example, for the following KCL file (db.k), we can use the KCL command line `-D` flag to receive an external dynamic parameter. - -```python -env: str = option("env") or "dev" # The attribute `env` has a default value "den" -database: str = option("database") -hosts = { - dev = "postgres.dev" - stage = "postgres.stage" - prod = "postgres.prod" -} -dbConfig = { - host = hosts[env] - database = database - port = "2023" - conn = "postgres://${host}:${port}/${database}" -} -``` - -```bash -# Use the `-D` flag to input external parameters. -kcl db.k -D database="foo" -``` - -The output is - -```yaml -env: dev -database: foo -hosts: - dev: postgres.dev - stage: postgres.stage - prod: postgres.prod -dbConfig: - host: postgres.dev - database: foo - port: "2023" - conn: "postgres://postgres.dev:2023/foo" -``` - -## Summary - -By using KCL, we can generate low-level data configurations. For different situations, we set dynamic parameters through the `-D` flag to meet the scene requirements. For more KCL features, please refer to [here](/docs/reference/lang/tour). diff --git a/versioned_docs/version-0.5.1/user_docs/guides/data-integration.md b/versioned_docs/version-0.5.1/user_docs/guides/data-integration.md deleted file mode 100644 index 6ba1f6e3..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/data-integration.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: "Data Integration" -sidebar_position: 4 ---- - -## Introduction - -In KCL, we can not only compile and output the configuration code written by KCL into YAML format data, but also directly embed JSON/YAML and other data into the KCL language. - -## Use KCL for Data Integration - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/data-integration -``` - -### 2. YAML Integration - -We can run the following command to show the YAML integration config. - -```bash -cat yaml.k -``` - -```python -import yaml - -schema Server: - ports: [int] - -server: Server = yaml.decode("""\ -ports: -- 80 -- 8080 -""") -server_yaml = yaml.encode({ - ports = [80, 8080] -}) -``` - -In the above code, we use the built-in `yaml` module of KCL and its `yaml.decode` function directly integrates YAML data, and uses the `Server` schema to directly verify the integrated YAML data. In addition, we can use `yaml.encode` to serialize YAML data. We can obtain the configuration output through the following command: - -```shell -kcl yaml.k -``` - -The output is - -```yaml -server: - ports: - - 80 - - 8080 -server_yaml: | - ports: - - 80 - - 8080 -``` - -### 3. JSON Integration - -Similarly, for JSON data, we can use `json.encode` and `json.decode` function performs data integration in the same way. - -We can run the following command to show the JSON integration config. - -```bash -cat json.k -``` - -```python -import json - -schema Server: - ports: [int] - -server: Server = json.decode('{"ports": [80, 8080]}') -server_json = json.encode({ - ports = [80, 8080] -}) -``` - -The output of the execution command is: - -```shell -kcl json.k -``` - -```yaml -server: - ports: - - 80 - - 8080 -server_json: '{"ports": [80, 8080]}' -``` - -## Summary - -This document introduces how to perform data integration in KCL, using the built-in yaml and json modules to directly integrate YAML and JSON data into the KCL language, and verify and serialize it using the corresponding decoding and encoding functions. diff --git a/versioned_docs/version-0.5.1/user_docs/guides/gitops/1-quick-start.md b/versioned_docs/version-0.5.1/user_docs/guides/gitops/1-quick-start.md deleted file mode 100644 index 26231885..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/gitops/1-quick-start.md +++ /dev/null @@ -1,159 +0,0 @@ ---- -id: gitops-quick-start -sidebar_label: Quick Start ---- - -# Quick Start - -## Introduction - -### What is GitOps - -GitOps is a modern way to do continuous delivery. Its core idea is to have a Git repository which contains environmental and application configurations. An automated process is also needed for sync the config to cluster. - -By changing the files in repository, developers can apply the applications automatically. The benefits of applying GitOps include: - -- Increased productivity. Continuous delivery can speed up the time of deployment. -- Lower the barrier for developer to deploy. By pushing code instead of container configuration, developers can easily deploy Kubernetes without knowing its internal implementation. -- Trace the change records. Managing the cluster with Git makes every change traceable, enhancing the audit trail. -- Recover the cluster with Git's rollback and branch. - -### GitOps with KCL - -Benefits of Using KCL and ArgoCD Together: - -- KCL can help us **simplify complex Kubernetes deployment configuration files**, reduce the error rate of manually writing YAML files, and improve code readability and maintainability. -- ArgoCD can **automate** the deployment of Kubernetes applications, achieve continuous deployment, and provide comprehensive monitoring and control functions. -- By combining KCL and ArgoCD, deployment efficiency can be improved, errors reduced, and management and monitoring of Kubernetes applications strengthened. -- The combination of KCL and ArgoCD can also help us achieve **Infrastructure as Code (IaC)**, simplify application deployment and management, and better implement DevOps principles. - -With GitOps, developer and operation teams can manage application deployment and configuration by modifying KCL code and generating YAML files. The GitOps toolchain will automatically synchronize the changes to the Kubernetes cluster, enabling continuous deployment and ensuring consistency. If there are issues, the GitOps toolchain can be used to quickly rollback. - -## How to - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/gitops -``` - -We can run the following command to show the config. - -```bash -cat config/main.k -``` - -The output is - -```python -import .app - -config = app.App { - name = "kcl-guestbook-ui" - containers.guestbook = { - image = "gcr.io/heptio-images/ks-guestbook-demo:0.2" - ports = [{containerPort = 80}] - } - service.ports = [{ port = 80 }] - service.type = "LoadBalancer" -} -``` - -In the above code, we defined a configuration using the `App` schema, where we configured an `gcr.io/heptio-images/ks-guestbook-demo:0.2` container and configured it with an `80` service port. - -### 2. Install Kubernetes and GitOps Tool - -#### Setup Kubernetes Cluster and ArgoCD Controllers - -- Install [K3d](https://github.com/k3d-io/k3d) to create a default cluster. - -```bash -k3d cluster create mycluster -``` - -- Install [ArgoCD](https://github.com/argoproj/argo-cd/releases/). - -```bash -kubectl create namespace argocd -kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml -``` - -- Enable ArgoCD KCL Plugin - -Write the patch YAML configuration file and update the ArgoCD configuration: - -```bash -kubectl apply -f ./install/kcl-cmp.yaml -``` - -After completing the first step, ArgoCD will recognize the KCL plugin, but the KCL plugin has not been loaded into the ArgoCD image. To implement configuration drift detection, we have to tune the Deployment of argocd-repo-server. - -```bash -kubectl -n argocd patch deploy/argocd-repo-server -p "$(cat ./install/patch-argocd-repo-server.yaml)" -``` - -Wait for the init container to complete execution (Running). - -```bash -kubectl get pod -n argocd -l app.kubernetes.io/name=argocd-repo-server -``` - -- To access the ArgoCD web UI - -```bash -kubectl port-forward svc/argocd-server -n argocd 8080:443 -``` - -- Open a browser and go to: `https://localhost:8080` - -- The username is "admin" and password get be obtained from the following command: - -```bash -kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d -``` - -#### Setup ArgoCD CLI - -- Install [ArgoCD CLI](https://github.com/argoproj/argo-cd/releases) - -Use "admin" and password to login to ArgoCD - -```bash -argocd login localhost:8080 -``` - -Create ArgoCD Application - -```bash -argocd app create guestbook \ ---repo https://github.com/kcl-lang/kcl-lang.io \ ---path examples/gitops/config \ ---dest-namespace default \ ---dest-server https://kubernetes.default.svc \ ---config-management-plugin kcl-v1.0 -``` - -If you are using a private repository, you need to configure the private repository access with private key credentials before executing the create command. - -Please refer [Private Repositories](https://argo-cd.readthedocs.io/en/stable/user-guide/private-repositories/#ssh-private-key-credential) for more details. - -After successfully creating, you can see the following output: - -```bash -application 'guestbook' created -``` - -Through the ArgoCD UI, you can see that the created applications have not been synchronized yet. Here, you can manually synchronize or set automatic synchronization. - -![](/img/docs/user_docs/guides/gitops/argocd-kcl-app.jpg) - -For more information on synchronization strategies, see [Sync Options](https://argo-cd.readthedocs.io/en/stable/user-guide/sync-options/) - -![](/img/docs/user_docs/guides/gitops/argocd-kcl-app-dashboard.jpg) - -## Summary - -With GitOps, you can easily manage your applications and configuration in your Kubernetes cluster with KCL, ensuring that your applications are always in the desired state. diff --git a/versioned_docs/version-0.5.1/user_docs/guides/gitops/_category_.json b/versioned_docs/version-0.5.1/user_docs/guides/gitops/_category_.json deleted file mode 100644 index 29a73c67..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/gitops/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "GitOps", - "position": 11 -} \ No newline at end of file diff --git a/versioned_docs/version-0.5.1/user_docs/guides/package-management/2-installation.md b/versioned_docs/version-0.5.1/user_docs/guides/package-management/2-installation.md deleted file mode 100644 index 783cde90..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/package-management/2-installation.md +++ /dev/null @@ -1,55 +0,0 @@ -# Installation - -## Install `kpm` - -Before installing and using kpm, ensure that KCL compiler has been installed successfully. - -[How to install KCL compiler.](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### Go install - -You can download kpm via go install. - -```shell -go install kcl-lang.io/kpm@latest -``` - -### Download from GITHUB release page - -You can get `kpm` from the [kpm github release](https://github.com/kcl-lang/kpm/releases) and set the `kpm` binary path to the environment variable PATH. - -```shell -# KPM_INSTALLATION_PATH is the path of the `kpm` binary. -export PATH=$KPM_INSTALLATION_PATH:$PATH -``` - -Use the following command to ensure that you install `kpm` successfully. - -```shell -kpm --help -``` - -If you get the following output, you have successfully installed `kpm` and you can proceed to the following steps. - -```shell -NAME: - kpm - kpm is a kcl package manager - -USAGE: - kpm [arguments]... - -COMMANDS: - init initialize new module in current directory - add add new dependency - pkg package a kcl package into tar - metadata output the resolved dependencies of a package - run compile kcl package. - login login to a registry - logout logout from a registry - push push kcl package to OCI registry. - pull pull kcl package from OCI registry. - help, h Shows a list of commands or help for one command - -GLOBAL OPTIONS: - --help, -h show help -``` diff --git a/versioned_docs/version-0.5.1/user_docs/guides/package-management/3-quick-start.md b/versioned_docs/version-0.5.1/user_docs/guides/package-management/3-quick-start.md deleted file mode 100644 index 732a20de..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/package-management/3-quick-start.md +++ /dev/null @@ -1,108 +0,0 @@ -# Quick Start - -## 1. Init an Empty KCL Package - -Create a new kcl package named `my_package`. And after we have created the package `my_package`, we need to go inside the package by `cd my_package` to complete the following operations. - -```shell -kpm init my_package && cd my_package -``` - -![kpm_init](/img/docs/user_docs/guides/package-management/gifs/kpm_init.gif) - -`kpm` will create two kcl package configuration files: `kcl.mod` and `kcl.mod.lock` in the directory where you executed the command. - -```shell -- my_package - |- kcl.mod - |- kcl.mod.lock - |- # You can write your kcl program directly in this directory. -``` - -`kcl.mod.lock` is the file generated by `kpm` to fix the dependency version. Do not modify this file manually. - -`kpm` initializes `kcl.mod` for an empty project as shown below: - -```shell -[package] -name = "my_package" -edition = "0.0.1" -version = "0.0.1" -``` - -## 2. Add a Dependency from OCI Registry - -You can then add a dependency to the current kcl package using the `kpm add` command - -As shown below, taking the example of adding a package dependency named `k8s`, the version of the package is `1.27.2`. - -```shell -kpm add k8s:1.27.2 -``` - -![kpm_add_k8s](/img/docs/user_docs/guides/package-management/gifs/kpm_add_k8s.gif) - -You can see that `kpm` adds the dependency you just added to kcl.mod. - -```shell -[package] -name = "my_package" -edition = "0.0.1" -version = "0.0.1" - -[dependencies] -k8s = "1.27.2" # The dependency 'k8s' with version '1.27.2' -``` - -### Write a kcl program that uses the content in `k8s` - -Create the `main.k` file in the current package. - -```shell -- my_package - |- kcl.mod - |- kcl.mod.lock - |- main.k # Your KCL program. -``` - -And write the following into the `main.k` file. - -```kcl -# Import and use the contents of the external dependency 'k8s'. -import k8s.api.core.v1 as k8core - -k8core.Pod { - metadata.name = "web-app" - spec.containers = [{ - name = "main-container" - image = "nginx" - ports = [{containerPort = 80}] - }] -} - -``` - -## 3. Run the KCL Code - -In the `my_package` directory, you can use `kpm` to compile the `main.k` file you just wrote. - -```shell -kpm run -``` - -The output is - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: web-app -spec: - containers: - - image: nginx - name: main-container - ports: - - containerPort: 80 -``` - -![kpm_run](/img/docs/user_docs/guides/package-management/gifs/kpm_run.gif) diff --git a/versioned_docs/version-0.5.1/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md b/versioned_docs/version-0.5.1/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md deleted file mode 100644 index aa9c119d..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md +++ /dev/null @@ -1,73 +0,0 @@ -# Share Your Package - -[kpm](https://github.com/kcl-lang/kpm) is a tool for managing kcl packages. This article will guide you on how to use kpm to push your kcl package to an OCI Registry for publication. kpm uses [ghcr.io](https://ghcr.io) as the default OCI Registry, and you can change the default OCI Registry by modifying the kpm configuration file. For information on how to modify the kpm configuration file, see [kpm oci registry](https://github.com/kcl-lang/kpm/blob/main/docs/kpm_oci.md#kpm-registry) - -Here is a simple step-by-step guide on how to use kpm to push your kcl package to ghcr.io. - -## Step 1: Install kpm - -First, you need to install kpm on your computer. You can follow the instructions in the [kpm installation documentation](https://kcl-lang.io/docs/user_docs/guides/package-management/installation). - -## Step 2: Create a ghcr.io token - -If you are using the default OCI Registry of kpm, to push a kcl package to ghcr.io, you need to create a token for authentication. You can follow the instruction. - -- [Creating a ghcr.io access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic) - -## Step 3: Log in to ghcr.io - -After installing kpm and creating a ghcr.io token, you need to log in to ghcr.io using kpm. You can do this using the following command: - -```shell -kpm login ghcr.io -u -p -``` - -Where `` is your GitHub username, `` is the token you created in step 2 - -For more information on how to log in to ghcr.io using kpm, see [kpm login](https://kcl-lang.io/docs/reference/package-management/command-reference/login). - -## Step 4: Push your kcl package - -Now, you can use kpm to push your kcl package to ghcr.io. - -### 1. A valid kcl package - -First, you need to make sure that what you are pushing conforms to the specifications of a kcl package, i.e., it must contain valid kcl.mod and kcl.mod.lock files. - -If you don't know how to get a valid kcl.mod and kcl.mod.lock, you can use the `kpm init` command. - -```shell -# Create a new kcl package named my_package -kpm init my_package -``` - -The `kpm init my_package` command will create a new kcl package `my_package` for you and create the `kcl.mod` and `kcl.mod.lock` files for this package. - -If you already have a directory containing kcl files `exist_kcl_package`, you can use the following command to convert it into a kcl package and create valid `kcl.mod` and `kcl.mod.lock` files for it. - -```shell -# In the exist_kcl_package directory -$ pwd -/home/user/exist_kcl_package - -# Run the `kpm init` command to create the `kcl.mod` and `kcl.mod.lock` files -$ kpm init -``` - -For more information on how to use `kpm init`, see [kpm init](https://kcl-lang.io/docs/reference/package-management/command-reference/init). - -### 2. Pushing the KCL Package - -You can use the following command in the root directory of your `kcl` package: - -```shell -# In the root directory of the exist_kcl_package package -$ pwd -/home/user/exist_kcl_package - -# Pushing the KCL Package to Default OCI Registry -$ kpm push -``` - -After completing these steps, you have successfully pushed your KCL Package to the default OCI Registry. -For more information on how to use `kpm push`, see [kpm push](https://kcl-lang.io/docs/reference/package-management/command-reference/push). diff --git a/versioned_docs/version-0.5.1/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md b/versioned_docs/version-0.5.1/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md deleted file mode 100644 index 3fa5aabe..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md +++ /dev/null @@ -1,66 +0,0 @@ -# Share Your Package to docker.io - -[kpm](https://github.com/KusionStack/kpm) is a tool for managing kcl packages. This article will show you how to use kpm to push your kcl packages to docker.io. - -Here is a simple step-by-step guide on how to use kpm to push your kcl package to docker.io. - -## Step 1: Install kpm - -First, you need to install kpm on your computer. You can follow the instructions in the [kpm installation documentation](https://kcl-lang.io/docs/user_docs/guides/package-management/installation). - -## Step 2: Create a docker.io account - -If you want to use `docker.io` as the OCI registry to share your kcl package with others, you need to create a `docker.io` account to support the push of your kcl package. - -## Step 3: Log in to docker.io - -You can use the following command to log in to docker.io. - -```shell -kpm login -u -p docker.io -``` - -Where `` is your `docker.io` username, and `` is your `docker.io` password. - -For more information on how to log in to docker.io using kpm, see [kpm login](https://kcl-lang.io/docs/reference/package-management/command-reference/login). - -## Step 4: Push your kcl package - -Now, you can use kpm to push your kcl package to `docker.io`. - -### 1. A valid kcl package - -First, you need to make sure that what you are pushing conforms to the specifications of a kcl package, i.e., it must contain valid kcl.mod and kcl.mod.lock files. - -If you don't know how to get a valid kcl.mod and kcl.mod.lock, you can use the `kpm init` command. - -Create a new kcl package named `my_package`. - -```shell -kpm init my_package -``` - -The `kpm init my_package` command will create a new kcl package `my_package` for you and create the `kcl.mod` and `kcl.mod.lock` files for this package. - -If you already have a directory containing kcl files `exist_kcl_package`, you can use the following command to convert it into a kcl package and create valid `kcl.mod` and `kcl.mod.lock` files for it. - -Run the `kpm init` command under the `exist_kcl_package` directory. - -```shell -kpm init -``` - -For more information on how to use `kpm init`, see [kpm init](https://kcl-lang.io/docs/reference/package-management/command-reference/init). - -### 2. Pushing the KCL Package - -You can use the following command in the root directory of your `kcl` package: - -Run the `kpm push` command under the `exist_kcl_package` directory. - -```shell -kpm push oci://docker.io//exist_kcl_package -``` - -After completing these steps, you have successfully pushed your KCL Package `exist_kcl_package` to `docker.io`. -For more information on how to use `kpm push`, see [kpm push](https://kcl-lang.io/docs/reference/package-management/command-reference/push). diff --git a/versioned_docs/version-0.5.1/user_docs/guides/package-management/4-how-to/6-push_github_action.md b/versioned_docs/version-0.5.1/user_docs/guides/package-management/4-how-to/6-push_github_action.md deleted file mode 100644 index de88dbcf..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/package-management/4-how-to/6-push_github_action.md +++ /dev/null @@ -1,81 +0,0 @@ -# Push Your KCL Package by GitHub Action - -[kpm](https://github.com/KusionStack/kpm) is a tool for managing kcl packages. This article will guide you how to use kpm in GitHub Action to push your kcl package to OCI registry. - -## Step 1: Install kpm - -At first, you need to install kpm on your computer. You can follow [kpm installation document](https://kcl-lang.io/docs/user_docs/guides/package-management/installation). - -## Step 2: Create a GitHub account - -If you already have a GitHub account, you can skip this step. - -[Sign up for a new GitHub account](https://docs.github.com/en/get-started/signing-up-for-github/signing-up-for-a-new-github-account) - -## Step 3: Create a GitHub repository for your KCL package - -### 1. Prepare a GitHub repository for your KCL package - -You need to prepare a GitHub repository for your KCL package. - -[Create a GitHub repository](https://docs.github.com/en/get-started/quickstart/create-a-repo) - -In this repository, add your KCL program, take the repository https://github.com/awesome-kusion/catalog.git as an example, - -```bash -├── .github -│ └── workflows -│ └── push.yaml # github action workflow -├── LICENSE -├── README.md -├── kcl.mod # kcl.mod to define your kcl package -├── kcl.mod.lock # kcl.mod.lock generated by kpm -└── main.k # Your KCL program -``` - -### 2. Set OCI Registry, account and password for your Github repository - -Take docker.io as an example, you can set secrets `REG`, `REG_ACCOUNT` and `REG_TOKEN` for your repository. The value of `REG` is `docker.io`, the value of `REG_ACCOUNT` is your `docker.io` account, and the value of `REG_TOKEN` is your `docker.io` login password. - -[Add secrets to the repository](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) - -If you use `ghcr.io` as `Registry`, you need to use GitHub token as secrets. - -[Create a GitHub Token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token#personal-access-tokens-classic) - -## Step 4: Add your KCL package to the repository and write github action workflow - -Add github action file `.github/workflows/push.yml` to this repository, the content is as follows: - -```yaml -name: KPM Push Workflow - -on: - push: - branches: - - main - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Set up Go 1.21 - uses: actions/setup-go@v2 - with: - go-version: 1.21 - - - name: Install kpm - run: go install kcl-lang.io/kpm@latest - - - name: Login and Push - env: - KPM_REG: ${{ secrets.REG }} - KPM_REPO: ${{ secrets.REG_ACCOUNT }} - run: kpm login -u ${{ secrets.REG_ACCOUNT }} -p ${{ secrets.REG_TOKEN }} ${{ secrets.REG }} && kpm push - - - name: Run kpm project from oci registry - run: kpm run oci://${{ secrets.REG }}/${{ secrets.REG_ACCOUNT }}/catalog --tag 0.0.1 -``` diff --git a/versioned_docs/version-0.5.1/user_docs/guides/schema-definition.md b/versioned_docs/version-0.5.1/user_docs/guides/schema-definition.md deleted file mode 100644 index 6ad910b8..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/schema-definition.md +++ /dev/null @@ -1,135 +0,0 @@ ---- -title: "Schema Definition" -sidebar_position: 3 ---- - -## Introduction - -The core scenario of KCL is write configurations and constraints. and a core feature of KCL is **modeling**. The keyword `schema` in KCL can be used to define structures and constraints, such as attribute types, default values, range check, and various other constraints. In addition, structures defined with KCL schema can be used in turn to verify implementation, validate input (JSON, YAML and other structured data) or generate code (multilingual structures, OpenAPI, and so on). - -## Use KCL for Defining Structures and Constraints - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/definition -``` - -We can run the following command to show the config. - -```bash -cat main.k -``` - -The output is - -```python -import .app_module # A relative path import - -app: app_module.App { - domainType = "Standard" - containerPort = 80 - volumes = [ - { - mountPath = "/tmp" - } - ] - services = [ - { - clusterIP = "None" - $type = "ClusterIP" - } - ] -} -``` - -We put the `app` model into a separate `app_module.k`, then we can use the `import` keyword in `main.k` for modular management, such as the following file structure - -``` -. -├── app_module.k -└── main.k -``` - -The content of `app_module.k` is - -```python -schema App: - domainType: "Standard" | "Customized" | "Global" - containerPort: int - volumes: [Volume] - services: [Service] - - check: - 1 <= containerPort <= 65535 - -schema Service: - clusterIP: str - $type: str - - check: - clusterIP == "None" if $type == "ClusterIP" - -schema Volume: - container: str = "*" # The default value of `container` is "*" - mountPath: str - - check: - mountPath not in ["/", "/boot", "/home", "dev", "/etc", "/root"] -``` - -In the above file, we use the `schema` keyword to define three models `App`, `Service` and `Volume`. The `App` model has four attributes `domainType`, `containerPort`, `volumes` and `services`, where - -- The type of `domainType` is a string literal union type, similar to an "enumeration", which means that the value of `domainType` can only take one of `"Standard"`, `"Customized"` and `"Global"`. -- The type of `containerPort` is an integer (`int`). In addition, we use the `check` keyword to define its value range from 1 to 65535. -- The type of `services` is `Service` schema list type, and we use `?` to mark it as an optional attribute. -- The type of `volumes` is a `Volume` schema list type, and we use `?` to mark it as an optional attribute. - -We can get the YAML output of the `app` instance by using the following command line - -```shell -kcl main.k -``` - -The output is - -```yaml -app: - domainType: Standard - containerPort: 80 - volumes: - - container: "*" - mountPath: /tmp - services: - - clusterIP: None - type: ClusterIP -``` - -### 2. Output Configuration - -We can still get the YAML output of the `app` instance by using the following command line - -```shell -kcl main.k -``` - -The output is - -```yaml -app: - domainType: Standard - containerPort: 80 - volumes: - - container: "*" - mountPath: /tmp - services: - - clusterIP: None - type: ClusterIP -``` - -## Summary - -KCL is a language for defining configurations and constraints, with a core feature of modeling using the schema keyword. This allows for the definition of structures with attributes, default values, range checks, and other constraints. Structures defined using KCL schema can be used to validate data, or generate code. The example demonstrates how to define models using schema, import them for modular management, and output the YAML configuration of an instance of the defined structure using the kcl command. diff --git a/versioned_docs/version-0.5.1/user_docs/guides/secret-management/_category_.json b/versioned_docs/version-0.5.1/user_docs/guides/secret-management/_category_.json deleted file mode 100644 index c57bb30e..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/secret-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Secret Management", - "position": 13 -} diff --git a/versioned_docs/version-0.5.1/user_docs/guides/validation.md b/versioned_docs/version-0.5.1/user_docs/guides/validation.md deleted file mode 100644 index 486fa619..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/validation.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: "Validation" -sidebar_position: 2 ---- - -## Introduction - -Validation is the process of verifying that data is accurate, reliable, and meets certain requirements or constraints. This includes checking the data for completeness, consistency, accuracy, and relevance. Data validation is performed to ensure that the data is fit for its intended purpose and that it can be used effectively and efficiently. - -We can use KCL and its vet tools to manually or automatically perform data validation to ensure data consistency. - -## Use KCL for Validation - -In addition to using KCL code to generate configuration formats such as JSON/YAML, KCL also supports format validation of JSON/YAML data. As a configuration language, KCL covers almost all features of [OpenAPI](https://www.openapis.org/). - -In KCL, a structure definition can be used to validate configuration data. At the same time, it supports user-defined constraint rules through the check block, and writes validation expressions in the schema to check and validate the attributes defined by the schema. It is very clear and simple to check whether the input JSON/YAML satisfies the corresponding schema structure definition and constraints. - -### 1. Get the Example - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/validation -``` - -We can run the following command to show the config. - -```bash -cat schema.k -``` - -```python -schema User: - name: str - age: int - message?: str - data: Data - labels: {str:} - hc: [int] - - check: - age > 10, "age must > 10" - -schema Data: - id: int - value: str -``` - -In the schema, we can use the `check` keyword to write the validation rules of every schema attribute. Each line in the check block corresponds to a conditional expression. When the condition is satisfied, the validation is successful. The conditional expression can be followed by `, "check error message"` to indicate the message to be displayed when the check fails. - -To sum up, the validation kinds supported in KCL schema are: - -| Kind | Method | -| ----------------- | ----------------------------------------------------------------------------------------- | -| Range | Using comparison operators such as `<`, `>` | -| Regex | Using methods such as `match` from the `regex` system module | -| Length | Using the `len` built-in function to get the length of a variable of type `list/dict/str` | -| Enum | Using literal union types | -| Optional/Required | Using optional/required attributes of schema | -| Condition | Using the check if conditional expression | - -### 2. Validate the Data - -There is a JSON format file `data.json`: - -```json -{ - "name": "Alice", - "age": 18, - "message": "This is Alice", - "data": { - "id": 1, - "value": "value1" - }, - "labels": { - "key": "value" - }, - "hc": [1, 2, 3] -} -``` - -Execute the following command: - -```bash -kcl-vet data.json schema.k -``` - -## Summary - -KCL is a configuration language that supports data validation through its structure definition and user-defined constraint rules. Validation kinds supported in KCL schema include range, regex, length, enum, optional/required, and condition. To validate data, a schema is defined with validation rules written using the check keyword, and the data is validated using the validation tool or a visualization product built on top of it. - -## Further Information - -The improvement of KCL validation capabilities will gradually focus on the "static" aspect, that is, at compile time, combined with the ability of formal validation, it can directly analyze whether the data meets the constraints, whether the constraints conflict with each other, etc., and can be exposed in real-time through the IDE. - -We also expect that KCL models and constraints can be managed as a package (this package has only KCL files). For example, the Kubernetes models and constraints can be used out of the box. Users can generate configurations or verify existing configurations, and can simply extend the models and constraints users want through KCL inheritance. diff --git a/versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md b/versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md deleted file mode 100644 index 47bcd213..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: "Adopt From Kubernetes" -sidebar_position: 1 ---- - -## Introduction - -KCL provides many out of the box support for Kubernetes configuration. Through KCL tools, we can integrate Kubernetes Schema and configuration into KCL. This section will introduce how to use KCL to integrate Kubernetes. - -## Quick Start - -### 1. Kubernetes OpenAPI Spec - -Starting from Kubernetes 1.4, the alpha support for the OpenAPI specification (known as Swagger 2.0 before it was donated to the OpenAPI Initiative) was introduced, and the API descriptions follow the [OpenAPI Spec 2.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md). And since Kubernetes 1.5, Kubernetes supports [directly extracting models from source code and then generating the OpenAPI spec file](https://github.com/kubernetes/kube-openapi) to automatically keep the specifications and documents up to date with the operation and models. - -In addition, Kubernetes CRD uses [OpenAPI V3.0 validation](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation) to describe a custom schema (in addition to the built-in attributes apiVersion, Kind, and metadata), that APIServer uses to validate the CR during the resource creation and update phases. - -### 2. KCL OpenAPI Support - -The `kcl-openapi` tool supports extracting and generating KCL schemas from Kubernetes OpenAPI/CRD. the [KCL OpenAPI Spec](/docs/tools/cli/openapi/spec) defines the mapping between the OpenAPI specification and the KCL language features. - -### 3. Migrate From Kubernetes To KCL - -#### 3.1 Write configurations based on the Kusion_Models package - -``We provide an out-of-the-box `kusion_models` package for you to quickly start. It contains a well-designed frontend model called [`Server schema`](https://github.com/KusionStack/konfig/blob/main/base/pkg/kusion_models/kube/frontend/server.k). You can declare the configurations by initializing the `Server schema`. For the description and usage of the schema and its attributes, please refer to the [Server schema documentation](https://kusionstack.io/docs/reference/model/kusion_models/kube/frontend/doc_server).`` - -#### 3.2 Build Your Custom Frontend Models - -The existing KCL Models may not meet your specific business requirements, then you can also design your custom frontend model package. You can design your custom models based on the pre-generated Kubernetes KCL models among all versions. And you can also develop your custom scripts to migrate your configuration data as what `kube2kcl` tool does. - -##### 3.2.1 Get the k8s package - -The [Kubernetes KCL models](https://github.com/orgs/KusionStack/packages/container/package/k8s) among all versions are pre-generated, you get it by executing `kpm add k8s:` under your project. For detailed information about kpm usage, please refer to [kpm quick start guide](https://github.com/kcl-lang/kpm#quick-start). - -Alternatively, if you may want to generate them yourself, please refer to [Generate KCL Packages from Kubernetes OpenAPI Specs](https://github.com/kcl-lang/kcl-openapi/blob/main/docs/generate_from_k8s_spec.md). - -##### 3.2.2 Design Custom Frontend Models - -Since the Kubernetes built-in models are atomistic and kind of complex to beginners, we recommend taking the native model of Kubernetes as the backend output model and designing a batch of frontend models which could become a more abstract, friendlier and simpler interface to the user. You can refer to the design pattern in the [`Server Schema in the Konfig repo`](https://github.com/KusionStack/konfig/blob/main/base/pkg/kusion_models/kube/frontend/server.k). - -##### 3.2.3 Migrate The Configuration Data - -You can develop your custom scripts to migrate your configuration data automatically. KCL will later provide writing scaffolding and writing guidelines for this script. - -### 4. Migrate From Kubernetes CRD - -If you developed CRDs, you can generate the KCL version of the CRD schemas and declare CRs based on that. - -- Generate KCL Schema from CRD - - ``` - kcl-openapi generate model --crd --skip-validation -f - ``` - -- Define CR based on CRDs in KCL - - You can initialize the CRD schema to define a CR, or further, you can use the generated schema as a backend model and design a frontend interface for users to initialize. The practice is similar to what `KCL Models` does on Kubernetes built-in models. - -## Summary - -This section provides a quick start guide for using KCL with OpenAPI and Custom Resource Definitions (CRD). KCL also supports OpenAPI through the `kcl-openapi tool`, which maps OpenAPI specifications to KCL language features. diff --git a/versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md b/versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md deleted file mode 100644 index a312933b..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -title: "Kustomize KCL Plugin" -sidebar_position: 3 ---- - -## Introduction - -[Kustomize](https://github.com/kubernetes-sigs/kustomize) lets you customize raw, template-free YAML files for multiple purposes, leaving the original YAML untouched and usable as is. - -KCL can be used to create functions to mutate and/or validate the YAML Kubernetes Resource Model (KRM) input/output format, and we provide Kustomize KCL functions to simplify the function authoring process. - -## Prerequisites - -- Install [kustomize](https://github.com/kubernetes-sigs/kustomize) - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=kustomize-kcl` only to Deployment resources. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/kustomize-kcl.git -cd ./kustomize-kcl/examples/set-annotation/ -``` - -### 2. Test and Run - -```bash -kustomize fn run ./local-resource/ --dry-run -``` - -The output YAML is - -```yaml -apiVersion: krm.kcl.dev/v1alpha1 -kind: KCLRun -metadata: - name: set-annotation - annotations: - config.kubernetes.io/function: | - container: - image: docker.io/kcllang/kustomize-kcl:v0.2.0 - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml -# EDIT THE SOURCE! -# This should be your KCL code which preloads the `ResourceList` to `option("resource_list") -spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "kustomize-kcl"}} for resource in option("resource_list").items] ---- -apiVersion: v1 -kind: Service -metadata: - name: test - annotations: - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml -spec: - selector: - app: MyApp - ports: - - protocol: TCP - port: 80 - targetPort: 9376 ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx - annotations: - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml - managed-by: kustomize-kcl -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Kustomize KCL Plugin](https://github.com/kcl-lang/kustomize-kcl) diff --git a/versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md b/versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md deleted file mode 100644 index fb879992..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: "Helmfile KCL Plugin" -sidebar_position: 5 ---- - -## Introduction - -[Helmfile](https://github.com/helmfile/helmfile) is a declarative spec for deploying helm charts. It lets you... - -- Keep a directory of chart value files and maintain changes in version control. -- Apply CI/CD to configuration changes. -- Periodically sync to avoid skew in environments. - -KCL can be used to create functions to mutate and/or validate the YAML Kubernetes Resource Model (KRM) input/output format, and we provide Kustomize KCL functions to simplify the function authoring process. - -## Prerequisites - -- Install [helmfile](https://github.com/helmfile/helmfile) -- Prepare a Kubernetes cluster - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=helmfile-kcl` only to Deployment resources. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/helmfile-kcl.git -cd ./helmfile-kcl/examples/hello-world/ -``` - -We can execute the command to show config - -```bash -cat helmfile.yaml -``` - -The output is - -```yaml -repositories: - - name: prometheus-community - url: https://prometheus-community.github.io/helm-charts - -releases: - - name: prom-norbac-ubuntu - namespace: prometheus - chart: prometheus-community/prometheus - set: - - name: rbac.create - value: false - transformers: - # Use KCL Plugin to mutate or validate Kubernetes manifests. - - apiVersion: krm.kcl.dev/v1alpha1 - kind: KCLRun - metadata: - name: "set-annotation" - annotations: - config.kubernetes.io/function: | - container: - image: docker.io/kcllang/kustomize-kcl:v0.2.0 - spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "helmfile-kcl"}} for resource in option("resource_list").items] -``` - -In the above config, we use a `KCLRun` plugin to assign the `transfomer` field. This means that we will add annotations to all deployment resources in the prometheus helm chart. - -### 2. Test and Run - -```bash -helmfile apply -``` - -The output is - -```bash -Adding repo prometheus-community https://prometheus-community.github.io/helm-charts -"prometheus-community" has been added to your repositories - -... -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Kustomize KCL Plugin](https://github.com/kcl-lang/kustomize-kcl) diff --git a/versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json b/versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json deleted file mode 100644 index 6e90c03c..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Mutate or Validate Kubernetes Manifests", - "position": 3 -} diff --git a/versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/_category_.json b/versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/_category_.json deleted file mode 100644 index 42681f2b..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Kubernetes", - "position": 9 -} diff --git a/versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/index.md b/versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/index.md deleted file mode 100644 index 8d6340de..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/index.md +++ /dev/null @@ -1 +0,0 @@ -# Kubernetes diff --git a/versioned_docs/version-0.5.1/user_docs/guides/working-with-konfig/1-overview.md b/versioned_docs/version-0.5.1/user_docs/guides/working-with-konfig/1-overview.md deleted file mode 100644 index aca119a1..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/working-with-konfig/1-overview.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -id: overview -sidebar_label: Overview ---- - -# Konfig Overview - -In KCL, it is recommended to uniformly manage all configurations and model libraries in the way of **configuration library**, that is, to store not only KCL definitions of the abstract model itself, but also various types of configurations, such as application operation and maintenance configuration, policy, etc. The configuration is recommended to be hosted in various VCS systems to facilitate configuration rollback and drift check. The best practice code of the configuration repository is Konfig, and the repository is hosted in [Github](https://github.com/KusionStack/konfig)。 - -⚡ The Konfig repository mainly includes: - -- KCL module declaration file (kcl.mod) -- KCL domain model libraries (Kubernetes, Prometheus, etc.) -- Directories of various configurations (application operation and maintenance configuration, etc) -- Configuration build and test scripts (Makefile, Github CI file, etc.) - -The reason for using a unified warehouse to manage all KCL configuration codes is that different code packages have different R&D entities, which will lead to package management and version management problems. When the business configuration code and basic configuration code are stored in a unified warehouse, the version dependency management between codes will be relatively simple. By locating the directory and file of the unique code base, the configuration code can be managed uniformly for easy search, modification and maintenance. - -The following is the architecture of Konfig: - -![](/img/docs/user_docs/guides/konfig/konfig-arch.png) - -Konfig provides users with an out-of-the-box and highly abstract configuration interface. The original simple starting point of the model library is to improve the efficiency and experience of Kubernetes YAML users. We hope to simplify the writing of user-side configuration code by abstracting and encapsulating the model with more complex code into a unified model. Konfig consists of the following parts: - -- **Core model**: - - **Front-end model**: The front-end model is the "user interface", which contains all configurable attributes exposed to users on the platform side. Some repetitive and deducible configurations are omitted, and essential attributes are abstracted and exposed to users. It has user-friendly features, such as `server.k`. - - **Back-end model**: The back-end model is "model implementation", which is the model that makes the properties of the front-end model effective. It mainly contains the rendering logic of the front-end model instance. The back-end model can use KCL to write validation, logic judgment, code fragment reuse and other code to improve the reusability and robustness of the configuration code, and is not sensitive to users, such as `server_backend.k`. -- **Domain model**: It is a model that does not contain any implementation logic and abstraction. It is often generated by tool transformation and does not need to be modified. It corresponds to the real effective YAML attribute one by one. The domain model needs to be further abstracted and is generally not directly used by users. For example, `kusion_kubernetes` is the domain model library of Kubernetes scenarios. - -In addition, the core model simplifies the configuration code of front-end users through two layers of abstraction: the front-end model and the back-end model. The domain model is automatically generated through the KCL OpenAPI. diff --git a/versioned_docs/version-0.5.1/user_docs/guides/working-with-konfig/2-structure.md b/versioned_docs/version-0.5.1/user_docs/guides/working-with-konfig/2-structure.md deleted file mode 100644 index 64e74b1d..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/working-with-konfig/2-structure.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -id: structure -sidebar_label: Structure ---- - -# Konfig Structure - -This article mainly explains the directory and code structure of the Konfig repository. - -## Overview - -```bash -. -├── .github # CI Scripts -├── Makefile # Building and testing scripts -├── README.md # Documents -├── appops # Application configuration. This folder is used to place KCL operation and maintenance configuration of all applications -│ ├── clickhouse-operator -│ ├── code-city -│ ├── guestbook -│ ├── http-echo -│ └── nginx-example -├── base # Models -│ ├── examples # Examples -│ │ ├── monitoring # Monitoring example -│ │ ├── native # Kubernetes resource example -│ │ ├── provider # Basic resource configuration example such as Terraform resource -│ │ └── server # Server example. -│ └── pkg -│ ├── kusion_kubernetes # Kubernetes domain models -│ ├── kusion_models # Core models -│ ├── kusion_prometheus # Prometheus domain models -│ └── kusion_provider # Basic resource models such as Terraform resource -└── kcl.mod # The KCL module declaration file -``` - -## Core Model - -The core model library is generally named `kusion_models`, mainly including front-end model, back-end model, renderer, etc. The directory structure is: - -```bash -├── commons # Common models -├── kube # Cloud-native resource core models -│ ├── backend # Back-end models -│ ├── frontend # Front-end models -│ │ ├── common # Common front-end models -│ │ ├── configmap # ConfigMap -│ │ ├── container # Container -│ │ ├── ingress # Ingress -│ │ ├── resource # Resource -│ │ ├── secret # Secret -│ │ ├── service # Service -│ │ ├── sidecar # Sidecar -│ │ ├── strategy # strategy -│ │ ├── volume # Volume -│ │ └── server.k # The `Server` model -│ ├── metadata # Kubernetes metadata -│ ├── mixins # Mixin -│ ├── render # Front-to-back-end renderers. -│ ├── templates # Data template -│ └── utils -└── metadata # Common metadata -``` - -## Project and Stack - -![](/img/docs/user_docs/concepts/project-stack.png) - -Project and Stack are logical isolation concepts used to organize the Konfig. - -### Project - -Any folder that contains the file `project.yaml` will be regarded as a Project, and the `project.yaml` is used to describe the metadata of this Project like `name` and `tenant`. Projects must have clear business semantics and must belong to a tenant. Users can map an application or an operation scenario to a Project. - -### Stack - -Like Project, any folder that contains the file `stack.yaml` will be regarded as a Stack and `stack.yaml` is used to describe the metadata of this Stack. Stack is a set of `.k` files that represents the smallest operation unit that can be configured and deployed individually. It tends to represent different stages in the CI/CD process, such as dev, gray, prod, etc. - -### Relationship between Project and Stack - -A Project contains one or more Stacks, and a Stack must belong to and can only belong to one Project. Users can interpret the meaning of Project and Stack according to their own needs and flexibly organize the Konfig structure. We provide the following example as a best practice according to our experiences: - -```bash -appops/nginx-example -├── README.md # Project readme -├── base # common configurations for all stacks -│ └── base.k -├── dev # dev stack -│ ├── ci-test # CI test configs -│ │ ├── settings.yaml # test data -│ │ └── stdout.golden.yaml # expected test result -│ ├── kcl.yaml # kcl config -│ ├── main.k -│ └── stack.yaml # Stack metadata -└── project.yaml # Project metadata -``` - -The Project represents an application and Stack represents different environments of this application, such as dev, pre, prod, etc. Common configurations can be stored in a `base` directory under this Project. diff --git a/versioned_docs/version-0.5.1/user_docs/guides/working-with-konfig/3-quick-start.md b/versioned_docs/version-0.5.1/user_docs/guides/working-with-konfig/3-quick-start.md deleted file mode 100644 index 82fa6f36..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/working-with-konfig/3-quick-start.md +++ /dev/null @@ -1,198 +0,0 @@ ---- -id: guide -sidebar_label: Quick Start ---- - -# Introduction - -This guide shows you how to use the KCL language and CLIs to complete the deployment of an application running in Kubernetes. We call the abstraction of application operation and maintenance configuration as `Server`, and its instance as `Application`. It is essentially an operation and maintenance model defined by KCL. - -In actual production, the application online generally needs to update several k8s resources: - -- Namespace -- Deployment -- Service - -This guide requires you to have a basic understanding of Kubernetes. If you are not familiar with the relevant concepts, please refer to the links below: - -- [Learn Kubernetes Basics](https://kubernetes.io/docs/tutorials/kubernetes-basics/) -- [Namespace](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/) -- [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) -- [Service](https://kubernetes.io/docs/concepts/services-networking/service/) - -## Prerequisites - -Before we start, we need to complete the following steps: - -1. Install KCL - See [Download and Install](/docs/user_docs/getting-started/install) for more details. - -2. Clone the [Konfig repo](https://github.com/KusionStack/konfig.git) - -```shell -git clone https://github.com/KusionStack/konfig.git && cd konfig -``` - -## Quick Start - -### 1. Compiling - -The programming language of the project is KCL, not JSON/YAML which Kubernetes recognizes, so it needs to be compiled to get the final output. - -Enter stack dir `appops/nginx-example/dev` and compile: - -```bash -cd appops/nginx-example/dev && kcl -Y kcl.yaml -D __konfig_output_format__=raw -``` - -The output YAML is: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-exampledev - namespace: nginx-example -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - template: - metadata: - labels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - spec: - containers: - - image: nginx:1.7.8 - name: main - ports: - - containerPort: 80 - protocol: TCP - resources: - limits: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi - requests: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi ---- -apiVersion: v1 -kind: Namespace -metadata: - name: nginx-example ---- -apiVersion: v1 -kind: Service -metadata: - name: nginx-example - namespace: nginx-example -spec: - ports: - - nodePort: 30201 - port: 80 - targetPort: 80 - selector: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - type: NodePort -``` - -After compiling, we can see three resources: - -- A `Deployment` with the name `nginx-exampledev` -- A `Namespace` with the name `nginx-example` -- A `Service` with the name `nginx-example` - -The above completes the configuration and takes effect. Later, we can use the command `kubectl apply` to apply and check the actual status of resources. This guide will not elaborate. - -### 2. Modification - -The `image` attribute in the `Server` model is used to declare the application's container image. We can modify the `image` value in `base/main.k` to modify or upgrade the image: - -```diff -14c14 -< image = "nginx:1.7.8" ---- -> image = "nginx:latest" -``` - -Recompile the configuration code to obtain the modified YAML output: - -```shell -kcl -Y kcl.yaml -D __konfig_output_format__=raw -``` - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-exampledev - namespace: nginx-example -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - template: - metadata: - labels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - spec: - containers: - - image: nginx:latest - name: main - ports: - - containerPort: 80 - protocol: TCP - resources: - limits: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi - requests: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi ---- -apiVersion: v1 -kind: Namespace -metadata: - name: nginx-example ---- -apiVersion: v1 -kind: Service -metadata: - name: nginx-example - namespace: nginx-example -spec: - ports: - - nodePort: 30201 - port: 80 - targetPort: 80 - selector: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - type: NodePort -``` - -## Summary - -This document mainly introduces how to use the KCL and Konfig library to deploy a Long Running application running in Kubernetes. diff --git a/versioned_docs/version-0.5.1/user_docs/guides/working-with-konfig/_category_.json b/versioned_docs/version-0.5.1/user_docs/guides/working-with-konfig/_category_.json deleted file mode 100644 index a71426f9..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/working-with-konfig/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Konfig", - "position": 10 -} diff --git a/versioned_docs/version-0.5.1/user_docs/guides/working-with-kusion/_category_.json b/versioned_docs/version-0.5.1/user_docs/guides/working-with-kusion/_category_.json deleted file mode 100644 index 9f914498..00000000 --- a/versioned_docs/version-0.5.1/user_docs/guides/working-with-kusion/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KusionStack", - "position": 15 -} diff --git a/versioned_docs/version-0.5.1/user_docs/support/faq-install.md b/versioned_docs/version-0.5.1/user_docs/support/faq-install.md deleted file mode 100644 index 37100c09..00000000 --- a/versioned_docs/version-0.5.1/user_docs/support/faq-install.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Installation Troubleshooting - -## MacOS prompts that 'kcl' cannot be opened because Apple cannot check if it contains malicious software - -MacOS prompts that 'kcl' cannot be opened because Apple cannot check if it contains malicious software. This issue is due to the Gatekeeper security feature in the macOS system preventing the application from running. To solve this issue, follow these steps: - -Open 'System Preferences' and click 'Security and Privacy'. In the "General" tab, you will see a message: '"kcl" cannot be opened'. Click 'Open still'. Alternatively, you can click 'Open any method' to open your application. (You may need to use administrator privileges to open the application.) - -If you don't want to perform these steps every time you open an application, you can add the application to the whitelist to run without being blocked. To add your application to the whitelist: - -Open the terminal and run the following command: - -```shell -xattr -rd com.apple.quarantine /path/to/kcl -``` - -Where `/path/to/kcl` is the complete path of the kcl application. After running the command, the application will be added to the whitelist and Gatekeeper will no longer prevent it from running. - -## program not found or run linker failed error on Windows/Linux/MacOS - -Please ensure that the following dependencies are in your PATH: - -- `clang` for MacOS -- `gcc` for Linux -- `cl.exe` for Windows, which can be obtained by installing MSVC diff --git a/versioned_docs/version-0.5.1/user_docs/support/faq-kcl.md b/versioned_docs/version-0.5.1/user_docs/support/faq-kcl.md deleted file mode 100644 index 860dd15b..00000000 --- a/versioned_docs/version-0.5.1/user_docs/support/faq-kcl.md +++ /dev/null @@ -1,2341 +0,0 @@ ---- -sidebar_position: 2 ---- - -# KCL - -## 1. How to write a simple key-value pair configuration with KCL - -Create a file named `config.k` - -```python -cpu = 256 -memory = 512 -image = "nginx:1.14.2" -service = "my-service" -``` - -In the above KCL code, `cpu` and `memory` are defined to be declared as integer types, and their values are `256` and `512`, while `image` and `service` are string types, their values are `image` and `service`. - -Use the following command to compile the above KCL file into YAML for output - -``` -kcl config.k -``` - -The output YAML is - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -If we want to output the YAML content to a file such as `config.yaml`, we can add the `-o|--output` CLI argument: - -``` -kcl config.k -o config.yaml -``` - -## 2. What are the basic data types in KCL? - -KCL's current basic data types and values include: - -- Integer type `int` - - Examples: decimal positive integer `1`, decimal negative integer `-1`, hexadecimal integer `0x10`, octal integer `0o10`, binary integer `0b10` -- float type `float` - - Examples: positive float `1.10`, `1.0`, negative float `-35.59`, `-90.`, scientific notation float `32.3e+18`, `70.2E-12` -- boolean type `bool` - - Example: true value `True`, false value `False` -- String type `str` - marked with `'`, `"` - - Example: double quoted string `"string"`, `"""string"""`, single quoted string `'string'`, `'''string'''` -- List type `list` - marked with `[`, `]` - - Example: empty list `[]`, string list `["string1", "string2", "string3"]` -- Dictionary type `dict` - marked with `{`, `}` - - Example: empty dictionary `{}`, dictionary whose keys and values ​​are all strings `{"key1": "value1", "key2": "value2"}` -- Structure type `schema` - defined with the keyword `schema` -- Null value type `None` - used to indicate that the value of a variable is null, corresponding to the `null` value of the output YAML -- Undefined value type `Undefined` - used to indicate that a variable has not been assigned a value, and a variable with a value of `Undefined` will not be output to YAML - -```python -schema Person: - name: str - age: int - -alice = Person { - name = "Alice" - age = 18 -} -bob = Person { - name = "Bob" - age = 10 -} -``` - -> Note: All KCL variables can be assigned the null value `None` and the undefined value `Undefined`. - -## 3. What do some KCL variable names prefixed with `_` underscore mean? What's the difference between without the `_` underscore prefix? In what scenarios are they suitable for use? - -A variable with an underscore prefix in KCL represents a **hidden**, **mutable** variable, **hidden** means a variable with an underscore prefix will not be output to YAML, and **mutable** means that a variable with an underscore prefix can be repeatedly assigned multiple times, and a variable without an underscore prefix is immutable after being assigned. - -```python -name = 'Foo' # Exported and immutable variable -name = 'Bar' # Error: An exported variable can only be assigned a value once -``` - -```python -_name = 'Foo' # Hidden and mutable variable -_name = 'Bar' - -schema Person: - _name: str # hidden and mutable -``` - -## 4. How to add elements to a dict? - -We can use the union operator `|` or the dict unpacking operator `**` to add elements into a dict, and we can use `in` and `not in` operators to determine whether the dict variable contains a certain key. - -```python -_left = {key: {key1 = "value1"}, intKey = 1} # Note: `=` denotes override the value. -_right = {key: {key2 = "value2"}, intKey = 2} -dataUnion = _left | _right # {"key": {"key1": "value1", "key2": "value2"}, "intKey": 2} -dataUnpack = {**_left, **_right} # {"key": {"key1": "value1", "key2": "value2"}, "intKey": 2} -``` - -The output YAML is - -```yaml -dataUnion: - key: - key1: value1 - key2: value2 - intKey: 2 -dataUnpack: - key: - key1: value1 - key2: value2 - intKey: 2 -``` - -It is also possible to add key-value pair to a dict using the `string interpolation` or the string `format` method. - -```python -dictKey1 = "key1" -dictKey2 = "key2" -data = { - "${dictKey1}" = "value1" - "{}".format(dictKey2) = "value2" -} -``` - -The output YAML is - -```yaml -dictKey1: key1 -dictKey2: key2 -data: - key1: value1 - key2: value2 -``` - -## 5. How to modify elements in dict? - -We can use the union operator `|`, or the unpacking operator `**` to modify the elements in the dict - -```python -_data = {key = "value"} # {"key": "value"} -_data = _data | {key = "override_value1"} # {"key": "override_value1"} -_data = {**_data, **{key = "override_value2"}} # {"key": "override_value2"} -``` - -If we want to delete a value with a key of `key` in the dict, we can use the unpacking operator `**{key = Undefined}` or the merge operator `| {key = Undefined}` to overwrite, the value of the key is Undefined after overwriting, and no YAML output will be done. - -## 6. How to add elements to list? - -There are two ways to add elements to a list: - -- Use `+`, `+=` and slice to concatenate list variables to add elements to the list - -```python -_args = ["a", "b", "c"] -_args += ["end"] # Add elements "end" to the end of the list: ["a", "b", "c", "end"] -_args = _args[:2] + ["x"] + _args[2:] # Insert element "x" at list index 2: ["a", "b", "x", "c", "end"] -_args = ["start"] + _args # Add elements "start" to the head of the list: ["start", "a", "b", "x", "c", "end"] -``` - -- Use the `*` unpacking operator to concatenate and merge lists - -```python -_args = ["a", "b", "c"] -_args = [*_args, "end"] # Add elements "end" to the end of the list: ["a", "b", "c", "end"] -_args = ["start", *_args] # Add elements "start" to the head of the list: ["start", "a", "b", "x", "c", "end"] -``` - -> Note: When the consecutive variables are `None/Undefined`, using `+` may cause an error, then we can use the list unpacking operator `*` or use the `or` operator to take the default value of the list to avoid null values judge. - -```python -data1 = [1, 2, 3] -data2 = None -data3 = [*data1, *data2] # Ok: [1, 2, 3] -data4 = data1 + data2 or [] # OK: [1, 2, 3], We can use the `or` operator to take the default value of data2 as [], when data2 is None/Undefined, take the empty list [] for calculation. -data5 = data1 + data2 # Error: can only concatenate list (not "NoneType") to list -``` - -## 7. How to modify/delete elements in list? - -There are two ways to modify the elements in the list: - -- Use slice to directly modify the value at an index of a list - -```python -_index = 1 -_args = ["a", "b", "c"] -_args = _args[:index] + ["x"] + _args[index+1:] # Modify the element of list index 1 to "x": ["a", "x", "c"] -``` - -- Use the list comprehension to modify elements in a list - -```python -_args = ["a", "b", "c"] -_args = ["x" if a == "b" else a for a in _args] # Change the value of "b" in the list to "x": ["a", "x", "c"] -``` - -There are two ways to delete elements in a list: - -- Use the list comprehension to delete elements with the `if` condition expressions. -- Use `filter` expression to filter elements. - -For example, if we want to delete a number greater than 2 in a list `[1, 2, 3, 4, 5]`, we can write as follows: - -```python -originList = [1, 2, 3, 4, 5] -oneWayDeleteListItem = [item for item in originList if item <= 2] -anotherWayDeleteListItem = filter item in originList { - item <= 2 -} -``` - -The output YAML is - -```yaml -originList: - - 1 - - 2 - - 3 - - 4 - - 5 -oneWayDeleteListItem: - - 1 - - 2 -anotherWayDeleteListItem: - - 1 - - 2 -``` - -## 8. How to write a for loop in KCL? How to understand and use list comprehension and dict comprehension? - -KCL currently only supports functional/declarative deductive for loops. We can traverse dict and list variables as follows: - -The specific form of a list comprehension is (where `[]` are used on both sides of the comprehension): - -```txt -[expression for expr in sequence1 - if condition1 - for expr2 in sequence2 - if condition2 - for expr3 in sequence3 ... - if condition3 - for exprN in sequenceN - if conditionN] -``` - -The specific form of dict comprehension is (where `{}` are used on both sides of the comprehension): - -```txt -{expression for expr in sequence1 - if condition1 - for expr2 in sequence2 - if condition2 - for expr3 in sequence3 ... - if condition3 - for exprN in sequenceN - if conditionN} -``` - -The `if` in the above forms represents the filter condition, and the expression `expr` that satisfies the condition will be generated into a new list or dict - -List comprehension example: - -```python -_listData = [1, 2, 3, 4, 5, 6] -_listData = [l * 2 for l in _listData] # All elements in _listData are multiplied by 2: [2, 4, 6, 8, 10, 12] -_listData = [l for l in _listData if l % 4 == 0] # Filter out all elements in _listData that are divisible by 4: [4, 8, 12] -_listData = [l + 100 if l % 8 == 0 else l for l in _listData] # Traverse _listData, when the element in it is divisible by 8, add 100 to the element, otherwise keep it unchanged: [4, 108, 12] -``` - -Note the difference between the two `if`s on lines 3 and 4 in the above code: - -- The first `if` represents the filter condition of the variable `_listData` list comprehension itself, and cannot be followed by `else`. Elements that meet the conditions will be added to the list, and elements that do not meet the conditions will be removed. Besides, the process may change the length of the list. -- The second `if` represents the selection condition of the list iteration variable `l`, which means the `if-else` ternary expression, which must be followed by `else`, regardless of whether the condition is met, the resulting element is still in the list, the length of the list does not change. - -Dict comprehension example: - -```python -_dictData = {key1 = "value1", key2 = "value2"} -_dictData = {k = _dictData[k] for k in _dictData if k == "key1" and _dictData[k] == "value1"} # Filter out the elements whose key is "key1" and value is "value1" in _dictData, {"key1": "value1"} -``` - -Use comprehension to get all keys of dict: - -```python -dictData = {key1 = "value1", key2 = "value2"} -dictDataKeys = [k for k in _dictData] # ["key1", "key2"] -``` - -Use comprehension to sort a dict in ascending order by key: - -```python -dictData = {key3 = "value3", key2 = "value2", key1 = "value1"} # {'key3': 'value3', 'key2': 'value2', 'key1': 'value1'} -dictSortedData = {k = dictData[k] for k in sorted(dictData)} # {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'} -``` - -Multi-level comprehension example: - -```python -array1 = [1, 2, 3] -array2 = [4, 5, 6] -data = [a1 + a2 for a1 in array1 for a2 in array2] # [5, 6, 7, 6, 7, 8, 7, 8, 9] len(data) == len(array1) * len(array2) -``` - -Double variable loop (list comprehension supports index iteration of list and value iteration of dict, which can simplify the code writing of list/dict iteration process): - -- list - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use _ to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -- dict - -```python -data = {key1 = "value1", key2 = "value2"} -# Single variable loop -dataKeys1 = [k for k in data] # ["key1", "key2"] -dataValues1 = [data[k] for k in data] # ["value1", "value2"] -# Double variable loop -dataKeys2 = [k for k, v in data] # ["key1", "key2"] -dataValues2 = [v for k, v in data] # ["value1", "value2"] -dataFilter = {k = v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use _ to ignore loop variables -dataKeys3 = [k for k, _ in data] # ["key1", "key2"] -dataValues3 = [v for _, v in data] # ["value1", "value2"] -``` - -## 9. How to write an if conditional statement? - -KCL supports two ways to write if conditional statements: - -- if-elif-else block statement, where both elif and else blocks can be omitted, and the elif block can be used multiple times - -```python -success = True -_result = "failed" -if success: - _result = "success" -``` - -```python -success = True -if success: - _result = "success" -else: - _result = "failed" -``` - -```python -_result = 0 -if condition == "one": - _result = 1 -elif condition == "two": - _result = 2 -elif condition == "three": - _result = 3 -else: - _result = 4 -``` - -- Conditional expression ` if else `, similar to ` ? : ` ternary expression in C language - -```python -success = True -_result = "success" if success else "failed" -``` - -> Note: When writing an if-elif-else block statement, pay attention to the colon `:` after the if condition and keep the indentation consistent. - -In addition, conditional expressions can also be written directly in a list or dict (the difference is that the value to be written in the if expression written in the structure is not a statement): - -- list - -```python -env = "prod" -data = [ - "env_value" - ":" - if env == "prod": - "prod" # Write values that need to be added to data, not statements - else: - "other_prod" -] # ["env_value", ":", "prod"] -``` - -- dict - -```python -env = "prod" -config = { - if env == "prod": - MY_PROD_ENV = "prod_value" # Write key-value pairs that need to be added to config, not statements - else: - OTHER_ENV = "other_value" -} # {"MY_PROD_ENV": "prod_value"} -``` - -## 10. How to express logical operations such as "and" "or" "not"? - -In KCL, use `and` for "logical and", use `or` for "logical or", use `not` for "not", which is similar to `&&`, `||` and `~` semantic in C language. - -```python -done = True -col == 0 -if done and (col == 0 or col == 3): - ok = 1 -``` - -For "bitwise AND", "bitwise OR" and "bitwise XOR" of integers, we can use `&`, `|` and `^` operators in KCL, which is similar to `&`, `|` and `^` semantic in C language. - -```python -value = 0x22 -bitmask = 0x0f - -assert (value & bitmask) == 0x02 -assert (value & ~bitmask) == 0x20 -assert (value | bitmask) == 0x2f -assert (value ^ bitmask) == 0x2d -``` - -When we need to write a pattern such as `A if A else B`, we can use `A or B` to simplify, such as the following code: - -```python -value = [0] -default = [1] -x0 = value if value else default -x1 = value or default # Use `value or default` instead of `value if value else default` -``` - -## 11. How to judge whether a variable is None/Undefined, and whether a string/dict/list is empty? - -Please note that `False`, `None`, `Undefined`, number `0`, empty list `[]`, empty dictionary `{}` and empty string `""`, `''`, `""""""`, `''''''` in the conditional expression, are all treated as `false` expressions. - -For example, when judging a string variable `strData` is neither `None/Undefined` nor an empty string (string length is greater than 0), we can simply use the following expression: - -```python -strData = "value" -if strData: - isEmptyStr = False -``` - -Empty dictionary and empty list judgment examples: - -```python -_emptyList = [] -_emptyDict = {} -isEmptyList = False if _emptyList else True -isEmptyDict = False if _emptyDict else True -``` - -The output YAML is - -```yaml -isEmptyList: true -isEmptyDict: true -``` - -Or use the boolean function `bool` to judge - -```python -_emptyList = [] -_emptyDict = {} -isEmptyList = bool(_emptyList) -isEmptyDict = bool(_emptyDict) -``` - -## 12. How to concatenate strings, format strings, check string prefixes and suffixes and replace string content? - -- The `+` operator can be used to concatenate two strings in KCL - -```python -data1 = "string1" + "string2" # "string1string2" -data2 = "string1" + " " + "string2" # "string1 string2" -``` - -- There are currently two ways to format strings in KCL: - - `format` method for string variables `"{}".format()` - - Using string interpolation `${}` - -```python -hello = "hello" -a = "{} world".format(hello) -b = "${hello} world" -``` - -Note that if we want to use the `{` character or `}` alone in `"{}".format()`, we need to use `{{` and `}}` to convert `{` and `}` respectively, such as escaping a JSON string as follows: - -```python -data = "value" -jsonData = '{{"key": "{}"}}'.format(data) -``` - -The output YAML is - -```yaml -data: value -jsonData: '{"key": "value"}' -``` - -Note that if we want to use the `$` character alone in the `${}` interpolated string, we need to escape the `$` with `$$` - -```python -world = "world" -a = "hello {}".format(world) # "hello world" -b = "hello ${world}" # "hello world" -c = "$$hello ${world}$$" # "$hello world$" -c2 = "$" + "hello ${world}" + "$" # "$hello world$" -``` - -The output YAML is - -```yaml -world: world -a: hello world -b: hello world -c: $hello world$ -c2: $hello world$ -``` - -- Use the `startswith` and `endswith` methods of strings in KCL to check the prefix and suffix of strings - -```python -data = "length" -isEndsWith = data.endswith("th") # True -isStartsWith = "length".startswith('len') # True -``` - -- Use the replace method of the string or the `regex.replace` function to replace the content of the string in KCL - -```python -import regex -data1 = "length".replace("len", "xxx") # Replace "len", "xxxgth" with "xxx" -data2 = regex.replace("abc123", r"\D", "0") # Replace all non-digits in "abc123" with "0", "000123" -``` - -Among them, `r"\D"` means that we do not need to use `\\` to escape the backslash `\` in `\D`, which is mostly used in regular expression strings. - -Besides, we can use index placeholders or keyword placeholders in string formatting expressions to format multiple strings - -- Index placeholders - -```python -x = '{2} {1} {0}'.format('directions', 'the', 'Read') -y = '{0} {0} {0}'.format('string') -``` - -The output YAML is - -```yaml -x: Read the directions -y: string string string -``` - -- Keyword placeholders - -```python -x = 'a: {a}, b: {b}, c: {c}'.format(a = 1, b = 'Two', c = 12.3) -``` - -The output YAML is - -```yaml -x: "a: 1, b: Two, c: 12.3" -``` - -## 13. What is the difference between using single and double quotes in a string? - -There is little difference between KCL single-quoted and double-quoted strings. The only difference is that we don't need to use `\"` to escape `"` in single-quoted strings, and we don't need to use `\'` to escape `'` in double-quoted strings. - -```python -singleQuotedString = 'This is my book named "foo"' # Don’t need to escape double quotes in single quoted strings. -doubleQuotedString = "This is my book named 'foo'" # Don’t need to escape single quotes in double quoted strings. -``` - -In addition, a long string consisting of three single quotes or three double quotes does not need to be escaped (except for the beginning and end of the string), such as the following example: - -```python -longStrWithQuote0 = """Double quotes in long strings "(not at the beginning and end)""" -longStrWithQuote1 = '''Double quotes in long strings "(not at the beginning and end)''' -longStrWithQuote2 = """Single quotes in long strings '(not at the beginning and end)""" -longStrWithQuote3 = '''Single quotes in long strings '(not at the beginning and end)''' -``` - -The output YAML is - -```yaml -longStrWithQuote0: Double quotes in long strings "(not at the beginning and end) -longStrWithQuote1: Double quotes in long strings "(not at the beginning and end) -longStrWithQuote2: Single quotes in long strings '(not at the beginning and end) -longStrWithQuote3: Single quotes in long strings '(not at the beginning and end) -``` - -## 14. How to write a long multiline string? - -In KCL, we can use a single-quoted string and newline characters `\n` or a triple-quoted string to write a multi-line string, and we can use the continuation character `\` to optimize the form of the KCL string. For example, for the three multi-line string variables in the following code, their values are the same: - -```python -string1 = "The first line\nThe second line\nThe third line\n" -string2 = """The first line -The second line -The third line -""" -string3 = """\ -The first line -The second line -The third line -""" # It is recommended to use the long string writing form of `string3`. -``` - -The output YAML is - -```yaml -string1: | - The first line - The second line - The third line -string2: | - The first line - The second line - The third line -string3: | - The first line - The second line - The third line -``` - -## 15. How to use regular expressions in KCL? - -Regular expressions can be used by importing the regular expression system module `import regex` in KCL, which includes the following functions: - -- **match**: Regular expression matching function, which matches the input string according to the regular expression, and returns a bool type to indicate whether the match is successful. -- **split**: Regular expression split function, which splits the string according to the regular expression, and returns a list of split strings. -- **replace**: Regular expression replacement function, which replaces all substrings in the string that satisfies the regular expression, and returns the replaced string. -- **compile**: Regular expression compilation function, which returns bool type to indicate whether it is a valid regular expression. -- **search**: Regular expression search function, which searches all substrings that satisfy the regular expression, and returns a list of substrings. - -Examples: - -```python -import regex - -regex_source = "Apple,Google,Baidu,Xiaomi" -regex_split = regex.split(regex_source, ",") -regex_replace = regex.replace(regex_source, ",", "|") -regex_compile = regex.compile("$^") -regex_search = regex.search("aaaa", "a") -regex_find_all = regex.findall("aaaa", "a") -regex_result = regex.match("192.168.0.1", "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$") # Determine if it is an IP string -regex_result_false = regex.match("192.168.0,1", "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$") # Determine if it is an IP string -``` - -The output YAML is - -```yaml -regex_source: Apple,Google,Baidu,Xiaomi -regex_split: - - Apple - - Google - - Baidu - - Xiaomi -regex_replace: Apple|Google|Baidu|Xiaomi -regex_compile: true -regex_search: true -regex_find_all: - - a - - a - - a - - a -regex_result: true -regex_result_false: false -``` - -For longer regular expressions, we can also use **r-string** to ignore the escape of `\` symbols to simplify the writing of regular expression strings. - -Examples: - -```python -import regex - -isIp = regex.match("192.168.0.1", r"^(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)$") # Determine if it is an IP string -``` - -```python -import regex - -schema Resource: - cpu: str = "1" - memory: str = "1024Mi" - disk: str = "10Gi" - check: - regex.match(cpu, r"^([+-]?[0-9.]+)([m]*[-+]?[0-9]*)$"), "cpu must match specific regular expression" - regex.match(memory, r"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"), "memory must match specific regular expression" - regex.match(disk, r"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"), "disk must match specific regular expression" -``` - -```python -import regex - -schema Env: - name: str - value?: str - check: - len(name) <= 63, "a valid env name must be no more than 63 characters" - regex.match(name, r"[A-Za-z_][A-Za-z0-9_]*"), "a valid env name must start with alphabetic character or '_', followed by a string of alphanumeric characters or '_'" -``` - -## 16. What is the meaning of schema in KCL? - -Schema is a language element in KCL that defines the type of configuration data. Like struct in C language or class in Java, attributes can be defined in it, and each attribute has a corresponding type. - -## 17. How to use schema? - -In KCL, we can use the `schema` keyword to define a structure in which we can declare the various attributes of the schema. - -```python -# A Person structure with firstName of attribute string type, lastName of string type, age of integer type. -schema Person: - firstName: str - lastName: str - # The default value of the age attribute is 0. - age: int = 0 -``` - -A complex example: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels: {str:str} -``` - -In the above code, `cpu` and `memory` are defined as integer types; `name`, `image` and `service` are string types; `command` is a list of string types; labels are dictionaries type whose key type and value type are both strings. - -## 18. How to add "optional" and "required" constraints to the schema attribute? - -The `?` operator is used in KCL to define an "optional" constraint for a schema, and the schema attribute is "required" by default. - -```python -# A Person structure with firstName of attribute string type, lastName of string type, age of integer type. -schema Person: - firstName?: str # firstName is an optional attribute that can be assigned to None/Undefined - lastName?: str # age is an optional attribute that can be assigned to None/Undefined - age: int = 18 # age is an optional attribute that can be assigned to None/Undefined. -``` - -## 19. How to write validation rules for attributes in schema? - -In the schema definition, we can use the `check` keyword to write the validation rules of the schema attribute. As shown below, each line in the check code block corresponds to a conditional expression. When the condition is satisfied, the validation is successful. The conditional expression can be followed by `, "check error message"` to indicate the information to be displayed when the validation fails. - -```python -import regex - -schema Sample: - foo: str # Required, cannot be None/Undefined, and the type must be str - bar: int # Required, cannot be None/Undefined, and the type must be int - fooList: [int] # Required, cannot be None/Undefined, and the type must be int list - color: "Red" | "Yellow" | "Blue" # Required, literal union type, and must be one of "Red", "Yellow", "Blue". - id?: int # Optional, can be None/Undefined, the type must be int - - check: - 0 <= bar < 100 # bar must be greater than or equal to 0 and less than 100 - 0 < len(fooList) < 100 # fooList cannot be None/Undefined, and the length must be greater than 0 and less than 100 - regex.match(foo, "^The.*Foo$") # regular expression matching - bar in range(100) # bar can only range from 1 to 99 - bar in [2, 4, 6, 8] # bar can only take 2, 4, 6, 8 - bar % 2 == 0 # bar must be a multiple of 2 - all foo in fooList { - foo > 1 - } # All elements in fooList must be greater than 1 - any foo in fooList { - foo > 10 - } # At least one element in fooList must be greater than 10 - abs(id) > 10 if id # check expression with if guard, when id is not empty, the absolute value of id must be greater than 10 -``` - -To sum up, the validation kinds supported in KCL schema are: - -| Kind | Method | -| ----------------- | ----------------------------------------------------------------------------------------- | -| Range | Using comparison operators such as `<`, `>` | -| Regex | Using methods such as `match` from the `regex` system module | -| Length | Using the `len` built-in function to get the length of a variable of type `list/dict/str` | -| Enum | Using literal union types | -| Optional/Required | Using optional/required attributes of schema | -| Condition | Using the check if conditional expression | - -## 20. How to add documentation to schema and its attributes? - -A complete schema document is represented as a triple-quoted string, with the following structure: - -```python -schema Person: - """The schema person definition - - Attributes - ---------- - name : str - The name of the person - age : int - The age of the person - - See Also - -------- - Son: - Sub-schema Son of the schema Person. - - Examples - -------- - person = Person { - name = "Alice" - age = 18 - } - """ - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -``` - -## 21. How to write configuration based on schema? How to reuse the common configuration between multiple configurations? - -In the process of schema instantiation, we can use the unpacking operator `**` to expand the public configuration - -```python -schema Boy: - name: str - age: int - hc: int - -schema Girl: - name: str - age: int - hc: int - -config = { - age = 18 - hc = 10 -} - -boy = Boy { - **config - name = "Bob" -} -girl = Girl { - **config - name = "Alice" -} -``` - -The output YAML is - -```yaml -config: - age: 18 - hc: 10 -boy: - name: Bob - age: 18 - hc: 10 -girl: - name: Alice - age: 18 - hc: 10 -``` - -## 22. How to override the default value of schema attribute when writing configuration based on schema? - -After defining a schema, we can use the schema name to instantiate the corresponding configuration, use the `:` operator to union schema attribute default values, and use `=` to override schema attribute default values. - -```python -schema Meta: - labels: {str:str} = {"key1" = "value1"} - annotations: {str:str} = {"key1" = "value1"} - -meta = Meta { - labels: {"key2": "value2"} - annotations = {"key2" = "value2"} -} -``` - -The output YAML is - -```yaml -meta: - labels: - key1: value1 - key2: value2 - annotations: - key2: value2 -``` - -## 23. How to reuse schema definitions? - -We can declare the schema name that the schema needs to inherit at the definition: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 - -# An employee **is** a person, and has some additional information. -schema Employee(Person): - bankCard: int - nationality: str - -employee = Employee { - firstName = "Bob" - lastName = "Green" - age = 18 - bankCard = 123456 - nationality = "China" -} -``` - -The output YAML is - -```yaml -employee: - firstName: Bob - lastName: Green - age: 18 - bankCard: 123456 - nationality: China -``` - -> Note: KCL only allows schema single inheritance. - -## 24. How to reuse schema logic through composition? - -We can use KCL schema mixin to reuse schema logic. Mixins are generally used for functions such as separation of data in schema internal attributes, and data mapping, which can make KCL code more modular and declarative. - -Note that it is not recommended to define dependencies for mixing attributes between different mixins, which will make the use of mixins complicated. - -Examples: - -```python -schema Person: - mixin [FullNameMixin, UpperMixin] - - firstName: str - lastName: str - fullName: str - upper: str - -schema FullNameMixin: - fullName = "{} {}".format(firstName, lastName) - -schema UpperMixin: - upper = fullName.upper() - -person = Person { - firstName = "John" - lastName = "Doe" -} -``` - -The output YAML is - -```yaml -person: - firstName: John - lastName: Doe - fullName: John Doe - upper: JOHN DOE -``` - -## 25. How to import other KCL files? - -Other KCL files can be imported via the `import` keyword, and KCL configuration files are organized into modules. A single KCL file is considered a module, and a directory is considered a package, as a special module. The `import` keyword supports both relative path import and absolute path import - -For example, for the following directory structure: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ │── service1.k - │ └── service2.k - └── mixin - └── mixin1.k -``` - -For `main.k`, relative path import and absolute path import can be expressed as: - -```python -import service # Absolute path import, the root directory is the path where kcl.mod is located -import mixin # Absolute path import, the root directory is the path where kcl.mod is located - -import .model1 # Relative path import, current directory module -import ..service # Relative path import, parent directory -import ...root # Relative path import, parent directory of parent directory -``` - -> Note that for KCL's entry file `main.k`, it cannot import the folder where it is located, otherwise a circular import error will occur: - -```python -import model # Error: recursively loading -``` - -## 26. When can import be omitted? - -KCL files in the same folder the not in the main package can refer to each other without importing each other. For example, for the following directory structure: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ │── service1.k - │ └── service2.k - └── mixin - └── mixin1.k -``` - -When main.k is used as the KCL command line entry file, the variables in main.k, model1.k and model2.k in the model folder cannot refer to each other and need to be imported through import, but service1.k in the service folder and Variables in service2.k can refer to each other, ignoring import - -service1.k - -```python -schema BaseService: - name: str - namespace: str -``` - -service2.k - -```python -schema Service(BaseService): - id: str -``` - -## 27. There is a line of code that is too long, how to wrap it gracefully with correct syntax? - -In KCL, we can use the continuation character `\` for newlines, and we can also use `\` in strings to indicate continuation. - -An example of a long string concatenation continuation line: - -```python -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " -``` - -An example of a continuation in the comprehension expression: - -```python -data = [1, 2, 3, 4] -dataNew = [ - d + 2 \ - for d in data \ - if d % 2 == 0 -] -``` - -An example of a continuation in the if expression: - -```python -condition = 1 -data1 = 1 \ - if condition \ - else 2 -data2 = 2 \ -if condition \ -else 1 -``` - -An example of a continuation in the long string: - -```python -longString = """\ -The first line\ -The continue second line\ -""" -``` - -Note: Use the line continuation character `\` while maintaining indentation, as follows: - -- Error use case: - -```python -data1 = [ - 1, 2, - 3, 4 \ -] # Error, need to keep the indentation of the closing bracket ] - -data2 = [ - 1, 2, - 3, 4 -] # Error, requires uniform indentation of numbers 1 and 3 -``` - -- Right use case: - -```python -data1 = [ - 1, 2, - 3, 4 -] # OK - -data2 = [ \ - 1, 2, \ - 3, 4 \ -] # OK - -data3 = [ \ - 1, 2, \ - 3, 4 \ -] # OK -``` - -## 28. What do these symbols `**` and `*` mean? - -- `**`, `*` appear outside dict/list to represent power operator and multiplication operator respectively. - -```python -data1 = 2 ** 4 # 16 -data2 = 2 * 3 # 6 -``` - -- `**`, `*` appear inside dict/list to indicate unpacking operator, often used for unpacking and merging of list/dict, similar to unpacking operator in Python - -Unpacking of dict: - -```python -data = {"key1" = "value1"} -dataUnpack = {**data, "key2" = "value2"} # {"key1": "value1", "key2": "value2"} -``` - -Unpacking of list: - -```python -data = [1, 2, 3] -dataUnpack = [*data, 4, 5, 6] # [1, 2, 3, 4, 5, 6] -``` - -## 29. How to get child elements of list/dict/schema - -- For list type, we can use `[]` to get an element in the list - -```python -data = [1, 2, 3] # Define an list of integer types -theFirstItem = data[0] # Get the element with index 0 in the list, that is, the first element 1 -theSecondItem = data[1] # Get the element with index 1 in the list, which is the first element 2 -``` - -> Note: The value of the index cannot exceed the length of the list, otherwise an error will occur, we can use the `len` function to get the length of the list. - -```python -data = [1, 2, 3] -dataLength = len(data) # List length is 3 -item = data[3] # Error: Index out of bounds -``` - -In addition, we can also use the negative index to get the elements in the list in reverse order. - -```python -data = [1, 2, 3] -item1 = data[-1] # Get the element with index -1 in the list, which is the last element 3 -item2 = data[-2] # Get the element with index -2 in the list, which is the second-to-last element 2 -``` - -In summary, the value range of the list index is `[-len, len - 1]` - -When we want to get a part of the sub-elements of the list, we can use the slice expression in `[]`, the specific syntax is `[::]`, Note that the value range of the start and end of the index is `left closed right open [, )`, note that the three parameters can be omitted or not written. - -```python -data = [1, 2, 3, 4, 5] -dataSlice0 = data[1:2] # Get the set of elements in the list whose index starts at 1 and ends at 2 [2] -dataSlice1 = data[1:3] # Get the set of elements in the list whose index starts at 1 and ends at 3 [2, 3] -dataSlice2 = data[1:] # Get the set of elements in the list whose index starts at 1 and ends at the last index [2, 3, 4, 5] -dataSlice3 = data[:3] # Get the set of elements in the list whose index starts at the first index and ends at 3 [1, 2, 3] -dataSlice4 = data[::2] # Get the set of elements in the list whose index starts at the first index and ends at the last index (step size is 2) [1, 3, 5] -dataSlice5 = data[::-1] # Reverse the list, [5, 4, 3, 2, 1] -dataSlice6 = data[2:1] # When the start, stop, step combination of three parameters does not meet the conditions, return an empty list []. -``` - -- For dict/schema types, we can use `[]` and `.` to get child elements in dict/schema. - -```python -data = {key1: "value1", key2: "value2"} -data1 = data["key1"] # "value1" -data2 = data.key1 # "value1" -data3 = data["key2"] # "value2" -data4 = data.key2 # "value2" -``` - -```python -schema Person: - name: str = "Alice" - age: int = 18 - -person = Person {} -name1 = person.name # "Alice" -name2 = person["name"] # "Alice" -age1 = person.age # 18 -age2 = person.age # 18 -``` - -When the key value does not exist in the dict, return the value `Undefined`. - -```python -data = {key1 = "value1", key2 = "value2"} -data1 = data["not_exist_key"] # Undefined -data2 = data.not_exist_key # Undefined -``` - -We can use the `in` keyword to determine whether a key value exists in dict/schema - -```python -data = {key1 = "value1", key2 = "value2"} -exist1 = "key1" in data # True -exist2 = "not_exist_key" in data # False -``` - -When there is `.` in the key value or when we need to get the value corresponding to a key value variable at runtime, we can only use the `[]` method. If there is no special case, use `.`: - -```python -name = "key1" -data = {key1 = "value1", key2 = "value2", "contains.dot" = "value3"} -data1 = data[name] # "value1" -data2 = data["contains.dot"] # "value3" -# Note that this is wrong: data3 = data.contains.dot -``` - -> Note: The above sub-element operators cannot operate on values of non-list/dict/schema collection types, such as integers, nulls, etc. - -```python -data = 1 -data1 = 1[0] # Error -``` - -```python -data = None -data1 = None[0] # Error -``` - -When getting the child elements of the collection type, it is often necessary to make a non-null or length judgment: - -```python -data = [] -item = data[0] if data else None -``` - -We can use the `?` operator to make an if non-null judgment, and return None when the condition is not satisfied. For example, the above code can be simplified to: - -```python -data = [] -item1 = data?[0] # When data is empty, return the empty value None -item2 = data?[0] or 1 # When data is empty, return the empty value None, if we don't want to return None, we can also use the or operator to return other default values e.g., "1" in `data?[0] or 1` -``` - -Use more `?` operators to avoid complicated and cumbersome non-null judgments - -```python -data = {key1.key2.key3 = []} -item = data?.key1?.key2?.key3?[0] -``` - -## 30. How to get the type of a variable in KCL code - -The KCL `typeof` built-in function can return the type (string representation) of a variable immediately for type assertion. - -Examples: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person{} -t3 = typeof(_x1) - -_x2 = pkg.Person{} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# Output -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -## 31. How to solve the conflict between keywords and KCL variable names? - -For identifier names that conflict with keywords, we can add a `$` prefix before the identifier to define a keyword identifier. For example, in the following code, keywords such as `if`, `else` can be used as identifiers with the `$` prefix and we can get the corresponding YAML output - -```python -$if = 1 -$else = "s" - -schema Data: - $filter: str = "filter" - -data = Data {} -``` - -The output YAML is - -```yaml -data: - filter: filter -if: 1 -else: s -``` - -> Note: Prefixing non-keyword identifiers with `$` has the same effect as not adding. - -```python -_a = 1 -$_a = 2 # Equivalent to `_a = 2` -``` - -## 32. Are built-in types of KCL a keyword of KCL? Whether they can be used for the definition of variables - -The built-in types of KCL include `int`, `float`, `bool` and `str`, which are not KCL keywords and can be used to define variables, such as the following code: - -```py -int = 1 -str = 2 -``` - -The output YAML is - -```yaml -int: 1 -str: 2 -``` - -> Note: If there are no special requirements, it is not recommended that the names of variables take these built-in types, because in some languages, they exist as keywords. - -## 33. How to implement enumeration in KCL? - -There are two ways to implement enumeration in KCL - -- Use **literal union types** (recommended) - -```python -schema Person: - name: str - gender: "Male" | "Female" - -person = Person { - name = "Alice" - gender = "Male" # gender can only be "Male" or "Female" -} -``` - -```python -schema Config: - colors: ["Red" | "Yellow" | "Blue"] # colors is an enumerated array - -config = Config { - colors = [ - "Red" - "Blue" - ] -} -``` - -- Use schema check expressions - -```python -schema Person: - name: str - gender: "Male" | "Female" - - check: - gender in ["Male", "Female"] - -person = Person { - name = "Alice" - gender = "Male" # gender can only be "Male" or "Female" -} -``` - -## 34. How to get the length of dict - -In KCL, we can use the `len` built-in function to directly find the length of a dict - -```python -len1 = len({k1: "v1"}) # 1 -len2 = len({k1: "v1", k2: "v2"}) # 2 -varDict = {k1 = 1, k2 = 2, k3 = 3} -len3 = len(varDict) # 3 -``` - -In addition, the `len` function can also be used to get the length of `str` and `list` types - -```python -len1 = len("hello") # 5 -len2 = len([1, 2, 3]) # 3 -``` - -## 35. How to write conditional configuration in KCL - -In KCL, in addition to writing `if-elif-else` conditional expressions in top-level statements, it also supports writing conditional expressions in KCL complex structures (list/dict/schema), and supports conditional configuration writing. - -```python -x = 1 -# Conditional configuration in list -dataList = [ - if x == 1: 1 -] -# Conditional configuration in dict -dataDict = { - if x == 1: key1 = "value1" # Inline form - elif x == 2: - key2 = "value2" # Multi-line form -} - -schema Config: - id?: int - -env = "prod" -# Conditional configuration in schema -dataSchema = Config { - if env == "prod": - id = 1 - elif env == "pre": - id = 2 - elif env == "test": - id = 3 -} -``` - -## 36. Does the == operator in KCL do deep comparisons? - -`==` operator in KCL - -- For primitive types `int`, `float`, `bool`, `str` variables are directly compared to see if their values are equal -- Variables of composite types `list`, `dict`, `schema` will deeply recursively compare their sub-elements for equality - - `list` type deep recursive recursive comparison of the value and length of each index - - `dict`/`schema` types deeply recursively compare the value of each attribute (regardless of the order in which the attributes appear) - -```python -print([1, 2] == [1, 2]) # True -print([[0, 1], 1] == [[0, 1], 1]) # True -print({k1 = 1, k2 = 2} == {k2 = 2, k1 = 1}) # True - -print([1, 2] == [1, 2, 3]) # False -print({k1 = 1, k2 = 2, k3 = 3} == {k2 = 2, k1 = 1}) # False -``` - -## 37. How to modify existing configuration blocks in KCL - -In KCL, there are three **attribute operators** `=`, `+=`, `:`, which can be used to modify existing configuration blocks, and can use **unpacking operator** ` **` etc. "inherit" all attribute fields and values ​​of a configuration block. - -- The `=` attribute operator means overriding, use `=` operator to override/delete the attribute with priority, (if it is overwritten with `Undefined`, it means deletion) -- The `+=` attribute operator means adding, which is generally used to add sub-elements to the attributes of the list type. The operand type following the `+=` attribute operator can only be of the list type. -- The `:` attribute operator means idempotent merge. When the value conflicts, an error is reported, and when there is no conflict, the merge is performed - -### Override attribute operator = - -The most commonly used attribute operator is `=`, which indicates the assignment of an attribute. When the same attribute is used multiple times, it means overwriting. For global variables outside `{}` or attributes within `{}`, it means using value overrides this global variable or attribute - -```python -data = { # define a dictionary type variable data - a = 1 # use = to declare a attribute a in data with a value of 1 - b = 2 # use = to declare a attribute b in data with a value of 1 -} # The final data value is {"a": 1, "b": 1} -``` - -we can also use the override attribute operator at the schema instantiation to achieve the effect of overriding the default value of the schema. Generally, when creating a new schema instance, if there is no special requirement, we can generally use `=` - -```python -schema Person: - name: str = "Alice" # schema Person's name attribute has default value "Alice" - age: int = 18 # schema Person's age attribute has a default value of 18 - -bob = Person { - name = "Bob" # "Bob" -> "Alice", the value of the attribute name "Bob" will override the default value "Alice" of the schema Person name attribute - age = 10 # 10 -> 18, the value of the attribute age of 10 will override the default value of the schema Person age attribute of 18 -} # The final value of bob is {"name": "Bob", age: 10} -``` - -### Insert attribute operator += - -The insert attribute operator means to add the value of an attribute in place, such as adding a new element to a list type attribute - -```python -data = { - args = ["kcl"] # use = to declare an attribute in data with value ["kcl"] args - args += ["-Y", "settings.yaml"] # Add two elements "-Y", "settings.yaml" to attribute args using += operator -} # The final data value is {"args": ["kcl", "-Y", "settings.yaml"]} -``` - -### Merge attribute operators : - -The merge attribute operator means idempotent merging of different configuration block values ​​of an attribute. When the values ​​to be merged conflict, an error is reported. It is mostly used in complex configuration merging scenarios. - -```python -data = { - labels: {key1: "value1"} # define a labels, its type is dict, the value is {"key1": "value1"} - labels: {key2: "value2"} # Use : to combine different configuration values ​​of labels -} # The final data value is {"labels": {"key1": "value1", "key2": "value2"}} -``` - -The merge attribute operator is an idempotent operator, and the writing order of the configuration blocks to be merged does not affect the final result. For example, the two `labels` attributes in the above example can also be written in reverse order. - -```python -data = { # The merged writing order of the same attribute labels does not affect the final result - labels: {key2: "value2"} # define a label whose type is dict and the value is {"key2": "value2"} - labels: {key1: "value1"} # Use : to combine different configuration values ​​of labels -} # The final data value is {"labels": {"key1": "value1", "key2": "value2"}} -``` - -Note: The merge attribute operator will check the merged values ​​for conflicts, and report an error when the configuration values ​​that need to be merged conflict. - -```python -data = { - a: 1 # the value of a is 1 - a: 2 # Error: The value 2 of a cannot be merged with the value 1 of a because the results conflict and the merge is not commutative -} -``` - -```python -data = { - labels: {key: "value"} - labels: {key: "override_value"} # Error: The values ​​"value" and "override_value" of the key attributes of two labels are conflicting and cannot be merged -} -``` - -The coalescing operator is used differently for different types - -- Attributes of different types cannot be merged -- When the attribute is a basic type such as int/float/str/bool, the operator will judge whether the values ​​to be merged are equal, and a merge conflict error will occur if they are not equal - -```python -data = { - a: 1 - a: 1 # Ok - a: 2 # Error -} -``` - -- when the attribute is of type list - - Merge conflict error occurs when two lists that need to be merged are not of equal length - - When the lengths of the two lists to be merged are equal, recursively merge each element in the list according to the index - -```python -data = { - args: ["kcl"] - args: ["-Y", "settings.yaml"] # Error: The lengths of the two args attributes are not the same and cannot be merged - env: [{key1: "value1"}] - env: [{key2: "value2"}] # Ok: The value of the final env attribute is [{"key1": "value1"}, {"key2": "value2"}] -} -``` - -- When the attribute is of type dict/schema, recursively merge each element in dict/schema according to key - -```python -data = { - labels: {key1: "value1"} - labels: {key2: "value2"} - labels: {key3: "value3"} -} # The final data value is {"labels": {"key1": "value1", "key2": "value2", "key3": "value3"}} -``` - -- the result of combining an attribute of any type with None/Undefined is itself - -```python -data = { - args: ["kcl"] - args: None # Ok - args: Undefined #Ok -} # The final data value is {"args": ["kcl"]} -``` - -Support declaration and merging of top-level variables using the `:` attribute (we can still declare a configuration block using `config = Config {}`) - -```python -schema Config: - id: int - value: str - -config: Config { - id: 1 -} -config: Config { - value: "1" -} -""" -Two Config configuration blocks are defined here, and the : operator can be used to merge the two configuration blocks together. The equivalent code for the merge is as follows: -config: Config { - id: 1 - value: "1" -} -""" -``` - -To sum up, the usage scenario of the merge attribute operator `:` is mainly the merge operation of the complex data structure list/dict/schema. In general, if there is no special requirement, the two attribute operators `=` and `+=` are used. Yes, so the best practice for attribute operators is as follows - -- For primitive types, use the `=` operator -- For the list type, the `=` and `+=` operators are generally used. Use `=` to completely override the list attribute, and use `+=` to add elements to the list -- For dict/schema types, the `:` operator is generally used - -In addition, when a configuration already exists, we can use the unpacking operator `**` to get all field values ​​of this configuration and modify the fields with different attribute operators, and get a new configuration - -```python -configBase = { - intKey = 1 # A attribute of type int - floatKey = 1.0 # A attribute of type float - listKey = [0] # A attribute of type list - dictKey = {key1: "value1"} # an attribute of type dict -} -configNew = { - **configBase # Unpack and inline configBase into configNew - intKey = 0 # Use override attribute operator = to override intKey attribute to 1 - floatKey = Undefined # Use override attribute operator = remove floatKey attribute - listKey += [1] # Add an attribute 1 to the end of the listKey attribute using the add attribute operator += - dictKey: {key2: "value2"} # Use the merge attribute operator: extend a key-value pair for the dictKey attribute -} -``` - -The output YAML result is: - -```yaml -configBase: - intKey: 1 - floatKey: 1.0 - listKey: - - 0 - dictKey: - key1: value1 -configNew: - intKey: 0 - listKey: - - 0 - - 1 - dictKey: - key1: value1 - key2: value2 -``` - -Alternatively two configuration blocks can be combined using the `|` operator: - -```python -configBase = { - intKey = 1 # A attribute of type int - floatKey = 1.0 # A attribute of type float - listKey = [0] # A attribute of type list - dictKey = {key1: "value1"} # an attribute of type dict -} -configNew = configBase | { # Use | to merge - intKey = 0 # Use override attribute operator = to override intKey attribute to 1 - floatKey = Undefined # Use override attribute operator = remove floatKey attribute - listKey += [1] # Add an attribute 1 to the end of the listKey attribute using the add attribute operator += - dictKey: {key2: "value2"} # Use the merge attribute operator: extend a key-value pair for the dictKey attribute -} -``` - -The output YAML is - -```yaml -configBase: - intKey: 1 - floatKey: 1.0 - listKey: - - 0 - dictKey: - key1: value1 -configNew: - intKey: 0 - listKey: - - 0 - - 1 - dictKey: - key1: value1 - key2: value2 -``` - -### The solution to the conflicting values on the attribute 'attr' between {value1} and {value2} error in KCL - -When an error like conflicting values on the attribute 'attr' between {value1} and {value2} occurs in KCL, it is usually a problem with the use of the merge attribute operator `:`, indicating that when the `value1` and `value2` configurations are merged, the attribute A conflict error occurred at `attr`. In general, modify the attr attribute of value2 to other attribute operators, use `=` to indicate overwrite, and use `+=` to indicate addition - -For example for the following code: - -```python -data = {k: 1} | {k: 2} # Error: conflicting values on the attribute 'k' between {'k': 1} and {'k': 2} -``` - -We can use the `=` attribute operator to modify it to the following form - -```python -data = {k: 1} | {k = 2} # Ok: the value 2 will override the value 1 through the `=` operator -``` - -## 38. How to traverse multiple elements at the same time in the for comprehension? - -In KCL, we can use for comprehension to traverse multiple elements - -- Example 1: two dimension element loop - -```python -dimension1 = [1, 2, 3] # The length of the dimension1 list is 3 -dimension2 = [1, 2, 3] # The length of the dimension2 list is 3 -matrix = [x + y for x in dimension1 for y in dimension2] # The length of the matrix list is 9 = 3 * 3 -``` - -The output YAML is: - -```yaml -dimension1: - - 1 - - 2 - - 3 -dimension2: - - 1 - - 2 - - 3 -matrix: - - 2 - - 3 - - 4 - - 3 - - 4 - - 5 - - 4 - - 5 - - 6 -``` - -- Example 2: Use for loop and `zip` built-in function to traverse multiple lists one by one by index - -```python -dimension1 = [1, 2, 3] # The length of the dimension1 list is 3 -dimension2 = [1, 2, 3] # The length of the dimension2 list is 3 -dimension3 = [d[0] + d[1] for d in zip(dimension1, dimension2)] # The length of the dimension1 list is 3 -``` - -The output YAML is: - -```yaml -dimension1: - - 1 - - 2 - - 3 -dimension2: - - 1 - - 2 - - 3 -dimension3: - - 2 - - 4 - - 6 -``` - -## 39. How to set default value for option function in KCL - -In KCL, when the value of the option attribute is None/Undefined or empty, we can use the logical `or` to directly specify a default value. - -```python -value = option("key") or "default_value" # When the value of key exists, take the value of option("key"), otherwise take "default_value" -``` - -Or use the default parameter of the option function. - -```python -value = option("key", default="default_value") # When the value of key exists, take the value of option("key"), otherwise take "default_value" -``` - -## 40. How to check that multiple attributes cannot be empty or set values at the same time in schema in KCL? - -In KCL, a single attribute of schema cannot be empty by default, unless we use the attribute optional operator `?`. - -```python -schema Person: - name: str # Required. - age: int # Required. - id?: int # Optional. -``` - -When it is necessary to check that the schema attributes cannot be empty at the same time or only one of them is empty, it needs to be written with the help of schema check expressions. The following takes two attributes `a`, `b` of the schema `Config` as an example to illustrate. - -- `a` and `b` attributes cannot be empty at the same time. - -```python -schema Config: - a?: str - b?: str - - check: - a or b -``` - -- `a` and `b` attributes can only have one or both empty (cannot exist at the same time or not empty) - -```python -schema Config: - a?: str - b?: str - - check: - not a or not b -``` - -## 41. A file is imported in KCL, but the schema defined by other KCL files in the same directory cannot be found. What might be the reason? - -It may be caused to import only this file in this folder. In KCL, import statement supports importing the entire folder, and also supports importing a certain KCL file under a certain folder. For the following directory structure. - -``` -. -├── kcl.mod -├── main.k -└── pkg - ├── pkg1.k - ├── pkg2.k - └── pkg3.k -``` - -There is an entry file main.k in the root directory. You can write the following code in main.k to import the entire pkg folder. At this time, all schema definitions in the pkg folder are visible to each other. - -```python -import pkg -``` - -We can also write the following code to import a single file pkg/pkg1.k. At this time, pkg1.k cannot find other files, namely the schema definitions under pkg2.k/pkg3.k - -```python -import pkg.pkg1 -``` - -## 42. How is indentation handled in KCL? - -In KCL, when a colon `:`, square bracket pair `[]` and curly bracket pair `{}` appear, we generally need to use newline + indentation, and the number of indented spaces for the same indentation level needs to be consistent. The indentation level is generally represented by 4 spaces. - -- colon `:` followed by newline and indent - -```python -"""Indentation in if statements""" -_a = 1 -_b = 1 -if _a >= 1: # colon `:` followed by newline and indent - if _a > 8: - _b = 2 - elif a > 6: - _b = 3 - -"""Indentation in schema statements""" -schema Person: # colon `:` followed by newline and indent - name: str - age: int -``` - -- opening bracket `[` followed by newline and indent - -```python -data = [ # opening bracket `[` followed by newline and indent - 1 - 2 - 3 -] # unindent before closing bracket ] -``` - -```python -data = [ # opening bracket `[` followed by newline and indent - i * 2 for i in range(5) -] # unindent before closing bracket `]` -``` - -- opening bracket `{` followed by newline and indent - -```python -data = { # opening bracket `{` followed by newline and indent - k1 = "v1" - k2 = "v2" -} # unindent before closing brace `}` -``` - -```python -data = { # opening bracket `{` followed by newline and indent - str(i): i * 2 for i in range(5) -} # unindent before closing brace `}` -``` - -## 43. How to write simple tests for KCL code? - -The current version of KCL does not support internal program debugging, we can use the assert statement and the print function to achieve data assertion and viewing. - -```python -a = 1 -print("The value of a is", a) -assert a == 1 -``` - -In addition, we can also use the kcl-test test tool to write KCL internal test cases - -Assuming there is a hello.k file, the code is as follows: - -```python -schema Person: - name: str = "kcl" - age: int = 1 - -hello = Person { - name = "hello kcl" - age = 102 -} -``` - -Construct the hello_test.k test file with the following contents: - -```python -schema TestPerson: - a = Person{} - assert a.name == 'kcl' - -schema TestPerson_age: - a = Person{} - assert a.age == 1 - -schema TestPerson_ok: - a = Person{} - assert a.name == "kcl" - assert a.age == 1 -``` - -Then execute the kcl-test command in the directory: - -``` -$ kcl-test -ok /pkg/to/app [365.154142ms] -$ -``` - -## 44. How to define and use functions in KCL? - -The schema structure acts as a function to a certain extent, and this function has the ability to have multiple input parameters and multiple output parameters. For example, the following code can implement the function of a Fibonacci sequence: - -```python -schema Fib: - n: int - value: int = 1 if n <= 2 else (Fib {n: n - 1}).value + (Fib {n: n - 2}).value - -fib8 = (Fib {n: 8}).value -``` - -The output is - -```yaml -fib8: 21 -``` - -A schema function that merges lists into dictionaries - -```python -schema UnionAll[data, n]: - _?: [] = data - value?: {:} = ((UnionAll(data=data, n=n - 1) {}).value | data[n] if n > 0 else data[0]) if data else {} - -schema MergeList[data]: - """Union all elements in a list returns the merged dictionary - - [{"key1": "value1"}, {"key2": "value2"}, {"key3": "value3"}] -> {"key1": "value1", "key2": "value2", "key3": "value3"} - """ - _?: [] = data - value?: {:} = (UnionAll(data=data, n=len(data) - 1) {}).value if data else {} -``` - -In addition, KCL supports defining a function using the `lambda` keyword: - -```python -func = lambda x: int, y: int -> int { - x + y -} -a = func(1, 1) # 2 -``` - -A lambda function has the following properties: - -- A lambda function takes the value of the last expression as the return value of the function, and an empty function body returns None. -- The return value type annotation can be omitted, the return value type is the type of the last expression value. -- There are no order-independent features in the function body, all expressions are executed in order. - -```python -_func = lambda x: int, y: int -> int { - x + y -} # Define a function using the lambda expression -_func = lambda x: int, y: int -> int { - x - y -} # Ok -_func = lambda x: int, y: int -> str { - str(x + y) -} # Error (int, int) -> str can't be assigned to (int, int) -> int -``` - -A lambda function cannot participate in any computation and can only be used in assignment and call statements. - -```python -func = lambda x: int, y: int -> int { - x + y -} -x = func + 1 # Error: unsupported operand type(s) for +: 'function' and 'int(1)' -``` - -```python -a = 1 -func = lambda x: int { - x + a -} -funcOther = lambda f, para: int { - f(para) -} -r = funcOther(func, 1) # 2 -``` - -The output is - -```python -a: 1 -r: 2 -``` - -We can define an anonymous function and call it directly - -```python -result = (lambda x, y { - z = 2 * x - z + y -})(1, 1) # 3 -``` - -Anonymous functions can be also used in for loops - -```python -result = [(lambda x, y { - x + y -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 3, 3, 4] -``` - -Functions can be defined and used in the KCL schema - -```python -_funcOutOfSchema = lambda x: int, y: int { - x + y -} -schema Data: - _funcInSchema = lambda x: int, y: int { - x + y - } - id0: int = _funcOutOfSchema(1, 1) - id1: int = _funcInSchema(1, 1) - id2: int = (lambda x: int, y: int { - x + y - })(1, 1) -``` - -The output YAML is - -```yaml -data: - id0: 2 - id1: 2 - id2: 2 -``` - -## 45. Why do we get an error when a variable is assigned an enumeration type (a literal union type)? - -In KCL, a attribute defined as a literal union type is only allowed to receive a literal value or a variable of the same literal union type during assignment. For example, the following code is correct: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -data = Data { - color = "Red" # Ok, can be assigned as "Red", "Yellow" and "Blue" -} -``` - -However the following code is wrong: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -_color = "Red" - -data = Data { - color = _color # Error: expect str(Red)|str(Yellow)|str(Blue), got str -} -``` - -This is because there is no type declared for the variable `_color`, it will be deduced by the KCL compiler as a `str` string type, so when a "larger" type `str` is assigned to a "smaller" type `"Red" | "Yellow" | "Blue"` will report an error, one solution is to declare a type for the `_color` variable, the following code is correct: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -_color: "Red" | "Yellow" | "Blue" = "Red" - -data = Data { - color = _color # Ok -} -``` - -Further, we can use type aliases to simplify enumeration (writing of literal union types), such as the following code: - -```python -type Color = "Red" | "Yellow" | "Blue" # Define a type alias, which can be reused in different places, reducing the amount of code writing - -schema Data: - color: Color - -_color: Color = "Red" - -data = Data { - color = _color # Ok -} -``` - -## 46. Procedural for loop - -KCL provides comprehensions and all/any/map/filter expressions for processing a collection element, which meets most needs, and provides a procedural for loop body. Providing a procedural for loop body is not very demanding from the current scenario, so there is no procedural for loop support yet. - -In addition, although KCL does not support procedural for loops, it is possible to "construct" corresponding procedural for loops through for loops and lambda functions. - -```python -result = [(lambda x: int, y: int -> int { - # Write procedural for loop logic in the lambda function. - z = x + y - x * 2 -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 2, 4, 4] -``` - -## 47. Default variables are immutable - -The immutability of KCL variables means that the exported variables starting with non-underscore `_` in the KCL top-level structure cannot be changed after initialization. - -```python -schema Person: - name: str - age: int - -a = 1 # a will be output to YAML, once assigned it cannot be modified -_b = 1 # _b The variable is named with an underscore and will not be output to YAML. It can be modified by multiple assignments -_b = 2 -alice = Person { - name = "Alice" - age = 18 -} -``` - -There are two ways of specifying that variables are immutable: - -- non-underscore top-level variables outside the schema - -```python -a = 1 # immutable exported variable -_b = 2 # mutable non-export variable -``` - -## 48. Is there a type like Go `interface{}`/`any` or Java `Object` in KCL? - -In KCL, we can use the `any` type annotation to define a variable to store any values such as integers, strings and schemas. For example: - -```python -schema Data: - id: int = 1 - -var_list: [any] = [1, "12", Data {}] -``` - -The output YAML is - -```yaml -var_list: - - 1 - - "12" - - id: 1 -``` - -In addition, we can also use the `typeof` function to determine the type of variables during KCL code execution: - -```python -schema Data1: - id: int = 1 - -schema Data2: - name: str = "name" - -data_list: [any] = [Data1 {}, Data2 {}] -data_type_list: [str] = [typeof(data) for data in data_list] -``` - -The output YAML is - -```yaml -data_list: - - id: 1 - - name: name -data_type_list: - - Data1 - - Data2 -``` - -## 49. How to develop a KCL plugin? - -KCL plugins are installed in the plugins subdirectory of KCL (usually installed in the `$HOME/.kcl/plugins` directory), or set through the `$KCL_PLUGINS_ROOT` environment variable. Besides, the `plugins` directory could also be placed at the `pwd` path. For plugin developers, plugins are managed in the [Git repository](https://github.com/kcl-lang/kcl-plugin), and the plugin repository can be cloned to this directory for development. - -KCL has built-in kcl-plugin scaffolding command to assist users to write KCL plug-ins in Python language, so that the corresponding plug-ins can be called in the KCL file to enhance the KCL language itself, such as accessing the network, reading and writing IO, CMDB query and encryption and decryption functions. - -``` -usage: kcl-plugin [-h] {list,init,info,gendoc,test} ... - -positional arguments: - {list,init,info,gendoc,test} - kcl plugin sub commands - list list all plugins - init init a new plugin - info show plugin document - gendoc gen all plugins document - test test plugin - -optional arguments: - -h, --help show this help message and exit -``` - -For example, if you want to develop a plugin named io, you can use the following command to successfully create a new io plugin - -``` -kcl-plugin init io -``` - -Then you can use the following command to get the root path of the plugin and cd to the corresponding io plugin directory for development - -``` -kcl-plugin info -``` - -For example, if you want to develop a function read_file to read a file, you can write python code in `plugin.py` of `$plugin_root/io`: - -```python -# Copyright 2020 The KCL Authors. All rights reserved. - -import pathlib - -INFO = { - 'name': 'io', - 'describe': 'my io plugin description test', - 'long_describe': 'my io plugin long description test', - 'version': '0.0.1', -} - - -def read_file(file: str) -> str: - """Read string from file""" - return pathlib.Path(file).read_text() - -``` - -In addition, you can write the corresponding test function in `plugin_test.py`, or you can directly write the following KCL file for testing: - -```python -import kcl_plugin.io - -text = io.read_file('test.txt') -``` - -You can also use the info command to view information about the io plugin - -``` -kcl-plugin info io -``` - -``` -{ - "name": "io", - "describe": "my io plugin description test", - "long_describe": "my io plugin long description test", - "version": "0.0.1", - "method": { - "read_file": "Read string from file" - } -} -``` - -Finally, the plugin that has written the test can be merged with MR in the `kcl_plugins` repository. - -## 50. How to do basic type conversion in KCL - -You can use the `int()`, `float()` function and `str()` function to convert the basic types between `int`, `float` and `str`. - -``` -_t = 1 - -t_str: str = str(_t) # you will get "t_str: '1'" -t_int: int = int(t_str) # you will get "t_int: 1" -t_float: float = float(t_str) # you will get "t_float: 1.0" -``` - -For more information about type conversion, see [KCL Builtin Types](https://kcl-lang.io/docs/reference/lang/tour#built-in-types) and [KCL Type System](https://kcl-lang.io/docs/reference/lang/tour#type-system). diff --git a/versioned_docs/version-0.5.2/community/contribute/git-guideline.md b/versioned_docs/version-0.5.2/community/contribute/git-guideline.md deleted file mode 100644 index 7d427c01..00000000 --- a/versioned_docs/version-0.5.2/community/contribute/git-guideline.md +++ /dev/null @@ -1,130 +0,0 @@ -# Git Commit Guide - -This document describes the matters needing attention when Git submits changes. If you refuse to accept the contents of this article, the submitted changes will not be accepted. - -## 1. About issue - -Before submitting an issue, please check the closed issue. There may already be an appropriate solution in the closed issue. - -If no suitable solution is found, we provide four templates to use when creating an issue. - -- Bug Report: If a bug is found, you can contact us by creating an issue through the bug report template. -- Enhancement: The developer has enhanced the tool, and can create an issue through the enhancement template to introduce the added content. -- Feature Request: If you want to add some new features or functions to the tool during use, you can create an issue through the Feature Request template to describe the new features. -- Ask a Question: If you have any questions, you can create an issue through the Ask a Question template to contact us. - -After selecting the appropriate template, you only need to fill in the required content on the template. If you find that there is no template or the template content is empty when creating the issue, you can feed back this problem to us through WeChat group, nail group or email. - -## 2. About Git Branch - -To contribute code to KCL, you must have a GitHub account so that you can push the code to your own branch and create pull requests. We recommend reference [Angular Specification]( https://github.com/angular/angular.js/blob/master/DEVELOPERS.md# -Git commit guidelines) name your own branches. - -The recommended format is as follows: - -``` -{type}-{a_short_description} -``` - -The branch name mainly includes two fields, which are separated by "-". Including: - -- `{type}`: the type of the current branch content. -- `{a_short_description}`: A short description of the main content of this branch. - -For example, Alice first transfers the Fork warehouse to his own account, and then creates a branch with the corresponding name 'alice: fix output fmt bug' (Alice's account is before the colon) to fix the output formatting bug. - -## 3. 关于 Git Commit - -We refer to [Commitizen](https://github.com/commitizen/cz-cli) to write a Commit Message. - -``` -Note: If you directly use Commit to generate a Commit Message, please note that -It is a tool for developers to manage commit. It is not related to the project itself, so it is an intermediate product generated by Commiten -(For example, the node_modules file directory) may not be in the project. gitignore file. - -You can git add {filename} select the file to submit and ignore the intermediate product. -Or you can add the following content to the. gitignore file and automatically ignore the intermediate products: -# commitizen -package.json -package-lock.json -node_modules/* -``` - -If you manually write a commit Message, we also recommend [Commiten](https://github.com/commitizen/cz-cli) for the commit message format. - -``` -{type} ( {component_or_file} ) {a_short_description} -{a_longer_description} -BREAKING CHANGE: {breaking_change_description}. -{linked issue} -``` - -It mainly includes 6 fields: - -- `{type}`: the type of the branch corresponding to the current commit. -- `{component_or_file}`: the name of the module or file that the current commit changes. -- `{a_short_description}`: A short description describes the content of the commit. -- `{a_longer_description}`: The detailed description is used to introduce the content in the commit. -- `{breaking_change_description}`: If the commit contains broken compatibility changes, the impact of compatibility changes needs to be introduced. -- `{linked issue}`: the issue associated with the current commit. - -Where `{breaking_change_description}` and `{linked issue}` can be omitted if the commit does not contain compatibility breaking changes and associated issues. - -For example, the commit created by Alice in branch 'alice: fix output fmt bug'. - -``` -fix(kcl-printer): fix an output format bug in kcl-printer - -There is an output format bug in kcl-printer because ..., -So, The calling of method "XXX" is replaced by "HHHH"..., -... - ---If there is no change to break the compatibility and the associated issue, the following contents can be omitted. -BREAKING CHANGE: This change maybe cause ....... - -fix #123 -``` - -## 4. About pull request - -Before submitting a PR, priority may be given to the following issues: - -- Please check the closed PRs first. There may be completed solutions in the closed PRs. -- We suggest that before submitting the change, submit a corresponding issue to describe the problems to be solved in the change, and associate the PR corresponding to the change with the issue. -- After submitting the PR to us, please sign [Contributor License Agreement (CLA)] (# cla). If you refuse to sign, we will not accept the PR. -- Make sure that each change creates a new branch and names the branch according to the specifications mentioned above. -- PR should not exceed two commit at a time. Please compress the extra commit with squash and write a commit message according to the specifications mentioned above. -- We provide [PR template](https://github.com/kcl-lang/.github/blob/main/.github/PULL_REQUEST_TEMPLATE.md). You only need to add the content required in the template. If you find no template or the template content is empty when creating a PR, you can feed back this problem to us through WeChat group, nail group or email. - -We suggest that the PR title be consistent with the branch name and the commit message style: - -``` -{type} ( {component_name_or_file_name} ) :{a_short_description} -``` - -比如,Alice 为分支`fix/alice/fix_output_fmt_bug`创建的PR名称。 - -For example, Alice creates the PR name `fix/alice/fix_output_fmt_bug` for one branch. - -``` -fix(kcl-printer): fix an output format bug in kcl-printer. -``` - -## 5. Supported PR Types - -``` -- feat: -- New features have been added. -- fix: -- Bug is repaired. -- docs: -- The document part has been modified. -- style: -- The modification of code format does not affect the functions of the code, such as deleting redundant spaces, code indentation, etc. -- refactor: -- refactoring code without changing its function. -- perf: -- Performs performance optimization on the code. -- test: -- Add or adjust existing test cases. -- build: -- Adjust the build system or external dependent libraries. -- ci: -- The configuration file or script of the CI has been adjusted. -- choice: -- Adjustments to other parts of the source code and test files. -- reverse: -- Rollback commit. -``` - -## 6. Contributor License Agreement (CLA) - -After the PR is submitted to us for the first time, the CLA check in the PR will fail and prompt to sign the CLA. You can reply "I have read the CLA Document and I hereby sign the CLA" between your accounts in PR to agree to sign the CLA, and then manually restart the failed CLA check action. After PR is successfully merged, it will be locked and cannot be modified. diff --git a/versioned_docs/version-0.5.2/community/release-policy/kcl.md b/versioned_docs/version-0.5.2/community/release-policy/kcl.md deleted file mode 100644 index a24e1509..00000000 --- a/versioned_docs/version-0.5.2/community/release-policy/kcl.md +++ /dev/null @@ -1,39 +0,0 @@ -# KCL Release Policy - -KCL 开发团队采用 [语义化版本](https://semver.org/lang/zh-CN/) 来简化管理。版本格式:主版本号.次版本号.修订号。版本号递增规则如下:主版本号对应不兼容的 API 修改,次版本号对应向下兼容的功能性新增,修订号对应向下兼容的问题修正。总体目标是每一个半月发布一个特性增强的次要版本,根据需要不定期发布其他版本的修订。 - -KCL 项目版本发布策略如下: - -- 主版本号:当进行重大的架构调整或者加入重大的新功能时,需要提升主版本号。对于 KCL 项目来说,目前的主版本号为 0。 -- 次版本号:当添加的功能和特性有较大的变化时,提升次版本号。目前的次版本号为 5,2023 年度会相继发布 0.5, 0.6, 0.7 版本。 -- 修订号:通过修复漏洞或者改进性能来更新程序时,会提升修订号,修订号从 0 开始计数以此加 1。 -- 发布周期:在未达到 v1.0.0 版本之前,计划每隔 3 个月发布一个新的次要版本。在此期间,需要持续收集用户反馈,并进行必要的修复和改进。 -- 发布流程:在发布新版本之前,需要进行严格的测试和审核,确保新版本的质量。封板并测试完成后,会在 Github 上发布新版本的源代码,二进制和镜像,并提供详细的文档和使用指南。 -- 版本支持:我们将对最新的版本提供长期支持,包括漏洞修复和安全更新。对于旧版本,我们将提供有限的支持,仅在必要时进行修复。 - -## 发布流程与规则 - -- 特性开发:main 分支主干开发,分支发布,block 用户使用的问题和严重的 bug, 安全隐患,高优先级解决,尽可能保持在一周内收敛,高于一般的功能研发。 -- 迭代周期:我们的迭代周期通常为 3 个月,即每 3 个月发布一个新的次要版本。 -- 版本规划:发版前两周产出 alpha 版本,前一周产出 beta 版本,alpha 版本仍可进行特性合并,beta 版本只合并错误修复,最终产出正式版本并打 tag 作为长期保存的 release 分支。 -- 发版计划:在每个发布周期开始时制定详细的发版计划(Github Milestone),包括发布日期、版本号、功能列表和测试计划等。需要尽可能地遵守发版计划,确保按时发布新版本。 -- 发布前测试:在发布新版本之前,需要进行全面的测试,包括单元测试、集成测试,模糊测试,压测,用户验收测试等。只有经过测试并无问题后,我们才会发布新版本。 -- 版本回滚:如果在发布后发现了严重的问题,需要立即回滚版本,并尽快修复问题。并通过邮件、社交媒体等渠道及时通知用户,并提供解决方案。 -- 发布文档:需要在发布时提供详细的文档,包括发布说明、更新日志、API 文档和使用指南等,帮助用户了解和使用新版本。在 KCL 中,我们统一在 KCL 网站进行维护。 -- 版本兼容性:在发布新版本时,需要尽可能保持兼容性,以确保用户无需进行过多的修改和适应。KCL 还没有达到 v1,暂时没有兼容性保证。KCL 的目标是尽可能少地进行重大更改,不应轻率地考虑对语言的更改,为了语言自身更好地演进和发展,一般认为更改具有重大好处时才会进行(较好地解决了目标场景的问题或者提升了绝大用户的使用体验)。对于可能引入兼容性问题的功能或变更,提供相应的提示和解决方案,同时会提供逐步升级的指南或提供自动迁移的工具,以帮助用户平滑地迁移到新版本。 - -## 发布组件 - -![](/img/docs/community/release-policy/kcl-components.png) - -每次版本发布时,KCL 相关所有组件保持一个依赖同一个 KCL 核心主要版本,整体采用树形结构组织依赖顺序发布并进行回归测试,直到发布测试完成,尽力避免三角依赖,禁止循环依赖。 - -## 一个 Feature 的生命周期 - -- 设计方案/文档:通过 Issue 回答清楚这个 feature 的动机是什么,它解决什么问题以及目标是什么,用户需求和用户故事是怎样的;这个 feature 做什么,如何做,难度怎样,需要多长时间,依赖项,需要做什么测试等。(Tips: 大的设计尽量拆分成小的设计,通过权衡和广泛的调研找到一个简单且可持续的解决方案,并且具备一定得到可扩展以适应未来的业务或技术变化,通过持续讨论和方案评审确定最终设计)。 -- 编写代码:通过高频小改动进行迭代、持续沟通和协作,提前设计单元测试、集成测试和 benchmark 等测试用例,确保编写代码 100% 测试覆盖,注释完整和逻辑清晰,并通过 Demo 演示持续收集反馈。 -- 文档撰写:在 [KCL 网站](https://kcl-lang.io) 中更新用户文档。 -- 测试和反馈:在发布功能之前,让一些同行/用户通过**随循文档**而不是口述来尝试和测试这些新功能。接收反馈并改进。 -- 发布和公告:撰写 Release Note, PR 文章,场景和新特性解读等以及渠道宣发等。 - -> 注:以上所有信息全是公开的,需要透出给所有社区研发者进行参与、讨论和贡献。 diff --git a/versioned_docs/version-0.5.2/community/release-policy/roadmap.md b/versioned_docs/version-0.5.2/community/release-policy/roadmap.md deleted file mode 100644 index df220576..00000000 --- a/versioned_docs/version-0.5.2/community/release-policy/roadmap.md +++ /dev/null @@ -1,3 +0,0 @@ -# Roadmap - -![](/img/docs/community/release-policy/roadmap.jpg) diff --git a/versioned_docs/version-0.5.2/reference/lang/error/exception.md b/versioned_docs/version-0.5.2/reference/lang/error/exception.md deleted file mode 100644 index 92c527a6..00000000 --- a/versioned_docs/version-0.5.2/reference/lang/error/exception.md +++ /dev/null @@ -1,1427 +0,0 @@ ---- -title: "KCL Errors and Warnings" -linkTitle: "KCL Errors and Warnings" -type: "docs" -weight: 2 -description: KCL Errors and Warnings ---- - -The articles in this section of the documentation explain the diagnostic error and warning messages that are generated by the KCL. - -**Important:** -**The KCL can report many kinds of errors and warnings. After an error or warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not apply to your project. When you correct issues in your project, always start with the first error or warning that's reported and rebuild often. One fix may make many subsequent errors go away.** - -In the following sections you will find: - -[KCL Syntax Error (E1xxx)](#11-kcl-syntax-error-e1xxx) : The KCL may reports KCL syntax errors when illegal syntax is used in KCL program. - -[KCL Compile Error (E2xxx)](#12-kcl-compile-error-e2xxx): The KCL may reports KCL compile errors when the KCL program conforms to the KCL syntax but does not conform to the KCL semantics. - -[KCL Runtime Error (E3xxx)](#13-kcl-runtime-error-e3xxx): The KCL may report KCL runtime errors when the virtual machine executing a KCL program that passes the compilation. - -[KCL Compile Warning (W2xxx)](#14-kcl-compile-warning-w2xxx): When the compiler compiles KCL programs and finds possible potential errors, such warnings will be reported by KCL. - -## 1.1 KCL Syntax Error (E1xxx) - -This section mainly includes KCL errors: - -| ewcode | KCL exception | messages | -| ------ | ------------------------------------------------------------------- | ----------------------- | -| E1001 | [InvalidSyntaxError](#111-invalidsyntaxerror-e1001) | Invalid syntax | -| E1002 | [KCLTabError](#112-kcltaberror-e1002) | Tab Error | -| E1003 | [KCLIndentationError](#113-kclindentationerrore1003) | Indentation Error | -| E1I37 | [IllegalArgumentSyntaxError](#114-illegalargumentsyntaxerror-e1i37) | Illegal argument syntax | - -### 1.1.1 InvalidSyntaxError (E1001) - -KCL will report `InvalidSyntaxError` when KCL has a syntax error. - -The `ewcode` of `InvalidSyntaxError` is `E1001`. - -For example: - -```python -a, b = 1, 2 # Multiple assign is illegal in KCL syntax -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> /syntax_error/general/multiple_assign/case0/main.k:1:2 - | -1 | a, b = 1, 2 # Multiple assign is illegal in KCL syntax - | ^ expected statement - | -``` - -Possible resolution: - -- Check and fix KCL syntax errors based on the KCL Language Standard - -### 1.1.2 KCLTabError - -KCL will report `KCLTabError` when KCL has a tab and white space syntax error. - -In KCL, it is forbidden to mix tabs and four spaces in one indentation block. And we recommend only using white spaces or tabs for indentation in the entire KCL project, don’t mix them. - -For example: - -```python -schema Person: - name: str # begin with a tab - age: int # begin with four white spaces, - # and four white spaces != tab in the env -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> File /syntax_error/tab/tab_error_0/main.k:6:5 - | -3 | age: int = 1 - | ^ inconsistent use of tabs and spaces in indentation - | -``` - -Possible resolution: - -- Only use a tab or four white spaces in KCL, do not mix them. - -### 1.1.3 KCLIndentationError - -KCL will report `KCLIndentationError` when KCL has an indentation syntax error. - -The KCL syntax includes indentation. A tab or four white spaces in KCL represents an indentation. The other cases will be regarded as syntax errors by KCL. - -For example: - -```python -schema Person: - name: str # a tab or four white spaces is legal. - age: int # three white spaces are illegal - info: str # two white spaces is illegal -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> /syntax_error/indent/indent_error_0/main.k:3:4 - | -3 | age: int # three white spaces are illegal - | ^ unindent 3 does not match any outer indentation level - | -``` - -Possible resolution: - -- Only use a tab or four white spaces in the KCL program for indentation. - -### 1.1.4 IllegalArgumentSyntaxError (E1I37) - -KCL will report `IllegalArgumentSyntaxError` when KCL has an illegal argument in KCL syntax. - -For example: - -```python -# Parameters without default values -# must be in front of parameters with default values. -a = option(type="list", default={"key": "value"}, "key1") -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> /option/type_convert_fail_2/main.k:3:57 - | -3 | a = option(type="list", default={"key": "value"}, "key1") - | ^ positional argument follows keyword argument - | -``` - -Possible resolution: - -```python -func(input_1, ..., input_n, param_with_key_1 = input_with_key_1, ..., param_with_key_n = input_with_key_n) -``` - -## 1.2 KCL Compile Error (E2xxx) - -This section mainly includes KCL errors: - -| ewcode | KCL exception | messages | -| ------ | ---------------------------------------------------------------------- | --------------------------------------------------- | -| E2F04 | [CannotFindModule](#121-cannotfindmodulee2f04) | Cannot find the module | -| E2F05 | [FailedLoadModule](#122-failedloadmodulee2f05) | Failed to load module | -| E2H13 | [UnKnownDecoratorError](#123-unknowndecoratorerrore2h13) | UnKnown decorator | -| E2H14 | [InvalidDecoratorTargetError](#124-invaliddecoratortargeterrore2h14) | Invalid Decorator Target | -| E2C15 | [MixinNamingError](#125-mixinnamingerrore2c15) | Illegal mixin naming | -| E2C16 | [MixinStructureIllegal](#126-mixinstructureillegale2c16) | Illegal mixin structure | -| E2B17 | [CannotAddMembersComplieError](#127-cannotaddmemberscomplieerrore2b17) | Cannot add members to a schema | -| E2B20 | [IndexSignatureError](#128-indexsignatureerrore2b20) | Invalid index signature | -| E2G22 | [TypeComplieError](#129-typecomplieerrore2g22) | The type got is inconsistent with the type expected | -| E2L23 | [CompileError](#1210-compileerrore2l23) | A complie error occurs during compiling | -| E2L25 | [KCLNameError](#1211-kclnameerrore2l25) | Name Error | -| E2L26 | [KCLValueError](#1212-kclvalueerrore2l26) | Value Error | -| E2L27 | [KCLKeyError](#1213-kclkeyerrore2l27) | Key Error | -| E2L28 | [UniqueKeyError](#1214-uniquekeyerrore2l28) | Unique key error | -| E2A29 | [KCLAttributeComplieError](#1215-kclattributecomplieerrore2a29) | Attribute error occurs during compiling | -| E2D32 | [MultiInheritError](#1216-multiinheriterrore2d32) | Multiple inheritance is illegal | -| E2D34 | [IllegalInheritError](#1217-illegalinheriterrore2d34) | Illegal inheritance | -| E2I36 | [IllegalArgumentComplieError](#1218-illegalargumentcomplieerrore2i36) | Illegal argument during compiling | -| E3L41 | [ImmutableCompileError](#1219-immutablecompileerror-e3l41) | Immutable variable is modified | - -### 1.2.1 CannotFindModule(E2F04) - -KCL will report `CannotFindModule` when KCL imports a module that does not exist. - -The `ewcode` of `CannotFindModule` is `E2F04`. - -For example: - -```python -import .some0.pkg1 as some00 # some0 not found in package - -Name1 = some00.Name # some0.pkg1.name -``` - -The KCL program will cause the following error message. - -```shell -error[E2F04]: CannotFindModule - --> import_abs_fail_0/app-main/main.k:1:1 - | -1 | import .some0.pkg1 as some00 # some0 not found in package - | Cannot find the module .some0.pkg1 - | -``` - -Possible resolution: - -- Add the import module file under the import path. - -### 1.2.2 FailedLoadModule(E2F05) - -KCL will report `FailedLoadModule` when an error occurs during loading a KCL external package. - -The `ewcode` of `FailedLoadModule` is `E2F05`. - -Possible resolution: - -- Check whether the module file is readable. -- Check whether the module file is a KCL file. - -### 1.2.3 UnKnownDecoratorError(E2H13) - -KCL will report `UnKnownDecoratorError` when an unknown decorator is used in KCL. - -The `ewcode` of `UnKnownDecoratorError` is `E2H13`. - -For example: - -```python -@err_deprecated # It is an unknown decorator -schema Person: - firstName: str = "John" - lastName: str - name: str - -JohnDoe = Person { - name: "deprecated" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> deprecated/unknown_fail_1/main.k:1:2 - | -1 | @err_deprecated # 这是一个非法的装饰器 - | ^ UnKnown decorator err_deprecated - | -``` - -Possible resolution: - -- Check whether the decorator exists. - -### 1.2.4 InvalidDecoratorTargetError(E2H14) - -KCL will report `InvalidDecoratorTargetError` when the target cannot be the target of the decorator. - -The `ewcode` of `InvalidDecoratorTargetError` is `E2H14`. - -Possible resolution: - -- Check whether the decorator in KCL is illegal. - -### 1.2.5 MixinNamingError(E2C15) - -KCL will report `MixinNamingError` when a mixin name does not end with 'Mixin'. - -The `ewcode` of `MixinNamingError` is `E2C15`. - -For example: - -```python -schema Person: - firstName: str - lastName: str - fullName: str - -schema Fullname: # It is a mixin, but 'Fullname' is not end with 'Mixin - fullName = "{} {}".format(firstName, lastName) - -schema Scholar(Person): - mixin [Fullname] - school: str - -JohnDoe = Scholar { - "firstName": "John", - "lastName": "Doe", - "fullName": "Doe Jon" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2D34]: IllegalInheritError - --> mixin/invalid_name_failure/main.k:10:12 - | -10 | mixin [Fullname] - | ^ illegal schema mixin object type 'Fullname' - | -``` - -Possible resolution: - -- If the schema is a mixin, then the name of the schema should end with Mixin. - -### 1.2.6 MixinStructureIllegal(E2C16) - -KCL will report `MixinStructureIllegal` when the KCL structure is illegal. - -The `ewcode` of `MixinStructureIllegal` is `E2C16`. - -Possible resolution: - -- Check the structure of schema as Mixin. - -### 1.2.7 CannotAddMembersComplieError(E2B17) - -KCL will report `CannotAddMembersComplieError` when members that are not in the schema are used. - -The `ewcode` of `CannotAddMembersComplieError` is `E2B17`. - -For example: - -```python -schema Girl: - gender: str = "female" - -alice = Girl { - "first": "alice", # "first" can not be found in schema Girl - "last": " Green", # "last" can not be found in schema Girl - "age": 10 # "age" can not be found in schema Girl -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:5:5 - | -5 | "first": "alice", - | ^ Cannot add member 'first' to schema 'Girl' - | - -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:6:5 - | -6 | "last": " Green", - | ^ Cannot add member 'last' to schema 'Girl' - | - -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:7:5 - | -7 | "age": 10 - | ^ Cannot add member 'age' to schema 'Girl' - | -``` - -Possible resolution: - -- Add the members to the schema. -- Remove the using of the members not exists - -### 1.2.8 IndexSignatureError(E2B20) - -The `ewcode` of `IndexSignatureError` is `E2B20`. - -KCL will report `IndexSignatureError` when: - -1. Multiple index signatures in one schema. - -For example: - -```python -schema Data: - [str]: str - [str]: int # Multiple index signatures in one schema. - -data = Data { - name: "test" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError ----> index_signature/fail_1/main.k:3:5 - | -3 | [str]: int - | 5 ^ only one index signature is allowed in the schema - | -``` - -Possible resolution: - -- Remove the extra index signature in the schema. - -2. The name of index signature attributes has the same name that conflicts with other attributes in the schema. - -For example: - -```python -schema Data: - name: str # name - [name: str]: str # the same name with the above attribute - -data = Data { - name: "test" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: IndexSignatureError - --> index_signature/fail_2/main.k:3:5 - | -3 | [name: str]: str # the same name with the above attribute - | ^ index signature attribute name 'name' cannot have the same name as schema attributes - | -``` - -Possible resolution: - -- Remove attributes or index signatures that have conflicts with the same name in the schema, or change their names. - -3. Schema index signature value type has conflicts with the instance of schema. - -For example: - -```python -schema Data: - [str]: int - -data = Data { - name: "test" # Conflict with [str]:int, "test" is a string. -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> index_signature/fail_3/main.k:5:5 - | -5 | name: "test" # Conflict with [str]:int, "test" is a string. - | ^ expected int, got str(test) - | -``` - -Possible resolution: - -- Check that the type of schema index signature is consistent with the attribute type in the schema instance. - -4. Schema index signature has conflicts with schema. - -For example: - -```python -schema Data: - count: int # got int - [str]: str # except str - -data = Data { - count: 1 -} -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: IndexSignatureError - --> index_signature/fail_4/main.k:2:5 - | -2 | count: int - | ^ the type 'int' of schema attribute 'count' does not meet the index signature definition [str]: str - | -``` - -Possible resolution: - -- Change schema for index signature or change index signature for schema. - -### 1.2.9 TypeComplieError(E2G22) - -KCL will report `TypeComplieError` when a type error occurs in compiling type check. - -The `ewcode` of `TypeComplieError` is `E2G22`. - -For example: - -```python -schema Person: - firstName: str - lastName: int - -JohnDoe = Person { - "firstName": "John", - "lastName": "Doe" # Type Error,lastName: int,“Doe” is a string. -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> type/type_fail_0/main.k:7:5 - | -7 | "lastName": "Doe" # Type Error,lastName: int,“Doe” is a string. - | ^ expected int, got str(Doe) - | - - --> type/type_fail_0/main.k:3:5 - | -3 | lastName: int - | ^ variable is defined here, its type is int, but got str(Doe) - | -``` - -Possible resolution: - -- Check that the type of value assigned to a variable is consistent with the type of the variable. - -### 1.2.10 CompileError(E2L23) - -The `ewcode` of `CompileError` is `E2L23`. - -KCL will report `CompileError` when: - -1. unsupport type union. - -For example: - -```python -_data = [1, 2, 3] -_data |= "value" -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> union/fail/fail_1/main.k:2:1 - | -2 | _data |= "value" - | ^ unsupported operand type(s) for |: '[int]' and 'str(value)' - | -``` - -Possible resolution: - -1. unsupported operand type. - -For example: - -```python -a = None -b = 1 + None # Unsupport operand type + for int and None -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> operator/operator_fail_0/main.k:2:5 - | -2 | b = 1 + None # Unsupport operand type + for int and None - | ^ unsupported operand type(s) for +: 'int(1)' and 'NoneType' - | -``` - -Possible resolution: - -- Adjust the operator so that it supports both operand types. -- Adjust the operands so that they conform to the constraints of the operator at the same time. - -1. variable is not defined. - -For example: - -```python -a = 1 -b = "${c + 1}" # 'c' is not defined -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> var_not_define_fail_0/main.k:2:8 - | -2 | b = "${c + 1}" # 'c' is not defined - | ^ name 'c' is not defined - | -``` - -Possible resolution: - -- Define undefined variables. -- Remove the undefined variable from the expression. - -1. invalid assign expression. - -For example: - -```python -# pkg.k -a = 1 - -# main.k -import pkg -pkg.a |= 2 -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> pkg_inplace_modify_1/main.k:3:1 - | -6 | pkg |= 2 - | ^ unsupported operand type(s) for |: 'module 'pkg'' and 'int(2)' - | -``` - -Possible resolution: - -- Check the assignment expression. - -1. invalid string expression. - -For example: - -```python -a = 1 -b = "${b = a + 1}" # Invalid string interpolation expression -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> invalid_format_value_fail_0/main.k:2:5 - | -2 | b = "${b = a + 1}" - | 5 ^ invalid string interpolation expression 'b = a + 1' - | -``` - -Possible resolution: - -- Check the string expression. - -1. invalid loop variable. - -For example: - -```python -data = {"key1": "value1", "key2": "value2"} -dataLoop = [i for i, j, k in data] # the number of loop variables can only be 1 or 2 -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> dict/invalid_loop_var_fail_0/main.k:2:25 - | -2 | dataLoop = [i for i, j, k in data] # the number of loop variables can only be 1 or 2 - | ^ the number of loop variables is 3, which can only be 1 or 2 - | -``` - -### 1.2.11 KCLNameError(E2L25) - -KCL will report `KCLNameError` when a name error occurs in compiling. - -The `ewcode` of `KCLNameError` is `E2L25`. - -### 1.2.12 KCLValueError(E2L26) - -KCL will report `KCLValueError` will be raised when a value error occurs in compiling. - -The `ewcode` of `KCLValueError` is `E2L25`. - -### 1.2.13 KCLKeyError(E2L27) - -KCL will report `KCLKeyError` will be raised when a key error occurs in compiling. - -The `ewcode` of `KCLKeyError` is `E2L25`. - -### 1.2.14 UniqueKeyError(E2L28) - -KCL will report `UniqueKeyError` when duplicate names appear in the KCL code. - -The `ewcode` of `UniqueKeyError` is `E2L28`. - -For example: - -```python -schema Person: - name: str = "kcl" - age: int = 1 - -schema Person: - aa: int - -x0 = Person{} -x1 = Person{age:101} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L28]: UniqueKeyError - --> /schema/same_name/main.k:5:8 - | -5 | schema Person: - | ^ Unique key error name 'Person' - | - - --> /schema/same_name/main.k:1:8 - | -1 | schema Person: - | ^ The variable 'Person' is declared here - | -``` - -Possible resolution: - -- Check if the name with error has been used. - -### 1.2.15 KCLAttributeComplieError(E2A29) - -KCL will report `KCLAttributeComplieError` when KCL has an illegal attribute in the schema. - -The `ewcode` of `KCLAttributeComplieError` is `E2A29`. - -For example: - -```python -# pkg -schema A: - field_A: str - -# main -import pkg as p - -a = p.D + 1 -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> /import/module/no_module_attr_fail_0/main.k:4:5 - | -4 | a = p.D + 1 - | ^ module 'pkg' has no attribute D - | -``` - -Possible resolution: - -- Check for the existence of the schema attribute when using it. - -### 1.2.16 MultiInheritError(E2D32) - -KCL will report `MultiInheritError` when multiple inheritance appears in the schema. - -The `ewcode` of `MultiInheritError` is `E2D32`. - -For example: - -```python -schema Person: - firstName: str - lastName: str - -schema KnowledgeMixin: - firstName: int - subject: str - -schema Scholar(KnowledgeMixin, Person): - school: str -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> /schema/inherit/multi_inherit_fail_1/main.k:9:30 - | -9 | schema Scholar(KnowledgeMixin, Person): - | ^ expected one of [")"] got , - | -``` - -Possible resolution: - -- Check the inheritance structure of the program, and multi-inheritance is not supported in KCL. - -### 1.2.17 IllegalInheritError(E2D34) - -KCL will report `IllegalInheritError` when an illegal inheritance occurs in the schema. - -The `ewcode` of `IllegalInheritError` is `E2D34`. - -For example: - -```python -schema FullnameMixin: - fullName = "{} {}".format(firstName, lastName) - -schema Scholar(FullnameMixin): # mixin inheritance is illegal - school: str -``` - -The KCL program will cause the following error message. - -```shell -error[E2D34]: IllegalInheritError - --> /schema/inherit/inherit_mixin_fail/main.k:4:16 - | -4 | schema Scholar(FullnameMixin): - | ^ invalid schema inherit object type, expect schema, got 'FullnameMixin' - | -``` - -Possible resolution: - -- Schema supports single inheritance of schema in KCL. - -### 1.2.18 IllegalArgumentComplieError(E2I36) - -KCL will report `IllegalArgumentComplieError` when the argument of option in KCL is illegal. - -The `ewcode` of `IllegalArgumentComplieError` is `E2I36`. -For example: - -```python -a = option("key") - -# kcl main.k -D key=value= -# key=value= is an illegal expression -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError -Invalid value for top level arguments -``` - -Possible resolution: - -- Check whether the KCL option arguments are legal. - -### 1.2.19 ImmutableCompileError (E3L41) - -KCL will report `ImmutableCompileError` when the value of the immutable variable changes. - -The `ewcode` of `ImmutableCompileError` is `E3L41`. - -For example: - -```python -a = 2147483646 -a += 1 -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: ImmutableError - --> augment_assign/main.k:2:1 - | -2 | a += 1 - | ^ Immutable variable 'a' is modified during compiling - | - - --> augment_assign/main.k:1:1 - | -1 | a = 2147483646 - | ^ The variable 'a' is declared here firstly - | -note: change the variable name to '_a' to make it mutable -``` - -Possible resolution: - -- Set immutable variables changed to private or remove immutable variables. - -## 1.3 KCL Runtime Error (E3xxx) - -This section mainly includes KCL errors: - -| ewcode | KCL exception | messages | -| ------ | ---------------------------------------------------------------------- | --------------------------------------------------- | -| E3F06 | [RecursiveLoad](#131-recursiveload-e3f06) | Recursively loading module | -| E3K04 | [FloatOverflow](#132-floatoverflow-e3k04) | Float overflow | -| E3K09 | [IntOverflow](#133-intoverflow-e3k09) | Integer overflow | -| E3N11 | [DeprecatedError](#134-deprecatederror-e3n11) | Deprecated error | -| E3A30 | [KCLAttributeRuntimeError](#135-kclattributeruntimeerror-e3a30) | Attribute error occurs at runtime | -| E3G21 | [TypeRuntimeError](#136-typeruntimeerror-e3g21) | The type got is inconsistent with the type expected | -| E3B17 | [SchemaCheckFailure](#137-schemacheckfailure-e3b17) | Schema check is failed to check condition | -| E3B19 | [CannotAddMembersRuntimeError](#138-cannotaddmembersruntimeerrore3b19) | Cannot add members to a schema | -| E3M38 | [EvaluationError](#139-evaluationerrore3m38) | Evaluation failure | -| E3M39 | [InvalidFormatSpec](#1310-invalidformatspec-e3m39) | Invalid format specification | -| E3M40 | [KCLAssertionError](#1311-kclassertionerror-e3m40) | Assertion failure | -| E3M44 | [ImmutableRuntimeError](#1312-immutableruntimeerror-e3m44) | Immutable variable is modified | -| E2D33 | [CycleInheritError](#1313-cycleinheriterror-e2d33) | Cycle Inheritance is illegal | -| E3M42 | [KCLRecursionError](#1314-kclrecursionerror-e3m42) | Recursively reference | - -### 1.3.1 RecursiveLoad (E3F06) - -KCL will report `RecursiveLoad` when a cycle import of external packages occurs in KCL. - -The `ewcode` of `RecursiveLoad` is `E2F06`. - -For example: - -```python -# module.k -import main # module.k imports main.k - -print('module') - -# main.k -import module # main.k imports module.k - -print('main') -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /import/recursive_import_fail/main.k:4 - | -2 | import module # main.k imports module.k - | ^ There is a circular import reference between module main and module - | -``` - -Possible resolution: - -- Check whether there is a circle import in KCL. - -### 1.3.2 FloatOverflow (E3K04) - -KCL will report `FloatOverflow` when a floating-point number overflows in KCL. - -The `ewcode` of `FloatOverflow` is `E3K04`. - -For example: - -```python -uplimit = 3.402823466e+39 -epsilon = 2.220446049250313e-16 -a = uplimit * (1 + epsilon) - -# kcl main.k -r -d -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /range_check_float/overflow/number_0/main.k:3:1 - | -3 | a = uplimit * (1 + epsilon) - | 3.4028234660000003e+39: A 32-bit floating point number overflow - | -``` - -Possible resolution: - -- Check whether the value of the float is the float range supported by KCL. - -### 1.3.3 IntOverflow (E3K09) - -KCL will report `IntOverflow` when an integer number overflows in KCL. - -The `ewcode` of `IntOverflow` is `E3K09`. - -For example: - -```python -_a = 9223372036854775807 -_a += 1 - -# kcl test.k -d -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /range_check_int/augment_assign_fail_1/main.k:2:1 - | -2 | _a += 1 - | 9223372036854775808: A 64 bit integer overflow - | -``` - -Possible resolution: - -- Check whether the value of the integer is the integer range supported by KCL. - -### 1.3.4 DeprecatedError (E3N11) - -KCL will report `DeprecatedError` when a deprecated variable is used and the strict is True. - -The `ewcode` of `DeprecatedError` is `E3N11`. - -For example: - -```python -schema Person: - firstName: str = "John" - lastName: str - @deprecated(version="1.16", reason="use firstName and lastName instead", strict=True) - name: str - -JohnDoe = Person { - name: "deprecated" # name is deprecated and strict is True -} -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /range_check_float/overflow/number_0/main.k:7:1 - | -7 | JohnDoe = Person { - | name was deprecated since version 1.16, use firstName and lastName instead - | -``` - -Possible resolution: - -- When strict is set to True, using deprecated code will cause an error and stop KCL. -- You can set the strict to False which will cause a warning insteads of an error. -- Adjust the code without using deprecated code. - -### 1.3.5 KCLAttributeRuntimeError (E3A30) - -KCL will report `KCLAttributeRuntimeError`, if an error occurs during dynamically accessing schema attributes through variables at runtime. - -The `ewcode` of `KCLAttributeRuntimeError` is `E3A30`. - -For example: - -```python -import math - -a = math.err_func(1) # err_func is not found in math -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /import/module/no_module_attr_fail_2/main.k:3:5 - | -3 | a = math.err_func(1) # err_func is not found in math - | ^ module 'math' has no attribute err_func - | -``` - -Possible resolution: - -- Check whether the attributes of schema are correct. - -### 1.3.6 TypeRuntimeError (E3G21) - -KCL will report `TypeRuntimeError` when an type error occurs in the runtime type check. - -The `ewcode` of `TypeRuntimeError` is `E3G21`. - -For example: - -```python -schema Person: - name: str = "Alice" - -_personA = Person {} -_personA |= {"name" = 123.0} # name: str = "Alice" -personA = _personA -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /fail/fail_4/main.k:2:1 - | -2 | name: str = "Alice" - | expect str, got float - | -``` - -Possible resolution: - -- Stop the wrong type union or adjust to the type union supported by KCL. - -### 1.3.7 SchemaCheckFailure (E3B17) - -KCL will report `SchemaCheckFailure` when the schema check conditions are not met. - -The `ewcode` of `SchemaCheckFailure` is `E3B17`. - -For example: - -```python -schema Person: - lastName: str - age: int - check: - age < 140, "age is too large" - -JohnDoe = Person { - "lastName": "Doe", - "age": 1000 # the check condition: age < 140 -} -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /check_block/check_block_fail_1/main.k:7:11 - | -7 | JohnDoe = Person { - | ^ Instance check failed - | - - --> /check_block/check_block_fail_1/main.k:5:1 - | -5 | age < 140, "age is too large" - | Check failed on the condition - | -``` - -Possible resolution: - -- Check whether the attributes of schema can satisfy the conditions in check. - -### 1.3.8 CannotAddMembersRuntimeError(E3B19) - -KCL will report `CannotAddMembersRuntimeError` when members that are not in the schema are used. - -The `ewcode` of `CannotAddMembersRuntimeError` is `E3B19`. - -For example: - -```python -schema Name: - name: str - -schema Person: - name: Name - -person = Person { - name.err_name: "Alice" # err_name is not found in schema Name -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /nest_var/nest_var_fail_1/main.k:8:5 - | -8 | name.err_name: "Alice" # err_name is not found in schema Name - | ^ Cannot add member 'err_name' to schema 'Name' - | -``` - -Possible resolution: - -- Add a non-existent member to the schema. -- Access members that exist in the schema. - -### 1.3.9 EvaluationError(E3M38) - -KCL will report `EvaluationError` when an illegal evaluation occurs in KCL. - -The `ewcode` of `EvaluationError` is `E3M38`. - -For example: - -```python -_list1 = [1, 2, 3] # _list1 is a variable, and its type can only be known at runtime -_list2 = None # _list1 is a variable, and its type can only be known at runtime - -result2 = _list1 + _list2 # list + NoneType is illegal -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /datatype/list/add_None_fail/main.k:1 - | -4 | result2 = _list1 + _list2 # list + NoneType is illegal - | can only concatenate list (not "NoneType") to list - | -``` - -Possible resolution: - -- Check whether the evaluation of the expression is legal. - -### 1.3.10 InvalidFormatSpec (E3M39) - -KCL will report `InvalidFormatSpec` when an illegal string format appears in KCL. - -The `ewcode` of `InvalidFormatSpec` is `E3M39`. - -For example: - -```python -a = 1 -b = 1 -data = "${a: #js}" + " $$ " # #js is illegal string -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /datatype/str_interpolation/invalid_format_spec_fail_0/main.k:3 - | -3 | data = "${a: #js}" + " $$ " # #js is illegal string - | ^ #js is a invalid format spec - | -``` - -Possible resolution: - -- Adjust illegal String to String supported by KCL standards. - -### 1.3.11 KCLAssertionError (E3M40) - -KCL will report `KCLAssertionError` when assert False occurs in KCL. - -The `ewcode` of `KCLAssertionError` is `E3M40`. - -For example: - -```python -assert False -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /assert/invalid/fail_0/main.k:1 - | -1 | assert False - | - | -``` - -Possible resolution: - -- Check the condition of Assert, and when the Assert condition is False, such an error occurs, removing the Assert statement or changing the condition to True. - -### 1.3.12 ImmutableRuntimeError (E3M44) - -KCL will report `ImmutableRuntimeError` when the value of the immutable variable changes. - -The `ewcode` of `ImmutableRuntimeError` is `E3M44`. - -For example: - -```python -schema Person: - final firstName : str - lastName : str - -schema Scholar(Person): - firstName = "CBA" - -scholar = Scholar { - "firstName": "ABC" # firstName in schema Person is final. -} -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /final/fail_lazy_init_0/main.k:8:1 - | -8 | scholar = Scholar { - | attribute 'lastName' of Scholar is required and can't be None or Undefined - | -``` - -Possible resolution: - -- Check if the final variables have been assigned or other changes affect the values of the final variables. - -### 1.3.13 CycleInheritError (E2D33) - -KCL will report `CycleInheritError` when circle inheritance appeared in the schema. - -The `ewcode` of `CycleInheritError` is `E2D33`. - -For example: - -```python -schema Parent(Son): - parent_field: str - -schema Son(GrandSon): - son_field: str - -schema GrandSon(Parent): - grandson_field: str - -parent = Parent { - parent_field: "" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /inherit/cycle_inherit_fail_1/main.k:7:8 - | -7 | schema GrandSon(Parent): - | ^ There is a circular reference between schema GrandSon and Parent - | -``` - -Possible resolution: - -- Check schema inheritance relationship to avoid A inheritance B and B inheritance A at the same time. - -### 1.3.14 KCLRecursionError (E3M42) - -KCL will report `KCLRecursionError` when a circle reference appears in the program. - -The `ewcode` of `KCLRecursionError` is `E3M42`. - -For example: - -```python -schema Parent(Son): - parent_field: str - son: Son = Son { # Parent has attribute Son - parent: Parent { - parent_field: "123" - } - } - -schema Son: - son_field: str - parent: Parent = Parent { # Son has attribute Parent - son: Son { - son_field: "123" - } - } - -parent = Parent { - parent_field: "", -} -``` - -The KCL program will cause the following error message. - -```shell -thread 'main' has overflowed its stack -fatal runtime error: stack overflow -``` - -Possible resolution: - -- Check the members in the schema to avoid the problem of circle references. - -## 1.4 KCL Compile Warning (W2xxx) - -This section mainly includes KCL warnings: - -| ewcode | KCL exception | messages | -| ------ | ------------------------------------------------- | ------------------ | -| W2K04 | [FloatUnderflow](#141-floatunderflow-w2k04) | Float underflow | -| W2P10 | [InvalidDocstring](#142-invaliddocstring-w2p10) | Invalid docstring | -| W2N12 | [DeprecatedWarning](#143-deprecatedwarning-w2n12) | Deprecated warning | - -### 1.4.1 FloatUnderflow (W2K04) - -KCL will report `FloatUnderflow` when a floating-point number underflows in KCL. - -The `ewcode` of `FloatUnderflow` is `W2K08`. - -Possible resolution: - -- Check whether the value of the float number is in the range supported by KCL. - -### 1.4.2 InvalidDocstring (W2P10) - -KCL will report `InvalidDocstring` when a string is illegal in KCL doc. - -The `ewcode` of `InvalidDocstring` is `W2P10`. - -Possible resolution: - -- Please write doc according to KCL standards. - -### 1.4.3 DeprecatedWarning (W2N12) - -KCL will report `DeprecatedWarning` when a deprecated variable is used and the strict is False. - -The `ewcode` of `DeprecatedWarning` is `W2N12`. - -Possible resolution: - -- Try not to use deprecated code. If the strict is True, KCL will output the error and stop running. diff --git a/versioned_docs/version-0.5.2/reference/lang/spec/codestyle.md b/versioned_docs/version-0.5.2/reference/lang/spec/codestyle.md deleted file mode 100644 index dd40925e..00000000 --- a/versioned_docs/version-0.5.2/reference/lang/spec/codestyle.md +++ /dev/null @@ -1,608 +0,0 @@ ---- -title: "Code Style" -linkTitle: "Code Style" -type: "docs" -weight: 2 -description: Code Style ---- - -## Introduction - -This document gives the KCL code style conventions. Good code style can play a vital role in the development and maintenance of the project. We can learn the KCL code style by referring to the full text of the description and sample codes, and use KCL format and lint tools to help coding. - -## Source File Encoding - -KCL file encoding should always use **UTF-8**. - -## Code Layout - -### Indentation - -Use **4 spaces** per indentation level such as in the schema statement and if statement. - -```python -schema PersonA: - name: str # non-recommended - age: int - -schema PersonB: - name: str # recommended - age: int - -if True: - a = 1 # recommended -elif True: - b = 2 # non-recommended -else: - c = 3 # non-recommended -``` - -The closing brace/bracket/parenthesis on multiline constructs should line up under **first character** of the line that starts the multiline construct, as in: - -```python -# valid and recommended -my_list = [ - 1, 2, 3, - 4, 5, 6, -] -``` - -```python -# invalid -my_list = [ - 1, 2, 3, - 4, 5, 6, - ] -``` - -### Tabs or Spaces - -- Spaces are the preferred indentation method. -- Tabs should be used solely to remain consistent with code that is already indented with tabs. - -KCL disallows mixing the use of tabs and spaces for indentation and an error will be reported during the compile time. - -### Blank Lines - -- Surround top-level schema definitions with one blank line. -- Keep at most one blank line between two statements and remove redundant blank lines. -- Remove extra blank characters at the end of the line -- Remove extra blank characters in a blank line. -- There is no blank line in the header of the file, start writing from the first line. -- Only one blank line will be left at the end of the KCL file. - -```python -# Remove blank lines in the file header -a = 1 # Remove white space at the end of the line -# Keep at most one blank line between two statements - -b = 2 -# Only leave one blank line at the end of the file - -``` - -### Inline Expressions - -Write indentation of KCL `if`, `elif`, `else` and other conditions on different lines. - -```python -if True: print("") # non-recommended - -if True: # recommended - print("") -``` - -### Line Break and Continuation lines - -- For long expressions, use the line continuation symbol `\` and keep the left end of multiple expressions aligned. -- The 4-space rule is optional for continuation lines. - -```python -anotherString = "Too long expression " + \ - "Too long expression " # non-recommended - -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " # recommended -``` - -### When to Use Trailing Commas - -- Always use trailing commas. - -### Maximum Line Length - -- The general recommendation is **80 characters** but not absolute. - -### Symbol Break White Space - -Try to keep the spaces between different symbols, but not too many, usually one is good. - -```python -a = 1 # recommended -b = 1 + 2 # non-recommended -``` - -### Whitespace in Expressions and Statements - -Avoid extraneous whitespace in the following situations: - -- The parentheses `()`, brackets `[]` and braces `{}` in the expression have no spaces inside. - -```python -a = (1 + 2) # recommended -b = ( 1 + 2 ) # non-recommended - -c = [1, 2, 3] # recommended -d = [ 1, 2, 3 ] # non-recommended - -e = {key = "value"} # recommended -f = { key = "value" } # non-recommended -``` - -```python -spam(ham[1], {eggs = 2}) # recommended -spam( ham[ 1 ], { eggs = 2 } ) # non-recommended -``` - -- Between a trailing comma and a following close parenthesis. - -```python -foo = [0,] # recommended -bar = [0, ] # non-recommended -``` - -- Immediately before the open parenthesis that starts the argument list of a function call. - -```python -print(1) # recommended -print (1) # non-recommended -``` - -- Immediately before the open parenthesis that starts indexing or slicing. - -```python -dct = {key = "value"} -lst = [1, 2, 3] - -a = dct['key'] # recommended -b = dct ['key'] # non-recommended - -c = lst[0] # recommended -d = lst [1] # non-recommended -``` - -- More than one space around an assignment `=` (or other) operator to align it with another. - -```python -# recommended: -x = 1 -y = 2 -long_variable = 3 -``` - -```python -# non-recommended: -x = 1 -y = 2 -long_variable = 3 -``` - -- Always surround these binary operators with a single space on either side: assignment (`=`), augmented assignment (`+=`, `-=`, etc.), comparisons (`==`, `<`, `>`, `!=`, `<=`, `>=`, `in`, `not in`, `is`, `is not`), booleans (`and`, `or`, `not`). - -```python -# recommended: -i = i + 1 -submitted += 1 -x = x * 2 - 1 -hypot2 = x * x + y * y -c = (a + b) * (a - b) -``` - -```python -# non-recommended: -i = i+1 -submitted+=1 -x = x*2 - 1 -hypot2 = x*x + y*y -c = (a+b) * (a-b) -``` - -- Break one blank line between different statements e.g., import, schema and expression statements. - -```python -import math -import net - -schema Person: - name: str - -person = Person { - name = "Alice" -} -``` - -- Compound statements (multiple statements on the same line) are generally discouraged - -```python -# recommended: -if foo == 'blah': - do_blah_thing() -do_one() -do_two() -do_three() -``` - -```python -# non-recommended: -if foo == 'blah': do_blah_thing() -do_one(); do_two(); do_three() -``` - -## Naming Conventions - -### Naming Styles - -The following naming styles are commonly distinguished: - -- `b` (single lowercase letter) -- `B` (single uppercase letter) -- `lowercase` -- `lower_case_with_underscores` -- `UPPERCASE` -- `UPPER_CASE_WITH_UNDERSCORES` -- `CapitalizedWords` (capitalize all letters of the acronym in `CapitalizedWords` e.g., `HTTPServer`.) -- `mixedCase` (differs from `CapitalizedWords` by initial lowercase character) -- `Capitalized_Words_With_Underscores` (ugly and non-recommended) - -### Names to Avoid - -Never use the characters 'l' (lowercase letter el), 'O' (uppercase letter oh), or 'I' (uppercase letter eye) as single-character variable names. - -### Package and Module Names - -Package and module names should have short, all-lowercase names. - -### Schema Names - -Schema names should normally use the `CapWords` convention. - -### Constants - -Constants are usually defined on a module level and written in all capital letters with underscores separating words such as `MAX_OVERFLOW` and `TOTAL`. - -## Import - -- Imports should usually be on separate lines. -- Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants. -- Imports should be grouped in the following order and we should put a blank line between each group of imports. - 1. Standard library imports. - 2. Related third party plugin imports. - 3. Local application/library specific imports. -- Use an alias when we import a package name with a relatively long path. -- Leave only one space between the Import keyword and the package name. - -```python -import net # recommended -import math # non-recommended - -import ..pkg.internal_pkg as alias_pkg # recommended -``` - -## Comments - -- Comments should be complete sentences. The first word should be capitalized unless it is an identifier that begins with a lower-case letter (never alter the case of identifiers!). -- Block comments generally consist of one or more paragraphs built out of complete sentences, with each sentence ending in a period. -- Use two spaces after a sentence-ending period in multi-sentence comments, except after the final sentence. - -### Block Comments - -Block comments generally apply to some (or all) code that follows them, and are indented to the same level as that code. Each line of a block comment starts with a `#` and **a single space**(unless it is indented text inside the comment). - -Paragraphs inside a block comment are separated by a line containing a single `#`. - -```python -# This is a block comment -a = 1 -``` - -### Inline Comments - -Use inline comments sparingly. - -An inline comment is a comment on the same line as a statement. Inline comments should be separated by **at least two spaces** from the statement. They should start with a `#` and **a single space**. - -```python -a = 1 # This is an inline comment -``` - -### Documentation Strings - -Write doc strings for all public schema and schema attributes. - -```python -schema Person: - """ - Person schema doc string - """ - - name: str = "Alice" -``` - -## String - -- Single-quoted strings and double-quoted strings are the same in KCL. -- Use double-quoted string with lowercase prefix -- For triple-quoted strings, always use double quote characters to be consistent with the docstring convention. -- When a string contains single or double quote characters, use the other one to avoid backslashes in the string. - -```python -strC = "'123'" # recommended -strD = "\"123\"" # non-recommended -``` - -## Number - -- Use lowercase for the prefix of non-decimal numbers, and use uppercase for the number itself. - -```python -foo = 0xAB # recommended -bar = 0Xab # non-recommended -``` - -## Operators - -### Binary Operators - -- Leave only one space before and after the assignment `=`. -- Leave only one space before and after the binary operator in the expression. - -```python -a = 1 # recommended -b=2 # non-recommended -c= 3 # non-recommended -d =4 # non-recommended - -_value = (1 + 2 * 3) # recommended -_value = (1+2*3) # non-recommended -``` - -### Unary Operators - -- There is only no space after unary operators e.g., `~`, `+` and `-`. - -```python -_value = 1 + -2 * ~3 # recommended -_value = 1+ - 2 * ~ 3 # non-recommended -``` - -- There is no space after `**` and `*` in the dict/list deduction expressions and argument expressions. - -```python -_list = [1, 2, 3] -_list = [*_list, [4, 5 ,6]] # recommended -_list = [* _list, [4, 5 ,6]] # non-recommended - -_dict = {**{k = "v"}, **{k = "v"}} # recommended -_dict = {** {k = "v"}, ** {k = "v"}} # non-recommended -``` - -- Use `is not` operator rather than `not ... is`. - -```python -# recommended: -if foo is not None: - a = 1 -``` - -```python -# non-recommended: -if not foo is None: - a = 1 -``` - -## Dict - -- There is no space before the colon `:` at the instantiation of KCL dict and schema config, and a space after the colon `:`. - -```python -d1 = {labels: {k1 = "v1"}} # recommended -d2 = {labels : {k1 = "v1"}} # non-recommended -d3 = {labels :{k1 = "v1"}} # non-recommended -``` - -- Always surround the override attribute operator `=` and the insert attribute operator `+=` with a single space on either sid. - -```python -d1 = {key = "value"} # recommended -d2 = {key= "value"} # non-recommended -d3 = {key ="value"} # non-recommended -``` - -```python -d1 = {key += [0, 1, 2]} # recommended -d2 = {key+= [0, 1, 2]} # non-recommended -d3 = {key +=[0, 1, 2]} # non-recommended -``` - -- Remove all commas at the end of the line in the KCL multiline dict because the end commas of each line are optional. - -```python -d = { - key1 = "value1" - key2 = "value2" - key3 = "value3" - key4 = "value4" -} -``` - -## List - -- Keep only **one space** after the comma `,` separating elements in the list - -```python -a = [1, 2, 3] # recommended -b = [1,2,3] # non-recommended -``` - -- Keep only **one space** before and after the comprehension expression token `for` and `in` in the dict and list. - -```python -a = [i for i in range(10)] # recommended -b = [i for i in range(10)] # non-recommended -``` - -## Slice - -- Keep the same number of spaces before and after the colon `:` of the list slice. - -```python -l = [1, 2, 3] -a = l[0:2] # recommended -b = l[0 : 2] # non-recommended -c = l[0: 2] # non-recommended - -d = l[0 + 0 : 1 + 1] # recommended -e = l[0 + 0:1 + 1] # non-recommended -``` - -## Schema - -- Leave only one space before and after the schema attribute assignment `=`. -- Always add a doc string to a schema, which is a good programming habit. - -```python -schema Person: - """ - Schema doc string - """ - name: str = "Alice" # recommended - age : int=12 # non-recommended - -person = Person {} -``` - -- Keep **no spaces** around the schema inheritance operator `()` - -```python -schema Base: - name: str - -schema Person(Base): # recommended - age: int - -schema Schema ( Base ): # non-recommended - age: int -``` - -- Keep **only one space** between the brackets and the schema name of the config at schema instantiation. - -```python -schema Base: - name: str - -schema Person(Base): - age: int - -personA = Person{} # non-recommended -personB = Person {} # recommended -``` - -- Keep **only one space** between the **mixin** keyword and the following `[]` operator - -```python -schema NameMixin: - name: str = "name" - -schema Person: - mixin [NameMixin] # non-recommended - age: int - -schema Parent: - mixin [NameMixin] # recommended - age: int -``` - -### Attribute Annotations - -- Annotations for schema attributes should have a single space after the colon `:` and no space before the colon `:`. - -```python -# recommended: -schema Person: - name: str # No space before the colon `:` - age: int = 18 # Spaces around assignment`=` -``` - -```python -# non-recommended: -schema Person: - codeA:int # No space after the colon `:` - codeB : int # Space before the colon `:` - name: str="Alice" # No spaces around assignment`=` -``` - -- There are no spaces around the colon `:` in the dict type annotation. - -```python -schema Person: - labels: {str:str} # recommended - keyValues: {str : str} # non-recommended -``` - -### Arguments - -- There are no spaces around the assignment `=` in the function/schema/decorator keyword arguments (kwargs). - -```python -schema Person[nameVar]: - # Decorator kwargs - @deprecated(strict=False) # recommended - name: str = nameVar - - @deprecated(strict = False) # non-recommended - age: int - -# Schema kwargs -personA = Person(nameVar="Alice") {} # recommended -personB = Person(nameVar = "Bob") {} # non-recommended - -# Function kwargs -print("", end='') # recommended -print("", end = '') # non-recommended -``` - -## Keywords - -- Only one space is usually reserved around the keyword, such as `schema`, `mixin`, `is` and `not`, etc. - -```python -schema NameMixin: - check: - name not None - -schema Person: - """ - Person schema definition - """ - mixin [NameMixin] - - name: str = "Alice" - age: int - -person = Person { - age = 18 -} -``` - -## Function - -- There are no spaces around the function/package select operator `.` -- There are no spaces between the function name and the parentheses `()`. - -```python -import math - -print(math.log(10)) # recommended -print( math . log (10)) # non-recommended -``` diff --git a/versioned_docs/version-0.5.2/reference/lang/spec/datatypes.md b/versioned_docs/version-0.5.2/reference/lang/spec/datatypes.md deleted file mode 100644 index ef7ea71a..00000000 --- a/versioned_docs/version-0.5.2/reference/lang/spec/datatypes.md +++ /dev/null @@ -1,452 +0,0 @@ ---- -title: "Data Types" -linkTitle: "Data Types" -type: "docs" -weight: 2 -description: Data Types ---- - -## Syntax - -### Bool - -Boolean values are the two constant objects `False` and `True`. They are used to represent truth values (although other values can also be considered false or true). The built-in function bool() can be used to convert any value to a Boolean, if the value can be interpreted as a truth value. - -### Int - -Int, or integer, is an arbitrarily sized integer, positive or negative, without decimals, of 64 binary digits precision(-9,223,372,036,854,775,808~9,223,372,036,854,775,807). Int is created by int literals or as the result of built-in functions and operators. Unadorned integer literals (including `hex`, `octal` and `binary` numbers) yield integers. The constructor int() can be used to produce int of a specific type. - -Besides, integer literals may have an `SI` or `IEC` multiplier. - -- `SI`: General integer or fixed-point number form: `P`, `T`, `G`, `M`, `K`, `k`, `m`, `u`, `n`. -- `IEC`: Corresponding power of 2: `Pi`, `Ti`, `Gi`, `Mi`, `Ki`. - -```python -a = 1 # positive integer: 1 -b = -1 # negative integer: -1 -c = 0x10 # hexadecimal literal: 16 -d = 0o10 # octal literal: 8, or the form `010` -e = 0b10 # binary literal: 2 -f = 10Ki # integer literal with IEC multiplier: 10240 -g = 1M # integer literal with SI multiplier: 1000000 -h = int("10") # int constructor: 10 -i = int("10Ki") # int constructor with multiplier: 10240 -``` - -Notes: - -- Report an error if unable to represent an integer value precisely. - -### Float - -Float, floating-point, approximation to real numbers, positive or negative, containing one or more decimals, of 64 bit IEEE 754 floats. The constructor float() can be used to produce int of a specific type. - -```python -a = 1.10 -b = 1.0 -c = -35.59 -d = 32.3+e18 -f = -90. -g = -32.54e100 -h = 70.2-E12 -i = float("112") # float constructor -``` - -Notes: - -- Report an error if unable to represent a floating-point value due to overflow -- Report a warning if unable to represent a floating-point value due to underflow. Round to the nearest representable value if unable to represent a floating-point value due to limits on precision. These requirements apply to the result of any expression except for built-in functions for which an unusual loss of precision must be explicitly documented. - -#### None - -In KCL, `None` can indicate that the value of the object is empty, which is similar to `nil` in Go or `null` in Java, and corresponds to `null` in YAML and JSON. - -```python -a = None -b = [1, 2, None] -c = {"key1" = "value1", "key2" = None} -``` - -Please note that `None` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + None # error -b = int(None) # error -c = not None # True -d = None == None # True -e = None or 1 # 1 -f = str(None) # None -``` - -#### Undefined - -`Undefined` is similar to None, but its semantics is that a variable is not assigned any value and will not be output to YAML or JSON. - -```python -a = Undefined -b = [1, 2, Undefined] -c = {"key1" = "value1", "key2" = Undefined} -``` - -Please note that `Undefined` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + Undefined # error -b = int(Undefined) # error -c = not Undefined # True -d = Undefined == Undefined # True -e = Undefined or 1 # 1 -f = str(Undefined) # Undefined -``` - -### Common Numeric Operations - -Int and Float support the following operations (see built-in proposal for built-in details): - -- `x + y`: sum of x and y. -- `x - y`: difference of x and y. -- `x * y`: product of x and y. -- `x / y`: quotient of x and y. -- `x // y`: floored quotient of x and y. -- `x % y`: remainder of x / y. -- `x ** y`: x to the power y. -- `-x`: x negated. -- `+x`: x unchanged. -- `~x`: x bitwise negation. -- `abs(x)`: absolute value or magnitude of x. -- `int(x)`: x converted to integer. -- `float(x)`: x converted to floating point. - -KCL supports mixed arithmetic: when a binary arithmetic operator has operands of different numeric types, the operand with the "narrower" type is widened to that of the other, where integer is narrower than floating-point. - -### String - -Strings are immutable sequences of Unicode characters. String literals are written in a variety of ways: - -```python -'allows embedded "double" quotes' # Single quotes -"allows embedded 'single' quotes" # Double quotes -'''Three single quotes''', """Three double quotes""" # Triple quoted -``` - -Triple quoted strings may span multiple lines. - -Indexing a string produces strings of length 1, for a non-empty string s, `s[0] == s[0:1]`. - -```python -a = "Hello, World!" -b = a[2:5] # "llo" -c = a[-5:-2] # "orl" -d = a[::-1] # "'!dlroW ,olleH'" -``` - -- `str(x=None) -> str` - -Return a string. If _x_ is not provided, raise a runtime error. - -```python -x = str(3.5) # "3.5" -``` - -#### Members - -Built-in function and members of a string - -- `str#len() -> int` - Return the number of characters in the string. -- `capitalize() -> str` - Return a copy of the string with its first character (if any) capitalized and the rest lowercased. -- `count(sub: str, start: int = 0, end: int = -1) -> int` - Returns the number of (non-overlapping) occurrences of substring sub in string, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `endswith(suffix: str, start: int = 0, end: int = -1) -> bool` - Returns `True` if the string ends with the specified suffix, otherwise return `False`, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `find(sub: str, start: int = 0, end: int = -1) -> int` - Returns the lowest index where substring sub is found, or -1 if no such index exists, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `format(*args, **kwargs) -> str` - Perform string interpolation. Format strings contain replacement fields surrounded by curly braces {}. Anything that is not contained in braces is considered literal text, which is copied unchanged to the output. If you need to include a bracket character in the literal text, it can be escaped by doubling: A replacement field can be either a name, a number or empty. Values are converted to strings using the str function. -- `index(sub: str, start: int = 0, end: int = -1) -> int` - Returns the first index where sub is found, or raises an error if no such index exists, optionally restricting to `[start:end]` start being inclusive and end being exclusive. -- `isalnum() -> bool` - Returns True if all characters in the string are alphanumeric (`[a-zA-Z0-9]`) and there is at least one character, False otherwise. -- `isalpha() -> bool` - Returns True if all characters in the string are alphabetic (`[a-zA-Z]`) and there is at least one character. -- `isdigit() -> bool` - Returns True if all characters in the string are digits (`[0-9]`) and there is at least one character. -- `islower() -> bool` - Returns True if all cased characters in the string are lowercase and there is at least one character. -- `isspace() -> bool` - Returns True if all characters are white space characters and the string contains at least one character. -- `istitle() -> bool` - Returns True if the string is in title case and it contains at least one character. This means that every uppercase character must follow an uncased one (e.g., whitespace) and every lowercase character must follow a cased one (e.g., uppercase or lowercase). -- `isupper() -> bool` - Returns True if all cased characters in the string are uppercase and there is at least one character. -- `join(iterable: list) -> str` - Return a string which is the concatenation of the strings in iterable. A TypeError will be raised if there are any non-string values in iterable. The separator between elements is the string providing this method. Example: - - ```python - >>> "|".join(["a", "b", "c"]) - "a|b|c" - ``` - -- `lower() -> str` - Returns a copy of the string with all the cased characters converted to lowercase. -- `lstrip(chars: str) -> str` - Return a copy of the string with leading characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.lstrip() - 'spacious ' - >>> 'www.example.com'.lstrip('cmowz.') - 'example.com' - ``` - -- `replace(old: str, new: str, count: int) -> str` - Return a copy of the string with all occurrences of substring old replaced by new. If the optional argument count is given, only the first count occurrences are replaced. -- `rfind(sub: str, start: int = 0, end: int = -1) -> int` - Return the highest index in the string where substring sub is found, such that sub is contained within s[start:end]. Optional arguments start and end are interpreted as in slice notation. Return -1 on failure. -- `rindex(sub: str, start: int = 0, end: int = -1) -> int` - Returns the last index where sub is found, or raises an ValueError if no such index exists, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `rsplit(sep: str, maxsplit: int = -1) -> list` - Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done, the rightmost ones. If sep is not specified or None, any whitespace string is a separator. Except for splitting from the right, rsplit() behaves like split() which is described in detail below. -- `rstrip(chars: str) -> str` - Return a copy of the string with trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a suffix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.rstrip() - ' spacious' - >>> 'mississippi'.rstrip('ipz') - 'mississ' - ``` - -- `split(sep: str, maxsplit: int) -> list` - Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done (thus, the list will have at most maxsplit+1 elements). If maxsplit is not specified or -1, then there is no limit on the number of splits (all possible splits are made). - - If sep is given, consecutive delimiters are not grouped together and are deemed to delimit empty strings (for example, `'1,,2'.split(',')` returns `['1', '', '2']`). The sep argument may consist of multiple characters (for example, `'1<>2<>3'.split('<>')` returns `['1', '2', '3']`). Splitting an empty string with a specified separator returns `['']`. - - For example: - - ```python - >>> '1,2,3'.split(',') - ['1', '2', '3'] - >>> '1,2,3'.split(',', maxsplit=1) - ['1', '2,3'] - >>> '1,2,,3,'.split(',') - ['1', '2', '', '3', ''] - ``` - - If sep is not specified or is None, a different splitting algorithm is applied: runs of consecutive whitespace are regarded as a single separator, and the result will contain no empty strings at the start or end if the string has leading or trailing whitespace. Consequently, splitting an empty string or a string consisting of just whitespace with a `None` separator returns `[]`. - - For example: - - ```python - >>> '1 2 3'.split() - ['1', '2', '3'] - >>> '1 2 3'.split(maxsplit=1) - ['1', '2 3'] - >>> ' 1 2 3 '.split() - ['1', '2', '3'] - ``` - -- `splitlines(keepends: str) -> list` - Return a list of the lines in the string, breaking at line boundaries('\n', '\r\n', '\r'). Line breaks are not included in the resulting list unless keepends is given and true. - - This method splits on the following line boundaries. In particular, the boundaries are a superset of universal newlines. - - For example: - - ```python - >>> 'ab c\n\nde fg\rkl\r\n'.splitlines() - ['ab c', '', 'de fg', 'kl'] - >>> 'ab c\n\nde fg\rkl\r\n'.splitlines(keepends=True) - ['ab c\n', '\n', 'de fg\r', 'kl\r\n'] - ``` - - Unlike `split()` when a delimiter string sep is given, this method returns an empty list for the empty string, and a terminal line break does not result in an extra line: - - ```python - >>> "".splitlines() - [] - >>> "One line\n".splitlines() - ['One line'] - ``` - - For comparison, `split('\n')` gives: - - ```python - >>> ''.split('\n') - [''] - >>> 'Two lines\n'.split('\n') - ['Two lines', ''] - ``` - -- `startswith(prefix: str, start: int = 0, end: int = -1) -> bool` - Return `True` if string starts with the prefix, otherwise return False. prefix can also be a list of prefixes to look for. With optional start, test string beginning at that position. With optional end, stop comparing string at that position. -- `strip(chars: str) -> str` - Return a copy of the string with the leading and trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix or suffix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.strip() - 'spacious' - >>> 'www.example.com'.strip('cmowz.') - 'example' - ``` - - The outermost leading and trailing chars argument values are stripped from the string. Characters are removed from the leading end until reaching a string character that is not contained in the set of characters in chars. A similar action takes place on the trailing end. For example: - - ```python - >>> comment_string = '#....... Section 3.2.1 Issue #32 .......' - >>> comment_string.strip('.#! ') - 'Section 3.2.1 Issue #32' - ``` - -- `title() -> str` - Return a titlecased version of the string where words start with an uppercase character and the remaining characters are lowercase. - - For example: - - ```python - >>> 'Hello world'.title() - 'Hello World' - ``` - - The algorithm uses a simple language-independent definition of a word as groups of consecutive letters. The definition works in many contexts but it means that apostrophes in contractions and possessives form word boundaries, which may not be the desired result: - - ```python - >>> "they're bill's friends from the UK".title() - "They'Re Bill'S Friends From The Uk" - ``` - -- `upper() -> str` - Return a copy of the string with all the cased characters 4 converted to uppercase. Note that `s.upper().isupper()` might be `False` if s contains uncased characters or if the Unicode category of the resulting character(s) is not “Lu” (Letter, uppercase), but e.g., “Lt” (Letter, titlecase). -- `removeprefix(prefix: str) -> str` - If the string starts with the prefix string, return string[len(prefix):]. Otherwise, return a copy of the original string. - ```python - >>> "prefix-data".removeprefix("prefix-") - "data" - ``` -- `rermovesuffix(suffix: str) -> str` - If the string ends with the suffix string and that suffix is not empty, return string[:-len(suffix)]. Otherwise, return a copy of the original string. - ```python - >>> "data-suffix".removesuffix("-suffix") - "data" - ``` - -### List - -Lists are immutable sequences, typically used to store collections of homogeneous items (where the precise degree of similarity will vary by application). - -Lists may be constructed in several ways: - -- Using a pair of square brackets to denote the empty list: `[]` -- Using square brackets, separating items with commas: `[a]`, `[a, b, c]` -- Using a list comprehension: `[x for x in iterable]` -- Using the type constructor: list() or list(iterable) - -The constructor builds a list whose items are the same and in the same order as iterable’s items.Iterable may be either a sequence, a container that supports iteration, or an iterator object. If iterable is already a list, a copy is made and returned, similar to `iterable[:]`. For example, `list('abc')` returns `['a', 'b', 'c']` and `list([1, 2, 3])` returns `[1, 2, 3]`. If no argument is given, the constructor creates a new empty list `[]`. - -Lists implement all of the common sequence operations. - -#### Members - -- `len()` - Return the number of items in the list. - -### Common Sequence Operations - -The operations in the following table are supported by List and Dict. - -This table lists the sequence operations sorted in ascending priority. In the table, s and t are sequences of the same type, n, i, j and k are integers and x is an arbitrary object that meets any type and value restrictions imposed by s. - -The `in` and `not in` operations have the same priorities as the comparison operations. The + -(concatenation) and \* (repetition) operations have the same priority as the corresponding numeric operations. - -| Operation | Result | Notes | -| ------------ | -------------------------------------------------- | ----- | -| `x in s` | `True` if an item of s is equal to x, else `False` | #1 | -| `x not in s` | `False` if an item of s is equal to x, else `True` | #1 | -| `s + t` | the concatenation of s and t | #5 | -| `s[i]` | ith item of s, origin 0 | #2 | -| `s[i:j]` | slice of s from i to j | #2 #3 | -| `s[i:j:k]` | slice of s from i to j with step k | #2 #4 | -| `min(s)` | smallest item of s | | -| `max(s)` | largest item of s | | - -Notes: - -- 1. While the in and not in operations are used only for simple containment testing in the - general case, some specialized sequences (str) also use them for subsequence testing: - -```python ->>> "gg" in "eggs" -True -``` - -- 2. If i or j is negative, the index is relative to the end of sequence s: `s.len() + i` or `s.len() + j` is substituted. But note that -0 is still 0. -- 3. The slice of s from i to j is defined as the sequence of items with index k such that `i <= k < j`. If i or j is greater than `s.len()`, use `s.len()`. If i is omitted or None, use 0. If j is omitted or None, use `s.len()`. If i is greater than or equal to j, the slice is empty. -- 4. The slice of s from i to j with step k is defined as the sequence of items with index `x = i + n*k` such that `0 <= n < (j-i)/k`. In other words, the indices are `i`, `i+k`, `i+2*k`, `i+3*k` and so on, stopping when j is reached (but never including j). When k is positive, i and j are reduced to s.len() if they are greater. When k is negative, i and j are reduced to s.len() - - - If they are greater. If i or j are omitted or None, they become “end” values (which end depends on the sign of k). Note, k cannot be zero. If k is None, it is treated like 1. - -- 5. Concatenating immutable sequences always results in a new object. This means that building up a sequence by repeated concatenation will have a quadratic runtime cost in the total sequence length. To get a linear runtime cost, you must switch to one of the alternatives below: - - - if concatenating str objects, you can build a list and use `str.join()` at the end - -- 6. `index` raises `ValueError` when x is not found in s. Not all implementations support passing the additional arguments i and j. These arguments allow efficient searching of subsections of the sequence. Passing the extra arguments is roughly equivalent to using `s[i:j].index(x)`, only without copying any data and with the returned index being relative to the start of the sequence rather than the start of the slice. - -### Dict - -Dict is an immutable mapping object maps hashable values to arbitrary objects. A dictionary’s keys are almost arbitrary values. Values that are not hashable, that is, values containing lists, dictionaries may not be used as keys. Numeric types used for keys obey the normal rules for numeric comparison: if two numbers compare equal (such as 1 and 1.0) then they can be used interchangeably to index the same dictionary entry. (Note however, that since computers store floating-point numbers as approximations it is usually unwise to use them as dictionary keys.) Dict is ordered. The order of the keys is the order of their declaration. - -Dictionaries can be created by placing a comma-separated list of keys: value pairs within braces, for example: `{'jack': 4098, 'sjoerd': 4127}` or `{4098: 'jack', 4127: 'sjoerd'}`, by the dict constructor, or list/dict comprehension. - -- `dict(obj)` - -Return a new dictionary initialized from an optional positional argument and a possibly empty set of keyword arguments.If no positional argument is given, an empty dictionary is created. If a positional argument is given and it is a mapping object, a dictionary is created with the same key-value pairs as the mapping object. Otherwise, the positional argument must be an iterable object. Each item in the iterable must itself be an iterable with exactly two objects. The first object of each item becomes a key in the new dictionary, and the second object the corresponding value. If a key occurs more than once, the last value for that key becomes the corresponding value in the new dictionary. If keyword arguments are given, the keyword arguments and their values are added to the dictionary created from the positional argument. If a key being added is already present, the value from the keyword argument replaces the value from the positional argument. To illustrate, the following examples all return a dictionary equal to `{"one": 1, "two": 2, "three": 3}`: - -```python ->>> a = {'two': 2, 'one': 1, 'three': 3} ->>> b = {'one': 1, 'two': 2, 'three': 3} ->>> c = {'three': 3, 'one': 1, 'two': 2} ->>> a == b == c -True -``` - -Providing keyword arguments as in the first example only works for keys that are valid KCL identifiers. Otherwise, any valid keys can be used. - -In the dict comprehension, key/value pairs yielded by the generator expression is set in the dictionary in the order yielded: the first occurrence of the key determines its insertion order, and the last determines the value associated to it. - -```python ->>> {str(i): 2 * i for i in range(3)} -{"0": 0, "1": 2, "2": 4} - ->>> a = {"one": 1, "two": 2, "three": 3} ->>> b = {k: v for k, v in a if v >= 2} -{two: 2, three: 3} -``` - -#### Operations & Members - -These are the operations that dictionaries the support. - -- `list(d)` - Return a list of all the keys used in the dictionary d. -- `len()` - Return the number of items in the dictionary d. -- `d[key]` - Return the item of d with key. Return Undefined if key is not in the map. -- `key in d` - Return True if d has a key, else False. -- `key not in d` - Equivalent to not key in d. -- `d.key` - Return the item of d with key. Return Undefined if key is not in the map. - -Dictionaries compare equal if and only if they have the same (key, value) pairs(keys' ordering matters). Order comparisons (‘<’, ‘<=’, ‘>=’, ‘>’) raise TypeError. - -```python ->>> d = {"one": 1, "two": 2, "three": 3, "four": 4} ->>> d -{'one': 1, 'two': 2, 'three': 3, 'four': 4} ->>> list(d) -['one', 'two', 'three', 'four'] -``` diff --git a/versioned_docs/version-0.5.2/reference/lang/spec/error.md b/versioned_docs/version-0.5.2/reference/lang/spec/error.md deleted file mode 100644 index 2a58b553..00000000 --- a/versioned_docs/version-0.5.2/reference/lang/spec/error.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: "Errors" -linkTitle: "Errors" -type: "docs" -weight: 2 -description: Errors ---- - -When errors happen, developers should be able to detect the error and abort -execution. Thus, KCL introduce the `assert` syntax. - -In the previous topic of `schema` syntax. Errors can also be raised when a -schema is violated. - -## Syntax - -The syntax of the `assert` statement is the following. - -```bnf -assert_stmt: 'assert' test ['if' test] [',' test] -``` - -In the basic form, an `assert` statement evaluates an expression. If the -expression is evaluated to `False`, the assertion is failed, and an error -should be reported. - -In the extended form, an error message can be provided. The error message is -another expression. It is only evaluated when the expression to be evaluated -is evaluated to `False`. The evaluation result of the error message is printed -when reporting the error. - -The following is an example: - -```python -a = 1 -b = 3 -condition = False -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -# if condition is True, then assert `a == b`, if failed, the message "error message" will be printed. -assert a == b if condition, "error message" -``` - -## The Implementation - -When an error happens, no matter it is caused by the `assert` or the `schema` syntax, -the virtual machine should exit with an exit code greater than `0`. - -The virtual machine may choose to dump the back trace information, and it is strongly recommended to implement it. - -In practice, KCL can dump back trace by default, and an argument can be introduced to disable it. diff --git a/versioned_docs/version-0.5.2/reference/lang/spec/expressions.md b/versioned_docs/version-0.5.2/reference/lang/spec/expressions.md deleted file mode 100644 index b52c10f3..00000000 --- a/versioned_docs/version-0.5.2/reference/lang/spec/expressions.md +++ /dev/null @@ -1,915 +0,0 @@ ---- -title: "Expressions" -linkTitle: "Expressions" -type: "docs" -weight: 2 -description: Expressions ---- - -## Syntax - -In KCL, an expression specifies the computation of a value. - -The syntax is the following: - -```bnf -expression: test ("," test)* -test: if_expr | primary_expr | unary_expr | binary_expr -``` - -KCL expressions consist of `if` expression, `primary` expression, `unary` expression, and `binary` expression. - -### Primary Expressions - -Primary expressions are the operands for unary and binary expressions. - -Operands are self-delimiting. An **operand** may be followed by any number of selector dot, a function call, or slice suffixes, to form a primary expression. The grammar uses `expression`, where a multiple-component expression is allowed, and `test` where it accepts an expression of only a single component. - -Syntax: - -```bnf -primary_expr: operand | primary_expr select_suffix | primary_expr call_suffix | primary_expr subscript_suffix -``` - -### Operands - -Operand denotes the elementary value in an expression. An operand may be an identifier, a literal, or a parenthesized expression. - -Syntax: - -```bnf -operand: operand_name | number | string | "True" | "False" | "None" | "Undefined" | list_expr | list_comp | dict_expr | dict_comp | "(" expression ")" -operand_name: identifier | qualified_identifier -``` - -### Identifiers - -In KCL, an identifier is a name, may with selectors, that identifies a value. - -Syntax: - -```bnf -identifier: NAME -``` - -Examples: - -```python -x -a -_b -``` - -Use the `$` character prefix to define keyword identifiers. - -```python -$if = 1 -$else = "s" -``` - -Please note: whether the non-keyword identifier is prefixed with `$` has the same effect. - -```python -_a = 1 -$_a = 2 # equal to `_a = 2` -``` - -To simplify the definition of the qualified identifier, such as 'pkg.type', we additionally define `qualified_identifier`: - -Syntax: - -```bnf -qualified_identifier: identifier "." identifier -``` - -Examples: - -```python -pkg.a -``` - -The package name in qualified_identifier must be imported. - -### Basic Literals - -Basic literals supported in KCL are `int`, `float`, `string` and `bool` including `True` and `False`. Evaluation of basic literal yields a value of the given type with the given value. - -Syntax: - -```bnf -operand: number | string | "True" | "False" | "None" | "Undefined" -``` - -Examples: - -```python -1 -2.3 -"abc" -True -False -None -Undefined -``` - -See more details about **data type** spec. - -### Parenthesized Expressions - -An expression enclosed in parentheses yields the result of that expression. - -Syntax: - -```bnf -operand: '(' expression ')' -``` - -Examples: - -```python -x = (1 + 2) * (3 + 4) # 21 -``` - -### Dictionary Expressions - -A dictionary expression is a comma-separated immutable list of colon-separated key/value expression pairs, enclosed in curly brackets, and it yields a new dictionary object. An optional comma may follow the final pair. - -```bnf -config_expr: '{' config_entries '}' -config_entries: config_entry [config_entry*] -config_comp: '{' (config_entry comp_clause+) '}' -config_entry: expr (':' | '=' | '+=') expr | double_star_expr | if_entry -double_star_expr: "**" expression -if_entry: - 'if' expr ';' if_entry_exec_block - ('elif' expr ':' if_entry_exec_block)* - ('else' ':' if_entry_exec_block)? -NEWLINE: '/r?/n' -``` - -Examples: - -```python -{} -{"one": 1} -{"one": 1, "two": 2} -``` - -The key and value expressions are evaluated in left-to-right order. Evaluation fails if the same key is used multiple times. - -Only hashable values may be used as the keys of a dictionary. This includes all built-in types except dictionaries, and lists. - -We can ignore the comma `,` at the end of the line for writing dict key-value pairs in multiple lines: - -```python -data = { - "key1" = "value1" # Ignore the comma ',' at the end of line - "key2" = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -We can ignore the key quotation marks when we writing simple literals on the key. - -```python -data = { - key1 = "value1" # Ignore the comma ',' at the end of line - key2 = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -In addition, the **config selector expressions** can be used to init a schema instance. - -```python -person = { - base.count = 2 - base.value = "value" - labels.key = "value" -} # {"base": {"count": 2, "value": "value"}, "labels": {"key": "value"}} -``` - -We can **merge** dict using the dict unpacking operator `**` like this: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = {**_part1, **_part2} # {"a: "b", "c": "d"} -``` - -We can use `if expressions` to dynamically add elements to the dict element, elements that meet the conditions are added to the dict, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = { - key1 = "value1" - if a == 1: key2 = "value2" - if a > 0: key3 = "value3" - if a < 0: key4 = "value4" -} # {"key1": "value1", "key2": "value2", "key3": "value3"} -``` - -```python -a = 1 # 1 -data1 = { - key1 = "value1" - if a == 1: - key2 = "value2" - elif a > 0: - key3 = "value3" - else: - key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -data2 = { - key1 = "value1" - if a == 1: key2 = "value2" - elif a > 0: key3 = "value3" - else: key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -``` - -### List Expressions - -A list expression is a comma-separated immutable list of element expressions, enclosed in square brackets, and it yields a new list. An optional comma may follow the last element expression. - -```bnf -list_expr: '[' [list_item [',']] ']' -list_item: test | "*" primary_expr | if_expr -``` - -Element expressions are evaluated in left-to-right order. - -Examples: - -```python -[] # [], empty list -[1] # [1], a 1-element list -[1, 2, 3] # [1, 2, 3], a 3-element list -``` - -We can use `if expressions` to dynamically add elements to the list element, elements that meet the conditions are added to the list, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = [ - 1 - if a == 1: 2 - if a > 0: 3 - if a < 0: 4 -] # [1, 2, 3] -``` - -```python -a = 1 # 1 -data1 = [ - 1 - if a == 1: - 2 - elif a == 2: - 3 - else: - 3 -] # [1, 2] -data2 = [ - 1 - if a == 1: 2 - elif a == 2: 2 - else: 3 -] # [1, 2] -``` - -### Comprehensions - -A comprehension constructs a new list or dictionary value by looping over one or more iterables and evaluating a body expression that produces successive elements of the result. - -Syntax: - -```bnf -list_comp: '[' list_item comp_clause+ ']' . -dict_comp: '{' entry comp_clause+ '}' . - -comp_clause: 'for' loop_variables [","] 'in' test ['if' test] -loop_variables: primary_expr (',' primary_expr)* -``` - -A list comprehension consists of a single expression followed by one or more clauses, the first of which must be a `for` clause. Each `for` clause resembles a `for` statement, and specifies an iterable operand and a set of variables to be assigned by successive values of the iterable. An `if` cause resembles an `if` statement, and specifies a condition that must be met for the body expression to be evaluated. A sequence of `for` and `if` clauses acts like a nested sequence of `for` and `if` statements. - -Examples: - -```python -[x * x for x in range(5)] # [0, 1, 4, 9, 16] -[x * x for x in range(5) if x % 2 == 0] # [0, 4, 16] -[[x, y] for x in range(5) \ - if x % 2 == 0 \ - for y in range(5) \ - if y > x] # [[0, 1], [0, 2], [0, 3], [0, 4], [2, 3], [2, 4]] -``` - -Besides, we can use two variables in the list comprehension, the first variable denotes the list index and the second variable denotes the list item. - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use `_` to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -A dict comprehension resembles a list comprehension, but its body is a pair of expressions, key: value, separated by a colon, and its result is a dictionary containing the key/value pairs for which the body expression was evaluated. Evaluation fails if the value of any key is un-hashable. - -Besides, we can use two variables in the dict comprehension, the first variable denotes the dict key and the second variable denotes the dict value of the key. - -```python -data = {"key1" = "value1", "key2" = "value2"} -# Single variable loop -dataKeys1 = {k: k for k in data} # {"key1": "key1", "key2": "key2"} -dataValues1 = {k: data[k] for k in data} # {"key1": "value1", "key2": "value2"} -# Double variable loop -dataKeys2 = {k: k for k, v in data} # {"key1": "key1", "key2": "key2"} -dataValues2 = {v: v for k, v in data} # {"value1": "value1", "value2": "value2"} -dataFilter = {k: v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use `_` to ignore loop variables -dataKeys3 = {k: k for k, _ in data} # {"key1": "key1", "key2": "key2"} -dataValues3 = {v: v for _, v in data} # {"value1": "value1", "value2": "value2"} -``` - -As with a `for` loop, the loop variables may exploit compound assignment: - -```python -[x * y + z for [x, y], z in [[[2, 3], 5], [["o", 2], "!"]]] # [11, 'oo!'] -``` - -KCL does not accept an un-parenthesized list as the operand of a for clause: - -```python -[x * x for x in 1, 2, 3] # parse error: unexpected comma -``` - -Comprehensions defines a new lexical block, so assignments to loop variables have no effect on variables of the same name in an enclosing block: - -```python -x = 1 -_ = [x for x in [2]] # new variable x is local to the comprehension -print(x) # 1 -``` - -The operand of a comprehension's first clause (always a for) is resolved in the lexical block enclosing the comprehension. In the examples below, identifiers referring to the outer variable named x have been distinguished by subscript. - -```python -x0 = [1, 2, 3] -[x * x for x in x0] # [1, 4, 9] -[x * x for x in x0 if x % 2 == 0] # [4] -``` - -All subsequent for and if expressions are resolved within the comprehension's lexical block, as in this rather obscure example: - -```python -x0 = [[1, 2], [3, 4], [5, 6]] -[x * x for x in x0 for x in x if x % 2 == 0] # [4, 16, 36] -``` - -which would be more clearly rewritten as: - -```python -x = [[1, 2], [3, 4], [5, 6]] -[z * z for y in x for z in y if z % 2 == 0] # [4, 16, 36] -``` - -### Conditional Expressions - -A conditional expression has the form `a if cond else b`. It first evaluates the condition `cond`. If it's true, it evaluates `a` and yields its value; otherwise it yields the value of `b`. - -Syntax: - -```bnf -if_expr: test "if" test "else" test -``` - -Examples: - -```python -x = True if enabled else False # if enabled is -``` - -### Unary Expressions - -In KCL, supported unary operators are `+`, `-`, `~`, and `not`. - -Syntax: - -```bnf -unary_expr: ("+" | "-" | "~") primary_expr - | "not" test -``` - -Usage: - -```bnf -+ number unary positive (int, float) -- number unary negation (int, float) -~ number unary bitwise inversion (int) -not x logical negation (any type) -``` - -The `+` and `-` operators may be applied to any number (int or float) and return the number. -The `not` operator returns the negation of the truth value of its operand. - -Examples: - -```python -~1 # -2 -~-1 # 0 -~0 # -1 -not True # False -not 0 # True -``` - -### Binary Expressions - -In KCL, binary expressions consist of `comparisons`, `logical operations`, `arithmetic operations` and `membership tests`. - -Syntax: - -```bnf -binary_expr: test bin_op test -bin_op: 'or' - | 'and' - | '==' | '!=' | '<' | '>' | '<=' | '>=' - | 'in' | 'not' 'in' - | '|' - | '^' - | '&' - | '-' | '+' - | '*' | '%' | '/' | '//' - | '<<' | '>>' -``` - -#### Logical Operations - -The `or` and `and` operators yield the logical disjunction and conjunction of their arguments, which need not be Booleans. - -The expression `x or y` yields the value of `x` if its truth value is `True`, or the value of `y` otherwise. - -```python -False or False # False -False or True # True -True or True # True -1 or "hello" # 1 -``` - -Similarly, `x` and `y` yields the value of `x` if its truth value is `False`, or the value of `y` otherwise. - -```python -False and False # False -False and True # False -True and True # True -1 and "hello" # "hello" -``` - -These operators use "short circuit" evaluation, so the second expression is not evaluated if the value of the first expression has already determined the result, allowing constructions like these: - -```python -x and x[0] == 1 # x[0] is not evaluated if x is empty -len(x) == 0 or x[0] == "" -not x or not x[0] -``` - -#### Comparisons - -The `==` operator reports whether its operands are equal; the `!=` operator is its negation. - -The operators `<`, `>`, `<=`, and `>=` perform an ordered comparison of their operands. It is an error to apply these operators to operands of unequal type, unless one of the operands is an `int` and the other is a `float`. Of the built-in types, only the following support ordered comparison, using the ordering relation shown: - -```bnf -NoneType # None <= None -bool # False < True -int # mathematical -float # as defined by IEEE 754 -string # lexicographical -list # lexicographical -``` - -Comparison of floating-point values follows the IEEE 754 standard, which breaks several mathematical identities. For example, if `x` is a `NaN` value, the comparisons `x < y`, `x == y`, and `x > y` all yield false for all values of `y`. - -The remaining built-in types support only equality comparisons. Values of type `dict` and `schema` compare equal if their elements compare equal, and values of type function or `builtin_function_or_method` are equal only to themselves. - -```bnf -dict # equal contents -schema # equal exported-attributes -function # identity -builtin_function_or_method # identity -``` - -#### Arithmetic Operations - -The following table summarizes the binary arithmetic operations available for built-in types: - -```bnf -Arithmetic (int or float; result has type float unless both operands have type int) - number + number # addition - number - number # subtraction - number * number # multiplication - number / number # real division (result is always a float) - number // number # floored division - number % number # remainder of floored division - number ^ number # bitwise XOR - number << number # bitwise left shift - number >> number # bitwise right shift - -Concatenation - string + string - list + list - -Repetition (string/list) - int * sequence - sequence * int - -Union - int | int - list | list - dict | dict - schema | schema - schema | dict -basictype | basictype -``` - -The operands of the arithmetic operators `+`, `-`, `*`, `//`, and `%` must both be numbers (`int` or `float`) but need not have the same type. The type of the result has type `int` only if both operands have that type. The result of real division / always has type `float`. - -The `+` operator may be applied to non-numeric operands of the same type, such as two lists, or two strings, in which case it computes the concatenation of the two operands and yields a new value of the same type. - -```python -"Hello, " + "world" # "Hello, world" -[1, 2] + [3, 4] # [1, 2, 3, 4] -``` - -The `*` operator may be applied to an integer n and a value of type `string`, `list`, in which case it yields a new value of the same sequence type consisting of n repetitions of the original sequence. The order of the operands is immaterial. Negative values of n behave like zero. - -```python -'mur' * 2 # 'murmur' -3 * range(3) # [0, 1, 2, 0, 1, 2, 0, 1, 2] -``` - -The `&` operator requires two operands of the same type, such as `int`. For integers, it yields the bitwise intersection (AND) of its operands. - -The `|` operator likewise computes bitwise, unions basic types and unions collection and schema data, such as **list**, **dict** and **schema**. - -Computing bitwise examples: - -```python -0x12345678 | 0xFF # 0x123456FF -``` - -Unioning basic types examples: - -```python -schema x: - a: int | str # attribute a could be a int or string -``` - -A union type is used to define a schema attribute type. See more details in **schema** spec. -Supported types in a union type are `int`, `str`, `float`, `bool`, `list` and `dict`. - -Unioning collection and schema data: - -- Unioning List. Overwrite the list expression on the right side of the operator `|` to the list variable on the left side of the operator one by one according to the **index**. - -```python -_a = [1, 2, 3] -_b = [4, 5, 6, 7] -x = _a | _b # [4, 5, 6, 7] 4 -> 1; 5 -> 2; 6 -> 3; 7 -> None -``` - -Unioning to the specific index or all elements is still under discussion. - -- Unioning Dict. Union the dict expression on the right side of the operator `|` one by one to the dict variable on the left side of the operator according to the **key** - -```python -_a = {key1 = "value1"} -_b = {key1 = "overwrite", key2 = "value2"} -_c = _a | _b # {"key1": "overwrite", "key2": "value2"} -``` - -The union of collection and schema is a new one whose attributes are unioning b to a, preserving the order of the attributes of the operands, left before right. - -Unioning to the specific key or all keys is still under discussion. - -- Unioning Schema. - -The union operation for schema is similar to dict. - -Schema union could be done as: - -```bnf -schema Person: - firstName: str - lastName: str - -_a = Person { - firstName = "John" -} -_b = {lastName = "Doe"} -_a = _a | _b # {"firstName": "John", "lastName": "Doe"} -``` - -Unioning to a specific attribute is still under discussion. Unioning to all attributes is not applicable to schema instances. - -See **selector expression** in **expression** spec for more details. - -The `^` operator accepts operands of `int`. For integers, it yields the bitwise XOR (exclusive OR) of its operands. - -The `<<` and `>>` operators require operands of `int` type both. They shift the first operand to the left or right by the number of bits given by the second operand. It is a dynamic error if the second operand is negative. Implementations may impose a limit on the second operand of a left shift. - -```python -0x12345678 & 0xFF # 0x00000078 -0b01011101 ^ 0b110101101 # 0b111110000 -0b01011101 >> 2 # 0b010111 -0b01011101 << 2 # 0b0101110100 -``` - -#### Membership Tests - -Usage: - -```bnf - any in sequence (list, dict, schema, string) - any not in sequence -``` - -The `in` operator reports whether its first operand is a member of its second operand, which must be a list, dict, schema, or string. The `not in` operator is its negation. Both return a Boolean. - -The meaning of membership varies by the type of the second operand: the members of a list are its elements; the members of a dict are its keys; the members of a string are all its substrings. - -```python -1 in [1, 2, 3] # True - -d = {"one" = 1, "two" = 2} -"one" in d # True -"three" in d # False -1 in d # False -[] in d # False - -"nasty" in "dynasty" # True -"a" in "banana" # True -"f" not in "way" # True - -d = data {one = 1, two = 2} # data is a schema with attributes one and two -"one" in d # True -"three" in d # False -``` - -### Function Invocations - -KCL allows calling built-in functions and functions from built-in and system modules. Whether KCL allows defining new functions is under discussion. - -Syntax: - -```bnf -call_suffix: "(" [arguments [","]] ")" -arguments: argument ("," argument)* -argument: test | identifier "=" test | "*" test | "**" test -``` - -To call a function, the basic way is shown as the following code excerpt: - -```python -print("An argument") - -import math -# 2 powers 3 is 8. -a = math.pow(2, 3) -``` - -As you can see, arguments are separated with `,`. Arguments can only be passed in this way. KCL supports positional arguments and key-value arguments. - -Note that: - -- Some functions have parameters with default values. -- Some functions accept variadic arguments. - -When an argument is not supplied for a parameter without a default value, -an error will be reported. - -### Selector Expressions - -A selector expression selects the attribute or method of the value. - -#### Select Attributes - -Syntax: - -```bnf -select_suffix: ["?"] "." identifier -``` - -KCL provides a wealth of ways to identify or filter attributes. - -x.y - -- schema: it denotes the attribute value of a schema `x` identified by `y` -- package: it denotes the identifier of a package `x` identified by `y` - -Examples: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -name = person.name # "Alice" -age = person.age # 18 -``` - -x?.y - -If the x if None/Undefined or empty(empty list or dict), just return None, otherwise behave as x.y. - -Examples - -```python -noneData = None -data?.name # None - -emptyDict = {} -emptyDict?.name # None - -emptyList = [] -emptyList?[0] # None -``` - -As a supplementary of the `selector` expression in KCL code, the KCL compiler needs to provide corresponding identifying and filtering features through the command line and api form. - -#### Select Methods - -Syntax: - -```bnf -select_suffix: "." identifier -``` - -A `identifier` identifies method belongs to the built-in types `string`, `list`, `dict`, and `schema`. - -- A selector expression fails if the value does not have an attribute of the specified name. -- A selector expression that selects a method typically appears within a call expression, as in these examples: - -Examples: - -```python -["able", "baker", "charlie"].index("baker") # 1 -"banana".count("a") # 3 -"banana".reverse() # error: string has no .reverse field or method -Person.instances() # all instances of schema Person -``` - -But when not called immediately, the selector expression evaluates to a bound method, that is, a method coupled to a specific receiver value. A bound method can be called like an ordinary function, without a receiver argument: - -```bnf -f = "banana".count -f # -f("a") # 3 -f("n") # 2 -``` - -### Index Expressions - -An index expression `a[i]` yields the `i` th element of an indexable type such as a string or list. The index `i` must be an `int` value in the range `-n` ≤ `i` < `n`, where `n` is `len(a)`; any other index results in an error. - -Syntax: - -```bnf -subscript_suffix: "[" [test] "]" -``` - -A valid negative index `i` behaves like the non-negative index `n+i`, allowing for convenient indexing relative to the end of the sequence. - -```python -"abc"[0] # "a" -"abc"[1] # "b" -"abc"[-1] # "c" - -["zero", "one", "two"][0] # "zero" -["zero", "one", "two"][1] # "one" -["zero", "one", "two"][-1] # "two" -``` - -An index expression `d[key]` may also be applied to a dictionary `d`, to obtain the value associated with the specified key. It returns `Undefined` if the dictionary contains no such key. - -An index expression appearing on the left side of an assignment causes the specified list or dictionary element to be updated: - -```python -a = range(3) # a == [0, 1, 2] -b = a[2] # 2 - - -``` - -It is a dynamic error to attempt to update an element of an immutable type, such as a list or string, or a frozen value of a mutable type. - -### Slice Expressions - -A slice expression `a[start:stop:stride]` yields a new value containing a sub-sequence of `a`, which must be a string, or list. - -```bnf -subscript_suffix: "[" [test] [":" [test] [":" [test]]] "]" -``` - -Each of the `start`, `stop`, and `stride` operands is optional; if present, and not `None`, each must be an integer. -The `stride` value defaults to 1. If the stride is not specified, the colon preceding it may be omitted too. It is an error to specify a stride of zero. - -Conceptually, these operands specify a sequence of values `i` starting at start and successively adding `stride` until `i` reaches or passes `stop`. The result consists of the concatenation of values of `a[i]` for which `i` is valid.` - -The effective start and stop indices are computed from the three operands as follows. Let `n` be the length of the sequence. - -**If the stride is positive**: If the `start` operand was omitted, it defaults to -infinity. If the `end` operand was omitted, it defaults to +infinity. For either operand, if a negative value was supplied, `n` is added to it. The `start` and `end` values are then "clamped" to the nearest value in the range 0 to `n`, inclusive. - -**If the stride is negative**: If the `start` operand was omitted, it defaults to +infinity. If the `end` operand was omitted, it defaults to -infinity. For either operand, if a negative value was supplied, `n` is added to it. The `start` and `end` values are then "clamped" to the nearest value in the range -1 to `n`-1, inclusive. - -```python -"abc"[1:] # "bc" (remove first element) -"abc"[:-1] # "ab" (remove last element) -"abc"[1:-1] # "b" (remove first and last element) -"banana"[1::2] # "aaa" (select alternate elements starting at index 1) -"banana"[4::-2] # "nnb" (select alternate elements in reverse, starting at index 4) -``` - -It's not allowed to define a slice expression as a left value in KCL. -Cause list and string are immutable, re-slicing can directly operate to operand to ensure better performance. - -#### Quantifier Expressions - -Quantifier expressions act on collection: list or dict, generally used to obtain a certain result after processing the collection, mainly in the following four forms: - -```bnf -quant_expr: quant_op [ identifier ',' ] identifier 'in' quant_target '{' expr ['if' expr] '}' -quant_target: string | identifier | list_expr |list_comp | dict_expr | dict_comp -quant_op: 'all' | 'any' | 'filter' | 'map' -``` - -- **all** - - Used to detect that all elements in the collection satisfy the given logical expression, and return a boolean value as the result. - - Only when all elements in the collection satisfy the expression true, the `all` expression is true, otherwise it is false. - - If the original collection is empty, return true. - - Supports short-circuiting of logical expressions during expression execution. -- **any** - - Used to detect that at least one element in the collection satisfies the given logical expression, and returns a boolean value as the result. - - When at least one element in the collection satisfies the expression true, the `any` expression is true, otherwise it is false. - - If the original collection is empty, return false. - - Supports short-circuiting of logical expressions during expression execution. -- **map** - - Generate a new **list** by mapping the elements in the original collection. - - The length of the new list is exactly the same as the original collection. -- **filter** - - By logically judging and filtering the elements in the original collection, and returning the filtered sub-collection. - - Only when the element judges the expression to be true, it is added to the sub-collection. - - The type (list, dict and schema) of the new collection is exactly the same as the original collection, and the length range is `[0, len(original-collection)]`. - -**all** and **any** expression sample codes: - -```python -schema Config: - volumes: [{str:}] - services: [{str:}] - - check: - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - }, "invalid cluster ip" - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } -``` - -**map** and **filter** expression sample codes: - -```python -a = map e in [{name = "1", value = 1}, {name = "2", value = 2}] { - {name = e.name, value = int(e.value) ** 2} -} # [{"name": "1", value: 1}, {"name": "2", "value": 4}] - -b = map k, v in {a = "foo", b = "bar"} { v } # ["foo", "bar"] - -c = filter e in [{name = "1", value = 1}, {name = "2", value = 2}] { - int(e.value) > 1 -} # [{"name": "2", "value": 2}] - -d = filter _, v in {a = "foo", b = "bar"} { - v == "foo" -} # {"a": "foo"} -``` - -Please pay attention to distinguish the difference between any expression and any type. When `any` is used in type annotations, it means that the value of the variable is arbitrary, while the any expression means that one of the elements in a set satisfies the condition. diff --git a/versioned_docs/version-0.5.2/reference/lang/spec/kcl-spec.md b/versioned_docs/version-0.5.2/reference/lang/spec/kcl-spec.md deleted file mode 100644 index 63a9d6e7..00000000 --- a/versioned_docs/version-0.5.2/reference/lang/spec/kcl-spec.md +++ /dev/null @@ -1,343 +0,0 @@ ---- -title: "KCL Spec" -linkTitle: "KCL Spec" -type: "docs" -weight: 2 -description: KCL Spec ---- - -## Lexical rules - -### Keywords and reserved words - -The following are the keywords of the KCL: - -```python -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -The following are reserved words for the KCL: - -```python -pass return validate rule flow -def del raise except try -finally while from with yield -global nonlocal struct class final -``` - -### Line comment - -```python -# a comment -``` - -### Operators - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != = -+= -= *= **= /= //= %= -<<= >>= &= ^= -``` - -### Delimiters - -```python -( ) [ ] { } -, : . ; @ -``` - -### Operator precedence - -The following list of operators is ordered from **highest to lowest**: - -| Operator | Description | -| -------------------------------------------------------------------------------- | -------------------------------------------------------- | -| `**` | Exponentiation (highest priority) | -| `+x` `-x` `~x` | Positive, negative, bitwise NOT | -| `*` `/` `%` `//` | Multiplication, division, floor division and remainder | -| `+` `-` | Addition and subtraction | -| `<<` `>>` | Left and right shifts | -| `&` | Bitwise AND | -| `^` | Bitwise XOR | -| \| | Bitwise OR | -| `in`, `not in`, `is`, `is not`, `<`, `<=`, `>`, `>=`, `!=`, `==` | Comparisons, including membership and identity operators | -| `not` | Boolean NOT | -| `and` | Boolean AND | -| `or` | Boolean OR | -| `if – else` | Conditional expression = | -| `=`, `+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `=`, `^=`, `\*\*=`, `//=`, `<<=`, `>>=` | Assign | - -## Grammar - -KCL uses Python's [LarkParser](https://lark-parser.readthedocs.io/en/latest/) tool to describe the grammar, and the specification rules are as follows: - -```bnf -//////////// KCL grammar //////////// -start: (NEWLINE | statement)* - -statement: simple_stmt | compound_stmt -simple_stmt: (assign_stmt | unification_stmt | expr_stmt | assert_stmt | import_stmt | type_alias_stmt) NEWLINE -compound_stmt: if_stmt | schema_stmt | rule_stmt - -//////////// import_stmt //////////// -import_stmt: IMPORT dot_name (AS NAME)? -dot_name: (leading_dots identifier) | identifier -leading_dots: DOT+ - -/////////// assert_stmt //////////// -assert_stmt: ASSERT simple_expr (IF simple_expr)? (COMMA test)? - -//////////// if_stmt //////////// -if_stmt: IF test COLON execution_block (ELIF test COLON execution_block)* (ELSE COLON execution_block)? -execution_block: if_simple_stmt | NEWLINE _INDENT schema_init_stmt+ _DEDENT -if_simple_stmt: (simple_assign_stmt | unification_stmt | expr_stmt | assert_stmt) NEWLINE - -//////////// assign_stmt //////////// -assign_stmt: identifier [COLON type] (ASSIGN identifier)* ASSIGN test - | identifier (COMP_PLUS | COMP_MINUS | COMP_MULTIPLY | COMP_DOUBLE_STAR | COMP_DIVIDE - | COMP_DOUBLE_DIVIDE | COMP_MOD | COMP_AND | COMP_OR | COMP_XOR | COMP_SHIFT_LEFT - | COMP_SHIFT_RIGHT) test - -simple_assign_stmt: identifier ASSIGN test - | identifier (COMP_PLUS | COMP_MINUS | COMP_MULTIPLY | COMP_DOUBLE_STAR | COMP_DIVIDE - | COMP_DOUBLE_DIVIDE | COMP_MOD | COMP_AND | COMP_OR | COMP_XOR | COMP_SHIFT_LEFT - | COMP_SHIFT_RIGHT) test - -//////////// unification_stmt //////////// -unification_stmt: identifier COLON schema_expr - -//////////// schema_stmt //////////// -schema_stmt: [decorators] (SCHEMA|MIXIN|PROTOCOL) NAME [LEFT_BRACKETS [schema_arguments] RIGHT_BRACKETS] [LEFT_PARENTHESES identifier (COMMA identifier)* RIGHT_PARENTHESES] [for_host] COLON NEWLINE [schema_body] -schema_arguments: schema_argument (COMMA schema_argument)* -schema_argument: NAME [COLON type] [ASSIGN test] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt|schema_init_stmt|schema_index_signature)* [check_block] _DEDENT -schema_attribute_stmt: attribute_stmt NEWLINE -attribute_stmt: [decorators] identifier [QUESTION] COLON type [(ASSIGN|COMP_OR) test] -schema_init_stmt: if_simple_stmt | if_stmt -schema_index_signature: LEFT_BRACKETS [NAME COLON] [ELLIPSIS] basic_type RIGHT_BRACKETS COLON type [ASSIGN test] NEWLINE - -//////////// rule_stmt //////////// -rule_stmt: [decorators] RULE NAME [LEFT_BRACKETS [schema_arguments] RIGHT_BRACKETS] [LEFT_PARENTHESES identifier (COMMA identifier)* RIGHT_PARENTHESES] [for_host] COLON NEWLINE [rule_body] -rule_body: _INDENT (string NEWLINE)* check_expr+ _DEDENT - -for_host: FOR identifier - -/////////// decorators //////////// -decorators: (AT decorator_expr NEWLINE)+ -decorator_expr: identifier [call_suffix] - -//////////// type //////////// -type: type_element (OR type_element)* -type_element: schema_type | basic_type | compound_type | literal_type -schema_type: identifier -basic_type: STRING_TYPE | INT_TYPE | FLOAT_TYPE | BOOL_TYPE | ANY_TYPE -compound_type: list_type | dict_type -list_type: LEFT_BRACKETS (type)? RIGHT_BRACKETS -dict_type: LEFT_BRACE (type)? COLON (type)? RIGHT_BRACE -literal_type: string | number | TRUE | FALSE | NONE - -//////////// type alias //////////// -type_alias_stmt: TYPE NAME ASSIGN type - -//////////// check_stmt //////////// -check_block: CHECK COLON NEWLINE _INDENT check_expr+ _DEDENT -check_expr: simple_expr [IF simple_expr] [COMMA primary_expr] NEWLINE - -//////////// mixin_stmt //////////// -mixin_stmt: MIXIN LEFT_BRACKETS [mixins | multiline_mixins] RIGHT_BRACKETS NEWLINE -multiline_mixins: NEWLINE _INDENT mixins NEWLINE _DEDENT -mixins: identifier (COMMA (NEWLINE mixins | identifier))* - - -//////////// expression_stmt //////////// -expr_stmt: testlist_expr -testlist_expr: test (COMMA test)* -test: if_expr | simple_expr -if_expr: simple_expr IF simple_expr ELSE test - -simple_expr: unary_expr | binary_expr | primary_expr - -unary_expr: un_op simple_expr -binary_expr: simple_expr bin_op simple_expr - -bin_op: L_OR | L_AND - | OR | XOR | AND - | SHIFT_LEFT | SHIFT_RIGHT - | PLUS | MINUS | MULTIPLY | DIVIDE | MOD | DOUBLE_DIVIDE - | DOUBLE_STAR - | EQUAL_TO | NOT_EQUAL_TO - | LESS_THAN | GREATER_THAN | LESS_THAN_OR_EQUAL_TO | GREATER_THAN_OR_EQUAL_TO - | IN | L_NOT IN | IS | IS L_NOT | L_NOT | AS -un_op: L_NOT | PLUS | MINUS | NOT - -primary_expr: identifier call_suffix | operand | primary_expr select_suffix | primary_expr call_suffix | primary_expr slice_suffix -operand: identifier | number | string | constant | quant_expr | list_expr | list_comp | config_expr | dict_comp | schema_expr | lambda_expr | LEFT_PARENTHESES test RIGHT_PARENTHESES -select_suffix: [QUESTION] DOT NAME -call_suffix: LEFT_PARENTHESES [arguments [COMMA]] RIGHT_PARENTHESES -slice_suffix: [QUESTION] LEFT_BRACKETS (test | [test] COLON [test] [COLON [test]]) RIGHT_BRACKETS -arguments: argument (COMMA argument)* -argument: test | NAME ASSIGN test | MULTIPLY test | DOUBLE_STAR test - - -//////////// operand //////////// -identifier: NAME (DOT NAME)* -quant_expr: quant_op [ identifier COMMA ] identifier IN quant_target LEFT_BRACE (simple_expr [IF simple_expr] | NEWLINE _INDENT simple_expr [IF simple_expr] NEWLINE _DEDENT)? RIGHT_BRACE -quant_target: string | identifier | list_expr | list_comp | config_expr | dict_comp -quant_op: ALL | ANY | FILTER | MAP -list_expr: LEFT_BRACKETS [list_items | NEWLINE [_INDENT list_items _DEDENT]] RIGHT_BRACKETS -list_items: list_item ((COMMA [NEWLINE] | [NEWLINE]) list_item)* [COMMA] [NEWLINE] -list_item: test | star_expr | if_item -list_comp: LEFT_BRACKETS (list_item comp_clause+ | NEWLINE _INDENT list_item comp_clause+ _DEDENT) RIGHT_BRACKETS -dict_comp: LEFT_BRACE (entry comp_clause+ | NEWLINE _INDENT entry comp_clause+ _DEDENT) RIGHT_BRACE -entry: test (COLON | ASSIGN | COMP_PLUS) test -comp_clause: FOR loop_variables [COMMA] IN simple_expr [NEWLINE] [IF test [NEWLINE]] -if_entry: IF test COLON if_entry_exec_block (ELIF test COLON if_entry_exec_block)* (ELSE COLON if_entry_exec_block)? -if_entry_exec_block: (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry) [NEWLINE] | NEWLINE _INDENT (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry) ((COMMA [NEWLINE] | [NEWLINE]) (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry))* [COMMA] [NEWLINE] _DEDENT -if_item: IF test COLON if_item_exec_block (ELIF test COLON if_item_exec_block)* (ELSE COLON if_item_exec_block)? -if_item_exec_block: list_item [NEWLINE] | NEWLINE _INDENT list_item ((COMMA [NEWLINE] | NEWLINE) list_item)* [COMMA] [NEWLINE] _DEDENT - -star_expr: MULTIPLY test -double_star_expr: DOUBLE_STAR test -loop_variables: primary_expr (COMMA primary_expr)* -schema_expr: identifier (LEFT_PARENTHESES [arguments] RIGHT_PARENTHESES)? config_expr -config_expr: LEFT_BRACE [config_entries | NEWLINE [_INDENT config_entries _DEDENT]] RIGHT_BRACE -config_entries: config_entry ((COMMA [NEWLINE] | [NEWLINE]) config_entry)* [COMMA] [NEWLINE] -config_entry: test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry - -//////////// lambda_expr //////////// -lambda_expr: LAMBDA [schema_arguments] [RIGHT_ARROW type] LEFT_BRACE [expr_stmt | NEWLINE _INDENT schema_init_stmt+ _DEDENT] RIGHT_BRACE - -//////////// misc //////////// -number: DEC_NUMBER [multiplier] | HEX_NUMBER | BIN_NUMBER | OCT_NUMBER | FLOAT_NUMBER -multiplier: SI_N_L | SI_U_L | SI_M_L | SI_K_L | SI_K | SI_M | SI_G | SI_T | SI_P - | SI_K_IEC | SI_M_IEC | SI_G_IEC | SI_T_IEC | SI_P_IEC -string: STRING | LONG_STRING -constant : TRUE | FALSE | NONE | UNDEFINED -// Tokens - -ASSIGN: "=" -COLON: ":" -SEMI_COLON: ";" -COMMA: "," -QUESTION: "?" -ELLIPSIS: "..." -RIGHT_ARROW: "->" -LEFT_PARENTHESES: "(" -RIGHT_PARENTHESES: ")" -LEFT_BRACKETS: "[" -RIGHT_BRACKETS: "]" -LEFT_BRACE: "{" -RIGHT_BRACE: "}" -PLUS: "+" -MINUS: "-" -MULTIPLY: "*" -DIVIDE: "/" -MOD: "%" -DOT: "." -AND: "&" -OR: "|" -XOR: "^" -NOT: "~" -LESS_THAN: "<" -GREATER_THAN: ">" -EQUAL_TO: "==" -NOT_EQUAL_TO: "!=" -GREATER_THAN_OR_EQUAL_TO: ">=" -LESS_THAN_OR_EQUAL_TO: "<=" -DOUBLE_STAR: "**" -DOUBLE_DIVIDE: "//" -SHIFT_LEFT: "<<" -SHIFT_RIGHT: ">>" -AT: "@" - -COMP_PLUS: "+=" -COMP_MINUS: "-=" -COMP_MULTIPLY: "*=" -COMP_DIVIDE: "/=" -COMP_MOD: "%=" -COMP_AND: "&=" -COMP_OR: "|=" -COMP_XOR: "^=" -COMP_DOUBLE_STAR: "**=" -COMP_DOUBLE_DIVIDE: "//=" -COMP_SHIFT_LEFT: "<<=" -COMP_SHIFT_RIGHT: ">>=" - -// Special tokens -IMPORT: "import" -AS: "as" -RULE: "rule" -SCHEMA: "schema" -MIXIN: "mixin" -PROTOCOL: "protocol" -CHECK: "check" -FOR: "for" -ASSERT: "assert" -IF: "if" -ELIF: "elif" -ELSE: "else" -L_OR: "or" -L_AND: "and" -L_NOT: "not" -IN: "in" -IS: "is" -LAMBDA: "lambda" -ALL: "all" -ANY: "any" -FILTER: "filter" -MAP: "map" -TYPE: "type" - -ANY_TYPE: "any" -STRING_TYPE: "str" -INT_TYPE: "int" -FLOAT_TYPE: "float" -BOOL_TYPE: "bool" - -// Constant tokens -TRUE: "True" -FALSE: "False" -NONE: "None" -UNDEFINED: "Undefined" - -// Binary prefix -SI_N_L: "n" -SI_U_L: "u" -SI_M_L: "m" -SI_K_L: "k" -SI_K: "K" -SI_M: "M" -SI_G: "G" -SI_T: "T" -SI_P: "P" -SI_K_IEC: "Ki" -SI_M_IEC: "Mi" -SI_G_IEC: "Gi" -SI_T_IEC: "Ti" -SI_P_IEC: "Pi" -IEC: "i" - -NAME: /\$?[a-zA-Z_]\w*/ -COMMENT: /#[^\n]*/ -NEWLINE: ( /\r?\n[\t ]*/ | COMMENT )+ - -STRING: /r?("(?!"").*?(? [as ] -``` - -The rule to search with the module name is very simple: - -- **Step 1**: Searches the module name from the **standard system modules**, then **plugins modules**. - - See **standard system modules** and **plugins modules** for more details. If matched, the module is imported. Otherwise, continue to **Step 2**. -- **Step 2**. Whether a module name starts with a `.` is checked. If yes, the name is a so-called relative pathname, and we go to **Step 5**. Otherwise, continue to **Step 3**. -- **Step 3**: If the module name does not start with any `.`, then the compiler searches the nearest `root path` directory from this directory to the parent, and find the module according to the name just from the `root path`. If no `root path` is found, find the module according to the name from the folder the `.k` file including this `import` statement exists. - - **root path**: the directory contains a `kcl.mod` file. If matched, the module is imported. Otherwise, continue to **Step 4**. -- **Step 4**: Then the compiler checks if the name is the name of any library module that requires explicit loading. If matched, the library module is imported. Otherwise, continue to **Step 6**. -- **Step 5**. For relative importing, find the module according to the name from the folder the `.k` file including this `import` statement exists. Interpret leading dots using the following rule: -- One dot: Ignore. -- Tow or more dots: Suppose there are `n` leading dots, then the searching starts at `n - 1` levels above this folder. If matched, the module is imported. Otherwise, continue to **Step 6**. -- **Step 6**. Module not found, report an error. - -Do case-sensitive search when the operating system allows. If case-sensitive search is not allowed, search directories before regular files. - -In KCL, the `from <> import <>` is unsupported, and relative import is performed with the `import <>` syntax. - -### Uniqueness of Module - -Each module has a unique location path in its scope, so that a module or package could be located with a unique location path, such as `a.b.c`. - -Searching by location path should be supported by the kcl compiler, which needs to provide corresponding searching features through the command line and api form. - -## Standard System Packages - -KCL supports a few standard system modules. The following is the full list of these standard system modules: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PackageMember
datetimetoday
now
ticks
date
mathceil
exp
expm1
factorial
floor
gcd
isfinite
isinf
isnan
log
log1p
log2
log10
modf
pow
sqrt
regexreplace
match
compile
findall
search
split
unitsn
u
m
k
K
M
G
T
P
Ki
Mi
Gi
Ti
Pi
to_n
to_u
to_m
to_K
to_M
to_G
to_T
to_P
to_Ki
to_Mi
to_Gi
to_Ti
to_Pi
jsonencode
decode
dump_to_file
yamlencode
decode
dump_to_file
netsplit_host_port
join_host_port
fqdn
parse_IP
to_IP4
to_IP16
IP_string
is_IPv4
is_IP
is_loopback_IP
is_multicast_IP
is_interface_local_multicast_IP
is_link_local_multicast_IP
is_link_local_unicast_IP
is_global_unicast_IP
is_unspecified_IP
base64encode
decode
cryptomd5
sha1
sha224
sha256
sha384
sha512
- -- datetime - - ticks() -> float - Return the current time in seconds since the Epoch. Fractions of a second may be present if the system clock provides them. - - date() -> str - return the `%Y-%m-%d %H:%M:%S` format date. - - now() -> str - return the local time. e.g. `'Sat Jun 06 16:26:11 1998'` - - today() -> str - return the `%Y-%m-%d %H:%M:%S.%{ticks}` format date. -- math - - ceil(x) -> int - Return the ceiling of x as an Integral. This is the smallest integer >= x. - - factorial(x) -> int - Return x!. Raise a error if x is negative or non-integral. - - floor(x) -> int - Return the floor of x as an Integral. This is the largest integer <= x. - - gcd(a: int, b: int) -> int - Return the greatest common divisor of x and y - - isfinite(x) -> bool - Return True if x is neither an infinity nor a NaN, and False otherwise. - - isinf(x) -> bool - Return True if x is a positive or negative infinity, and False otherwise. - - isnan(x) -> bool - Return True if x is a NaN (not a number), and False otherwise. - - modf(x) -> Listfloat, float] - Return the fractional and integer parts of x. Both results carry the sign of x and are floats. - - exp(x) -> float - Return e raised to the power of x. - - expm1(x) -> float - Return exp(x)-1. This function avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small x. - - log(x, base=2.71828182845904523536028747135266250) -> float - Return the logarithm of x to the base e. - - log1p(x) -> float - Return the natural logarithm of 1+x (base e). The result is computed in a way which is accurate for x near zero. - - log2(x) -> float - Return the base 2 logarithm of x. - - log10(x) -> float - Return the base 10 logarithm of x. - - pow(x, y) -> float - Return x\*\*y (x to the power of y). - - sqrt(x) -> float - Return the square root of x. -- regex - - replace(string: str, pattern: str, replace: str, count=0) -> str - Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement. - - match(string: str, pattern: str) -> bool - Try to apply the pattern at the start of the string, returning a bool value True if any match was found, or False if no match was found. - - compile(pattern: str) -> bool - Compile a regular expression pattern, returning a bool value denoting whether the pattern is valid. - - findall(string: str, pattern: str) -> List[str] - Return a list of all non-overlapping matches in the string. - - search(string: str, pattern: str) -> bool - Scan through string looking for a match to the pattern, returning a bool value True if any match was found, or False if no match was found. - - split(string: str, pattern: str, maxsplit=0) -> List[str] - Scan through string looking for a match to the pattern, returning a Match object, or None if no match was found. -- units - - Unit constants - - Fixed point: `n`, `u`, `m`, `k`, `K`, `G`, `T` and `P`. - - Power of 2: `Ki`, `Mi`, `Gi`, `Ti` and `Pi`. - - Functions - - to_n(num: int) -> str - Int literal to string with `n` suffix - - to_u(num: int) -> str - Int literal to string with `u` suffix - - to_m(num: int) -> str - Int literal to string with `m` suffix - - to_K(num: int) -> str - Int literal to string with `K` suffix - - to_M(num: int) -> str - Int literal to string with `M` suffix - - to_G(num: int) -> str - Int literal to string with `G` suffix - - to_T(num: int) -> str - Int literal to string with `T` suffix - - to_P(num: int) -> str - Int literal to string with `P` suffix - - to_Ki(num: int) -> str - Int literal to string with `Ki` suffix - - to_Mi(num: int) -> str - Int literal to string with `Mi` suffix - - to_Gi(num: int) -> str - Int literal to string with `Gi` suffix - - to_Ti(num: int) -> str - Int literal to string with `Ti` suffix - - to_Pi(num: int) -> str - Int literal to string with `Pi` suffix -- json - - encode(data: any, sort_keys: bool = False, indent: int = None, ignore_private: bool = False, ignore_none: bool = False) -> str - Serialize a KCL object `data` to a JSON formatted str. - - decode(value: str) -> any - Deserialize `value` (a string instance containing a JSON document) to a KCL object. - - dump_to_file(data: any, filename: str, ignore_private: bool = False, ignore_none: bool = False) -> None - Serialize a KCL object `data` to a JSON formatted str and write it into the file `filename`. -- yaml - - encode(data: any, sort_keys: bool = False, ignore_private: bool = False, ignore_none: bool = False) -> str - Serialize a KCL object `data` to a YAML formatted str. - - decode(value: str) -> any - Deserialize `value` (a string instance containing a YAML document) to a KCL object. - - dump_to_file(data: any, filename: str, ignore_private: bool = False, ignore_none: bool = False) -> None - Serialize a KCL object `data` to a YAML formatted str and write it into the file `filename`. -- net - - split_host_port(ip_end_point: str) -> List[str] - Split the 'host' and 'port' from the ip end point. - - join_host_port(host, port) -> str - Merge the 'host' and 'port'. - - fqdn(name: str = '') -> str - Return Fully Qualified Domain Name (FQDN). - - parse_IP(ip) -> str - Parse 'ip' to a real IP address - - to_IP4(ip) -> str - Get the IP4 form of 'ip'. - - to_IP16(ip) -> int - Get the IP16 form of 'ip'. - - IP_string(ip: str | int) -> str - Get the IP string. - - is_IPv4(ip: str) -> bool - Whether 'ip' is a IPv4 one. - - is_IP(ip: str) -> bool - Whether ip is a valid ip address. - - is_loopback_IP(ip: str) -> bool - Whether 'ip' is a loopback one. - - is_multicast_IP(ip: str) -> bool - Whether 'ip' is a multicast one. - - is_interface_local_multicast_IP(ip: str) -> bool - Whether 'ip' is a interface, local and multicast one. - - is_link_local_multicast_IP(ip: str) -> bool - Whether 'ip' is a link local and multicast one. - - is_link_local_unicast_IP(ip: str) -> bool - Whether 'ip' is a link local and unicast one. - - is_global_unicast_IP(ip: str) -> bool - Whether 'ip' is a global and unicast one. - - is_unspecified_IP(ip: str) -> bool - Whether 'ip' is a unspecified one. -- base64 - - encode(value: str, encoding: str = "utf-8") -> str - Encode the string `value` using the codec registered for encoding. - - decode(value: str, encoding: str = "utf-8") -> str - Decode the string `value` using the codec registered for encoding. -- crypto - - md5(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `MD5` and the codec registered for encoding. - - sha1(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA1` and the codec registered for encoding. - - sha224(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA224` and the codec registered for encoding. - - sha256(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA256` and the codec registered for encoding. - - sha384(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA384` and the codec registered for encoding. - - sha512(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA512` and the codec registered for encoding. -- manifests - - `yaml_stream(values: [any], opts: {str:} = {sort_keys = False, ignore_private = True, ignore_none = False, sep = "---"}`. This function is used to serialize the KCL object list into YAML output with the `---` separator - -### The Built-in System Package - -KCL provides a list of built-in system modules, which are loaded automatically and can be directly used without providing any module name. For example, `print` is a widely used built-in module. - -The following is the full list of these built-in system modules: - -- print() - - The print function. -- multiplyof(a, b) - - Check if the modular result of a and b is 0 -- isunique(inval) - - Check if a list has duplicated elements -- len(inval) - Return the length of a value -- abs(x) - Return the absolute value of the argument. -- all(iterable) - Return True if bool(x) is True for all values x in the iterable. If the iterable is empty, return True. -- any(iterable) - Return True if bool(x) is True for any x in the iterable. If the iterable is empty, return False. -- bin(number) - Return the binary representation of an integer. -- hex(number) - Return the hexadecimal representation of an integer. -- oct(number) - Return the octal representation of an integer. -- ord(c) -> int - Return the Unicode code point for a one-character string. -- sorted(iterable) - Return a new list containing all items from the iterable in ascending order. A custom key function can be supplied to customize the sort order, and the reverse flag can be set to request the result in descending order. -- range(start, end, step=1) - Return the range of a value with start, end and step parameter. -- min(iterable) - With a single iterable argument, return its smallest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the smallest argument. -- max(iterable) - With a single iterable argument, return its biggest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the largest argument. -- sum(iterable, start) - Return the sum of a 'start' value (default: 0) plus an iterable of numbers. When the iterable is empty, return the start value. This function is intended specifically for use with numeric values and may reject non-numeric types. -- pow(x, y, z) - Equivalent to `x**y` (with two arguments) or `x**y % z` (with three arguments). Some types, such as ints, are able to use a more efficient algorithm when invoked using the three argument form. -- round(number, ndigits) - Round a number to a given precision in decimal digits. The return value is an integer if ndigits is omitted or None. Otherwise the return value has the same type as the number. ndigits may be negative. -- typeof(x: any, \*, full_name: bool = False) -> str - Return the type of the value 'x' at runtime. When the 'full_name' is 'True', return the full package type name such as `pkg.schema`. - -### Plugin Modules - -KCL compiler needs to provide the ability to dynamically expand and load plugin modules without modifying the compiler itself. KCL compiler needs to support flexible pluggable module extension mechanism, so that KCL users can use more abundant built-in function capabilities to simplify writing. - -KCL compiler needs to ensure the stability and safety of the expansion mechanism, without affecting the core of the compiler. - -Searching extended plugin module is performed after the standard system module. The standard system module has a higher priority in naming. If it exists a standard or built-in system module with the same name, the extended plugin module will be ignored. - -Importing and using the extended plugin module should be consistent with the standard or built-in system module. - -### Replacing Standard System Packages - -Replacing standard system modules is not allowed. - -## Examples - -We show more module features through an example. - -Suppose we have the following directories and files: - -``` - . - ├── mod1.k - ├── mod2.k - ├── pkg1 - │   ├── def1.k - │   ├── def2.k - │   └── def3init.k - └── pkg2 - ├── file2.k - └── subpkg3 - └── file3.k -``` - -From the structure we can see that `pkg1` and `pkg2` are two packages, `subpkg3` is a subpackage of `pkg2`, and `mod1.k` and `mod2.k` are regular modules. - -### Importing a Standard System Package - -The following statement can import the standard system module `math` - -```python -import math -``` - -This is the only way to import a standard system module. After importing a standard system module, functions, variables and schemas defined in it can be used. For example, the following statement uses the `log10` function -defined in `math` - -```python -a = math.log10(100) # a is 2 after computation. -``` - -### Importing a Regular Module - -In `mod1.k`, we can import `mod2` using one of the following syntaxes. - -```python -import mod2 -``` - -```python -import .mod2 -``` - -The difference is that in the first syntax, the KCL compiler will first try to check if `mod2` matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where `mod1.k` resists in, like what the second statement does. - -Suppose in `mod2.k` there is a definition of a variable:: - -```python -a = 100 -``` - -After importing `mod2`, we can access `a` in `mod1.k` using the following syntax - -```python -b = mod2.a -``` - -### Importing a Package - -In `mod1.k`, we can import `pkg1` using one of the following syntaxes. - -```python -import pkg1 -``` - -```python -import .pkg1 -``` - -The difference is that in the first syntax, the KCL compiler will first try to check if `pkg1` matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where `mod1.k` resists in, like what the second statement does. - -We can use similar statements to import `pkg2`. Note that importing `pkg2` will not import `subpkg3`. - -The name of the package is the name of the imported module. - -Suppose in `file2.k` that is inside `pkg2` there is a definition to variable `foo` - -```python -foo = 100 -``` - -This variable can be used in `mod1.k` after importing `pkg2` like the following - -```python -bar = pkg2.foo -``` - -### Importing a Subpackage - -To import `subpkg3` from `mod1.k`, one of the following statements can be used. - -```python -import pkg2.subpkg3 -``` - -```python -import .pkg2.subpkg3 -``` - -The behaviors of these statements are identical. - -The name of the subpackage is the name of the imported module. - -Suppose in `file3.k` that is inside `subpkg3` there is a definition to variable `foo` - -```python -foo = 100 -``` - -This variable can be used in `mod1.k` after importing `subpkg3` like the following - -```python -bar = subpkg3.foo -``` - -### Relative Importing - -Relative importing is useful when there is code trying to import modules that does not exist recursively inside the current directory. - -For example, the following statements, if written in `file3.k`, can be used to import `pkg2`, `pkg1` and `mod2` respectively. - -```python -import ...pkg2 # Go two levels up then import pkg2 -import ...pkg1 # Go two levels up then import pkg1 -import ...mod2 # Go two levels up then import mod2 -``` - -### Importing from a Root Path - -Suppose we have a `kcl.mod` file in the directory to mark it as a root path, then we have the following files: - -``` - . - |── kcl.mod - ├── mod1.k - ├── mod2.k - ├── pkg1 - │   ├── def1.k - │   ├── def2.k - │   └── def3init.k - └── pkg2 - ├── file2.k - └── subpkg3 - └── file3.k -``` - -In `pkg1` `def1.k`, we can import `pkg2.subpkg3` `file3` using the following syntaxes. - -```python -import pkg2.subpkg3.file3 -``` - -Importing from the root path is very convenient when the code is trying to import modules from a directory needs to look up multiple directories above this directory. At also, it is helpful to organize a large number of files in a root directory. - -### Importing a Module Inside a Package - -Note that `subpkg3` is only implemented with one file `file3.k`. The file can be regarded as a regular module and imported directly. - -In `mod1.k`, the importing statement would be:: - -```python -import pkg2.subpkg3.file3 -``` - -Different from importing `subpkg3`, now the name of the module is `file3`. We can access the variable `foo` defined in this module with the following -statement - -```python -bar = file3.foo -``` - -### Precedence of Importing - -When an import statement specifies a package to import, the virtual machine first looks for a directory named according to the import statement in the file system. - -If such a directory is not found, the virtual machine looks for a single file module. - -For example, when the statement `import a.b.c` appears, the virtual machine first looks for the directory `a/b/c` from the directory of the current file. If `a/b/c` is not found, the virtual machine looks for a file named `a/b/c.k`. If the file is also absent, an error is reported. - -### Package Implemented with Multiple Files - -Package `pkg1` is implemented with multiple KCL files. - -Multiple files can be used to define variables, schemas and functions, and they can access names defined in other files of this package. - -For example, suppose `def1.k` defines a variable `foo`, `def2.k` defines `bar`, and `def3init.k` defines a variable `baz`, when `pkg1` is imported by `mod1.k`, all these variable can be used - -```python -import pkg1 -a = pkg1.foo + pkg1.bar + pkg1.baz -``` - -Inside a module, names defined in a file can be accessed in another file without further importing. For example, suppose `bar` in `def2.k` would invoke `foo` defined in `def1.k`, it can directly use `foo` like the following - -```python -bar = foo + 1 -``` diff --git a/versioned_docs/version-0.5.2/reference/lang/spec/schema.md b/versioned_docs/version-0.5.2/reference/lang/spec/schema.md deleted file mode 100644 index c3d09f65..00000000 --- a/versioned_docs/version-0.5.2/reference/lang/spec/schema.md +++ /dev/null @@ -1,916 +0,0 @@ ---- -title: "Schema" -linkTitle: "Schema" -type: "docs" -weight: 2 -description: Schema ---- - -## Syntax - -### Schema Definition - -A schema is a language element to define a type of configuration data. - -To define a schema, the syntax is the following: - -```bnf -schema_stmt: [decorators] "schema" ["relaxed"] identifier ["[" [arguments] "]"] ["(" operand_name ")"] ":" NEWLINE [schema_body] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt | schema_index_signature | statement)* [check_block] _DEDENT -``` - -Attributes could be defined in a schema, the syntax is the following: - -```bnf -schema_attribute_stmt: [decorators] identifier ["?"] ":" type [(ASSIGN | augassign) test] NEWLINE -``` - -Index signature could be defined in a schema, the syntax is the following: - -```bnf -schema_index_signature: LEFT_BRACKETS [NAME COLON] [ELLIPSIS] basic_type RIGHT_BRACKETS COLON type [ASSIGN test] NEWLINE -``` - -Once defined, an attribute must have a valid type: - -```bnf -type: type_element ("|" type_element)* -type_element: schema_type | basic_type | list_type | dict_type -schema_type: operand_name -basic_type: "str" | "int" | "float" | "bool" -list_type: "[" (type)? "]" -dict_type: "{" (type)? COLON (type)? "}" -``` - -The followings are some basic examples: - -```python -# A person has a first name, a last name and an age. -schema person: - firstName: str - lastName: str - # fullName is generated by firstName and lastName - fullName: str = firstName + ' ' + lastName - # The default value of age is 0 - age: int = 0 - -# An employee IS a person, and has some additional information. -schema employee(person): - bankCard: int - nationality: str - -# A company has a name and many employees. -schema company: - name: str - employees: [employee] -``` - -More complex schema definitions will be elaborated after other concepts are -introduced. - -#### Optional Attribute - -Each attribute **must** be assigned with a not-None value as a schema instance unless it is modified by a question mark as an optional attribute. - -Examples: - -```bnf -schema employee(person): - bankCard?: int # bankCard is an optional attribute - nationality?: str # # nationality is an optional attribute -``` - -When there is an inheritance relationship: - -- If the attribute is optional in the base schema, it could be optional or required in the sub-schema. -- If the attribute is required in the base schema, it must be required in the sub-schema. - -### Configuration Definition - -A configuration is structured data stored in a dict-like structure. In KCL, we have introduced -the configuration definition syntax as a variant of dict definition syntax. - -```bnf -schema_expr: operand_name ("(" [arguments] ")")? dict_expr -``` - -As can be seen, apart from having an identifier as schema type, a configuration definition -is just an ordinary dict definition, and each key in the dict matches an attribute in the schema. - -To simplify configuration, schema attribute key is much easier to define as: - -- schema attribute key can be unquoted. When the attribute key has the same name as a variable, it must be quoted as a normal dict to avoid naming conflict. -- schema attribute key can be defined nested through `select expression`, such as `a.b.c`. - -The comma at the end of each line can be omitted. - -For example, we can define a `person` named `John Doe` using the following statement: - -```python -johnDoe = person { - # In the result, 'lastName' appears later than 'firstName', according the schema - lastName = 'Doe' - firstName = 'John' - # If we don't specify the 'age', the default value 0 is used. - # 'age': 20 -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' - 'age': 0 -} -``` - -Compared to the ordinary dict definition, a configuration definition has the following features: - -- Each attribute defined in the schema (or one of the schemas) could be configured, and config data has higher priority than the default value. -- When an attribute defined in the schema (or one of the schemas) is not configured in the configuration definition statement, and it has a default value, the default value is used. -- Unless the schema (or one of the schemas) is a **relaxed schema**, no more attributes can be defined. -- The quotation marks of dict key can be omitted. -- The comma at the end of each line can be omitted. -- Cases of **inheritance** will be discussed separately. - -For attributes of list, dict and schema types, the config data is added by **union** instead of reassignment. For instance: - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name = { - firstNam = "John" - lastName = "default" - } - -JohnDoe = Person { - name.lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' -} -``` - -#### Attribute Identify - -Each key identifier in the configuration expr identifies an element or a range of elements in a schema. The key identifier may consist of multiple attribute identifiers, and each attribute may be a basic type value, a list, a dict or schema. For example, the key identifier 'a.b.c' identifies the element 'c' in the 'A' schema: - -```python - -schema C: - c: int - -schema B: - b: C - -schema A: - a: B - -A { - a.b.c: 5 -} -``` - -To make the key identifier usage rules as clear as possible, we define the way of identifying with complex data types as follows. - -##### List - -Suppose we have a list attribute a. - -Identify an element in a: - -```python -a[0] # the first element -a[3] # the 4th element -a[-1] # the last element -a[-2] # the penultimate element -``` - -Identify a range of elements in the list: - -```python -a[2:5] # a slice of the third, 4th, and 5th elements -a[:5] # a slice of the first to 5th elements -``` - -#### Attribute Operator - -Once we identified the element(s), we can declare operation on it. It follows the pattern of `identifier op E`. - -#### Union - -Pattern: `identifier : E` - -The value of the expression `E` will be unioned into the element value. - -Examples: - -```python -a = A { - # union {d:4} into the element b.c, suppose c is a schema with an int type attribute d. - b.c : { - d : 4 - } -} -``` - -See 'union' in `expressions` spec for more details. - -#### Override - -Pattern: `identifier = E` - -The value of the expression `E` will override the element value. - -Examples: - -```python -a = A { - # override {c:4} to the element b, suppose b is a schema with an int type attribute c. - b = { - c: 4 - } -} -``` - -Unlike union, the override operation will reassign the element with a brand new value. -For basic type value, `union` and `override` have equivalent effects. - -Note: - -- Especially, we can "delete" its content by overriding the element to `Undefined`, such as `{ a = Undefined }`. - -#### Insert - -Pattern: `identifier += E` -Insert only works for list type `identifier`. - -List `E` will be inserted just after the specified index of the list `identifier`, and the following elements after the index will be automatically shifted. - -Examples: - -```python -a = A { - # insert {c:4} to the end position(just after index=1), suppose b is a list of schema with an int type attribute c. - b += { - c: 4 - } -} -``` - -If no index is specified, the last index will be used. - -The type of 'E' must be compatible with the type of list. See `types` for more details. - -#### Index Signature - -Index signatures can be defined in the KCL schema, and it means that the key-value constraints of the index signature can be used to construct a dict with the schema type, or additional checks can be added to the relaxed schema attributes to enhance the KCL type and semantic checks. - -- Use the form `[{attr_alias}: {key_type}]: {value_type}` to define an index signature in the schema, and `{attr_alias}` can be omitted. - -```python -schema Map: - """ - Map is a relaxed schema with a key of str type and a value of str type - """ - [str]: str # `{attr_alias}` can be omitted. - -data = Map { - key1 = "value1" - key2 = "value2" -} -``` - -- Mandatory all attributes of the schema key and value types - -```python -schema Person: - name: str - age: int # error, conflicts with the index signature definition `[str]: str` - [str]: str # The values of all attributes of the schema can only be strings -``` - -- Mandatory all attribute key and value types are defined in the schema, which is equivalent to restricting all attribute types except the relaxed attributes. - -```python -schema Person: - name: str - age: int - [...str]: str # Except for the `name` and `age` attributes, the key type of all other attributes of the schema must be `str`, and the value type must also be `str`. -``` - -- Define the index signature attribute alias and use it with the check block. - -```python -schema Data: - [dataName: str]: str - check: - dataName in ["Alice", "Bob", "John"] - -data = Data { - Alice = "10" - Bob = "12" - Jonn = "8" # error Jonn not in ["Alice", "Bob", "John"] -} -``` - -```python -import regex - -schema DataMap: - [attr: str]: str - check: - regex.match(attr, r'^[-._a-zA-Z0-9]+$') - -data = DataMap { - key1 = "value1" - "foo.bar" = "value2" # check error -} -``` - -### Schema Context - -The schema definition space can be regarded as a separate function context. - -Init statement could be defined inside the schema, the syntax is the following: - -```bnf -statement: small_stmt NEWLINE | if_stmt -``` - -The following is an example: - -```python -schema Person: - firstName: str = "John" - lastName: str - # fullName is generated by firstName and lastName in a separate init statement - fullName: str = firstName + ' ' + lastName - -JohnDoe = Person { - lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' -} -``` - -If statement, expr statement and assert statement are supported as a schema init -statement. See more in statement spec. - -- The attributes must be defined first, including inherited ones, and then used in the init statement. -- Statements in the schema context will be executed sequentially. -- The value of attributes referenced in the init statement will be evaluated at runtime. - See the **Configuration Definition** section for the assignment rules of non-referenced attributes. For example, `"fullName"` in Person is generated by `"firstName"` and `"lastName"` evaluated at runtime, in which firstName is 'John', and lastName is "Doe". - -The immutability of attributes in the schema context follows the same rules as the immutability of global variables: - -```python -schema Person: - age: int = 1 # Immutable attribute - _name: str = "Alice" # Mutable attribute - - age = 10 # Error - _name = "Bob" # Ok -``` - -#### Arguments - -Schema context can also have arguments. The following is an example. - -```python -schema Person[separator]: - firstName: str = "John" - lastName: str - fullName: str = firstName + separator + lastName - -JohnDoe = Person('_') { - lastName = "Doe" -} -``` - -The example is similar to the previous one, except that the separator character used in -the `"fullName"` member is passed in as an argument. The way to perform a schema generation -when the schema has an initialization function with arguments is demonstrated in the code. - -### Check Block - -Optionally, a check block can be added to a schema definition to allow -additional checking to be performed. - -The syntax is the following: - -```bnf -check_block: "check" ":" NEWLINE _INDENT check_expr+ _DEDENT -check_expr: test (IF test)? [":" primary_expr] NEWLINE -``` - -In terms of grammatical definition, a check block consists of a list of conditional expressions. The following is an example: - -```python -schema employee(person): - bankCard: int - gender: str - - check: - len(str(bankCard)) == 16 - gender in ['male', 'female'], "The gender {} is unsupported".format(gender) -``` - -The ability of KCL check expressions covers the abilities that can be defined by OpenAPI spec and is aligned with the ability of logical expressions. We consider further aligning the syntax with `CEL` spec. -Whether to support `lambda expressions` is still under discussion. - -Summary: - -- A check block consists of one or more logical **expressions**. -- When defining a configuration, the expressions in the check block are evaluated - in any order. If any of the expression is `False`, an error is reported. -- A custom error message can be provided after an expression. - -### Specifying Types - -Optionally, the type of any member of a schema can be specified. As previous examples have shown. - -A member can be of a basic type, such as a string (`str`), a floating-point number (`float`), a fixed-point number (`int`) or a boolean number (`bool`). - -A member can also be of a dictionary generated from another schema. In such a case, the name of the other schema is used as the type name. - -A member can also be a list or an ordinary dict: - -- A list with unspecified type of elements is `[]`. -- A list with elements of type `t` is `[t]`. Here `t` is another type. -- A dict with keys of type `kt` and values of type `vt` is `{kt:vt}`. -- `kt`, `vt` or both of them can be missing, like a list with unspecified type of elements. - -The followings are some more examples: - -- A list of lists of strings: `[[str]]`. -- A dict of keys with the type string and unspecified value types: `{str:}`. - -A member can be a **union type** defined by `|`, such as `a | b`, which means the type of the member could be a or b. - -A union type can include types of `int`, `str`, `float`, `bool`, `list` and `dict` and support type nesting e.g. `{str:str|int}` and `[[int|str]|str|float]`, etc. - -Examples: - -```python -schema x: - p: int | str # p could be defined as a int or string -``` - -### Immutability - -KCL pursues strict immutability of schema attributes. It's generally followed the rules: - -- For the attributes of the basic type, such as string, int and float, it's allowed to be reassigned - through the init statement in **schema context** or by the **configuration definition**. -- For the attributes of list, dict and schema type, it's allowed to be reassigned only by the init statement in **schema context**. The content of it is allowed to be operated in **schema context** or by the **configuration definition**. -- Any other attempt to reassign or modify schema attribute will report an error. - -#### Assign by Value - -When using a schema variable to assign the value to another variable, we can only get a deep copy of its value, not a pointer or reference. That is, modifying the assigned value will not change the assigned schema variable. - -```python -schema Person: - name: str - -person = { - name = "Alice" -} -personCopy = person # 'personCopy' is a deep copy of 'person' and modifying 'personCopy' will not affect 'person' -``` - -### Union Operator - -For list, dict and schema, we can union delta to existing data. For example: - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name = { - firstName = "John" - } - - # union a schema and a dict - name: Name { - lastName = "Doe" - } - -person = Person {} -``` - -The result is a **dict**: - -```python -{ - 'person': { - 'name': { - 'firstName': 'Jhon', - 'lastName': 'Doe' - } - } -} -``` - -### Other Operators - -Except for `assignment` and `union assignment`, it's not support other operators on schema type data. -Report an error if trying to use other operators on schema type data. - -### Deprecated - -The schema attribute can be marked as deprecated once it's considered invalid. - -```python -schema Person: - @deprecated(version="1.1.0", reason="use fullName instead", strict=True) - name: str - ... # Omitted contents - -person = Person { - # report an error on configing a deprecated attribute - name = "name" -} -``` - -- Deprecated attributes cannot be configured under any circumstances. Report an error or warning once the attribute is assigned. -- Define the expired version of the attribute through **version**, and define the reason for the attribute expired through **reason**. -- When strict is true, the attribute assignment will cause an error, otherwise it will report a warning and ignore the attribute assignment. - -### Composition - -The composition is a common way to define complex structures. KCL provides simplified means for the configuration definition of combined structures. - -Assuming we have the following schemas, which is defined by a combination of multiple schemas. - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name - age: int - -schema Group: - name: str - persons: [Person] -``` - -To config a group: - -```python -group = Group { - name = "group" - persons = [{ - name = { - firstName = "John" - lastName = "Doe" - } - age = 24 - }] -} -``` - -- Top-level schema name is required to config a schema. -- The schema of the attributes in the schema can be omitted. - -Multi-level nested schemas will make the configuration verbose. KCL supports defining attributes in the schema through `selector expression`. The selector form is **x.y.z**, see the following example: - -```python -group = Group { - name = "group" - persons = [{ - name.firstName = "John" - name.lastName = "Doe" - age = 24 - }] -} -``` - -- Selector can be used to represent attribute in a schema - -### Inheritance - -Inheritance is an effective means to define a hierarchical structure definition, and KCL supports limited **single inheritance** of the schema. - -```python -schema Person: - firstName: str - lastName: str - -# schema Scholar inherits schema Person -schema Scholar(Person): - fullName: str = firstName + '_' + lastName - subject: str - -JohnDoe = Scholar { - firstName = "John", - lastName = "Doe", - subject = "CS" -} -``` - -The result is a **dict**: - -```python -{ - 'JohnDoe': { - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' - 'subject': 'CS' - } -} -``` - -Each schema can be treated as a separated function context. Statements, including attribute statements and init statements, in the context of schemas will be evaluated from base schema to subschema according to the inheritance order. Each schema context is evaluated only once sequentially. The same goes for expressions in the check block. In the example, firstName and lastName are configured in the context of Person schema, and fullName is formed by splicing firstName and lastName in the context of Scholar schema. - -The default value can be modified in each schema. Value defined in **Configuration Definition** has a higher priority than the default value. Attributes with default values in any schema context ​​will eventually be unioned by configuration data. References to attributes in the schema context statements will use the value with unioned configuration data on evaluating at runtime. For example: - -```python -schema a: - x = 1 - y = x * 2 - -schema b(a): - x = 2 - -v = a { - x = 3 -} - -``` - -The result is a **dict**: - -```python -{ - 'v': { - 'x': 3 - 'y': 6 - } -} -``` - -Notes: - -- Report an error if inheriting more than one base schema. -- The type of the base schema attribute cannot be modified in the subschema. -- Report an error if inheriting a **mixin**. -- Report an error when a circular dependency occurs. - -Limitations: - -Since inheritance will derive some complex demands, we are cautious about these complex demands. There are still some restrictions on inheritance, and it's still under discussion. - -- KCL provides limited and deterministic polymorphism support, more complex and flexible polymorphism support, such as **self**, **super** keywords, are temporarily not included in the schema definition. -- Currently, KCL only supports the polymorphism of the inherited attributes of the schema, and does not support the polymorphism of the expressions in the check block. -- For the case of multiple levels of schema inheritance, the schema arguments can only be passed to the last level of sub-schema. - -### Mixin - -In addition to **composition** and **inheritance**, KCL supports declarative reuse of schema code through the **mixin** mechanism. To use a mixin, we only need to declare the **mixin** in the schema definition. - -The **mixin** syntax is the following: - -```bnf -//////////// mixin_stmt //////////// -mixin_stmt: "mixin" "[" [mixins | multiline_mixins] "]" "\n" -multiline_mixins: "\n" _INDENT mixins "\n" _DEDENT -mixins: operand_name ("," ("\n" mixins | operand_name))* -``` - -Here is a simple example: - -```python -schema Person: - mixin [FullNameMixin] - firstName: str = "default" - lastName: str - -schema FullNameMixin: - fullName: str = "{} {}".format(firstName, lastName) - -JohnDoe = Person { - firstName = "John" - lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'JohnDoe': { - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' - } -} -``` - -Multiple mixins can be added to a single schema, and mixins context will be evaluated after the host schema context at runtime. In the inheritance scenario, the mixin context can be regarded as a part of the host schema context, and the overall evaluation of schema context order is not affected. - -Notes: - -- The name of **mixin** schema must end with 'Mixin', otherwise an error will be reported. -- The attributes referenced in the **mixin** must be defined in the **mixin** itself or host schema, otherwise an error will be reported. - -### Protocol - -In addition to schema, an additional type definition method `protocol` is provided in KCL, and its properties are as follows: - -- In a protocol, only attributes and their types can be defined, complex logic and check expressions cannot be written, and mixins cannot be used. -- A protocol can only inherit or refer to other protocols, but cannot inherit or refer to other schemas. - -We can use **protocol** to add an optional host type to the dynamically inserted **mixin**. - -The **mixin** can define its host type through the `for` keyword, and internally it will query the type corresponding to the attribute from the host type. - -```python -protocol DataProtocol: # A mixin host type - data: str - -mixin DataMixin for DataProtocol: # Using the `for` keyword to define a mixin host type - x: int = data # The type of `data` is `str`, which is from `data` of `DataProtocol` -``` - -In `DataMixin`, the `data` attribute is obtained according to the `DataProtocol` host type as `str` type, and then a type error will occur when the value is assigned to `x` of type `int`: - -```python -protocol DataProtocol: - data: str - -mixin DataMixin for DataProtocol: - x: int = data # Error: expect int, got str - x: str = data # Error: can't change schema field type of 'x' from int to str -``` - -Please note that the host type **protocol** can only be used for **mixin** definitions (the suffix name is `Mixin`), otherwise an error will be reported. - -```python -protocol DataProtocol: - data: str - -schema Data for DataProtocol: # Error: only schema mixin can inherit from protocol - x: str = data -``` - -### Schema Context Evaluation - -The schema definition is composed of attribute statements, configuration data, init statements, mixins, and checks. In a separate schema context, the evaluation top-down order is as follows: - -``` -|------------------------------------------| -| attribute defaulting | -|------------------------------------------| -| configuration union | -|------------------------------------------| -| attribute templating | -|------------------------------------------| -| statements in declaration order | -|------------------------------------------| -| mixins in declaration order | -|------------------------------------------| -| check expressions in any order | -|------------------------------------------| -``` - -In the case of schema inheritance, each schema context is evaluated from the base schema in the order of inheritance, and each context is evaluated only once. -Suppose there are schemas a, b, and c, where c inherits b and b inherits a. Schema contexts will be evaluated in top-down order as: - -``` -|-----------------| -| schema a | -|-----------------| -| schema b | -|-----------------| -| schema c | -|-----------------| -``` - -### Members - -Built-in function and members of schema - -- instances() - Return the list of existing instances of a schema. - -### Irrelevant Order Calculation - -The irrelevant order calculation in the schema indicates the reference relationship between the internal attributes of the schema. For example, when we declare an expression of the form `a = b + 1`, the calculation of the value of `a` depends on the calculation of the value of `b`. When the compiler calculate the value of `a` and the value of `a` depends on the value of `b`, the compiler will choose to first calculate the value of `b`, and then calculate the value of a according to the expression `a = b + 1`, which is slightly different from the calculation method of traditional procedural language the difference. - -Since the calculation of values in the schema is based on dependencies, just like a directed acyclic graph traverses each node in the graph according to the order of topological sorting, the order of declaration of attributes in the schema is not so important, so the feature is called the irrelevant order calculation. - -Please note that there can be no circular references between different schema attribute values. - -We can see this feature through the following examples. - -```python -schema Person: - name?: str - age: int = _age - - _age = 10 - - if name == "Son": - _age = 18 - -schema Son(Person): - name: str = "Son" - -person = Person {} -son = Son {} -``` - -The output is - -```yaml -person: - name: null - age: 10 -son: - name: Son - age: 18 -``` - -Besides, we can achieve KCL polymorphism such as - -```python -schema Person: - name?: str - _age: int = _age - - _age = 10 - if name == "Son": - _age = 18 - elif name == "SonConf": - _age = 24 - -schema Son(Person): - name: str = "Son" - -person = Person() {} -son = Son() { - name = "SonConf" -} -``` - -The output is - -```yaml -person: - name: null - age: 10 -son: - name: SonConf - age: 24 -``` - -More examples: - -```python -schema Fib: - n1: int = n - 1 - n2: int = n1 - 1 - n: int - value: int = _value - - if n <= 2: - _value = 1 - else: - _value = (Fib {n = n1}).value + (Fib {n = n2}).value - -fib8 = (Fib {n = 8}).value -``` - -The output is - -```yaml -fib8: 21 -``` - -As in the above examples, we can see that in the schema, we only need to simply specify the dependency between attributes, and the compiler will automatically calculate the value based on the dependency, which can help us save a lot of boilerplate code and reduce configuration difficulty of writing. diff --git a/versioned_docs/version-0.5.2/reference/lang/spec/statements.md b/versioned_docs/version-0.5.2/reference/lang/spec/statements.md deleted file mode 100644 index b09488b9..00000000 --- a/versioned_docs/version-0.5.2/reference/lang/spec/statements.md +++ /dev/null @@ -1,185 +0,0 @@ ---- -title: "Statements" -linkTitle: "Statements" -type: "docs" -weight: 2 -description: Statements ---- - -## Syntax - -In KCL, statements consist of small statements and compound statements. The syntax is the following: - -```bnf -preamble_statement: preamble_small_stmt | preamble_compound_stmt -preamble_small_stmt: (small_stmt | import_stmt) NEWLINE -preamble_compound_stmt: compound_stmt | schema_stmt -statement: small_stmt NEWLINE | compound_stmt -compound_stmt: if_stmt -small_stmt: assign_stmt | expr_stmt | assert_stmt -``` - -The preamble statement is used to define the module level statements, consist of `statement`, `import_stmt`, and `schema_stmt`. The statement is used to define the block level statements, which are used in the `if` statement and `schema` statement. - -### Small Statements - -A small statement is comprised of a single logical line. Multiple statements in one-line are not allowed. - -#### Assignment Statements - -Generally, assign_stmt is divided into assignment and augmented assignment. The syntax is the following: - -```bnf -assign_stmt: target_primary ("=" target_primary)* "=" test | target_primary augassign test -augassign: "+=" | "-=" | "*=" | "**=" | "/=" | "//=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>=" | "or" | "and" -target_primary: identifier | target_primary DOT identifier -``` - -An assignment statement has the form `lhs = rhs`. It evaluates the expression on the right-hand side then assigns its value (or values) to the variable (or variables) on the left-hand side. - -The **target_primary** on the left-hand side is an `identifier` or an `identifier` followed by select dots. - -Note: When using **target_primary** will cause collisions, use **primary_expr** as an alternative. - -Examples: - -```python -k = 1 -a.b = "a.b" -``` - -To keep it simple, the compound target is not supported as **target_primary**. - -The right value of an assignment statement is a conditional expression, which is discussed separately. - -An augmented assignment, which has the form `lhs op= rhs` updates the variable `lhs` by applying a binary arithmetic operator op (one of +, -, \*, /, //, %, &, |, ^, <<, >>) to the previous value of `lhs` and the value of `rhs`. - -The **target_primary** on the left-hand side is the same as assignment statement. Examples: - -```python -_x -= 1 -_filename += ".k" -``` - -There is no concept of in-place modification in KCL. The `augassign` statement will modify a copy of the **target_primary** and assign the copy to **target_primary**. - -In particular, in KCL, the `|=` symbol represents the **union** operation, which is defined as follows: - -- The behavior of the **union** operation needs to be consistent with the behavior of the **configuration definition**. - -See **expressions** spec for more details of union operator in **Arithmetic Operations**. - -#### Expression Statements - -An expression statement evaluates an expression and discards its result. - -Syntax: - -```bnf -expr_stmt: expression -``` - -An expression statement supported in KCL is function invocation expression, which is discussed in **expression** spec. - -```python -print(k) # print a variable -``` - -#### Import Statements - -Import statements are used to **search** and **load** a module, and define a name or names in the local namespace for the scope where the import statement occurs. - -Syntax: - -```bnf -import_stmt: "import" dot_name ("as" NAME)? -dot_name: [leading_dots] identifier (DOT identifier)* -leading_dots: "."+ -``` - -Examples: - -```python -import math # import a built-in module math -import pkg # import pkg -import pkg.foo # import pkg.foo -import pkg.subpkg # import a subpkg in a pkg -import .pkg2.subpkg3 # import a subpkg in a pkg inside of current pkg -import ...pkg2 # Go two levels up then import pkg2 -``` - -See **module** spec for more details of module spec. - -#### Assert Statements - -Assert statements are a convenient way to insert debugging assertions into KCL code. - -The syntax is the following: - -``` -assert_stmt: ASSERT test ("," test)? -``` - -The conditional expression in assert will be evaluated and get a boolean. Report an error if returning a `False`. - -Examples: - -```python -assert: x > 1 # report an error on x <= 1 -``` - -#### Conditional Statements - -KCL allows using conditional statements to control the instructions to -be executed. They are also called the control-flow statements. - -The only type of control-flow syntax is the well-known `if-elif-else` syntax. - -The syntax of the `if-elif-else` statement is the following. - -```bnf -if_stmt: "if" test ":" suite ("elif" test ":" suite)* (ELSE ":" suite)? -suite: small_stmt | NEWLINE _INDENT statement+ _DEDENT -``` - -An `if` or `elif` statement evaluates a given expression. When the expression -is evaluated to `True`, a list of statements following `:` are executed. - -The following is an example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - print("maybe a is negative") -else: - print("a >= 100") -``` - -`if-elif-else` statements can be nested. For example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - if a < 0: - print("a is negative") - print("No matter a is negative or positive, this message is printed") -else: - print("a >= 100") -``` - -#### Schema Statements - -Schema statements are used to define a type of configuration data. The syntax is the following: - -```bnf -schema_stmt: [decorators] "schema" ["relaxed"] identifier ["[" [arguments] "]"] ["(" operand_name ")"] ":" NEWLINE [schema_body] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt | statement)* [check_block] _DEDENT -``` - -See **schema** spec for more details of schema spec. diff --git a/versioned_docs/version-0.5.2/reference/lang/spec/variables.md b/versioned_docs/version-0.5.2/reference/lang/spec/variables.md deleted file mode 100644 index b3e1c539..00000000 --- a/versioned_docs/version-0.5.2/reference/lang/spec/variables.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: "Variables" -linkTitle: "Variable" -type: "docs" -weight: 2 -description: Variable ---- - -In KCL, variables can be defined using assign statements. For example, the following statement defines a variable `spam` to a string `"ham"`. - -```python -spam = "ham" -``` - -There are two types of variables, which are global variables and list comprehension local variables. - -- A global variable is defined not within any context. -- A comprehension local variable is defined inside a comprehension. - -A variable can be used after definition, until the end of the current scope. - -For a global variable, the scope is the module it is defined in. Note that a module can consists of multiple source files. - -For a list comprehension local variable, the scope is the list comprehension it is defined in. - -More information on modules, list comprehensions and scopes will be discussed in later chapters. - -## Immutability - -Global variables are immutable. In other words, once defined such a variable cannot be redefined (or, i.e., modified). - -The following code is illegal, and KCL will report an error during evaluation. - -```python -spam = "ham" -spam = "eggs" # Error: The immutability rule is violated! -``` - -- A variable starts with the `_` character is mutable. - -```python -_spam -cond = True -if cond: - _spam = "ham" -else: - _spam = "eggs" -``` - -## Variable Exporting - -As shown in the preview chapter, KCL is able to export evaluation results to the standard output according to a target data format. - -The rules are the followings: - -- Living global variables at the end of an evaluation will be dumped out. -- If the name of a variable starts with the `_` character, it will not be dumped out. - -## Uniqueness of Exported Variable Identifier - -Each exported variable identifier must be unique in its package, so that an exported variable could be located uniquely by package location path and variable identifier, such as 'a.b.c:var', in which 'a.b.c' locates a package. - -Two variable identifiers are different if: - -- they are spelled differently -- they are defined in different packages and are not compiled in a single execution - -Identifying an exported variable should be supported by the kcl compiler, which needs to provide corresponding identifying features through the command line and api form. diff --git a/versioned_docs/version-0.5.2/reference/lang/tour.md b/versioned_docs/version-0.5.2/reference/lang/tour.md deleted file mode 100644 index f7acf49c..00000000 --- a/versioned_docs/version-0.5.2/reference/lang/tour.md +++ /dev/null @@ -1,3324 +0,0 @@ ---- -title: "KCL Tour" -sidebar_position: 1 ---- - -This page shows how to use major KCL features, from variables and operators to schemas and libraries, with the assumption that you have already known how to program in another language. KCL is mainly inspired by Python, and knowing Python is very helpful for learning KCL. - -### Important Concepts - -As we learn about the KCL language, keep these facts and concepts in mind: - -- KCL is a configuration and policy language. It provides simplified and self-contained language design and library support for writing configurations and policies. It cannot be used for application development or other purposes supported by General Purpose Language (GPL). -- KCL absorbs classic **OOP** elements and provides simple, developer-friendly and reliable configuration writing practice with **type**, **reusing**, and **union**. -- KCL prefers **immutability** and recommend to add up incremental updates through the **union**. Immutability reduces side effects like unpredictable issues. -- KCL **schema** struct defines strict attributes, static types, and it also supports validation expressions. The **schema** struct is mainly composed of typed attributes, the schema context and the check block. -- KCL **config** is a **json**-like expression, by which we can reuse a full definition of the schema. KCL provides support for definition and configuration by separating schema and config. -- KCL **rule** is a structure for writing rule constraint expressions, which can be used for data verification and policy writing. -- KCL code files are managed as packages(directories) and modules(files). The schema types in the same package are visible to each other; the data cross packages need to be imported through the **import statement**. The package-level variables can be exported, but they are immutable for other packages. -- The KCL syntax definition mainly uses declarative expressions, and only provides a small number of necessary and imperative statements, such as import, if .. else, assert, assignment and schema. -- No main function, each `.k` file could be executed as a separate configuration. -- **Built-in functions** and **plugins** are supported to simplify coding. - -### Keywords - -The following table lists the words that the KCL language treats specially. - -```txt -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -### Identifiers - -In KCL, an identifier is a name, may with selectors, that identifies a value. - -- Identifiers consist of letters, numbers, underscores or the prefix `$`. -- Identifiers cannot be repeated with keywords unless they have a `$` prefix. -- Identifiers must not contain any embedded spaces or symbols. -- Letters and underscores can be used anywhere in the identifier. -- Numbers cannot be placed in the first place of the identifier. -- The `$` character can only be placed in the first position of the identifier. - -Examples: - -```python -x -a -b1 -b_2 -_c -$if -``` - -To simplify the definition of the qualified identifier, such as `pkg.type`, we additionally define `qualified identifier`: - -Examples: - -```python -pkg.a -``` - -The package name in `qualified identifier` must be imported. - -#### Identifier Prefix - -Use the `$` character prefix to define keyword identifiers. - -```python -$if = 1 -$else = "s" -``` - -Please note: whether the non-keyword identifier is prefixed with `$` has the same effect. - -```python -_a = 1 -$_a = 2 # equal to `_a = 2` -``` - -### Variables - -Here’s an example of how to create a variable and initialize it: - -```python -name = "Foo" # Declare a variable named `name` and its value is a string literal "Foo" -``` - -It corresponds to the following YAML output: - -```yaml -name: Foo -``` - -In KCL, we can export variables as config data by defining package-level variables. To make it direct, clear, and maintainable. Exported variables are immutable so that once we declare it, we can't modify it. For example, assume we have a config file named `example.k`, the variable `name` can't be modified after the declaration, just like the standard imperative language. - -```python -name = "Foo" # exported - -... - -name = "Bar" # error: a exported declaration variable can only be set once. -``` - -As a complement, we can define a non-exported variable in module level which is mutable, which won't show up in YAML output: - -```python -_name = "Foo" # _ variables are not output to YAML and are mutable -_name = "Bar" -``` - -Please note that the variable name cannot be one of `True`, `False`, `None`, `Undefined` because of ambiguity. - -```python -False = 1 # Error -True = False # Error -None = Undefined # Error -Undefined = None # Error -``` - -### Built-in Types - -The KCL language has special support for the following types: - -- number -- string -- boolean -- list -- dict - -#### Number - -KCL number comes into two flavors: - -- **Int**: 64 bits signed integer values. Values can be from -9223372036854775808~9223372036854775807. -- **Float**: 64-bit floating-point numbers, as specified by the IEEE 754 standard. We do not recommend using the float type in the configuration, we can use a string instead and parse it during runtime processing. - -Both int and float support basic operators such as `+`, `-`, `/`, and `*`, while complex operations, such as `abs()`, `ceil()`, and `floor()`, are supported through the built-in math library. - -Integers are numbers without a decimal point. Here are some examples of defining integer literals: - -```python -a = 1 -b = -1 -c = 0x10 # hexadecimal literal -d = 0o10 # octal literal -e = 010 # octal literal -f = 0b10 # binary literal -g = int("10") # int constructor -``` - -If a number includes a decimal point, it is a float number. Here are some examples of defining float literals: - -```python -a = 1.10 -b = 1.0 -c = -35.59 -d = 32.3e+18 -f = -90. -h = 70.2E-12 -i = float("112") # float constructor -``` - -Built-in math libraries can be used with numbers: - -```python -import math - -assert abs(-40) == 40 -assert round(70.23456) == 70 -assert min(80, 100, 1000) == 80 -assert max(80, 100, 1000) == 1000 -assert sum([0,1,2]) == 3 -assert math.ceil(100.12) == 101.0 -assert math.floor(100.12) == 100.0 -assert math.pow(100, 2) == 10000.0 -``` - -In addition, please note that the KCL number is 64-bit by default. We can perform a stricter 32-bit range check by adding the `-r` parameter to the KCL command-line tool. - -```bash -kcl main.k -r -d -``` - -Please note that the value range check is only enabled in `debug` mode - -##### Units - -In KCL, we can add a unit suffix to an integer denomination to indicate that it does not affect its true value as follows. - -- General integer or fixed-point number form: `P`, `T`, `G`, `M`, `K`, `k`, `m`, `u`, `n` -- Corresponding power of 2: `Pi`, `Ti`, `Gi`, `Mi`, `Ki` - -```python -# SI -n = 1n # 1e-09 -u = 1u # 1e-06 -m = 1m # 1e-03 -k = 1k # 1000 -K = 1K # 1000 -M = 1M # 1000000 -G = 1G # 1000000000 -T = 1T # 100000000000 -P = 1P # 1000000000000000 -# IEC -Ki = 1Ki # 1024 -Mi = 1Mi # 1024 ** 2 -Gi = 1Gi # 1024 ** 3 -Ti = 1Ti # 1024 ** 4 -Pi = 1Pi # 1024 ** 5 -``` - -Besides, And we can also use the unit constants defined in the `units` module as follows: - -```python -import units - -n = 1 * units.n # 1e-09 -u = 1 * units.u # 1e-06 -m = 1 * units.m # 1e-03 -k = 1 * units.k # 1000 -K = 1 * units.K # 1000 -M = 1 * units.M # 1000000 -G = 1 * units.G # 1000000000 -T = 1 * units.T # 1000000000000 -P = 1 * units.P # 1000000000000000 -# IEC -Ki = 1 * units.Ki # 1024 -Mi = 1 * units.Mi # 1024 ** 2 -Gi = 1 * units.Gi # 1024 ** 3 -Ti = 1 * units.Ti # 1024 ** 4 -Pi = 1 * units.Pi # 1024 ** 5 -``` - -We can also use the methods in the `units` module to convert between integers and unit strings. - -```python -import units -# SI -K = units.to_K(1000) # "1K" -M = units.to_M(1000000) # "1M" -G = units.to_G(1000000000) # "1G" -T = units.to_T(1000000000000) # "1T" -P = units.to_P(1000000000000000) # "1P" -# IEC -Ki = units.to_Ki(1024) # "1Ki" -Mi = units.to_Mi(1024 ** 2) # "1Mi" -Gi = units.to_Gi(1024 ** 3) # "1Gi" -Ti = units.to_Ti(1024 ** 4) # "1Ti" -Pi = units.to_Pi(1024 ** 5) # "1Pi" -``` - -```python -import units -# SI -K = units.to_K(int("1M")) # "1000K" -M = units.to_M(int("1G")) # "1000M" -G = units.to_G(int("1T")) # "1000G" -T = units.to_T(int("1P")) # "1000T" -P = units.to_P(int("10P")) # "10P" -# IEC -Ki = units.to_Ki(int("1Mi")) # "1024Ki" -Mi = units.to_Mi(int("1Gi")) # "1024Mi" -Gi = units.to_Gi(int("1Ti")) # "1024Gi" -Ti = units.to_Ti(int("1Pi")) # "1024Ti" -Pi = units.to_Pi(int("10Pi")) # "10Pi" -``` - -The unit value type is defined in the units module, and the unit value type does not allow any four calculations. - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -x0: NumberMultiplier = 1M # Ok -x1: NumberMultiplier = x0 # Ok -x2 = x0 + x1 # Error: unsupported operand type(s) for +: 'number_multiplier(1M)' and 'number_multiplier(1M)' -``` - -We can use the `int()`, `float()` function and `str()` function to convert the numeric unit type to the normal integer type and string type. - -```python -a: int = int(1Ki) # 1024 -b: float = float(1Ki) # 1024.0 -c: str = str(1Mi) # "1Mi" -``` - -#### String - -The string is an immutable sequence of Unicode characters. We can use either single or double quotes to create a string: - -```python -'allows embedded "double" quotes' # Single quotes -"allows embedded 'single' quotes" # Double quotes -'''Three single quotes''', """Three double quotes""" # Triple quoted -``` - -Triple quoted strings may span multiple lines. - -```python -"""This is a long triple quoted string -may span multiple lines. -""" -``` - -Please note that there is almost no difference in the use of KCL single-quoted and double-quoted strings. The only thing that can be simplified is that we don’t need to escape double quotes in single quoted strings, and we don’t need to escape single quotes in double quoted strings. - -```python -'This is my book named "foo"' # Don’t need to escape double quotes in single quoted strings. -"This is my book named 'foo'" # Don’t need to escape single quotes in double quoted strings. -``` - -We can concatenate strings using the `+` operator: - -```python -x = 'The + operator ' + 'works, as well.' -``` - -We can cast an int or float to a string using the built-in function `str`: - -```python -x = str(3.5) # "3.5" -``` - -A lot of handy built-in functions and members of a string could be used: - -```python -x = "length" -assert len(x) == 6 # True -assert x.capitalize() == "Length" -assert x.count("gt") == 1 -assert x.endswith("th") == True -assert x.find("gth") == 3 -assert "{} {}".format("hello", "world") == 'hello world' -assert x.index("gth") == 3 -assert x.isalnum() == True -assert x.isalpha() == True -assert "123456".isdigit() == True -assert x.islower() == True -assert " ".isspace() == True -assert "This Is Title Example".istitle() == True -assert x.isupper() == False -assert "|".join(["a", "b", "c"]) == "a|b|c" -assert "LENGTH".lower() == "length" -assert ' spacious '.lstrip() == 'spacious ' -assert x.replace("th", "ht") == "lenght" -assert "lengthlength".rfind("le") == 6 -assert "lengthlength".rindex("le") == 6 -assert "length length".rsplit() == ["length", "length"] -assert "length ".rstrip() == "length" -assert "length length".split() == ["length", "length"] -assert 'ab c\n\nde fg\rkl\r\n'.splitlines() == ['ab c', '', 'de fg', 'kl'] -assert "length".startswith('len') == True -assert "***length***".strip('*') == "length" -assert "length length".title() == "Length Length" -assert x.upper() == "LENGTH" -``` - -There are 2 different ways to format a string: to use the `"{}".format()` built-in function, or to specify the variable between the curly braces and use a `$` mark to tell KCL to extract its value. This is called **string interpolation** in KCL. In following example, both `a` and `b` will be assigned to string `"hello world"`. - -Besides, the variable to serialized can be extracted in special data format, such as YAML or JSON. In this case, a `#yaml` or `#json` can be included within the curly braces. - -Specifically, when the dollar sign `$` itself is needed in a **string interpolation**, it needs to be escaped and use `$$` instead. Or in another way, `+` can be used to concat the dollar sign with the **string interpolation** to avoid that escape. In following example, both `c` and `c2` will be assigned to string `$hello world$` - -```python -world = "world" -a = "hello {}".format(world) # "hello world" -b = "hello ${world}" # "hello world" -c = "$$hello ${world}$$" # "$hello world$" -c2 = "$" + "hello ${world}" + "$" # "$hello world$" - -myDict = { - "key1" = "value1" - "key2" = "value2" -} - -d = "here is myDict in json: ${myDict: #json}" -# d: 'here is myDict in json: {"key1": "value1", "key2": "value2"}' - -e = "here is myDict in yaml:\n${myDict: #yaml}" -# e: | -# here is myDict in yaml: -# key1: value1 -# key2: value2 -``` - -Besides, we can see some symbols in the example code output **YAML string** above such as `|`, `>`, `+`, `-`. - -- `|` denotes the **block literal style** that indicates how newlines inside the block should behave. -- `>` denotes the **block folded style** in the block scalar that the newlines will be replaced by spaces. -- `+` and `-` are the **block chomping indicators** that control what should happen with newlines at the end of the string. The default value **clip** puts a single newline at the end of the string. To remove all newlines, **strip** them by putting a `-` after the style indicators `|` or `>`. Both clip and strip ignore how many newlines are actually at the end of the block; to **keep** them all put a `+` after the style indicator. - -For example, a **strip block literal style** yaml string is - -```yaml -example: |- - Several lines of text, - with some "quotes" of various 'types', - and also a blank line: - - plus another line at the end. -``` - -The result is - -```plain -Several lines of text, -with some "quotes" of various 'types', -and also a blank line: - -plus another line at the end. -``` - -See [Yaml Multiline String](https://yaml-multiline.info/) and [YAML Specification v1.2](https://yaml.org/spec/1.2.1/) for more information. - -##### Raw String - -KCL raw string is created by prefixing a string literal with `'r'` or `'R'`. KCL raw string treats backslash (`\`) and string interpolation (`${}`) as a literal character. This is useful when we want to have a string that contains backslash, string interpolation and don’t want them to be treated as an escape character. - -- For backslash (`\`), the KCL code and output YAML are as follows: - -```python -s = "Hi\nHello" -raw_s = r"Hi\nHello" # This is a KCL raw string with the `r` prefix. -``` - -```yaml -s: |- - Hi - Hello -raw_s: Hi\nHello -``` - -- For string interpolation (`${}`), the KCL code and output YAML are as follows: - -```python -worldString = "world" -s = "Hello ${worldString}" -raw_s = r"Hello ${worldString}" # This is a KCL raw string with the `r` prefix. -``` - -```yaml -worldString: world -s: Hello world -raw_s: Hello ${worldString} -``` - -In addition, the most common scenario for raw strings is to be used with regular expressions: - -```python -import regex - -key = "key" -result = regex.match(key, r"[A-Za-z0-9_.-]*") # True -``` - -#### Boolean - -Boolean values are the two constant objects `False` and `True`. - -```python -a = True -b = False -``` - -#### List - -The list is a sequence, typically used to store collections of homogeneous items. Here’s a simple KCL list: - -```python -list = [1, 2, 3] -assert len(list) == 3 # True -assert list[0] == 1 # True -``` - -We can declare a list with list comprehension: - -```python -list = [ _x for _x in range(20) if _x % 2 == 0] -assert list == [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] # True -``` - -We can perform nested list comprehension: - -```python -matrix = [[1, 2], [3,4], [5,6], [7,8]] -transpose = [[row[_i] for row in matrix] for _i in range(2)] -assert transpose == [[1, 3, 5, 7], [2, 4, 6, 8]] # True -``` - -Besides, we can use two variables in the list comprehension, the first variable denotes the list index and the second variable denotes the list item. - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use `_` to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -We can merge list like this: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -joined_list = _list0 + _list1 # [1, 2, 3, 4, 5, 6] -``` - -We can also use the list unpacking operator `*` to merge multiple lists: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -union_list = [*_list0, *_list1] # [1, 2, 3, 4, 5, 6] -``` - -We can use `if expressions` to dynamically add elements to the list element, elements that meet the conditions are added to the list, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = [ - 1 - if a == 1: 2 - if a > 0: 3 - if a < 0: 4 -] # [1, 2, 3] -``` - -```python -a = 1 # 1 -data1 = [ - 1 - if a == 1: - 2 - elif a == 2: - 3 - else: - 3 -] # [1, 2] -data2 = [ - 1 - if a == 1: 2 - elif a == 2: 2 - else: 3 -] # [1, 2] -``` - -Please note that in the above `if expressions`, nested use is not supported. - -We can union two lists like this: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -union_list = _list0 | _list1 # [4, 5, 6] -``` - -We can use the expression `for k in list_var` to traverse a list. - -```python -data = [1, 2, 3] -dataAnother = [val * 2 for val in data] # [2, 4, 6] -``` - -#### Dict - -Dict is a mapping object that maps hashable values to arbitrary objects. Dict is ordered. The order of the keys follows the order of their declaration. - -Here are a couple of simple KCL dict, created using dict literals: - -```python -a = {"one" = 1, "two" = 2, "three" = 3} -b = {'one' = 1, 'two' = 2, 'three' = 3} -assert a == b # True -assert len(a) == 3 # True -``` - -We can ignore the comma `,` at the end of the line for writing dict key-value pairs in multiple lines: - -```python -data = { - "key1" = "value1" # Ignore the comma ',' at the end of line - "key2" = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -We can ignore the key quotation marks when we writing simple literals on the key. - -```python -data = { - key1 = "value1" # Ignore key quotation '"' - key2 = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -In addition, the **config selector expressions** can be used to init a dict instance with nested keys. - -```python -person = { - base.count = 2 - base.value = "value" - labels.key = "value" -} # {"base": {"count": 2, "value": "value"}, "labels": {"key": "value"}} -``` - -The output YAML is - -```yaml -person: - base: - count: 2 - value: value - labels: - key: value -``` - -In KCL, different fields in dict can be referenced, such as the following example. - -```python -config = { - name = "me" - metadata.name = name # Reference `name` with the value `"me"` in `config` directly. -} -``` - -The output YAML is - -```yaml -config: - name: me - metadata: - name: me -``` - -We can declare a dict with dict comprehension: - -```python -x = {str(i): 2 * i for i in range(3)} -assert x == {"0" = 0, "1" = 2, "2" = 4} -``` - -Besides, we can use two variables in the dict comprehension, the first variable denotes the dict key and the second variable denotes the dict value of the key. - -```python -data = {key1 = "value1", key2 = "value2"} -# Single variable loop -dataKeys1 = {k: k for k in data} # {"key1": "key1", "key2": "key2"} -dataValues1 = {k: data[k] for k in data} # {"key1": "value1", "key2": "value2"} -# Double variable loop -dataKeys2 = {k: k for k, v in data} # {"key1": "key1", "key2": "key2"} -dataValues2 = {v: v for k, v in data} # {"value1": "value1", "value2": "value2"} -dataFilter = {k: v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use `_` to ignore loop variables -dataKeys3 = {k: k for k, _ in data} # {"key1": "key1", "key2": "key2"} -dataValues3 = {v: v for _, v in data} # {"value1": "value1", "value2": "value2"} -``` - -We can **merge** dict using the dict unpacking operator `**` like this: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = {**_part1, **_part2} # {"a: "b", "c": "d"} -``` - -In addition, the same effect can be achieved by using the union operator `|`: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = _part1 | _part2 # {"a: "b", "c": "d"} -``` - -We can use `if expressions` to dynamically add elements to the dict element, elements that meet the conditions are added to the dict, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = { - key1 = "value1" - if a == 1: key2 = "value2" - if a > 0: key3 = "value3" - if a < 0: key4 = "value4" -} # {"key1": "value1", "key2": "value2", "key3": "value3"} -``` - -```python -a = 1 # 1 -data1 = { - key1 = "value1" - if a == 1: - key2 = "value2" - elif a > 0: - key3 = "value3" - else: - key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -data2 = { - key1 = "value1" - if a == 1: key2 = "value2" - elif a > 0: key3 = "value3" - else: key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -``` - -We can use the expression `for k in dict_var` to traverse a dict, and we can use the `in` operator to determine whether a dict contains a certain key - -```python -data = {key1 = "value1", key2 = "value2"} -dataAnother = {k: data[k] + "suffix" for k in data} # {"key1": "value1suffix", "key2": "value2suffix"} -containsKey1 = "key1" in data # True -containsKey2 = "key" in data # False -``` - -#### None - -In KCL, `None` can indicate that the value of the object is empty, which is similar to `nil` in Go or `null` in Java, and corresponds to `null` in YAML. - -```python -a = None -b = [1, 2, None] -c = {key1 = value1, key2 = None} -``` - -The output is as follows: - -```yaml -a: null -b: - - 1 - - 2 - - null -c: - key1: value1 - key2: null -``` - -Please note that `None` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + None # error -b = int(None) # error -c = not None # True -d = None == None # True -e = None or 1 # 1 -f = str(None) # None -``` - -#### Undefined - -`Undefined` is similar to `None`, but its semantics is that a variable is not assigned any value and will not be output to YAML - -```python -a = Undefined -b = [1, 2, Undefined] -c = {key1 = "value1", key2 = Undefined} -``` - -The output is as follows: - -```yaml -b: - - 1 - - 2 -c: - key1: value1 -``` - -Please note that `Undefined` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + Undefined # error -b = int(Undefined) # error -c = not Undefined # True -d = Undefined == Undefined # True -e = Undefined or 1 # 1 -f = str(Undefined) # Undefined -``` - -### Operators - -The following character sequences represent operators: - -```txt -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != @ \ -``` - -#### Arithmetic Operators - -KCL supports the common arithmetic operators: - -```python -assert 2 + 3 == 5 -assert 2 - 3 == -1 -assert 2 * 3 == 6 -assert 5 / 2 == 2.5 -assert 5 // 2 == 2 -assert 5 % 2 == 1 -``` - -#### Equality and Relational Operators - -KCL supports the meanings of equality and relational operators: - -```python -assert 2 == 2 -assert 2 != 3 -assert 3 > 2 -assert 2 < 3 -assert 3 >= 3 -assert 2 <= 3 -``` - -#### Logical Operators - -We can invert or combine boolean expressions using the logical operators e.g., `and` and `or`: - -```python -if not done and (col == 0 or col == 3): - # ...Do something... - -``` - -#### Bitwise and Shift Operators - -Here are examples of using bitwise and shift operators: - -```python -value = 0x22 -bitmask = 0x0f - -assert (value & bitmask) == 0x02 -assert (value & ~bitmask) == 0x20 -assert (value | bitmask) == 0x2f -assert (value ^ bitmask) == 0x2d -assert (value << 4) == 0x220 -assert (value >> 4) == 0x02 -``` - -The `|` operator likewise computes bitwise, unions basic types and unions collection and schema data, such as **list**, **dict** and **schema**. - -Computing bitwise examples: - -```python -0x12345678 | 0xFF # 0x123456FF -``` - -Unioning basic types examples: - -```python -schema x: - a: int | str # attribute a could be a int or string -``` - -#### Assignment Operators - -The following tokens serve as delimiters in the grammar: - -```bash - ( ) [ ] { } - , : . ; = -> - += -= *= /= //= %= - &= ^= >>= <<= **= -``` - -The following examples use assignment and argument assignment operators: - -```python -_a = 2 -_a *= 3 -_a += 1 -assert _a == 7 -``` - -#### Identity Operators - -The following keywords serve as identity operators in the grammar: - -```python -is, is not -``` - -The identity operators check whether the right hand side and the left hand side are the very same object. They are usually used to check if some variable is `None/Undefined/True/False`. Here are some examples: - -```python -empty_String = "" -empty_String is not None # True -``` - -#### Membership Operators - -The following keywords serve as membership operators in the grammar: - -```python -in, not in -``` - -- The `in` operator reports whether its first operand is a member of its second operand, which must be a list, dict, schema, or string. -- The `not in` operator is its negation. Both return a Boolean. - -The meaning of membership varies by the type of the second operand: the members of a list are its elements; the members of a dict are its keys; the members of a string are all its substrings. - -```python -1 in [1, 2, 3] # True - -d = {one = 1, two = 2} -"one" in d # True -"three" in d # False -1 in d # False -[] in d # False - -"nasty" in "dynasty" # True -"a" in "banana" # True -"f" not in "way" # True - -d = Data {one = 1, two = 2} # Data is a schema with attributes one and two -"one" in d # True -"three" in d # False -``` - -#### Comprehension - -A comprehension constructs a new list or dictionary value by looping over one or more iterables and evaluating a body expression that produces successive elements of the result. - -We can declare list and dict by comprehension as: - -```python -listVar = [_x for _x in range(20) if _x % 2 == 0] # list comprehension -dictVar = {str(_i): 2 * _i for _i in range(3)} # dict comprehension -``` - -#### Other Operators - -We can: - -- Represents a function call with **()**, like `"{} {}".format("hello", world)` -- Refers to the value at the specified index in the list with **[]** -- Define a type hint with **:** -- Refers to a member field with **.** -- Use the line continuation symbol `\` to write long expressions - -```python -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " -``` - -### Expressions - -#### Conditional Expressions - -A conditional expression has the form `a if cond else b`. It first evaluates the condition `cond`. If it's true, it evaluates `a` and yields its value; otherwise, it yields the value of `b`. - -Examples: - -```python -x = True if enabled else False # If enabled is True, x is True, otherwise x is False -``` - -#### Index Expressions - -An index expression `a[i]` yields the `i` th element of an indexable type such as a string or list. The index `i` must be an `int` value in the range `-n` ≤ `i` < `n`, where `n` is `len(a)`; any other index results in an error. - -A valid negative index `i` behaves like the non-negative index `n+i`, allowing for convenient indexing relative to the end of the sequence. - -```python -val = "abc" -list = ["zero", "one", "two"] -str_0 = val[0] # "a" -str_1 = val[1] # "b" -str_n1 = val[-1] # "c" - -list_0 = list[0] # "zero" -list_1 = list[1] # "one" -list_n1 = list[-1] # "two" -``` - -An index expression `d[key]` may also be applied to a dictionary `d`, to obtain the value associated with the specified key. It returns `Undefined` if the dictionary contains no such key. - -An index expression appearing on the left side of an assignment causes the specified list or dictionary element to be updated: - -```python -d = {key1 = "value1", key2 = "value2"} -key1value = d["key1"] # value1 -key2value = d["key2"] # value2 -``` - -It is a dynamic error to attempt to update an element of an immutable type, such as a list or string, or a frozen value of a mutable type. - -#### Slice Expressions - -A slice expression `a[start:stop:step]` yields a new value containing a sub-sequence of `a`, which must be a string, or list. - -Each of the `start`, `stop`, and `step` operands is optional; if present, each must be an integer. The `step` value defaults to 1. If the step is not specified, the colon preceding it may be omitted too. It is an error to specify a step of zero. - -Conceptually, these operands specify a sequence of values `i` starting at start and successively adding 'step' until `i` reaches or passes `stop`. The result consists of the concatenation of values of `a[i]` for which `i` is valid. - -The effective start and stop indices are computed from the three operands as follows. Let `n` be the length of the sequence. - -```python -val = "abc" -len = len(val) -a = val[1:len] # "bc" (remove first element) -b = val[0:-1] # "ab" (remove last element) -c = val[1:-1] # "b" (remove first and last element) -``` - -```python -"abc"[1:] # "bc" (remove first element) -"abc"[:-1] # "ab" (remove last element) -"abc"[1:-1] # "b" (remove first and last element) -"banana"[1::2] # "aaa" (select alternate elements starting at index 1) -"banana"[4::-2] # "nnb" (select alternate elements in reverse, starting at index 4) -``` - -It's not allowed to define a slice expression as a left value in KCL. Cause list and string are immutable, re-slicing can directly operate to operand to ensure better performance. - -#### Function Invocations - -KCL allows calling built-in functions and functions from built-in and system modules. - -To call a function, the basic way is shown as the following code excerpt: - -```python -import math - -a = math.pow(2, 3) # 2 powers 3 is 8. -b = len([1, 2, 3]) # the length of [1, 2, 3] is 3 -``` - -As you can see, arguments are separated with `,`, and KCL also supports positional arguments and key-value arguments. - -```python -print("hello world", end="") -``` - -Note that: - -- Some functions have parameters with default values. -- Some functions accept variadic arguments. - -When an argument is not supplied for a parameter without a default value, an error will be reported. - -#### Selector Expressions - -A selector expression selects the attribute or method of the value. KCL provides a wealth of ways to identify or filter attributes. - -`x.y` - -- dict: it denotes the value of the key `y` in the dict `x` -- schema: it denotes the attribute value of a schema `x` identified by `y` -- package: it denotes the identifier of a package `x` identified by `y` - -Examples: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -name = person.name # "Alice" -age = person.age # 18 - -myDict = { - key = "value" -} -result = myDict.key # "value" -``` - -`x?.y` - -`x` can be a schema instance or a dict. This is extremely helpful when the value of `x` might be `None` or when the key `y` might not exist in `x`. - -```python -# Example of dict: -data = {key = "value"} -a = data?.key # "value" -b = data?.name # Undefined - -# example of schema instance: -schema Company: - name: str - address: str - -schema Person: - name: str - job?: Company - -alice = Person { - name = "alice" -} - -if alice?.job?.name == "Group": - print("work in Group") -``` - -#### Quantifier Expressions - -Quantifier expressions act on collection: list or dict, generally used to obtain a certain result after processing the collection, mainly in the following four forms: - -- **all** - - Used to detect that all elements in the collection satisfy the given logical expression, and return a boolean value as the result. - - Only when all elements in the collection satisfy the expression true, the `all` expression is true, otherwise it is false. - - If the original collection is empty, return true. - - Supports short-circuiting of logical expressions during expression execution. -- **any** - - Used to detect that at least one element in the collection satisfies the given logical expression, and returns a boolean value as the result. - - When at least one element in the collection satisfies the expression true, the `any` expression is true, otherwise it is false. - - If the original collection is empty, return false. - - Supports short-circuiting of logical expressions during expression execution. -- **map** - - Generate a new **list** by mapping the elements in the original collection. - - The length of the new list is exactly the same as the original collection. -- **filter** - - By logically judging and filtering the elements in the original collection, and returning the filtered sub-collection. - - Only when the element judges the expression to be true, it is added to the sub-collection. - - The type (list, dict and schema) of the new collection is exactly the same as the original collection, and the length range is `[0, len(original-collection)]`. - -**all** and **any** expression sample codes: - -```python -schema Config: - volumes: [{str:}] - services: [{str:}] - - check: - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - }, "invalid cluster ip" - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } -``` - -**map** and **filter** expression sample codes: - -```python -a = map e in [{name = "1", value = 1}, {name = "2", value = 2}] { - {name = e.name, value = int(e.value) ** 2} -} # [{"name": "1", value: 1}, {"name": "2", "value": 4}] - -b = map k, v in {a = "foo", b = "bar"} { v } # ["foo", "bar"] - -c = filter e in [{name = "1", value = 1}, {name = "2", value = 2}] { - int(e.value) > 1 -} # [{"name": "2", "value": 2}] - -d = filter _, v in {a = "foo", b = "bar"} { - v == "foo" -} # {"a": "foo"} -``` - -Please pay attention to distinguish the difference between any expression and any type. When `any` is used in type annotations, it means that the value of the variable is arbitrary, while the any expression means that one of the elements in a set satisfies the condition. - -### Control Flow Statements - -#### If and Else - -KCL supports `if` statements with optional `elif` and `else` statements, as the next sample shows. - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - print("maybe a is negative") -else: - print("a >= 100") -``` - -The `elif` example: - -```python -_result = 0 -if condition == "one": - _result = 1 -elif condition == "two": - _result = 2 -elif condition == "three": - _result = 3 -else: - _result = 4 -``` - -`if-elif-else` statements can be nested. For example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - if a < 0: - print("a is negative") - print("No matter a is negative or positive, this message is printed") -else: - print("a >= 100") -``` - -In addition, for simple `if` statements as follows: - -```python -if success: - _result = "success" -else: - _result = "failed" -``` - -We can have it in one line using the ` if else ` pattern: - -```python -_result = "success" if success else "failed" -``` - -An `if` or `elif` statement evaluates a given expression. When the expression is evaluated to `True`, a list of statements following `:` are executed and when the expression is evaluated to `False` and statements will not be executed. - -Please note that the false name constant `False`, `None`, the zero number `0`, the empty list `[]`, the empty dict `{}` and the empty string `""` are all seen as `False` expressions. - -```python -_emptyStr = "" -_emptyList = [] -_emptyDict = {} -isEmptyStr = False if _emptyStr else True -isEmptyList = False if _emptyList else True -isEmptyDict = False if _emptyDict else True -``` - -The output is - -```yaml -isEmptyStr: true -isEmptyList: true -isEmptyDict: true -``` - -### Assert - -When errors happen, developers should be able to detect the error and abort execution. Thus, KCL introduce the `assert` syntax. The following is an example: - -```python -a = 1 -b = 3 -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -``` - -In addition, we can declare a condition for the assert statement and make an assertion when the condition is met. The usual way of writing is - -```python -a = None -if a: - assert a > 2: -``` - -In KCL, it can also be simplified to the following form using the **if** expression to compose more complex conditional assert logic: - -```python -a = None -assert a > 2 if a -``` - -### Function - -KCL supports using the lambda keyword to define a function. - -```python -func = lambda x: int, y: int -> int { - x + y -} -a = func(1, 1) # 2 -``` - -- The value of the last expression is used as the return value of the function, and the empty function body returns `None`. -- The return value type annotation can be omitted, and the return value type is the type of the last expression value. -- There is no order-independent feature in the function body, all expressions are executed in order. - -```python -_func = lambda x: int, y: int -> int { - x + y -} # Define a function using the lambda expression -_func = lambda x: int, y: int -> int { - x - y -} # Ok -_func = lambda x: int, y: int -> str { - str(x + y) -} # Error (int, int) -> str can't be assigned to (int, int) -> int -``` - -The function type variables cannot participate in any calculations and can only be used in assignment statements and call statements. - -```python -func = lambda x: int, y: int -> int { - x + y -} -x = func + 1 # Error: unsupported operand type(s) for +: 'function' and 'int(1)' -``` - -The lambda function supports the capture of external variables, which can be passed as parameters of other functions. - -```python -a = 1 -func = lambda x: int { - x + a -} -funcOther = lambda f, para: int { - f(para) -} -r0 = funcOther(func, 1) # 2 -r1 = funcOther(lambda x: int { - x + a -}, 1) # 2 -``` - -The output is - -```yaml -a: 1 -r: 2 -``` - -Further, we can define an anonymous function through lambda expression and call it. - -```python -result = (lambda x, y { - z = 2 * x - z + y -})(1, 1) # 3 -``` - -We can also use anonymous functions in the for loop. - -```python -result = [(lambda x, y { - x + y -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 3, 3, 4] -``` - -Note that the functions defined in the KCL are pure functions: - -- The return result of a function depends only on its arguments. -- There are no side effects in the function execution process. - -Therefore, KCL functions cannot modify external variables, but can only reference external variables. For example, the following code will cause an error: - -```python -globalVar = 1 -func = lambda { - x = globalVar # Ok - globalVar = 1 # Error -} -``` - -### Type System - -#### Type Annotation - -Type annotations can be used on top level variables, schema attributes and arguments. - -- An attribute can be of a basic type, such as a string (`str`), a floating-point number (`float`), a fixed-point number (`int`) or a boolean (`bool`). -- An attribute can be a literal type, such as a string literal (`"TCP"` and `"UDP"`), a number literal (`"1"` and `"1.2"`), a boolean literal (`True` and `False`) -- An attribute can also be a list or an ordinary dict: - - A list with unspecified type of elements is `[]`. - - A list with elements of type `t` is `[t]`. Here `t` is another type. - - A dict with keys of type `kt` and values of type `vt` is `{kt:vt}`. - - `kt`, `vt` or both of them can be missing, like a list with unspecified type of elements. -- An attribute can be a **union type** defined by `|`, such as `a | b`, which means the type of the member could be a or b. - - A union type can include any types of `int`, `str`, `float`, `bool`, `list`, `dict`, literal and schema type, and supports type nesting e.g. `{str:str|int}`, `[[int|str]|str|float]` and `2 | 4 | 6`, etc. -- An attribute can also be of a type generated from other schema. In such a case, the name of the other schema (including the package path prefix) is used as the type name. -- An attribute can annotated an any type e.g., `any`. - -Examples: - -- Basic type - -```python -"""Top level variable type annotation""" -a: int = 1 # Declare a variable `a` that has the type `int` and the value `1` -b: str = "s" # Declare a variable `b` that has the type `str` and the value `"s"` -c: float = 1.0 # Declare a variable `c` that has the type `float` and the value `1.0` -d: bool = True # Declare a variable `d` that has the type `bool` and the value `True` -``` - -- List/Dict/Schema Type - -```python -schema Person: - name: str = "Alice" - age: int = 10 - -a: [int] = [1, 2, 3] # Declare a variable `a` that has the list type `[int]` and the value `[1, 2, 3]` -b: {str:str} = {k1 = "v1", k2 = "v2"} # Declare a variable `b` that has the dict type `{str:str}` and the value `{k1 = "v1", k2 = "v2"}` -c: Person = Person {} # Declare a variable `c` that has the schema type `Person` and the value `Person {}` -``` - -- Union Type - -```python -# Basic union types -schema x[argc: int]: # Schema argument type annotation - p: int | str # Schema attribute type annotation -``` - -```python -# Literal union types -schema LiteralType: - # String literal union types, x_01 can be one of "TCP" and "UDP" - x_01: "TCP" | "UDP" - # Number literal union types, x_02 can be one of 2, 4, and 6 - x_02: 2 | 4 | 6 - # Unit union types, x_03 can be one of 1Gi, 2Gi and 4Gi - x_03: 1Gi | 2Gi | 4Gi - -x = LiteralType { - x_01 = "TCP" - x_02 = 2 - x_03 = 1Gi -} -``` - -The compiler throws an error when the value of a property does not conform to the union type definition: - -```python -# Literal union types -schema LiteralType: - # String literal union types, x_01 can be one of "TCP" and "UDP" - x_01: "TCP" | "UDP" - -x = LiteralType { - x_01 = "HTTP" # Error: the type got is inconsistent with the type expected, expect str(TCP)|str(UDP), got str(HTTP) -} -``` - -- Any Type - -```python -# Any type -schema Config: - literalConf: any = 1 - dictConf: {str:any} = {key = "value"} - listConf: [any] = [1, "2", True] - -config = Config {} -``` - -In KCL, changing the type of a variable is not allowed. If the type is not satisfied when reassigning the value, the type error will be raised. - -```python -_a = 1 # The type of `_a` is `int` -_a = "s" # Error: expect int, got str(s) -``` - -The type of a variable can be assigned to its upper bound type, but cannot be assigned to its specialized type. - -`None` and `Undefined` can be assigned to any type: - -- All types can be assigned to `any` type, `None` and `Undefined` can be assigned to `any` type. - -```python -a: int = None -b: str = Undefined -c: any = 1 -d: any = "s" -e: any = None -``` - -- The `int` type can be assigned to the `float` type, and the `float` type cannot be assigned to the `int` type. - -```python -a: float = 1 -b: int = 1.0 # Error: expect int, got float(1.0) -``` - -- The `int` type can be assigned to the `int|str` type, and the `int|str` type cannot be assigned to the `int` type. - -```python -a: int | str = 1 -b: int = 1 if a else "s" # Error: expect int, got int(1)|str(s) -``` - -Note that although the any type is provided in the KCl, it is still a static type, and the types of all variables are immutable during compilation. - -#### Type Inference - -If a variable or constant declaration in the top level or in the schema is not annotated explicitly with a type, the declaration's type is inferred from the initial value. - -- Integer literals are inferred to type `int`. - -```python -a = 1 # The variable `a` has the type `int` -``` - -- Float literals are inferred to type `float`. - -```python -a = 1.0 # The variable `a` has the type `float` -``` - -- String literals are inferred to type `str`. - -```python -a = "s" # The variable `a` has the type `str` -``` - -- Boolean literals are inferred to type `bool` - -```python -a = True # The variable `a` has the type `bool` -b = False # The variable `b` has the type `bool` -``` - -- `None` and `Undefined` are inferred to type `any` - -```python -a = None # The variable `a` has the type `any` -b = Undefined # The variable `b` has the type `any` -``` - -- List literals are inferred based on the elements of the literal, and to be variable-size. - -```python -a = [1, 2, 3] # The variable `a` has the type `[int]` -b = [1, 2, True] # The variable `b` has the list union type `[int|bool]` -c = ["s", 1] # The variable `c` has the list union type `[int|str]` -``` - -Please note that a empty list will be inferred to `[any]` - -```python -a = [] # The variable `a` has the type `[any]` -``` - -- Dict literals are inferred based on the keys and values of the literal, and to be variable-size. - -```python -a = {key = "value"} # The variable `a` has the type `{str:str}` -b = {key = 1} # The variable `b` has the type `{str:int}` -c = {key1 = 1, key2 = "s"} # The variable `c` has the type `{str:int|str}` -``` - -Please note that a empty dict will be inferred to `{any:any}` - -```python -a = {} # The variable `a` has the type `{any:any}` -``` - -- The type of the if conditional expression carrying the runtime value will be statically inferred as a union type of all possible results. - -```python -a: bool = True # The variable `a` has the type `bool` -b = 1 if a else "s" # The variable `b` has the type `int|str` -``` - -When a variable is deduced to a certain type, its type cannot be changed - -```python -_a = 1 -_a = "s" # Error: expect int, got str(1) -``` - -#### Type Alias - -We can use the `type` keyword to declare a type alias for all types in KCL to simplify the writing and use of complex types. - -```python -type Int = int -type String = str -type StringOrInt = String | Int -type IntList = [int] -type StringAnyDict = {str:} -``` - -We can import a type through import and define an alias for it. - -```py -import pkg - -type Data = pkg.Data -``` - -In addition, we can use type aliases and union types to achieve similar enumeration functions. - -```python -# A type alias of string literal union types -type Color = "Red" | "Yellow" | "Blue" - -schema Config: - color: Color = "Red" # The type of color is `"Red" | "Yellow" | "Blue"`, and it has an alias `Color`, whose default value is `"Red"` - -config = Config { - color = "Blue" -} -``` - -The output YAML is - -```yaml -config: - color: Blue -``` - -Please note that the type alias name cannot be one of `any`, `int`, `float`, `bool` and `str` because of ambiguity. - -```python -type any = int | str # Error -type int = str # Error -type float = int # Error -type bool = True # Error -type str = "A" | "B" | "C" # Error -``` - -#### Type Guards - -KCL supports the `typeof` function which can give very basic information about the type of values we have at runtime. In KCL, checking against the value returned by `typeof` is a type guard. KCL expects this to return a certain set of strings: - -Example: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person {} -t3 = typeof(_x1) - -_x2 = pkg.Person {} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# Output -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -In addition, we can use the `as` keyword in conjunction with type guards to complete defensive type conversion programming. - -Only types with partial order can be downcast converted, the use of the as keyword is as follows: - -- Basic types of partial order relations, e.g., `float -> int` -- Partial order relation of union type, e.g., `int | str -> str` and `[int | str] -> [str]` -- Contains the partial order relation of the upper bound of the type, e.g., `any -> int` -- Partial order relationship of structure type, e.g., `base-schema -> sub-schema` - -```python -schema Data1: - id?: int - -schema Data2: - name?: str - -data: Data1 | Data2 = Data1 {} - -if typeof(a) == "Data1": - data1 = data as Data1 # The type of `data1` is `Data1` -elif typeof(a) == "Data2": - data2 = data as Data2 # The type of `data2` is `Data2` -``` - -When a runtime error occurs in the `as` type conversion, a runtime error is thrown. - -```python -a: any = "s" -b: int = a as int # Error: The `str` type cannot be converted to the `int` type -``` - -If we don’t want to throw a runtime error, we can use the type guard for defensive coding with `if` expressions. - -```python -a: any = "s" -b = a as int if typeof(a) == "int" else None # The type of b is `int` -``` - -Note that the `as` conversion of literal type and union type is not supported, because they are not a certain runtime object, only int, float and other objects at runtime, there is no int literal, float literal object, and no union object. - -### Schema - -#### Overview - -A schema is a language element to define a complex configuration. -We can define typed attributes, initialization assignment, and verification rules. In addition, KCL supports schema single inheritance, mixin and protocol to realize the reuse of complex configuration. - -#### Basic - -##### Attribute - -The followings are some basic examples: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 -``` - -In KCL, we can use type annotations to define some attributes in the schema, each attribute can be set with an optional default value (such as the `age` attribute in the above code, its default value is `0`), attributes that are not set default values have an initial value of `Undefined`, which are not output in YAML. - -Note, the immutability of attributes in the schema follows the same rules as the immutability of global variables, only mutable attributes in the schema can be modified in the schema. - -```python -schema Person: - age: int = 1 # Immutable attribute - _name: str = "Alice" # Mutable attribute - - age = 10 # Error - _name = "Bob" # Ok -``` - -###### Optional Attribute - -Each attribute **must** be assigned with a not `None`/`Undefined` value as a schema instance unless it is modified by a question mark as an optional attribute. - -Examples: - -```python -schema Employee: - bankCard: int # bankCard is a required attribute, and it can NOT be None or Undefined - nationality?: str # nationality is an optional attribute, and it can be None or Undefined - -employee = Employee { - bankCard = None # Error, attribute 'bankCard' of Employee is required and can't be None or Undefined - nationality = None # Ok -} -``` - -##### Irrelevant Order Calculation - -The irrelevant order calculation in the schema indicates the reference relationship between the internal attributes of the schema. For example, when we declare an expression of the form `a = b + 1`, the calculation of the value of `a` depends on the calculation of the value of `b`. When the compiler calculate the value of `a` and the value of `a` depends on the value of `b`, the compiler will choose to first calculate the value of `b`, and then calculate the value of a according to the expression `a = b + 1`, which is slightly different from the calculation method of traditional procedural language the difference. - -Since the calculation of values in the schema is based on dependencies, just like a directed acyclic graph traverses each node in the graph according to the order of topological sorting, the order of declaration of attributes in the schema is not so important, so the feature is called the irrelevant order calculation. - -Please note that there can be no circular references between different schema attribute values. - -We can see this feature through the following examples. - -```python -schema Fib: - n1: int = n - 1 # Refers to the attribute `n` declared after `n1` - n2: int = n1 - 1 - n: int - value: int = 1 if n <= 2 else Fib {n = n1}.value + Fib {n = n2}.value - -fib8 = Fib {n = 8}.value -``` - -The output is - -```yaml -fib8: 21 -``` - -We can see that in the schema, we only need to simply specify the dependency between attributes, and the compiler will automatically calculate the value based on the dependency, which can help us save a lot of boilerplate code and reduce configuration difficulty of writing. - -##### Schema Context - -We can define the context of the schema to manage the attributes of the schema, and we can write schema parameters, temporary variables and expressions directly in the schema: - -```python -schema Person[_name: str]: # define a schema argument - name: str = _name # define a schema attribute - age: int = 10 # define a schema attribute with default value - hands: [int] = [i for i in [1, 2, 3]] # define a for statement -``` - -##### Validation - -In addition to using **static typing** (the type annotation) and **immutability** in KCL schema mentioned earlier to ensure code stability, a bunch of validation rules are supported in a simple **check** block (KCL supports almost all authentication capabilities of [OpenAPI](https://www.openapis.org/)): - -```python -import regex - -schema Sample: - foo: str - bar: int - fooList: [str] - - check: - bar > 0 # minimum, also support the exclusive case - bar < 100 # maximum, also support the exclusive case - len(fooList) > 0 # min length, also support exclusive case - len(fooList) < 100 # max length, also support exclusive case - regex.match(foo, "^The.*Foo$") # regex match - isunique(fooList) # unique - bar in range(100) # range - bar in [2, 4, 6, 8] # enum - multiplyof(bar, 2) # multipleOf -``` - -With the schema, all instances will be validated at compile time - -```python -# Ok -goodSample = Sample { - foo = "The Foo" - bar = 2 - fooList = ["foo0", "foo1"] -} - -# Error: validation failure: Check failed on check conditions: bar < 100. -badSample = Sample { - foo = "The Foo" - bar = 123 - fooList = ["foo0", "foo1"] -} -``` - -In addition, we can use **and**, **or**, **if** to compose more complex conditional check logic: - -```python -schema Sample: - bar: int - foo: str - doCheck: bool - - check: - regex.match(foo, "^The.*Foo$") and bar in [2, 4, 6, 8] if doCheck -``` - -In order to ensure that all check rules can play their corresponding roles well, we can test the rationality and correctness of different data combinations by writing KCL test cases, and run all test cases through the kcl test tool. - -##### Documents - -Usually after we write the schema model, we will write documentation comments for the schema, which can be completed by using a three-quoted string as follows: - -```python -schema Server: - """Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - - Attributes - ---------- - workloadType : str, default is Deployment - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - name : str, default is None - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - labels : {str:str}, optional, default is None - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - - Examples - ---------------------- - myCustomApp = AppConfiguration { - name = "componentName" - } - """ - workloadType: str = "Deployment" - name: str - labels?: {str:str} -``` - -##### Config - -Suppose we have the following schema definition: - -```python -schema Person: - firstName: str - lastName: str -``` - -A config could be defined with a JSON-like expression: - -```python -person = Person { - firstName = "firstName" - lastName = "lastName" -} -``` - -At the same time, the schema adheres to strict attribute definitions, -and configuring undefined attributes will trigger a compilation error. - -```python -person = Person { - firstName = "firstName" - lastName = "lastName" - fullName = "fullName" # Error: Cannot add member 'fullName' to schema 'Person', 'fullName' is not defined in schema 'Person' -} -``` - -We can use `if expressions` to dynamically add elements to the schema config, elements that meet the conditions are added to the schema config, and elements that do not meet the conditions are ignored. Besides, the **config selector expressions** can be used to init a schema instance. - -```python -schema Base: - count: int - value: str - -schema Person: - base: Base - labels: {str:str} - name?: str - -env = "prod" - -person1 = Person { - base.count = 2 # Config selector expression - base.value = "value" # A schema variable in schema can use selector expressions - labels.key = "value" # A dict variable in schema can use selector expressions -} - -person2 = Person { - base = { - count = 1 - value = "value" - } - labels.key = "value" - if env == "prod": - labels.env = env - else: - labels.env = "other" -} -``` - -The output YAML is - -```yaml -person1: - base: - count: 2 - value: value - labels: - key: value -person2: - base: - count: 1 - value: value - labels: - key: value - env: prod -``` - -When we instantiate a schema without config parameters, we can generate schema instances in the following three forms: - -```python -schema Data: - id: int = 1 - -data1 = Data {} -data2 = Data() {} -data3 = Data() -``` - -In addition to using a schema type to instantiate a schema, we can also use a schema instance to get a new instance using the config expression. - -```python -schema Config: - id: int - values: [int] - -configOrigin = Config { - id = 1 - values = [0, 1] -} -configNew = configOrigin { - id = 2 - values += [2, 3] -} -``` - -The output is - -```yaml -configOrigin: - id: 1 - values: - - 0 - - 1 -configNew: - id: 2 - values: - - 0 - - 1 - - 2 - - 3 -``` - -In addition, schema attribute default values can be modified by schema config. - -```python -schema Person: - age: int = 1 - name: str = "Alice" - - age = 2 # Error, can't change the default value of the attribute `age` in the schema context - -person = Person { - age = 3 # Ok, can change the default value of the attribute `age` in the schema config -} -``` - -#### Advanced - -##### Protocol & Mixin - -In addition to schema, an additional type definition method `protocol` is provided in KCL, and its properties are as follows: - -- In a protocol, only attributes and their types can be defined, complex logic and check expressions cannot be written, and mixins cannot be used. -- A protocol can only constrain properties that do not start with `_`. -- A protocol can only inherit or refer to other protocols, but cannot inherit or refer to other schemas. - -Besides, we can declare a complex assembly schema with optional **mixin** support and use **protocol** to add an optional host type to the dynamically inserted **mixin**.: - -```python -schema Person: - mixin [FullNameMixin] - - firstName: str # Required - lastName: str # Required - fullName?: str # Optional -``` - -A fullName mixin which generates a fullName as a simple sample: - -```python -protocol PersonProtocol: - firstName: str - lastName: str - fullName?: str - -mixin FullNameMixin for PersonProtocol: - fullName = "{} {}".format(firstName, lastName) -``` - -Then we can get the schema instance by: - -```python -person = Person { - firstName = "John" - lastName = "Doe" -} -``` - -The output is - -```yaml -person: - firstName: John - lastName: Doe - fullName: John Doe -``` - -Please note that the host type **protocol** can only be used for **mixin** definitions (the suffix name is `Mixin`), otherwise an error will be reported. - -```python -protocol DataProtocol: - data: str - -schema Data for DataProtocol: # Error: only schema mixin can inherit from protocol - x: str = data -``` - -##### Index Signature - -Index signatures can be defined in the KCL schema, and it means that the key-value constraints of the index signature can be used to construct a dict with the schema type, or additional checks can be added to the schema attributes to enhance the KCL type and semantic checks. - -- Use the form `[{attr_alias}: {key_type}]: {value_type}` to define an index signature in the schema, and `{attr_alias}` can be omitted. - -```python -schema Map: - """ - Map is a schema with a key of str type and a value of str type - """ - [str]: str # `{attr_alias}` can be omitted. - -data = Map { - key1 = "value1" - key2 = "value2" -} -``` - -- Mandatory all attributes of the schema key and value types - -```python -schema Person: - name: str - age: int # error, conflicts with the index signature definition `[str]: str` - [str]: str # The values of all attributes of the schema can only be strings -``` - -- Mandatory all attribute key and value types are defined in the schema, which is equivalent to restricting all attribute types except the additional attributes. - -```python -schema Person: - name: str - age: int - [...str]: str # Except for the `name` and `age` attributes, the key type of all other attributes of the schema must be `str`, and the value type must also be `str`. -``` - -- Define the index signature attribute alias and use it with the check block. - -```python -schema Data: - [dataName: str]: str - check: - dataName in ["Alice", "Bob", "John"] - -data = Data { - Alice = "10" - Bob = "12" - Jonn = "8" # Error: Jonn not in ["Alice", "Bob", "John"] -} -``` - -```python -import regex - -schema DataMap: - [attr: str]: str - check: - regex.match(attr, r'^[-._a-zA-Z0-9]+$') - -data = DataMap { - key1 = "value1" - "foo.bar" = "value2" # check error -} -``` - -##### Inheritance - -Like some other object-oriented languages, KCL provides fundamental but limited object-oriented support, such as **attribute reuse**, **private and public variables**, and **single inheritance**. Besides, KCL does NOT support multiple inheritances for the schema. - -The following is an example of schema inheritance: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 - -# An employee **is** a person, and has some additional information. -schema Employee(Person): - bankCard: int - nationality?: str - -employee = Employee { - firstName = "Bob" - lastName = "Green" - age = 18 - bankCard = 123456 -} -``` - -The output is - -```yaml -employee: - firstName: Bob - lastName: Green - age: 18 - bankCard: 123456 - nationality: null -``` - -Please note that KCL only allows **single inheritance** on schemas. - -In addition, when the schema has an inheritance relationship, the properties of optional attributes are as follows: - -- If the attribute is optional in the base schema, it could be optional or required in the sub-schema. -- If the attribute is required in the base schema, it must be required in the sub-schema. - -```python -schema Person: - bankCard?: int - nationality: str - -schema Employee(Person): - bankCard: int # Valid, both `bankCard: int` and `bankCard?: int` are allowed - nationality?: str # Error, only `nationality: str` is allowed -``` - -##### Schema Function - -Schema map very nicely onto functions; it can have any number of input and output parameters. For example, the Fibonacci function can be written as follows using the recursive schema config: - -```python -schema Fib[n: int]: - n1 = n - 1 - n2 = n - 2 - if n == 0: - value = 0 - elif n == 1: - value = 1 - else: - value = Fib(n1).value + Fib(n2).value - -fib8 = Fib(8).value # 21 -``` - -##### Decorators - -Just like Python, KCL supports the use of decorators on the schema. KCL Decorators dynamically alter the functionality of a schema without having to directly use sub schema or change the source code of the schema being decorated. And like a function call, the decorator supports passing in additional parameters. - -Built-in decorators of schema - -- `@deprecated` - Mark whether a schema or schema attribute is deprecated. The `@deprecated` decorator supports three parameters: - - **version** - string type, indicating the version information. The default value is empty. - - **reason** - string type, indicating the deprecated reason. The default value is empty. - - **strict** - bool type, indicating whether to report an error or warning. The default value is true. If `strict` is `True` and the error is thrown, the program will be interrupted. If `strict` is `False`, a warning will be output and the program will not be interrupted. - -Examples: - -```python -@deprecated -schema ObsoleteSchema: - attr: str - -schema Person: - name: str = "John" - attrs: ObsoleteSchema = { - attr = "value" - } - -person = Person {} # Error: ObsoleteSchema was deprecated -``` - -```python -schema Person: - firstName: str = "John" - lastName: str - @deprecated(version="1.16", reason="use firstName and lastName instead", strict=True) - name: str - -JohnDoe = Person { # Error: name was deprecated since version 1.16, use firstName and lastName instead - name = "deprecated" -} -``` - -Note that the current version of KCL does not yet support user-defined decorators. - -##### Members - -Built-in functions and members of schema - -- instances() - Return the list of existing instances of a schema. - -```python -schema Person: - name: str - age: int - -alice = Person { - name = "Alice" - age = 18 -} - -bob = Person { - name = "Bob" - age = 10 -} - -aliceAndBob = Person.instances() # Person is a schema type, instances() is its member method -``` - -The output is - -```yaml -alice: - name: Alice - age: 18 -bob: - name: Bob - age: 10 -aliceAndBob: - - name: Alice - age: 18 - - name: Bob - age: 10 -``` - -### Config Operations - -#### Config Unification - -##### | Operators - -In KCL, we can use the union operator `|` to achieve the merging of configurations, the types supported by the union operator are as follows: - -```txt -SchemaInstance | SchemaInstance -SchemaInstance | Dict -Dict | Dict -List | List -``` - -Unioning collection and schema data: - -- Unioning List. Overwrite the list expression on the right side of the operator `|` to the list variable on the left side of the operator one by one according to the **index**. - -```python -_a = [1, 2, 3] -_b = [4, 5, 6, 7] -x = _a | _b # [4, 5, 6, 7] 1 -> 4; 2 -> 5; 3 -> 6; Undefined -> 7 -``` - -Unioning to the specific index or all elements is still under discussion. - -- Unioning Dict. Union the dict expression on the right side of the operator `|` one by one to the dict variable on the left side of the operator according to the **key** - -```python -_a = {key1 = "value1"} -_b = {key1 = "overwrite", key2 = "value2"} -x = _a | _b # {"key1": "overwrite", "key2": "value2"} -``` - -The union of collection and schema is a new one whose attributes are unioning b to a, preserving the order of the attributes of the operands, left before right. - -- Unioning Schema. The union operation for schema is similar to dict. - -Schema union could be done as: - -```python -schema Person: - firstName?: str - lastName?: str - -_a = Person { - firstName = "John" -} -_b = {lastName = "Doe"} -_c = _a | _b # {"firstName": "John", "lastName": "Doe"} -_d = _a | None # {"firstName": "John"} -_e = _a | Undefined # {"firstName": "John"} -_f = None | _a # {"firstName": "John"} -_g = Undefined | _a # {"firstName": "John"} -``` - -Please note that when one of the left and right operands of the union operator is None, the other operand is returned immediately. - -```python -data1 = {key = "value"} | None # {"key": "value"} -data2 = None | [1, 2, 3] # [1, 2, 3] -data3 = None | None # None -``` - -The output is - -```yaml -data1: - key: value -data2: - - 1 - - 2 - - 3 -data3: null -``` - -##### : Operators - -Pattern: `identifier : E` or `identifier : T E` - -The value of the expression `E` with optional type annotation `T` will be unioned into the element value. - -Examples: - -```python -data = { - labels: {key1: "value1"} - # union {key2: "value2"} into the attribute labels. - labels: {key2: "value2"} -} -``` - -Output: - -```yaml -data: - labels: - key1: value1 - key2: value2 -``` - -In addition to using attribute operators on the schema config attributes, variables inside and outside the schema can use attribute operators to perform different operations on the configuration. - -- Using `:` outside the schema - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - data: Data - -# This is one configuration that will be merged. -config: Config { - data.d1 = 1 -} -# This is another configuration that will be merged. -config: Config { - data.d2 = 2 -} -``` - -Its equivalent configuration code can be expressed as - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - data: Data - -config: Config { - data.d1 = 1 - data.d2 = 1 -} -``` - -The output is - -```yaml -config: - data: - d1: 1 - d2: 1 -``` - -- Using `:` inside the schema - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - # This is one configuration that will be merged. - data: Data { - d1 = 1 - } - # This is another configuration that will be merged. - data: Data { - d2 = 1 - } - -config: Config {} -``` - -#### Config Override - -##### = Operators - -Pattern: `identifier = E` or `identifier : T = E` - -The value of the expression `E` with optional type annotation `T` will override the attribute value. - -Examples: - -```python -schema Data: - labels: {str:} = {key1 = "value1"} - -data = Data { - # override {key2: "value2"} into the attribute labels of the schema Data. - labels = {key2 = "value2"} -} -``` - -Output: - -```yaml -data: - labels: - key2: value2 -``` - -Note: - -- Especially, we can "delete" its content by overriding the attribute to `Undefined`, such as `{ a = Undefined }`. - -#### Insert - -##### += Operators - -Pattern: `identifier += E` or `identifier : T += E` - -Insert only works for list type `identifier`. - -`E` will be inserted just after the specified index of the list `identifier`, and the following attributes after the index will be automatically shifted. - -Examples: - -```python -schema Data: - labels: {str:} = {key1 = [0]} - -data = Data { - # insert [1] into the attribute labels.key1 of the schema Data. - labels: {key1 += [1]} -} -``` - -Output: - -```yaml -data: - labels: - key1: - - 0 - - 1 -``` - -If no index is specified, the last index will be used. - -#### Notice - -Please note that the calculations of the `=` and `+=` attribute operators of the same attribute are sequential, and the latter ones have a higher priority. - -```python -x = { - a = 1 # 1 -} | { - a = 2 # 1 -> 2 -} | { - a = 3 # 2 -> 3 -} # The final value of attribute `a` is 3 -``` - -Please note that the `:` attribute operator represents an idempotent merge operation, and an error will be thrown when the values that need to be merged conflict. - -Therefore, when we need a configuration to override or add and delete operations, it is best to use the `=` and `+=` operators - -```python -data0 = {id: 1} | {id: 2} # Error:conflicting values between {'id': 2} and {'id': 1} -data1 = {id: 1} | {id = 2} # Ok, the value of `data` is {"id": 2} -``` - -The check rules for `:` operator for KCL value conflicts are as follows: - -- For `None` and `Undefined` variables, they do not conflict with any value. - -```python -data0 = None | {id: 1} # Ok -``` - -- For `int`, `float`, `str` and `bool` types, when their values are different, they are considered as conflicts. - -```python -data0 = 1 | 1 # Ok -data1 = 1 | "s" # Error -``` - -- For list type - - When their lengths are not equal, they are regarded as conflicts. - - When their lengths are equal, as long as there is a conflict in the value of a child element, it is regarded as a conflict. - -```python -data0 = [1] | [1] # Ok -data1 = [1, 2] | [1] # Error -``` - -- For dict/schema type - - When the values of the same key conflict, they are regarded as conflicts - -```python -data0 = {id: 1} | {id: 1} # Ok -data1 = {id: 1} | {id: 2} # Error -data1 = {id: 1} | {idAnother: 1} # Ok -``` - -### Rule - -In addition to using the check keyword for verification and writing in the schema, KCL also supports the use of the `rule` keyword to define a set of rules for policy verification - -The KCL rule is the same as the schema/mixin/protocol and it is defined by indentation. We need write a rule per line and we can write if filter conditions and verification failure information for each rule. Different conditions are connected with logic `and` (similar to the way of writing in check block). - -```python -rule SomeRule: - age > 0, "rule check failure message" -``` - -We can call a KCL rule like instantiating a schema: - -```python -age = 1 -name = "Alice" - -rule SomeRule: - age > 0, "rule check failure message" - name == "Alice" - -rule1 = SomeRule() # Rule call -rule2 = SomeRule {} # Rule call -``` - -We can use protocol to implement type checking of rule structure: - -```python -# Schema definition -protocol Service: - clusterIp: str - $type: str - -# Schema definition -protocol Volume: - mountPath: [str] - -# Protocol -protocol SomeProtocol: - id: int - env: {str: any} - services: [Service] - volumes: [Volume] - -rule SomeChecker for SomeProtocol: - id > 0, "id must >0" - - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - } - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } - -# Call rule to check with config parameter -SomeChecker { - id = 1 - env = { - MY_ENV = "MY_ENV_VALUE" - } - services = [ - { - type = "ClusterIP" - clusterIP = "NONE" - } - ] - volumes = [ - { - mountPath = "/home/admin" - } - { - mountPath = "/home/myapp" - } - ] -} -``` - -Please note that the combination of `protocol` and `rule` can separate attributes from their constraint definitions. We can define different rules and protocols in different packages and combine them as needed. This is different from check expressions in schema, which can only be combined with schema attributes. - -Besides, the following two ways can be used to achieve the multiplexing of different Rules: - -- Inline Call - -```python -weather = "sunny" -day = "wednesday" - -rule IsSunny: - weather == "sunny" - -rule IsWednesday: - day == "wednesday" - -rule Main: - IsSunny() # Rule inline call - IsWednesday() # Rule inline call - -Main() # Rule call -``` - -- Inherit - -```python -weather = "sunny" -day = "wednesday" - -rule IsSunny: - weather == "sunny" - -rule IsWednesday: - day == "wednesday" - -rule Main(IsSunny, IsWednesday): - id == 1 - -Main() -``` - -We can obtain external data or input from the `option` function and the CLI parameter `-D` for verification: - -- A simple example - -```python -schema Day: - day: str - homework: str - -days: [Day] = option("days") - -rule Main: - filter d in days { - d.day not in ["saturday", "sunday"] and d.homework - } - -Main() -``` - -- A complex example - -```python -data = option("data") -input = option("input") - -rule Allow: - UserIsAdmin() - any grant in UserIsGranted() { - input.action == grant.action and input.type == grant.type - } - -rule UserIsAdmin: - any user in data.user_roles[input.user] { - user == "admin" - } - -rule UserIsGranted: - [ - grant - for role in data.user_roles[input.user] - for grant in data.role_grants[role] - ] - -allow = Allow() or False -``` - -Further, the above KCL rule code can be compiled into a target such as WASM and used at runtime. - -### Module - -KCL config files are organized as **modules**. A single KCL file is considered as a module, and a directory is considered as a package, which is a special module. - -The modules in the same package are visible and cross-package references need to be visible through import. - -Code structure: - -```bash -. -└── root - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -model1.k: - -```python -# schema CatalogItem in model1.k - -schema CatalogItem: - id: int - image: CatalogItemImage # CatalogItemImage is defined in the module of the same package e.g., model2.k in package model - title: str -``` - -service1.k: - -```python -import ..model as model # cross-package references - -schema ImageService: - image: model.CatalogItemImage # CatalogItemImage is imported from another package e.g., model2.k in package model - name: str -``` - -#### Relative Path Import - -We can use the operator `.` to realize the relative path import of KCL entry files. - -main.k: - -```python -import .model1 # Current directory module -import ..service # Parent directory -import ...root # Parent of parent directory - -s = service.ImageService {} -m = root.Schema {} -``` - -#### Absolute Path Import - -The semantics of `import a.b.c.d` is - -1. If `kcl.mod` not exist, regard the current directory as the package root and search the path `a/b/c/d` from the current directory. -2. If the current directory search fails, search from the root path `ROOT_PATH/a/b/c/d`, else raise an import error. - -The definition of the root path `ROOT_PATH` is the directory corresponding to the `kcl.mod` file from the current directory. - -Code structure: - -```bash -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -main.k: - -```python -import service # `root package` and `kcl.mod` are in the same directory -import mixin # `root package` and `kcl.mod` are in the same directory - -myModel = model.CatalogItem {} -``` - -Note that for the KCL entry file `main.k`, it cannot be imported into the folder where it is located, otherwise a recursive import error will occur: - -```python -import model # Error: recursively loading -``` - -### Top-Level Argument - -Assume some field need to be passed in dynamically like user input, we can define a top-level argument in a module: - -```python -bankCard = option("bankCard") # Get bankCard through the option function. -``` - -Then we can use the module as below: - -```bash -kcl employee.k -D bankCard=123 -``` - -Currently, supported types of top-level argument are number, string, bool, list and dict. - -```bash -kcl main.k -D list_key='[1,2,3]' -D dict_key='{"key":"value"}' -``` - -We need to pay attention to the escape of quotation marks `"` and other symbols in the command line - -#### Arguments with Setting Files - -In addition, it also supports inputting a YAML file as top-level arguments. - -```yaml -kcl_options: - - key: key_number - value: 1 - - key: key_dict - value: - innerDictKey: innerDictValue - - key: key_list - value: - - 1 - - 2 - - 3 - - key: bankCard - value: 123 -``` - -```bash -kcl -Y setting.yaml employee.k -``` - -In addition, the setting file also supports configuring command-line compilation parameters as follows: - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - disable_none: true - strict_range_check: true - debug: 1 - verbose: 1 - sort_keys: true - output: ./stdout.golden - overrides: - - app.image=new_image - path_selector: - - config - package_maps: - k8s: /Users/.kcl/kpm/k8s_1.24 -kcl_options: - - key: image - value: docker.io/kcllang/kcl:latest -``` - -KCL CLI -Y parameters also support multi-file configuration, and support separate writing and merging of compilation parameters and option top level arguments parameter configuration. - -```bash -kcl -Y compile_setting.yaml option_setting.yaml -``` - -- `compile_setting.yaml` - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - disable_none: true - strict_range_check: true - debug: 1 - verbose: 1 - output: ./stdout.golden -``` - -- `option_setting.yaml` - -```yaml -kcl_options: - - key: image - value: docker.io/kcllang/kcl:latest -``` - -We can use the following command line to get the meaning of each configuration parameter or see KCL Quick Start - -```bash -kcl --help -``` - -#### Option Functions - -We can use the `option` function in the KCL code to get the top-level arguments. - -```python -value = option(key="key", type='str', default="default_value", required=True, help="Set key value") -``` - -Parameters - -- **key**: The argument key. -- **type**: The argument type to be converted. -- **default**: The argument default value when the key-value argument is not provided -- **required**: Report an error when the key-value argument is not provided and required is True. -- **help**: The help message. - -### Multi-file Compilation - -In addition to the above KCL single file execution, we can compile multiple KCL entry files at the same time using the following command: - -```bash -kcl main_1.k main_2.k ... main_n.k -``` - -main_1.k - -```python -a = 1 -b = 2 -``` - -main_2.k - -```python -c = 3 -d = 4 -``` - -The output is: - -```yaml -a: 1 -b: 2 -c: 3 -d: 4 -``` - -Taking advantage of the **multi-file combination**, we can assemble multiple KCL files without the need to use import management files. Let us see an example of combining **multi-file compilation** and **schema instance**. - -model.k - -```python -schema Model: - name: str - labels?: {str:} - annotations?: {str:} - replicas: int - -_model1 = Model { - name = "model1" - labels.key1 = "value1" - labels.key2 = "value2" - annotations.key = "value" - replicas = 2 -} - -_model2 = Model { - name = "model2" - replicas = 3 -} -``` - -backend.k - -```python -import yaml - -schema Backend: - apiVersion: str = "v1" - kind: str = "Deployment" - metadata: {str:} - spec: {str:} = { - minReadySeconds = 0 - paused = False - progressDeadlineSeconds = 600 - replicas = 1 - revisionHistoryLimit = 10 - selector = {} - } - -_backends = [Backend { - metadata.name = model.name - metadata.labels = model.labels - metadata.annotations = model.annotations - spec.selector.matchLabels: model.labels - spec.replicas = model.replicas -} for model in Model.instances()] # Schema Model is defined in model.k -print("---\n".join([yaml.encode(_b, ignore_private=True) for _b in _backends])) -``` - -The command is - -```bash -kcl model.k backend.k -``` - -The output is - -```yaml -apiVersion: v1 -kind: Deployment -metadata: - name: model1 - labels: - key1: value1 - key2: value2 - annotations: - key: value -spec: - minReadySeconds: 0 - paused: false - progressDeadlineSeconds: 600 - replicas: 2 - revisionHistoryLimit: 10 - selector: - matchLabels: - key1: value1 - key2: value2 ---- -apiVersion: v1 -kind: Deployment -metadata: - name: model2 -spec: - minReadySeconds: 0 - paused: false - progressDeadlineSeconds: 600 - replicas: 3 - revisionHistoryLimit: 10 - selector: {} -``` - -### KCL CLI Path Selector - -We can use KCL CLI `-S|--path-selector` parameter to select one or more values out of a KCL model. - -The path selector looks like this: - -`var.name` - -#### Examples - -Code structure: - -```bash -. -├── kcl.mod -└── main.k - └── pkg - └── model.k -``` - -pkg/model.k: - -```python -schema Person: - name: str - age: int - -var = Person { - name = "Alice" - age = 18 -} -``` - -main.k - -```python -import pkg - -var = pkg.Person { - name = "Bob" - age = 10 -} -``` - -The command is - -```bash -kcl main.k -S var -``` - -The output is - -```yaml -name: Alice -age: 18 -``` - -### KCL CLI Variable Override - -In addition to **Variable Selector**, KCL also allows us to directly modify the values in the configuration model through the KCL CLI `-O|--overrides` parameter. - -The use of **Variable Override** is similar to [**Variable Selector**](#variable-selector), and the parameter contains three parts e.g., `pkg`, `identifier`, `attribute` and `override_value`. - -```bash -kcl main.k -O override_spec -``` - -- `override_spec` represents a unified representation of the configuration model fields and values that need to be modified - -```txt -override_spec: [[pkgpath] ":"] identifier ("=" value | "-") -``` - -- `pkgpath`: Indicates the path of the package whose identifier needs to be modified, usually in the form of `a.b.c`. For the main package, `pkgpath` is expressed as `__main__`, which can be omitted. If omitted, it means the main package. -- `identifier`: Indicates the identifier that needs to modify the configuration, usually in the form of `a.b.c`. -- `value`: Indicates the value of the configuration that needs to be modified, which can be any legal KCL expression, such as number/string literal value, list/dict/schema expression, etc. -- `=`: means to modify the value of identifier. - - When the identifier exists, modify the value of the existing identifier to value. - - When identifier does not exist, add the identifier attribute and set its value to value. -- `-`: means to delete the identifier attribute. - - When the identifier exists, delete it directly. - - When the identifier does not exist, no modification is made to the configuration. - -Note: When `identifier` appears multiple times, modify/delete all `identifier` values - -#### Examples - -##### Override Update Sample - -KCL code: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -``` - -The command is - -```bash -kcl main.k -O :person.name=\"Bob\" -O :person.age=10 -``` - -The output is - -```yaml -person: - name: Bob - age: 10 -``` - -Besides, when we use KCL CLI `-d` argument, the KCL file will be modified to the following content at the same time - -```bash -kcl main.k -O :person.name=\"Bob\" -O :person.age=10 -d -``` - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Bob" - age = 10 -} -``` - -Another more complicated example: - -```python -schema Person: - name: str - age: int - ids?: [int] - -person = Person { - name = "Alice" - age = 10 -} -``` - -The command is - -```bash -kcl main.k -O :person.ids=\[1,2\] -``` - -The output is - -```yaml -person: - name: Alice - age: 10 - ids: - - 1 - - 2 -``` - -##### Override Delete Sample - -KCL code: - -```python -schema Config: - x?: int = 1 - y?: str = "s" - -config = Config { - x = 2 -} -``` - -The command is - -```bash -kcl main.k -O config.x- -``` - -The output is - -```yaml -config: - x: 1 - y: s -``` - -### Summary - -This page summarized the commonly used features in the KCL language. As a new language, KCL will gradually increase the functional features according to the requirements of the configuration scenario. - -For more information, please try further resources: - -- KCL codelabs -- KCL language specification -- KCL OpenAPI specification diff --git a/versioned_docs/version-0.5.2/reference/model/datetime.md b/versioned_docs/version-0.5.2/reference/model/datetime.md deleted file mode 100644 index 5b829890..00000000 --- a/versioned_docs/version-0.5.2/reference/model/datetime.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: "datetime" -linkTitle: "datetime" -type: "docs" -description: datetime system module -weight: 100 ---- - -## time - -`ticks() -> float` - -Return the current time in seconds since the Epoch. Fractions of a second may be present if the system clock provides them. - -## date - -`date() -> str` - -Return the `%Y-%m-%d %H:%M:%S` format date. - -## now - -`now() -> str` - -Return the local time. e.g. `'Sat Jun 06 16:26:11 1998'` - -## today - -`today() -> str` - -Return the `%Y-%m-%d %H:%M:%S.%{ticks}` format date. diff --git a/versioned_docs/version-0.5.2/reference/model/index.md b/versioned_docs/version-0.5.2/reference/model/index.md deleted file mode 100644 index 163e8db3..00000000 --- a/versioned_docs/version-0.5.2/reference/model/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# System Package - -KCL provides engineering extensibility through system modules, user modules and plug-in modules. This section describes the basic concepts of system modules. diff --git a/versioned_docs/version-0.5.2/reference/model/json.md b/versioned_docs/version-0.5.2/reference/model/json.md deleted file mode 100644 index 44ec8c73..00000000 --- a/versioned_docs/version-0.5.2/reference/model/json.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: "json" -linkTitle: "json" -type: "docs" -description: json system module -weight: 100 ---- - -## encode - -``` -encode( - data: any, - sort_keys: bool = False, - indent: int = None, - ignore_private: bool = False, - ignore_none: bool = False -) -> str -``` - -Serialize a KCL object `data` to a JSON formatted str. - -## decode - -`decode(value: str) -> any` - -Deserialize `value` (a string instance containing a JSON document) to a KCL object. - -## dump_to_file - -``` -dump_to_file( - data: any, - filename: str, - ignore_private: bool = False, - ignore_none: bool = False -) -> None -``` - -Serialize a KCL object `data` to a JSON formatted str and write it into the file `filename`. diff --git a/versioned_docs/version-0.5.2/reference/model/math.md b/versioned_docs/version-0.5.2/reference/model/math.md deleted file mode 100644 index dae369af..00000000 --- a/versioned_docs/version-0.5.2/reference/model/math.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: "math" -linkTitle: "math" -type: "docs" -description: math system module -weight: 100 ---- - -## ceil - -`ceil(x) -> int` - -Return the ceiling of `x` as an Integral. This is the smallest integer >= x. - -## factorial - -`factorial(x) -> int` - -Return `x!`. Raise a error if `x` is negative or non-integral. - -## floor - -`floor(x) -> int` - -Return the floor of `x` as an Integral. This is the largest integer <= x. - -## gcd - -`gcd(a: int, b: int) -> int` - -Return the greatest common divisor of `x` and `y` - -## isfinite - -`isfinite(x) -> bool` - -Return `True` if `x` is neither an infinity nor a `NaN`, and `False` otherwise. - -## isinf - -`isinf(x) -> bool` - -Return `True` if `x` is a positive or negative infinity, and `False` otherwise. - -## isnan - -`isnan(x) -> bool` - -Return `True` if `x` is a `NaN` (not a number), and `False` otherwise. - -## modf - -`modf(x) -> List[float, float]` - -Return the fractional and integer parts of `x`. Both results carry the sign of `x` and are floats. - -## exp - -`exp(x) -> float` - -Return `e` raised to the power of `x`. - -## expm1 - -`expm1(x) -> float` - -Return `exp(x) - 1`. This function avoids the loss of precision involved in the direct evaluation of `exp(x) - 1` for small `x`. - -## log - -`log(x, base=2.71828182845904523536028747135266250) -> float` - -Return the logarithm of `x` to the base `e`. - -## log1p - -`log1p(x) -> float` - -Return the natural logarithm of `1+x` (base `e`). The result is computed in a way which is accurate for `x` near zero. - -## log2 - -`log2(x) -> float` -Return the base 2 logarithm of `x`. - -## log10 - -`log10(x) -> float` - -Return the base 10 logarithm of `x`. - -## pow - -`pow(x, y) -> float` - -Return `x**y` (`x` to the power of `y`). - -## sqrt - -`sqrt(x) -> float` - -Return the square root of `x`. diff --git a/versioned_docs/version-0.5.2/reference/model/overview.md b/versioned_docs/version-0.5.2/reference/model/overview.md deleted file mode 100644 index 36365ac1..00000000 --- a/versioned_docs/version-0.5.2/reference/model/overview.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -sidebar_position: 0 ---- - -# Overview - -KCL provides engineering extensibility through built-in modules, system modules and plug-in modules. - -![](/img/docs/reference/lang/model/kcl-module.png) - -The user code does not need to import functions that directly use builtin functions (such as calculating the length of a list with `len`, obtaining the type of value through `typeof`, etc.), and for basic types such as strings, it also provides some built-in methods (such as converting the case of strings, etc.). - -For relatively complex general logic, it is provided through the system modules. For example, by importing the `math` module, we can use related mathematical functions, and we can use the regular expression by importing the `regex` module. For KCL code, it can also be organized into different user modules. - -In addition, Python and Go can be used to develop plug-ins for KCL through the plugin mechanism. For example, there are the app-context plug-in can be used to obtain the context information of the current application to simplify code writing. diff --git a/versioned_docs/version-0.5.2/reference/model/yaml.md b/versioned_docs/version-0.5.2/reference/model/yaml.md deleted file mode 100644 index 4b952dcf..00000000 --- a/versioned_docs/version-0.5.2/reference/model/yaml.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: "yaml" -linkTitle: "yaml" -type: "docs" -description: yaml encode and decode function -weight: 300 ---- - -## encode - -``` -encode( - data: any, - sort_keys: bool = False, - ignore_private: bool = False, - ignore_none: bool = False -) -> str -``` - -Serialize a KCL object `data` to a YAML formatted str. - -## decode - -`decode(value: str) -> any` - -Deserialize `value` (a string instance containing a YAML document) to a KCL object. - -## dump_to_file - -``` -dump_to_file( - data: any, - filename: str, - ignore_private: bool = False, - ignore_none: bool = False -) -> None -``` - -Serialize a KCL object `data` to a YAML formatted str and write it into the file `filename`. diff --git a/versioned_docs/version-0.5.2/reference/package-management/_category_.json b/versioned_docs/version-0.5.2/reference/package-management/_category_.json deleted file mode 100644 index 7848e437..00000000 --- a/versioned_docs/version-0.5.2/reference/package-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Package Management Tools", - "position": 4 -} diff --git a/versioned_docs/version-0.5.2/reference/package-management/command-reference/1.init.md b/versioned_docs/version-0.5.2/reference/package-management/command-reference/1.init.md deleted file mode 100644 index 6a46976a..00000000 --- a/versioned_docs/version-0.5.2/reference/package-management/command-reference/1.init.md +++ /dev/null @@ -1,45 +0,0 @@ -# kpm init - -Init a kcl package. - -## Usage - -```shell -kpm init [options][package_name] -``` - -## Description - -`kpm init` will initialize a kcl package in the current directory. If the package name is not provided, the name of the current directory will be used. - -If the package name is provided, a subdirectory with the name of the package will be created and the package will be initialized in that directory. - -`kpm init` will create `kcl.mod`, `kcl.mod.lock` and `main.k` under the package directory. - -## Options - -### --help, -h - -Show help for `kpm init` command. - -## Examples - -### Init the current directory into a kcl package - -```shell -# create an empty directory -$ mkdir my_package - -# cd into the directory -$ cd my_package - -# init the current directory into a kcl package -$ kpm init -``` - -### Init a kcl package with a name - -```shell -# init a kcl package with a name 'my_package' -kpm init my_package -``` diff --git a/versioned_docs/version-0.5.2/reference/package-management/command-reference/10.help.md b/versioned_docs/version-0.5.2/reference/package-management/command-reference/10.help.md deleted file mode 100644 index 94c078f5..00000000 --- a/versioned_docs/version-0.5.2/reference/package-management/command-reference/10.help.md +++ /dev/null @@ -1,21 +0,0 @@ -# kpm help - -Print help information for kpm commands. - -## Usage - -```shell -kpm help -``` - -## Description - -`kpm help` will print help information for kpm commands. - -## Examples - -Use `kpm help` to print help information for kpm commands. - -```shell -kpm help -``` diff --git a/versioned_docs/version-0.5.2/reference/package-management/command-reference/2.add.md b/versioned_docs/version-0.5.2/reference/package-management/command-reference/2.add.md deleted file mode 100644 index 1d2517fb..00000000 --- a/versioned_docs/version-0.5.2/reference/package-management/command-reference/2.add.md +++ /dev/null @@ -1,53 +0,0 @@ -# kpm add - -Add a dependency to a kcl package. - -## Usage - -```shell -kpm add [options][package_reference] -``` - -## Description - -`kpm add` will add a dependency to a kcl package. The dependency can be from a git repository, or a kcl registry. - -`package_reference` is a kcl package reference, looks like `package_name:version`. - -## options - -### --git - -Specify the git url of the dependency from a git repository. - -### --tag - -Specify the tag of the dependency from a git repository. - -### --help, -h - -Show help for `kpm add` command. - -## Examples - -### Add a dependency from kcl registry - -Add kcl dependency named `k8s` to the current package.The version of the dependency will be the latest version. - -```shell -kpm add k8s -``` - -Add kcl dependency named 'k8s' with version 'v1.27.2'. - -```shell -kpm add k8s:v1.27.2 -``` - -### Add a dependency from git repository - -Add kcl dependency named `konfig` with version `v0.1.0` from git repository. - -```shell -kpm add --git https://github.com/awesome-kusion/konfig.git --tag v0.1.0 -``` diff --git a/versioned_docs/version-0.5.2/reference/package-management/command-reference/3.pkg.md b/versioned_docs/version-0.5.2/reference/package-management/command-reference/3.pkg.md deleted file mode 100644 index 9b4298a5..00000000 --- a/versioned_docs/version-0.5.2/reference/package-management/command-reference/3.pkg.md +++ /dev/null @@ -1,33 +0,0 @@ -# kpm pkg - -Package a kcl package into `*.tar`. - -## Usage - -```shell -kpm pkg [options] -``` - -## Description - -`kpm pkg` will package a kcl package into `*.tar`. - -Option `--target` is required to specify the tar file path of the package. - -## options - -### --target - -Specify the tar file path of the package. - -### --help, -h - -Show help for `kpm pkm` command. - -## Examples - -### Package a kcl package - -```shell -kpm pkg --target /Users/my_package_tar -``` diff --git a/versioned_docs/version-0.5.2/reference/package-management/command-reference/4.metadata.md b/versioned_docs/version-0.5.2/reference/package-management/command-reference/4.metadata.md deleted file mode 100644 index 3074a8d5..00000000 --- a/versioned_docs/version-0.5.2/reference/package-management/command-reference/4.metadata.md +++ /dev/null @@ -1,41 +0,0 @@ -# kpm metadata - -Print the metadata of a kcl package. - -## Usage - -```shell -kpm metadata [options] -``` - -## Description - -`kpm metadata` will print the metadata of a kcl package. The metadata includes the dependency information of the package. - -`--update` option is used to automatically download the missing dependency packages. - -## options - -### --update - -Automatically download the missing dependency packages. - -### --help, -h - -Show help for `kpm metadata` command. - -## Examples - -### Print the metadata of a kcl package - -Print the metadata of a kcl package. - -```shell -kpm metadata -``` - -Print the metadata of a kcl package and automatically download the missing dependency packages. - -```shell -kpm metadata --update -``` diff --git a/versioned_docs/version-0.5.2/reference/package-management/command-reference/5.run.md b/versioned_docs/version-0.5.2/reference/package-management/command-reference/5.run.md deleted file mode 100644 index b5001185..00000000 --- a/versioned_docs/version-0.5.2/reference/package-management/command-reference/5.run.md +++ /dev/null @@ -1,69 +0,0 @@ -# kpm run - -Compile a kcl package. - -## Usage - -```shell -kpm run [options][package_source] -``` - -## Description - -`kpm run` will compile a kcl package. - -## options - -### --input - -Specify the entry file path of the package. - -### --tag - -Specify the tag of the package specified by oci url `package_source`. - -### --vendor - -`--vendor` will move the dependency packages into the current packages and automatically download the missing dependency packages. - -### --kcl_args - -`--kcl_args` specifies the arguments passed to the kcl compiler. - -### --help, -h - -Show help for `kpm run` command. - -## Examples - -### compile the current kcl package - -Under the kcl package directory, `kpm run` can be used to compile the current kcl package. - -```shell -kpm run -``` - -### compile a kcl package tar file - -`kpm run` can be used to compile a kcl package tar file. - -```shell -kpm run /Users/demo/my_package.tar -``` - -### compile a kcl package from oci url - -`kpm run` can be used to compile a kcl package from oci url. - -```shell -kpm run --tag 0.0.1 oci://localhost:5001/test/my_package -``` - -### compile a kcl package from oci ref - -`kpm run` can be used to compile a kcl package from oci ref. - -```shell -kpm run test/my_package:0.0.1 -``` diff --git a/versioned_docs/version-0.5.2/reference/package-management/command-reference/6.login.md b/versioned_docs/version-0.5.2/reference/package-management/command-reference/6.login.md deleted file mode 100644 index 68ca0f1b..00000000 --- a/versioned_docs/version-0.5.2/reference/package-management/command-reference/6.login.md +++ /dev/null @@ -1,68 +0,0 @@ -# kpm login - -Login to the kpm registry. - -## Usage - -```shell -kpm login [options][kpm_registry] -``` - -## Description - -`kpm login` will login the kpm registry. - -## options - -### --username - -Specify the username of the kpm registry. - -### --password - -Specify the password of the kpm registry. - -### --help, -h - -Show help for `kpm login` command. - -## Examples - -### login to a registry with account and password - -```shell -kpm login -u -p -``` - -The output is - -```shell -Login succeeded -``` - -### login to a registry with account, and enter the password interactively - -```shell -kpm login -u -``` - -The output is - -```shell -Password: -Login succeeded -``` - -### login to a registry, and enter the account and password interactively - -```shell -kpm login -``` - -The output is - -```shell -Username: -Password: -Login succeeded -``` diff --git a/versioned_docs/version-0.5.2/reference/package-management/command-reference/7.logout.md b/versioned_docs/version-0.5.2/reference/package-management/command-reference/7.logout.md deleted file mode 100644 index 6c5d9aec..00000000 --- a/versioned_docs/version-0.5.2/reference/package-management/command-reference/7.logout.md +++ /dev/null @@ -1,27 +0,0 @@ -# kpm logout - -Logout from the kpm registry. - -## Usage - -```shell -kpm logout [options][kpm_registry] -``` - -## Description - -`kpm logout` will logout from the kpm registry. - -## options - -### --help, -h - -Show help for `kpm logout` command. - -## Examples - -### logout from oci registry - -```shell -kpm logout -``` diff --git a/versioned_docs/version-0.5.2/reference/package-management/command-reference/8.push.md b/versioned_docs/version-0.5.2/reference/package-management/command-reference/8.push.md deleted file mode 100644 index a70c5bc1..00000000 --- a/versioned_docs/version-0.5.2/reference/package-management/command-reference/8.push.md +++ /dev/null @@ -1,46 +0,0 @@ -# kpm push - -Push a package to the kpm registry. - -## Usage - -```shell -kpm push [options][kpm_registry] -``` - -## Description - -`kpm push` will push a package to the kpm registry. - -## options - -### --tar_path - -The path to the tar file to push. - -### --help, -h - -Show help for `kpm push` command. - -## Examples - -### push the current package - -You can use `kpm push` under the kcl package root directory to upload a kcl package to an OCI-based registry. - -```shell -# create a new kcl package. -$ kpm init -# enter the kcl package root directory -$ cd -# push it to an oci registry -$ kpm push -``` - -### push a tar to the registry - -You can also use `kpm push` to upload a tar file to an OCI-based registry. - -```shell -kpm push --tar_path -``` diff --git a/versioned_docs/version-0.5.2/reference/package-management/command-reference/9.pull.md b/versioned_docs/version-0.5.2/reference/package-management/command-reference/9.pull.md deleted file mode 100644 index b0126bcf..00000000 --- a/versioned_docs/version-0.5.2/reference/package-management/command-reference/9.pull.md +++ /dev/null @@ -1,42 +0,0 @@ -# kpm pull - -Pull a package from the kpm registry. - -## Usage - -```shell -kpm pull [options][package_source] -``` - -## Description - -`kpm pull` will pull a package from the kpm registry. - -## options - -### --tag - -The tag of the package to pull. - -### --help, -h - -Show help for `kpm push` command. - -## Examples - -### pull the package by package name - -You can use `kpm pull` to download a kcl package from the default OCI registry by kcl package name. -`kpm` will download the kcl package from the default OCI registry specified in the configuration file `kpm.json`. - -```shell -kpm pull : -``` - -### pull the package by oci url - -You can download a kcl package from an OCI-based registry url. - -```shell -kpm pull --tag -``` diff --git a/versioned_docs/version-0.5.2/reference/package-management/command-reference/index.md b/versioned_docs/version-0.5.2/reference/package-management/command-reference/index.md deleted file mode 100644 index ab6cc90c..00000000 --- a/versioned_docs/version-0.5.2/reference/package-management/command-reference/index.md +++ /dev/null @@ -1,36 +0,0 @@ -# kpm - -The kpm cli - -## Usage - -```shell -kpm [arguments]... -``` - -## Description - -`kpm` is a kcl package manager. It is used to install, remove, and update kcl packages. - -## Options - -### --help, -h - -Show help for kpm command - -### --version, -v - -Print the version of kpm - -## Subcommands - -- [kpm init](./1.init.md) - Init a kcl package -- [kpm add](./2.add.md) - Add a dependency to a kcl package -- [kpm pkg](./3.pkg.md) - Package a kcl package into `\*.tar`` -- [kpm metadata](./4.metadata.md) - Print the metadata of a kcl package -- [kpm run](./5.run.md) - Compile a kcl package into yaml -- [kpm login](./6.login.md) - Login to a kcl registry -- [kpm logout](./7.logout.md) - Logout from a kcl registry -- [kpm push](./8.push.md) - Push a kcl package to a registry -- [kpm pull](./9.pull.md) - Pull a kcl package from a registry -- [kpm help](./10.help.md) - print help for kpm command diff --git a/versioned_docs/version-0.5.2/reference/plugin/overview.md b/versioned_docs/version-0.5.2/reference/plugin/overview.md deleted file mode 100644 index f9561ddc..00000000 --- a/versioned_docs/version-0.5.2/reference/plugin/overview.md +++ /dev/null @@ -1,187 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Introduction - -KCL provides plugin support through a plugin agent and auxiliary command line tools, and the KCL plugin framework supports different general-purpose languages to develop plugins. Here we take Python as an example to briefly explain the use of plugins. - -KCL plugin Git repository: [https://github.com/kcl-lang/kcl-plugin](https://github.com/kcl-lang/kcl-plugin) - -## 0. Prerequisites - -Using the KCL Python plugin requires the presence of `Python 3.7+` in your `PATH`. - -## 1. Hello Plugin - -KCL plugins are installed in the `plugins` subdirectory of KCL (usually installed in the `$HOME/.kcl/plugins` directory), or set through the `$KCL_PLUGINS_ROOT` environment variable. Besides, the `plugins` directory could also be placed at the `pwd` path. KCL plugins are managed in the Git repository: [https://github.com/kcl-lang/kcl-plugin](https://github.com/kcl-lang/kcl-plugin), we can clone the repository for development. - -Enter the `kcl-plugin info` command to view the plugin directory (replace `/Users/kcl_user` with the local `$HOME` path): - -```shell -$ kcl-plugin info -# plugin_root: /Users/kcl_user/.kcl/plugins -``` - -View the list of plugins with the `kcl-plugin list` subcommand: - -```shell -$ kcl-plugin list -hello: hello doc - 0.0.1 -``` - -Where `hello` is an example builtin plugin (do not modify the plugin). - -In KCL code, the `hello` plugin can be imported via `import kcl_plugin.hello`. `main.k` code is as follows: - -```python -import kcl_plugin.hello - -name = "kcl" -three = hello.add(1,2) -``` - -The output result is - -```shell -$ python3 -m kclvm main.k -name: kcl -three: 3 -``` - -## 2. `kcl-plugin` Command - -`kcl-plugin` is a plugin helper command line tool, the command line help is as follows: - -```shell -$ kcl-plugin -usage: kcl-plugin [-h] {list,info,init,gendoc,test} ... -positional arguments: - {list,info,init,gendoc,test} - kcl plugin sub commands - list list all plugins - info show plugin document - init init a new plugin - gendoc gen all plugins document - test test plugin -optional arguments: - -h, --help show this help message and exit -``` - -- The `list` subcommand is used to view the list of plugins. -- The `info` subcommand is used to view the plugin directory and information about each plugin. -- The `init` subcommand is used to initialize new plugins. -- The `gendoc` subcommand is used to update the API documentation of all plugins. -- The `test` subcommand is used to test specified plugins. - -## 3. Plugin Information and Documentation - -Enter `kcl-plugin info hello` to view the `hello` plugin information: - -```shell -$ kcl-plugin info hello -{ - "name": "hello", - "describe": "hello doc", - "long_describe": "long describe", - "version": "0.0.1", - "method": { - "add": "add two numbers, and return result", - "foo": "no doc", - "list_append": "no doc", - "say_hello": "no doc", - "tolower": "no doc", - "update_dict": "no doc" - } -} -``` - -The information of the plugin mainly includes the name and version information of the plugin, and the function information provided by the plugin. This information is consistent with the automatically generated `api.md` file in the plugin directory (regenerate the `api.md` file for all plugins via `kcl-plugin gendoc` when the plugin API document changes). - -## 4. Plugin Directory Structure - -The directory structure of the plugin is as follows (replace `/Users/kcl_user` with the local `$HOME` path): - -```shell -$ tree /Users/kcl_user/.kcl/plugins/ -/Users/kcl_user/.kcl/plugins/ -├── _examples -├── _test -└── hello - ├── api.md - ├── plugin.py - └── plugin_test.py -$ -``` - -The `_examples` directory is the sample code of the plugin, the `_test` directory is the KCL test code of the plugin, and the other directories starting with letters are ordinary plugins. The content of the plugin is as follows: - -```shell -$ cat ./hello/plugin.py -# Copyright 2020 The KCL Authors. All rights reserved. -INFO = { - 'name': 'hello', - 'describe': 'hello doc', - 'long_describe': 'long describe', - 'version': '0.0.1', -} -def add(a: int, b: int) -> int: - """add two numbers, and return result""" - return a + b -... -``` - -Where `INFO` specifies the name of the plugin, a brief description, a detailed description and version information. And all the functions whose names start with letters are the functions provided by the plugin, so the `add` function can be called directly in KCL. - -> Note: KCL plugins are implemented in an independent pure Python code file, and plugins cannot directly call each other. - -## 5. Create Plugin - -A plugin can be created with the `kcl-plugin init` command: - -``` -$ kcl-plugin init hi -$ kcl-plugin list -hello: hello doc - 0.0.1 -hi: hi doc - 0.0.1 -``` - -The `kcl-plugin init` command will construct a new plugin from the built-in template, and then we can view the created plugin information with the `kcl-plugin list` command. - -## 6. Remove Plugin - -KCL plugins are located in the `plugins` subdirectory of KCL (usually installed in the `$HOME/.kcl/plugins` directory). -We can query the plugin installation directory with the command `kcl-plugin info`. - -```shell -$ kcl-plugin info -/Users/kcl_user/.kcl/plugins/ -$ tree /Users/kcl_user/.kcl/plugins/ -/Users/kcl_user/.kcl/plugins/ -├── _examples -├── _test -└── hello -- Delete this directory to delete the hello plugin - ├── api.md - ├── plugin.py - └── plugin_test.py -$ -``` - -## 7. Test Plugin - -There is a `plugin_test.py` file in the plugin directory, which is the unit test file of the plugin (based on the `pytest` testing framework). Also placed in the `_test` directory are plugin integration tests for KCL files. The `plugin_test.py` unit test is required, and the KCL integration tests in the `_test` directory can be added as needed. - -Unit tests for plugins can be executed via `kcl-plugin test`: - -```shell -$ kcl-plugin test hello -============================= test session starts ============================== -platform darwin -- Python 3.7.6+, pytest-5.3.5, py-1.9.0, pluggy-0.13.1 -rootdir: /Users/kcl_user -collected 5 items -.kcl/plugins/hello/plugin_test.py ..... [100%] -============================== 5 passed in 0.03s =============================== -$ -``` - -Integration tests can be tested by executing the `python3 -m pytest` command in the `_test` directory. diff --git a/versioned_docs/version-0.5.2/reference/plugin/project_context.md b/versioned_docs/version-0.5.2/reference/plugin/project_context.md deleted file mode 100644 index 0be02e78..00000000 --- a/versioned_docs/version-0.5.2/reference/plugin/project_context.md +++ /dev/null @@ -1,59 +0,0 @@ -# project_context - -project_context extract base info from project.yaml&stack.yaml - -_version: 0.0.1_ - -## `get_project_current_path` - -return the relative path of first file - -Example: - -```py -import kcl_plugin.project_context as ctx - -path = ctx.get_project_current_path() -print(path) -``` - -## `get_project_input_file` - -return compiling file list - -Example: - -```py -import kcl_plugin.project_context as ctx - -input_file = ctx.get_project_input_file() -print(input_file) -``` - -## `get_project_context` - -return the current project context from project.yaml - -Example: - -```py -import kcl_plugin.project_context as ctx - -project = ctx.get_project_context() -# Get project name -print(project?.name) -``` - -## `get_stack_context` - -return the current stack context from stack.yaml - -Example: - -```py -import kcl_plugin.project_context as ctx - -stack = ctx.get_stack_context() -# Get stack name -print(stack?.name) -``` diff --git a/versioned_docs/version-0.5.2/reference/xlang-api/go-api.md b/versioned_docs/version-0.5.2/reference/xlang-api/go-api.md deleted file mode 100644 index 2a978250..00000000 --- a/versioned_docs/version-0.5.2/reference/xlang-api/go-api.md +++ /dev/null @@ -1,665 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Go API - -```go -import kcl "kcl-lang.io/kcl-go" -``` - -## KCL Go SDK - -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ kcl files │ │ KCL-Go-API │ │ KCLResultList │ -│ ┌───────────┐ │ │ │ │ │ -│ │ 1.k │ │ │ │ │ │ -│ └───────────┘ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ ┌───────────┐ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.Get("a.b.c") │ -│ │ 2.k │ │ │ │ Run(path) │ │ │ └───────────┘ │ └───────────────┘ -│ └───────────┘ │────┐ │ └───────────┘ │ │ │ -│ ┌───────────┐ │ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ │ 3.k │ │ │ │ │ │ │ KCLResult │──┼────────▶│x.Get("k", &v) │ -│ └───────────┘ │ │ │ │ │ └───────────┘ │ └───────────────┘ -│ ┌───────────┐ │ ├───▶│ ┌───────────┐ │──────────▶│ │ -│ │setting.yml│ │ │ │ │RunFiles() │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ └───────────┘ │ │ │ └───────────┘ │ │ │ KCLResult │──┼────────▶│x.JSONString() │ -└─────────────────┘ │ │ │ │ └───────────┘ │ └───────────────┘ - │ │ │ │ │ -┌─────────────────┐ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ Options │ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.YAMLString() │ -│WithOptions │ │ │ │MustRun() │ │ │ └───────────┘ │ └───────────────┘ -│WithOverrides │────┘ │ └───────────┘ │ │ │ -│WithWorkDir │ │ │ │ │ -│WithDisableNone │ │ │ │ │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ -``` - -
Example -

- -```go -{ - const k_code = ` -name = "kcl" -age = 1 - -two = 2 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {} -x1 = Person { - age = 101 -} -` - - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First().YAMLString() - fmt.Println(yaml) - - fmt.Println("----") - - result := kcl.MustRun("./testdata/main.k").First() - fmt.Println(result.JSONString()) - - fmt.Println("----") - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - - fmt.Println("----") - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x1", &person)) -} -``` - -

-
- -## Index - -- [Go API](#go-api) - - [KCL Go SDK](#kcl-go-sdk) - - [Index](#index) - - [Constants](#constants) - - [func FormatCode](#func-formatcode) - - [func FormatPath](#func-formatpath) - - [func InitKclvmPath](#func-initkclvmpath) - - [func InitKclvmRuntime](#func-initkclvmruntime) - - [func LintPath](#func-lintpath) - - [func ListDepFiles](#func-listdepfiles) - - [func ListDownStreamFiles](#func-listdownstreamfiles) - - [func ListUpStreamFiles](#func-listupstreamfiles) - - [func OverrideFile](#func-overridefile) - - [func ValidateCode](#func-validatecode) - - [type KCLResult](#type-kclresult) - - [type KCLResultList](#type-kclresultlist) - - [func MustRun](#func-mustrun) - - [func Run](#func-run) - - [func RunFiles](#func-runfiles) - - [type KclType](#type-kcltype) - - [func GetSchemaType](#func-getschematype) - - [type ListDepFilesOption](#type-listdepfilesoption) - - [type ListDepsOptions](#type-listdepsoptions) - - [type Option](#type-option) - - [func WithCode](#func-withcode) - - [func WithDisableNone](#func-withdisablenone) - - [func WithKFilenames](#func-withkfilenames) - - [func WithOptions](#func-withoptions) - - [func WithOverrides](#func-withoverrides) - - [func WithPrintOverridesAST](#func-withprintoverridesast) - - [func WithSettings](#func-withsettings) - - [func WithSortKeys](#func-withsortkeys) - - [func WithWorkDir](#func-withworkdir) - - [type ValidateOptions](#type-validateoptions) - -## Constants - -KclvmAbiVersion is the current kclvm ABI version. - -```go -const KclvmAbiVersion = scripts.KclvmAbiVersion -``` - -## func [FormatCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L110) - -```go -func FormatCode(code interface{}) ([]byte, error) -``` - -FormatCode returns the formatted code. - -
Example -

- -```go -{ - out, err := kcl.FormatCode(`a = 1+2`) - if err != nil { - log.Fatal(err) - } - fmt.Println(string(out)) - -} -``` - -``` -a = 1 + 2 -``` - -

-
- -## func [FormatPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L122) - -```go -func FormatPath(path string) (changedPaths []string, err error) -``` - -FormatPath formats files from the given path path: if path is \`.\` or empty string, all KCL files in current directory will be formatted, not recursively if path is \`path/file.k\`, the specified KCL file will be formatted if path is \`path/to/dir\`, all KCL files in the specified dir will be formatted, not recursively if path is \`path/to/dir/...\`, all KCL files in the specified dir will be formatted recursively - -the returned changedPaths are the changed file paths \(relative path\) - -
Example -

- -```go -{ - changedPaths, err := kcl.FormatPath("testdata/fmt") - if err != nil { - log.Fatal(err) - } - fmt.Println(changedPaths) -} -``` - -

-
- -## func [InitKclvmPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L54) - -```go -func InitKclvmPath(kclvmRoot string) -``` - -InitKclvmPath init kclvm path. - -## func [InitKclvmRuntime](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L59) - -```go -func InitKclvmRuntime(n int) -``` - -InitKclvmRuntime init kclvm process. - -## func [LintPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L142) - -```go -func LintPath(paths []string) (results []string, err error) -``` - -LintPath lint files from the given path - -
Example -

- -```go -{ - - results, err := kcl.LintPath([]string{"testdata/lint/import.k"}) - if err != nil { - log.Fatal(err) - } - for _, s := range results { - fmt.Println(s) - } - -} -``` - -``` -Module 'a' is reimported multiple times -Module 'a' imported but unused -``` - -

-
- -## func [ListDepFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L127) - -```go -func ListDepFiles(workDir string, opt *ListDepFilesOption) (files []string, err error) -``` - -ListDepFiles return the depend files from the given path - -## func [ListDownStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L137) - -```go -func ListDownStreamFiles(workDir string, opt *ListDepsOptions) ([]string, error) -``` - -ListDownStreamFiles return a list of downstream depend files from the given changed path list. - -## func [ListUpStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L132) - -```go -func ListUpStreamFiles(workDir string, opt *ListDepsOptions) (deps []string, err error) -``` - -ListUpStreamFiles return a list of upstream depend files from the given path list - -## func [OverrideFile](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L154) - -```go -func OverrideFile(file string, specs, importPaths []string) (bool, error) -``` - -OverrideFile rewrites a file with override spec file: string. The File that need to be overridden specs: \[\]string. List of specs that need to be overridden. - -``` -Each spec string satisfies the form: := or :- -When the pkgpath is '__main__', it can be omitted. -``` - -importPaths. List of import statements that need to be added - -## func [ValidateCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L159) - -```go -func ValidateCode(data, code string, opt *ValidateOptions) (ok bool, err error) -``` - -ValidateCode validate data match code - -## type [KCLResult](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L47) - -```go -type KCLResult = kcl.KCLResult -``` - -
Example -

- -```go -{ - const k_code = ` -name = "kcl" -age = 1 - -two = 2 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {name = "kcl-go"} -x1 = Person {age = 101} -` - - result := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First() - - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - -} -``` - -``` -x0.name: kcl-go -x1.age: 101 -``` - -

-
- -
Example ('et_struct) -

- -```go -{ - const k_code = ` -schema Person: - name: str = "kcl" - age: int = 1 - X: int = 2 - -x = { - "a": Person {age = 101} - "b": 123 -} -` - - result := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First() - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x.a", &person)) - fmt.Printf("person: %+v\n", person) - -} -``` - -``` -person: &{Name:kcl Age:101} -person: {Name:kcl Age:101} -``` - -

-
- -## type [KCLResultList](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L48) - -```go -type KCLResultList = kcl.KCLResultList -``` - -### func [MustRun](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L64) - -```go -func MustRun(path string, opts ...Option) *KCLResultList -``` - -MustRun is like Run but panics if return any error. - -
Example -

- -```go -{ - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(`name = "kcl"`)).First().YAMLString() - fmt.Println(yaml) - -} -``` - -``` -name: kcl -``` - -

-
- -
Example (Raw Yaml) -

- -```go -{ - const code = ` -b = 1 -a = 2 -` - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(code)).GetRawYamlResult() - fmt.Println(yaml) - - yaml_sorted := kcl.MustRun("testdata/main.k", kcl.WithCode(code), kcl.WithSortKeys(true)).GetRawYamlResult() - fmt.Println(yaml_sorted) - -} -``` - -``` -b: 1 -a: 2 -a: 2 -b: 1 -``` - -

-
- -
Example (Schema Type) -

- -```go -{ - const code = ` -schema Person: - name: str = "" - -x = Person() -` - json := kcl.MustRun("testdata/main.k", kcl.WithCode(code)).First().JSONString() - fmt.Println(json) - -} -``` - -``` -{ - "x": { - "name": "" - } -} -``` - -

-
- -
Example (Settings) -

- -```go -{ - yaml := kcl.MustRun("./testdata/app0/kcl.yaml").First().YAMLString() - fmt.Println(yaml) -} -``` - -

-
- -### func [Run](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L69) - -```go -func Run(path string, opts ...Option) (*KCLResultList, error) -``` - -Run evaluates the KCL program with path and opts, then returns the object list. - -
Example (Get Field) -

- -```go -{ - - x, err := kcl.Run("./testdata/app0/kcl.yaml") - assert(err == nil, err) - - fmt.Println(x.First().Get("deploy_topology.1.zone")) - -} -``` - -``` -R000A -``` - -

-
- -### func [RunFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L74) - -```go -func RunFiles(paths []string, opts ...Option) (*KCLResultList, error) -``` - -RunFiles evaluates the KCL program with multi file path and opts, then returns the object list. - -
Example -

- -```go -{ - result, _ := kcl.RunFiles([]string{"./testdata/app0/kcl.yaml"}) - fmt.Println(result.First().YAMLString()) -} -``` - -

-
- -## type [KclType](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L50) - -```go -type KclType = kcl.KclType -``` - -### func [GetSchemaType](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L176) - -```go -func GetSchemaType(file, code, schemaName string) ([]*KclType, error) -``` - -GetSchemaType returns schema types from a kcl file or code. - -file: string - -``` -The kcl filename -``` - -code: string - -``` -The kcl code string -``` - -schema_name: string - -``` -The schema name got, when the schema name is empty, all schemas are returned. -``` - -## type [ListDepFilesOption](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L45) - -```go -type ListDepFilesOption = list.Option -``` - -## type [ListDepsOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L44) - -```go -type ListDepsOptions = list.DepOptions -``` - -## type [Option](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L43) - -```go -type Option = kcl.Option -``` - -### func [WithCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L79) - -```go -func WithCode(codes ...string) Option -``` - -WithCode returns a Option which hold a kcl source code list. - -### func [WithDisableNone](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L97) - -```go -func WithDisableNone(disableNone bool) Option -``` - -WithDisableNone returns a Option which hold a disable none switch. - -### func [WithKFilenames](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L82) - -```go -func WithKFilenames(filenames ...string) Option -``` - -WithKFilenames returns a Option which hold a filenames list. - -### func [WithOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L85) - -```go -func WithOptions(key_value_list ...string) Option -``` - -WithOptions returns a Option which hold a key=value pair list for option function. - -
Example -

- -```go -{ - const code = ` -name = option("name") -age = option("age") -` - x, err := kcl.Run("hello.k", kcl.WithCode(code), - kcl.WithOptions("name=kcl", "age=1"), - ) - if err != nil { - log.Fatal(err) - } - - fmt.Println(x.First().YAMLString()) - -} -``` - -``` -age: 1 -name: kcl -``` - -

-
- -### func [WithOverrides](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L88) - -```go -func WithOverrides(override_list ...string) Option -``` - -WithOverrides returns a Option which hold a override list. - -### func [WithPrintOverridesAST](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L100) - -```go -func WithPrintOverridesAST(printOverridesAST bool) Option -``` - -WithPrintOverridesAST returns a Option which hold a printOverridesAST switch. - -### func [WithSettings](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L91) - -```go -func WithSettings(filename string) Option -``` - -WithSettings returns a Option which hold a settings file. - -### func [WithSortKeys](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L105) - -```go -func WithSortKeys(sortKeys bool) Option -``` - -WithSortKeys returns a Option which hold a sortKeys switch. - -### func [WithWorkDir](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L94) - -```go -func WithWorkDir(workDir string) Option -``` - -WithWorkDir returns a Option which hold a work dir. - -## type [ValidateOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L46) - -```go -type ValidateOptions = validate.ValidateOptions -``` diff --git a/versioned_docs/version-0.5.2/reference/xlang-api/rest-api.md b/versioned_docs/version-0.5.2/reference/xlang-api/rest-api.md deleted file mode 100644 index 4723280f..00000000 --- a/versioned_docs/version-0.5.2/reference/xlang-api/rest-api.md +++ /dev/null @@ -1,443 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Rest API - -## 1. Start REST Service - -The RestAPI service can be started in the following ways: - -```shell -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -or - -```shell -go install kcl-lang.io/kcl-go/cmds/kcl-go@main -kcl-go rest-server -``` - -The service can then be requested via the POST protocol: - -```shell -$ curl -X POST http://127.0.0.1:2021/api:protorpc/BuiltinService.Ping --data '{}' -{ - "error": "", - "result": {} -} -``` - -The POST request and the returned JSON data are consistent with the structure defined by Protobuf. - -## 2. `BuiltinService` - -Where the `/api:protorpc/BuiltinService.Ping` path represents the `Ping` method of the `BuiltinService` service. - -The complete `BuiltinService` is defined by Protobuf: - -```protobuf -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} -``` - -The `Ping` method can verify whether the service is normal, and the `ListMethod` method can query the list of all services and functions provided. - -## 3. `KclvmService` - -The `KclvmService` service is a service related to KCL functionality. The usage is the same as the `BuiltinService` service. - -For example, there is the following `Person` structure definition: - -```python -schema Person: - key: str - - check: - "value" in key # 'key' is required and 'key' must contain "value" -``` - -Then we want to use `Person` to verify the following JSON data: - -```json -{ "key": "value" } -``` - -This can be done through the `ValidateCode` method of the `KclvmService` service. Refer to the `ValidateCode_Args` structure of the `ValidateCode` method: - -```protobuf -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} -``` - -Construct the JSON data required by the POST request according to the `ValidateCode_Args` structure, which contains the `Person` definition and the JSON data to be verified: - -```json -{ - "code": "\nschema Person:\n key: str\n\n check:\n \"value\" in key # 'key' is required and 'key' must contain \"value\"\n", - "data": "{\"key\": \"value\"}" -} -``` - -Save this JSON data to the `vet-hello.json` file and verify it with the following command: - -```shell -$ curl -X POST \ - http://127.0.0.1:2021/api:protorpc/KclvmService.ValidateCode \ - -H "accept: application/json" \ - --data @./vet-hello.json -{ - "error": "", - "result": { - "success": true - } -} -``` - -## 4. Complete Protobuf Service Definition - -Cross-language APIs defined via Protobuf([https://github.com/kcl-lang/kcl-go/blob/main/pkg/spec/gpyrpc/gpyrpc.proto](https://github.com/kcl-lang/kcl-go/blob/main/pkg/spec/gpyrpc/gpyrpc.proto)): - -```protobuf -// Copyright 2023 The KCL Authors. All rights reserved. -// -// This file defines the request parameters and return structure of the KCL RPC server. -// We can use the following command to start a KCL RPC server. - -syntax = "proto3"; - -package gpyrpc; - -import "google/protobuf/any.proto"; -import "google/protobuf/descriptor.proto"; - -// ---------------------------------------------------------------------------- - -// kcl main.k -D name=value -message CmdArgSpec { - string name = 1; - string value = 2; -} - -// kcl main.k -O pkgpath:path.to.field=field_value -message CmdOverrideSpec { - string pkgpath = 1; - string field_path = 2; - string field_value = 3; - string action = 4; -} - -// ---------------------------------------------------------------------------- -// gpyrpc request/response/error types -// ---------------------------------------------------------------------------- - -message RestResponse { - google.protobuf.Any result = 1; - string error = 2; - KclError kcl_err = 3; -} - -message KclError { - string ewcode = 1; // See kclvm/kcl/error/kcl_err_msg.py - string name = 2; - string msg = 3; - repeated KclErrorInfo error_infos = 4; -} - -message KclErrorInfo { - string err_level = 1; - string arg_msg = 2; - string filename = 3; - string src_code = 4; - string line_no = 5; - string col_no = 6; -} - -// ---------------------------------------------------------------------------- -// service requset/response -// ---------------------------------------------------------------------------- - -// gpyrpc.BuiltinService -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -// gpyrpc.KclvmService -service KclvmService { - rpc Ping(Ping_Args) returns(Ping_Result); - - rpc ExecProgram(ExecProgram_Args) returns(ExecProgram_Result); - - rpc FormatCode(FormatCode_Args) returns(FormatCode_Result); - rpc FormatPath(FormatPath_Args) returns(FormatPath_Result); - rpc LintPath(LintPath_Args) returns(LintPath_Result); - rpc OverrideFile(OverrideFile_Args) returns (OverrideFile_Result); - - rpc GetSchemaType(GetSchemaType_Args) returns(GetSchemaType_Result); - rpc GetSchemaTypeMapping(GetSchemaTypeMapping_Args) returns(GetSchemaTypeMapping_Result); - rpc ValidateCode(ValidateCode_Args) returns(ValidateCode_Result); - - rpc ListDepFiles(ListDepFiles_Args) returns(ListDepFiles_Result); - rpc LoadSettingsFiles(LoadSettingsFiles_Args) returns(LoadSettingsFiles_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} - -message ParseFile_AST_Args { - string filename = 1; - string source_code = 2; -} -message ParseFile_AST_Result { - string ast_json = 1; // json value - KclError kcl_err = 2; -} - -message ParseProgram_AST_Args { - repeated string k_filename_list = 1; -} -message ParseProgram_AST_Result { - string ast_json = 1; // json value - KclError kcl_err = 2; -} - -message ExecProgram_Args { - string work_dir = 1; - - repeated string k_filename_list = 2; - repeated string k_code_list = 3; - - repeated CmdArgSpec args = 4; - repeated CmdOverrideSpec overrides = 5; - - bool disable_yaml_result = 6; - - bool print_override_ast = 7; - - // -r --strict-range-check - bool strict_range_check = 8; - - // -n --disable-none - bool disable_none = 9; - // -v --verbose - int32 verbose = 10; - - // -d --debug - int32 debug = 11; - - // yaml/json: sort keys - bool sort_keys = 12; - // include schema type path in JSON/YAML result - bool include_schema_type_path = 13; -} -message ExecProgram_Result { - string json_result = 1; - string yaml_result = 2; - - string escaped_time = 101; -} - -message ResetPlugin_Args { - string plugin_root = 1; -} -message ResetPlugin_Result { - // empty -} - -message FormatCode_Args { - string source = 1; -} - -message FormatCode_Result { - bytes formatted = 1; -} - -message FormatPath_Args { - string path = 1; -} - -message FormatPath_Result { - repeated string changed_paths = 1; -} - -message LintPath_Args { - repeated string paths = 1; -} - -message LintPath_Result { - repeated string results = 1; -} - -message OverrideFile_Args { - string file = 1; - repeated string specs = 2; - repeated string import_paths = 3; -} - -message OverrideFile_Result { - bool result = 1; -} - -message EvalCode_Args { - string code = 1; -} -message EvalCode_Result { - string json_result = 2; -} - -message ResolveCode_Args { - string code = 1; -} - -message ResolveCode_Result { - bool success = 1; -} - -message GetSchemaType_Args { - string file = 1; - string code = 2; - string schema_name = 3; -} -message GetSchemaType_Result { - repeated KclType schema_type_list = 1; -} - -message GetSchemaTypeMapping_Args { - string file = 1; - string code = 2; - string schema_name = 3; -} -message GetSchemaTypeMapping_Result { - map schema_type_mapping = 1; -} - -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} - -message ValidateCode_Result { - bool success = 1; - string err_message = 2; -} - -message Position { - int64 line = 1; - int64 column = 2; - string filename = 3; -} - -message ListDepFiles_Args { - string work_dir = 1; - bool use_abs_path = 2; - bool include_all = 3; - bool use_fast_parser = 4; -} - -message ListDepFiles_Result { - string pkgroot = 1; - string pkgpath = 2; - repeated string files = 3; -} - -// --------------------------------------------------------------------------------- -// LoadSettingsFiles API -// Input work dir and setting files and return the merged kcl singleton config. -// --------------------------------------------------------------------------------- - -message LoadSettingsFiles_Args { - string work_dir = 1; - repeated string files = 2; -} - -message LoadSettingsFiles_Result { - CliConfig kcl_cli_configs = 1; - repeated KeyValuePair kcl_options = 2; -} - -message CliConfig { - repeated string files = 1; - string output = 2; - repeated string overrides = 3; - repeated string path_selector = 4; - bool strict_range_check = 5; - bool disable_none = 6; - int64 verbose = 7; - bool debug = 8; -} - -message KeyValuePair { - string key = 1; - string value = 2; -} - -// ---------------------------------------------------------------------------- -// JSON Schema Lit -// ---------------------------------------------------------------------------- - -message KclType { - string type = 1; // schema, dict, list, str, int, float, bool, any, union, number_multiplier - repeated KclType union_types = 2 ; // union types - string default = 3; // default value - - string schema_name = 4; // schema name - string schema_doc = 5; // schema doc - map properties = 6; // schema properties - repeated string required = 7; // required schema properties, [property_name1, property_name2] - - KclType key = 8; // dict key type - KclType item = 9; // dict/list item type - - int32 line = 10; - - repeated Decorator decorators = 11; // schema decorators -} - -message Decorator { - string name = 1; - repeated string arguments = 2; - map keywords = 3; -} - -// ---------------------------------------------------------------------------- -// END -// ---------------------------------------------------------------------------- -``` diff --git a/versioned_docs/version-0.5.2/tools/Ide/index.md b/versioned_docs/version-0.5.2/tools/Ide/index.md deleted file mode 100644 index aec7245a..00000000 --- a/versioned_docs/version-0.5.2/tools/Ide/index.md +++ /dev/null @@ -1,6 +0,0 @@ -# IDE - -We have provided two simple kinds of plugins for KCL. You can get more help information at the following link: - -- IntelliJ Plugin: https://github.com/kcl-lang/intellij-kcl -- VSCode Plugin: https://github.com/kcl-lang/vscode-kcl diff --git a/versioned_docs/version-0.5.2/tools/Ide/intellij.md b/versioned_docs/version-0.5.2/tools/Ide/intellij.md deleted file mode 100644 index be637514..00000000 --- a/versioned_docs/version-0.5.2/tools/Ide/intellij.md +++ /dev/null @@ -1,3 +0,0 @@ -# IntelliJ IDEA - -- IntelliJ Plugin: https://github.com/kcl-lang/intellij-kcl diff --git a/versioned_docs/version-0.5.2/tools/Ide/vs-code.md b/versioned_docs/version-0.5.2/tools/Ide/vs-code.md deleted file mode 100644 index 6b00815c..00000000 --- a/versioned_docs/version-0.5.2/tools/Ide/vs-code.md +++ /dev/null @@ -1,55 +0,0 @@ -# KCL Extension for Visual Studio Code - -## Quick Start - -- **Step 1.** [Install KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) on your system. Please check that `kcl` and `kcl-language-server` are installed and have been added to your PATH: - - ```bash - which kcl - which kcl-language-server - ``` - -- **Step 2.** Install the [KCL extension](https://marketplace.visualstudio.com/items?itemName=kcl.kcl-vscode-extension) for Visual Studio Code. This extension requires the VS Code 1.50+. -- **Step 3.** Reopen VS Code and create a KCL file and begin your KCL tour! - -## Features - -This extension provides some coding assistance, including the following features: - -- **Syntax Highlight:** - ![Highlight](/img/docs/tools/Ide/vs-code/Highlight.png) -- **Goto Definition:** Goto definition of schema, variable, schema attribute, and import pkg. - ![Goto Definition](/img/docs/tools/Ide/vs-code/GotoDef.gif) -- **Completion:** Keywords completions and dot(`.`) completion. - ![Completion](/img/docs/tools/Ide/vs-code/Completion.gif) -- **Outline:** Main definition(schema def) and variables in KCL file. - ![Outline](/img/docs/tools/Ide/vs-code/Outline.gif) -- **Hover:** Identifier information (type and schema documentation). - ![Hover](/img/docs/tools/Ide/vs-code/Hover.gif) -- **Diagnostics:** Warnings and errors in KCL file. - - > Tips: You can enhance the effect of diagnostics by installing another plugin: [Error Lens](https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens). - - ![Diagnostics](/img/docs/tools/Ide/vs-code/Diagnostics.gif) - -Other useful features such as refactoring and testing are in development. - -## Dependencies - -We recommend that you use the latest version of KCL, but the minimum required version for this extension is 0.4.6. If you are using an earlier version, the extension may not work properly. - -## Known Issues - -See [here](https://github.com/kcl-lang/kcl/issues/524). - -## Ask for help - -If the extension isn't working as you expect, please contact us with [community](https://kcl-lang.io/docs/community/intro/support) for help. - -## Contributing - -We are working actively on improving the KCL development on VS Code. All kinds of contributions are welcomed. You can refer to our [contribution guide](https://kcl-lang.io/docs/community/contribute). It introduces how to build and run the extension locally, and describes the process of sending a contribution. - -## License - -Apache License 2.0 diff --git a/versioned_docs/version-0.5.2/tools/cli/kcl/docgen.md b/versioned_docs/version-0.5.2/tools/cli/kcl/docgen.md deleted file mode 100644 index ca647228..00000000 --- a/versioned_docs/version-0.5.2/tools/cli/kcl/docgen.md +++ /dev/null @@ -1,317 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Docgen - -The KCL Docgen tool supports extracting model documents from KCL source code and supports multiple output formats: JSON, YAML and Markdown. This article introduces the document specification of the KCL language, gives an example of how to use the KCL Docgen tool to extract documents, and shows the process of importing localization documents. - -## 1. Document Specification of KCL - -The documentation of the KCL file mainly contains the following two parts: - -- Current KCL Module document: description of the current KCL file -- All schema documents contained in the KCL file: a description of the current schema, including schema description, schema attribute descriptions, and Examples. The specific format is as follows: - -1. Schema description - -```python -"""This is a brief description of the Schema -""" -``` - -2. Description of each attribute of Schema: including attribute description, attribute type, default value, optional or required - -```python -""" -Attributes ----------- -x : type, default is a, optional. - Description of parameter `x`. -y : type, default is b, required. - Description of parameter `y`. -""" -``` - -`----------` indicates that `Attributes` is a title (the length of the symbol `-` is the same as the length of the title), the attribute name and attribute type are separated by a colon `:`, the description of the attribute is written on another line with indentation. The default value of the attribute is separated by a comma `,` after the attribute type, and it is written in the form of `default is {default value}`. In addition, it is necessary to indicate whether the attribute is optional/required. Write `optional` after the default value for an optional attribute, and write `required` after the default value for a required attribute. - -3. Examples - -```python -""" -Examples --------- -val = Schema { - name = "Alice" - age = 18 -} -""" -``` - -In addition, the KCL docstring syntax should use a subset of the [re-structured text (reST)](https://docutils.sourceforge.io/rst.html) and be rendered using the [Sphinx](https://www.sphinx-doc.org/en/master/). - -## 2. Generating Documentation From KCL - -Use the `kcl-doc generate` command to extract documentation from a user-specified file or directory and output it to the specified directory. - -1. Args - -``` -usage: kcl-doc generate [-h] [--format YAML] [-o OUTPUT] [--r] - [--i18n-locale LOCALE] [--repo-url REPO_URL] - [files [files ...]] - -positional arguments: - files KCL file paths. If there's more than one files to - generate, separate them by space - -optional arguments: - -h, --help show this help message and exit - --format YAML Doc file format, support YAML, JSON and MARKDOWN. - Defaults to MARKDOWN - -o OUTPUT, --output-path OUTPUT - Specify the output directory. Defaults to ./kcl_doc - --r, -R, --recursive Search directory recursively - --i18n-locale LOCALE I18n locale, e.g.: zh, zh_cn, en, en_AS. Defaults to - en - --repo-url REPO_URL The source code repository url. It will be displayed in - the generated doc to link to the source code. -``` - -2. Extract documents from the file(s) and output them to the specified directory - -```text -kcl-doc generate your_config.k your_another_config.k -o your_docs_output_dir -``` - -3. From the specified directory, recursively find the KCL file(s) and extract the documentation - -```text -kcl-doc generate your_config_dir -r -o your_docs_output_dir -``` - -4. When generating documentation, specify the source code repository address. The generated documentation will contain links to source files - -```text -kcl-doc generate your_config.k -o your_docs_output_dir --repo-url https://url/to/source_code -``` - -## 3. Add Documentation for Localized Languages - -As shown before, by default, the documentation extracted by the documentation generation tool is based on the content of the source docstring, and thus the language of the documentation depends on the language in which the docstring was written. If you need to add localized language documentation to the source file, you can follow the steps below: - -1. Initialize the i18n configuration file. This step generates the corresponding i18n configuration file based on the specified KCL file. The file format can be JSON/YAML, and the default is YAML. The output profile name will end in the specified target localization language - -```text -kcl-doc init-i18n your_config.k --format JSON --i18n-locale your_target_locale -``` - -2. Modify the i18n configuration file and update each doc field in your locale language - -3. Generate localized documents from the modified i18n configuration file - -```text -kcl-doc generate your_config_dir --i18n-locale your_target_locale --format Markdown -``` - -Next, a simple example is used to demonstrate the process of adding localized language documents. - -3.1 Prepare the KCL file, such as `server.k`: - - ```python - schema Server: - """Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - - Attributes - ---------- - workloadType : str, default is "Deployment", required - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - name : str, required - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - labels : {str:str}, optional - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - - Examples - ---------------------- - myCustomApp = AppConfiguration { - name = "componentName" - } - """ - - workloadType: str = "Deployment" - name: str - labels?: {str: str} - ``` - -3.2 Get the initialized i18n configuration file from the `server.k`. For example, if you want to add Chinese documents to it, specify the format of the generated configuration file as YAML - - ```text - kcl-doc init-i18n server.k --format YAML --i18n-locale zh_cn - ``` - - This command will create the directory `kcl_doc` under the current directory and generate the i18n configuration file `kcl_doc/i18n_server_zh_cn.yaml`. Its contents are as follows: - - ```yaml - name: server - relative_path: ./server.k - schemas: - - name: Server - doc: | - Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - attributes: - - name: workloadType - doc: | - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - default_value: '"Deployment"' - is_optional: false - - name: name - doc: | - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: false - default_value: '' - - name: labels - doc: | - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - type: - type_str: '{str: str}' - type_category: DICT - dict_type: - key_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - value_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: true - default_value: '' - examples: | - myCustomApp = AppConfiguration { - name = "componentName" - } - doc: '' - source_code_url: '' - ``` - -3.3 Modify all the `doc` fields to the Chinese description. The modified configuration is as follows: - - ```yaml - name: server - relative_path: ./server.k - schemas: - - name: Server - doc: | - Server 模型定义了采用 Kubernetes 最佳实践的持续运行的服务的通用配置接口 - attributes: - - name: workloadType - doc: | - workloadType 属性定义了服务的类型,是服务级别的属性。合法的取值有:Deployment, CafeDeployment. - 另请查看:k8s/core/v1/workload_metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - default_value: '"Deployment"' - is_optional: false - - name: name - doc: | - name 为服务的名称,是服务级别的属性。 - 另请查看:k8s/core/v1/metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: false - default_value: '' - - name: labels - doc: | - labels 为服务的标签,是服务级别的属性。 - 另请查看:k8s/core/v1/metadata.k. - type: - type_str: '{str: str}' - type_category: DICT - dict_type: - key_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - value_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: true - default_value: '' - examples: | - myCustomApp = AppConfiguration { - name = "componentName" - } - doc: '' - source_code_url: '' - ``` - -3.4 Based on the modified i18n configuration, generate documents in localized languages. Execute the following command to output the Chinese document `kcl_doc/doc_server_zh_cn.md`. The commands and the contents of the generated documents are as follows: - -```text -kcl-doc generate server.k --i18n-locale zh_cn --format Markdown -``` - -````markdown -# server - -## Schema Server - -Server 模型定义了采用 Kubernetes 最佳实践的持续运行的服务的通用配置接口 - -### Attributes - -| Name and Description | Type | Default Value | Required | -| -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | ------------- | ------------ | -| **workloadType**
workloadType 属性定义了服务的类型,是服务级别的属性。合法的取值有:Deployment, CafeDeployment.
另请查看:k8s/core/v1/workload_metadata.k. | str | "Deployment" | **required** | -| **name**
name 为服务的名称,是服务级别的属性。
另请查看:k8s/core/v1/metadata.k. | str | Undefined | **required** | -| **labels**
labels 为服务的标签,是服务级别的属性。
另请查看:k8s/core/v1/metadata.k. | {str: str} | Undefined | optional | - -### Examples - -``` -myCustomApp = AppConfiguration { - name = "componentName" -} -``` - - -```` - -## 4. Appendix - -### 1. Concept of reST - -For documents in reST format, paragraphs and indentation are important, new paragraphs are marked with blank lines, and indentation is the indentation indicated in the output. Font styles can be expressed as follows: - -- \*Italic\* -- \*\*Bold\*\* -- \`\`Monospaced\`\` - -Refer to [reST](https://docutils.sourceforge.io/rst.html) for more information. diff --git a/versioned_docs/version-0.5.2/tools/cli/kcl/fmt.md b/versioned_docs/version-0.5.2/tools/cli/kcl/fmt.md deleted file mode 100644 index eaf562cd..00000000 --- a/versioned_docs/version-0.5.2/tools/cli/kcl/fmt.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Format - -The KCL Format tool supports reformatting KCL files to the standard code style. This article demonstrates the KCL code style and how to use the KCL Format tool. - -## Code Style - -The KCL Format tool modifies the files according to the KCL code style: [Style Guide for KCL Code](/docs/reference/lang/spec/codestyle) - -## How to use - -- Formatting Single File - -```text -kcl-fmt your_config.k -``` - -- Formatting multiple files - -```text -kcl-fmt your_config_path -R -``` - -- Args - - `-R|--recursive` Whether to recursively traverse subfolders - - `-w|--fmt-output` Whether to output to STDOUT, without `-w` indicates in-place modification. - -## Display of formatting files - -- Before formatting - -```py -import math -mixin DeploymentMixin: - service:str ="my-service" -schema DeploymentBase: - name: str - image : str -schema Deployment[replicas] ( DeploymentBase ) : - mixin[DeploymentMixin] - replicas : int = replicas - command: [str ] - labels: {str: str} -deploy = Deployment(replicas = 3){} -``` - -- After formatting - -```py -import math - -mixin DeploymentMixin: - service: str = "my-service" - -schema DeploymentBase: - name: str - image: str - -schema Deployment[replicas](DeploymentBase): - mixin [DeploymentMixin] - replicas: int = replicas - command: [str] - labels: {str:str} - -deploy = Deployment(replicas=3) {} - -``` diff --git a/versioned_docs/version-0.5.2/tools/cli/kcl/index.md b/versioned_docs/version-0.5.2/tools/cli/kcl/index.md deleted file mode 100644 index b750f652..00000000 --- a/versioned_docs/version-0.5.2/tools/cli/kcl/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# KCL Language Tools - -KCL not only provides the command `kcl` to compile and execute configuration programs but also provides fmt, lint, test, vet, docgen and other supporting tools. diff --git a/versioned_docs/version-0.5.2/tools/cli/kcl/lint.md b/versioned_docs/version-0.5.2/tools/cli/kcl/lint.md deleted file mode 100644 index 627177a9..00000000 --- a/versioned_docs/version-0.5.2/tools/cli/kcl/lint.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Lint - -The KCL Lint tool supports checking some warning-level defects in KCL code and supports multiple output formats. This document shows how to use the KCL Lint tool. - -## Example - -### Project Struct - -```text -. -└── Test - └── kcl.mod - └── a.k - └── b.k - └── dir - └── c.k - └── test.k -``` - -`a.k`, `b.k`, `c.k` and `test.k` are the kcl file to be checked. - -Args: - -```shell -kcl-lint your_config.k -``` - -or - -```shell -kcl-lint your_config_path -``` - -## KCL Lint Tool - -### Args - -```shell -USAGE: - kcl-lint [OPTIONS] [--] [input]... - -ARGS: - ... Sets the input file to use - -OPTIONS: - --emit_warning Emit warning message - -h, --help Print help information - -v, --verbose Print test information verbosely - -Y, --setting ... Sets the input file to use -``` - -- input: the path of a single `*.k` file or directory to be checked. Support the absolute path or relative path of the current directory. diff --git a/versioned_docs/version-0.5.2/tools/cli/kcl/test.md b/versioned_docs/version-0.5.2/tools/cli/kcl/test.md deleted file mode 100644 index 4f99e53d..00000000 --- a/versioned_docs/version-0.5.2/tools/cli/kcl/test.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Test Tool - -Coming soon. diff --git a/versioned_docs/version-0.5.2/tools/cli/kcl/vet.md b/versioned_docs/version-0.5.2/tools/cli/kcl/vet.md deleted file mode 100644 index d2f2220e..00000000 --- a/versioned_docs/version-0.5.2/tools/cli/kcl/vet.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Validation - -## Intro - -The KCL Validation tool supports basic configuration data verification capabilities. You can write a KCL schema to verify the type and value of the input JSON/YAML files. - -## How to use - -There is a JSON format file `data.json`: - -```json -{ - "name": "Alice", - "age": 18, - "message": "This is Alice", - "data": { - "id": 1, - "value": "value1" - }, - "labels": { - "key": "value" - }, - "hc": [1, 2, 3] -} -``` - -Build a validated KCL file `schema.k`: - -```py -schema User: - name: str - age: int - message?: str - data: Data - labels: {str:} - hc: [int] - - check: - age > 10 - -schema Data: - id: int - value: str -``` - -Execute the following command: - -```shell -kcl-vet data.json schema.k -``` - -## Specify the schema for validation - -When multiple schema definitions exist in the KCL file, by default, the KCL Validation tool will use the first schema to check. If you need to specify a schema for verification, you can use the `-d|--schema` parameter - -```shell -kcl-vet data.json schema.k -d User -``` - -## Args - -```shell -$ kcl-vet -h -USAGE: - kcl-vet [OPTIONS] [ARGS] - -ARGS: - Validation data file - KCL file - -OPTIONS: - -d, --schema - Iterate through subdirectories recursively - - --format - Validation data file format, support YAML and JSON, default is JSON - - -h, --help - Print help information - - -n, --attribute_name - The attribute name for the data loading -``` diff --git a/versioned_docs/version-0.5.2/tools/cli/openapi/crd-to-kcl.md b/versioned_docs/version-0.5.2/tools/cli/openapi/crd-to-kcl.md deleted file mode 100644 index aafebcd9..00000000 --- a/versioned_docs/version-0.5.2/tools/cli/openapi/crd-to-kcl.md +++ /dev/null @@ -1,118 +0,0 @@ -# CRD to KCL - -To convert from models defined in the Kubernetes CRD file to KCL schema, we could run the following script: - -```shell -kcl-openapi generate model --crd -f ${your_CRD.yaml} -t ${the_kcl_files_output_dir} --skip-validation -``` - -## Example - -- There is the Kubernetes CRD file that we need to convert: `test_crontab_CRD.yaml`: - -```yaml -# Deprecated in v1.16 in favor of apiextensions.k8s.io/v1 -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - # name must match the spec fields below, and be in the form: . - name: crontabs.stable.example.com -spec: - # group name to use for REST API: /apis// - group: stable.example.com - # list of versions supported by this CustomResourceDefinition - versions: - - name: v1 - # Each version can be enabled/disabled by Served flag. - served: true - # One and only one version must be marked as the storage version. - storage: true - # either Namespaced or Cluster - scope: Namespaced - names: - # plural name to be used in the URL: /apis/// - plural: crontabs - # singular name to be used as an alias on the CLI and for display - singular: crontab - # kind is normally the CamelCased singular type. Your resource manifests use this. - kind: CronTab - # shortNames allow shorter string to match your resource on the CLI - shortNames: - - ct - preserveUnknownFields: false - validation: - openAPIV3Schema: - type: object - properties: - spec: - type: object - properties: - cronSpec: - type: string - image: - type: string - replicas: - type: integer -``` - -- The script will be: - -```shell -kcl-openapi generate model -f test_crontab_CRD.yaml -t ~/ --skip-validation --crd -``` - -- Then we can find the generated file here: `~/models/stable_example_com_v1_cron_tab.k` - -```python -""" -This file was generated by the KCL auto-gen tool. DO NOT EDIT. -Editing this file might prove futile when you re-run the KCL auto-gen generate command. -""" -import kusion_kubernetes.apimachinery.apis - - -schema CronTab: - """stable example com v1 cron tab - - Attributes - ---------- - apiVersion : str, default is "stable.example.com/v1", required - APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - kind : str, default is "CronTab", required - Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - metadata : apis.ObjectMeta, default is Undefined, optional - metadata - spec : StableExampleComV1CronTabSpec, default is Undefined, optional - spec - """ - - - apiVersion: "stable.example.com/v1" = "stable.example.com/v1" - - kind: "CronTab" = "CronTab" - - metadata?: apis.ObjectMeta - - spec?: StableExampleComV1CronTabSpec - - -schema StableExampleComV1CronTabSpec: - """stable example com v1 cron tab spec - - Attributes - ---------- - cronSpec : str, default is Undefined, optional - cron spec - image : str, default is Undefined, optional - image - replicas : int, default is Undefined, optional - replicas - """ - - - cronSpec?: str - - image?: str - - replicas?: int -``` diff --git a/versioned_docs/version-0.5.2/tools/cli/openapi/openapi-to-kcl.md b/versioned_docs/version-0.5.2/tools/cli/openapi/openapi-to-kcl.md deleted file mode 100644 index bef582ec..00000000 --- a/versioned_docs/version-0.5.2/tools/cli/openapi/openapi-to-kcl.md +++ /dev/null @@ -1,64 +0,0 @@ -# OpenAPI to KCL - -To convert from models defined in the OpenAPI spec file to KCL schema, we could run the following script: - -```shell -kcl-openapi generate model -f ${your_open_api_spec.yaml} -t ${the_kcl_files_output_dir} -``` - -For example: - -- There is the OpenAPI spec file that we need to convert: `test_open_api_spec.yaml` - -```yaml -definitions: - v1.TestInt: - type: object - properties: - name: - type: string - format: int-or-string - required: - - name - x-kcl-type: - import: - package: v1.test_int - alias: test_int - type: TestInt -swagger: "2.0" -info: - title: KCL - version: v0.0.2 -paths: {} -``` - -- The script will be: - -```shell -kcl-openapi generate model -f test_open_api_spec.yaml -t ~/ --skip-validation -``` - -- Then we can find the generated file here: `~/models/v1/test_int.k` - -```python -""" -This is the test_int module in v1 package. -This file was generated by the KCL auto-gen tool. DO NOT EDIT. -Editing this file might prove futile when you re-run the KCL auto-gen generate command. -""" - - -schema TestInt: - """v1 test int - - Attributes - ---------- - name : int | str, default is Undefined, required - name - """ - - - name: int | str - - -``` diff --git a/versioned_docs/version-0.5.2/tools/cli/openapi/quick-start.md b/versioned_docs/version-0.5.2/tools/cli/openapi/quick-start.md deleted file mode 100644 index d5812e3a..00000000 --- a/versioned_docs/version-0.5.2/tools/cli/openapi/quick-start.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Quick Start - -## 1. Install KCLOpenAPI Tool - -The kcl-openapi tool can be installed in following ways: - -- [go install](#11-go-install) -- [curl|sh install (MacOS & Linux)](#12-curlsh-install-macos--linux) -- [download from release](#13-dowload-from-release) - -## 1.1 go install - -```shell -go install kcl-lang.io/kcl-openapi@latest -``` - -## 1.2 Curl|sh install (MacOS & Linux) - -If you don't have go, you can install the CLI with this one-liner: - -```shell -curl -fsSL https://kcl-lang.io/script/install-kcl-openapi.sh | /bin/bash -``` - -## 1.3 Download from release - -```shell -# 1. download the released binary from: -# https://github.com/kcl-lang/kcl-openapi/releases - -# 2. Unzip the package and add the binary location to PATH -export PATH=":$PATH" -``` - -## 1.4 Verify your installation - -```shell -➜ kcl-openapi -v -kcl-openapi 0.5.0 -``` - -## 2. Generate KCL Files - -- [OpenAPI to KCL](../openapi/openapi-to-kcl.md) -- [CRD to KCL](../openapi/crd-to-kcl.md) diff --git a/versioned_docs/version-0.5.2/tools/cli/openapi/spec.md b/versioned_docs/version-0.5.2/tools/cli/openapi/spec.md deleted file mode 100644 index 7a144e4c..00000000 --- a/versioned_docs/version-0.5.2/tools/cli/openapi/spec.md +++ /dev/null @@ -1,438 +0,0 @@ -# KCL OpenAPI Spec - -[OpenAPI](https://www.openapis.org/) defines the API Specification for API providers to describe their operations and models in a normative way and provides generating tools to automatically convert to client codes in specific languages. - -The KCL OpenAPI Spec describes the rules about how the OpenAPI definitions are translated to the KCL schemas. - -## The File Structure of the KCL OpenAPI - -According to the OpenAPI 3.0 specification, an OpenAPI file should at least contains four root objects: `openapi`, `components`, `info`, `paths`. The KCL OpenAPI focuses on the part in which the models are defined in the `definitions` object. Yet the `paths` part which describes the Restful API operations is not considered by the KCL OpenAPI Spec. - -:::info -Note: In addition to the objects listed above, the OpenAPI spec also supports `servers`, `security`, `tags`, and `externalDocs` as optional root objects, but none of them are concerned by KCL OpenAPI when generating model codes, so we do not need to fill in this section. Yet it won't make any difference if you do. -::: - -To put it more comprehensible for beginners, let's take a quick look at the root objects that forms the typical KCL OpenAPI file (snippets from swagger example [Petstore](https://petstore.swagger.io/). The KCL OpenAPI tool only focuses on the `definitions` object which describes two data models (`Pet` and `Category`), and the model `Pet` contains three attributes: `name`, `id`, and `category`) - -## KCL schema - -The KCL schema structure defines the "type" of configuration data. - -:::info -More information about KCL schema, see [KCL Language Tour#Schema](../../../reference/lang/tour.md) -::: - -In the OpenAPI spec, a KCL schema can be defined by adding a `definition` element within the `definitions` object. - -Example: -The following example defines two schemas in KCL: `Pet` and `Category`, followed by the corresponding data models defined in OpenAPI: - -```python -# KCL schema -schema Pet: - name: str - id?: int - category?: Category - -schema Category: - name?: str - -# The corresponding OpenAPI spec -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "id": { - "type": "integer", - "format": "int64" - }, - "category": { - "$ref": "#/definitions/Category" - } - }, - "required": [ - "name" - ] - }, - "Category": { - "type": "object", - "properties": { - "name": { - "type": "string" - } - } - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### Schema Name - -In KCL, the schema name is declared immediately after the schema keyword, and in OpenAPI, the name of the model is defined by the key of the definition element. - -### Schema Type - -The type of KCL schema in OpenAPI is always "object". As in the previous example, the value of the `type` object in `Pet` should be `object`. - -### Schema Attribute - -Zero or more attributes can be defined in the KCL schema. The declaration of attributes generally includes the following parts: - -- Attribute annotation: Optional, starting with `@`, such as `@deprecated` to indicate a deprecated attribute -- Attribute name: Required -- Attribute optional modifiers(`?`): Optional. A question mark indicates that the current attribute is optional and may not be assigned. Conversely, the absence of a question mark indicates a required attribute -- Attribute type: Required. The attribute can be a primitive data type, a schema type, or a combination of the two preceding types -- Attribute default value: Optional - -The mapping between them and the OpenAPI spec is as follows: - -| Elements of KCL Schema Attribute | Corresponding Elements in OpenAPI | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| attribute annotation | Not supported. We are planning to add an extension `deprecate` field to the KCL-OpenAPI | -| attribute name | The key of the property under the `property` object | -| attribute optional modifiers(`?`) | In each element in the `definition` object, here's an optional `required` field which lists the all the required attributes of that model, and the attributes not listed are optional | -| attribute type | The basic types can be declared by a combination of `type` and `format`, and the schema type is declared by a `$ref` to the schema definition. KCL-OpenAPI spec adds a `x-kcl-types` extension to indicate a type union. `enum` indicates a union of several literal types. For the type declaration in KCL-OpenAPI, see the chapter - [basic data types](#basic-data-types) | -| attribute default value | The value of the `default` field is used to set the default value for the attribute | - -Example: - -The following KCL code defines a Pet model which contains two attributes: name (`string` type, `required`, with no attribute annotation and no default value) and id (`int64` type, optional, with no attribute annotation, and the default value is -1). - -```python -# the KCL schema Pet defines two attributes: name, id -schema Pet: - name: str - id?: int = -1 - -# The corresponding OpenAPI spec -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - "id": { - "type": "integer", - "format": "int64", - "default": -1 - } - }, - "required": [ - "name" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### Schema Index Signature - -In the KCL schema, the index signatures can be used to define attributes with undefined attribute names. The KCL schema index signature contains the following elements: - -- Type of the key in the index signature: Declared in square brackets. It must be the basic type -- Type of value in the index signature: Declared after the colon in the square brackets. It can be any valid KCL type -- Ellipses(`...`) in the index signature: In the square brackets, before the type declaration of the key. It indicates that the index signature is only used to constrain attributes not defined in the schema. The absentation of the symbol indicates that all defined and undefined attributes in the schema are constrained by the index signature. -- Alias for key in index signature: Declared in square brackets, immediately after the left square bracket and takes the form of `:`. The alias can then be used to reference the index signature by name -- The default value of the index signature: Assign a value to the index signature as the default value - -The index signature with its key in `string` type can be described based on the field `additionalProperties`. Other index signatures with a key in types besides `string`, and the `check` expressions used to validate the index signature are not supported by the KCL OpenAPI spec. - -The mapping between them and the OpenAPI spec is as follows: - -| Elements of KCL Index Signature | Corresponding Elements in OpenAPI | -| -------------------------------------------- | ----------------------------------------------------------------------------------------------- | -| Type of the key in the KCL index signature | Only string type is allowed in OpenAPI | -| Type of the value in the KCL index signature | Declared by the `type` in the `additionalProperties` field | -| Ellipses(`...`) in the index signature | Only the corresponding meaning of the attendance of the `...` symbol is allowed in OpenAPI | -| Alias for key in index signature | Not supported in KCL-OpenAPI yet. We are planning to add an `x-alias` extension to support that | -| Default value of the index signature | Not supported in KCL-OpenAPI | - -Example: - -The following KCL code defines a Pet model which contains two pre-declared attributes(`name` and `id`) and allows users to add attributes with `string` type keys and `bool` type values. - -```python -# the KCL schema Pet. Besides the pre-declared attributes name and id, it allows to add attributes with key in string type and value in bool type -schema Pet: - name: str - id?: int - [...str]: bool - -# The corresponding OpenAPI spec -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - "id": { - "type": "integer", - "format": "int64", - } - }, - "additionalProperties": { - "type": "bool" - }, - "required": [ - "name" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### Schema Inherit - -working in progress - -### Inline schema - -OpenAPI supports models to be declared inline. But KCL currently does not support that. The model defined inline in OpenAPI will be converted to a schema with a name in KCL. And the naming convention will be: - -| element to define an inline schema in OpenAPI | the name of the corresponding KCL schema | -| --------------------------------------------- | -------------------------------------------------------------- | -| inline Property | add the Property name at the end of the outer schema Name | -| AdditionalProperties | add "AdditionalProperties" at the end of the outer schema Name | - -We are planning to support inline schema in KCL, and when supported, the naming convention will be updated then. - -Example-1: - -The following KCL code defines a `Deployment` model which contains two attributes(`kind` and `spec`). And the schema of the `spec` attribute is defined inline. - -```python -# The OpenAPI spec -{ - "definitions": { - "Deployment": { - "type": "object", - "properties": { - "kind": { - "type": "string", - }, - "spec": { - "type": "object", - "properties": { - "replicas": { - "type": "integer", - "format": "int64" - } - } - } - }, - "required": [ - "kind", - "spec" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -# The corresponding KCL schemas -schema Deployment: - kind: str - spec: DeploymentSpec - -schema DeploymentSpec: - replicas?: int -``` - -Example-2: - -The following KCL code defines a Person model which contains a pre-declared attribute(`name`) and allows some `additionalProperties` to be assigned by user. And the type of the values in the `additionalProperties` is defined inline. - -```python -# The OpenAPI spec -{ - "definitions": { - "Person": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - }, - "required": [ - "name", - "spec" - ], - "additionalProperties": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "description": { - "type": "string" - } - }, - "required": [ - "name" - ] - }, - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -# The corresponding KCL schemas -schema Person: - name: str - [...str]: [PersonAdditionalProperties] - -schema PersonAdditionalProperties: - name: str - description?: str -``` - -## KCL Doc - -:::info -More information about KCL doc specification, please refer to the [KCL Document Specification](../kcl/docgen.md) -::: - -KCL documents consist of module documents and schema documents. And only the schema documents can be extracted from OpenAPI. The KCL schema document contains four parts: - -- Schema Description: Declared right after the schema declaration and before the schema attribute declaration. It provides an overview of schemas -- Schema Attribute Doc: Declared right after the schema Description and separated by `Attributes` + `---` delimiters. It describes the attribute -- Additional information about the schema: Declared right after the schema attribute doc and separated by `See Also` + `---` delimiters -- Example information about the schema: Declared right after the schema additional information and separated by `Examples` + `---` delimiters - -The mapping between them and the OpenAPI spec is as follows: - -| Elements of KCL Schema Document | Corresponding Elements in OpenAPI | -| --------------------------------------- | ------------------------------------------------------- | -| Schema Description | The value of the `description` field of the data model | -| Schema Attribute Doc | The value of the `description` field of the property | -| Additional information about the schema | The value of the `externalDocs` field of the data model | -| Example information about the schema | The value of the `example` field of the data model | - -Example: - -The following KCL code defines a Pet model with a schema description `The schema Pet definition`, and two attributes `name` and `id` with their attribute doc `The name of the pet` and `The id of the pet`; The additional information about the Pet schema is [here](https://petstore.swagger.io/) and the example to use the Pet schema are provided, too. - -```python -# The KCL schema Pet, with doc following the KCL Document Specification -schema Pet: - """The schema Pet definition - - Attributes - ---------- - name : str, default is Undefined, required - The name of the pet - id : int, default is -1, optional - The age of the pet - - See Also - -------- - Find more info here. https://petstore.swagger.io/ - - Examples - -------- - pet = Pet { - name = "doggie" - id = 123 - } - """ - name: str - id?: int = -1 - -# The corresponding OpenAPI Spec -{ - "definitions": { - "Pet": { - "description": "The schema Pet definition", - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "The name of the pet" - }, - "id": { - "type": "integer", - "format": "int64", - "default": -1, - "description": "The age of the pet" - } - }, - "required": [ - "name" - ], - "externalDocs": { - "description": "Find more info here", - "url": "https://petstore.swagger.io/" - }, - "example": { - "name": "doggie", - "id": 123 - } - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -## Basic Data Types - -| JSON Schema type | swagger type | KCL type | comment | -| ---------------- | --------------------------- | --------------- | --------------------------------------------------------------------------- | -| boolean | boolean | bool | | -| number | number | float | | -| | number format double | **unsupported** | | -| | number format float | float | | -| integer | integer | int (32) | | -| | integer format int64 | **unsupported** | | -| | integer format int32 | int (32) | | -| string | string | str | | -| | string format byte | str | | -| | string format int-or-string | int \| str | | -| | string format binay | str | | -| | string format date | unsupported | As defined by full-date - [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) | -| | string format date-time | unsupported | As defined by date-time - [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) | -| | string format password | unsupported | for swagger: A hint to UIs to obscure input | -| | datetime | datetime | | - -## Reference - -- OpenAPI spec 2.0: [https://swagger.io/specification/v2/](https://swagger.io/specification/v2/) -- OpenAPI spec 3.0: [https://spec.openapis.org/oas/v3.1.0](https://spec.openapis.org/oas/v3.1.0) -- OpenAPI spec 3.0: [https://swagger.io/specification/](https://swagger.io/specification/) -- OpenAPI spec 2.0: [https://swagger.io/specification/v2/#schemaObject](https://swagger.io/specification/v2/#schemaObject) -- Go swagger: [https://goswagger.io/use/models/schemas.html](https://goswagger.io/use/models/schemas.html) -- Swagger data models: [https://swagger.io/docs/specification/data-models/](https://swagger.io/docs/specification/data-models/) diff --git a/versioned_docs/version-0.5.2/user_docs/concepts/concepts.md b/versioned_docs/version-0.5.2/user_docs/concepts/concepts.md deleted file mode 100644 index 627212ad..00000000 --- a/versioned_docs/version-0.5.2/user_docs/concepts/concepts.md +++ /dev/null @@ -1,3 +0,0 @@ -# Concepts - -Learn more about KCL concepts. diff --git a/versioned_docs/version-0.5.2/user_docs/getting-started/index.md b/versioned_docs/version-0.5.2/user_docs/getting-started/index.md deleted file mode 100644 index c50dbaa6..00000000 --- a/versioned_docs/version-0.5.2/user_docs/getting-started/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# Get Started - -Get started include a quick overview of the KCL programming language. diff --git a/versioned_docs/version-0.5.2/user_docs/getting-started/install.md b/versioned_docs/version-0.5.2/user_docs/getting-started/install.md deleted file mode 100644 index 261ab804..00000000 --- a/versioned_docs/version-0.5.2/user_docs/getting-started/install.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Installation - -## 1. Install KCL - -### From the Binary Releases - -Each release of KCL includes various OSes and architectures. These binary versions can be manually downloaded and installed from [Github](https://github.com/kcl-lang/kcl/releases/) or [Gitee](https://gitee.com/kusionstack/kcl/releases) and add `{install-location}/kclvm/bin` to the environment PATH. - -> ⚠️ If you cannot successfully access Github, you can also access Gitee to obtain binaries for installation. - -#### MacOS & Linux - -```bash -export PATH=$PATH:{install-location}/kclvm/bin -``` - -#### Windows - -```powershell -$env:PATH += ";{install-location}\kclvm\bin;" -``` - -### Using script to install the latest release - -#### MacOS - -Install or upgrade the latest darwin KCL to /usr/local/kclvm/bin - -```bash -curl -fsSL https://kcl-lang.io/script/install.sh | /bin/bash -``` - -#### Linux - -Install or upgrade the latest linux KCL to /usr/local/kclvm/bin - -```bash -wget -q https://kcl-lang.io/script/install.sh -O - | /bin/bash -``` - -#### Windows - -Install or upgrade the latest windows KCL to $Env:SystemDrive\kclvm\bin and add this directory to User PATH environment variable. - -```bash -powershell -Command "iwr -useb https://kcl-lang.io/script/install.ps1 | iex" -``` - -### Homebrew (MacOS) - -- Install - -```bash -brew install kcl-lang/tap/kcl -``` - -- Upgrade - -```bash -brew upgrade kcl-lang/tap/kcl -``` - -- Uninstall - -```bash -brew uninstall kcl-lang/tap/kcl -``` - -### Scoop (Windows) - -Install [Scoop](https://scoop.sh/) first, then add this bucket and install `kcl` by running: - -```bash -scoop bucket add kcl-lang https://github.com/kcl-lang/scoop-bucket.git -scoop install kcl-lang/kcl -``` - -### From Go - -Install `kcl` through the `Go` command (`Go` requires 1.18+). - -```bash -go install kcl-lang.io/kcl-go/cmds/kcl-go@main -``` - -Add an alias for the kcl command (optional). - -```bash -alias kcl='kcl-go run' -``` - -> Note: `kcl-go` does not rely on the installation of `kcl`, but if `kcl` exists in PATH, it will be used by `kcl-go` first. - -### From Docker - -- Command - -```bash -docker run --rm -it kcllang/kcl -``` - -- Update image - -```bash -docker pull kcllang/kcl -``` - -### Note - -We can execute the following command to ensure that KCL has been installed correctly. - -```bash -kcl -V -``` - -The output may looks like this: - -```bash -Version: {kcl version} -Platform: {your platform} -GitCommit: {git commit} -``` - -For all the above operating systems and installation methods, if you want to use [KCL Python Plugin](/docs/reference/plugin/overview), you need to ensure that Python 3.7+ is installed and add the python3 command to your PATH environment variable. - -## 2. Install KCL IDE Extension - -### VS Code - -The KCL Extension extension provides some coding assistance, e.g., highlight, goto definition, completion, hover, outline, and diagnostics. You can go [here](/docs/tools/Ide/vs-code) for more information about the installation. - -![Completion](/img/docs/tools/Ide/vs-code/Completion.gif) - -### IntelliJ IDEA - -Download the distribution from [here](https://github.com/kcl-lang/intellij-kcl/releases) and in IntelliJ IDEA, click Preference -> plugins -> install Plugin from Disk... -> select kcl-idea-plugin zip -> restart IDE. This plugin requires the IntelliJ IDEA 2020.2+ diff --git a/versioned_docs/version-0.5.2/user_docs/getting-started/intro.md b/versioned_docs/version-0.5.2/user_docs/getting-started/intro.md deleted file mode 100644 index c4515840..00000000 --- a/versioned_docs/version-0.5.2/user_docs/getting-started/intro.md +++ /dev/null @@ -1,199 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Introduction - -## What is KCL? - -[KCL](https://github.com/kcl-lang/kcl) is an open-source, constraint-based record and functional language that enhances the writing of complex configurations, including those for cloud-native scenarios. With its advanced programming language technology and practices, KCL is dedicated to promoting better modularity, scalability, and stability for configurations. It enables simpler logic writing and offers ease of automation APIs and integration with homegrown systems. - -## Why Use KCL? - -KCL expects to solve the following problems: - -- Hide infrastructure and platform details by defining more appropriate **API abstractions** to reduce the burden of developers. -- **Mutate** and **validate** existing config files or manifests. -- Manage large-scale configuration data across teams without side effects through configuration language. - - Use **production level high-performance programming language** to **write code** to improve the flexibility of configuration, such as conditional statements, loops, functions, package management and other features to improve the ability of configuration reuse. - - Improve the ability of **configuration semantic verification** at the code level, such as optional/required fields, types, ranges, and other configuration checks. - - Provide the **ability to write, combine and abstract configuration blocks**, such as structure definition, structure inheritance, constraint definition, etc. - -You can use KCL to - -- **Generate** low-level static configuration data like JSON, YAML, etc. -- Reduce boilerplate in configuration data with the **schema modeling**. -- Define transformers and constraints for configuration data and templates and **mutate/validate** them automatically. -- Organize, simplify, unify and manage large configurations scalably without side effects. -- Used as a platform engineering language to deliver modern app with [KusionStack](https://kusionstack.io/). - -In addition to the language itself, KCL also provides many additional tools, such as formatting, testing, document, package management, to help users use, understand and check the configuration or policy they write. We can reduce the cost of configuration writing and sharing through IDE extensions such as VS Code, playground and package manage tools. In addition, through KCL Rust, Go, and Python multilingual SDKs, the configuration can be automatically managed and executed. - -![](/img/docs/user_docs/intro/kcl-overview.png) - -Besides, KCL is a modern high-level domain language, which is a compiled, static and strongly typed language. It provides developers with the ability to write **configuration (config)**, **modeling abstraction (schema)**, **logic (lambda)**, and **policies (rule)** as the core elements through recording and functional language design. - -![](/img/docs/user_docs/intro/kcl-concepts.png) - -KCL tries to provide runtime-independent programmability and does not natively provide system functions such as threads and IO, but supports functions for cloud-native operation scenarios, and tries to provide stable, secure, low-noise, low-side effect, easy-to-automate and easy-to-govern programming support for solving domain problems. - -In summary, KCL has the following characteristics: - -- **Easy-to-use**: Originated from high-level languages ​​such as Python and Golang, incorporating functional language features with low side effects. -- **Well-designed**: Independent Spec-driven syntax, semantics, runtime and system modules design. -- **Quick modeling**: [Schema](https://kcl-lang.github.io/docs/reference/lang/tour#schema)-centric configuration types and modular abstraction. -- **Rich capabilities**: Configuration with type, logic and policy based on [Config](https://kcl-lang.github.io/docs/reference/lang/codelab/simple), [Schema](https://kcl-lang.github.io/docs/reference/lang/tour/#schema), [Lambda](https://kcl-lang.github.io/docs/reference/lang/tour/#function), [Rule](https://kcl-lang.github.io/docs/reference/lang/tour/#rule). -- **Stability**: Configuration stability built on [static type system](https://kcl-lang.github.io/docs/reference/lang/tour/#type-system), [constraints](https://kcl-lang.github.io/docs/reference/lang/tour/#validation), and [rules](https://kcl-lang.github.io/docs/reference/lang/tour#rule). -- **Scalability**: High scalability through [automatic merge mechanism](https://kcl-lang.github.io/docs/reference/lang/tour/#-operators-1) of isolated config blocks. -- **Fast automation**: Gradient automation scheme of [CRUD APIs](https://kcl-lang.github.io/docs/reference/lang/tour/#kcl-cli-variable-override), [multilingual SDKs](https://kcl-lang.github.io/docs/reference/xlang-api/overview), [language plugin](https://kcl-lang.github.io/docs/reference/plugin/overview) -- **High performance**: High compile time and runtime performance using Rust & C and [LLVM](https://llvm.org/), and support compilation to native code and [WASM](https://webassembly.org/). -- **API affinity**: Native support API ecological specifications such as [OpenAPI](https://kcl-lang.github.io/docs/tools/cli/openapi/), Kubernetes CRD, Kubernetes YAML spec. -- **Development friendly**: Friendly development experiences with rich [language tools](https://kcl-lang.github.io/docs/tools/cli/kcl/overview) (Format, Lint, Test, Vet, Doc, etc.) and [IDE extensions](https://kcl-lang.github.io/docs/tools/Ide/). -- **Safety & maintainable**: Domain-oriented, no system-level functions such as native threads and IO, low noise and security risk, easy maintenance and governance. -- **Rich multi-language SDK**: [Go](https://kcl-lang.io/docs/reference/xlang-api/go-api), [Python](https://kcl-lang.io/docs/reference/xlang-api/python-api), [Java](https://kcl-lang.io/docs/reference/xlang-api/java-api) and [REST APIs](https://kcl-lang.io/docs/reference/xlang-api/rest-api) meet different scenarios and application use prelude. -- **Kubernetes Integrations**: External mutation and validation plugins including [Kustomize KCL Plugin](https://github.com/kcl-lang/kustomize-kcl), [Helm KCL Plugin](https://github.com/kcl-lang/helm-kcl), [KPT KCL SDK](https://github.com/kcl-lang/kpt-kcl-sdk), [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) to separate data and logic. -- **Production-ready**: Widely used in production practice of platform engineering and automation at Ant Group. - -Although KCL is not a general language, it has corresponding application scenarios. Developers can write **config**, **schema**, **function** and **rule** through KCL, where config is used to define data, schema is used to describe the model definition of data, rule is used to validate data, and schema and rule can also be combined to use models and constraints that fully describe data, In addition, we can also use the lambda pure function in KCL to organize data code, encapsulate common code, and call it directly when needed. - -The configuration of attributes in KCL usually meets the simple pattern: - -$$ -k = (T) v -$$ - -where $k$ is the attribute name, $v$ is the attributes value, and $T$ is the type annotation. Since KCL has the ability of the type inference, $T$ is usually omitted. - -This is an example of generating kubernetes manifests. - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = name -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -We can use the KCL code to generate a Kubernetes YAML manifest. - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## How to Choose? - -Communities have been making significant efforts to improve their configuration technologies, which can be categorized into three groups: - -- Low-level data format-based tools that utilize external tools for enhancing reuse and validation, specifically for templating, patching, and validation. -- Domain-Specific Languages (DSLs) and Configuration Languages (CLs), which enhance language abilities. -- General Purpose Language (GPL)-based solutions that utilize Cloud-Development Kit (CDK) or framework to define the configuration. - -To simplify, here are some recommended options: - -- YAML/JSON/Kustomize/Helm are recommended if you need to write structured key-value pairs, or use Kubernetes native tools. -- HCL is recommended if you want to use programming language convenience to remove boilerplate with good human readability, or if you are already a Terraform user. -- CUE is recommended if you want to use type system to improve stability and maintain scalable configurations. -- KCL is recommended if you want types and modeling like a modern language, scalable configurations, in-house pure functions and rules, and production-ready performance and automation. - -### vs. YAML/JSON - -YAML/JSON configurations are suitable for small-scale configuration scenarios. However, if you require frequent modifications in large-scale cloud-native configuration scenarios, KCL is more appropriate. The primary difference between the two is the abstraction of configuration data and deployment. - -The advantages of using KCL for configuration are numerous. First, abstracting one layer for static data provides deployment flexibility, allowing various configuration environments, tenants, and runtime to have distinct requirements for static data. Additionally, different organizations may have different specifications and product requirements. By leveraging KCL, administrators can expose the most important and frequently modified configurations to users. - -### vs. Jsonnet/GCL - -GCL is a declarative configuration programming language implemented in Python, providing necessary language capabilities for template abstraction. However, the compiler itself is written in Python, and the language runs with interpretation, leading to poor performance for large template instances, such as the Kubernetes model. - -On the other hand, Jsonnet is a data template language implemented in C++/Go, suitable for application and tool developers. It can generate configuration data and organize, simplify, and manage large configurations without any side effects. - -Both Jsonnet and GCL are excellent at reducing boilerplate, using code to generate configuration, so engineers can write advanced GPL code instead of manually writing error-prone and difficult-to-understand server binary code. Despite reducing some of the complexities of GCL, Jsonnet largely falls into the same category. Both have runtime errors, insufficient type-checking and constraint capacity. - -### vs. HCL - -HCL is a configuration language implemented in Go that is structured and inspired by the syntax of libucl and nginx configurations. It is designed to be both human and machine-friendly, primarily for use in devops tools, server configurations, and resource configurations as a [Terraform language](https://www.terraform.io/language). - -The user interface of HCL is not readily apparent in the Terraform provider Schema definition and can be cumbersome when defining complex object and required/optional fields. Dynamic parameters are constrained by the condition field of the variable, and resource constraints must be defined either by the provider schema or through the use of Sentinel/Rego and other policy languages. The language itself may not be self-contained. - -### vs. CUE - -CUE can be utilized for modeling through structures without the need for inheritance or other features. This can lead to high abstraction as long as there are no conflicts with model definitions. However, since CUE performs all constraint checks at runtime, there may be performance bottlenecks in large-scale modeling scenarios. Despite this, CUE simplifies constraint writing through various syntax options, eliminating the need for generic types and enumerations. Additionally, configuration merging is supported but is completely idempotent, which may not be suitable for complex multi-tenant and multi-environment configuration scenarios. Writing complex loop and constraint scenarios can be challenging and cumbersome for accurately modifying configurations. - -On the other hand, KCL conducts modeling through the schema and achieves high model abstraction through language-level engineering and some object-oriented features, such as single inheritance. KCL is a statically compiled language with low overhead for large-scale modeling scenarios. Additionally, KCL provides a richer declarative constraint syntax, making it easier to write. Compared to CUE, KCL offers more if guard combination constraints, all/any/map/filter, and other collection constraint writing methods, which simplify configuration field combination constraints. - -### vs. Dhall - -Dhall is a functional, programmable configuration language that incorporates JSON, functions, types and imports. If you have experience with languages like Haskell, you may find Dhall familiar. KCL also offers similar functionality for programmability and abstraction, but has made greater advancements in areas such as modeling, constraint checking, automation and package management for sharing models. KCL's syntax and semantics are more aligned with object-oriented languages, making it more approachable than pure functional styles in some cases. - -### vs. Nickel - -Nickel is the cheap configuration language. Its purpose is to automate the generation of static configuration files and it is in essence JSON with functions and types. - -KCL and Nickel both have a similar gradual type system (static + dynamic), merge strategy, function and constraint definition. The difference is that KCL is a Python-like language, while Nickel is a JSON-like language. In addition, KCL provides the schema keyword to distinguish between configuration definitions and configuration data to avoid mixed use. - -### vs. Starlark - -Starlark is the language of Bazel, which is a dialect of Python. It does not have types and recursion is forbidden. - -KCL can also be regarded as a variant of Python to some extent, but it greatly enhances the design related to static typing and configuration extensibility, and is a compiled language, which is essentially different from Starlark. - -### vs. Kustomize - -The key feature of Kustomize is its ability to overlay files at a granular level. However, it faces challenges with multiple overlay chains as a specific attribute value may not be the final value, as it can be overridden by another value elsewhere. Retrieving the inheritance chain of Kustomize files can be less convenient than retrieving the inheritance chain of KCL code, particularly for complex scenarios where careful consideration of the specified configuration file overwrite order is necessary. Additionally, Kustomize does not address issues related to YAML configuration writing, constraint verification, model abstraction, and development, making it more suited for simpler configuration scenarios. - -In contrast, KCL offers fine-grained configuration merge operations for each attribute in the code, with flexible merge strategy settings that are not limited to overall resources. KCL also allows for static analysis of configuration dependencies through import statements. - -### vs. Helm - -The idea behind Helm can be traced back to the package management system used in operating systems. It is a package management tool that relies on templated YAML files to execute and manage resources within packages. - -KCL provides a greater range of capabilities than Helm, making it a viable alternative. Users who have already adopted Helm can still utilize KCL by packaging the stack compilation results in a Helm format or by using the Helm-KCL plugin to programmatically extend existing Helm charts. - -### vs. CDK - -CDK's high-level language integrates well into application projects, effectively becoming part of the client runtime. In contrast, KCL decouples external configurations and policies written using KCL from the client runtime. - -General-purpose languages can often be over-engineered, going beyond the requirements of the problem being solved. These languages can also present various security issues, such as problems with the ability boundary, such as accessing I/O, network, code infinite looping, and other security risks. In specialized fields, such as music, there are special notes used to communicate effectively, which cannot be expressed clearly in general-purpose languages. - -Furthermore, general-purpose languages come in a variety of styles, which can create challenges in terms of unified maintenance, management, and automation. These languages are generally better suited to writing the client runtime, which is a continuation of the server runtime. They are not ideal for writing configurations that are independent of the runtime, as they are compiled into binaries and started from the process, making stability and scalability challenging to control. In contrast, configuration languages are often used to write data combined with simple logic, and they describe the expected final result, which is then consumed by the compiler or engine. - -### vs. OPA/Rego - -While not originally intended as a data definition language, Rego, the language used for Open Policy Agent (OPA), can also address the issue of adding constraints from multiple sources. - -Rego has its roots in logic programming and is based on Datalog, a restricted form of Prolog. In contrast, KCL is based on a static type structure. Typed-feature structures were developed to address the limitations of Prolog in encoding human languages. Using a Datalog variant for a constraint validation task may seem unusual. Datalog excels as a query language, but it can be cumbersome for constraint enforcement, in that values must be queried before applying constraints. - -KCL's approach to constraint validation is more conducive to finding normalized and simplified representations of constraints, making it well-suited for creating structures generated from OpenAPI. diff --git a/versioned_docs/version-0.5.2/user_docs/guides/_working-with-terraform/1-overview.md b/versioned_docs/version-0.5.2/user_docs/guides/_working-with-terraform/1-overview.md deleted file mode 100644 index c2ec836d..00000000 --- a/versioned_docs/version-0.5.2/user_docs/guides/_working-with-terraform/1-overview.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -id: overview -sidebar_label: Overview ---- - -# Overview - -Coming Soon diff --git a/versioned_docs/version-0.5.2/user_docs/guides/_working-with-terraform/2-abstraction.md b/versioned_docs/version-0.5.2/user_docs/guides/_working-with-terraform/2-abstraction.md deleted file mode 100644 index 18a25571..00000000 --- a/versioned_docs/version-0.5.2/user_docs/guides/_working-with-terraform/2-abstraction.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -id: abstraction -sidebar_label: Abstraction ---- - -# Abstract Your Terraform Modules - -Coming Soon diff --git a/versioned_docs/version-0.5.2/user_docs/guides/_working-with-terraform/3-coverter.md b/versioned_docs/version-0.5.2/user_docs/guides/_working-with-terraform/3-coverter.md deleted file mode 100644 index 1dc975bb..00000000 --- a/versioned_docs/version-0.5.2/user_docs/guides/_working-with-terraform/3-coverter.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -id: converter -sidebar_label: Converter ---- - -# Convert Your Terraform Provider Schema to KCL Schema - -Coming Soon diff --git a/versioned_docs/version-0.5.2/user_docs/guides/_working-with-terraform/_category_.json b/versioned_docs/version-0.5.2/user_docs/guides/_working-with-terraform/_category_.json deleted file mode 100644 index 3e72e820..00000000 --- a/versioned_docs/version-0.5.2/user_docs/guides/_working-with-terraform/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Terraform", - "position": 13 -} diff --git a/versioned_docs/version-0.5.2/user_docs/guides/ci-integration/_3-jenkins-ci.md b/versioned_docs/version-0.5.2/user_docs/guides/ci-integration/_3-jenkins-ci.md deleted file mode 100644 index f85d231f..00000000 --- a/versioned_docs/version-0.5.2/user_docs/guides/ci-integration/_3-jenkins-ci.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -id: github-ci -sidebar_label: Github CI ---- - -Coming Soon - -## Introduction - -## How to - -## Summary diff --git a/versioned_docs/version-0.5.2/user_docs/guides/ci-integration/_category_.json b/versioned_docs/version-0.5.2/user_docs/guides/ci-integration/_category_.json deleted file mode 100644 index 3145ed7f..00000000 --- a/versioned_docs/version-0.5.2/user_docs/guides/ci-integration/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "CI Integration", - "position": 12 -} \ No newline at end of file diff --git a/versioned_docs/version-0.5.2/user_docs/guides/gitops/_category_.json b/versioned_docs/version-0.5.2/user_docs/guides/gitops/_category_.json deleted file mode 100644 index 29a73c67..00000000 --- a/versioned_docs/version-0.5.2/user_docs/guides/gitops/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "GitOps", - "position": 11 -} \ No newline at end of file diff --git a/versioned_docs/version-0.5.2/user_docs/guides/index.md b/versioned_docs/version-0.5.2/user_docs/guides/index.md deleted file mode 100644 index cd3d4522..00000000 --- a/versioned_docs/version-0.5.2/user_docs/guides/index.md +++ /dev/null @@ -1 +0,0 @@ -# User Guide diff --git a/versioned_docs/version-0.5.2/user_docs/guides/package-management/1-overview.md b/versioned_docs/version-0.5.2/user_docs/guides/package-management/1-overview.md deleted file mode 100644 index cffccc67..00000000 --- a/versioned_docs/version-0.5.2/user_docs/guides/package-management/1-overview.md +++ /dev/null @@ -1,3 +0,0 @@ -# Overview - -KCL manages packages through the package management tool [kpm](https://github.com/kcl-lang/kpm). diff --git a/versioned_docs/version-0.5.2/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md b/versioned_docs/version-0.5.2/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md deleted file mode 100644 index aa9c119d..00000000 --- a/versioned_docs/version-0.5.2/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md +++ /dev/null @@ -1,73 +0,0 @@ -# Share Your Package - -[kpm](https://github.com/kcl-lang/kpm) is a tool for managing kcl packages. This article will guide you on how to use kpm to push your kcl package to an OCI Registry for publication. kpm uses [ghcr.io](https://ghcr.io) as the default OCI Registry, and you can change the default OCI Registry by modifying the kpm configuration file. For information on how to modify the kpm configuration file, see [kpm oci registry](https://github.com/kcl-lang/kpm/blob/main/docs/kpm_oci.md#kpm-registry) - -Here is a simple step-by-step guide on how to use kpm to push your kcl package to ghcr.io. - -## Step 1: Install kpm - -First, you need to install kpm on your computer. You can follow the instructions in the [kpm installation documentation](https://kcl-lang.io/docs/user_docs/guides/package-management/installation). - -## Step 2: Create a ghcr.io token - -If you are using the default OCI Registry of kpm, to push a kcl package to ghcr.io, you need to create a token for authentication. You can follow the instruction. - -- [Creating a ghcr.io access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic) - -## Step 3: Log in to ghcr.io - -After installing kpm and creating a ghcr.io token, you need to log in to ghcr.io using kpm. You can do this using the following command: - -```shell -kpm login ghcr.io -u -p -``` - -Where `` is your GitHub username, `` is the token you created in step 2 - -For more information on how to log in to ghcr.io using kpm, see [kpm login](https://kcl-lang.io/docs/reference/package-management/command-reference/login). - -## Step 4: Push your kcl package - -Now, you can use kpm to push your kcl package to ghcr.io. - -### 1. A valid kcl package - -First, you need to make sure that what you are pushing conforms to the specifications of a kcl package, i.e., it must contain valid kcl.mod and kcl.mod.lock files. - -If you don't know how to get a valid kcl.mod and kcl.mod.lock, you can use the `kpm init` command. - -```shell -# Create a new kcl package named my_package -kpm init my_package -``` - -The `kpm init my_package` command will create a new kcl package `my_package` for you and create the `kcl.mod` and `kcl.mod.lock` files for this package. - -If you already have a directory containing kcl files `exist_kcl_package`, you can use the following command to convert it into a kcl package and create valid `kcl.mod` and `kcl.mod.lock` files for it. - -```shell -# In the exist_kcl_package directory -$ pwd -/home/user/exist_kcl_package - -# Run the `kpm init` command to create the `kcl.mod` and `kcl.mod.lock` files -$ kpm init -``` - -For more information on how to use `kpm init`, see [kpm init](https://kcl-lang.io/docs/reference/package-management/command-reference/init). - -### 2. Pushing the KCL Package - -You can use the following command in the root directory of your `kcl` package: - -```shell -# In the root directory of the exist_kcl_package package -$ pwd -/home/user/exist_kcl_package - -# Pushing the KCL Package to Default OCI Registry -$ kpm push -``` - -After completing these steps, you have successfully pushed your KCL Package to the default OCI Registry. -For more information on how to use `kpm push`, see [kpm push](https://kcl-lang.io/docs/reference/package-management/command-reference/push). diff --git a/versioned_docs/version-0.5.2/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md b/versioned_docs/version-0.5.2/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md deleted file mode 100644 index 3fa5aabe..00000000 --- a/versioned_docs/version-0.5.2/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md +++ /dev/null @@ -1,66 +0,0 @@ -# Share Your Package to docker.io - -[kpm](https://github.com/KusionStack/kpm) is a tool for managing kcl packages. This article will show you how to use kpm to push your kcl packages to docker.io. - -Here is a simple step-by-step guide on how to use kpm to push your kcl package to docker.io. - -## Step 1: Install kpm - -First, you need to install kpm on your computer. You can follow the instructions in the [kpm installation documentation](https://kcl-lang.io/docs/user_docs/guides/package-management/installation). - -## Step 2: Create a docker.io account - -If you want to use `docker.io` as the OCI registry to share your kcl package with others, you need to create a `docker.io` account to support the push of your kcl package. - -## Step 3: Log in to docker.io - -You can use the following command to log in to docker.io. - -```shell -kpm login -u -p docker.io -``` - -Where `` is your `docker.io` username, and `` is your `docker.io` password. - -For more information on how to log in to docker.io using kpm, see [kpm login](https://kcl-lang.io/docs/reference/package-management/command-reference/login). - -## Step 4: Push your kcl package - -Now, you can use kpm to push your kcl package to `docker.io`. - -### 1. A valid kcl package - -First, you need to make sure that what you are pushing conforms to the specifications of a kcl package, i.e., it must contain valid kcl.mod and kcl.mod.lock files. - -If you don't know how to get a valid kcl.mod and kcl.mod.lock, you can use the `kpm init` command. - -Create a new kcl package named `my_package`. - -```shell -kpm init my_package -``` - -The `kpm init my_package` command will create a new kcl package `my_package` for you and create the `kcl.mod` and `kcl.mod.lock` files for this package. - -If you already have a directory containing kcl files `exist_kcl_package`, you can use the following command to convert it into a kcl package and create valid `kcl.mod` and `kcl.mod.lock` files for it. - -Run the `kpm init` command under the `exist_kcl_package` directory. - -```shell -kpm init -``` - -For more information on how to use `kpm init`, see [kpm init](https://kcl-lang.io/docs/reference/package-management/command-reference/init). - -### 2. Pushing the KCL Package - -You can use the following command in the root directory of your `kcl` package: - -Run the `kpm push` command under the `exist_kcl_package` directory. - -```shell -kpm push oci://docker.io//exist_kcl_package -``` - -After completing these steps, you have successfully pushed your KCL Package `exist_kcl_package` to `docker.io`. -For more information on how to use `kpm push`, see [kpm push](https://kcl-lang.io/docs/reference/package-management/command-reference/push). diff --git a/versioned_docs/version-0.5.2/user_docs/guides/package-management/4-how-to/6-push_github_action.md b/versioned_docs/version-0.5.2/user_docs/guides/package-management/4-how-to/6-push_github_action.md deleted file mode 100644 index de88dbcf..00000000 --- a/versioned_docs/version-0.5.2/user_docs/guides/package-management/4-how-to/6-push_github_action.md +++ /dev/null @@ -1,81 +0,0 @@ -# Push Your KCL Package by GitHub Action - -[kpm](https://github.com/KusionStack/kpm) is a tool for managing kcl packages. This article will guide you how to use kpm in GitHub Action to push your kcl package to OCI registry. - -## Step 1: Install kpm - -At first, you need to install kpm on your computer. You can follow [kpm installation document](https://kcl-lang.io/docs/user_docs/guides/package-management/installation). - -## Step 2: Create a GitHub account - -If you already have a GitHub account, you can skip this step. - -[Sign up for a new GitHub account](https://docs.github.com/en/get-started/signing-up-for-github/signing-up-for-a-new-github-account) - -## Step 3: Create a GitHub repository for your KCL package - -### 1. Prepare a GitHub repository for your KCL package - -You need to prepare a GitHub repository for your KCL package. - -[Create a GitHub repository](https://docs.github.com/en/get-started/quickstart/create-a-repo) - -In this repository, add your KCL program, take the repository https://github.com/awesome-kusion/catalog.git as an example, - -```bash -├── .github -│ └── workflows -│ └── push.yaml # github action workflow -├── LICENSE -├── README.md -├── kcl.mod # kcl.mod to define your kcl package -├── kcl.mod.lock # kcl.mod.lock generated by kpm -└── main.k # Your KCL program -``` - -### 2. Set OCI Registry, account and password for your Github repository - -Take docker.io as an example, you can set secrets `REG`, `REG_ACCOUNT` and `REG_TOKEN` for your repository. The value of `REG` is `docker.io`, the value of `REG_ACCOUNT` is your `docker.io` account, and the value of `REG_TOKEN` is your `docker.io` login password. - -[Add secrets to the repository](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) - -If you use `ghcr.io` as `Registry`, you need to use GitHub token as secrets. - -[Create a GitHub Token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token#personal-access-tokens-classic) - -## Step 4: Add your KCL package to the repository and write github action workflow - -Add github action file `.github/workflows/push.yml` to this repository, the content is as follows: - -```yaml -name: KPM Push Workflow - -on: - push: - branches: - - main - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Set up Go 1.21 - uses: actions/setup-go@v2 - with: - go-version: 1.21 - - - name: Install kpm - run: go install kcl-lang.io/kpm@latest - - - name: Login and Push - env: - KPM_REG: ${{ secrets.REG }} - KPM_REPO: ${{ secrets.REG_ACCOUNT }} - run: kpm login -u ${{ secrets.REG_ACCOUNT }} -p ${{ secrets.REG_TOKEN }} ${{ secrets.REG }} && kpm push - - - name: Run kpm project from oci registry - run: kpm run oci://${{ secrets.REG }}/${{ secrets.REG_ACCOUNT }}/catalog --tag 0.0.1 -``` diff --git a/versioned_docs/version-0.5.2/user_docs/guides/secret-management/_category_.json b/versioned_docs/version-0.5.2/user_docs/guides/secret-management/_category_.json deleted file mode 100644 index c57bb30e..00000000 --- a/versioned_docs/version-0.5.2/user_docs/guides/secret-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Secret Management", - "position": 13 -} diff --git a/versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md b/versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md deleted file mode 100644 index ea65e2f1..00000000 --- a/versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md +++ /dev/null @@ -1,249 +0,0 @@ ---- -title: "Generate Kubernetes Manifests" -sidebar_position: 2 ---- - -## Introduction - -When we manage the Kubernetes resources, we often maintain it by hand, or use Helm and Kustomize tools to maintain our YAML configurations or configuration templates, and then apply the resources to the cluster through kubectl tools. However, as a "YAML engineer", maintaining YAML configuration every day is undoubtedly trivial and boring, and prone to errors. For example as follows: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: ... # Omit -spec: - selector: - matchlabels: - cell: RZ00A - replicas: 2 - template: - metadata: ... # Omit - spec: - tolerations: - - effect: NoSchedules - key: is-over-quota - operator: Equal - value: 'true' - containers: - - name: test-app - image: images.example/app:v1 # Wrong ident - resources: - limits: - cpu: 2 # Wrong type. The type of cpu should be str - memory: 4Gi - # Field missing: ephemeral-storage - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: is-over-quota - operator: In - values: - - 'true' -``` - -- The structured data in YAML is untyped and lacks validation methods, so the validity of all data cannot be checked immediately. -- YAML has poor programming ability. It is easy to write incorrect indents and has no common code organization methods such as logical judgment. It is easy to write a large number of repeated configurations and difficult to maintain. -- The design of Kubernetes is complex, and it is difficult for users to understand all the details, such as the `toleration` and `affinity` fields in the above configuration. If users do not understand the scheduling logic, it may be wrongly omitted or superfluous added. - -Therefore, KCL expects to solve the following problems in Kubernetes YAML resource management: - -- Use **production level high-performance programming language** to **write code** to improve the flexibility of configuration, such as conditional statements, loops, functions, package management and other features to improve the ability of configuration reuse. -- Improve the ability of **configuration semantic verification** at the code level, such as optional/required fields, types, ranges, and other configuration checks. -- Provide **the ability to write, combine and abstract configuration blocks**, such as structure definition, structure inheritance, constraint definition, etc. - -## Prerequisite - -First, you can visit the [KCL Quick Start](/docs/user_docs/getting-started/kcl-quick-start) to download and install KCL according to the instructions, and then prepare a [Kubernetes](https://kubernetes.io/) environment. - -## Quick Start - -### 1. Generate Kubernetes Resource - -We can write the following KCL code and name it `main.k`. KCL is inspired by Python. Its basic syntax is very close to Python, which is easy to learn. The configuration mode is simple, `k [: T] = v`, where `k` denotes the configured attribute name, `v` denotes the configured attribute value and `: T` denotes an optional type annotation. - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -In the above KCL code, we declare the `apiVersion`, `kind`, `metadata`, `spec` and other variables of a Kubernetes `Deployment` resource, and assign the corresponding contents respectively. In particular, we will assign `metadata.labels` fields are reused in `spec.selector.matchLabels` and `spec.template.metadata.labels` field. It can be seen that, compared with YAML, the data structure defined by KCL is more compact, and configuration reuse can be realized by defining local variables. - -We can get a Kubernetes YAML file by executing the following command line - -```bash -kcl main.k -``` - -The output is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -Of course, we can use KCL together with kubectl and other tools. Let's execute the following commands and see the result: - -```shell -kcl main.k | kubectl apply -f - -``` - -The output is - -```shell -deployment.apps/nginx-deployment configured -``` - -It can be seen from the command line that it is completely consistent with the deployment experience of using YAML configuration and kubectl application directly. - -Check the deployment status through kubectl - -```shell -kubectl get deploy -``` - -The output is - -```shell -NAME READY UP-TO-DATE AVAILABLE AGE -nginx-deployment 3/3 3 3 15s -``` - -### 2. Write Code to Manage Kubernetes resources - -When publishing Kubernetes resources, we often encounter scenarios where configuration parameters need to be dynamically specified. For example, different environments need to set different `image` field values to generate resources in different environments. For this scenario, we can dynamically receive external parameters through KCL conditional statements and `option` functions. Based on the above example, we can adjust the configuration parameters according to different environments. For example, for the following code, we wrote a conditional statement and entered a dynamic parameter named `env`. - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" if option("env") == "prod" else "${metadata.name}:latest" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -Use the KCL command line `-D` flag to receive an external dynamic parameter: - -```bash -kcl main.k -D env=prod -``` - -The output is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -The `image=metadata.name+": 1.14.2" if option ("env")=="prod" else metadata.name + ": latest"` in the above code snippet means that when the value of the dynamic parameter `env` is set to `prod`, the value of the image field is `nginx: 1.14.2`; otherwise, it is' nginx: latest'. Therefore, we can set env to different values as required to obtain Kubernetes resources with different contents. - -KCL also supports maintaining the dynamic parameters of the option function in the configuration file, such as writing the `kcl.yaml` file. - -```yaml -kcl_options: - - key: env - value: prod -``` - -The same YAML output can be obtained by using the following command line to simplify the input process of KCL dynamic parameters. - -```bash -kcl main.k -Y kcl.yaml -``` - -The output is: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## Summary - -KCL can be used to generate and manage Kubernetes resources, addressing the limitations of managing YAML configurations, such as a lack of validation methods and poor programming capabilities. It can also dynamically receive external parameters through conditional statements and option functions, allowing configuration parameters to be adjusted according to different environments. In addition, KCL can be used in conjunction with other tools such as kubectl to apply configuration to the cluster. diff --git a/versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md b/versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md deleted file mode 100644 index 17918b29..00000000 --- a/versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: "Kubectl KCL Plugin" -sidebar_position: 1 ---- - -## Introduction - -[Kubectl](https://kubernetes.io/docs/reference/kubectl/) is a command line tool for communicating with a Kubernetes cluster's control plane, using the Kubernetes API. You can use the `Kubectl-KCL-Plugin` to - -- Edit the YAML configuration in a hook way to separate data and logic for the Kubernetes manifests management. -- For multi-environment and multi-tenant scenarios, you can maintain these configurations gracefully rather than simply copy and paste. -- Validate all KRM resources using the KCL schema. - -## Prerequisites - -- Install [Kubectl](https://github.com/kubernetes/kubectl) -- Install [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=krm-kcl` only to `Deployment` resources in the helm chart. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/kubectl-kcl.git/ -cd ./kubectl-kcl/examples/ -``` - -### 2. Test and Run - -Run the KCL code via the `Kubectl KCL Plugin`. - -```bash -kubectl kcl run -f ./kcl-run.yaml -``` - -The output yaml is - -```yaml -apiVersion: config.kubernetes.io/v1 -kind: ResourceList -items: - - apiVersion: apps/v1 - kind: Deployment - metadata: - annotations: - managed-by: krm-kcl - labels: - app: nginx - name: nginx-deployment - spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - image: "nginx:1.14.2" - name: nginx - ports: - - containerPort: 80 - - apiVersion: v1 - kind: Service - metadata: - name: test - spec: - ports: - - port: 80 - protocol: TCP - targetPort: 9376 - selector: - app: MyApp -functionConfig: - # kcl-fn-config.yaml - apiVersion: krm.kcl.dev/v1alpha1 - kind: KCLRun - metadata: - # EDIT THE SOURCE! - # This should be your KCL code which preloads the `ResourceList` to `option("resource_list") - spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "krm-kcl"}} for resource in option("resource_list").items] -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) diff --git a/versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md b/versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md deleted file mode 100644 index 01897f37..00000000 --- a/versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: "Helm KCL Plugin" -sidebar_position: 2 ---- - -## Introduction - -[Helm](https://github.com/helm/helm) is a tool for managing Charts. Charts are packages of pre-configured Kubernetes resources. You can use the `Helm-KCL-Plugin` to - -- Edit the helm charts in a hook way to separate data and logic for the Kubernetes manifests management. -- For multi-environment and multi-tenant scenarios, you can maintain these configurations gracefully rather than simply copy and paste. -- Validate all KRM resources using the KCL schema. - -## Prerequisites - -- Install [Helm](https://github.com/helm/helm) -- Install [Helm KCL Plugin](https://github.com/kcl-lang/helm-kcl) - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=helm-kcl-plugin` only to `Deployment` resources in the helm chart. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/helm-kcl.git/ -cd ./helm-kcl/examples/workload-charts-with-kcl -``` - -### 2. Test and Run - -Run the KCL code via the `Helm KCL Plugin`. - -```bash -helm kcl template --file ./kcl-run.yaml -``` - -The output yaml is - -```yaml -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: workload - app.kubernetes.io/version: 0.1.0 - helm.sh/chart: workload-0.1.0 - name: workload -spec: - ports: - - name: www - port: 80 - protocol: TCP - targetPort: 80 - selector: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - type: ClusterIP ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: workload - app.kubernetes.io/version: 0.1.0 - helm.sh/chart: workload-0.1.0 - name: workload - annotations: - managed-by: helm-kcl-plugin -spec: - selector: - matchLabels: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - template: - metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - spec: - containers: - - image: nginx:alpine - name: frontend -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Helm KCL Plugin](https://github.com/kcl-lang/helm-kcl) diff --git a/versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md b/versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md deleted file mode 100644 index 3a029bdd..00000000 --- a/versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: "KPT KCL SDK" -sidebar_position: 4 ---- - -## Introduction - -[kpt](https://github.com/GoogleContainerTools/kpt) is a package-centric toolchain that enables a configuration authoring, automation, and delivery experience, which simplifies managing Kubernetes platforms and KRM-driven infrastructure (e.g., Config Connector, Crossplane) at scale by manipulating declarative Configuration as Data for automating Kubernetes configuration editing including transforming and validating. - -KCL can be used to create functions to transform and/or validate the YAML Kubernetes Resource Model (KRM) input/output format, but we provide KPT KCL SDKs to simplify the function authoring process. - -## Prerequisites - -- Install [kpt](https://github.com/GoogleContainerTools/kpt) -- Install [Docker](https://www.docker.com/) - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=kpt` only to Deployment resources. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/kpt-kcl-sdk.git/ -cd ./kpt-kcl-sdk/get-started/set-annotation -``` - -### 2. Show the KRM - -```bash -kpt pkg tree -``` - -The output is - -```bash -set-annotation -├── [kcl-fn-config.yaml] KCLRun set-annotation -└── data - ├── [resources.yaml] Deployment nginx-deployment - └── [resources.yaml] Service test -``` - -### 3. Show and Update the KCL `FunctionConfig` - -```bash -cat ./kcl-fn-config.yaml -``` - -The output is - -```yaml -# kcl-fn-config.yaml -apiVersion: krm.kcl.dev/v1alpha1 -kind: KCLRun -metadata: # kpt-merge: /set-annotation - name: set-annotation -spec: - # EDIT THE SOURCE! - # This should be your KCL code which preloads the `ResourceList` to `option("resource_list")` - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "kpt"}} for resource in option("resource_list").items] -``` - -### 4. Test and Run - -Run the KCL code via kpt - -```bash -kpt fn eval ./data -i docker.io/kcllang/kpt-kcl:v0.2.0 --fn-config kcl-fn-config.yaml - -# Verify that the annotation is added to the `Deployment` resource and the other resource `Service` -# does not have this annotation. -cat ./data/resources.yaml | grep annotations -A1 -B0 -``` - -The output is - -```bash - annotations: - managed-by: kpt -``` - -It can be seen that we have indeed added the annotation `managed-by=kpt`. - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [KPT KCL SDK](https://github.com/kcl-lang/kpt-kcl-sdk) diff --git a/versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json b/versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json deleted file mode 100644 index 6e90c03c..00000000 --- a/versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Mutate or Validate Kubernetes Manifests", - "position": 3 -} diff --git a/versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/_category_.json b/versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/_category_.json deleted file mode 100644 index 42681f2b..00000000 --- a/versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Kubernetes", - "position": 9 -} diff --git a/versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/index.md b/versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/index.md deleted file mode 100644 index 8d6340de..00000000 --- a/versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/index.md +++ /dev/null @@ -1 +0,0 @@ -# Kubernetes diff --git a/versioned_docs/version-0.5.2/user_docs/guides/working-with-konfig/1-overview.md b/versioned_docs/version-0.5.2/user_docs/guides/working-with-konfig/1-overview.md deleted file mode 100644 index aca119a1..00000000 --- a/versioned_docs/version-0.5.2/user_docs/guides/working-with-konfig/1-overview.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -id: overview -sidebar_label: Overview ---- - -# Konfig Overview - -In KCL, it is recommended to uniformly manage all configurations and model libraries in the way of **configuration library**, that is, to store not only KCL definitions of the abstract model itself, but also various types of configurations, such as application operation and maintenance configuration, policy, etc. The configuration is recommended to be hosted in various VCS systems to facilitate configuration rollback and drift check. The best practice code of the configuration repository is Konfig, and the repository is hosted in [Github](https://github.com/KusionStack/konfig)。 - -⚡ The Konfig repository mainly includes: - -- KCL module declaration file (kcl.mod) -- KCL domain model libraries (Kubernetes, Prometheus, etc.) -- Directories of various configurations (application operation and maintenance configuration, etc) -- Configuration build and test scripts (Makefile, Github CI file, etc.) - -The reason for using a unified warehouse to manage all KCL configuration codes is that different code packages have different R&D entities, which will lead to package management and version management problems. When the business configuration code and basic configuration code are stored in a unified warehouse, the version dependency management between codes will be relatively simple. By locating the directory and file of the unique code base, the configuration code can be managed uniformly for easy search, modification and maintenance. - -The following is the architecture of Konfig: - -![](/img/docs/user_docs/guides/konfig/konfig-arch.png) - -Konfig provides users with an out-of-the-box and highly abstract configuration interface. The original simple starting point of the model library is to improve the efficiency and experience of Kubernetes YAML users. We hope to simplify the writing of user-side configuration code by abstracting and encapsulating the model with more complex code into a unified model. Konfig consists of the following parts: - -- **Core model**: - - **Front-end model**: The front-end model is the "user interface", which contains all configurable attributes exposed to users on the platform side. Some repetitive and deducible configurations are omitted, and essential attributes are abstracted and exposed to users. It has user-friendly features, such as `server.k`. - - **Back-end model**: The back-end model is "model implementation", which is the model that makes the properties of the front-end model effective. It mainly contains the rendering logic of the front-end model instance. The back-end model can use KCL to write validation, logic judgment, code fragment reuse and other code to improve the reusability and robustness of the configuration code, and is not sensitive to users, such as `server_backend.k`. -- **Domain model**: It is a model that does not contain any implementation logic and abstraction. It is often generated by tool transformation and does not need to be modified. It corresponds to the real effective YAML attribute one by one. The domain model needs to be further abstracted and is generally not directly used by users. For example, `kusion_kubernetes` is the domain model library of Kubernetes scenarios. - -In addition, the core model simplifies the configuration code of front-end users through two layers of abstraction: the front-end model and the back-end model. The domain model is automatically generated through the KCL OpenAPI. diff --git a/versioned_docs/version-0.5.2/user_docs/guides/working-with-konfig/2-structure.md b/versioned_docs/version-0.5.2/user_docs/guides/working-with-konfig/2-structure.md deleted file mode 100644 index 64e74b1d..00000000 --- a/versioned_docs/version-0.5.2/user_docs/guides/working-with-konfig/2-structure.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -id: structure -sidebar_label: Structure ---- - -# Konfig Structure - -This article mainly explains the directory and code structure of the Konfig repository. - -## Overview - -```bash -. -├── .github # CI Scripts -├── Makefile # Building and testing scripts -├── README.md # Documents -├── appops # Application configuration. This folder is used to place KCL operation and maintenance configuration of all applications -│ ├── clickhouse-operator -│ ├── code-city -│ ├── guestbook -│ ├── http-echo -│ └── nginx-example -├── base # Models -│ ├── examples # Examples -│ │ ├── monitoring # Monitoring example -│ │ ├── native # Kubernetes resource example -│ │ ├── provider # Basic resource configuration example such as Terraform resource -│ │ └── server # Server example. -│ └── pkg -│ ├── kusion_kubernetes # Kubernetes domain models -│ ├── kusion_models # Core models -│ ├── kusion_prometheus # Prometheus domain models -│ └── kusion_provider # Basic resource models such as Terraform resource -└── kcl.mod # The KCL module declaration file -``` - -## Core Model - -The core model library is generally named `kusion_models`, mainly including front-end model, back-end model, renderer, etc. The directory structure is: - -```bash -├── commons # Common models -├── kube # Cloud-native resource core models -│ ├── backend # Back-end models -│ ├── frontend # Front-end models -│ │ ├── common # Common front-end models -│ │ ├── configmap # ConfigMap -│ │ ├── container # Container -│ │ ├── ingress # Ingress -│ │ ├── resource # Resource -│ │ ├── secret # Secret -│ │ ├── service # Service -│ │ ├── sidecar # Sidecar -│ │ ├── strategy # strategy -│ │ ├── volume # Volume -│ │ └── server.k # The `Server` model -│ ├── metadata # Kubernetes metadata -│ ├── mixins # Mixin -│ ├── render # Front-to-back-end renderers. -│ ├── templates # Data template -│ └── utils -└── metadata # Common metadata -``` - -## Project and Stack - -![](/img/docs/user_docs/concepts/project-stack.png) - -Project and Stack are logical isolation concepts used to organize the Konfig. - -### Project - -Any folder that contains the file `project.yaml` will be regarded as a Project, and the `project.yaml` is used to describe the metadata of this Project like `name` and `tenant`. Projects must have clear business semantics and must belong to a tenant. Users can map an application or an operation scenario to a Project. - -### Stack - -Like Project, any folder that contains the file `stack.yaml` will be regarded as a Stack and `stack.yaml` is used to describe the metadata of this Stack. Stack is a set of `.k` files that represents the smallest operation unit that can be configured and deployed individually. It tends to represent different stages in the CI/CD process, such as dev, gray, prod, etc. - -### Relationship between Project and Stack - -A Project contains one or more Stacks, and a Stack must belong to and can only belong to one Project. Users can interpret the meaning of Project and Stack according to their own needs and flexibly organize the Konfig structure. We provide the following example as a best practice according to our experiences: - -```bash -appops/nginx-example -├── README.md # Project readme -├── base # common configurations for all stacks -│ └── base.k -├── dev # dev stack -│ ├── ci-test # CI test configs -│ │ ├── settings.yaml # test data -│ │ └── stdout.golden.yaml # expected test result -│ ├── kcl.yaml # kcl config -│ ├── main.k -│ └── stack.yaml # Stack metadata -└── project.yaml # Project metadata -``` - -The Project represents an application and Stack represents different environments of this application, such as dev, pre, prod, etc. Common configurations can be stored in a `base` directory under this Project. diff --git a/versioned_docs/version-0.5.2/user_docs/guides/working-with-konfig/3-quick-start.md b/versioned_docs/version-0.5.2/user_docs/guides/working-with-konfig/3-quick-start.md deleted file mode 100644 index 82fa6f36..00000000 --- a/versioned_docs/version-0.5.2/user_docs/guides/working-with-konfig/3-quick-start.md +++ /dev/null @@ -1,198 +0,0 @@ ---- -id: guide -sidebar_label: Quick Start ---- - -# Introduction - -This guide shows you how to use the KCL language and CLIs to complete the deployment of an application running in Kubernetes. We call the abstraction of application operation and maintenance configuration as `Server`, and its instance as `Application`. It is essentially an operation and maintenance model defined by KCL. - -In actual production, the application online generally needs to update several k8s resources: - -- Namespace -- Deployment -- Service - -This guide requires you to have a basic understanding of Kubernetes. If you are not familiar with the relevant concepts, please refer to the links below: - -- [Learn Kubernetes Basics](https://kubernetes.io/docs/tutorials/kubernetes-basics/) -- [Namespace](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/) -- [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) -- [Service](https://kubernetes.io/docs/concepts/services-networking/service/) - -## Prerequisites - -Before we start, we need to complete the following steps: - -1. Install KCL - See [Download and Install](/docs/user_docs/getting-started/install) for more details. - -2. Clone the [Konfig repo](https://github.com/KusionStack/konfig.git) - -```shell -git clone https://github.com/KusionStack/konfig.git && cd konfig -``` - -## Quick Start - -### 1. Compiling - -The programming language of the project is KCL, not JSON/YAML which Kubernetes recognizes, so it needs to be compiled to get the final output. - -Enter stack dir `appops/nginx-example/dev` and compile: - -```bash -cd appops/nginx-example/dev && kcl -Y kcl.yaml -D __konfig_output_format__=raw -``` - -The output YAML is: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-exampledev - namespace: nginx-example -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - template: - metadata: - labels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - spec: - containers: - - image: nginx:1.7.8 - name: main - ports: - - containerPort: 80 - protocol: TCP - resources: - limits: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi - requests: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi ---- -apiVersion: v1 -kind: Namespace -metadata: - name: nginx-example ---- -apiVersion: v1 -kind: Service -metadata: - name: nginx-example - namespace: nginx-example -spec: - ports: - - nodePort: 30201 - port: 80 - targetPort: 80 - selector: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - type: NodePort -``` - -After compiling, we can see three resources: - -- A `Deployment` with the name `nginx-exampledev` -- A `Namespace` with the name `nginx-example` -- A `Service` with the name `nginx-example` - -The above completes the configuration and takes effect. Later, we can use the command `kubectl apply` to apply and check the actual status of resources. This guide will not elaborate. - -### 2. Modification - -The `image` attribute in the `Server` model is used to declare the application's container image. We can modify the `image` value in `base/main.k` to modify or upgrade the image: - -```diff -14c14 -< image = "nginx:1.7.8" ---- -> image = "nginx:latest" -``` - -Recompile the configuration code to obtain the modified YAML output: - -```shell -kcl -Y kcl.yaml -D __konfig_output_format__=raw -``` - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-exampledev - namespace: nginx-example -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - template: - metadata: - labels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - spec: - containers: - - image: nginx:latest - name: main - ports: - - containerPort: 80 - protocol: TCP - resources: - limits: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi - requests: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi ---- -apiVersion: v1 -kind: Namespace -metadata: - name: nginx-example ---- -apiVersion: v1 -kind: Service -metadata: - name: nginx-example - namespace: nginx-example -spec: - ports: - - nodePort: 30201 - port: 80 - targetPort: 80 - selector: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - type: NodePort -``` - -## Summary - -This document mainly introduces how to use the KCL and Konfig library to deploy a Long Running application running in Kubernetes. diff --git a/versioned_docs/version-0.5.2/user_docs/guides/working-with-konfig/_category_.json b/versioned_docs/version-0.5.2/user_docs/guides/working-with-konfig/_category_.json deleted file mode 100644 index a71426f9..00000000 --- a/versioned_docs/version-0.5.2/user_docs/guides/working-with-konfig/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Konfig", - "position": 10 -} diff --git a/versioned_docs/version-0.5.2/user_docs/guides/working-with-kusion/_category_.json b/versioned_docs/version-0.5.2/user_docs/guides/working-with-kusion/_category_.json deleted file mode 100644 index 9f914498..00000000 --- a/versioned_docs/version-0.5.2/user_docs/guides/working-with-kusion/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KusionStack", - "position": 15 -} diff --git a/versioned_docs/version-0.5.2/user_docs/support/faq-install.md b/versioned_docs/version-0.5.2/user_docs/support/faq-install.md deleted file mode 100644 index 37100c09..00000000 --- a/versioned_docs/version-0.5.2/user_docs/support/faq-install.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Installation Troubleshooting - -## MacOS prompts that 'kcl' cannot be opened because Apple cannot check if it contains malicious software - -MacOS prompts that 'kcl' cannot be opened because Apple cannot check if it contains malicious software. This issue is due to the Gatekeeper security feature in the macOS system preventing the application from running. To solve this issue, follow these steps: - -Open 'System Preferences' and click 'Security and Privacy'. In the "General" tab, you will see a message: '"kcl" cannot be opened'. Click 'Open still'. Alternatively, you can click 'Open any method' to open your application. (You may need to use administrator privileges to open the application.) - -If you don't want to perform these steps every time you open an application, you can add the application to the whitelist to run without being blocked. To add your application to the whitelist: - -Open the terminal and run the following command: - -```shell -xattr -rd com.apple.quarantine /path/to/kcl -``` - -Where `/path/to/kcl` is the complete path of the kcl application. After running the command, the application will be added to the whitelist and Gatekeeper will no longer prevent it from running. - -## program not found or run linker failed error on Windows/Linux/MacOS - -Please ensure that the following dependencies are in your PATH: - -- `clang` for MacOS -- `gcc` for Linux -- `cl.exe` for Windows, which can be obtained by installing MSVC diff --git a/versioned_docs/version-0.5.2/user_docs/support/faq-kcl.md b/versioned_docs/version-0.5.2/user_docs/support/faq-kcl.md deleted file mode 100644 index 860dd15b..00000000 --- a/versioned_docs/version-0.5.2/user_docs/support/faq-kcl.md +++ /dev/null @@ -1,2341 +0,0 @@ ---- -sidebar_position: 2 ---- - -# KCL - -## 1. How to write a simple key-value pair configuration with KCL - -Create a file named `config.k` - -```python -cpu = 256 -memory = 512 -image = "nginx:1.14.2" -service = "my-service" -``` - -In the above KCL code, `cpu` and `memory` are defined to be declared as integer types, and their values are `256` and `512`, while `image` and `service` are string types, their values are `image` and `service`. - -Use the following command to compile the above KCL file into YAML for output - -``` -kcl config.k -``` - -The output YAML is - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -If we want to output the YAML content to a file such as `config.yaml`, we can add the `-o|--output` CLI argument: - -``` -kcl config.k -o config.yaml -``` - -## 2. What are the basic data types in KCL? - -KCL's current basic data types and values include: - -- Integer type `int` - - Examples: decimal positive integer `1`, decimal negative integer `-1`, hexadecimal integer `0x10`, octal integer `0o10`, binary integer `0b10` -- float type `float` - - Examples: positive float `1.10`, `1.0`, negative float `-35.59`, `-90.`, scientific notation float `32.3e+18`, `70.2E-12` -- boolean type `bool` - - Example: true value `True`, false value `False` -- String type `str` - marked with `'`, `"` - - Example: double quoted string `"string"`, `"""string"""`, single quoted string `'string'`, `'''string'''` -- List type `list` - marked with `[`, `]` - - Example: empty list `[]`, string list `["string1", "string2", "string3"]` -- Dictionary type `dict` - marked with `{`, `}` - - Example: empty dictionary `{}`, dictionary whose keys and values ​​are all strings `{"key1": "value1", "key2": "value2"}` -- Structure type `schema` - defined with the keyword `schema` -- Null value type `None` - used to indicate that the value of a variable is null, corresponding to the `null` value of the output YAML -- Undefined value type `Undefined` - used to indicate that a variable has not been assigned a value, and a variable with a value of `Undefined` will not be output to YAML - -```python -schema Person: - name: str - age: int - -alice = Person { - name = "Alice" - age = 18 -} -bob = Person { - name = "Bob" - age = 10 -} -``` - -> Note: All KCL variables can be assigned the null value `None` and the undefined value `Undefined`. - -## 3. What do some KCL variable names prefixed with `_` underscore mean? What's the difference between without the `_` underscore prefix? In what scenarios are they suitable for use? - -A variable with an underscore prefix in KCL represents a **hidden**, **mutable** variable, **hidden** means a variable with an underscore prefix will not be output to YAML, and **mutable** means that a variable with an underscore prefix can be repeatedly assigned multiple times, and a variable without an underscore prefix is immutable after being assigned. - -```python -name = 'Foo' # Exported and immutable variable -name = 'Bar' # Error: An exported variable can only be assigned a value once -``` - -```python -_name = 'Foo' # Hidden and mutable variable -_name = 'Bar' - -schema Person: - _name: str # hidden and mutable -``` - -## 4. How to add elements to a dict? - -We can use the union operator `|` or the dict unpacking operator `**` to add elements into a dict, and we can use `in` and `not in` operators to determine whether the dict variable contains a certain key. - -```python -_left = {key: {key1 = "value1"}, intKey = 1} # Note: `=` denotes override the value. -_right = {key: {key2 = "value2"}, intKey = 2} -dataUnion = _left | _right # {"key": {"key1": "value1", "key2": "value2"}, "intKey": 2} -dataUnpack = {**_left, **_right} # {"key": {"key1": "value1", "key2": "value2"}, "intKey": 2} -``` - -The output YAML is - -```yaml -dataUnion: - key: - key1: value1 - key2: value2 - intKey: 2 -dataUnpack: - key: - key1: value1 - key2: value2 - intKey: 2 -``` - -It is also possible to add key-value pair to a dict using the `string interpolation` or the string `format` method. - -```python -dictKey1 = "key1" -dictKey2 = "key2" -data = { - "${dictKey1}" = "value1" - "{}".format(dictKey2) = "value2" -} -``` - -The output YAML is - -```yaml -dictKey1: key1 -dictKey2: key2 -data: - key1: value1 - key2: value2 -``` - -## 5. How to modify elements in dict? - -We can use the union operator `|`, or the unpacking operator `**` to modify the elements in the dict - -```python -_data = {key = "value"} # {"key": "value"} -_data = _data | {key = "override_value1"} # {"key": "override_value1"} -_data = {**_data, **{key = "override_value2"}} # {"key": "override_value2"} -``` - -If we want to delete a value with a key of `key` in the dict, we can use the unpacking operator `**{key = Undefined}` or the merge operator `| {key = Undefined}` to overwrite, the value of the key is Undefined after overwriting, and no YAML output will be done. - -## 6. How to add elements to list? - -There are two ways to add elements to a list: - -- Use `+`, `+=` and slice to concatenate list variables to add elements to the list - -```python -_args = ["a", "b", "c"] -_args += ["end"] # Add elements "end" to the end of the list: ["a", "b", "c", "end"] -_args = _args[:2] + ["x"] + _args[2:] # Insert element "x" at list index 2: ["a", "b", "x", "c", "end"] -_args = ["start"] + _args # Add elements "start" to the head of the list: ["start", "a", "b", "x", "c", "end"] -``` - -- Use the `*` unpacking operator to concatenate and merge lists - -```python -_args = ["a", "b", "c"] -_args = [*_args, "end"] # Add elements "end" to the end of the list: ["a", "b", "c", "end"] -_args = ["start", *_args] # Add elements "start" to the head of the list: ["start", "a", "b", "x", "c", "end"] -``` - -> Note: When the consecutive variables are `None/Undefined`, using `+` may cause an error, then we can use the list unpacking operator `*` or use the `or` operator to take the default value of the list to avoid null values judge. - -```python -data1 = [1, 2, 3] -data2 = None -data3 = [*data1, *data2] # Ok: [1, 2, 3] -data4 = data1 + data2 or [] # OK: [1, 2, 3], We can use the `or` operator to take the default value of data2 as [], when data2 is None/Undefined, take the empty list [] for calculation. -data5 = data1 + data2 # Error: can only concatenate list (not "NoneType") to list -``` - -## 7. How to modify/delete elements in list? - -There are two ways to modify the elements in the list: - -- Use slice to directly modify the value at an index of a list - -```python -_index = 1 -_args = ["a", "b", "c"] -_args = _args[:index] + ["x"] + _args[index+1:] # Modify the element of list index 1 to "x": ["a", "x", "c"] -``` - -- Use the list comprehension to modify elements in a list - -```python -_args = ["a", "b", "c"] -_args = ["x" if a == "b" else a for a in _args] # Change the value of "b" in the list to "x": ["a", "x", "c"] -``` - -There are two ways to delete elements in a list: - -- Use the list comprehension to delete elements with the `if` condition expressions. -- Use `filter` expression to filter elements. - -For example, if we want to delete a number greater than 2 in a list `[1, 2, 3, 4, 5]`, we can write as follows: - -```python -originList = [1, 2, 3, 4, 5] -oneWayDeleteListItem = [item for item in originList if item <= 2] -anotherWayDeleteListItem = filter item in originList { - item <= 2 -} -``` - -The output YAML is - -```yaml -originList: - - 1 - - 2 - - 3 - - 4 - - 5 -oneWayDeleteListItem: - - 1 - - 2 -anotherWayDeleteListItem: - - 1 - - 2 -``` - -## 8. How to write a for loop in KCL? How to understand and use list comprehension and dict comprehension? - -KCL currently only supports functional/declarative deductive for loops. We can traverse dict and list variables as follows: - -The specific form of a list comprehension is (where `[]` are used on both sides of the comprehension): - -```txt -[expression for expr in sequence1 - if condition1 - for expr2 in sequence2 - if condition2 - for expr3 in sequence3 ... - if condition3 - for exprN in sequenceN - if conditionN] -``` - -The specific form of dict comprehension is (where `{}` are used on both sides of the comprehension): - -```txt -{expression for expr in sequence1 - if condition1 - for expr2 in sequence2 - if condition2 - for expr3 in sequence3 ... - if condition3 - for exprN in sequenceN - if conditionN} -``` - -The `if` in the above forms represents the filter condition, and the expression `expr` that satisfies the condition will be generated into a new list or dict - -List comprehension example: - -```python -_listData = [1, 2, 3, 4, 5, 6] -_listData = [l * 2 for l in _listData] # All elements in _listData are multiplied by 2: [2, 4, 6, 8, 10, 12] -_listData = [l for l in _listData if l % 4 == 0] # Filter out all elements in _listData that are divisible by 4: [4, 8, 12] -_listData = [l + 100 if l % 8 == 0 else l for l in _listData] # Traverse _listData, when the element in it is divisible by 8, add 100 to the element, otherwise keep it unchanged: [4, 108, 12] -``` - -Note the difference between the two `if`s on lines 3 and 4 in the above code: - -- The first `if` represents the filter condition of the variable `_listData` list comprehension itself, and cannot be followed by `else`. Elements that meet the conditions will be added to the list, and elements that do not meet the conditions will be removed. Besides, the process may change the length of the list. -- The second `if` represents the selection condition of the list iteration variable `l`, which means the `if-else` ternary expression, which must be followed by `else`, regardless of whether the condition is met, the resulting element is still in the list, the length of the list does not change. - -Dict comprehension example: - -```python -_dictData = {key1 = "value1", key2 = "value2"} -_dictData = {k = _dictData[k] for k in _dictData if k == "key1" and _dictData[k] == "value1"} # Filter out the elements whose key is "key1" and value is "value1" in _dictData, {"key1": "value1"} -``` - -Use comprehension to get all keys of dict: - -```python -dictData = {key1 = "value1", key2 = "value2"} -dictDataKeys = [k for k in _dictData] # ["key1", "key2"] -``` - -Use comprehension to sort a dict in ascending order by key: - -```python -dictData = {key3 = "value3", key2 = "value2", key1 = "value1"} # {'key3': 'value3', 'key2': 'value2', 'key1': 'value1'} -dictSortedData = {k = dictData[k] for k in sorted(dictData)} # {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'} -``` - -Multi-level comprehension example: - -```python -array1 = [1, 2, 3] -array2 = [4, 5, 6] -data = [a1 + a2 for a1 in array1 for a2 in array2] # [5, 6, 7, 6, 7, 8, 7, 8, 9] len(data) == len(array1) * len(array2) -``` - -Double variable loop (list comprehension supports index iteration of list and value iteration of dict, which can simplify the code writing of list/dict iteration process): - -- list - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use _ to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -- dict - -```python -data = {key1 = "value1", key2 = "value2"} -# Single variable loop -dataKeys1 = [k for k in data] # ["key1", "key2"] -dataValues1 = [data[k] for k in data] # ["value1", "value2"] -# Double variable loop -dataKeys2 = [k for k, v in data] # ["key1", "key2"] -dataValues2 = [v for k, v in data] # ["value1", "value2"] -dataFilter = {k = v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use _ to ignore loop variables -dataKeys3 = [k for k, _ in data] # ["key1", "key2"] -dataValues3 = [v for _, v in data] # ["value1", "value2"] -``` - -## 9. How to write an if conditional statement? - -KCL supports two ways to write if conditional statements: - -- if-elif-else block statement, where both elif and else blocks can be omitted, and the elif block can be used multiple times - -```python -success = True -_result = "failed" -if success: - _result = "success" -``` - -```python -success = True -if success: - _result = "success" -else: - _result = "failed" -``` - -```python -_result = 0 -if condition == "one": - _result = 1 -elif condition == "two": - _result = 2 -elif condition == "three": - _result = 3 -else: - _result = 4 -``` - -- Conditional expression ` if else `, similar to ` ? : ` ternary expression in C language - -```python -success = True -_result = "success" if success else "failed" -``` - -> Note: When writing an if-elif-else block statement, pay attention to the colon `:` after the if condition and keep the indentation consistent. - -In addition, conditional expressions can also be written directly in a list or dict (the difference is that the value to be written in the if expression written in the structure is not a statement): - -- list - -```python -env = "prod" -data = [ - "env_value" - ":" - if env == "prod": - "prod" # Write values that need to be added to data, not statements - else: - "other_prod" -] # ["env_value", ":", "prod"] -``` - -- dict - -```python -env = "prod" -config = { - if env == "prod": - MY_PROD_ENV = "prod_value" # Write key-value pairs that need to be added to config, not statements - else: - OTHER_ENV = "other_value" -} # {"MY_PROD_ENV": "prod_value"} -``` - -## 10. How to express logical operations such as "and" "or" "not"? - -In KCL, use `and` for "logical and", use `or` for "logical or", use `not` for "not", which is similar to `&&`, `||` and `~` semantic in C language. - -```python -done = True -col == 0 -if done and (col == 0 or col == 3): - ok = 1 -``` - -For "bitwise AND", "bitwise OR" and "bitwise XOR" of integers, we can use `&`, `|` and `^` operators in KCL, which is similar to `&`, `|` and `^` semantic in C language. - -```python -value = 0x22 -bitmask = 0x0f - -assert (value & bitmask) == 0x02 -assert (value & ~bitmask) == 0x20 -assert (value | bitmask) == 0x2f -assert (value ^ bitmask) == 0x2d -``` - -When we need to write a pattern such as `A if A else B`, we can use `A or B` to simplify, such as the following code: - -```python -value = [0] -default = [1] -x0 = value if value else default -x1 = value or default # Use `value or default` instead of `value if value else default` -``` - -## 11. How to judge whether a variable is None/Undefined, and whether a string/dict/list is empty? - -Please note that `False`, `None`, `Undefined`, number `0`, empty list `[]`, empty dictionary `{}` and empty string `""`, `''`, `""""""`, `''''''` in the conditional expression, are all treated as `false` expressions. - -For example, when judging a string variable `strData` is neither `None/Undefined` nor an empty string (string length is greater than 0), we can simply use the following expression: - -```python -strData = "value" -if strData: - isEmptyStr = False -``` - -Empty dictionary and empty list judgment examples: - -```python -_emptyList = [] -_emptyDict = {} -isEmptyList = False if _emptyList else True -isEmptyDict = False if _emptyDict else True -``` - -The output YAML is - -```yaml -isEmptyList: true -isEmptyDict: true -``` - -Or use the boolean function `bool` to judge - -```python -_emptyList = [] -_emptyDict = {} -isEmptyList = bool(_emptyList) -isEmptyDict = bool(_emptyDict) -``` - -## 12. How to concatenate strings, format strings, check string prefixes and suffixes and replace string content? - -- The `+` operator can be used to concatenate two strings in KCL - -```python -data1 = "string1" + "string2" # "string1string2" -data2 = "string1" + " " + "string2" # "string1 string2" -``` - -- There are currently two ways to format strings in KCL: - - `format` method for string variables `"{}".format()` - - Using string interpolation `${}` - -```python -hello = "hello" -a = "{} world".format(hello) -b = "${hello} world" -``` - -Note that if we want to use the `{` character or `}` alone in `"{}".format()`, we need to use `{{` and `}}` to convert `{` and `}` respectively, such as escaping a JSON string as follows: - -```python -data = "value" -jsonData = '{{"key": "{}"}}'.format(data) -``` - -The output YAML is - -```yaml -data: value -jsonData: '{"key": "value"}' -``` - -Note that if we want to use the `$` character alone in the `${}` interpolated string, we need to escape the `$` with `$$` - -```python -world = "world" -a = "hello {}".format(world) # "hello world" -b = "hello ${world}" # "hello world" -c = "$$hello ${world}$$" # "$hello world$" -c2 = "$" + "hello ${world}" + "$" # "$hello world$" -``` - -The output YAML is - -```yaml -world: world -a: hello world -b: hello world -c: $hello world$ -c2: $hello world$ -``` - -- Use the `startswith` and `endswith` methods of strings in KCL to check the prefix and suffix of strings - -```python -data = "length" -isEndsWith = data.endswith("th") # True -isStartsWith = "length".startswith('len') # True -``` - -- Use the replace method of the string or the `regex.replace` function to replace the content of the string in KCL - -```python -import regex -data1 = "length".replace("len", "xxx") # Replace "len", "xxxgth" with "xxx" -data2 = regex.replace("abc123", r"\D", "0") # Replace all non-digits in "abc123" with "0", "000123" -``` - -Among them, `r"\D"` means that we do not need to use `\\` to escape the backslash `\` in `\D`, which is mostly used in regular expression strings. - -Besides, we can use index placeholders or keyword placeholders in string formatting expressions to format multiple strings - -- Index placeholders - -```python -x = '{2} {1} {0}'.format('directions', 'the', 'Read') -y = '{0} {0} {0}'.format('string') -``` - -The output YAML is - -```yaml -x: Read the directions -y: string string string -``` - -- Keyword placeholders - -```python -x = 'a: {a}, b: {b}, c: {c}'.format(a = 1, b = 'Two', c = 12.3) -``` - -The output YAML is - -```yaml -x: "a: 1, b: Two, c: 12.3" -``` - -## 13. What is the difference between using single and double quotes in a string? - -There is little difference between KCL single-quoted and double-quoted strings. The only difference is that we don't need to use `\"` to escape `"` in single-quoted strings, and we don't need to use `\'` to escape `'` in double-quoted strings. - -```python -singleQuotedString = 'This is my book named "foo"' # Don’t need to escape double quotes in single quoted strings. -doubleQuotedString = "This is my book named 'foo'" # Don’t need to escape single quotes in double quoted strings. -``` - -In addition, a long string consisting of three single quotes or three double quotes does not need to be escaped (except for the beginning and end of the string), such as the following example: - -```python -longStrWithQuote0 = """Double quotes in long strings "(not at the beginning and end)""" -longStrWithQuote1 = '''Double quotes in long strings "(not at the beginning and end)''' -longStrWithQuote2 = """Single quotes in long strings '(not at the beginning and end)""" -longStrWithQuote3 = '''Single quotes in long strings '(not at the beginning and end)''' -``` - -The output YAML is - -```yaml -longStrWithQuote0: Double quotes in long strings "(not at the beginning and end) -longStrWithQuote1: Double quotes in long strings "(not at the beginning and end) -longStrWithQuote2: Single quotes in long strings '(not at the beginning and end) -longStrWithQuote3: Single quotes in long strings '(not at the beginning and end) -``` - -## 14. How to write a long multiline string? - -In KCL, we can use a single-quoted string and newline characters `\n` or a triple-quoted string to write a multi-line string, and we can use the continuation character `\` to optimize the form of the KCL string. For example, for the three multi-line string variables in the following code, their values are the same: - -```python -string1 = "The first line\nThe second line\nThe third line\n" -string2 = """The first line -The second line -The third line -""" -string3 = """\ -The first line -The second line -The third line -""" # It is recommended to use the long string writing form of `string3`. -``` - -The output YAML is - -```yaml -string1: | - The first line - The second line - The third line -string2: | - The first line - The second line - The third line -string3: | - The first line - The second line - The third line -``` - -## 15. How to use regular expressions in KCL? - -Regular expressions can be used by importing the regular expression system module `import regex` in KCL, which includes the following functions: - -- **match**: Regular expression matching function, which matches the input string according to the regular expression, and returns a bool type to indicate whether the match is successful. -- **split**: Regular expression split function, which splits the string according to the regular expression, and returns a list of split strings. -- **replace**: Regular expression replacement function, which replaces all substrings in the string that satisfies the regular expression, and returns the replaced string. -- **compile**: Regular expression compilation function, which returns bool type to indicate whether it is a valid regular expression. -- **search**: Regular expression search function, which searches all substrings that satisfy the regular expression, and returns a list of substrings. - -Examples: - -```python -import regex - -regex_source = "Apple,Google,Baidu,Xiaomi" -regex_split = regex.split(regex_source, ",") -regex_replace = regex.replace(regex_source, ",", "|") -regex_compile = regex.compile("$^") -regex_search = regex.search("aaaa", "a") -regex_find_all = regex.findall("aaaa", "a") -regex_result = regex.match("192.168.0.1", "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$") # Determine if it is an IP string -regex_result_false = regex.match("192.168.0,1", "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$") # Determine if it is an IP string -``` - -The output YAML is - -```yaml -regex_source: Apple,Google,Baidu,Xiaomi -regex_split: - - Apple - - Google - - Baidu - - Xiaomi -regex_replace: Apple|Google|Baidu|Xiaomi -regex_compile: true -regex_search: true -regex_find_all: - - a - - a - - a - - a -regex_result: true -regex_result_false: false -``` - -For longer regular expressions, we can also use **r-string** to ignore the escape of `\` symbols to simplify the writing of regular expression strings. - -Examples: - -```python -import regex - -isIp = regex.match("192.168.0.1", r"^(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)$") # Determine if it is an IP string -``` - -```python -import regex - -schema Resource: - cpu: str = "1" - memory: str = "1024Mi" - disk: str = "10Gi" - check: - regex.match(cpu, r"^([+-]?[0-9.]+)([m]*[-+]?[0-9]*)$"), "cpu must match specific regular expression" - regex.match(memory, r"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"), "memory must match specific regular expression" - regex.match(disk, r"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"), "disk must match specific regular expression" -``` - -```python -import regex - -schema Env: - name: str - value?: str - check: - len(name) <= 63, "a valid env name must be no more than 63 characters" - regex.match(name, r"[A-Za-z_][A-Za-z0-9_]*"), "a valid env name must start with alphabetic character or '_', followed by a string of alphanumeric characters or '_'" -``` - -## 16. What is the meaning of schema in KCL? - -Schema is a language element in KCL that defines the type of configuration data. Like struct in C language or class in Java, attributes can be defined in it, and each attribute has a corresponding type. - -## 17. How to use schema? - -In KCL, we can use the `schema` keyword to define a structure in which we can declare the various attributes of the schema. - -```python -# A Person structure with firstName of attribute string type, lastName of string type, age of integer type. -schema Person: - firstName: str - lastName: str - # The default value of the age attribute is 0. - age: int = 0 -``` - -A complex example: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels: {str:str} -``` - -In the above code, `cpu` and `memory` are defined as integer types; `name`, `image` and `service` are string types; `command` is a list of string types; labels are dictionaries type whose key type and value type are both strings. - -## 18. How to add "optional" and "required" constraints to the schema attribute? - -The `?` operator is used in KCL to define an "optional" constraint for a schema, and the schema attribute is "required" by default. - -```python -# A Person structure with firstName of attribute string type, lastName of string type, age of integer type. -schema Person: - firstName?: str # firstName is an optional attribute that can be assigned to None/Undefined - lastName?: str # age is an optional attribute that can be assigned to None/Undefined - age: int = 18 # age is an optional attribute that can be assigned to None/Undefined. -``` - -## 19. How to write validation rules for attributes in schema? - -In the schema definition, we can use the `check` keyword to write the validation rules of the schema attribute. As shown below, each line in the check code block corresponds to a conditional expression. When the condition is satisfied, the validation is successful. The conditional expression can be followed by `, "check error message"` to indicate the information to be displayed when the validation fails. - -```python -import regex - -schema Sample: - foo: str # Required, cannot be None/Undefined, and the type must be str - bar: int # Required, cannot be None/Undefined, and the type must be int - fooList: [int] # Required, cannot be None/Undefined, and the type must be int list - color: "Red" | "Yellow" | "Blue" # Required, literal union type, and must be one of "Red", "Yellow", "Blue". - id?: int # Optional, can be None/Undefined, the type must be int - - check: - 0 <= bar < 100 # bar must be greater than or equal to 0 and less than 100 - 0 < len(fooList) < 100 # fooList cannot be None/Undefined, and the length must be greater than 0 and less than 100 - regex.match(foo, "^The.*Foo$") # regular expression matching - bar in range(100) # bar can only range from 1 to 99 - bar in [2, 4, 6, 8] # bar can only take 2, 4, 6, 8 - bar % 2 == 0 # bar must be a multiple of 2 - all foo in fooList { - foo > 1 - } # All elements in fooList must be greater than 1 - any foo in fooList { - foo > 10 - } # At least one element in fooList must be greater than 10 - abs(id) > 10 if id # check expression with if guard, when id is not empty, the absolute value of id must be greater than 10 -``` - -To sum up, the validation kinds supported in KCL schema are: - -| Kind | Method | -| ----------------- | ----------------------------------------------------------------------------------------- | -| Range | Using comparison operators such as `<`, `>` | -| Regex | Using methods such as `match` from the `regex` system module | -| Length | Using the `len` built-in function to get the length of a variable of type `list/dict/str` | -| Enum | Using literal union types | -| Optional/Required | Using optional/required attributes of schema | -| Condition | Using the check if conditional expression | - -## 20. How to add documentation to schema and its attributes? - -A complete schema document is represented as a triple-quoted string, with the following structure: - -```python -schema Person: - """The schema person definition - - Attributes - ---------- - name : str - The name of the person - age : int - The age of the person - - See Also - -------- - Son: - Sub-schema Son of the schema Person. - - Examples - -------- - person = Person { - name = "Alice" - age = 18 - } - """ - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -``` - -## 21. How to write configuration based on schema? How to reuse the common configuration between multiple configurations? - -In the process of schema instantiation, we can use the unpacking operator `**` to expand the public configuration - -```python -schema Boy: - name: str - age: int - hc: int - -schema Girl: - name: str - age: int - hc: int - -config = { - age = 18 - hc = 10 -} - -boy = Boy { - **config - name = "Bob" -} -girl = Girl { - **config - name = "Alice" -} -``` - -The output YAML is - -```yaml -config: - age: 18 - hc: 10 -boy: - name: Bob - age: 18 - hc: 10 -girl: - name: Alice - age: 18 - hc: 10 -``` - -## 22. How to override the default value of schema attribute when writing configuration based on schema? - -After defining a schema, we can use the schema name to instantiate the corresponding configuration, use the `:` operator to union schema attribute default values, and use `=` to override schema attribute default values. - -```python -schema Meta: - labels: {str:str} = {"key1" = "value1"} - annotations: {str:str} = {"key1" = "value1"} - -meta = Meta { - labels: {"key2": "value2"} - annotations = {"key2" = "value2"} -} -``` - -The output YAML is - -```yaml -meta: - labels: - key1: value1 - key2: value2 - annotations: - key2: value2 -``` - -## 23. How to reuse schema definitions? - -We can declare the schema name that the schema needs to inherit at the definition: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 - -# An employee **is** a person, and has some additional information. -schema Employee(Person): - bankCard: int - nationality: str - -employee = Employee { - firstName = "Bob" - lastName = "Green" - age = 18 - bankCard = 123456 - nationality = "China" -} -``` - -The output YAML is - -```yaml -employee: - firstName: Bob - lastName: Green - age: 18 - bankCard: 123456 - nationality: China -``` - -> Note: KCL only allows schema single inheritance. - -## 24. How to reuse schema logic through composition? - -We can use KCL schema mixin to reuse schema logic. Mixins are generally used for functions such as separation of data in schema internal attributes, and data mapping, which can make KCL code more modular and declarative. - -Note that it is not recommended to define dependencies for mixing attributes between different mixins, which will make the use of mixins complicated. - -Examples: - -```python -schema Person: - mixin [FullNameMixin, UpperMixin] - - firstName: str - lastName: str - fullName: str - upper: str - -schema FullNameMixin: - fullName = "{} {}".format(firstName, lastName) - -schema UpperMixin: - upper = fullName.upper() - -person = Person { - firstName = "John" - lastName = "Doe" -} -``` - -The output YAML is - -```yaml -person: - firstName: John - lastName: Doe - fullName: John Doe - upper: JOHN DOE -``` - -## 25. How to import other KCL files? - -Other KCL files can be imported via the `import` keyword, and KCL configuration files are organized into modules. A single KCL file is considered a module, and a directory is considered a package, as a special module. The `import` keyword supports both relative path import and absolute path import - -For example, for the following directory structure: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ │── service1.k - │ └── service2.k - └── mixin - └── mixin1.k -``` - -For `main.k`, relative path import and absolute path import can be expressed as: - -```python -import service # Absolute path import, the root directory is the path where kcl.mod is located -import mixin # Absolute path import, the root directory is the path where kcl.mod is located - -import .model1 # Relative path import, current directory module -import ..service # Relative path import, parent directory -import ...root # Relative path import, parent directory of parent directory -``` - -> Note that for KCL's entry file `main.k`, it cannot import the folder where it is located, otherwise a circular import error will occur: - -```python -import model # Error: recursively loading -``` - -## 26. When can import be omitted? - -KCL files in the same folder the not in the main package can refer to each other without importing each other. For example, for the following directory structure: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ │── service1.k - │ └── service2.k - └── mixin - └── mixin1.k -``` - -When main.k is used as the KCL command line entry file, the variables in main.k, model1.k and model2.k in the model folder cannot refer to each other and need to be imported through import, but service1.k in the service folder and Variables in service2.k can refer to each other, ignoring import - -service1.k - -```python -schema BaseService: - name: str - namespace: str -``` - -service2.k - -```python -schema Service(BaseService): - id: str -``` - -## 27. There is a line of code that is too long, how to wrap it gracefully with correct syntax? - -In KCL, we can use the continuation character `\` for newlines, and we can also use `\` in strings to indicate continuation. - -An example of a long string concatenation continuation line: - -```python -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " -``` - -An example of a continuation in the comprehension expression: - -```python -data = [1, 2, 3, 4] -dataNew = [ - d + 2 \ - for d in data \ - if d % 2 == 0 -] -``` - -An example of a continuation in the if expression: - -```python -condition = 1 -data1 = 1 \ - if condition \ - else 2 -data2 = 2 \ -if condition \ -else 1 -``` - -An example of a continuation in the long string: - -```python -longString = """\ -The first line\ -The continue second line\ -""" -``` - -Note: Use the line continuation character `\` while maintaining indentation, as follows: - -- Error use case: - -```python -data1 = [ - 1, 2, - 3, 4 \ -] # Error, need to keep the indentation of the closing bracket ] - -data2 = [ - 1, 2, - 3, 4 -] # Error, requires uniform indentation of numbers 1 and 3 -``` - -- Right use case: - -```python -data1 = [ - 1, 2, - 3, 4 -] # OK - -data2 = [ \ - 1, 2, \ - 3, 4 \ -] # OK - -data3 = [ \ - 1, 2, \ - 3, 4 \ -] # OK -``` - -## 28. What do these symbols `**` and `*` mean? - -- `**`, `*` appear outside dict/list to represent power operator and multiplication operator respectively. - -```python -data1 = 2 ** 4 # 16 -data2 = 2 * 3 # 6 -``` - -- `**`, `*` appear inside dict/list to indicate unpacking operator, often used for unpacking and merging of list/dict, similar to unpacking operator in Python - -Unpacking of dict: - -```python -data = {"key1" = "value1"} -dataUnpack = {**data, "key2" = "value2"} # {"key1": "value1", "key2": "value2"} -``` - -Unpacking of list: - -```python -data = [1, 2, 3] -dataUnpack = [*data, 4, 5, 6] # [1, 2, 3, 4, 5, 6] -``` - -## 29. How to get child elements of list/dict/schema - -- For list type, we can use `[]` to get an element in the list - -```python -data = [1, 2, 3] # Define an list of integer types -theFirstItem = data[0] # Get the element with index 0 in the list, that is, the first element 1 -theSecondItem = data[1] # Get the element with index 1 in the list, which is the first element 2 -``` - -> Note: The value of the index cannot exceed the length of the list, otherwise an error will occur, we can use the `len` function to get the length of the list. - -```python -data = [1, 2, 3] -dataLength = len(data) # List length is 3 -item = data[3] # Error: Index out of bounds -``` - -In addition, we can also use the negative index to get the elements in the list in reverse order. - -```python -data = [1, 2, 3] -item1 = data[-1] # Get the element with index -1 in the list, which is the last element 3 -item2 = data[-2] # Get the element with index -2 in the list, which is the second-to-last element 2 -``` - -In summary, the value range of the list index is `[-len, len - 1]` - -When we want to get a part of the sub-elements of the list, we can use the slice expression in `[]`, the specific syntax is `[::]`, Note that the value range of the start and end of the index is `left closed right open [, )`, note that the three parameters can be omitted or not written. - -```python -data = [1, 2, 3, 4, 5] -dataSlice0 = data[1:2] # Get the set of elements in the list whose index starts at 1 and ends at 2 [2] -dataSlice1 = data[1:3] # Get the set of elements in the list whose index starts at 1 and ends at 3 [2, 3] -dataSlice2 = data[1:] # Get the set of elements in the list whose index starts at 1 and ends at the last index [2, 3, 4, 5] -dataSlice3 = data[:3] # Get the set of elements in the list whose index starts at the first index and ends at 3 [1, 2, 3] -dataSlice4 = data[::2] # Get the set of elements in the list whose index starts at the first index and ends at the last index (step size is 2) [1, 3, 5] -dataSlice5 = data[::-1] # Reverse the list, [5, 4, 3, 2, 1] -dataSlice6 = data[2:1] # When the start, stop, step combination of three parameters does not meet the conditions, return an empty list []. -``` - -- For dict/schema types, we can use `[]` and `.` to get child elements in dict/schema. - -```python -data = {key1: "value1", key2: "value2"} -data1 = data["key1"] # "value1" -data2 = data.key1 # "value1" -data3 = data["key2"] # "value2" -data4 = data.key2 # "value2" -``` - -```python -schema Person: - name: str = "Alice" - age: int = 18 - -person = Person {} -name1 = person.name # "Alice" -name2 = person["name"] # "Alice" -age1 = person.age # 18 -age2 = person.age # 18 -``` - -When the key value does not exist in the dict, return the value `Undefined`. - -```python -data = {key1 = "value1", key2 = "value2"} -data1 = data["not_exist_key"] # Undefined -data2 = data.not_exist_key # Undefined -``` - -We can use the `in` keyword to determine whether a key value exists in dict/schema - -```python -data = {key1 = "value1", key2 = "value2"} -exist1 = "key1" in data # True -exist2 = "not_exist_key" in data # False -``` - -When there is `.` in the key value or when we need to get the value corresponding to a key value variable at runtime, we can only use the `[]` method. If there is no special case, use `.`: - -```python -name = "key1" -data = {key1 = "value1", key2 = "value2", "contains.dot" = "value3"} -data1 = data[name] # "value1" -data2 = data["contains.dot"] # "value3" -# Note that this is wrong: data3 = data.contains.dot -``` - -> Note: The above sub-element operators cannot operate on values of non-list/dict/schema collection types, such as integers, nulls, etc. - -```python -data = 1 -data1 = 1[0] # Error -``` - -```python -data = None -data1 = None[0] # Error -``` - -When getting the child elements of the collection type, it is often necessary to make a non-null or length judgment: - -```python -data = [] -item = data[0] if data else None -``` - -We can use the `?` operator to make an if non-null judgment, and return None when the condition is not satisfied. For example, the above code can be simplified to: - -```python -data = [] -item1 = data?[0] # When data is empty, return the empty value None -item2 = data?[0] or 1 # When data is empty, return the empty value None, if we don't want to return None, we can also use the or operator to return other default values e.g., "1" in `data?[0] or 1` -``` - -Use more `?` operators to avoid complicated and cumbersome non-null judgments - -```python -data = {key1.key2.key3 = []} -item = data?.key1?.key2?.key3?[0] -``` - -## 30. How to get the type of a variable in KCL code - -The KCL `typeof` built-in function can return the type (string representation) of a variable immediately for type assertion. - -Examples: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person{} -t3 = typeof(_x1) - -_x2 = pkg.Person{} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# Output -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -## 31. How to solve the conflict between keywords and KCL variable names? - -For identifier names that conflict with keywords, we can add a `$` prefix before the identifier to define a keyword identifier. For example, in the following code, keywords such as `if`, `else` can be used as identifiers with the `$` prefix and we can get the corresponding YAML output - -```python -$if = 1 -$else = "s" - -schema Data: - $filter: str = "filter" - -data = Data {} -``` - -The output YAML is - -```yaml -data: - filter: filter -if: 1 -else: s -``` - -> Note: Prefixing non-keyword identifiers with `$` has the same effect as not adding. - -```python -_a = 1 -$_a = 2 # Equivalent to `_a = 2` -``` - -## 32. Are built-in types of KCL a keyword of KCL? Whether they can be used for the definition of variables - -The built-in types of KCL include `int`, `float`, `bool` and `str`, which are not KCL keywords and can be used to define variables, such as the following code: - -```py -int = 1 -str = 2 -``` - -The output YAML is - -```yaml -int: 1 -str: 2 -``` - -> Note: If there are no special requirements, it is not recommended that the names of variables take these built-in types, because in some languages, they exist as keywords. - -## 33. How to implement enumeration in KCL? - -There are two ways to implement enumeration in KCL - -- Use **literal union types** (recommended) - -```python -schema Person: - name: str - gender: "Male" | "Female" - -person = Person { - name = "Alice" - gender = "Male" # gender can only be "Male" or "Female" -} -``` - -```python -schema Config: - colors: ["Red" | "Yellow" | "Blue"] # colors is an enumerated array - -config = Config { - colors = [ - "Red" - "Blue" - ] -} -``` - -- Use schema check expressions - -```python -schema Person: - name: str - gender: "Male" | "Female" - - check: - gender in ["Male", "Female"] - -person = Person { - name = "Alice" - gender = "Male" # gender can only be "Male" or "Female" -} -``` - -## 34. How to get the length of dict - -In KCL, we can use the `len` built-in function to directly find the length of a dict - -```python -len1 = len({k1: "v1"}) # 1 -len2 = len({k1: "v1", k2: "v2"}) # 2 -varDict = {k1 = 1, k2 = 2, k3 = 3} -len3 = len(varDict) # 3 -``` - -In addition, the `len` function can also be used to get the length of `str` and `list` types - -```python -len1 = len("hello") # 5 -len2 = len([1, 2, 3]) # 3 -``` - -## 35. How to write conditional configuration in KCL - -In KCL, in addition to writing `if-elif-else` conditional expressions in top-level statements, it also supports writing conditional expressions in KCL complex structures (list/dict/schema), and supports conditional configuration writing. - -```python -x = 1 -# Conditional configuration in list -dataList = [ - if x == 1: 1 -] -# Conditional configuration in dict -dataDict = { - if x == 1: key1 = "value1" # Inline form - elif x == 2: - key2 = "value2" # Multi-line form -} - -schema Config: - id?: int - -env = "prod" -# Conditional configuration in schema -dataSchema = Config { - if env == "prod": - id = 1 - elif env == "pre": - id = 2 - elif env == "test": - id = 3 -} -``` - -## 36. Does the == operator in KCL do deep comparisons? - -`==` operator in KCL - -- For primitive types `int`, `float`, `bool`, `str` variables are directly compared to see if their values are equal -- Variables of composite types `list`, `dict`, `schema` will deeply recursively compare their sub-elements for equality - - `list` type deep recursive recursive comparison of the value and length of each index - - `dict`/`schema` types deeply recursively compare the value of each attribute (regardless of the order in which the attributes appear) - -```python -print([1, 2] == [1, 2]) # True -print([[0, 1], 1] == [[0, 1], 1]) # True -print({k1 = 1, k2 = 2} == {k2 = 2, k1 = 1}) # True - -print([1, 2] == [1, 2, 3]) # False -print({k1 = 1, k2 = 2, k3 = 3} == {k2 = 2, k1 = 1}) # False -``` - -## 37. How to modify existing configuration blocks in KCL - -In KCL, there are three **attribute operators** `=`, `+=`, `:`, which can be used to modify existing configuration blocks, and can use **unpacking operator** ` **` etc. "inherit" all attribute fields and values ​​of a configuration block. - -- The `=` attribute operator means overriding, use `=` operator to override/delete the attribute with priority, (if it is overwritten with `Undefined`, it means deletion) -- The `+=` attribute operator means adding, which is generally used to add sub-elements to the attributes of the list type. The operand type following the `+=` attribute operator can only be of the list type. -- The `:` attribute operator means idempotent merge. When the value conflicts, an error is reported, and when there is no conflict, the merge is performed - -### Override attribute operator = - -The most commonly used attribute operator is `=`, which indicates the assignment of an attribute. When the same attribute is used multiple times, it means overwriting. For global variables outside `{}` or attributes within `{}`, it means using value overrides this global variable or attribute - -```python -data = { # define a dictionary type variable data - a = 1 # use = to declare a attribute a in data with a value of 1 - b = 2 # use = to declare a attribute b in data with a value of 1 -} # The final data value is {"a": 1, "b": 1} -``` - -we can also use the override attribute operator at the schema instantiation to achieve the effect of overriding the default value of the schema. Generally, when creating a new schema instance, if there is no special requirement, we can generally use `=` - -```python -schema Person: - name: str = "Alice" # schema Person's name attribute has default value "Alice" - age: int = 18 # schema Person's age attribute has a default value of 18 - -bob = Person { - name = "Bob" # "Bob" -> "Alice", the value of the attribute name "Bob" will override the default value "Alice" of the schema Person name attribute - age = 10 # 10 -> 18, the value of the attribute age of 10 will override the default value of the schema Person age attribute of 18 -} # The final value of bob is {"name": "Bob", age: 10} -``` - -### Insert attribute operator += - -The insert attribute operator means to add the value of an attribute in place, such as adding a new element to a list type attribute - -```python -data = { - args = ["kcl"] # use = to declare an attribute in data with value ["kcl"] args - args += ["-Y", "settings.yaml"] # Add two elements "-Y", "settings.yaml" to attribute args using += operator -} # The final data value is {"args": ["kcl", "-Y", "settings.yaml"]} -``` - -### Merge attribute operators : - -The merge attribute operator means idempotent merging of different configuration block values ​​of an attribute. When the values ​​to be merged conflict, an error is reported. It is mostly used in complex configuration merging scenarios. - -```python -data = { - labels: {key1: "value1"} # define a labels, its type is dict, the value is {"key1": "value1"} - labels: {key2: "value2"} # Use : to combine different configuration values ​​of labels -} # The final data value is {"labels": {"key1": "value1", "key2": "value2"}} -``` - -The merge attribute operator is an idempotent operator, and the writing order of the configuration blocks to be merged does not affect the final result. For example, the two `labels` attributes in the above example can also be written in reverse order. - -```python -data = { # The merged writing order of the same attribute labels does not affect the final result - labels: {key2: "value2"} # define a label whose type is dict and the value is {"key2": "value2"} - labels: {key1: "value1"} # Use : to combine different configuration values ​​of labels -} # The final data value is {"labels": {"key1": "value1", "key2": "value2"}} -``` - -Note: The merge attribute operator will check the merged values ​​for conflicts, and report an error when the configuration values ​​that need to be merged conflict. - -```python -data = { - a: 1 # the value of a is 1 - a: 2 # Error: The value 2 of a cannot be merged with the value 1 of a because the results conflict and the merge is not commutative -} -``` - -```python -data = { - labels: {key: "value"} - labels: {key: "override_value"} # Error: The values ​​"value" and "override_value" of the key attributes of two labels are conflicting and cannot be merged -} -``` - -The coalescing operator is used differently for different types - -- Attributes of different types cannot be merged -- When the attribute is a basic type such as int/float/str/bool, the operator will judge whether the values ​​to be merged are equal, and a merge conflict error will occur if they are not equal - -```python -data = { - a: 1 - a: 1 # Ok - a: 2 # Error -} -``` - -- when the attribute is of type list - - Merge conflict error occurs when two lists that need to be merged are not of equal length - - When the lengths of the two lists to be merged are equal, recursively merge each element in the list according to the index - -```python -data = { - args: ["kcl"] - args: ["-Y", "settings.yaml"] # Error: The lengths of the two args attributes are not the same and cannot be merged - env: [{key1: "value1"}] - env: [{key2: "value2"}] # Ok: The value of the final env attribute is [{"key1": "value1"}, {"key2": "value2"}] -} -``` - -- When the attribute is of type dict/schema, recursively merge each element in dict/schema according to key - -```python -data = { - labels: {key1: "value1"} - labels: {key2: "value2"} - labels: {key3: "value3"} -} # The final data value is {"labels": {"key1": "value1", "key2": "value2", "key3": "value3"}} -``` - -- the result of combining an attribute of any type with None/Undefined is itself - -```python -data = { - args: ["kcl"] - args: None # Ok - args: Undefined #Ok -} # The final data value is {"args": ["kcl"]} -``` - -Support declaration and merging of top-level variables using the `:` attribute (we can still declare a configuration block using `config = Config {}`) - -```python -schema Config: - id: int - value: str - -config: Config { - id: 1 -} -config: Config { - value: "1" -} -""" -Two Config configuration blocks are defined here, and the : operator can be used to merge the two configuration blocks together. The equivalent code for the merge is as follows: -config: Config { - id: 1 - value: "1" -} -""" -``` - -To sum up, the usage scenario of the merge attribute operator `:` is mainly the merge operation of the complex data structure list/dict/schema. In general, if there is no special requirement, the two attribute operators `=` and `+=` are used. Yes, so the best practice for attribute operators is as follows - -- For primitive types, use the `=` operator -- For the list type, the `=` and `+=` operators are generally used. Use `=` to completely override the list attribute, and use `+=` to add elements to the list -- For dict/schema types, the `:` operator is generally used - -In addition, when a configuration already exists, we can use the unpacking operator `**` to get all field values ​​of this configuration and modify the fields with different attribute operators, and get a new configuration - -```python -configBase = { - intKey = 1 # A attribute of type int - floatKey = 1.0 # A attribute of type float - listKey = [0] # A attribute of type list - dictKey = {key1: "value1"} # an attribute of type dict -} -configNew = { - **configBase # Unpack and inline configBase into configNew - intKey = 0 # Use override attribute operator = to override intKey attribute to 1 - floatKey = Undefined # Use override attribute operator = remove floatKey attribute - listKey += [1] # Add an attribute 1 to the end of the listKey attribute using the add attribute operator += - dictKey: {key2: "value2"} # Use the merge attribute operator: extend a key-value pair for the dictKey attribute -} -``` - -The output YAML result is: - -```yaml -configBase: - intKey: 1 - floatKey: 1.0 - listKey: - - 0 - dictKey: - key1: value1 -configNew: - intKey: 0 - listKey: - - 0 - - 1 - dictKey: - key1: value1 - key2: value2 -``` - -Alternatively two configuration blocks can be combined using the `|` operator: - -```python -configBase = { - intKey = 1 # A attribute of type int - floatKey = 1.0 # A attribute of type float - listKey = [0] # A attribute of type list - dictKey = {key1: "value1"} # an attribute of type dict -} -configNew = configBase | { # Use | to merge - intKey = 0 # Use override attribute operator = to override intKey attribute to 1 - floatKey = Undefined # Use override attribute operator = remove floatKey attribute - listKey += [1] # Add an attribute 1 to the end of the listKey attribute using the add attribute operator += - dictKey: {key2: "value2"} # Use the merge attribute operator: extend a key-value pair for the dictKey attribute -} -``` - -The output YAML is - -```yaml -configBase: - intKey: 1 - floatKey: 1.0 - listKey: - - 0 - dictKey: - key1: value1 -configNew: - intKey: 0 - listKey: - - 0 - - 1 - dictKey: - key1: value1 - key2: value2 -``` - -### The solution to the conflicting values on the attribute 'attr' between {value1} and {value2} error in KCL - -When an error like conflicting values on the attribute 'attr' between {value1} and {value2} occurs in KCL, it is usually a problem with the use of the merge attribute operator `:`, indicating that when the `value1` and `value2` configurations are merged, the attribute A conflict error occurred at `attr`. In general, modify the attr attribute of value2 to other attribute operators, use `=` to indicate overwrite, and use `+=` to indicate addition - -For example for the following code: - -```python -data = {k: 1} | {k: 2} # Error: conflicting values on the attribute 'k' between {'k': 1} and {'k': 2} -``` - -We can use the `=` attribute operator to modify it to the following form - -```python -data = {k: 1} | {k = 2} # Ok: the value 2 will override the value 1 through the `=` operator -``` - -## 38. How to traverse multiple elements at the same time in the for comprehension? - -In KCL, we can use for comprehension to traverse multiple elements - -- Example 1: two dimension element loop - -```python -dimension1 = [1, 2, 3] # The length of the dimension1 list is 3 -dimension2 = [1, 2, 3] # The length of the dimension2 list is 3 -matrix = [x + y for x in dimension1 for y in dimension2] # The length of the matrix list is 9 = 3 * 3 -``` - -The output YAML is: - -```yaml -dimension1: - - 1 - - 2 - - 3 -dimension2: - - 1 - - 2 - - 3 -matrix: - - 2 - - 3 - - 4 - - 3 - - 4 - - 5 - - 4 - - 5 - - 6 -``` - -- Example 2: Use for loop and `zip` built-in function to traverse multiple lists one by one by index - -```python -dimension1 = [1, 2, 3] # The length of the dimension1 list is 3 -dimension2 = [1, 2, 3] # The length of the dimension2 list is 3 -dimension3 = [d[0] + d[1] for d in zip(dimension1, dimension2)] # The length of the dimension1 list is 3 -``` - -The output YAML is: - -```yaml -dimension1: - - 1 - - 2 - - 3 -dimension2: - - 1 - - 2 - - 3 -dimension3: - - 2 - - 4 - - 6 -``` - -## 39. How to set default value for option function in KCL - -In KCL, when the value of the option attribute is None/Undefined or empty, we can use the logical `or` to directly specify a default value. - -```python -value = option("key") or "default_value" # When the value of key exists, take the value of option("key"), otherwise take "default_value" -``` - -Or use the default parameter of the option function. - -```python -value = option("key", default="default_value") # When the value of key exists, take the value of option("key"), otherwise take "default_value" -``` - -## 40. How to check that multiple attributes cannot be empty or set values at the same time in schema in KCL? - -In KCL, a single attribute of schema cannot be empty by default, unless we use the attribute optional operator `?`. - -```python -schema Person: - name: str # Required. - age: int # Required. - id?: int # Optional. -``` - -When it is necessary to check that the schema attributes cannot be empty at the same time or only one of them is empty, it needs to be written with the help of schema check expressions. The following takes two attributes `a`, `b` of the schema `Config` as an example to illustrate. - -- `a` and `b` attributes cannot be empty at the same time. - -```python -schema Config: - a?: str - b?: str - - check: - a or b -``` - -- `a` and `b` attributes can only have one or both empty (cannot exist at the same time or not empty) - -```python -schema Config: - a?: str - b?: str - - check: - not a or not b -``` - -## 41. A file is imported in KCL, but the schema defined by other KCL files in the same directory cannot be found. What might be the reason? - -It may be caused to import only this file in this folder. In KCL, import statement supports importing the entire folder, and also supports importing a certain KCL file under a certain folder. For the following directory structure. - -``` -. -├── kcl.mod -├── main.k -└── pkg - ├── pkg1.k - ├── pkg2.k - └── pkg3.k -``` - -There is an entry file main.k in the root directory. You can write the following code in main.k to import the entire pkg folder. At this time, all schema definitions in the pkg folder are visible to each other. - -```python -import pkg -``` - -We can also write the following code to import a single file pkg/pkg1.k. At this time, pkg1.k cannot find other files, namely the schema definitions under pkg2.k/pkg3.k - -```python -import pkg.pkg1 -``` - -## 42. How is indentation handled in KCL? - -In KCL, when a colon `:`, square bracket pair `[]` and curly bracket pair `{}` appear, we generally need to use newline + indentation, and the number of indented spaces for the same indentation level needs to be consistent. The indentation level is generally represented by 4 spaces. - -- colon `:` followed by newline and indent - -```python -"""Indentation in if statements""" -_a = 1 -_b = 1 -if _a >= 1: # colon `:` followed by newline and indent - if _a > 8: - _b = 2 - elif a > 6: - _b = 3 - -"""Indentation in schema statements""" -schema Person: # colon `:` followed by newline and indent - name: str - age: int -``` - -- opening bracket `[` followed by newline and indent - -```python -data = [ # opening bracket `[` followed by newline and indent - 1 - 2 - 3 -] # unindent before closing bracket ] -``` - -```python -data = [ # opening bracket `[` followed by newline and indent - i * 2 for i in range(5) -] # unindent before closing bracket `]` -``` - -- opening bracket `{` followed by newline and indent - -```python -data = { # opening bracket `{` followed by newline and indent - k1 = "v1" - k2 = "v2" -} # unindent before closing brace `}` -``` - -```python -data = { # opening bracket `{` followed by newline and indent - str(i): i * 2 for i in range(5) -} # unindent before closing brace `}` -``` - -## 43. How to write simple tests for KCL code? - -The current version of KCL does not support internal program debugging, we can use the assert statement and the print function to achieve data assertion and viewing. - -```python -a = 1 -print("The value of a is", a) -assert a == 1 -``` - -In addition, we can also use the kcl-test test tool to write KCL internal test cases - -Assuming there is a hello.k file, the code is as follows: - -```python -schema Person: - name: str = "kcl" - age: int = 1 - -hello = Person { - name = "hello kcl" - age = 102 -} -``` - -Construct the hello_test.k test file with the following contents: - -```python -schema TestPerson: - a = Person{} - assert a.name == 'kcl' - -schema TestPerson_age: - a = Person{} - assert a.age == 1 - -schema TestPerson_ok: - a = Person{} - assert a.name == "kcl" - assert a.age == 1 -``` - -Then execute the kcl-test command in the directory: - -``` -$ kcl-test -ok /pkg/to/app [365.154142ms] -$ -``` - -## 44. How to define and use functions in KCL? - -The schema structure acts as a function to a certain extent, and this function has the ability to have multiple input parameters and multiple output parameters. For example, the following code can implement the function of a Fibonacci sequence: - -```python -schema Fib: - n: int - value: int = 1 if n <= 2 else (Fib {n: n - 1}).value + (Fib {n: n - 2}).value - -fib8 = (Fib {n: 8}).value -``` - -The output is - -```yaml -fib8: 21 -``` - -A schema function that merges lists into dictionaries - -```python -schema UnionAll[data, n]: - _?: [] = data - value?: {:} = ((UnionAll(data=data, n=n - 1) {}).value | data[n] if n > 0 else data[0]) if data else {} - -schema MergeList[data]: - """Union all elements in a list returns the merged dictionary - - [{"key1": "value1"}, {"key2": "value2"}, {"key3": "value3"}] -> {"key1": "value1", "key2": "value2", "key3": "value3"} - """ - _?: [] = data - value?: {:} = (UnionAll(data=data, n=len(data) - 1) {}).value if data else {} -``` - -In addition, KCL supports defining a function using the `lambda` keyword: - -```python -func = lambda x: int, y: int -> int { - x + y -} -a = func(1, 1) # 2 -``` - -A lambda function has the following properties: - -- A lambda function takes the value of the last expression as the return value of the function, and an empty function body returns None. -- The return value type annotation can be omitted, the return value type is the type of the last expression value. -- There are no order-independent features in the function body, all expressions are executed in order. - -```python -_func = lambda x: int, y: int -> int { - x + y -} # Define a function using the lambda expression -_func = lambda x: int, y: int -> int { - x - y -} # Ok -_func = lambda x: int, y: int -> str { - str(x + y) -} # Error (int, int) -> str can't be assigned to (int, int) -> int -``` - -A lambda function cannot participate in any computation and can only be used in assignment and call statements. - -```python -func = lambda x: int, y: int -> int { - x + y -} -x = func + 1 # Error: unsupported operand type(s) for +: 'function' and 'int(1)' -``` - -```python -a = 1 -func = lambda x: int { - x + a -} -funcOther = lambda f, para: int { - f(para) -} -r = funcOther(func, 1) # 2 -``` - -The output is - -```python -a: 1 -r: 2 -``` - -We can define an anonymous function and call it directly - -```python -result = (lambda x, y { - z = 2 * x - z + y -})(1, 1) # 3 -``` - -Anonymous functions can be also used in for loops - -```python -result = [(lambda x, y { - x + y -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 3, 3, 4] -``` - -Functions can be defined and used in the KCL schema - -```python -_funcOutOfSchema = lambda x: int, y: int { - x + y -} -schema Data: - _funcInSchema = lambda x: int, y: int { - x + y - } - id0: int = _funcOutOfSchema(1, 1) - id1: int = _funcInSchema(1, 1) - id2: int = (lambda x: int, y: int { - x + y - })(1, 1) -``` - -The output YAML is - -```yaml -data: - id0: 2 - id1: 2 - id2: 2 -``` - -## 45. Why do we get an error when a variable is assigned an enumeration type (a literal union type)? - -In KCL, a attribute defined as a literal union type is only allowed to receive a literal value or a variable of the same literal union type during assignment. For example, the following code is correct: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -data = Data { - color = "Red" # Ok, can be assigned as "Red", "Yellow" and "Blue" -} -``` - -However the following code is wrong: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -_color = "Red" - -data = Data { - color = _color # Error: expect str(Red)|str(Yellow)|str(Blue), got str -} -``` - -This is because there is no type declared for the variable `_color`, it will be deduced by the KCL compiler as a `str` string type, so when a "larger" type `str` is assigned to a "smaller" type `"Red" | "Yellow" | "Blue"` will report an error, one solution is to declare a type for the `_color` variable, the following code is correct: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -_color: "Red" | "Yellow" | "Blue" = "Red" - -data = Data { - color = _color # Ok -} -``` - -Further, we can use type aliases to simplify enumeration (writing of literal union types), such as the following code: - -```python -type Color = "Red" | "Yellow" | "Blue" # Define a type alias, which can be reused in different places, reducing the amount of code writing - -schema Data: - color: Color - -_color: Color = "Red" - -data = Data { - color = _color # Ok -} -``` - -## 46. Procedural for loop - -KCL provides comprehensions and all/any/map/filter expressions for processing a collection element, which meets most needs, and provides a procedural for loop body. Providing a procedural for loop body is not very demanding from the current scenario, so there is no procedural for loop support yet. - -In addition, although KCL does not support procedural for loops, it is possible to "construct" corresponding procedural for loops through for loops and lambda functions. - -```python -result = [(lambda x: int, y: int -> int { - # Write procedural for loop logic in the lambda function. - z = x + y - x * 2 -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 2, 4, 4] -``` - -## 47. Default variables are immutable - -The immutability of KCL variables means that the exported variables starting with non-underscore `_` in the KCL top-level structure cannot be changed after initialization. - -```python -schema Person: - name: str - age: int - -a = 1 # a will be output to YAML, once assigned it cannot be modified -_b = 1 # _b The variable is named with an underscore and will not be output to YAML. It can be modified by multiple assignments -_b = 2 -alice = Person { - name = "Alice" - age = 18 -} -``` - -There are two ways of specifying that variables are immutable: - -- non-underscore top-level variables outside the schema - -```python -a = 1 # immutable exported variable -_b = 2 # mutable non-export variable -``` - -## 48. Is there a type like Go `interface{}`/`any` or Java `Object` in KCL? - -In KCL, we can use the `any` type annotation to define a variable to store any values such as integers, strings and schemas. For example: - -```python -schema Data: - id: int = 1 - -var_list: [any] = [1, "12", Data {}] -``` - -The output YAML is - -```yaml -var_list: - - 1 - - "12" - - id: 1 -``` - -In addition, we can also use the `typeof` function to determine the type of variables during KCL code execution: - -```python -schema Data1: - id: int = 1 - -schema Data2: - name: str = "name" - -data_list: [any] = [Data1 {}, Data2 {}] -data_type_list: [str] = [typeof(data) for data in data_list] -``` - -The output YAML is - -```yaml -data_list: - - id: 1 - - name: name -data_type_list: - - Data1 - - Data2 -``` - -## 49. How to develop a KCL plugin? - -KCL plugins are installed in the plugins subdirectory of KCL (usually installed in the `$HOME/.kcl/plugins` directory), or set through the `$KCL_PLUGINS_ROOT` environment variable. Besides, the `plugins` directory could also be placed at the `pwd` path. For plugin developers, plugins are managed in the [Git repository](https://github.com/kcl-lang/kcl-plugin), and the plugin repository can be cloned to this directory for development. - -KCL has built-in kcl-plugin scaffolding command to assist users to write KCL plug-ins in Python language, so that the corresponding plug-ins can be called in the KCL file to enhance the KCL language itself, such as accessing the network, reading and writing IO, CMDB query and encryption and decryption functions. - -``` -usage: kcl-plugin [-h] {list,init,info,gendoc,test} ... - -positional arguments: - {list,init,info,gendoc,test} - kcl plugin sub commands - list list all plugins - init init a new plugin - info show plugin document - gendoc gen all plugins document - test test plugin - -optional arguments: - -h, --help show this help message and exit -``` - -For example, if you want to develop a plugin named io, you can use the following command to successfully create a new io plugin - -``` -kcl-plugin init io -``` - -Then you can use the following command to get the root path of the plugin and cd to the corresponding io plugin directory for development - -``` -kcl-plugin info -``` - -For example, if you want to develop a function read_file to read a file, you can write python code in `plugin.py` of `$plugin_root/io`: - -```python -# Copyright 2020 The KCL Authors. All rights reserved. - -import pathlib - -INFO = { - 'name': 'io', - 'describe': 'my io plugin description test', - 'long_describe': 'my io plugin long description test', - 'version': '0.0.1', -} - - -def read_file(file: str) -> str: - """Read string from file""" - return pathlib.Path(file).read_text() - -``` - -In addition, you can write the corresponding test function in `plugin_test.py`, or you can directly write the following KCL file for testing: - -```python -import kcl_plugin.io - -text = io.read_file('test.txt') -``` - -You can also use the info command to view information about the io plugin - -``` -kcl-plugin info io -``` - -``` -{ - "name": "io", - "describe": "my io plugin description test", - "long_describe": "my io plugin long description test", - "version": "0.0.1", - "method": { - "read_file": "Read string from file" - } -} -``` - -Finally, the plugin that has written the test can be merged with MR in the `kcl_plugins` repository. - -## 50. How to do basic type conversion in KCL - -You can use the `int()`, `float()` function and `str()` function to convert the basic types between `int`, `float` and `str`. - -``` -_t = 1 - -t_str: str = str(_t) # you will get "t_str: '1'" -t_int: int = int(t_str) # you will get "t_int: 1" -t_float: float = float(t_str) # you will get "t_float: 1.0" -``` - -For more information about type conversion, see [KCL Builtin Types](https://kcl-lang.io/docs/reference/lang/tour#built-in-types) and [KCL Type System](https://kcl-lang.io/docs/reference/lang/tour#type-system). diff --git a/versioned_docs/version-0.5.2/user_docs/support/support.md b/versioned_docs/version-0.5.2/user_docs/support/support.md deleted file mode 100644 index fac13ef2..00000000 --- a/versioned_docs/version-0.5.2/user_docs/support/support.md +++ /dev/null @@ -1,3 +0,0 @@ -# FAQ - -KCL frequently asked questions. diff --git a/versioned_docs/version-0.5.3/community/contribute/git-guideline.md b/versioned_docs/version-0.5.3/community/contribute/git-guideline.md deleted file mode 100644 index 7d427c01..00000000 --- a/versioned_docs/version-0.5.3/community/contribute/git-guideline.md +++ /dev/null @@ -1,130 +0,0 @@ -# Git Commit Guide - -This document describes the matters needing attention when Git submits changes. If you refuse to accept the contents of this article, the submitted changes will not be accepted. - -## 1. About issue - -Before submitting an issue, please check the closed issue. There may already be an appropriate solution in the closed issue. - -If no suitable solution is found, we provide four templates to use when creating an issue. - -- Bug Report: If a bug is found, you can contact us by creating an issue through the bug report template. -- Enhancement: The developer has enhanced the tool, and can create an issue through the enhancement template to introduce the added content. -- Feature Request: If you want to add some new features or functions to the tool during use, you can create an issue through the Feature Request template to describe the new features. -- Ask a Question: If you have any questions, you can create an issue through the Ask a Question template to contact us. - -After selecting the appropriate template, you only need to fill in the required content on the template. If you find that there is no template or the template content is empty when creating the issue, you can feed back this problem to us through WeChat group, nail group or email. - -## 2. About Git Branch - -To contribute code to KCL, you must have a GitHub account so that you can push the code to your own branch and create pull requests. We recommend reference [Angular Specification]( https://github.com/angular/angular.js/blob/master/DEVELOPERS.md# -Git commit guidelines) name your own branches. - -The recommended format is as follows: - -``` -{type}-{a_short_description} -``` - -The branch name mainly includes two fields, which are separated by "-". Including: - -- `{type}`: the type of the current branch content. -- `{a_short_description}`: A short description of the main content of this branch. - -For example, Alice first transfers the Fork warehouse to his own account, and then creates a branch with the corresponding name 'alice: fix output fmt bug' (Alice's account is before the colon) to fix the output formatting bug. - -## 3. 关于 Git Commit - -We refer to [Commitizen](https://github.com/commitizen/cz-cli) to write a Commit Message. - -``` -Note: If you directly use Commit to generate a Commit Message, please note that -It is a tool for developers to manage commit. It is not related to the project itself, so it is an intermediate product generated by Commiten -(For example, the node_modules file directory) may not be in the project. gitignore file. - -You can git add {filename} select the file to submit and ignore the intermediate product. -Or you can add the following content to the. gitignore file and automatically ignore the intermediate products: -# commitizen -package.json -package-lock.json -node_modules/* -``` - -If you manually write a commit Message, we also recommend [Commiten](https://github.com/commitizen/cz-cli) for the commit message format. - -``` -{type} ( {component_or_file} ) {a_short_description} -{a_longer_description} -BREAKING CHANGE: {breaking_change_description}. -{linked issue} -``` - -It mainly includes 6 fields: - -- `{type}`: the type of the branch corresponding to the current commit. -- `{component_or_file}`: the name of the module or file that the current commit changes. -- `{a_short_description}`: A short description describes the content of the commit. -- `{a_longer_description}`: The detailed description is used to introduce the content in the commit. -- `{breaking_change_description}`: If the commit contains broken compatibility changes, the impact of compatibility changes needs to be introduced. -- `{linked issue}`: the issue associated with the current commit. - -Where `{breaking_change_description}` and `{linked issue}` can be omitted if the commit does not contain compatibility breaking changes and associated issues. - -For example, the commit created by Alice in branch 'alice: fix output fmt bug'. - -``` -fix(kcl-printer): fix an output format bug in kcl-printer - -There is an output format bug in kcl-printer because ..., -So, The calling of method "XXX" is replaced by "HHHH"..., -... - ---If there is no change to break the compatibility and the associated issue, the following contents can be omitted. -BREAKING CHANGE: This change maybe cause ....... - -fix #123 -``` - -## 4. About pull request - -Before submitting a PR, priority may be given to the following issues: - -- Please check the closed PRs first. There may be completed solutions in the closed PRs. -- We suggest that before submitting the change, submit a corresponding issue to describe the problems to be solved in the change, and associate the PR corresponding to the change with the issue. -- After submitting the PR to us, please sign [Contributor License Agreement (CLA)] (# cla). If you refuse to sign, we will not accept the PR. -- Make sure that each change creates a new branch and names the branch according to the specifications mentioned above. -- PR should not exceed two commit at a time. Please compress the extra commit with squash and write a commit message according to the specifications mentioned above. -- We provide [PR template](https://github.com/kcl-lang/.github/blob/main/.github/PULL_REQUEST_TEMPLATE.md). You only need to add the content required in the template. If you find no template or the template content is empty when creating a PR, you can feed back this problem to us through WeChat group, nail group or email. - -We suggest that the PR title be consistent with the branch name and the commit message style: - -``` -{type} ( {component_name_or_file_name} ) :{a_short_description} -``` - -比如,Alice 为分支`fix/alice/fix_output_fmt_bug`创建的PR名称。 - -For example, Alice creates the PR name `fix/alice/fix_output_fmt_bug` for one branch. - -``` -fix(kcl-printer): fix an output format bug in kcl-printer. -``` - -## 5. Supported PR Types - -``` -- feat: -- New features have been added. -- fix: -- Bug is repaired. -- docs: -- The document part has been modified. -- style: -- The modification of code format does not affect the functions of the code, such as deleting redundant spaces, code indentation, etc. -- refactor: -- refactoring code without changing its function. -- perf: -- Performs performance optimization on the code. -- test: -- Add or adjust existing test cases. -- build: -- Adjust the build system or external dependent libraries. -- ci: -- The configuration file or script of the CI has been adjusted. -- choice: -- Adjustments to other parts of the source code and test files. -- reverse: -- Rollback commit. -``` - -## 6. Contributor License Agreement (CLA) - -After the PR is submitted to us for the first time, the CLA check in the PR will fail and prompt to sign the CLA. You can reply "I have read the CLA Document and I hereby sign the CLA" between your accounts in PR to agree to sign the CLA, and then manually restart the failed CLA check action. After PR is successfully merged, it will be locked and cannot be modified. diff --git a/versioned_docs/version-0.5.3/community/release-policy/kcl.md b/versioned_docs/version-0.5.3/community/release-policy/kcl.md deleted file mode 100644 index a24e1509..00000000 --- a/versioned_docs/version-0.5.3/community/release-policy/kcl.md +++ /dev/null @@ -1,39 +0,0 @@ -# KCL Release Policy - -KCL 开发团队采用 [语义化版本](https://semver.org/lang/zh-CN/) 来简化管理。版本格式:主版本号.次版本号.修订号。版本号递增规则如下:主版本号对应不兼容的 API 修改,次版本号对应向下兼容的功能性新增,修订号对应向下兼容的问题修正。总体目标是每一个半月发布一个特性增强的次要版本,根据需要不定期发布其他版本的修订。 - -KCL 项目版本发布策略如下: - -- 主版本号:当进行重大的架构调整或者加入重大的新功能时,需要提升主版本号。对于 KCL 项目来说,目前的主版本号为 0。 -- 次版本号:当添加的功能和特性有较大的变化时,提升次版本号。目前的次版本号为 5,2023 年度会相继发布 0.5, 0.6, 0.7 版本。 -- 修订号:通过修复漏洞或者改进性能来更新程序时,会提升修订号,修订号从 0 开始计数以此加 1。 -- 发布周期:在未达到 v1.0.0 版本之前,计划每隔 3 个月发布一个新的次要版本。在此期间,需要持续收集用户反馈,并进行必要的修复和改进。 -- 发布流程:在发布新版本之前,需要进行严格的测试和审核,确保新版本的质量。封板并测试完成后,会在 Github 上发布新版本的源代码,二进制和镜像,并提供详细的文档和使用指南。 -- 版本支持:我们将对最新的版本提供长期支持,包括漏洞修复和安全更新。对于旧版本,我们将提供有限的支持,仅在必要时进行修复。 - -## 发布流程与规则 - -- 特性开发:main 分支主干开发,分支发布,block 用户使用的问题和严重的 bug, 安全隐患,高优先级解决,尽可能保持在一周内收敛,高于一般的功能研发。 -- 迭代周期:我们的迭代周期通常为 3 个月,即每 3 个月发布一个新的次要版本。 -- 版本规划:发版前两周产出 alpha 版本,前一周产出 beta 版本,alpha 版本仍可进行特性合并,beta 版本只合并错误修复,最终产出正式版本并打 tag 作为长期保存的 release 分支。 -- 发版计划:在每个发布周期开始时制定详细的发版计划(Github Milestone),包括发布日期、版本号、功能列表和测试计划等。需要尽可能地遵守发版计划,确保按时发布新版本。 -- 发布前测试:在发布新版本之前,需要进行全面的测试,包括单元测试、集成测试,模糊测试,压测,用户验收测试等。只有经过测试并无问题后,我们才会发布新版本。 -- 版本回滚:如果在发布后发现了严重的问题,需要立即回滚版本,并尽快修复问题。并通过邮件、社交媒体等渠道及时通知用户,并提供解决方案。 -- 发布文档:需要在发布时提供详细的文档,包括发布说明、更新日志、API 文档和使用指南等,帮助用户了解和使用新版本。在 KCL 中,我们统一在 KCL 网站进行维护。 -- 版本兼容性:在发布新版本时,需要尽可能保持兼容性,以确保用户无需进行过多的修改和适应。KCL 还没有达到 v1,暂时没有兼容性保证。KCL 的目标是尽可能少地进行重大更改,不应轻率地考虑对语言的更改,为了语言自身更好地演进和发展,一般认为更改具有重大好处时才会进行(较好地解决了目标场景的问题或者提升了绝大用户的使用体验)。对于可能引入兼容性问题的功能或变更,提供相应的提示和解决方案,同时会提供逐步升级的指南或提供自动迁移的工具,以帮助用户平滑地迁移到新版本。 - -## 发布组件 - -![](/img/docs/community/release-policy/kcl-components.png) - -每次版本发布时,KCL 相关所有组件保持一个依赖同一个 KCL 核心主要版本,整体采用树形结构组织依赖顺序发布并进行回归测试,直到发布测试完成,尽力避免三角依赖,禁止循环依赖。 - -## 一个 Feature 的生命周期 - -- 设计方案/文档:通过 Issue 回答清楚这个 feature 的动机是什么,它解决什么问题以及目标是什么,用户需求和用户故事是怎样的;这个 feature 做什么,如何做,难度怎样,需要多长时间,依赖项,需要做什么测试等。(Tips: 大的设计尽量拆分成小的设计,通过权衡和广泛的调研找到一个简单且可持续的解决方案,并且具备一定得到可扩展以适应未来的业务或技术变化,通过持续讨论和方案评审确定最终设计)。 -- 编写代码:通过高频小改动进行迭代、持续沟通和协作,提前设计单元测试、集成测试和 benchmark 等测试用例,确保编写代码 100% 测试覆盖,注释完整和逻辑清晰,并通过 Demo 演示持续收集反馈。 -- 文档撰写:在 [KCL 网站](https://kcl-lang.io) 中更新用户文档。 -- 测试和反馈:在发布功能之前,让一些同行/用户通过**随循文档**而不是口述来尝试和测试这些新功能。接收反馈并改进。 -- 发布和公告:撰写 Release Note, PR 文章,场景和新特性解读等以及渠道宣发等。 - -> 注:以上所有信息全是公开的,需要透出给所有社区研发者进行参与、讨论和贡献。 diff --git a/versioned_docs/version-0.5.3/community/release-policy/roadmap.md b/versioned_docs/version-0.5.3/community/release-policy/roadmap.md deleted file mode 100644 index df220576..00000000 --- a/versioned_docs/version-0.5.3/community/release-policy/roadmap.md +++ /dev/null @@ -1,3 +0,0 @@ -# Roadmap - -![](/img/docs/community/release-policy/roadmap.jpg) diff --git a/versioned_docs/version-0.5.3/reference/lang/error/exception.md b/versioned_docs/version-0.5.3/reference/lang/error/exception.md deleted file mode 100644 index 92c527a6..00000000 --- a/versioned_docs/version-0.5.3/reference/lang/error/exception.md +++ /dev/null @@ -1,1427 +0,0 @@ ---- -title: "KCL Errors and Warnings" -linkTitle: "KCL Errors and Warnings" -type: "docs" -weight: 2 -description: KCL Errors and Warnings ---- - -The articles in this section of the documentation explain the diagnostic error and warning messages that are generated by the KCL. - -**Important:** -**The KCL can report many kinds of errors and warnings. After an error or warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not apply to your project. When you correct issues in your project, always start with the first error or warning that's reported and rebuild often. One fix may make many subsequent errors go away.** - -In the following sections you will find: - -[KCL Syntax Error (E1xxx)](#11-kcl-syntax-error-e1xxx) : The KCL may reports KCL syntax errors when illegal syntax is used in KCL program. - -[KCL Compile Error (E2xxx)](#12-kcl-compile-error-e2xxx): The KCL may reports KCL compile errors when the KCL program conforms to the KCL syntax but does not conform to the KCL semantics. - -[KCL Runtime Error (E3xxx)](#13-kcl-runtime-error-e3xxx): The KCL may report KCL runtime errors when the virtual machine executing a KCL program that passes the compilation. - -[KCL Compile Warning (W2xxx)](#14-kcl-compile-warning-w2xxx): When the compiler compiles KCL programs and finds possible potential errors, such warnings will be reported by KCL. - -## 1.1 KCL Syntax Error (E1xxx) - -This section mainly includes KCL errors: - -| ewcode | KCL exception | messages | -| ------ | ------------------------------------------------------------------- | ----------------------- | -| E1001 | [InvalidSyntaxError](#111-invalidsyntaxerror-e1001) | Invalid syntax | -| E1002 | [KCLTabError](#112-kcltaberror-e1002) | Tab Error | -| E1003 | [KCLIndentationError](#113-kclindentationerrore1003) | Indentation Error | -| E1I37 | [IllegalArgumentSyntaxError](#114-illegalargumentsyntaxerror-e1i37) | Illegal argument syntax | - -### 1.1.1 InvalidSyntaxError (E1001) - -KCL will report `InvalidSyntaxError` when KCL has a syntax error. - -The `ewcode` of `InvalidSyntaxError` is `E1001`. - -For example: - -```python -a, b = 1, 2 # Multiple assign is illegal in KCL syntax -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> /syntax_error/general/multiple_assign/case0/main.k:1:2 - | -1 | a, b = 1, 2 # Multiple assign is illegal in KCL syntax - | ^ expected statement - | -``` - -Possible resolution: - -- Check and fix KCL syntax errors based on the KCL Language Standard - -### 1.1.2 KCLTabError - -KCL will report `KCLTabError` when KCL has a tab and white space syntax error. - -In KCL, it is forbidden to mix tabs and four spaces in one indentation block. And we recommend only using white spaces or tabs for indentation in the entire KCL project, don’t mix them. - -For example: - -```python -schema Person: - name: str # begin with a tab - age: int # begin with four white spaces, - # and four white spaces != tab in the env -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> File /syntax_error/tab/tab_error_0/main.k:6:5 - | -3 | age: int = 1 - | ^ inconsistent use of tabs and spaces in indentation - | -``` - -Possible resolution: - -- Only use a tab or four white spaces in KCL, do not mix them. - -### 1.1.3 KCLIndentationError - -KCL will report `KCLIndentationError` when KCL has an indentation syntax error. - -The KCL syntax includes indentation. A tab or four white spaces in KCL represents an indentation. The other cases will be regarded as syntax errors by KCL. - -For example: - -```python -schema Person: - name: str # a tab or four white spaces is legal. - age: int # three white spaces are illegal - info: str # two white spaces is illegal -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> /syntax_error/indent/indent_error_0/main.k:3:4 - | -3 | age: int # three white spaces are illegal - | ^ unindent 3 does not match any outer indentation level - | -``` - -Possible resolution: - -- Only use a tab or four white spaces in the KCL program for indentation. - -### 1.1.4 IllegalArgumentSyntaxError (E1I37) - -KCL will report `IllegalArgumentSyntaxError` when KCL has an illegal argument in KCL syntax. - -For example: - -```python -# Parameters without default values -# must be in front of parameters with default values. -a = option(type="list", default={"key": "value"}, "key1") -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> /option/type_convert_fail_2/main.k:3:57 - | -3 | a = option(type="list", default={"key": "value"}, "key1") - | ^ positional argument follows keyword argument - | -``` - -Possible resolution: - -```python -func(input_1, ..., input_n, param_with_key_1 = input_with_key_1, ..., param_with_key_n = input_with_key_n) -``` - -## 1.2 KCL Compile Error (E2xxx) - -This section mainly includes KCL errors: - -| ewcode | KCL exception | messages | -| ------ | ---------------------------------------------------------------------- | --------------------------------------------------- | -| E2F04 | [CannotFindModule](#121-cannotfindmodulee2f04) | Cannot find the module | -| E2F05 | [FailedLoadModule](#122-failedloadmodulee2f05) | Failed to load module | -| E2H13 | [UnKnownDecoratorError](#123-unknowndecoratorerrore2h13) | UnKnown decorator | -| E2H14 | [InvalidDecoratorTargetError](#124-invaliddecoratortargeterrore2h14) | Invalid Decorator Target | -| E2C15 | [MixinNamingError](#125-mixinnamingerrore2c15) | Illegal mixin naming | -| E2C16 | [MixinStructureIllegal](#126-mixinstructureillegale2c16) | Illegal mixin structure | -| E2B17 | [CannotAddMembersComplieError](#127-cannotaddmemberscomplieerrore2b17) | Cannot add members to a schema | -| E2B20 | [IndexSignatureError](#128-indexsignatureerrore2b20) | Invalid index signature | -| E2G22 | [TypeComplieError](#129-typecomplieerrore2g22) | The type got is inconsistent with the type expected | -| E2L23 | [CompileError](#1210-compileerrore2l23) | A complie error occurs during compiling | -| E2L25 | [KCLNameError](#1211-kclnameerrore2l25) | Name Error | -| E2L26 | [KCLValueError](#1212-kclvalueerrore2l26) | Value Error | -| E2L27 | [KCLKeyError](#1213-kclkeyerrore2l27) | Key Error | -| E2L28 | [UniqueKeyError](#1214-uniquekeyerrore2l28) | Unique key error | -| E2A29 | [KCLAttributeComplieError](#1215-kclattributecomplieerrore2a29) | Attribute error occurs during compiling | -| E2D32 | [MultiInheritError](#1216-multiinheriterrore2d32) | Multiple inheritance is illegal | -| E2D34 | [IllegalInheritError](#1217-illegalinheriterrore2d34) | Illegal inheritance | -| E2I36 | [IllegalArgumentComplieError](#1218-illegalargumentcomplieerrore2i36) | Illegal argument during compiling | -| E3L41 | [ImmutableCompileError](#1219-immutablecompileerror-e3l41) | Immutable variable is modified | - -### 1.2.1 CannotFindModule(E2F04) - -KCL will report `CannotFindModule` when KCL imports a module that does not exist. - -The `ewcode` of `CannotFindModule` is `E2F04`. - -For example: - -```python -import .some0.pkg1 as some00 # some0 not found in package - -Name1 = some00.Name # some0.pkg1.name -``` - -The KCL program will cause the following error message. - -```shell -error[E2F04]: CannotFindModule - --> import_abs_fail_0/app-main/main.k:1:1 - | -1 | import .some0.pkg1 as some00 # some0 not found in package - | Cannot find the module .some0.pkg1 - | -``` - -Possible resolution: - -- Add the import module file under the import path. - -### 1.2.2 FailedLoadModule(E2F05) - -KCL will report `FailedLoadModule` when an error occurs during loading a KCL external package. - -The `ewcode` of `FailedLoadModule` is `E2F05`. - -Possible resolution: - -- Check whether the module file is readable. -- Check whether the module file is a KCL file. - -### 1.2.3 UnKnownDecoratorError(E2H13) - -KCL will report `UnKnownDecoratorError` when an unknown decorator is used in KCL. - -The `ewcode` of `UnKnownDecoratorError` is `E2H13`. - -For example: - -```python -@err_deprecated # It is an unknown decorator -schema Person: - firstName: str = "John" - lastName: str - name: str - -JohnDoe = Person { - name: "deprecated" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> deprecated/unknown_fail_1/main.k:1:2 - | -1 | @err_deprecated # 这是一个非法的装饰器 - | ^ UnKnown decorator err_deprecated - | -``` - -Possible resolution: - -- Check whether the decorator exists. - -### 1.2.4 InvalidDecoratorTargetError(E2H14) - -KCL will report `InvalidDecoratorTargetError` when the target cannot be the target of the decorator. - -The `ewcode` of `InvalidDecoratorTargetError` is `E2H14`. - -Possible resolution: - -- Check whether the decorator in KCL is illegal. - -### 1.2.5 MixinNamingError(E2C15) - -KCL will report `MixinNamingError` when a mixin name does not end with 'Mixin'. - -The `ewcode` of `MixinNamingError` is `E2C15`. - -For example: - -```python -schema Person: - firstName: str - lastName: str - fullName: str - -schema Fullname: # It is a mixin, but 'Fullname' is not end with 'Mixin - fullName = "{} {}".format(firstName, lastName) - -schema Scholar(Person): - mixin [Fullname] - school: str - -JohnDoe = Scholar { - "firstName": "John", - "lastName": "Doe", - "fullName": "Doe Jon" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2D34]: IllegalInheritError - --> mixin/invalid_name_failure/main.k:10:12 - | -10 | mixin [Fullname] - | ^ illegal schema mixin object type 'Fullname' - | -``` - -Possible resolution: - -- If the schema is a mixin, then the name of the schema should end with Mixin. - -### 1.2.6 MixinStructureIllegal(E2C16) - -KCL will report `MixinStructureIllegal` when the KCL structure is illegal. - -The `ewcode` of `MixinStructureIllegal` is `E2C16`. - -Possible resolution: - -- Check the structure of schema as Mixin. - -### 1.2.7 CannotAddMembersComplieError(E2B17) - -KCL will report `CannotAddMembersComplieError` when members that are not in the schema are used. - -The `ewcode` of `CannotAddMembersComplieError` is `E2B17`. - -For example: - -```python -schema Girl: - gender: str = "female" - -alice = Girl { - "first": "alice", # "first" can not be found in schema Girl - "last": " Green", # "last" can not be found in schema Girl - "age": 10 # "age" can not be found in schema Girl -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:5:5 - | -5 | "first": "alice", - | ^ Cannot add member 'first' to schema 'Girl' - | - -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:6:5 - | -6 | "last": " Green", - | ^ Cannot add member 'last' to schema 'Girl' - | - -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:7:5 - | -7 | "age": 10 - | ^ Cannot add member 'age' to schema 'Girl' - | -``` - -Possible resolution: - -- Add the members to the schema. -- Remove the using of the members not exists - -### 1.2.8 IndexSignatureError(E2B20) - -The `ewcode` of `IndexSignatureError` is `E2B20`. - -KCL will report `IndexSignatureError` when: - -1. Multiple index signatures in one schema. - -For example: - -```python -schema Data: - [str]: str - [str]: int # Multiple index signatures in one schema. - -data = Data { - name: "test" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError ----> index_signature/fail_1/main.k:3:5 - | -3 | [str]: int - | 5 ^ only one index signature is allowed in the schema - | -``` - -Possible resolution: - -- Remove the extra index signature in the schema. - -2. The name of index signature attributes has the same name that conflicts with other attributes in the schema. - -For example: - -```python -schema Data: - name: str # name - [name: str]: str # the same name with the above attribute - -data = Data { - name: "test" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: IndexSignatureError - --> index_signature/fail_2/main.k:3:5 - | -3 | [name: str]: str # the same name with the above attribute - | ^ index signature attribute name 'name' cannot have the same name as schema attributes - | -``` - -Possible resolution: - -- Remove attributes or index signatures that have conflicts with the same name in the schema, or change their names. - -3. Schema index signature value type has conflicts with the instance of schema. - -For example: - -```python -schema Data: - [str]: int - -data = Data { - name: "test" # Conflict with [str]:int, "test" is a string. -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> index_signature/fail_3/main.k:5:5 - | -5 | name: "test" # Conflict with [str]:int, "test" is a string. - | ^ expected int, got str(test) - | -``` - -Possible resolution: - -- Check that the type of schema index signature is consistent with the attribute type in the schema instance. - -4. Schema index signature has conflicts with schema. - -For example: - -```python -schema Data: - count: int # got int - [str]: str # except str - -data = Data { - count: 1 -} -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: IndexSignatureError - --> index_signature/fail_4/main.k:2:5 - | -2 | count: int - | ^ the type 'int' of schema attribute 'count' does not meet the index signature definition [str]: str - | -``` - -Possible resolution: - -- Change schema for index signature or change index signature for schema. - -### 1.2.9 TypeComplieError(E2G22) - -KCL will report `TypeComplieError` when a type error occurs in compiling type check. - -The `ewcode` of `TypeComplieError` is `E2G22`. - -For example: - -```python -schema Person: - firstName: str - lastName: int - -JohnDoe = Person { - "firstName": "John", - "lastName": "Doe" # Type Error,lastName: int,“Doe” is a string. -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> type/type_fail_0/main.k:7:5 - | -7 | "lastName": "Doe" # Type Error,lastName: int,“Doe” is a string. - | ^ expected int, got str(Doe) - | - - --> type/type_fail_0/main.k:3:5 - | -3 | lastName: int - | ^ variable is defined here, its type is int, but got str(Doe) - | -``` - -Possible resolution: - -- Check that the type of value assigned to a variable is consistent with the type of the variable. - -### 1.2.10 CompileError(E2L23) - -The `ewcode` of `CompileError` is `E2L23`. - -KCL will report `CompileError` when: - -1. unsupport type union. - -For example: - -```python -_data = [1, 2, 3] -_data |= "value" -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> union/fail/fail_1/main.k:2:1 - | -2 | _data |= "value" - | ^ unsupported operand type(s) for |: '[int]' and 'str(value)' - | -``` - -Possible resolution: - -1. unsupported operand type. - -For example: - -```python -a = None -b = 1 + None # Unsupport operand type + for int and None -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> operator/operator_fail_0/main.k:2:5 - | -2 | b = 1 + None # Unsupport operand type + for int and None - | ^ unsupported operand type(s) for +: 'int(1)' and 'NoneType' - | -``` - -Possible resolution: - -- Adjust the operator so that it supports both operand types. -- Adjust the operands so that they conform to the constraints of the operator at the same time. - -1. variable is not defined. - -For example: - -```python -a = 1 -b = "${c + 1}" # 'c' is not defined -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> var_not_define_fail_0/main.k:2:8 - | -2 | b = "${c + 1}" # 'c' is not defined - | ^ name 'c' is not defined - | -``` - -Possible resolution: - -- Define undefined variables. -- Remove the undefined variable from the expression. - -1. invalid assign expression. - -For example: - -```python -# pkg.k -a = 1 - -# main.k -import pkg -pkg.a |= 2 -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> pkg_inplace_modify_1/main.k:3:1 - | -6 | pkg |= 2 - | ^ unsupported operand type(s) for |: 'module 'pkg'' and 'int(2)' - | -``` - -Possible resolution: - -- Check the assignment expression. - -1. invalid string expression. - -For example: - -```python -a = 1 -b = "${b = a + 1}" # Invalid string interpolation expression -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> invalid_format_value_fail_0/main.k:2:5 - | -2 | b = "${b = a + 1}" - | 5 ^ invalid string interpolation expression 'b = a + 1' - | -``` - -Possible resolution: - -- Check the string expression. - -1. invalid loop variable. - -For example: - -```python -data = {"key1": "value1", "key2": "value2"} -dataLoop = [i for i, j, k in data] # the number of loop variables can only be 1 or 2 -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> dict/invalid_loop_var_fail_0/main.k:2:25 - | -2 | dataLoop = [i for i, j, k in data] # the number of loop variables can only be 1 or 2 - | ^ the number of loop variables is 3, which can only be 1 or 2 - | -``` - -### 1.2.11 KCLNameError(E2L25) - -KCL will report `KCLNameError` when a name error occurs in compiling. - -The `ewcode` of `KCLNameError` is `E2L25`. - -### 1.2.12 KCLValueError(E2L26) - -KCL will report `KCLValueError` will be raised when a value error occurs in compiling. - -The `ewcode` of `KCLValueError` is `E2L25`. - -### 1.2.13 KCLKeyError(E2L27) - -KCL will report `KCLKeyError` will be raised when a key error occurs in compiling. - -The `ewcode` of `KCLKeyError` is `E2L25`. - -### 1.2.14 UniqueKeyError(E2L28) - -KCL will report `UniqueKeyError` when duplicate names appear in the KCL code. - -The `ewcode` of `UniqueKeyError` is `E2L28`. - -For example: - -```python -schema Person: - name: str = "kcl" - age: int = 1 - -schema Person: - aa: int - -x0 = Person{} -x1 = Person{age:101} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L28]: UniqueKeyError - --> /schema/same_name/main.k:5:8 - | -5 | schema Person: - | ^ Unique key error name 'Person' - | - - --> /schema/same_name/main.k:1:8 - | -1 | schema Person: - | ^ The variable 'Person' is declared here - | -``` - -Possible resolution: - -- Check if the name with error has been used. - -### 1.2.15 KCLAttributeComplieError(E2A29) - -KCL will report `KCLAttributeComplieError` when KCL has an illegal attribute in the schema. - -The `ewcode` of `KCLAttributeComplieError` is `E2A29`. - -For example: - -```python -# pkg -schema A: - field_A: str - -# main -import pkg as p - -a = p.D + 1 -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> /import/module/no_module_attr_fail_0/main.k:4:5 - | -4 | a = p.D + 1 - | ^ module 'pkg' has no attribute D - | -``` - -Possible resolution: - -- Check for the existence of the schema attribute when using it. - -### 1.2.16 MultiInheritError(E2D32) - -KCL will report `MultiInheritError` when multiple inheritance appears in the schema. - -The `ewcode` of `MultiInheritError` is `E2D32`. - -For example: - -```python -schema Person: - firstName: str - lastName: str - -schema KnowledgeMixin: - firstName: int - subject: str - -schema Scholar(KnowledgeMixin, Person): - school: str -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> /schema/inherit/multi_inherit_fail_1/main.k:9:30 - | -9 | schema Scholar(KnowledgeMixin, Person): - | ^ expected one of [")"] got , - | -``` - -Possible resolution: - -- Check the inheritance structure of the program, and multi-inheritance is not supported in KCL. - -### 1.2.17 IllegalInheritError(E2D34) - -KCL will report `IllegalInheritError` when an illegal inheritance occurs in the schema. - -The `ewcode` of `IllegalInheritError` is `E2D34`. - -For example: - -```python -schema FullnameMixin: - fullName = "{} {}".format(firstName, lastName) - -schema Scholar(FullnameMixin): # mixin inheritance is illegal - school: str -``` - -The KCL program will cause the following error message. - -```shell -error[E2D34]: IllegalInheritError - --> /schema/inherit/inherit_mixin_fail/main.k:4:16 - | -4 | schema Scholar(FullnameMixin): - | ^ invalid schema inherit object type, expect schema, got 'FullnameMixin' - | -``` - -Possible resolution: - -- Schema supports single inheritance of schema in KCL. - -### 1.2.18 IllegalArgumentComplieError(E2I36) - -KCL will report `IllegalArgumentComplieError` when the argument of option in KCL is illegal. - -The `ewcode` of `IllegalArgumentComplieError` is `E2I36`. -For example: - -```python -a = option("key") - -# kcl main.k -D key=value= -# key=value= is an illegal expression -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError -Invalid value for top level arguments -``` - -Possible resolution: - -- Check whether the KCL option arguments are legal. - -### 1.2.19 ImmutableCompileError (E3L41) - -KCL will report `ImmutableCompileError` when the value of the immutable variable changes. - -The `ewcode` of `ImmutableCompileError` is `E3L41`. - -For example: - -```python -a = 2147483646 -a += 1 -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: ImmutableError - --> augment_assign/main.k:2:1 - | -2 | a += 1 - | ^ Immutable variable 'a' is modified during compiling - | - - --> augment_assign/main.k:1:1 - | -1 | a = 2147483646 - | ^ The variable 'a' is declared here firstly - | -note: change the variable name to '_a' to make it mutable -``` - -Possible resolution: - -- Set immutable variables changed to private or remove immutable variables. - -## 1.3 KCL Runtime Error (E3xxx) - -This section mainly includes KCL errors: - -| ewcode | KCL exception | messages | -| ------ | ---------------------------------------------------------------------- | --------------------------------------------------- | -| E3F06 | [RecursiveLoad](#131-recursiveload-e3f06) | Recursively loading module | -| E3K04 | [FloatOverflow](#132-floatoverflow-e3k04) | Float overflow | -| E3K09 | [IntOverflow](#133-intoverflow-e3k09) | Integer overflow | -| E3N11 | [DeprecatedError](#134-deprecatederror-e3n11) | Deprecated error | -| E3A30 | [KCLAttributeRuntimeError](#135-kclattributeruntimeerror-e3a30) | Attribute error occurs at runtime | -| E3G21 | [TypeRuntimeError](#136-typeruntimeerror-e3g21) | The type got is inconsistent with the type expected | -| E3B17 | [SchemaCheckFailure](#137-schemacheckfailure-e3b17) | Schema check is failed to check condition | -| E3B19 | [CannotAddMembersRuntimeError](#138-cannotaddmembersruntimeerrore3b19) | Cannot add members to a schema | -| E3M38 | [EvaluationError](#139-evaluationerrore3m38) | Evaluation failure | -| E3M39 | [InvalidFormatSpec](#1310-invalidformatspec-e3m39) | Invalid format specification | -| E3M40 | [KCLAssertionError](#1311-kclassertionerror-e3m40) | Assertion failure | -| E3M44 | [ImmutableRuntimeError](#1312-immutableruntimeerror-e3m44) | Immutable variable is modified | -| E2D33 | [CycleInheritError](#1313-cycleinheriterror-e2d33) | Cycle Inheritance is illegal | -| E3M42 | [KCLRecursionError](#1314-kclrecursionerror-e3m42) | Recursively reference | - -### 1.3.1 RecursiveLoad (E3F06) - -KCL will report `RecursiveLoad` when a cycle import of external packages occurs in KCL. - -The `ewcode` of `RecursiveLoad` is `E2F06`. - -For example: - -```python -# module.k -import main # module.k imports main.k - -print('module') - -# main.k -import module # main.k imports module.k - -print('main') -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /import/recursive_import_fail/main.k:4 - | -2 | import module # main.k imports module.k - | ^ There is a circular import reference between module main and module - | -``` - -Possible resolution: - -- Check whether there is a circle import in KCL. - -### 1.3.2 FloatOverflow (E3K04) - -KCL will report `FloatOverflow` when a floating-point number overflows in KCL. - -The `ewcode` of `FloatOverflow` is `E3K04`. - -For example: - -```python -uplimit = 3.402823466e+39 -epsilon = 2.220446049250313e-16 -a = uplimit * (1 + epsilon) - -# kcl main.k -r -d -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /range_check_float/overflow/number_0/main.k:3:1 - | -3 | a = uplimit * (1 + epsilon) - | 3.4028234660000003e+39: A 32-bit floating point number overflow - | -``` - -Possible resolution: - -- Check whether the value of the float is the float range supported by KCL. - -### 1.3.3 IntOverflow (E3K09) - -KCL will report `IntOverflow` when an integer number overflows in KCL. - -The `ewcode` of `IntOverflow` is `E3K09`. - -For example: - -```python -_a = 9223372036854775807 -_a += 1 - -# kcl test.k -d -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /range_check_int/augment_assign_fail_1/main.k:2:1 - | -2 | _a += 1 - | 9223372036854775808: A 64 bit integer overflow - | -``` - -Possible resolution: - -- Check whether the value of the integer is the integer range supported by KCL. - -### 1.3.4 DeprecatedError (E3N11) - -KCL will report `DeprecatedError` when a deprecated variable is used and the strict is True. - -The `ewcode` of `DeprecatedError` is `E3N11`. - -For example: - -```python -schema Person: - firstName: str = "John" - lastName: str - @deprecated(version="1.16", reason="use firstName and lastName instead", strict=True) - name: str - -JohnDoe = Person { - name: "deprecated" # name is deprecated and strict is True -} -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /range_check_float/overflow/number_0/main.k:7:1 - | -7 | JohnDoe = Person { - | name was deprecated since version 1.16, use firstName and lastName instead - | -``` - -Possible resolution: - -- When strict is set to True, using deprecated code will cause an error and stop KCL. -- You can set the strict to False which will cause a warning insteads of an error. -- Adjust the code without using deprecated code. - -### 1.3.5 KCLAttributeRuntimeError (E3A30) - -KCL will report `KCLAttributeRuntimeError`, if an error occurs during dynamically accessing schema attributes through variables at runtime. - -The `ewcode` of `KCLAttributeRuntimeError` is `E3A30`. - -For example: - -```python -import math - -a = math.err_func(1) # err_func is not found in math -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /import/module/no_module_attr_fail_2/main.k:3:5 - | -3 | a = math.err_func(1) # err_func is not found in math - | ^ module 'math' has no attribute err_func - | -``` - -Possible resolution: - -- Check whether the attributes of schema are correct. - -### 1.3.6 TypeRuntimeError (E3G21) - -KCL will report `TypeRuntimeError` when an type error occurs in the runtime type check. - -The `ewcode` of `TypeRuntimeError` is `E3G21`. - -For example: - -```python -schema Person: - name: str = "Alice" - -_personA = Person {} -_personA |= {"name" = 123.0} # name: str = "Alice" -personA = _personA -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /fail/fail_4/main.k:2:1 - | -2 | name: str = "Alice" - | expect str, got float - | -``` - -Possible resolution: - -- Stop the wrong type union or adjust to the type union supported by KCL. - -### 1.3.7 SchemaCheckFailure (E3B17) - -KCL will report `SchemaCheckFailure` when the schema check conditions are not met. - -The `ewcode` of `SchemaCheckFailure` is `E3B17`. - -For example: - -```python -schema Person: - lastName: str - age: int - check: - age < 140, "age is too large" - -JohnDoe = Person { - "lastName": "Doe", - "age": 1000 # the check condition: age < 140 -} -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /check_block/check_block_fail_1/main.k:7:11 - | -7 | JohnDoe = Person { - | ^ Instance check failed - | - - --> /check_block/check_block_fail_1/main.k:5:1 - | -5 | age < 140, "age is too large" - | Check failed on the condition - | -``` - -Possible resolution: - -- Check whether the attributes of schema can satisfy the conditions in check. - -### 1.3.8 CannotAddMembersRuntimeError(E3B19) - -KCL will report `CannotAddMembersRuntimeError` when members that are not in the schema are used. - -The `ewcode` of `CannotAddMembersRuntimeError` is `E3B19`. - -For example: - -```python -schema Name: - name: str - -schema Person: - name: Name - -person = Person { - name.err_name: "Alice" # err_name is not found in schema Name -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /nest_var/nest_var_fail_1/main.k:8:5 - | -8 | name.err_name: "Alice" # err_name is not found in schema Name - | ^ Cannot add member 'err_name' to schema 'Name' - | -``` - -Possible resolution: - -- Add a non-existent member to the schema. -- Access members that exist in the schema. - -### 1.3.9 EvaluationError(E3M38) - -KCL will report `EvaluationError` when an illegal evaluation occurs in KCL. - -The `ewcode` of `EvaluationError` is `E3M38`. - -For example: - -```python -_list1 = [1, 2, 3] # _list1 is a variable, and its type can only be known at runtime -_list2 = None # _list1 is a variable, and its type can only be known at runtime - -result2 = _list1 + _list2 # list + NoneType is illegal -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /datatype/list/add_None_fail/main.k:1 - | -4 | result2 = _list1 + _list2 # list + NoneType is illegal - | can only concatenate list (not "NoneType") to list - | -``` - -Possible resolution: - -- Check whether the evaluation of the expression is legal. - -### 1.3.10 InvalidFormatSpec (E3M39) - -KCL will report `InvalidFormatSpec` when an illegal string format appears in KCL. - -The `ewcode` of `InvalidFormatSpec` is `E3M39`. - -For example: - -```python -a = 1 -b = 1 -data = "${a: #js}" + " $$ " # #js is illegal string -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /datatype/str_interpolation/invalid_format_spec_fail_0/main.k:3 - | -3 | data = "${a: #js}" + " $$ " # #js is illegal string - | ^ #js is a invalid format spec - | -``` - -Possible resolution: - -- Adjust illegal String to String supported by KCL standards. - -### 1.3.11 KCLAssertionError (E3M40) - -KCL will report `KCLAssertionError` when assert False occurs in KCL. - -The `ewcode` of `KCLAssertionError` is `E3M40`. - -For example: - -```python -assert False -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /assert/invalid/fail_0/main.k:1 - | -1 | assert False - | - | -``` - -Possible resolution: - -- Check the condition of Assert, and when the Assert condition is False, such an error occurs, removing the Assert statement or changing the condition to True. - -### 1.3.12 ImmutableRuntimeError (E3M44) - -KCL will report `ImmutableRuntimeError` when the value of the immutable variable changes. - -The `ewcode` of `ImmutableRuntimeError` is `E3M44`. - -For example: - -```python -schema Person: - final firstName : str - lastName : str - -schema Scholar(Person): - firstName = "CBA" - -scholar = Scholar { - "firstName": "ABC" # firstName in schema Person is final. -} -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /final/fail_lazy_init_0/main.k:8:1 - | -8 | scholar = Scholar { - | attribute 'lastName' of Scholar is required and can't be None or Undefined - | -``` - -Possible resolution: - -- Check if the final variables have been assigned or other changes affect the values of the final variables. - -### 1.3.13 CycleInheritError (E2D33) - -KCL will report `CycleInheritError` when circle inheritance appeared in the schema. - -The `ewcode` of `CycleInheritError` is `E2D33`. - -For example: - -```python -schema Parent(Son): - parent_field: str - -schema Son(GrandSon): - son_field: str - -schema GrandSon(Parent): - grandson_field: str - -parent = Parent { - parent_field: "" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /inherit/cycle_inherit_fail_1/main.k:7:8 - | -7 | schema GrandSon(Parent): - | ^ There is a circular reference between schema GrandSon and Parent - | -``` - -Possible resolution: - -- Check schema inheritance relationship to avoid A inheritance B and B inheritance A at the same time. - -### 1.3.14 KCLRecursionError (E3M42) - -KCL will report `KCLRecursionError` when a circle reference appears in the program. - -The `ewcode` of `KCLRecursionError` is `E3M42`. - -For example: - -```python -schema Parent(Son): - parent_field: str - son: Son = Son { # Parent has attribute Son - parent: Parent { - parent_field: "123" - } - } - -schema Son: - son_field: str - parent: Parent = Parent { # Son has attribute Parent - son: Son { - son_field: "123" - } - } - -parent = Parent { - parent_field: "", -} -``` - -The KCL program will cause the following error message. - -```shell -thread 'main' has overflowed its stack -fatal runtime error: stack overflow -``` - -Possible resolution: - -- Check the members in the schema to avoid the problem of circle references. - -## 1.4 KCL Compile Warning (W2xxx) - -This section mainly includes KCL warnings: - -| ewcode | KCL exception | messages | -| ------ | ------------------------------------------------- | ------------------ | -| W2K04 | [FloatUnderflow](#141-floatunderflow-w2k04) | Float underflow | -| W2P10 | [InvalidDocstring](#142-invaliddocstring-w2p10) | Invalid docstring | -| W2N12 | [DeprecatedWarning](#143-deprecatedwarning-w2n12) | Deprecated warning | - -### 1.4.1 FloatUnderflow (W2K04) - -KCL will report `FloatUnderflow` when a floating-point number underflows in KCL. - -The `ewcode` of `FloatUnderflow` is `W2K08`. - -Possible resolution: - -- Check whether the value of the float number is in the range supported by KCL. - -### 1.4.2 InvalidDocstring (W2P10) - -KCL will report `InvalidDocstring` when a string is illegal in KCL doc. - -The `ewcode` of `InvalidDocstring` is `W2P10`. - -Possible resolution: - -- Please write doc according to KCL standards. - -### 1.4.3 DeprecatedWarning (W2N12) - -KCL will report `DeprecatedWarning` when a deprecated variable is used and the strict is False. - -The `ewcode` of `DeprecatedWarning` is `W2N12`. - -Possible resolution: - -- Try not to use deprecated code. If the strict is True, KCL will output the error and stop running. diff --git a/versioned_docs/version-0.5.3/reference/lang/spec/codestyle.md b/versioned_docs/version-0.5.3/reference/lang/spec/codestyle.md deleted file mode 100644 index dd40925e..00000000 --- a/versioned_docs/version-0.5.3/reference/lang/spec/codestyle.md +++ /dev/null @@ -1,608 +0,0 @@ ---- -title: "Code Style" -linkTitle: "Code Style" -type: "docs" -weight: 2 -description: Code Style ---- - -## Introduction - -This document gives the KCL code style conventions. Good code style can play a vital role in the development and maintenance of the project. We can learn the KCL code style by referring to the full text of the description and sample codes, and use KCL format and lint tools to help coding. - -## Source File Encoding - -KCL file encoding should always use **UTF-8**. - -## Code Layout - -### Indentation - -Use **4 spaces** per indentation level such as in the schema statement and if statement. - -```python -schema PersonA: - name: str # non-recommended - age: int - -schema PersonB: - name: str # recommended - age: int - -if True: - a = 1 # recommended -elif True: - b = 2 # non-recommended -else: - c = 3 # non-recommended -``` - -The closing brace/bracket/parenthesis on multiline constructs should line up under **first character** of the line that starts the multiline construct, as in: - -```python -# valid and recommended -my_list = [ - 1, 2, 3, - 4, 5, 6, -] -``` - -```python -# invalid -my_list = [ - 1, 2, 3, - 4, 5, 6, - ] -``` - -### Tabs or Spaces - -- Spaces are the preferred indentation method. -- Tabs should be used solely to remain consistent with code that is already indented with tabs. - -KCL disallows mixing the use of tabs and spaces for indentation and an error will be reported during the compile time. - -### Blank Lines - -- Surround top-level schema definitions with one blank line. -- Keep at most one blank line between two statements and remove redundant blank lines. -- Remove extra blank characters at the end of the line -- Remove extra blank characters in a blank line. -- There is no blank line in the header of the file, start writing from the first line. -- Only one blank line will be left at the end of the KCL file. - -```python -# Remove blank lines in the file header -a = 1 # Remove white space at the end of the line -# Keep at most one blank line between two statements - -b = 2 -# Only leave one blank line at the end of the file - -``` - -### Inline Expressions - -Write indentation of KCL `if`, `elif`, `else` and other conditions on different lines. - -```python -if True: print("") # non-recommended - -if True: # recommended - print("") -``` - -### Line Break and Continuation lines - -- For long expressions, use the line continuation symbol `\` and keep the left end of multiple expressions aligned. -- The 4-space rule is optional for continuation lines. - -```python -anotherString = "Too long expression " + \ - "Too long expression " # non-recommended - -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " # recommended -``` - -### When to Use Trailing Commas - -- Always use trailing commas. - -### Maximum Line Length - -- The general recommendation is **80 characters** but not absolute. - -### Symbol Break White Space - -Try to keep the spaces between different symbols, but not too many, usually one is good. - -```python -a = 1 # recommended -b = 1 + 2 # non-recommended -``` - -### Whitespace in Expressions and Statements - -Avoid extraneous whitespace in the following situations: - -- The parentheses `()`, brackets `[]` and braces `{}` in the expression have no spaces inside. - -```python -a = (1 + 2) # recommended -b = ( 1 + 2 ) # non-recommended - -c = [1, 2, 3] # recommended -d = [ 1, 2, 3 ] # non-recommended - -e = {key = "value"} # recommended -f = { key = "value" } # non-recommended -``` - -```python -spam(ham[1], {eggs = 2}) # recommended -spam( ham[ 1 ], { eggs = 2 } ) # non-recommended -``` - -- Between a trailing comma and a following close parenthesis. - -```python -foo = [0,] # recommended -bar = [0, ] # non-recommended -``` - -- Immediately before the open parenthesis that starts the argument list of a function call. - -```python -print(1) # recommended -print (1) # non-recommended -``` - -- Immediately before the open parenthesis that starts indexing or slicing. - -```python -dct = {key = "value"} -lst = [1, 2, 3] - -a = dct['key'] # recommended -b = dct ['key'] # non-recommended - -c = lst[0] # recommended -d = lst [1] # non-recommended -``` - -- More than one space around an assignment `=` (or other) operator to align it with another. - -```python -# recommended: -x = 1 -y = 2 -long_variable = 3 -``` - -```python -# non-recommended: -x = 1 -y = 2 -long_variable = 3 -``` - -- Always surround these binary operators with a single space on either side: assignment (`=`), augmented assignment (`+=`, `-=`, etc.), comparisons (`==`, `<`, `>`, `!=`, `<=`, `>=`, `in`, `not in`, `is`, `is not`), booleans (`and`, `or`, `not`). - -```python -# recommended: -i = i + 1 -submitted += 1 -x = x * 2 - 1 -hypot2 = x * x + y * y -c = (a + b) * (a - b) -``` - -```python -# non-recommended: -i = i+1 -submitted+=1 -x = x*2 - 1 -hypot2 = x*x + y*y -c = (a+b) * (a-b) -``` - -- Break one blank line between different statements e.g., import, schema and expression statements. - -```python -import math -import net - -schema Person: - name: str - -person = Person { - name = "Alice" -} -``` - -- Compound statements (multiple statements on the same line) are generally discouraged - -```python -# recommended: -if foo == 'blah': - do_blah_thing() -do_one() -do_two() -do_three() -``` - -```python -# non-recommended: -if foo == 'blah': do_blah_thing() -do_one(); do_two(); do_three() -``` - -## Naming Conventions - -### Naming Styles - -The following naming styles are commonly distinguished: - -- `b` (single lowercase letter) -- `B` (single uppercase letter) -- `lowercase` -- `lower_case_with_underscores` -- `UPPERCASE` -- `UPPER_CASE_WITH_UNDERSCORES` -- `CapitalizedWords` (capitalize all letters of the acronym in `CapitalizedWords` e.g., `HTTPServer`.) -- `mixedCase` (differs from `CapitalizedWords` by initial lowercase character) -- `Capitalized_Words_With_Underscores` (ugly and non-recommended) - -### Names to Avoid - -Never use the characters 'l' (lowercase letter el), 'O' (uppercase letter oh), or 'I' (uppercase letter eye) as single-character variable names. - -### Package and Module Names - -Package and module names should have short, all-lowercase names. - -### Schema Names - -Schema names should normally use the `CapWords` convention. - -### Constants - -Constants are usually defined on a module level and written in all capital letters with underscores separating words such as `MAX_OVERFLOW` and `TOTAL`. - -## Import - -- Imports should usually be on separate lines. -- Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants. -- Imports should be grouped in the following order and we should put a blank line between each group of imports. - 1. Standard library imports. - 2. Related third party plugin imports. - 3. Local application/library specific imports. -- Use an alias when we import a package name with a relatively long path. -- Leave only one space between the Import keyword and the package name. - -```python -import net # recommended -import math # non-recommended - -import ..pkg.internal_pkg as alias_pkg # recommended -``` - -## Comments - -- Comments should be complete sentences. The first word should be capitalized unless it is an identifier that begins with a lower-case letter (never alter the case of identifiers!). -- Block comments generally consist of one or more paragraphs built out of complete sentences, with each sentence ending in a period. -- Use two spaces after a sentence-ending period in multi-sentence comments, except after the final sentence. - -### Block Comments - -Block comments generally apply to some (or all) code that follows them, and are indented to the same level as that code. Each line of a block comment starts with a `#` and **a single space**(unless it is indented text inside the comment). - -Paragraphs inside a block comment are separated by a line containing a single `#`. - -```python -# This is a block comment -a = 1 -``` - -### Inline Comments - -Use inline comments sparingly. - -An inline comment is a comment on the same line as a statement. Inline comments should be separated by **at least two spaces** from the statement. They should start with a `#` and **a single space**. - -```python -a = 1 # This is an inline comment -``` - -### Documentation Strings - -Write doc strings for all public schema and schema attributes. - -```python -schema Person: - """ - Person schema doc string - """ - - name: str = "Alice" -``` - -## String - -- Single-quoted strings and double-quoted strings are the same in KCL. -- Use double-quoted string with lowercase prefix -- For triple-quoted strings, always use double quote characters to be consistent with the docstring convention. -- When a string contains single or double quote characters, use the other one to avoid backslashes in the string. - -```python -strC = "'123'" # recommended -strD = "\"123\"" # non-recommended -``` - -## Number - -- Use lowercase for the prefix of non-decimal numbers, and use uppercase for the number itself. - -```python -foo = 0xAB # recommended -bar = 0Xab # non-recommended -``` - -## Operators - -### Binary Operators - -- Leave only one space before and after the assignment `=`. -- Leave only one space before and after the binary operator in the expression. - -```python -a = 1 # recommended -b=2 # non-recommended -c= 3 # non-recommended -d =4 # non-recommended - -_value = (1 + 2 * 3) # recommended -_value = (1+2*3) # non-recommended -``` - -### Unary Operators - -- There is only no space after unary operators e.g., `~`, `+` and `-`. - -```python -_value = 1 + -2 * ~3 # recommended -_value = 1+ - 2 * ~ 3 # non-recommended -``` - -- There is no space after `**` and `*` in the dict/list deduction expressions and argument expressions. - -```python -_list = [1, 2, 3] -_list = [*_list, [4, 5 ,6]] # recommended -_list = [* _list, [4, 5 ,6]] # non-recommended - -_dict = {**{k = "v"}, **{k = "v"}} # recommended -_dict = {** {k = "v"}, ** {k = "v"}} # non-recommended -``` - -- Use `is not` operator rather than `not ... is`. - -```python -# recommended: -if foo is not None: - a = 1 -``` - -```python -# non-recommended: -if not foo is None: - a = 1 -``` - -## Dict - -- There is no space before the colon `:` at the instantiation of KCL dict and schema config, and a space after the colon `:`. - -```python -d1 = {labels: {k1 = "v1"}} # recommended -d2 = {labels : {k1 = "v1"}} # non-recommended -d3 = {labels :{k1 = "v1"}} # non-recommended -``` - -- Always surround the override attribute operator `=` and the insert attribute operator `+=` with a single space on either sid. - -```python -d1 = {key = "value"} # recommended -d2 = {key= "value"} # non-recommended -d3 = {key ="value"} # non-recommended -``` - -```python -d1 = {key += [0, 1, 2]} # recommended -d2 = {key+= [0, 1, 2]} # non-recommended -d3 = {key +=[0, 1, 2]} # non-recommended -``` - -- Remove all commas at the end of the line in the KCL multiline dict because the end commas of each line are optional. - -```python -d = { - key1 = "value1" - key2 = "value2" - key3 = "value3" - key4 = "value4" -} -``` - -## List - -- Keep only **one space** after the comma `,` separating elements in the list - -```python -a = [1, 2, 3] # recommended -b = [1,2,3] # non-recommended -``` - -- Keep only **one space** before and after the comprehension expression token `for` and `in` in the dict and list. - -```python -a = [i for i in range(10)] # recommended -b = [i for i in range(10)] # non-recommended -``` - -## Slice - -- Keep the same number of spaces before and after the colon `:` of the list slice. - -```python -l = [1, 2, 3] -a = l[0:2] # recommended -b = l[0 : 2] # non-recommended -c = l[0: 2] # non-recommended - -d = l[0 + 0 : 1 + 1] # recommended -e = l[0 + 0:1 + 1] # non-recommended -``` - -## Schema - -- Leave only one space before and after the schema attribute assignment `=`. -- Always add a doc string to a schema, which is a good programming habit. - -```python -schema Person: - """ - Schema doc string - """ - name: str = "Alice" # recommended - age : int=12 # non-recommended - -person = Person {} -``` - -- Keep **no spaces** around the schema inheritance operator `()` - -```python -schema Base: - name: str - -schema Person(Base): # recommended - age: int - -schema Schema ( Base ): # non-recommended - age: int -``` - -- Keep **only one space** between the brackets and the schema name of the config at schema instantiation. - -```python -schema Base: - name: str - -schema Person(Base): - age: int - -personA = Person{} # non-recommended -personB = Person {} # recommended -``` - -- Keep **only one space** between the **mixin** keyword and the following `[]` operator - -```python -schema NameMixin: - name: str = "name" - -schema Person: - mixin [NameMixin] # non-recommended - age: int - -schema Parent: - mixin [NameMixin] # recommended - age: int -``` - -### Attribute Annotations - -- Annotations for schema attributes should have a single space after the colon `:` and no space before the colon `:`. - -```python -# recommended: -schema Person: - name: str # No space before the colon `:` - age: int = 18 # Spaces around assignment`=` -``` - -```python -# non-recommended: -schema Person: - codeA:int # No space after the colon `:` - codeB : int # Space before the colon `:` - name: str="Alice" # No spaces around assignment`=` -``` - -- There are no spaces around the colon `:` in the dict type annotation. - -```python -schema Person: - labels: {str:str} # recommended - keyValues: {str : str} # non-recommended -``` - -### Arguments - -- There are no spaces around the assignment `=` in the function/schema/decorator keyword arguments (kwargs). - -```python -schema Person[nameVar]: - # Decorator kwargs - @deprecated(strict=False) # recommended - name: str = nameVar - - @deprecated(strict = False) # non-recommended - age: int - -# Schema kwargs -personA = Person(nameVar="Alice") {} # recommended -personB = Person(nameVar = "Bob") {} # non-recommended - -# Function kwargs -print("", end='') # recommended -print("", end = '') # non-recommended -``` - -## Keywords - -- Only one space is usually reserved around the keyword, such as `schema`, `mixin`, `is` and `not`, etc. - -```python -schema NameMixin: - check: - name not None - -schema Person: - """ - Person schema definition - """ - mixin [NameMixin] - - name: str = "Alice" - age: int - -person = Person { - age = 18 -} -``` - -## Function - -- There are no spaces around the function/package select operator `.` -- There are no spaces between the function name and the parentheses `()`. - -```python -import math - -print(math.log(10)) # recommended -print( math . log (10)) # non-recommended -``` diff --git a/versioned_docs/version-0.5.3/reference/lang/spec/datatypes.md b/versioned_docs/version-0.5.3/reference/lang/spec/datatypes.md deleted file mode 100644 index ef7ea71a..00000000 --- a/versioned_docs/version-0.5.3/reference/lang/spec/datatypes.md +++ /dev/null @@ -1,452 +0,0 @@ ---- -title: "Data Types" -linkTitle: "Data Types" -type: "docs" -weight: 2 -description: Data Types ---- - -## Syntax - -### Bool - -Boolean values are the two constant objects `False` and `True`. They are used to represent truth values (although other values can also be considered false or true). The built-in function bool() can be used to convert any value to a Boolean, if the value can be interpreted as a truth value. - -### Int - -Int, or integer, is an arbitrarily sized integer, positive or negative, without decimals, of 64 binary digits precision(-9,223,372,036,854,775,808~9,223,372,036,854,775,807). Int is created by int literals or as the result of built-in functions and operators. Unadorned integer literals (including `hex`, `octal` and `binary` numbers) yield integers. The constructor int() can be used to produce int of a specific type. - -Besides, integer literals may have an `SI` or `IEC` multiplier. - -- `SI`: General integer or fixed-point number form: `P`, `T`, `G`, `M`, `K`, `k`, `m`, `u`, `n`. -- `IEC`: Corresponding power of 2: `Pi`, `Ti`, `Gi`, `Mi`, `Ki`. - -```python -a = 1 # positive integer: 1 -b = -1 # negative integer: -1 -c = 0x10 # hexadecimal literal: 16 -d = 0o10 # octal literal: 8, or the form `010` -e = 0b10 # binary literal: 2 -f = 10Ki # integer literal with IEC multiplier: 10240 -g = 1M # integer literal with SI multiplier: 1000000 -h = int("10") # int constructor: 10 -i = int("10Ki") # int constructor with multiplier: 10240 -``` - -Notes: - -- Report an error if unable to represent an integer value precisely. - -### Float - -Float, floating-point, approximation to real numbers, positive or negative, containing one or more decimals, of 64 bit IEEE 754 floats. The constructor float() can be used to produce int of a specific type. - -```python -a = 1.10 -b = 1.0 -c = -35.59 -d = 32.3+e18 -f = -90. -g = -32.54e100 -h = 70.2-E12 -i = float("112") # float constructor -``` - -Notes: - -- Report an error if unable to represent a floating-point value due to overflow -- Report a warning if unable to represent a floating-point value due to underflow. Round to the nearest representable value if unable to represent a floating-point value due to limits on precision. These requirements apply to the result of any expression except for built-in functions for which an unusual loss of precision must be explicitly documented. - -#### None - -In KCL, `None` can indicate that the value of the object is empty, which is similar to `nil` in Go or `null` in Java, and corresponds to `null` in YAML and JSON. - -```python -a = None -b = [1, 2, None] -c = {"key1" = "value1", "key2" = None} -``` - -Please note that `None` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + None # error -b = int(None) # error -c = not None # True -d = None == None # True -e = None or 1 # 1 -f = str(None) # None -``` - -#### Undefined - -`Undefined` is similar to None, but its semantics is that a variable is not assigned any value and will not be output to YAML or JSON. - -```python -a = Undefined -b = [1, 2, Undefined] -c = {"key1" = "value1", "key2" = Undefined} -``` - -Please note that `Undefined` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + Undefined # error -b = int(Undefined) # error -c = not Undefined # True -d = Undefined == Undefined # True -e = Undefined or 1 # 1 -f = str(Undefined) # Undefined -``` - -### Common Numeric Operations - -Int and Float support the following operations (see built-in proposal for built-in details): - -- `x + y`: sum of x and y. -- `x - y`: difference of x and y. -- `x * y`: product of x and y. -- `x / y`: quotient of x and y. -- `x // y`: floored quotient of x and y. -- `x % y`: remainder of x / y. -- `x ** y`: x to the power y. -- `-x`: x negated. -- `+x`: x unchanged. -- `~x`: x bitwise negation. -- `abs(x)`: absolute value or magnitude of x. -- `int(x)`: x converted to integer. -- `float(x)`: x converted to floating point. - -KCL supports mixed arithmetic: when a binary arithmetic operator has operands of different numeric types, the operand with the "narrower" type is widened to that of the other, where integer is narrower than floating-point. - -### String - -Strings are immutable sequences of Unicode characters. String literals are written in a variety of ways: - -```python -'allows embedded "double" quotes' # Single quotes -"allows embedded 'single' quotes" # Double quotes -'''Three single quotes''', """Three double quotes""" # Triple quoted -``` - -Triple quoted strings may span multiple lines. - -Indexing a string produces strings of length 1, for a non-empty string s, `s[0] == s[0:1]`. - -```python -a = "Hello, World!" -b = a[2:5] # "llo" -c = a[-5:-2] # "orl" -d = a[::-1] # "'!dlroW ,olleH'" -``` - -- `str(x=None) -> str` - -Return a string. If _x_ is not provided, raise a runtime error. - -```python -x = str(3.5) # "3.5" -``` - -#### Members - -Built-in function and members of a string - -- `str#len() -> int` - Return the number of characters in the string. -- `capitalize() -> str` - Return a copy of the string with its first character (if any) capitalized and the rest lowercased. -- `count(sub: str, start: int = 0, end: int = -1) -> int` - Returns the number of (non-overlapping) occurrences of substring sub in string, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `endswith(suffix: str, start: int = 0, end: int = -1) -> bool` - Returns `True` if the string ends with the specified suffix, otherwise return `False`, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `find(sub: str, start: int = 0, end: int = -1) -> int` - Returns the lowest index where substring sub is found, or -1 if no such index exists, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `format(*args, **kwargs) -> str` - Perform string interpolation. Format strings contain replacement fields surrounded by curly braces {}. Anything that is not contained in braces is considered literal text, which is copied unchanged to the output. If you need to include a bracket character in the literal text, it can be escaped by doubling: A replacement field can be either a name, a number or empty. Values are converted to strings using the str function. -- `index(sub: str, start: int = 0, end: int = -1) -> int` - Returns the first index where sub is found, or raises an error if no such index exists, optionally restricting to `[start:end]` start being inclusive and end being exclusive. -- `isalnum() -> bool` - Returns True if all characters in the string are alphanumeric (`[a-zA-Z0-9]`) and there is at least one character, False otherwise. -- `isalpha() -> bool` - Returns True if all characters in the string are alphabetic (`[a-zA-Z]`) and there is at least one character. -- `isdigit() -> bool` - Returns True if all characters in the string are digits (`[0-9]`) and there is at least one character. -- `islower() -> bool` - Returns True if all cased characters in the string are lowercase and there is at least one character. -- `isspace() -> bool` - Returns True if all characters are white space characters and the string contains at least one character. -- `istitle() -> bool` - Returns True if the string is in title case and it contains at least one character. This means that every uppercase character must follow an uncased one (e.g., whitespace) and every lowercase character must follow a cased one (e.g., uppercase or lowercase). -- `isupper() -> bool` - Returns True if all cased characters in the string are uppercase and there is at least one character. -- `join(iterable: list) -> str` - Return a string which is the concatenation of the strings in iterable. A TypeError will be raised if there are any non-string values in iterable. The separator between elements is the string providing this method. Example: - - ```python - >>> "|".join(["a", "b", "c"]) - "a|b|c" - ``` - -- `lower() -> str` - Returns a copy of the string with all the cased characters converted to lowercase. -- `lstrip(chars: str) -> str` - Return a copy of the string with leading characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.lstrip() - 'spacious ' - >>> 'www.example.com'.lstrip('cmowz.') - 'example.com' - ``` - -- `replace(old: str, new: str, count: int) -> str` - Return a copy of the string with all occurrences of substring old replaced by new. If the optional argument count is given, only the first count occurrences are replaced. -- `rfind(sub: str, start: int = 0, end: int = -1) -> int` - Return the highest index in the string where substring sub is found, such that sub is contained within s[start:end]. Optional arguments start and end are interpreted as in slice notation. Return -1 on failure. -- `rindex(sub: str, start: int = 0, end: int = -1) -> int` - Returns the last index where sub is found, or raises an ValueError if no such index exists, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `rsplit(sep: str, maxsplit: int = -1) -> list` - Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done, the rightmost ones. If sep is not specified or None, any whitespace string is a separator. Except for splitting from the right, rsplit() behaves like split() which is described in detail below. -- `rstrip(chars: str) -> str` - Return a copy of the string with trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a suffix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.rstrip() - ' spacious' - >>> 'mississippi'.rstrip('ipz') - 'mississ' - ``` - -- `split(sep: str, maxsplit: int) -> list` - Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done (thus, the list will have at most maxsplit+1 elements). If maxsplit is not specified or -1, then there is no limit on the number of splits (all possible splits are made). - - If sep is given, consecutive delimiters are not grouped together and are deemed to delimit empty strings (for example, `'1,,2'.split(',')` returns `['1', '', '2']`). The sep argument may consist of multiple characters (for example, `'1<>2<>3'.split('<>')` returns `['1', '2', '3']`). Splitting an empty string with a specified separator returns `['']`. - - For example: - - ```python - >>> '1,2,3'.split(',') - ['1', '2', '3'] - >>> '1,2,3'.split(',', maxsplit=1) - ['1', '2,3'] - >>> '1,2,,3,'.split(',') - ['1', '2', '', '3', ''] - ``` - - If sep is not specified or is None, a different splitting algorithm is applied: runs of consecutive whitespace are regarded as a single separator, and the result will contain no empty strings at the start or end if the string has leading or trailing whitespace. Consequently, splitting an empty string or a string consisting of just whitespace with a `None` separator returns `[]`. - - For example: - - ```python - >>> '1 2 3'.split() - ['1', '2', '3'] - >>> '1 2 3'.split(maxsplit=1) - ['1', '2 3'] - >>> ' 1 2 3 '.split() - ['1', '2', '3'] - ``` - -- `splitlines(keepends: str) -> list` - Return a list of the lines in the string, breaking at line boundaries('\n', '\r\n', '\r'). Line breaks are not included in the resulting list unless keepends is given and true. - - This method splits on the following line boundaries. In particular, the boundaries are a superset of universal newlines. - - For example: - - ```python - >>> 'ab c\n\nde fg\rkl\r\n'.splitlines() - ['ab c', '', 'de fg', 'kl'] - >>> 'ab c\n\nde fg\rkl\r\n'.splitlines(keepends=True) - ['ab c\n', '\n', 'de fg\r', 'kl\r\n'] - ``` - - Unlike `split()` when a delimiter string sep is given, this method returns an empty list for the empty string, and a terminal line break does not result in an extra line: - - ```python - >>> "".splitlines() - [] - >>> "One line\n".splitlines() - ['One line'] - ``` - - For comparison, `split('\n')` gives: - - ```python - >>> ''.split('\n') - [''] - >>> 'Two lines\n'.split('\n') - ['Two lines', ''] - ``` - -- `startswith(prefix: str, start: int = 0, end: int = -1) -> bool` - Return `True` if string starts with the prefix, otherwise return False. prefix can also be a list of prefixes to look for. With optional start, test string beginning at that position. With optional end, stop comparing string at that position. -- `strip(chars: str) -> str` - Return a copy of the string with the leading and trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix or suffix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.strip() - 'spacious' - >>> 'www.example.com'.strip('cmowz.') - 'example' - ``` - - The outermost leading and trailing chars argument values are stripped from the string. Characters are removed from the leading end until reaching a string character that is not contained in the set of characters in chars. A similar action takes place on the trailing end. For example: - - ```python - >>> comment_string = '#....... Section 3.2.1 Issue #32 .......' - >>> comment_string.strip('.#! ') - 'Section 3.2.1 Issue #32' - ``` - -- `title() -> str` - Return a titlecased version of the string where words start with an uppercase character and the remaining characters are lowercase. - - For example: - - ```python - >>> 'Hello world'.title() - 'Hello World' - ``` - - The algorithm uses a simple language-independent definition of a word as groups of consecutive letters. The definition works in many contexts but it means that apostrophes in contractions and possessives form word boundaries, which may not be the desired result: - - ```python - >>> "they're bill's friends from the UK".title() - "They'Re Bill'S Friends From The Uk" - ``` - -- `upper() -> str` - Return a copy of the string with all the cased characters 4 converted to uppercase. Note that `s.upper().isupper()` might be `False` if s contains uncased characters or if the Unicode category of the resulting character(s) is not “Lu” (Letter, uppercase), but e.g., “Lt” (Letter, titlecase). -- `removeprefix(prefix: str) -> str` - If the string starts with the prefix string, return string[len(prefix):]. Otherwise, return a copy of the original string. - ```python - >>> "prefix-data".removeprefix("prefix-") - "data" - ``` -- `rermovesuffix(suffix: str) -> str` - If the string ends with the suffix string and that suffix is not empty, return string[:-len(suffix)]. Otherwise, return a copy of the original string. - ```python - >>> "data-suffix".removesuffix("-suffix") - "data" - ``` - -### List - -Lists are immutable sequences, typically used to store collections of homogeneous items (where the precise degree of similarity will vary by application). - -Lists may be constructed in several ways: - -- Using a pair of square brackets to denote the empty list: `[]` -- Using square brackets, separating items with commas: `[a]`, `[a, b, c]` -- Using a list comprehension: `[x for x in iterable]` -- Using the type constructor: list() or list(iterable) - -The constructor builds a list whose items are the same and in the same order as iterable’s items.Iterable may be either a sequence, a container that supports iteration, or an iterator object. If iterable is already a list, a copy is made and returned, similar to `iterable[:]`. For example, `list('abc')` returns `['a', 'b', 'c']` and `list([1, 2, 3])` returns `[1, 2, 3]`. If no argument is given, the constructor creates a new empty list `[]`. - -Lists implement all of the common sequence operations. - -#### Members - -- `len()` - Return the number of items in the list. - -### Common Sequence Operations - -The operations in the following table are supported by List and Dict. - -This table lists the sequence operations sorted in ascending priority. In the table, s and t are sequences of the same type, n, i, j and k are integers and x is an arbitrary object that meets any type and value restrictions imposed by s. - -The `in` and `not in` operations have the same priorities as the comparison operations. The + -(concatenation) and \* (repetition) operations have the same priority as the corresponding numeric operations. - -| Operation | Result | Notes | -| ------------ | -------------------------------------------------- | ----- | -| `x in s` | `True` if an item of s is equal to x, else `False` | #1 | -| `x not in s` | `False` if an item of s is equal to x, else `True` | #1 | -| `s + t` | the concatenation of s and t | #5 | -| `s[i]` | ith item of s, origin 0 | #2 | -| `s[i:j]` | slice of s from i to j | #2 #3 | -| `s[i:j:k]` | slice of s from i to j with step k | #2 #4 | -| `min(s)` | smallest item of s | | -| `max(s)` | largest item of s | | - -Notes: - -- 1. While the in and not in operations are used only for simple containment testing in the - general case, some specialized sequences (str) also use them for subsequence testing: - -```python ->>> "gg" in "eggs" -True -``` - -- 2. If i or j is negative, the index is relative to the end of sequence s: `s.len() + i` or `s.len() + j` is substituted. But note that -0 is still 0. -- 3. The slice of s from i to j is defined as the sequence of items with index k such that `i <= k < j`. If i or j is greater than `s.len()`, use `s.len()`. If i is omitted or None, use 0. If j is omitted or None, use `s.len()`. If i is greater than or equal to j, the slice is empty. -- 4. The slice of s from i to j with step k is defined as the sequence of items with index `x = i + n*k` such that `0 <= n < (j-i)/k`. In other words, the indices are `i`, `i+k`, `i+2*k`, `i+3*k` and so on, stopping when j is reached (but never including j). When k is positive, i and j are reduced to s.len() if they are greater. When k is negative, i and j are reduced to s.len() - - - If they are greater. If i or j are omitted or None, they become “end” values (which end depends on the sign of k). Note, k cannot be zero. If k is None, it is treated like 1. - -- 5. Concatenating immutable sequences always results in a new object. This means that building up a sequence by repeated concatenation will have a quadratic runtime cost in the total sequence length. To get a linear runtime cost, you must switch to one of the alternatives below: - - - if concatenating str objects, you can build a list and use `str.join()` at the end - -- 6. `index` raises `ValueError` when x is not found in s. Not all implementations support passing the additional arguments i and j. These arguments allow efficient searching of subsections of the sequence. Passing the extra arguments is roughly equivalent to using `s[i:j].index(x)`, only without copying any data and with the returned index being relative to the start of the sequence rather than the start of the slice. - -### Dict - -Dict is an immutable mapping object maps hashable values to arbitrary objects. A dictionary’s keys are almost arbitrary values. Values that are not hashable, that is, values containing lists, dictionaries may not be used as keys. Numeric types used for keys obey the normal rules for numeric comparison: if two numbers compare equal (such as 1 and 1.0) then they can be used interchangeably to index the same dictionary entry. (Note however, that since computers store floating-point numbers as approximations it is usually unwise to use them as dictionary keys.) Dict is ordered. The order of the keys is the order of their declaration. - -Dictionaries can be created by placing a comma-separated list of keys: value pairs within braces, for example: `{'jack': 4098, 'sjoerd': 4127}` or `{4098: 'jack', 4127: 'sjoerd'}`, by the dict constructor, or list/dict comprehension. - -- `dict(obj)` - -Return a new dictionary initialized from an optional positional argument and a possibly empty set of keyword arguments.If no positional argument is given, an empty dictionary is created. If a positional argument is given and it is a mapping object, a dictionary is created with the same key-value pairs as the mapping object. Otherwise, the positional argument must be an iterable object. Each item in the iterable must itself be an iterable with exactly two objects. The first object of each item becomes a key in the new dictionary, and the second object the corresponding value. If a key occurs more than once, the last value for that key becomes the corresponding value in the new dictionary. If keyword arguments are given, the keyword arguments and their values are added to the dictionary created from the positional argument. If a key being added is already present, the value from the keyword argument replaces the value from the positional argument. To illustrate, the following examples all return a dictionary equal to `{"one": 1, "two": 2, "three": 3}`: - -```python ->>> a = {'two': 2, 'one': 1, 'three': 3} ->>> b = {'one': 1, 'two': 2, 'three': 3} ->>> c = {'three': 3, 'one': 1, 'two': 2} ->>> a == b == c -True -``` - -Providing keyword arguments as in the first example only works for keys that are valid KCL identifiers. Otherwise, any valid keys can be used. - -In the dict comprehension, key/value pairs yielded by the generator expression is set in the dictionary in the order yielded: the first occurrence of the key determines its insertion order, and the last determines the value associated to it. - -```python ->>> {str(i): 2 * i for i in range(3)} -{"0": 0, "1": 2, "2": 4} - ->>> a = {"one": 1, "two": 2, "three": 3} ->>> b = {k: v for k, v in a if v >= 2} -{two: 2, three: 3} -``` - -#### Operations & Members - -These are the operations that dictionaries the support. - -- `list(d)` - Return a list of all the keys used in the dictionary d. -- `len()` - Return the number of items in the dictionary d. -- `d[key]` - Return the item of d with key. Return Undefined if key is not in the map. -- `key in d` - Return True if d has a key, else False. -- `key not in d` - Equivalent to not key in d. -- `d.key` - Return the item of d with key. Return Undefined if key is not in the map. - -Dictionaries compare equal if and only if they have the same (key, value) pairs(keys' ordering matters). Order comparisons (‘<’, ‘<=’, ‘>=’, ‘>’) raise TypeError. - -```python ->>> d = {"one": 1, "two": 2, "three": 3, "four": 4} ->>> d -{'one': 1, 'two': 2, 'three': 3, 'four': 4} ->>> list(d) -['one', 'two', 'three', 'four'] -``` diff --git a/versioned_docs/version-0.5.3/reference/lang/spec/error.md b/versioned_docs/version-0.5.3/reference/lang/spec/error.md deleted file mode 100644 index 2a58b553..00000000 --- a/versioned_docs/version-0.5.3/reference/lang/spec/error.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: "Errors" -linkTitle: "Errors" -type: "docs" -weight: 2 -description: Errors ---- - -When errors happen, developers should be able to detect the error and abort -execution. Thus, KCL introduce the `assert` syntax. - -In the previous topic of `schema` syntax. Errors can also be raised when a -schema is violated. - -## Syntax - -The syntax of the `assert` statement is the following. - -```bnf -assert_stmt: 'assert' test ['if' test] [',' test] -``` - -In the basic form, an `assert` statement evaluates an expression. If the -expression is evaluated to `False`, the assertion is failed, and an error -should be reported. - -In the extended form, an error message can be provided. The error message is -another expression. It is only evaluated when the expression to be evaluated -is evaluated to `False`. The evaluation result of the error message is printed -when reporting the error. - -The following is an example: - -```python -a = 1 -b = 3 -condition = False -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -# if condition is True, then assert `a == b`, if failed, the message "error message" will be printed. -assert a == b if condition, "error message" -``` - -## The Implementation - -When an error happens, no matter it is caused by the `assert` or the `schema` syntax, -the virtual machine should exit with an exit code greater than `0`. - -The virtual machine may choose to dump the back trace information, and it is strongly recommended to implement it. - -In practice, KCL can dump back trace by default, and an argument can be introduced to disable it. diff --git a/versioned_docs/version-0.5.3/reference/lang/spec/expressions.md b/versioned_docs/version-0.5.3/reference/lang/spec/expressions.md deleted file mode 100644 index b52c10f3..00000000 --- a/versioned_docs/version-0.5.3/reference/lang/spec/expressions.md +++ /dev/null @@ -1,915 +0,0 @@ ---- -title: "Expressions" -linkTitle: "Expressions" -type: "docs" -weight: 2 -description: Expressions ---- - -## Syntax - -In KCL, an expression specifies the computation of a value. - -The syntax is the following: - -```bnf -expression: test ("," test)* -test: if_expr | primary_expr | unary_expr | binary_expr -``` - -KCL expressions consist of `if` expression, `primary` expression, `unary` expression, and `binary` expression. - -### Primary Expressions - -Primary expressions are the operands for unary and binary expressions. - -Operands are self-delimiting. An **operand** may be followed by any number of selector dot, a function call, or slice suffixes, to form a primary expression. The grammar uses `expression`, where a multiple-component expression is allowed, and `test` where it accepts an expression of only a single component. - -Syntax: - -```bnf -primary_expr: operand | primary_expr select_suffix | primary_expr call_suffix | primary_expr subscript_suffix -``` - -### Operands - -Operand denotes the elementary value in an expression. An operand may be an identifier, a literal, or a parenthesized expression. - -Syntax: - -```bnf -operand: operand_name | number | string | "True" | "False" | "None" | "Undefined" | list_expr | list_comp | dict_expr | dict_comp | "(" expression ")" -operand_name: identifier | qualified_identifier -``` - -### Identifiers - -In KCL, an identifier is a name, may with selectors, that identifies a value. - -Syntax: - -```bnf -identifier: NAME -``` - -Examples: - -```python -x -a -_b -``` - -Use the `$` character prefix to define keyword identifiers. - -```python -$if = 1 -$else = "s" -``` - -Please note: whether the non-keyword identifier is prefixed with `$` has the same effect. - -```python -_a = 1 -$_a = 2 # equal to `_a = 2` -``` - -To simplify the definition of the qualified identifier, such as 'pkg.type', we additionally define `qualified_identifier`: - -Syntax: - -```bnf -qualified_identifier: identifier "." identifier -``` - -Examples: - -```python -pkg.a -``` - -The package name in qualified_identifier must be imported. - -### Basic Literals - -Basic literals supported in KCL are `int`, `float`, `string` and `bool` including `True` and `False`. Evaluation of basic literal yields a value of the given type with the given value. - -Syntax: - -```bnf -operand: number | string | "True" | "False" | "None" | "Undefined" -``` - -Examples: - -```python -1 -2.3 -"abc" -True -False -None -Undefined -``` - -See more details about **data type** spec. - -### Parenthesized Expressions - -An expression enclosed in parentheses yields the result of that expression. - -Syntax: - -```bnf -operand: '(' expression ')' -``` - -Examples: - -```python -x = (1 + 2) * (3 + 4) # 21 -``` - -### Dictionary Expressions - -A dictionary expression is a comma-separated immutable list of colon-separated key/value expression pairs, enclosed in curly brackets, and it yields a new dictionary object. An optional comma may follow the final pair. - -```bnf -config_expr: '{' config_entries '}' -config_entries: config_entry [config_entry*] -config_comp: '{' (config_entry comp_clause+) '}' -config_entry: expr (':' | '=' | '+=') expr | double_star_expr | if_entry -double_star_expr: "**" expression -if_entry: - 'if' expr ';' if_entry_exec_block - ('elif' expr ':' if_entry_exec_block)* - ('else' ':' if_entry_exec_block)? -NEWLINE: '/r?/n' -``` - -Examples: - -```python -{} -{"one": 1} -{"one": 1, "two": 2} -``` - -The key and value expressions are evaluated in left-to-right order. Evaluation fails if the same key is used multiple times. - -Only hashable values may be used as the keys of a dictionary. This includes all built-in types except dictionaries, and lists. - -We can ignore the comma `,` at the end of the line for writing dict key-value pairs in multiple lines: - -```python -data = { - "key1" = "value1" # Ignore the comma ',' at the end of line - "key2" = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -We can ignore the key quotation marks when we writing simple literals on the key. - -```python -data = { - key1 = "value1" # Ignore the comma ',' at the end of line - key2 = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -In addition, the **config selector expressions** can be used to init a schema instance. - -```python -person = { - base.count = 2 - base.value = "value" - labels.key = "value" -} # {"base": {"count": 2, "value": "value"}, "labels": {"key": "value"}} -``` - -We can **merge** dict using the dict unpacking operator `**` like this: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = {**_part1, **_part2} # {"a: "b", "c": "d"} -``` - -We can use `if expressions` to dynamically add elements to the dict element, elements that meet the conditions are added to the dict, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = { - key1 = "value1" - if a == 1: key2 = "value2" - if a > 0: key3 = "value3" - if a < 0: key4 = "value4" -} # {"key1": "value1", "key2": "value2", "key3": "value3"} -``` - -```python -a = 1 # 1 -data1 = { - key1 = "value1" - if a == 1: - key2 = "value2" - elif a > 0: - key3 = "value3" - else: - key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -data2 = { - key1 = "value1" - if a == 1: key2 = "value2" - elif a > 0: key3 = "value3" - else: key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -``` - -### List Expressions - -A list expression is a comma-separated immutable list of element expressions, enclosed in square brackets, and it yields a new list. An optional comma may follow the last element expression. - -```bnf -list_expr: '[' [list_item [',']] ']' -list_item: test | "*" primary_expr | if_expr -``` - -Element expressions are evaluated in left-to-right order. - -Examples: - -```python -[] # [], empty list -[1] # [1], a 1-element list -[1, 2, 3] # [1, 2, 3], a 3-element list -``` - -We can use `if expressions` to dynamically add elements to the list element, elements that meet the conditions are added to the list, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = [ - 1 - if a == 1: 2 - if a > 0: 3 - if a < 0: 4 -] # [1, 2, 3] -``` - -```python -a = 1 # 1 -data1 = [ - 1 - if a == 1: - 2 - elif a == 2: - 3 - else: - 3 -] # [1, 2] -data2 = [ - 1 - if a == 1: 2 - elif a == 2: 2 - else: 3 -] # [1, 2] -``` - -### Comprehensions - -A comprehension constructs a new list or dictionary value by looping over one or more iterables and evaluating a body expression that produces successive elements of the result. - -Syntax: - -```bnf -list_comp: '[' list_item comp_clause+ ']' . -dict_comp: '{' entry comp_clause+ '}' . - -comp_clause: 'for' loop_variables [","] 'in' test ['if' test] -loop_variables: primary_expr (',' primary_expr)* -``` - -A list comprehension consists of a single expression followed by one or more clauses, the first of which must be a `for` clause. Each `for` clause resembles a `for` statement, and specifies an iterable operand and a set of variables to be assigned by successive values of the iterable. An `if` cause resembles an `if` statement, and specifies a condition that must be met for the body expression to be evaluated. A sequence of `for` and `if` clauses acts like a nested sequence of `for` and `if` statements. - -Examples: - -```python -[x * x for x in range(5)] # [0, 1, 4, 9, 16] -[x * x for x in range(5) if x % 2 == 0] # [0, 4, 16] -[[x, y] for x in range(5) \ - if x % 2 == 0 \ - for y in range(5) \ - if y > x] # [[0, 1], [0, 2], [0, 3], [0, 4], [2, 3], [2, 4]] -``` - -Besides, we can use two variables in the list comprehension, the first variable denotes the list index and the second variable denotes the list item. - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use `_` to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -A dict comprehension resembles a list comprehension, but its body is a pair of expressions, key: value, separated by a colon, and its result is a dictionary containing the key/value pairs for which the body expression was evaluated. Evaluation fails if the value of any key is un-hashable. - -Besides, we can use two variables in the dict comprehension, the first variable denotes the dict key and the second variable denotes the dict value of the key. - -```python -data = {"key1" = "value1", "key2" = "value2"} -# Single variable loop -dataKeys1 = {k: k for k in data} # {"key1": "key1", "key2": "key2"} -dataValues1 = {k: data[k] for k in data} # {"key1": "value1", "key2": "value2"} -# Double variable loop -dataKeys2 = {k: k for k, v in data} # {"key1": "key1", "key2": "key2"} -dataValues2 = {v: v for k, v in data} # {"value1": "value1", "value2": "value2"} -dataFilter = {k: v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use `_` to ignore loop variables -dataKeys3 = {k: k for k, _ in data} # {"key1": "key1", "key2": "key2"} -dataValues3 = {v: v for _, v in data} # {"value1": "value1", "value2": "value2"} -``` - -As with a `for` loop, the loop variables may exploit compound assignment: - -```python -[x * y + z for [x, y], z in [[[2, 3], 5], [["o", 2], "!"]]] # [11, 'oo!'] -``` - -KCL does not accept an un-parenthesized list as the operand of a for clause: - -```python -[x * x for x in 1, 2, 3] # parse error: unexpected comma -``` - -Comprehensions defines a new lexical block, so assignments to loop variables have no effect on variables of the same name in an enclosing block: - -```python -x = 1 -_ = [x for x in [2]] # new variable x is local to the comprehension -print(x) # 1 -``` - -The operand of a comprehension's first clause (always a for) is resolved in the lexical block enclosing the comprehension. In the examples below, identifiers referring to the outer variable named x have been distinguished by subscript. - -```python -x0 = [1, 2, 3] -[x * x for x in x0] # [1, 4, 9] -[x * x for x in x0 if x % 2 == 0] # [4] -``` - -All subsequent for and if expressions are resolved within the comprehension's lexical block, as in this rather obscure example: - -```python -x0 = [[1, 2], [3, 4], [5, 6]] -[x * x for x in x0 for x in x if x % 2 == 0] # [4, 16, 36] -``` - -which would be more clearly rewritten as: - -```python -x = [[1, 2], [3, 4], [5, 6]] -[z * z for y in x for z in y if z % 2 == 0] # [4, 16, 36] -``` - -### Conditional Expressions - -A conditional expression has the form `a if cond else b`. It first evaluates the condition `cond`. If it's true, it evaluates `a` and yields its value; otherwise it yields the value of `b`. - -Syntax: - -```bnf -if_expr: test "if" test "else" test -``` - -Examples: - -```python -x = True if enabled else False # if enabled is -``` - -### Unary Expressions - -In KCL, supported unary operators are `+`, `-`, `~`, and `not`. - -Syntax: - -```bnf -unary_expr: ("+" | "-" | "~") primary_expr - | "not" test -``` - -Usage: - -```bnf -+ number unary positive (int, float) -- number unary negation (int, float) -~ number unary bitwise inversion (int) -not x logical negation (any type) -``` - -The `+` and `-` operators may be applied to any number (int or float) and return the number. -The `not` operator returns the negation of the truth value of its operand. - -Examples: - -```python -~1 # -2 -~-1 # 0 -~0 # -1 -not True # False -not 0 # True -``` - -### Binary Expressions - -In KCL, binary expressions consist of `comparisons`, `logical operations`, `arithmetic operations` and `membership tests`. - -Syntax: - -```bnf -binary_expr: test bin_op test -bin_op: 'or' - | 'and' - | '==' | '!=' | '<' | '>' | '<=' | '>=' - | 'in' | 'not' 'in' - | '|' - | '^' - | '&' - | '-' | '+' - | '*' | '%' | '/' | '//' - | '<<' | '>>' -``` - -#### Logical Operations - -The `or` and `and` operators yield the logical disjunction and conjunction of their arguments, which need not be Booleans. - -The expression `x or y` yields the value of `x` if its truth value is `True`, or the value of `y` otherwise. - -```python -False or False # False -False or True # True -True or True # True -1 or "hello" # 1 -``` - -Similarly, `x` and `y` yields the value of `x` if its truth value is `False`, or the value of `y` otherwise. - -```python -False and False # False -False and True # False -True and True # True -1 and "hello" # "hello" -``` - -These operators use "short circuit" evaluation, so the second expression is not evaluated if the value of the first expression has already determined the result, allowing constructions like these: - -```python -x and x[0] == 1 # x[0] is not evaluated if x is empty -len(x) == 0 or x[0] == "" -not x or not x[0] -``` - -#### Comparisons - -The `==` operator reports whether its operands are equal; the `!=` operator is its negation. - -The operators `<`, `>`, `<=`, and `>=` perform an ordered comparison of their operands. It is an error to apply these operators to operands of unequal type, unless one of the operands is an `int` and the other is a `float`. Of the built-in types, only the following support ordered comparison, using the ordering relation shown: - -```bnf -NoneType # None <= None -bool # False < True -int # mathematical -float # as defined by IEEE 754 -string # lexicographical -list # lexicographical -``` - -Comparison of floating-point values follows the IEEE 754 standard, which breaks several mathematical identities. For example, if `x` is a `NaN` value, the comparisons `x < y`, `x == y`, and `x > y` all yield false for all values of `y`. - -The remaining built-in types support only equality comparisons. Values of type `dict` and `schema` compare equal if their elements compare equal, and values of type function or `builtin_function_or_method` are equal only to themselves. - -```bnf -dict # equal contents -schema # equal exported-attributes -function # identity -builtin_function_or_method # identity -``` - -#### Arithmetic Operations - -The following table summarizes the binary arithmetic operations available for built-in types: - -```bnf -Arithmetic (int or float; result has type float unless both operands have type int) - number + number # addition - number - number # subtraction - number * number # multiplication - number / number # real division (result is always a float) - number // number # floored division - number % number # remainder of floored division - number ^ number # bitwise XOR - number << number # bitwise left shift - number >> number # bitwise right shift - -Concatenation - string + string - list + list - -Repetition (string/list) - int * sequence - sequence * int - -Union - int | int - list | list - dict | dict - schema | schema - schema | dict -basictype | basictype -``` - -The operands of the arithmetic operators `+`, `-`, `*`, `//`, and `%` must both be numbers (`int` or `float`) but need not have the same type. The type of the result has type `int` only if both operands have that type. The result of real division / always has type `float`. - -The `+` operator may be applied to non-numeric operands of the same type, such as two lists, or two strings, in which case it computes the concatenation of the two operands and yields a new value of the same type. - -```python -"Hello, " + "world" # "Hello, world" -[1, 2] + [3, 4] # [1, 2, 3, 4] -``` - -The `*` operator may be applied to an integer n and a value of type `string`, `list`, in which case it yields a new value of the same sequence type consisting of n repetitions of the original sequence. The order of the operands is immaterial. Negative values of n behave like zero. - -```python -'mur' * 2 # 'murmur' -3 * range(3) # [0, 1, 2, 0, 1, 2, 0, 1, 2] -``` - -The `&` operator requires two operands of the same type, such as `int`. For integers, it yields the bitwise intersection (AND) of its operands. - -The `|` operator likewise computes bitwise, unions basic types and unions collection and schema data, such as **list**, **dict** and **schema**. - -Computing bitwise examples: - -```python -0x12345678 | 0xFF # 0x123456FF -``` - -Unioning basic types examples: - -```python -schema x: - a: int | str # attribute a could be a int or string -``` - -A union type is used to define a schema attribute type. See more details in **schema** spec. -Supported types in a union type are `int`, `str`, `float`, `bool`, `list` and `dict`. - -Unioning collection and schema data: - -- Unioning List. Overwrite the list expression on the right side of the operator `|` to the list variable on the left side of the operator one by one according to the **index**. - -```python -_a = [1, 2, 3] -_b = [4, 5, 6, 7] -x = _a | _b # [4, 5, 6, 7] 4 -> 1; 5 -> 2; 6 -> 3; 7 -> None -``` - -Unioning to the specific index or all elements is still under discussion. - -- Unioning Dict. Union the dict expression on the right side of the operator `|` one by one to the dict variable on the left side of the operator according to the **key** - -```python -_a = {key1 = "value1"} -_b = {key1 = "overwrite", key2 = "value2"} -_c = _a | _b # {"key1": "overwrite", "key2": "value2"} -``` - -The union of collection and schema is a new one whose attributes are unioning b to a, preserving the order of the attributes of the operands, left before right. - -Unioning to the specific key or all keys is still under discussion. - -- Unioning Schema. - -The union operation for schema is similar to dict. - -Schema union could be done as: - -```bnf -schema Person: - firstName: str - lastName: str - -_a = Person { - firstName = "John" -} -_b = {lastName = "Doe"} -_a = _a | _b # {"firstName": "John", "lastName": "Doe"} -``` - -Unioning to a specific attribute is still under discussion. Unioning to all attributes is not applicable to schema instances. - -See **selector expression** in **expression** spec for more details. - -The `^` operator accepts operands of `int`. For integers, it yields the bitwise XOR (exclusive OR) of its operands. - -The `<<` and `>>` operators require operands of `int` type both. They shift the first operand to the left or right by the number of bits given by the second operand. It is a dynamic error if the second operand is negative. Implementations may impose a limit on the second operand of a left shift. - -```python -0x12345678 & 0xFF # 0x00000078 -0b01011101 ^ 0b110101101 # 0b111110000 -0b01011101 >> 2 # 0b010111 -0b01011101 << 2 # 0b0101110100 -``` - -#### Membership Tests - -Usage: - -```bnf - any in sequence (list, dict, schema, string) - any not in sequence -``` - -The `in` operator reports whether its first operand is a member of its second operand, which must be a list, dict, schema, or string. The `not in` operator is its negation. Both return a Boolean. - -The meaning of membership varies by the type of the second operand: the members of a list are its elements; the members of a dict are its keys; the members of a string are all its substrings. - -```python -1 in [1, 2, 3] # True - -d = {"one" = 1, "two" = 2} -"one" in d # True -"three" in d # False -1 in d # False -[] in d # False - -"nasty" in "dynasty" # True -"a" in "banana" # True -"f" not in "way" # True - -d = data {one = 1, two = 2} # data is a schema with attributes one and two -"one" in d # True -"three" in d # False -``` - -### Function Invocations - -KCL allows calling built-in functions and functions from built-in and system modules. Whether KCL allows defining new functions is under discussion. - -Syntax: - -```bnf -call_suffix: "(" [arguments [","]] ")" -arguments: argument ("," argument)* -argument: test | identifier "=" test | "*" test | "**" test -``` - -To call a function, the basic way is shown as the following code excerpt: - -```python -print("An argument") - -import math -# 2 powers 3 is 8. -a = math.pow(2, 3) -``` - -As you can see, arguments are separated with `,`. Arguments can only be passed in this way. KCL supports positional arguments and key-value arguments. - -Note that: - -- Some functions have parameters with default values. -- Some functions accept variadic arguments. - -When an argument is not supplied for a parameter without a default value, -an error will be reported. - -### Selector Expressions - -A selector expression selects the attribute or method of the value. - -#### Select Attributes - -Syntax: - -```bnf -select_suffix: ["?"] "." identifier -``` - -KCL provides a wealth of ways to identify or filter attributes. - -x.y - -- schema: it denotes the attribute value of a schema `x` identified by `y` -- package: it denotes the identifier of a package `x` identified by `y` - -Examples: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -name = person.name # "Alice" -age = person.age # 18 -``` - -x?.y - -If the x if None/Undefined or empty(empty list or dict), just return None, otherwise behave as x.y. - -Examples - -```python -noneData = None -data?.name # None - -emptyDict = {} -emptyDict?.name # None - -emptyList = [] -emptyList?[0] # None -``` - -As a supplementary of the `selector` expression in KCL code, the KCL compiler needs to provide corresponding identifying and filtering features through the command line and api form. - -#### Select Methods - -Syntax: - -```bnf -select_suffix: "." identifier -``` - -A `identifier` identifies method belongs to the built-in types `string`, `list`, `dict`, and `schema`. - -- A selector expression fails if the value does not have an attribute of the specified name. -- A selector expression that selects a method typically appears within a call expression, as in these examples: - -Examples: - -```python -["able", "baker", "charlie"].index("baker") # 1 -"banana".count("a") # 3 -"banana".reverse() # error: string has no .reverse field or method -Person.instances() # all instances of schema Person -``` - -But when not called immediately, the selector expression evaluates to a bound method, that is, a method coupled to a specific receiver value. A bound method can be called like an ordinary function, without a receiver argument: - -```bnf -f = "banana".count -f # -f("a") # 3 -f("n") # 2 -``` - -### Index Expressions - -An index expression `a[i]` yields the `i` th element of an indexable type such as a string or list. The index `i` must be an `int` value in the range `-n` ≤ `i` < `n`, where `n` is `len(a)`; any other index results in an error. - -Syntax: - -```bnf -subscript_suffix: "[" [test] "]" -``` - -A valid negative index `i` behaves like the non-negative index `n+i`, allowing for convenient indexing relative to the end of the sequence. - -```python -"abc"[0] # "a" -"abc"[1] # "b" -"abc"[-1] # "c" - -["zero", "one", "two"][0] # "zero" -["zero", "one", "two"][1] # "one" -["zero", "one", "two"][-1] # "two" -``` - -An index expression `d[key]` may also be applied to a dictionary `d`, to obtain the value associated with the specified key. It returns `Undefined` if the dictionary contains no such key. - -An index expression appearing on the left side of an assignment causes the specified list or dictionary element to be updated: - -```python -a = range(3) # a == [0, 1, 2] -b = a[2] # 2 - - -``` - -It is a dynamic error to attempt to update an element of an immutable type, such as a list or string, or a frozen value of a mutable type. - -### Slice Expressions - -A slice expression `a[start:stop:stride]` yields a new value containing a sub-sequence of `a`, which must be a string, or list. - -```bnf -subscript_suffix: "[" [test] [":" [test] [":" [test]]] "]" -``` - -Each of the `start`, `stop`, and `stride` operands is optional; if present, and not `None`, each must be an integer. -The `stride` value defaults to 1. If the stride is not specified, the colon preceding it may be omitted too. It is an error to specify a stride of zero. - -Conceptually, these operands specify a sequence of values `i` starting at start and successively adding `stride` until `i` reaches or passes `stop`. The result consists of the concatenation of values of `a[i]` for which `i` is valid.` - -The effective start and stop indices are computed from the three operands as follows. Let `n` be the length of the sequence. - -**If the stride is positive**: If the `start` operand was omitted, it defaults to -infinity. If the `end` operand was omitted, it defaults to +infinity. For either operand, if a negative value was supplied, `n` is added to it. The `start` and `end` values are then "clamped" to the nearest value in the range 0 to `n`, inclusive. - -**If the stride is negative**: If the `start` operand was omitted, it defaults to +infinity. If the `end` operand was omitted, it defaults to -infinity. For either operand, if a negative value was supplied, `n` is added to it. The `start` and `end` values are then "clamped" to the nearest value in the range -1 to `n`-1, inclusive. - -```python -"abc"[1:] # "bc" (remove first element) -"abc"[:-1] # "ab" (remove last element) -"abc"[1:-1] # "b" (remove first and last element) -"banana"[1::2] # "aaa" (select alternate elements starting at index 1) -"banana"[4::-2] # "nnb" (select alternate elements in reverse, starting at index 4) -``` - -It's not allowed to define a slice expression as a left value in KCL. -Cause list and string are immutable, re-slicing can directly operate to operand to ensure better performance. - -#### Quantifier Expressions - -Quantifier expressions act on collection: list or dict, generally used to obtain a certain result after processing the collection, mainly in the following four forms: - -```bnf -quant_expr: quant_op [ identifier ',' ] identifier 'in' quant_target '{' expr ['if' expr] '}' -quant_target: string | identifier | list_expr |list_comp | dict_expr | dict_comp -quant_op: 'all' | 'any' | 'filter' | 'map' -``` - -- **all** - - Used to detect that all elements in the collection satisfy the given logical expression, and return a boolean value as the result. - - Only when all elements in the collection satisfy the expression true, the `all` expression is true, otherwise it is false. - - If the original collection is empty, return true. - - Supports short-circuiting of logical expressions during expression execution. -- **any** - - Used to detect that at least one element in the collection satisfies the given logical expression, and returns a boolean value as the result. - - When at least one element in the collection satisfies the expression true, the `any` expression is true, otherwise it is false. - - If the original collection is empty, return false. - - Supports short-circuiting of logical expressions during expression execution. -- **map** - - Generate a new **list** by mapping the elements in the original collection. - - The length of the new list is exactly the same as the original collection. -- **filter** - - By logically judging and filtering the elements in the original collection, and returning the filtered sub-collection. - - Only when the element judges the expression to be true, it is added to the sub-collection. - - The type (list, dict and schema) of the new collection is exactly the same as the original collection, and the length range is `[0, len(original-collection)]`. - -**all** and **any** expression sample codes: - -```python -schema Config: - volumes: [{str:}] - services: [{str:}] - - check: - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - }, "invalid cluster ip" - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } -``` - -**map** and **filter** expression sample codes: - -```python -a = map e in [{name = "1", value = 1}, {name = "2", value = 2}] { - {name = e.name, value = int(e.value) ** 2} -} # [{"name": "1", value: 1}, {"name": "2", "value": 4}] - -b = map k, v in {a = "foo", b = "bar"} { v } # ["foo", "bar"] - -c = filter e in [{name = "1", value = 1}, {name = "2", value = 2}] { - int(e.value) > 1 -} # [{"name": "2", "value": 2}] - -d = filter _, v in {a = "foo", b = "bar"} { - v == "foo" -} # {"a": "foo"} -``` - -Please pay attention to distinguish the difference between any expression and any type. When `any` is used in type annotations, it means that the value of the variable is arbitrary, while the any expression means that one of the elements in a set satisfies the condition. diff --git a/versioned_docs/version-0.5.3/reference/lang/spec/kcl-spec.md b/versioned_docs/version-0.5.3/reference/lang/spec/kcl-spec.md deleted file mode 100644 index 63a9d6e7..00000000 --- a/versioned_docs/version-0.5.3/reference/lang/spec/kcl-spec.md +++ /dev/null @@ -1,343 +0,0 @@ ---- -title: "KCL Spec" -linkTitle: "KCL Spec" -type: "docs" -weight: 2 -description: KCL Spec ---- - -## Lexical rules - -### Keywords and reserved words - -The following are the keywords of the KCL: - -```python -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -The following are reserved words for the KCL: - -```python -pass return validate rule flow -def del raise except try -finally while from with yield -global nonlocal struct class final -``` - -### Line comment - -```python -# a comment -``` - -### Operators - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != = -+= -= *= **= /= //= %= -<<= >>= &= ^= -``` - -### Delimiters - -```python -( ) [ ] { } -, : . ; @ -``` - -### Operator precedence - -The following list of operators is ordered from **highest to lowest**: - -| Operator | Description | -| -------------------------------------------------------------------------------- | -------------------------------------------------------- | -| `**` | Exponentiation (highest priority) | -| `+x` `-x` `~x` | Positive, negative, bitwise NOT | -| `*` `/` `%` `//` | Multiplication, division, floor division and remainder | -| `+` `-` | Addition and subtraction | -| `<<` `>>` | Left and right shifts | -| `&` | Bitwise AND | -| `^` | Bitwise XOR | -| \| | Bitwise OR | -| `in`, `not in`, `is`, `is not`, `<`, `<=`, `>`, `>=`, `!=`, `==` | Comparisons, including membership and identity operators | -| `not` | Boolean NOT | -| `and` | Boolean AND | -| `or` | Boolean OR | -| `if – else` | Conditional expression = | -| `=`, `+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `=`, `^=`, `\*\*=`, `//=`, `<<=`, `>>=` | Assign | - -## Grammar - -KCL uses Python's [LarkParser](https://lark-parser.readthedocs.io/en/latest/) tool to describe the grammar, and the specification rules are as follows: - -```bnf -//////////// KCL grammar //////////// -start: (NEWLINE | statement)* - -statement: simple_stmt | compound_stmt -simple_stmt: (assign_stmt | unification_stmt | expr_stmt | assert_stmt | import_stmt | type_alias_stmt) NEWLINE -compound_stmt: if_stmt | schema_stmt | rule_stmt - -//////////// import_stmt //////////// -import_stmt: IMPORT dot_name (AS NAME)? -dot_name: (leading_dots identifier) | identifier -leading_dots: DOT+ - -/////////// assert_stmt //////////// -assert_stmt: ASSERT simple_expr (IF simple_expr)? (COMMA test)? - -//////////// if_stmt //////////// -if_stmt: IF test COLON execution_block (ELIF test COLON execution_block)* (ELSE COLON execution_block)? -execution_block: if_simple_stmt | NEWLINE _INDENT schema_init_stmt+ _DEDENT -if_simple_stmt: (simple_assign_stmt | unification_stmt | expr_stmt | assert_stmt) NEWLINE - -//////////// assign_stmt //////////// -assign_stmt: identifier [COLON type] (ASSIGN identifier)* ASSIGN test - | identifier (COMP_PLUS | COMP_MINUS | COMP_MULTIPLY | COMP_DOUBLE_STAR | COMP_DIVIDE - | COMP_DOUBLE_DIVIDE | COMP_MOD | COMP_AND | COMP_OR | COMP_XOR | COMP_SHIFT_LEFT - | COMP_SHIFT_RIGHT) test - -simple_assign_stmt: identifier ASSIGN test - | identifier (COMP_PLUS | COMP_MINUS | COMP_MULTIPLY | COMP_DOUBLE_STAR | COMP_DIVIDE - | COMP_DOUBLE_DIVIDE | COMP_MOD | COMP_AND | COMP_OR | COMP_XOR | COMP_SHIFT_LEFT - | COMP_SHIFT_RIGHT) test - -//////////// unification_stmt //////////// -unification_stmt: identifier COLON schema_expr - -//////////// schema_stmt //////////// -schema_stmt: [decorators] (SCHEMA|MIXIN|PROTOCOL) NAME [LEFT_BRACKETS [schema_arguments] RIGHT_BRACKETS] [LEFT_PARENTHESES identifier (COMMA identifier)* RIGHT_PARENTHESES] [for_host] COLON NEWLINE [schema_body] -schema_arguments: schema_argument (COMMA schema_argument)* -schema_argument: NAME [COLON type] [ASSIGN test] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt|schema_init_stmt|schema_index_signature)* [check_block] _DEDENT -schema_attribute_stmt: attribute_stmt NEWLINE -attribute_stmt: [decorators] identifier [QUESTION] COLON type [(ASSIGN|COMP_OR) test] -schema_init_stmt: if_simple_stmt | if_stmt -schema_index_signature: LEFT_BRACKETS [NAME COLON] [ELLIPSIS] basic_type RIGHT_BRACKETS COLON type [ASSIGN test] NEWLINE - -//////////// rule_stmt //////////// -rule_stmt: [decorators] RULE NAME [LEFT_BRACKETS [schema_arguments] RIGHT_BRACKETS] [LEFT_PARENTHESES identifier (COMMA identifier)* RIGHT_PARENTHESES] [for_host] COLON NEWLINE [rule_body] -rule_body: _INDENT (string NEWLINE)* check_expr+ _DEDENT - -for_host: FOR identifier - -/////////// decorators //////////// -decorators: (AT decorator_expr NEWLINE)+ -decorator_expr: identifier [call_suffix] - -//////////// type //////////// -type: type_element (OR type_element)* -type_element: schema_type | basic_type | compound_type | literal_type -schema_type: identifier -basic_type: STRING_TYPE | INT_TYPE | FLOAT_TYPE | BOOL_TYPE | ANY_TYPE -compound_type: list_type | dict_type -list_type: LEFT_BRACKETS (type)? RIGHT_BRACKETS -dict_type: LEFT_BRACE (type)? COLON (type)? RIGHT_BRACE -literal_type: string | number | TRUE | FALSE | NONE - -//////////// type alias //////////// -type_alias_stmt: TYPE NAME ASSIGN type - -//////////// check_stmt //////////// -check_block: CHECK COLON NEWLINE _INDENT check_expr+ _DEDENT -check_expr: simple_expr [IF simple_expr] [COMMA primary_expr] NEWLINE - -//////////// mixin_stmt //////////// -mixin_stmt: MIXIN LEFT_BRACKETS [mixins | multiline_mixins] RIGHT_BRACKETS NEWLINE -multiline_mixins: NEWLINE _INDENT mixins NEWLINE _DEDENT -mixins: identifier (COMMA (NEWLINE mixins | identifier))* - - -//////////// expression_stmt //////////// -expr_stmt: testlist_expr -testlist_expr: test (COMMA test)* -test: if_expr | simple_expr -if_expr: simple_expr IF simple_expr ELSE test - -simple_expr: unary_expr | binary_expr | primary_expr - -unary_expr: un_op simple_expr -binary_expr: simple_expr bin_op simple_expr - -bin_op: L_OR | L_AND - | OR | XOR | AND - | SHIFT_LEFT | SHIFT_RIGHT - | PLUS | MINUS | MULTIPLY | DIVIDE | MOD | DOUBLE_DIVIDE - | DOUBLE_STAR - | EQUAL_TO | NOT_EQUAL_TO - | LESS_THAN | GREATER_THAN | LESS_THAN_OR_EQUAL_TO | GREATER_THAN_OR_EQUAL_TO - | IN | L_NOT IN | IS | IS L_NOT | L_NOT | AS -un_op: L_NOT | PLUS | MINUS | NOT - -primary_expr: identifier call_suffix | operand | primary_expr select_suffix | primary_expr call_suffix | primary_expr slice_suffix -operand: identifier | number | string | constant | quant_expr | list_expr | list_comp | config_expr | dict_comp | schema_expr | lambda_expr | LEFT_PARENTHESES test RIGHT_PARENTHESES -select_suffix: [QUESTION] DOT NAME -call_suffix: LEFT_PARENTHESES [arguments [COMMA]] RIGHT_PARENTHESES -slice_suffix: [QUESTION] LEFT_BRACKETS (test | [test] COLON [test] [COLON [test]]) RIGHT_BRACKETS -arguments: argument (COMMA argument)* -argument: test | NAME ASSIGN test | MULTIPLY test | DOUBLE_STAR test - - -//////////// operand //////////// -identifier: NAME (DOT NAME)* -quant_expr: quant_op [ identifier COMMA ] identifier IN quant_target LEFT_BRACE (simple_expr [IF simple_expr] | NEWLINE _INDENT simple_expr [IF simple_expr] NEWLINE _DEDENT)? RIGHT_BRACE -quant_target: string | identifier | list_expr | list_comp | config_expr | dict_comp -quant_op: ALL | ANY | FILTER | MAP -list_expr: LEFT_BRACKETS [list_items | NEWLINE [_INDENT list_items _DEDENT]] RIGHT_BRACKETS -list_items: list_item ((COMMA [NEWLINE] | [NEWLINE]) list_item)* [COMMA] [NEWLINE] -list_item: test | star_expr | if_item -list_comp: LEFT_BRACKETS (list_item comp_clause+ | NEWLINE _INDENT list_item comp_clause+ _DEDENT) RIGHT_BRACKETS -dict_comp: LEFT_BRACE (entry comp_clause+ | NEWLINE _INDENT entry comp_clause+ _DEDENT) RIGHT_BRACE -entry: test (COLON | ASSIGN | COMP_PLUS) test -comp_clause: FOR loop_variables [COMMA] IN simple_expr [NEWLINE] [IF test [NEWLINE]] -if_entry: IF test COLON if_entry_exec_block (ELIF test COLON if_entry_exec_block)* (ELSE COLON if_entry_exec_block)? -if_entry_exec_block: (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry) [NEWLINE] | NEWLINE _INDENT (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry) ((COMMA [NEWLINE] | [NEWLINE]) (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry))* [COMMA] [NEWLINE] _DEDENT -if_item: IF test COLON if_item_exec_block (ELIF test COLON if_item_exec_block)* (ELSE COLON if_item_exec_block)? -if_item_exec_block: list_item [NEWLINE] | NEWLINE _INDENT list_item ((COMMA [NEWLINE] | NEWLINE) list_item)* [COMMA] [NEWLINE] _DEDENT - -star_expr: MULTIPLY test -double_star_expr: DOUBLE_STAR test -loop_variables: primary_expr (COMMA primary_expr)* -schema_expr: identifier (LEFT_PARENTHESES [arguments] RIGHT_PARENTHESES)? config_expr -config_expr: LEFT_BRACE [config_entries | NEWLINE [_INDENT config_entries _DEDENT]] RIGHT_BRACE -config_entries: config_entry ((COMMA [NEWLINE] | [NEWLINE]) config_entry)* [COMMA] [NEWLINE] -config_entry: test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry - -//////////// lambda_expr //////////// -lambda_expr: LAMBDA [schema_arguments] [RIGHT_ARROW type] LEFT_BRACE [expr_stmt | NEWLINE _INDENT schema_init_stmt+ _DEDENT] RIGHT_BRACE - -//////////// misc //////////// -number: DEC_NUMBER [multiplier] | HEX_NUMBER | BIN_NUMBER | OCT_NUMBER | FLOAT_NUMBER -multiplier: SI_N_L | SI_U_L | SI_M_L | SI_K_L | SI_K | SI_M | SI_G | SI_T | SI_P - | SI_K_IEC | SI_M_IEC | SI_G_IEC | SI_T_IEC | SI_P_IEC -string: STRING | LONG_STRING -constant : TRUE | FALSE | NONE | UNDEFINED -// Tokens - -ASSIGN: "=" -COLON: ":" -SEMI_COLON: ";" -COMMA: "," -QUESTION: "?" -ELLIPSIS: "..." -RIGHT_ARROW: "->" -LEFT_PARENTHESES: "(" -RIGHT_PARENTHESES: ")" -LEFT_BRACKETS: "[" -RIGHT_BRACKETS: "]" -LEFT_BRACE: "{" -RIGHT_BRACE: "}" -PLUS: "+" -MINUS: "-" -MULTIPLY: "*" -DIVIDE: "/" -MOD: "%" -DOT: "." -AND: "&" -OR: "|" -XOR: "^" -NOT: "~" -LESS_THAN: "<" -GREATER_THAN: ">" -EQUAL_TO: "==" -NOT_EQUAL_TO: "!=" -GREATER_THAN_OR_EQUAL_TO: ">=" -LESS_THAN_OR_EQUAL_TO: "<=" -DOUBLE_STAR: "**" -DOUBLE_DIVIDE: "//" -SHIFT_LEFT: "<<" -SHIFT_RIGHT: ">>" -AT: "@" - -COMP_PLUS: "+=" -COMP_MINUS: "-=" -COMP_MULTIPLY: "*=" -COMP_DIVIDE: "/=" -COMP_MOD: "%=" -COMP_AND: "&=" -COMP_OR: "|=" -COMP_XOR: "^=" -COMP_DOUBLE_STAR: "**=" -COMP_DOUBLE_DIVIDE: "//=" -COMP_SHIFT_LEFT: "<<=" -COMP_SHIFT_RIGHT: ">>=" - -// Special tokens -IMPORT: "import" -AS: "as" -RULE: "rule" -SCHEMA: "schema" -MIXIN: "mixin" -PROTOCOL: "protocol" -CHECK: "check" -FOR: "for" -ASSERT: "assert" -IF: "if" -ELIF: "elif" -ELSE: "else" -L_OR: "or" -L_AND: "and" -L_NOT: "not" -IN: "in" -IS: "is" -LAMBDA: "lambda" -ALL: "all" -ANY: "any" -FILTER: "filter" -MAP: "map" -TYPE: "type" - -ANY_TYPE: "any" -STRING_TYPE: "str" -INT_TYPE: "int" -FLOAT_TYPE: "float" -BOOL_TYPE: "bool" - -// Constant tokens -TRUE: "True" -FALSE: "False" -NONE: "None" -UNDEFINED: "Undefined" - -// Binary prefix -SI_N_L: "n" -SI_U_L: "u" -SI_M_L: "m" -SI_K_L: "k" -SI_K: "K" -SI_M: "M" -SI_G: "G" -SI_T: "T" -SI_P: "P" -SI_K_IEC: "Ki" -SI_M_IEC: "Mi" -SI_G_IEC: "Gi" -SI_T_IEC: "Ti" -SI_P_IEC: "Pi" -IEC: "i" - -NAME: /\$?[a-zA-Z_]\w*/ -COMMENT: /#[^\n]*/ -NEWLINE: ( /\r?\n[\t ]*/ | COMMENT )+ - -STRING: /r?("(?!"").*?(? [as ] -``` - -The rule to search with the module name is very simple: - -- **Step 1**: Searches the module name from the **standard system modules**, then **plugins modules**. - - See **standard system modules** and **plugins modules** for more details. If matched, the module is imported. Otherwise, continue to **Step 2**. -- **Step 2**. Whether a module name starts with a `.` is checked. If yes, the name is a so-called relative pathname, and we go to **Step 5**. Otherwise, continue to **Step 3**. -- **Step 3**: If the module name does not start with any `.`, then the compiler searches the nearest `root path` directory from this directory to the parent, and find the module according to the name just from the `root path`. If no `root path` is found, find the module according to the name from the folder the `.k` file including this `import` statement exists. - - **root path**: the directory contains a `kcl.mod` file. If matched, the module is imported. Otherwise, continue to **Step 4**. -- **Step 4**: Then the compiler checks if the name is the name of any library module that requires explicit loading. If matched, the library module is imported. Otherwise, continue to **Step 6**. -- **Step 5**. For relative importing, find the module according to the name from the folder the `.k` file including this `import` statement exists. Interpret leading dots using the following rule: -- One dot: Ignore. -- Tow or more dots: Suppose there are `n` leading dots, then the searching starts at `n - 1` levels above this folder. If matched, the module is imported. Otherwise, continue to **Step 6**. -- **Step 6**. Module not found, report an error. - -Do case-sensitive search when the operating system allows. If case-sensitive search is not allowed, search directories before regular files. - -In KCL, the `from <> import <>` is unsupported, and relative import is performed with the `import <>` syntax. - -### Uniqueness of Module - -Each module has a unique location path in its scope, so that a module or package could be located with a unique location path, such as `a.b.c`. - -Searching by location path should be supported by the kcl compiler, which needs to provide corresponding searching features through the command line and api form. - -## Standard System Packages - -KCL supports a few standard system modules. The following is the full list of these standard system modules: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PackageMember
datetimetoday
now
ticks
date
mathceil
exp
expm1
factorial
floor
gcd
isfinite
isinf
isnan
log
log1p
log2
log10
modf
pow
sqrt
regexreplace
match
compile
findall
search
split
unitsn
u
m
k
K
M
G
T
P
Ki
Mi
Gi
Ti
Pi
to_n
to_u
to_m
to_K
to_M
to_G
to_T
to_P
to_Ki
to_Mi
to_Gi
to_Ti
to_Pi
jsonencode
decode
dump_to_file
yamlencode
decode
dump_to_file
netsplit_host_port
join_host_port
fqdn
parse_IP
to_IP4
to_IP16
IP_string
is_IPv4
is_IP
is_loopback_IP
is_multicast_IP
is_interface_local_multicast_IP
is_link_local_multicast_IP
is_link_local_unicast_IP
is_global_unicast_IP
is_unspecified_IP
base64encode
decode
cryptomd5
sha1
sha224
sha256
sha384
sha512
- -- datetime - - ticks() -> float - Return the current time in seconds since the Epoch. Fractions of a second may be present if the system clock provides them. - - date() -> str - return the `%Y-%m-%d %H:%M:%S` format date. - - now() -> str - return the local time. e.g. `'Sat Jun 06 16:26:11 1998'` - - today() -> str - return the `%Y-%m-%d %H:%M:%S.%{ticks}` format date. -- math - - ceil(x) -> int - Return the ceiling of x as an Integral. This is the smallest integer >= x. - - factorial(x) -> int - Return x!. Raise a error if x is negative or non-integral. - - floor(x) -> int - Return the floor of x as an Integral. This is the largest integer <= x. - - gcd(a: int, b: int) -> int - Return the greatest common divisor of x and y - - isfinite(x) -> bool - Return True if x is neither an infinity nor a NaN, and False otherwise. - - isinf(x) -> bool - Return True if x is a positive or negative infinity, and False otherwise. - - isnan(x) -> bool - Return True if x is a NaN (not a number), and False otherwise. - - modf(x) -> Listfloat, float] - Return the fractional and integer parts of x. Both results carry the sign of x and are floats. - - exp(x) -> float - Return e raised to the power of x. - - expm1(x) -> float - Return exp(x)-1. This function avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small x. - - log(x, base=2.71828182845904523536028747135266250) -> float - Return the logarithm of x to the base e. - - log1p(x) -> float - Return the natural logarithm of 1+x (base e). The result is computed in a way which is accurate for x near zero. - - log2(x) -> float - Return the base 2 logarithm of x. - - log10(x) -> float - Return the base 10 logarithm of x. - - pow(x, y) -> float - Return x\*\*y (x to the power of y). - - sqrt(x) -> float - Return the square root of x. -- regex - - replace(string: str, pattern: str, replace: str, count=0) -> str - Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement. - - match(string: str, pattern: str) -> bool - Try to apply the pattern at the start of the string, returning a bool value True if any match was found, or False if no match was found. - - compile(pattern: str) -> bool - Compile a regular expression pattern, returning a bool value denoting whether the pattern is valid. - - findall(string: str, pattern: str) -> List[str] - Return a list of all non-overlapping matches in the string. - - search(string: str, pattern: str) -> bool - Scan through string looking for a match to the pattern, returning a bool value True if any match was found, or False if no match was found. - - split(string: str, pattern: str, maxsplit=0) -> List[str] - Scan through string looking for a match to the pattern, returning a Match object, or None if no match was found. -- units - - Unit constants - - Fixed point: `n`, `u`, `m`, `k`, `K`, `G`, `T` and `P`. - - Power of 2: `Ki`, `Mi`, `Gi`, `Ti` and `Pi`. - - Functions - - to_n(num: int) -> str - Int literal to string with `n` suffix - - to_u(num: int) -> str - Int literal to string with `u` suffix - - to_m(num: int) -> str - Int literal to string with `m` suffix - - to_K(num: int) -> str - Int literal to string with `K` suffix - - to_M(num: int) -> str - Int literal to string with `M` suffix - - to_G(num: int) -> str - Int literal to string with `G` suffix - - to_T(num: int) -> str - Int literal to string with `T` suffix - - to_P(num: int) -> str - Int literal to string with `P` suffix - - to_Ki(num: int) -> str - Int literal to string with `Ki` suffix - - to_Mi(num: int) -> str - Int literal to string with `Mi` suffix - - to_Gi(num: int) -> str - Int literal to string with `Gi` suffix - - to_Ti(num: int) -> str - Int literal to string with `Ti` suffix - - to_Pi(num: int) -> str - Int literal to string with `Pi` suffix -- json - - encode(data: any, sort_keys: bool = False, indent: int = None, ignore_private: bool = False, ignore_none: bool = False) -> str - Serialize a KCL object `data` to a JSON formatted str. - - decode(value: str) -> any - Deserialize `value` (a string instance containing a JSON document) to a KCL object. - - dump_to_file(data: any, filename: str, ignore_private: bool = False, ignore_none: bool = False) -> None - Serialize a KCL object `data` to a JSON formatted str and write it into the file `filename`. -- yaml - - encode(data: any, sort_keys: bool = False, ignore_private: bool = False, ignore_none: bool = False) -> str - Serialize a KCL object `data` to a YAML formatted str. - - decode(value: str) -> any - Deserialize `value` (a string instance containing a YAML document) to a KCL object. - - dump_to_file(data: any, filename: str, ignore_private: bool = False, ignore_none: bool = False) -> None - Serialize a KCL object `data` to a YAML formatted str and write it into the file `filename`. -- net - - split_host_port(ip_end_point: str) -> List[str] - Split the 'host' and 'port' from the ip end point. - - join_host_port(host, port) -> str - Merge the 'host' and 'port'. - - fqdn(name: str = '') -> str - Return Fully Qualified Domain Name (FQDN). - - parse_IP(ip) -> str - Parse 'ip' to a real IP address - - to_IP4(ip) -> str - Get the IP4 form of 'ip'. - - to_IP16(ip) -> int - Get the IP16 form of 'ip'. - - IP_string(ip: str | int) -> str - Get the IP string. - - is_IPv4(ip: str) -> bool - Whether 'ip' is a IPv4 one. - - is_IP(ip: str) -> bool - Whether ip is a valid ip address. - - is_loopback_IP(ip: str) -> bool - Whether 'ip' is a loopback one. - - is_multicast_IP(ip: str) -> bool - Whether 'ip' is a multicast one. - - is_interface_local_multicast_IP(ip: str) -> bool - Whether 'ip' is a interface, local and multicast one. - - is_link_local_multicast_IP(ip: str) -> bool - Whether 'ip' is a link local and multicast one. - - is_link_local_unicast_IP(ip: str) -> bool - Whether 'ip' is a link local and unicast one. - - is_global_unicast_IP(ip: str) -> bool - Whether 'ip' is a global and unicast one. - - is_unspecified_IP(ip: str) -> bool - Whether 'ip' is a unspecified one. -- base64 - - encode(value: str, encoding: str = "utf-8") -> str - Encode the string `value` using the codec registered for encoding. - - decode(value: str, encoding: str = "utf-8") -> str - Decode the string `value` using the codec registered for encoding. -- crypto - - md5(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `MD5` and the codec registered for encoding. - - sha1(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA1` and the codec registered for encoding. - - sha224(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA224` and the codec registered for encoding. - - sha256(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA256` and the codec registered for encoding. - - sha384(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA384` and the codec registered for encoding. - - sha512(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA512` and the codec registered for encoding. -- manifests - - `yaml_stream(values: [any], opts: {str:} = {sort_keys = False, ignore_private = True, ignore_none = False, sep = "---"}`. This function is used to serialize the KCL object list into YAML output with the `---` separator - -### The Built-in System Package - -KCL provides a list of built-in system modules, which are loaded automatically and can be directly used without providing any module name. For example, `print` is a widely used built-in module. - -The following is the full list of these built-in system modules: - -- print() - - The print function. -- multiplyof(a, b) - - Check if the modular result of a and b is 0 -- isunique(inval) - - Check if a list has duplicated elements -- len(inval) - Return the length of a value -- abs(x) - Return the absolute value of the argument. -- all(iterable) - Return True if bool(x) is True for all values x in the iterable. If the iterable is empty, return True. -- any(iterable) - Return True if bool(x) is True for any x in the iterable. If the iterable is empty, return False. -- bin(number) - Return the binary representation of an integer. -- hex(number) - Return the hexadecimal representation of an integer. -- oct(number) - Return the octal representation of an integer. -- ord(c) -> int - Return the Unicode code point for a one-character string. -- sorted(iterable) - Return a new list containing all items from the iterable in ascending order. A custom key function can be supplied to customize the sort order, and the reverse flag can be set to request the result in descending order. -- range(start, end, step=1) - Return the range of a value with start, end and step parameter. -- min(iterable) - With a single iterable argument, return its smallest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the smallest argument. -- max(iterable) - With a single iterable argument, return its biggest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the largest argument. -- sum(iterable, start) - Return the sum of a 'start' value (default: 0) plus an iterable of numbers. When the iterable is empty, return the start value. This function is intended specifically for use with numeric values and may reject non-numeric types. -- pow(x, y, z) - Equivalent to `x**y` (with two arguments) or `x**y % z` (with three arguments). Some types, such as ints, are able to use a more efficient algorithm when invoked using the three argument form. -- round(number, ndigits) - Round a number to a given precision in decimal digits. The return value is an integer if ndigits is omitted or None. Otherwise the return value has the same type as the number. ndigits may be negative. -- typeof(x: any, \*, full_name: bool = False) -> str - Return the type of the value 'x' at runtime. When the 'full_name' is 'True', return the full package type name such as `pkg.schema`. - -### Plugin Modules - -KCL compiler needs to provide the ability to dynamically expand and load plugin modules without modifying the compiler itself. KCL compiler needs to support flexible pluggable module extension mechanism, so that KCL users can use more abundant built-in function capabilities to simplify writing. - -KCL compiler needs to ensure the stability and safety of the expansion mechanism, without affecting the core of the compiler. - -Searching extended plugin module is performed after the standard system module. The standard system module has a higher priority in naming. If it exists a standard or built-in system module with the same name, the extended plugin module will be ignored. - -Importing and using the extended plugin module should be consistent with the standard or built-in system module. - -### Replacing Standard System Packages - -Replacing standard system modules is not allowed. - -## Examples - -We show more module features through an example. - -Suppose we have the following directories and files: - -``` - . - ├── mod1.k - ├── mod2.k - ├── pkg1 - │   ├── def1.k - │   ├── def2.k - │   └── def3init.k - └── pkg2 - ├── file2.k - └── subpkg3 - └── file3.k -``` - -From the structure we can see that `pkg1` and `pkg2` are two packages, `subpkg3` is a subpackage of `pkg2`, and `mod1.k` and `mod2.k` are regular modules. - -### Importing a Standard System Package - -The following statement can import the standard system module `math` - -```python -import math -``` - -This is the only way to import a standard system module. After importing a standard system module, functions, variables and schemas defined in it can be used. For example, the following statement uses the `log10` function -defined in `math` - -```python -a = math.log10(100) # a is 2 after computation. -``` - -### Importing a Regular Module - -In `mod1.k`, we can import `mod2` using one of the following syntaxes. - -```python -import mod2 -``` - -```python -import .mod2 -``` - -The difference is that in the first syntax, the KCL compiler will first try to check if `mod2` matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where `mod1.k` resists in, like what the second statement does. - -Suppose in `mod2.k` there is a definition of a variable:: - -```python -a = 100 -``` - -After importing `mod2`, we can access `a` in `mod1.k` using the following syntax - -```python -b = mod2.a -``` - -### Importing a Package - -In `mod1.k`, we can import `pkg1` using one of the following syntaxes. - -```python -import pkg1 -``` - -```python -import .pkg1 -``` - -The difference is that in the first syntax, the KCL compiler will first try to check if `pkg1` matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where `mod1.k` resists in, like what the second statement does. - -We can use similar statements to import `pkg2`. Note that importing `pkg2` will not import `subpkg3`. - -The name of the package is the name of the imported module. - -Suppose in `file2.k` that is inside `pkg2` there is a definition to variable `foo` - -```python -foo = 100 -``` - -This variable can be used in `mod1.k` after importing `pkg2` like the following - -```python -bar = pkg2.foo -``` - -### Importing a Subpackage - -To import `subpkg3` from `mod1.k`, one of the following statements can be used. - -```python -import pkg2.subpkg3 -``` - -```python -import .pkg2.subpkg3 -``` - -The behaviors of these statements are identical. - -The name of the subpackage is the name of the imported module. - -Suppose in `file3.k` that is inside `subpkg3` there is a definition to variable `foo` - -```python -foo = 100 -``` - -This variable can be used in `mod1.k` after importing `subpkg3` like the following - -```python -bar = subpkg3.foo -``` - -### Relative Importing - -Relative importing is useful when there is code trying to import modules that does not exist recursively inside the current directory. - -For example, the following statements, if written in `file3.k`, can be used to import `pkg2`, `pkg1` and `mod2` respectively. - -```python -import ...pkg2 # Go two levels up then import pkg2 -import ...pkg1 # Go two levels up then import pkg1 -import ...mod2 # Go two levels up then import mod2 -``` - -### Importing from a Root Path - -Suppose we have a `kcl.mod` file in the directory to mark it as a root path, then we have the following files: - -``` - . - |── kcl.mod - ├── mod1.k - ├── mod2.k - ├── pkg1 - │   ├── def1.k - │   ├── def2.k - │   └── def3init.k - └── pkg2 - ├── file2.k - └── subpkg3 - └── file3.k -``` - -In `pkg1` `def1.k`, we can import `pkg2.subpkg3` `file3` using the following syntaxes. - -```python -import pkg2.subpkg3.file3 -``` - -Importing from the root path is very convenient when the code is trying to import modules from a directory needs to look up multiple directories above this directory. At also, it is helpful to organize a large number of files in a root directory. - -### Importing a Module Inside a Package - -Note that `subpkg3` is only implemented with one file `file3.k`. The file can be regarded as a regular module and imported directly. - -In `mod1.k`, the importing statement would be:: - -```python -import pkg2.subpkg3.file3 -``` - -Different from importing `subpkg3`, now the name of the module is `file3`. We can access the variable `foo` defined in this module with the following -statement - -```python -bar = file3.foo -``` - -### Precedence of Importing - -When an import statement specifies a package to import, the virtual machine first looks for a directory named according to the import statement in the file system. - -If such a directory is not found, the virtual machine looks for a single file module. - -For example, when the statement `import a.b.c` appears, the virtual machine first looks for the directory `a/b/c` from the directory of the current file. If `a/b/c` is not found, the virtual machine looks for a file named `a/b/c.k`. If the file is also absent, an error is reported. - -### Package Implemented with Multiple Files - -Package `pkg1` is implemented with multiple KCL files. - -Multiple files can be used to define variables, schemas and functions, and they can access names defined in other files of this package. - -For example, suppose `def1.k` defines a variable `foo`, `def2.k` defines `bar`, and `def3init.k` defines a variable `baz`, when `pkg1` is imported by `mod1.k`, all these variable can be used - -```python -import pkg1 -a = pkg1.foo + pkg1.bar + pkg1.baz -``` - -Inside a module, names defined in a file can be accessed in another file without further importing. For example, suppose `bar` in `def2.k` would invoke `foo` defined in `def1.k`, it can directly use `foo` like the following - -```python -bar = foo + 1 -``` diff --git a/versioned_docs/version-0.5.3/reference/lang/spec/schema.md b/versioned_docs/version-0.5.3/reference/lang/spec/schema.md deleted file mode 100644 index c3d09f65..00000000 --- a/versioned_docs/version-0.5.3/reference/lang/spec/schema.md +++ /dev/null @@ -1,916 +0,0 @@ ---- -title: "Schema" -linkTitle: "Schema" -type: "docs" -weight: 2 -description: Schema ---- - -## Syntax - -### Schema Definition - -A schema is a language element to define a type of configuration data. - -To define a schema, the syntax is the following: - -```bnf -schema_stmt: [decorators] "schema" ["relaxed"] identifier ["[" [arguments] "]"] ["(" operand_name ")"] ":" NEWLINE [schema_body] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt | schema_index_signature | statement)* [check_block] _DEDENT -``` - -Attributes could be defined in a schema, the syntax is the following: - -```bnf -schema_attribute_stmt: [decorators] identifier ["?"] ":" type [(ASSIGN | augassign) test] NEWLINE -``` - -Index signature could be defined in a schema, the syntax is the following: - -```bnf -schema_index_signature: LEFT_BRACKETS [NAME COLON] [ELLIPSIS] basic_type RIGHT_BRACKETS COLON type [ASSIGN test] NEWLINE -``` - -Once defined, an attribute must have a valid type: - -```bnf -type: type_element ("|" type_element)* -type_element: schema_type | basic_type | list_type | dict_type -schema_type: operand_name -basic_type: "str" | "int" | "float" | "bool" -list_type: "[" (type)? "]" -dict_type: "{" (type)? COLON (type)? "}" -``` - -The followings are some basic examples: - -```python -# A person has a first name, a last name and an age. -schema person: - firstName: str - lastName: str - # fullName is generated by firstName and lastName - fullName: str = firstName + ' ' + lastName - # The default value of age is 0 - age: int = 0 - -# An employee IS a person, and has some additional information. -schema employee(person): - bankCard: int - nationality: str - -# A company has a name and many employees. -schema company: - name: str - employees: [employee] -``` - -More complex schema definitions will be elaborated after other concepts are -introduced. - -#### Optional Attribute - -Each attribute **must** be assigned with a not-None value as a schema instance unless it is modified by a question mark as an optional attribute. - -Examples: - -```bnf -schema employee(person): - bankCard?: int # bankCard is an optional attribute - nationality?: str # # nationality is an optional attribute -``` - -When there is an inheritance relationship: - -- If the attribute is optional in the base schema, it could be optional or required in the sub-schema. -- If the attribute is required in the base schema, it must be required in the sub-schema. - -### Configuration Definition - -A configuration is structured data stored in a dict-like structure. In KCL, we have introduced -the configuration definition syntax as a variant of dict definition syntax. - -```bnf -schema_expr: operand_name ("(" [arguments] ")")? dict_expr -``` - -As can be seen, apart from having an identifier as schema type, a configuration definition -is just an ordinary dict definition, and each key in the dict matches an attribute in the schema. - -To simplify configuration, schema attribute key is much easier to define as: - -- schema attribute key can be unquoted. When the attribute key has the same name as a variable, it must be quoted as a normal dict to avoid naming conflict. -- schema attribute key can be defined nested through `select expression`, such as `a.b.c`. - -The comma at the end of each line can be omitted. - -For example, we can define a `person` named `John Doe` using the following statement: - -```python -johnDoe = person { - # In the result, 'lastName' appears later than 'firstName', according the schema - lastName = 'Doe' - firstName = 'John' - # If we don't specify the 'age', the default value 0 is used. - # 'age': 20 -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' - 'age': 0 -} -``` - -Compared to the ordinary dict definition, a configuration definition has the following features: - -- Each attribute defined in the schema (or one of the schemas) could be configured, and config data has higher priority than the default value. -- When an attribute defined in the schema (or one of the schemas) is not configured in the configuration definition statement, and it has a default value, the default value is used. -- Unless the schema (or one of the schemas) is a **relaxed schema**, no more attributes can be defined. -- The quotation marks of dict key can be omitted. -- The comma at the end of each line can be omitted. -- Cases of **inheritance** will be discussed separately. - -For attributes of list, dict and schema types, the config data is added by **union** instead of reassignment. For instance: - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name = { - firstNam = "John" - lastName = "default" - } - -JohnDoe = Person { - name.lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' -} -``` - -#### Attribute Identify - -Each key identifier in the configuration expr identifies an element or a range of elements in a schema. The key identifier may consist of multiple attribute identifiers, and each attribute may be a basic type value, a list, a dict or schema. For example, the key identifier 'a.b.c' identifies the element 'c' in the 'A' schema: - -```python - -schema C: - c: int - -schema B: - b: C - -schema A: - a: B - -A { - a.b.c: 5 -} -``` - -To make the key identifier usage rules as clear as possible, we define the way of identifying with complex data types as follows. - -##### List - -Suppose we have a list attribute a. - -Identify an element in a: - -```python -a[0] # the first element -a[3] # the 4th element -a[-1] # the last element -a[-2] # the penultimate element -``` - -Identify a range of elements in the list: - -```python -a[2:5] # a slice of the third, 4th, and 5th elements -a[:5] # a slice of the first to 5th elements -``` - -#### Attribute Operator - -Once we identified the element(s), we can declare operation on it. It follows the pattern of `identifier op E`. - -#### Union - -Pattern: `identifier : E` - -The value of the expression `E` will be unioned into the element value. - -Examples: - -```python -a = A { - # union {d:4} into the element b.c, suppose c is a schema with an int type attribute d. - b.c : { - d : 4 - } -} -``` - -See 'union' in `expressions` spec for more details. - -#### Override - -Pattern: `identifier = E` - -The value of the expression `E` will override the element value. - -Examples: - -```python -a = A { - # override {c:4} to the element b, suppose b is a schema with an int type attribute c. - b = { - c: 4 - } -} -``` - -Unlike union, the override operation will reassign the element with a brand new value. -For basic type value, `union` and `override` have equivalent effects. - -Note: - -- Especially, we can "delete" its content by overriding the element to `Undefined`, such as `{ a = Undefined }`. - -#### Insert - -Pattern: `identifier += E` -Insert only works for list type `identifier`. - -List `E` will be inserted just after the specified index of the list `identifier`, and the following elements after the index will be automatically shifted. - -Examples: - -```python -a = A { - # insert {c:4} to the end position(just after index=1), suppose b is a list of schema with an int type attribute c. - b += { - c: 4 - } -} -``` - -If no index is specified, the last index will be used. - -The type of 'E' must be compatible with the type of list. See `types` for more details. - -#### Index Signature - -Index signatures can be defined in the KCL schema, and it means that the key-value constraints of the index signature can be used to construct a dict with the schema type, or additional checks can be added to the relaxed schema attributes to enhance the KCL type and semantic checks. - -- Use the form `[{attr_alias}: {key_type}]: {value_type}` to define an index signature in the schema, and `{attr_alias}` can be omitted. - -```python -schema Map: - """ - Map is a relaxed schema with a key of str type and a value of str type - """ - [str]: str # `{attr_alias}` can be omitted. - -data = Map { - key1 = "value1" - key2 = "value2" -} -``` - -- Mandatory all attributes of the schema key and value types - -```python -schema Person: - name: str - age: int # error, conflicts with the index signature definition `[str]: str` - [str]: str # The values of all attributes of the schema can only be strings -``` - -- Mandatory all attribute key and value types are defined in the schema, which is equivalent to restricting all attribute types except the relaxed attributes. - -```python -schema Person: - name: str - age: int - [...str]: str # Except for the `name` and `age` attributes, the key type of all other attributes of the schema must be `str`, and the value type must also be `str`. -``` - -- Define the index signature attribute alias and use it with the check block. - -```python -schema Data: - [dataName: str]: str - check: - dataName in ["Alice", "Bob", "John"] - -data = Data { - Alice = "10" - Bob = "12" - Jonn = "8" # error Jonn not in ["Alice", "Bob", "John"] -} -``` - -```python -import regex - -schema DataMap: - [attr: str]: str - check: - regex.match(attr, r'^[-._a-zA-Z0-9]+$') - -data = DataMap { - key1 = "value1" - "foo.bar" = "value2" # check error -} -``` - -### Schema Context - -The schema definition space can be regarded as a separate function context. - -Init statement could be defined inside the schema, the syntax is the following: - -```bnf -statement: small_stmt NEWLINE | if_stmt -``` - -The following is an example: - -```python -schema Person: - firstName: str = "John" - lastName: str - # fullName is generated by firstName and lastName in a separate init statement - fullName: str = firstName + ' ' + lastName - -JohnDoe = Person { - lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' -} -``` - -If statement, expr statement and assert statement are supported as a schema init -statement. See more in statement spec. - -- The attributes must be defined first, including inherited ones, and then used in the init statement. -- Statements in the schema context will be executed sequentially. -- The value of attributes referenced in the init statement will be evaluated at runtime. - See the **Configuration Definition** section for the assignment rules of non-referenced attributes. For example, `"fullName"` in Person is generated by `"firstName"` and `"lastName"` evaluated at runtime, in which firstName is 'John', and lastName is "Doe". - -The immutability of attributes in the schema context follows the same rules as the immutability of global variables: - -```python -schema Person: - age: int = 1 # Immutable attribute - _name: str = "Alice" # Mutable attribute - - age = 10 # Error - _name = "Bob" # Ok -``` - -#### Arguments - -Schema context can also have arguments. The following is an example. - -```python -schema Person[separator]: - firstName: str = "John" - lastName: str - fullName: str = firstName + separator + lastName - -JohnDoe = Person('_') { - lastName = "Doe" -} -``` - -The example is similar to the previous one, except that the separator character used in -the `"fullName"` member is passed in as an argument. The way to perform a schema generation -when the schema has an initialization function with arguments is demonstrated in the code. - -### Check Block - -Optionally, a check block can be added to a schema definition to allow -additional checking to be performed. - -The syntax is the following: - -```bnf -check_block: "check" ":" NEWLINE _INDENT check_expr+ _DEDENT -check_expr: test (IF test)? [":" primary_expr] NEWLINE -``` - -In terms of grammatical definition, a check block consists of a list of conditional expressions. The following is an example: - -```python -schema employee(person): - bankCard: int - gender: str - - check: - len(str(bankCard)) == 16 - gender in ['male', 'female'], "The gender {} is unsupported".format(gender) -``` - -The ability of KCL check expressions covers the abilities that can be defined by OpenAPI spec and is aligned with the ability of logical expressions. We consider further aligning the syntax with `CEL` spec. -Whether to support `lambda expressions` is still under discussion. - -Summary: - -- A check block consists of one or more logical **expressions**. -- When defining a configuration, the expressions in the check block are evaluated - in any order. If any of the expression is `False`, an error is reported. -- A custom error message can be provided after an expression. - -### Specifying Types - -Optionally, the type of any member of a schema can be specified. As previous examples have shown. - -A member can be of a basic type, such as a string (`str`), a floating-point number (`float`), a fixed-point number (`int`) or a boolean number (`bool`). - -A member can also be of a dictionary generated from another schema. In such a case, the name of the other schema is used as the type name. - -A member can also be a list or an ordinary dict: - -- A list with unspecified type of elements is `[]`. -- A list with elements of type `t` is `[t]`. Here `t` is another type. -- A dict with keys of type `kt` and values of type `vt` is `{kt:vt}`. -- `kt`, `vt` or both of them can be missing, like a list with unspecified type of elements. - -The followings are some more examples: - -- A list of lists of strings: `[[str]]`. -- A dict of keys with the type string and unspecified value types: `{str:}`. - -A member can be a **union type** defined by `|`, such as `a | b`, which means the type of the member could be a or b. - -A union type can include types of `int`, `str`, `float`, `bool`, `list` and `dict` and support type nesting e.g. `{str:str|int}` and `[[int|str]|str|float]`, etc. - -Examples: - -```python -schema x: - p: int | str # p could be defined as a int or string -``` - -### Immutability - -KCL pursues strict immutability of schema attributes. It's generally followed the rules: - -- For the attributes of the basic type, such as string, int and float, it's allowed to be reassigned - through the init statement in **schema context** or by the **configuration definition**. -- For the attributes of list, dict and schema type, it's allowed to be reassigned only by the init statement in **schema context**. The content of it is allowed to be operated in **schema context** or by the **configuration definition**. -- Any other attempt to reassign or modify schema attribute will report an error. - -#### Assign by Value - -When using a schema variable to assign the value to another variable, we can only get a deep copy of its value, not a pointer or reference. That is, modifying the assigned value will not change the assigned schema variable. - -```python -schema Person: - name: str - -person = { - name = "Alice" -} -personCopy = person # 'personCopy' is a deep copy of 'person' and modifying 'personCopy' will not affect 'person' -``` - -### Union Operator - -For list, dict and schema, we can union delta to existing data. For example: - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name = { - firstName = "John" - } - - # union a schema and a dict - name: Name { - lastName = "Doe" - } - -person = Person {} -``` - -The result is a **dict**: - -```python -{ - 'person': { - 'name': { - 'firstName': 'Jhon', - 'lastName': 'Doe' - } - } -} -``` - -### Other Operators - -Except for `assignment` and `union assignment`, it's not support other operators on schema type data. -Report an error if trying to use other operators on schema type data. - -### Deprecated - -The schema attribute can be marked as deprecated once it's considered invalid. - -```python -schema Person: - @deprecated(version="1.1.0", reason="use fullName instead", strict=True) - name: str - ... # Omitted contents - -person = Person { - # report an error on configing a deprecated attribute - name = "name" -} -``` - -- Deprecated attributes cannot be configured under any circumstances. Report an error or warning once the attribute is assigned. -- Define the expired version of the attribute through **version**, and define the reason for the attribute expired through **reason**. -- When strict is true, the attribute assignment will cause an error, otherwise it will report a warning and ignore the attribute assignment. - -### Composition - -The composition is a common way to define complex structures. KCL provides simplified means for the configuration definition of combined structures. - -Assuming we have the following schemas, which is defined by a combination of multiple schemas. - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name - age: int - -schema Group: - name: str - persons: [Person] -``` - -To config a group: - -```python -group = Group { - name = "group" - persons = [{ - name = { - firstName = "John" - lastName = "Doe" - } - age = 24 - }] -} -``` - -- Top-level schema name is required to config a schema. -- The schema of the attributes in the schema can be omitted. - -Multi-level nested schemas will make the configuration verbose. KCL supports defining attributes in the schema through `selector expression`. The selector form is **x.y.z**, see the following example: - -```python -group = Group { - name = "group" - persons = [{ - name.firstName = "John" - name.lastName = "Doe" - age = 24 - }] -} -``` - -- Selector can be used to represent attribute in a schema - -### Inheritance - -Inheritance is an effective means to define a hierarchical structure definition, and KCL supports limited **single inheritance** of the schema. - -```python -schema Person: - firstName: str - lastName: str - -# schema Scholar inherits schema Person -schema Scholar(Person): - fullName: str = firstName + '_' + lastName - subject: str - -JohnDoe = Scholar { - firstName = "John", - lastName = "Doe", - subject = "CS" -} -``` - -The result is a **dict**: - -```python -{ - 'JohnDoe': { - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' - 'subject': 'CS' - } -} -``` - -Each schema can be treated as a separated function context. Statements, including attribute statements and init statements, in the context of schemas will be evaluated from base schema to subschema according to the inheritance order. Each schema context is evaluated only once sequentially. The same goes for expressions in the check block. In the example, firstName and lastName are configured in the context of Person schema, and fullName is formed by splicing firstName and lastName in the context of Scholar schema. - -The default value can be modified in each schema. Value defined in **Configuration Definition** has a higher priority than the default value. Attributes with default values in any schema context ​​will eventually be unioned by configuration data. References to attributes in the schema context statements will use the value with unioned configuration data on evaluating at runtime. For example: - -```python -schema a: - x = 1 - y = x * 2 - -schema b(a): - x = 2 - -v = a { - x = 3 -} - -``` - -The result is a **dict**: - -```python -{ - 'v': { - 'x': 3 - 'y': 6 - } -} -``` - -Notes: - -- Report an error if inheriting more than one base schema. -- The type of the base schema attribute cannot be modified in the subschema. -- Report an error if inheriting a **mixin**. -- Report an error when a circular dependency occurs. - -Limitations: - -Since inheritance will derive some complex demands, we are cautious about these complex demands. There are still some restrictions on inheritance, and it's still under discussion. - -- KCL provides limited and deterministic polymorphism support, more complex and flexible polymorphism support, such as **self**, **super** keywords, are temporarily not included in the schema definition. -- Currently, KCL only supports the polymorphism of the inherited attributes of the schema, and does not support the polymorphism of the expressions in the check block. -- For the case of multiple levels of schema inheritance, the schema arguments can only be passed to the last level of sub-schema. - -### Mixin - -In addition to **composition** and **inheritance**, KCL supports declarative reuse of schema code through the **mixin** mechanism. To use a mixin, we only need to declare the **mixin** in the schema definition. - -The **mixin** syntax is the following: - -```bnf -//////////// mixin_stmt //////////// -mixin_stmt: "mixin" "[" [mixins | multiline_mixins] "]" "\n" -multiline_mixins: "\n" _INDENT mixins "\n" _DEDENT -mixins: operand_name ("," ("\n" mixins | operand_name))* -``` - -Here is a simple example: - -```python -schema Person: - mixin [FullNameMixin] - firstName: str = "default" - lastName: str - -schema FullNameMixin: - fullName: str = "{} {}".format(firstName, lastName) - -JohnDoe = Person { - firstName = "John" - lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'JohnDoe': { - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' - } -} -``` - -Multiple mixins can be added to a single schema, and mixins context will be evaluated after the host schema context at runtime. In the inheritance scenario, the mixin context can be regarded as a part of the host schema context, and the overall evaluation of schema context order is not affected. - -Notes: - -- The name of **mixin** schema must end with 'Mixin', otherwise an error will be reported. -- The attributes referenced in the **mixin** must be defined in the **mixin** itself or host schema, otherwise an error will be reported. - -### Protocol - -In addition to schema, an additional type definition method `protocol` is provided in KCL, and its properties are as follows: - -- In a protocol, only attributes and their types can be defined, complex logic and check expressions cannot be written, and mixins cannot be used. -- A protocol can only inherit or refer to other protocols, but cannot inherit or refer to other schemas. - -We can use **protocol** to add an optional host type to the dynamically inserted **mixin**. - -The **mixin** can define its host type through the `for` keyword, and internally it will query the type corresponding to the attribute from the host type. - -```python -protocol DataProtocol: # A mixin host type - data: str - -mixin DataMixin for DataProtocol: # Using the `for` keyword to define a mixin host type - x: int = data # The type of `data` is `str`, which is from `data` of `DataProtocol` -``` - -In `DataMixin`, the `data` attribute is obtained according to the `DataProtocol` host type as `str` type, and then a type error will occur when the value is assigned to `x` of type `int`: - -```python -protocol DataProtocol: - data: str - -mixin DataMixin for DataProtocol: - x: int = data # Error: expect int, got str - x: str = data # Error: can't change schema field type of 'x' from int to str -``` - -Please note that the host type **protocol** can only be used for **mixin** definitions (the suffix name is `Mixin`), otherwise an error will be reported. - -```python -protocol DataProtocol: - data: str - -schema Data for DataProtocol: # Error: only schema mixin can inherit from protocol - x: str = data -``` - -### Schema Context Evaluation - -The schema definition is composed of attribute statements, configuration data, init statements, mixins, and checks. In a separate schema context, the evaluation top-down order is as follows: - -``` -|------------------------------------------| -| attribute defaulting | -|------------------------------------------| -| configuration union | -|------------------------------------------| -| attribute templating | -|------------------------------------------| -| statements in declaration order | -|------------------------------------------| -| mixins in declaration order | -|------------------------------------------| -| check expressions in any order | -|------------------------------------------| -``` - -In the case of schema inheritance, each schema context is evaluated from the base schema in the order of inheritance, and each context is evaluated only once. -Suppose there are schemas a, b, and c, where c inherits b and b inherits a. Schema contexts will be evaluated in top-down order as: - -``` -|-----------------| -| schema a | -|-----------------| -| schema b | -|-----------------| -| schema c | -|-----------------| -``` - -### Members - -Built-in function and members of schema - -- instances() - Return the list of existing instances of a schema. - -### Irrelevant Order Calculation - -The irrelevant order calculation in the schema indicates the reference relationship between the internal attributes of the schema. For example, when we declare an expression of the form `a = b + 1`, the calculation of the value of `a` depends on the calculation of the value of `b`. When the compiler calculate the value of `a` and the value of `a` depends on the value of `b`, the compiler will choose to first calculate the value of `b`, and then calculate the value of a according to the expression `a = b + 1`, which is slightly different from the calculation method of traditional procedural language the difference. - -Since the calculation of values in the schema is based on dependencies, just like a directed acyclic graph traverses each node in the graph according to the order of topological sorting, the order of declaration of attributes in the schema is not so important, so the feature is called the irrelevant order calculation. - -Please note that there can be no circular references between different schema attribute values. - -We can see this feature through the following examples. - -```python -schema Person: - name?: str - age: int = _age - - _age = 10 - - if name == "Son": - _age = 18 - -schema Son(Person): - name: str = "Son" - -person = Person {} -son = Son {} -``` - -The output is - -```yaml -person: - name: null - age: 10 -son: - name: Son - age: 18 -``` - -Besides, we can achieve KCL polymorphism such as - -```python -schema Person: - name?: str - _age: int = _age - - _age = 10 - if name == "Son": - _age = 18 - elif name == "SonConf": - _age = 24 - -schema Son(Person): - name: str = "Son" - -person = Person() {} -son = Son() { - name = "SonConf" -} -``` - -The output is - -```yaml -person: - name: null - age: 10 -son: - name: SonConf - age: 24 -``` - -More examples: - -```python -schema Fib: - n1: int = n - 1 - n2: int = n1 - 1 - n: int - value: int = _value - - if n <= 2: - _value = 1 - else: - _value = (Fib {n = n1}).value + (Fib {n = n2}).value - -fib8 = (Fib {n = 8}).value -``` - -The output is - -```yaml -fib8: 21 -``` - -As in the above examples, we can see that in the schema, we only need to simply specify the dependency between attributes, and the compiler will automatically calculate the value based on the dependency, which can help us save a lot of boilerplate code and reduce configuration difficulty of writing. diff --git a/versioned_docs/version-0.5.3/reference/lang/spec/statements.md b/versioned_docs/version-0.5.3/reference/lang/spec/statements.md deleted file mode 100644 index b09488b9..00000000 --- a/versioned_docs/version-0.5.3/reference/lang/spec/statements.md +++ /dev/null @@ -1,185 +0,0 @@ ---- -title: "Statements" -linkTitle: "Statements" -type: "docs" -weight: 2 -description: Statements ---- - -## Syntax - -In KCL, statements consist of small statements and compound statements. The syntax is the following: - -```bnf -preamble_statement: preamble_small_stmt | preamble_compound_stmt -preamble_small_stmt: (small_stmt | import_stmt) NEWLINE -preamble_compound_stmt: compound_stmt | schema_stmt -statement: small_stmt NEWLINE | compound_stmt -compound_stmt: if_stmt -small_stmt: assign_stmt | expr_stmt | assert_stmt -``` - -The preamble statement is used to define the module level statements, consist of `statement`, `import_stmt`, and `schema_stmt`. The statement is used to define the block level statements, which are used in the `if` statement and `schema` statement. - -### Small Statements - -A small statement is comprised of a single logical line. Multiple statements in one-line are not allowed. - -#### Assignment Statements - -Generally, assign_stmt is divided into assignment and augmented assignment. The syntax is the following: - -```bnf -assign_stmt: target_primary ("=" target_primary)* "=" test | target_primary augassign test -augassign: "+=" | "-=" | "*=" | "**=" | "/=" | "//=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>=" | "or" | "and" -target_primary: identifier | target_primary DOT identifier -``` - -An assignment statement has the form `lhs = rhs`. It evaluates the expression on the right-hand side then assigns its value (or values) to the variable (or variables) on the left-hand side. - -The **target_primary** on the left-hand side is an `identifier` or an `identifier` followed by select dots. - -Note: When using **target_primary** will cause collisions, use **primary_expr** as an alternative. - -Examples: - -```python -k = 1 -a.b = "a.b" -``` - -To keep it simple, the compound target is not supported as **target_primary**. - -The right value of an assignment statement is a conditional expression, which is discussed separately. - -An augmented assignment, which has the form `lhs op= rhs` updates the variable `lhs` by applying a binary arithmetic operator op (one of +, -, \*, /, //, %, &, |, ^, <<, >>) to the previous value of `lhs` and the value of `rhs`. - -The **target_primary** on the left-hand side is the same as assignment statement. Examples: - -```python -_x -= 1 -_filename += ".k" -``` - -There is no concept of in-place modification in KCL. The `augassign` statement will modify a copy of the **target_primary** and assign the copy to **target_primary**. - -In particular, in KCL, the `|=` symbol represents the **union** operation, which is defined as follows: - -- The behavior of the **union** operation needs to be consistent with the behavior of the **configuration definition**. - -See **expressions** spec for more details of union operator in **Arithmetic Operations**. - -#### Expression Statements - -An expression statement evaluates an expression and discards its result. - -Syntax: - -```bnf -expr_stmt: expression -``` - -An expression statement supported in KCL is function invocation expression, which is discussed in **expression** spec. - -```python -print(k) # print a variable -``` - -#### Import Statements - -Import statements are used to **search** and **load** a module, and define a name or names in the local namespace for the scope where the import statement occurs. - -Syntax: - -```bnf -import_stmt: "import" dot_name ("as" NAME)? -dot_name: [leading_dots] identifier (DOT identifier)* -leading_dots: "."+ -``` - -Examples: - -```python -import math # import a built-in module math -import pkg # import pkg -import pkg.foo # import pkg.foo -import pkg.subpkg # import a subpkg in a pkg -import .pkg2.subpkg3 # import a subpkg in a pkg inside of current pkg -import ...pkg2 # Go two levels up then import pkg2 -``` - -See **module** spec for more details of module spec. - -#### Assert Statements - -Assert statements are a convenient way to insert debugging assertions into KCL code. - -The syntax is the following: - -``` -assert_stmt: ASSERT test ("," test)? -``` - -The conditional expression in assert will be evaluated and get a boolean. Report an error if returning a `False`. - -Examples: - -```python -assert: x > 1 # report an error on x <= 1 -``` - -#### Conditional Statements - -KCL allows using conditional statements to control the instructions to -be executed. They are also called the control-flow statements. - -The only type of control-flow syntax is the well-known `if-elif-else` syntax. - -The syntax of the `if-elif-else` statement is the following. - -```bnf -if_stmt: "if" test ":" suite ("elif" test ":" suite)* (ELSE ":" suite)? -suite: small_stmt | NEWLINE _INDENT statement+ _DEDENT -``` - -An `if` or `elif` statement evaluates a given expression. When the expression -is evaluated to `True`, a list of statements following `:` are executed. - -The following is an example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - print("maybe a is negative") -else: - print("a >= 100") -``` - -`if-elif-else` statements can be nested. For example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - if a < 0: - print("a is negative") - print("No matter a is negative or positive, this message is printed") -else: - print("a >= 100") -``` - -#### Schema Statements - -Schema statements are used to define a type of configuration data. The syntax is the following: - -```bnf -schema_stmt: [decorators] "schema" ["relaxed"] identifier ["[" [arguments] "]"] ["(" operand_name ")"] ":" NEWLINE [schema_body] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt | statement)* [check_block] _DEDENT -``` - -See **schema** spec for more details of schema spec. diff --git a/versioned_docs/version-0.5.3/reference/lang/spec/variables.md b/versioned_docs/version-0.5.3/reference/lang/spec/variables.md deleted file mode 100644 index b3e1c539..00000000 --- a/versioned_docs/version-0.5.3/reference/lang/spec/variables.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: "Variables" -linkTitle: "Variable" -type: "docs" -weight: 2 -description: Variable ---- - -In KCL, variables can be defined using assign statements. For example, the following statement defines a variable `spam` to a string `"ham"`. - -```python -spam = "ham" -``` - -There are two types of variables, which are global variables and list comprehension local variables. - -- A global variable is defined not within any context. -- A comprehension local variable is defined inside a comprehension. - -A variable can be used after definition, until the end of the current scope. - -For a global variable, the scope is the module it is defined in. Note that a module can consists of multiple source files. - -For a list comprehension local variable, the scope is the list comprehension it is defined in. - -More information on modules, list comprehensions and scopes will be discussed in later chapters. - -## Immutability - -Global variables are immutable. In other words, once defined such a variable cannot be redefined (or, i.e., modified). - -The following code is illegal, and KCL will report an error during evaluation. - -```python -spam = "ham" -spam = "eggs" # Error: The immutability rule is violated! -``` - -- A variable starts with the `_` character is mutable. - -```python -_spam -cond = True -if cond: - _spam = "ham" -else: - _spam = "eggs" -``` - -## Variable Exporting - -As shown in the preview chapter, KCL is able to export evaluation results to the standard output according to a target data format. - -The rules are the followings: - -- Living global variables at the end of an evaluation will be dumped out. -- If the name of a variable starts with the `_` character, it will not be dumped out. - -## Uniqueness of Exported Variable Identifier - -Each exported variable identifier must be unique in its package, so that an exported variable could be located uniquely by package location path and variable identifier, such as 'a.b.c:var', in which 'a.b.c' locates a package. - -Two variable identifiers are different if: - -- they are spelled differently -- they are defined in different packages and are not compiled in a single execution - -Identifying an exported variable should be supported by the kcl compiler, which needs to provide corresponding identifying features through the command line and api form. diff --git a/versioned_docs/version-0.5.3/reference/lang/tour.md b/versioned_docs/version-0.5.3/reference/lang/tour.md deleted file mode 100644 index f7acf49c..00000000 --- a/versioned_docs/version-0.5.3/reference/lang/tour.md +++ /dev/null @@ -1,3324 +0,0 @@ ---- -title: "KCL Tour" -sidebar_position: 1 ---- - -This page shows how to use major KCL features, from variables and operators to schemas and libraries, with the assumption that you have already known how to program in another language. KCL is mainly inspired by Python, and knowing Python is very helpful for learning KCL. - -### Important Concepts - -As we learn about the KCL language, keep these facts and concepts in mind: - -- KCL is a configuration and policy language. It provides simplified and self-contained language design and library support for writing configurations and policies. It cannot be used for application development or other purposes supported by General Purpose Language (GPL). -- KCL absorbs classic **OOP** elements and provides simple, developer-friendly and reliable configuration writing practice with **type**, **reusing**, and **union**. -- KCL prefers **immutability** and recommend to add up incremental updates through the **union**. Immutability reduces side effects like unpredictable issues. -- KCL **schema** struct defines strict attributes, static types, and it also supports validation expressions. The **schema** struct is mainly composed of typed attributes, the schema context and the check block. -- KCL **config** is a **json**-like expression, by which we can reuse a full definition of the schema. KCL provides support for definition and configuration by separating schema and config. -- KCL **rule** is a structure for writing rule constraint expressions, which can be used for data verification and policy writing. -- KCL code files are managed as packages(directories) and modules(files). The schema types in the same package are visible to each other; the data cross packages need to be imported through the **import statement**. The package-level variables can be exported, but they are immutable for other packages. -- The KCL syntax definition mainly uses declarative expressions, and only provides a small number of necessary and imperative statements, such as import, if .. else, assert, assignment and schema. -- No main function, each `.k` file could be executed as a separate configuration. -- **Built-in functions** and **plugins** are supported to simplify coding. - -### Keywords - -The following table lists the words that the KCL language treats specially. - -```txt -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -### Identifiers - -In KCL, an identifier is a name, may with selectors, that identifies a value. - -- Identifiers consist of letters, numbers, underscores or the prefix `$`. -- Identifiers cannot be repeated with keywords unless they have a `$` prefix. -- Identifiers must not contain any embedded spaces or symbols. -- Letters and underscores can be used anywhere in the identifier. -- Numbers cannot be placed in the first place of the identifier. -- The `$` character can only be placed in the first position of the identifier. - -Examples: - -```python -x -a -b1 -b_2 -_c -$if -``` - -To simplify the definition of the qualified identifier, such as `pkg.type`, we additionally define `qualified identifier`: - -Examples: - -```python -pkg.a -``` - -The package name in `qualified identifier` must be imported. - -#### Identifier Prefix - -Use the `$` character prefix to define keyword identifiers. - -```python -$if = 1 -$else = "s" -``` - -Please note: whether the non-keyword identifier is prefixed with `$` has the same effect. - -```python -_a = 1 -$_a = 2 # equal to `_a = 2` -``` - -### Variables - -Here’s an example of how to create a variable and initialize it: - -```python -name = "Foo" # Declare a variable named `name` and its value is a string literal "Foo" -``` - -It corresponds to the following YAML output: - -```yaml -name: Foo -``` - -In KCL, we can export variables as config data by defining package-level variables. To make it direct, clear, and maintainable. Exported variables are immutable so that once we declare it, we can't modify it. For example, assume we have a config file named `example.k`, the variable `name` can't be modified after the declaration, just like the standard imperative language. - -```python -name = "Foo" # exported - -... - -name = "Bar" # error: a exported declaration variable can only be set once. -``` - -As a complement, we can define a non-exported variable in module level which is mutable, which won't show up in YAML output: - -```python -_name = "Foo" # _ variables are not output to YAML and are mutable -_name = "Bar" -``` - -Please note that the variable name cannot be one of `True`, `False`, `None`, `Undefined` because of ambiguity. - -```python -False = 1 # Error -True = False # Error -None = Undefined # Error -Undefined = None # Error -``` - -### Built-in Types - -The KCL language has special support for the following types: - -- number -- string -- boolean -- list -- dict - -#### Number - -KCL number comes into two flavors: - -- **Int**: 64 bits signed integer values. Values can be from -9223372036854775808~9223372036854775807. -- **Float**: 64-bit floating-point numbers, as specified by the IEEE 754 standard. We do not recommend using the float type in the configuration, we can use a string instead and parse it during runtime processing. - -Both int and float support basic operators such as `+`, `-`, `/`, and `*`, while complex operations, such as `abs()`, `ceil()`, and `floor()`, are supported through the built-in math library. - -Integers are numbers without a decimal point. Here are some examples of defining integer literals: - -```python -a = 1 -b = -1 -c = 0x10 # hexadecimal literal -d = 0o10 # octal literal -e = 010 # octal literal -f = 0b10 # binary literal -g = int("10") # int constructor -``` - -If a number includes a decimal point, it is a float number. Here are some examples of defining float literals: - -```python -a = 1.10 -b = 1.0 -c = -35.59 -d = 32.3e+18 -f = -90. -h = 70.2E-12 -i = float("112") # float constructor -``` - -Built-in math libraries can be used with numbers: - -```python -import math - -assert abs(-40) == 40 -assert round(70.23456) == 70 -assert min(80, 100, 1000) == 80 -assert max(80, 100, 1000) == 1000 -assert sum([0,1,2]) == 3 -assert math.ceil(100.12) == 101.0 -assert math.floor(100.12) == 100.0 -assert math.pow(100, 2) == 10000.0 -``` - -In addition, please note that the KCL number is 64-bit by default. We can perform a stricter 32-bit range check by adding the `-r` parameter to the KCL command-line tool. - -```bash -kcl main.k -r -d -``` - -Please note that the value range check is only enabled in `debug` mode - -##### Units - -In KCL, we can add a unit suffix to an integer denomination to indicate that it does not affect its true value as follows. - -- General integer or fixed-point number form: `P`, `T`, `G`, `M`, `K`, `k`, `m`, `u`, `n` -- Corresponding power of 2: `Pi`, `Ti`, `Gi`, `Mi`, `Ki` - -```python -# SI -n = 1n # 1e-09 -u = 1u # 1e-06 -m = 1m # 1e-03 -k = 1k # 1000 -K = 1K # 1000 -M = 1M # 1000000 -G = 1G # 1000000000 -T = 1T # 100000000000 -P = 1P # 1000000000000000 -# IEC -Ki = 1Ki # 1024 -Mi = 1Mi # 1024 ** 2 -Gi = 1Gi # 1024 ** 3 -Ti = 1Ti # 1024 ** 4 -Pi = 1Pi # 1024 ** 5 -``` - -Besides, And we can also use the unit constants defined in the `units` module as follows: - -```python -import units - -n = 1 * units.n # 1e-09 -u = 1 * units.u # 1e-06 -m = 1 * units.m # 1e-03 -k = 1 * units.k # 1000 -K = 1 * units.K # 1000 -M = 1 * units.M # 1000000 -G = 1 * units.G # 1000000000 -T = 1 * units.T # 1000000000000 -P = 1 * units.P # 1000000000000000 -# IEC -Ki = 1 * units.Ki # 1024 -Mi = 1 * units.Mi # 1024 ** 2 -Gi = 1 * units.Gi # 1024 ** 3 -Ti = 1 * units.Ti # 1024 ** 4 -Pi = 1 * units.Pi # 1024 ** 5 -``` - -We can also use the methods in the `units` module to convert between integers and unit strings. - -```python -import units -# SI -K = units.to_K(1000) # "1K" -M = units.to_M(1000000) # "1M" -G = units.to_G(1000000000) # "1G" -T = units.to_T(1000000000000) # "1T" -P = units.to_P(1000000000000000) # "1P" -# IEC -Ki = units.to_Ki(1024) # "1Ki" -Mi = units.to_Mi(1024 ** 2) # "1Mi" -Gi = units.to_Gi(1024 ** 3) # "1Gi" -Ti = units.to_Ti(1024 ** 4) # "1Ti" -Pi = units.to_Pi(1024 ** 5) # "1Pi" -``` - -```python -import units -# SI -K = units.to_K(int("1M")) # "1000K" -M = units.to_M(int("1G")) # "1000M" -G = units.to_G(int("1T")) # "1000G" -T = units.to_T(int("1P")) # "1000T" -P = units.to_P(int("10P")) # "10P" -# IEC -Ki = units.to_Ki(int("1Mi")) # "1024Ki" -Mi = units.to_Mi(int("1Gi")) # "1024Mi" -Gi = units.to_Gi(int("1Ti")) # "1024Gi" -Ti = units.to_Ti(int("1Pi")) # "1024Ti" -Pi = units.to_Pi(int("10Pi")) # "10Pi" -``` - -The unit value type is defined in the units module, and the unit value type does not allow any four calculations. - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -x0: NumberMultiplier = 1M # Ok -x1: NumberMultiplier = x0 # Ok -x2 = x0 + x1 # Error: unsupported operand type(s) for +: 'number_multiplier(1M)' and 'number_multiplier(1M)' -``` - -We can use the `int()`, `float()` function and `str()` function to convert the numeric unit type to the normal integer type and string type. - -```python -a: int = int(1Ki) # 1024 -b: float = float(1Ki) # 1024.0 -c: str = str(1Mi) # "1Mi" -``` - -#### String - -The string is an immutable sequence of Unicode characters. We can use either single or double quotes to create a string: - -```python -'allows embedded "double" quotes' # Single quotes -"allows embedded 'single' quotes" # Double quotes -'''Three single quotes''', """Three double quotes""" # Triple quoted -``` - -Triple quoted strings may span multiple lines. - -```python -"""This is a long triple quoted string -may span multiple lines. -""" -``` - -Please note that there is almost no difference in the use of KCL single-quoted and double-quoted strings. The only thing that can be simplified is that we don’t need to escape double quotes in single quoted strings, and we don’t need to escape single quotes in double quoted strings. - -```python -'This is my book named "foo"' # Don’t need to escape double quotes in single quoted strings. -"This is my book named 'foo'" # Don’t need to escape single quotes in double quoted strings. -``` - -We can concatenate strings using the `+` operator: - -```python -x = 'The + operator ' + 'works, as well.' -``` - -We can cast an int or float to a string using the built-in function `str`: - -```python -x = str(3.5) # "3.5" -``` - -A lot of handy built-in functions and members of a string could be used: - -```python -x = "length" -assert len(x) == 6 # True -assert x.capitalize() == "Length" -assert x.count("gt") == 1 -assert x.endswith("th") == True -assert x.find("gth") == 3 -assert "{} {}".format("hello", "world") == 'hello world' -assert x.index("gth") == 3 -assert x.isalnum() == True -assert x.isalpha() == True -assert "123456".isdigit() == True -assert x.islower() == True -assert " ".isspace() == True -assert "This Is Title Example".istitle() == True -assert x.isupper() == False -assert "|".join(["a", "b", "c"]) == "a|b|c" -assert "LENGTH".lower() == "length" -assert ' spacious '.lstrip() == 'spacious ' -assert x.replace("th", "ht") == "lenght" -assert "lengthlength".rfind("le") == 6 -assert "lengthlength".rindex("le") == 6 -assert "length length".rsplit() == ["length", "length"] -assert "length ".rstrip() == "length" -assert "length length".split() == ["length", "length"] -assert 'ab c\n\nde fg\rkl\r\n'.splitlines() == ['ab c', '', 'de fg', 'kl'] -assert "length".startswith('len') == True -assert "***length***".strip('*') == "length" -assert "length length".title() == "Length Length" -assert x.upper() == "LENGTH" -``` - -There are 2 different ways to format a string: to use the `"{}".format()` built-in function, or to specify the variable between the curly braces and use a `$` mark to tell KCL to extract its value. This is called **string interpolation** in KCL. In following example, both `a` and `b` will be assigned to string `"hello world"`. - -Besides, the variable to serialized can be extracted in special data format, such as YAML or JSON. In this case, a `#yaml` or `#json` can be included within the curly braces. - -Specifically, when the dollar sign `$` itself is needed in a **string interpolation**, it needs to be escaped and use `$$` instead. Or in another way, `+` can be used to concat the dollar sign with the **string interpolation** to avoid that escape. In following example, both `c` and `c2` will be assigned to string `$hello world$` - -```python -world = "world" -a = "hello {}".format(world) # "hello world" -b = "hello ${world}" # "hello world" -c = "$$hello ${world}$$" # "$hello world$" -c2 = "$" + "hello ${world}" + "$" # "$hello world$" - -myDict = { - "key1" = "value1" - "key2" = "value2" -} - -d = "here is myDict in json: ${myDict: #json}" -# d: 'here is myDict in json: {"key1": "value1", "key2": "value2"}' - -e = "here is myDict in yaml:\n${myDict: #yaml}" -# e: | -# here is myDict in yaml: -# key1: value1 -# key2: value2 -``` - -Besides, we can see some symbols in the example code output **YAML string** above such as `|`, `>`, `+`, `-`. - -- `|` denotes the **block literal style** that indicates how newlines inside the block should behave. -- `>` denotes the **block folded style** in the block scalar that the newlines will be replaced by spaces. -- `+` and `-` are the **block chomping indicators** that control what should happen with newlines at the end of the string. The default value **clip** puts a single newline at the end of the string. To remove all newlines, **strip** them by putting a `-` after the style indicators `|` or `>`. Both clip and strip ignore how many newlines are actually at the end of the block; to **keep** them all put a `+` after the style indicator. - -For example, a **strip block literal style** yaml string is - -```yaml -example: |- - Several lines of text, - with some "quotes" of various 'types', - and also a blank line: - - plus another line at the end. -``` - -The result is - -```plain -Several lines of text, -with some "quotes" of various 'types', -and also a blank line: - -plus another line at the end. -``` - -See [Yaml Multiline String](https://yaml-multiline.info/) and [YAML Specification v1.2](https://yaml.org/spec/1.2.1/) for more information. - -##### Raw String - -KCL raw string is created by prefixing a string literal with `'r'` or `'R'`. KCL raw string treats backslash (`\`) and string interpolation (`${}`) as a literal character. This is useful when we want to have a string that contains backslash, string interpolation and don’t want them to be treated as an escape character. - -- For backslash (`\`), the KCL code and output YAML are as follows: - -```python -s = "Hi\nHello" -raw_s = r"Hi\nHello" # This is a KCL raw string with the `r` prefix. -``` - -```yaml -s: |- - Hi - Hello -raw_s: Hi\nHello -``` - -- For string interpolation (`${}`), the KCL code and output YAML are as follows: - -```python -worldString = "world" -s = "Hello ${worldString}" -raw_s = r"Hello ${worldString}" # This is a KCL raw string with the `r` prefix. -``` - -```yaml -worldString: world -s: Hello world -raw_s: Hello ${worldString} -``` - -In addition, the most common scenario for raw strings is to be used with regular expressions: - -```python -import regex - -key = "key" -result = regex.match(key, r"[A-Za-z0-9_.-]*") # True -``` - -#### Boolean - -Boolean values are the two constant objects `False` and `True`. - -```python -a = True -b = False -``` - -#### List - -The list is a sequence, typically used to store collections of homogeneous items. Here’s a simple KCL list: - -```python -list = [1, 2, 3] -assert len(list) == 3 # True -assert list[0] == 1 # True -``` - -We can declare a list with list comprehension: - -```python -list = [ _x for _x in range(20) if _x % 2 == 0] -assert list == [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] # True -``` - -We can perform nested list comprehension: - -```python -matrix = [[1, 2], [3,4], [5,6], [7,8]] -transpose = [[row[_i] for row in matrix] for _i in range(2)] -assert transpose == [[1, 3, 5, 7], [2, 4, 6, 8]] # True -``` - -Besides, we can use two variables in the list comprehension, the first variable denotes the list index and the second variable denotes the list item. - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use `_` to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -We can merge list like this: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -joined_list = _list0 + _list1 # [1, 2, 3, 4, 5, 6] -``` - -We can also use the list unpacking operator `*` to merge multiple lists: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -union_list = [*_list0, *_list1] # [1, 2, 3, 4, 5, 6] -``` - -We can use `if expressions` to dynamically add elements to the list element, elements that meet the conditions are added to the list, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = [ - 1 - if a == 1: 2 - if a > 0: 3 - if a < 0: 4 -] # [1, 2, 3] -``` - -```python -a = 1 # 1 -data1 = [ - 1 - if a == 1: - 2 - elif a == 2: - 3 - else: - 3 -] # [1, 2] -data2 = [ - 1 - if a == 1: 2 - elif a == 2: 2 - else: 3 -] # [1, 2] -``` - -Please note that in the above `if expressions`, nested use is not supported. - -We can union two lists like this: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -union_list = _list0 | _list1 # [4, 5, 6] -``` - -We can use the expression `for k in list_var` to traverse a list. - -```python -data = [1, 2, 3] -dataAnother = [val * 2 for val in data] # [2, 4, 6] -``` - -#### Dict - -Dict is a mapping object that maps hashable values to arbitrary objects. Dict is ordered. The order of the keys follows the order of their declaration. - -Here are a couple of simple KCL dict, created using dict literals: - -```python -a = {"one" = 1, "two" = 2, "three" = 3} -b = {'one' = 1, 'two' = 2, 'three' = 3} -assert a == b # True -assert len(a) == 3 # True -``` - -We can ignore the comma `,` at the end of the line for writing dict key-value pairs in multiple lines: - -```python -data = { - "key1" = "value1" # Ignore the comma ',' at the end of line - "key2" = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -We can ignore the key quotation marks when we writing simple literals on the key. - -```python -data = { - key1 = "value1" # Ignore key quotation '"' - key2 = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -In addition, the **config selector expressions** can be used to init a dict instance with nested keys. - -```python -person = { - base.count = 2 - base.value = "value" - labels.key = "value" -} # {"base": {"count": 2, "value": "value"}, "labels": {"key": "value"}} -``` - -The output YAML is - -```yaml -person: - base: - count: 2 - value: value - labels: - key: value -``` - -In KCL, different fields in dict can be referenced, such as the following example. - -```python -config = { - name = "me" - metadata.name = name # Reference `name` with the value `"me"` in `config` directly. -} -``` - -The output YAML is - -```yaml -config: - name: me - metadata: - name: me -``` - -We can declare a dict with dict comprehension: - -```python -x = {str(i): 2 * i for i in range(3)} -assert x == {"0" = 0, "1" = 2, "2" = 4} -``` - -Besides, we can use two variables in the dict comprehension, the first variable denotes the dict key and the second variable denotes the dict value of the key. - -```python -data = {key1 = "value1", key2 = "value2"} -# Single variable loop -dataKeys1 = {k: k for k in data} # {"key1": "key1", "key2": "key2"} -dataValues1 = {k: data[k] for k in data} # {"key1": "value1", "key2": "value2"} -# Double variable loop -dataKeys2 = {k: k for k, v in data} # {"key1": "key1", "key2": "key2"} -dataValues2 = {v: v for k, v in data} # {"value1": "value1", "value2": "value2"} -dataFilter = {k: v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use `_` to ignore loop variables -dataKeys3 = {k: k for k, _ in data} # {"key1": "key1", "key2": "key2"} -dataValues3 = {v: v for _, v in data} # {"value1": "value1", "value2": "value2"} -``` - -We can **merge** dict using the dict unpacking operator `**` like this: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = {**_part1, **_part2} # {"a: "b", "c": "d"} -``` - -In addition, the same effect can be achieved by using the union operator `|`: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = _part1 | _part2 # {"a: "b", "c": "d"} -``` - -We can use `if expressions` to dynamically add elements to the dict element, elements that meet the conditions are added to the dict, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = { - key1 = "value1" - if a == 1: key2 = "value2" - if a > 0: key3 = "value3" - if a < 0: key4 = "value4" -} # {"key1": "value1", "key2": "value2", "key3": "value3"} -``` - -```python -a = 1 # 1 -data1 = { - key1 = "value1" - if a == 1: - key2 = "value2" - elif a > 0: - key3 = "value3" - else: - key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -data2 = { - key1 = "value1" - if a == 1: key2 = "value2" - elif a > 0: key3 = "value3" - else: key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -``` - -We can use the expression `for k in dict_var` to traverse a dict, and we can use the `in` operator to determine whether a dict contains a certain key - -```python -data = {key1 = "value1", key2 = "value2"} -dataAnother = {k: data[k] + "suffix" for k in data} # {"key1": "value1suffix", "key2": "value2suffix"} -containsKey1 = "key1" in data # True -containsKey2 = "key" in data # False -``` - -#### None - -In KCL, `None` can indicate that the value of the object is empty, which is similar to `nil` in Go or `null` in Java, and corresponds to `null` in YAML. - -```python -a = None -b = [1, 2, None] -c = {key1 = value1, key2 = None} -``` - -The output is as follows: - -```yaml -a: null -b: - - 1 - - 2 - - null -c: - key1: value1 - key2: null -``` - -Please note that `None` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + None # error -b = int(None) # error -c = not None # True -d = None == None # True -e = None or 1 # 1 -f = str(None) # None -``` - -#### Undefined - -`Undefined` is similar to `None`, but its semantics is that a variable is not assigned any value and will not be output to YAML - -```python -a = Undefined -b = [1, 2, Undefined] -c = {key1 = "value1", key2 = Undefined} -``` - -The output is as follows: - -```yaml -b: - - 1 - - 2 -c: - key1: value1 -``` - -Please note that `Undefined` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + Undefined # error -b = int(Undefined) # error -c = not Undefined # True -d = Undefined == Undefined # True -e = Undefined or 1 # 1 -f = str(Undefined) # Undefined -``` - -### Operators - -The following character sequences represent operators: - -```txt -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != @ \ -``` - -#### Arithmetic Operators - -KCL supports the common arithmetic operators: - -```python -assert 2 + 3 == 5 -assert 2 - 3 == -1 -assert 2 * 3 == 6 -assert 5 / 2 == 2.5 -assert 5 // 2 == 2 -assert 5 % 2 == 1 -``` - -#### Equality and Relational Operators - -KCL supports the meanings of equality and relational operators: - -```python -assert 2 == 2 -assert 2 != 3 -assert 3 > 2 -assert 2 < 3 -assert 3 >= 3 -assert 2 <= 3 -``` - -#### Logical Operators - -We can invert or combine boolean expressions using the logical operators e.g., `and` and `or`: - -```python -if not done and (col == 0 or col == 3): - # ...Do something... - -``` - -#### Bitwise and Shift Operators - -Here are examples of using bitwise and shift operators: - -```python -value = 0x22 -bitmask = 0x0f - -assert (value & bitmask) == 0x02 -assert (value & ~bitmask) == 0x20 -assert (value | bitmask) == 0x2f -assert (value ^ bitmask) == 0x2d -assert (value << 4) == 0x220 -assert (value >> 4) == 0x02 -``` - -The `|` operator likewise computes bitwise, unions basic types and unions collection and schema data, such as **list**, **dict** and **schema**. - -Computing bitwise examples: - -```python -0x12345678 | 0xFF # 0x123456FF -``` - -Unioning basic types examples: - -```python -schema x: - a: int | str # attribute a could be a int or string -``` - -#### Assignment Operators - -The following tokens serve as delimiters in the grammar: - -```bash - ( ) [ ] { } - , : . ; = -> - += -= *= /= //= %= - &= ^= >>= <<= **= -``` - -The following examples use assignment and argument assignment operators: - -```python -_a = 2 -_a *= 3 -_a += 1 -assert _a == 7 -``` - -#### Identity Operators - -The following keywords serve as identity operators in the grammar: - -```python -is, is not -``` - -The identity operators check whether the right hand side and the left hand side are the very same object. They are usually used to check if some variable is `None/Undefined/True/False`. Here are some examples: - -```python -empty_String = "" -empty_String is not None # True -``` - -#### Membership Operators - -The following keywords serve as membership operators in the grammar: - -```python -in, not in -``` - -- The `in` operator reports whether its first operand is a member of its second operand, which must be a list, dict, schema, or string. -- The `not in` operator is its negation. Both return a Boolean. - -The meaning of membership varies by the type of the second operand: the members of a list are its elements; the members of a dict are its keys; the members of a string are all its substrings. - -```python -1 in [1, 2, 3] # True - -d = {one = 1, two = 2} -"one" in d # True -"three" in d # False -1 in d # False -[] in d # False - -"nasty" in "dynasty" # True -"a" in "banana" # True -"f" not in "way" # True - -d = Data {one = 1, two = 2} # Data is a schema with attributes one and two -"one" in d # True -"three" in d # False -``` - -#### Comprehension - -A comprehension constructs a new list or dictionary value by looping over one or more iterables and evaluating a body expression that produces successive elements of the result. - -We can declare list and dict by comprehension as: - -```python -listVar = [_x for _x in range(20) if _x % 2 == 0] # list comprehension -dictVar = {str(_i): 2 * _i for _i in range(3)} # dict comprehension -``` - -#### Other Operators - -We can: - -- Represents a function call with **()**, like `"{} {}".format("hello", world)` -- Refers to the value at the specified index in the list with **[]** -- Define a type hint with **:** -- Refers to a member field with **.** -- Use the line continuation symbol `\` to write long expressions - -```python -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " -``` - -### Expressions - -#### Conditional Expressions - -A conditional expression has the form `a if cond else b`. It first evaluates the condition `cond`. If it's true, it evaluates `a` and yields its value; otherwise, it yields the value of `b`. - -Examples: - -```python -x = True if enabled else False # If enabled is True, x is True, otherwise x is False -``` - -#### Index Expressions - -An index expression `a[i]` yields the `i` th element of an indexable type such as a string or list. The index `i` must be an `int` value in the range `-n` ≤ `i` < `n`, where `n` is `len(a)`; any other index results in an error. - -A valid negative index `i` behaves like the non-negative index `n+i`, allowing for convenient indexing relative to the end of the sequence. - -```python -val = "abc" -list = ["zero", "one", "two"] -str_0 = val[0] # "a" -str_1 = val[1] # "b" -str_n1 = val[-1] # "c" - -list_0 = list[0] # "zero" -list_1 = list[1] # "one" -list_n1 = list[-1] # "two" -``` - -An index expression `d[key]` may also be applied to a dictionary `d`, to obtain the value associated with the specified key. It returns `Undefined` if the dictionary contains no such key. - -An index expression appearing on the left side of an assignment causes the specified list or dictionary element to be updated: - -```python -d = {key1 = "value1", key2 = "value2"} -key1value = d["key1"] # value1 -key2value = d["key2"] # value2 -``` - -It is a dynamic error to attempt to update an element of an immutable type, such as a list or string, or a frozen value of a mutable type. - -#### Slice Expressions - -A slice expression `a[start:stop:step]` yields a new value containing a sub-sequence of `a`, which must be a string, or list. - -Each of the `start`, `stop`, and `step` operands is optional; if present, each must be an integer. The `step` value defaults to 1. If the step is not specified, the colon preceding it may be omitted too. It is an error to specify a step of zero. - -Conceptually, these operands specify a sequence of values `i` starting at start and successively adding 'step' until `i` reaches or passes `stop`. The result consists of the concatenation of values of `a[i]` for which `i` is valid. - -The effective start and stop indices are computed from the three operands as follows. Let `n` be the length of the sequence. - -```python -val = "abc" -len = len(val) -a = val[1:len] # "bc" (remove first element) -b = val[0:-1] # "ab" (remove last element) -c = val[1:-1] # "b" (remove first and last element) -``` - -```python -"abc"[1:] # "bc" (remove first element) -"abc"[:-1] # "ab" (remove last element) -"abc"[1:-1] # "b" (remove first and last element) -"banana"[1::2] # "aaa" (select alternate elements starting at index 1) -"banana"[4::-2] # "nnb" (select alternate elements in reverse, starting at index 4) -``` - -It's not allowed to define a slice expression as a left value in KCL. Cause list and string are immutable, re-slicing can directly operate to operand to ensure better performance. - -#### Function Invocations - -KCL allows calling built-in functions and functions from built-in and system modules. - -To call a function, the basic way is shown as the following code excerpt: - -```python -import math - -a = math.pow(2, 3) # 2 powers 3 is 8. -b = len([1, 2, 3]) # the length of [1, 2, 3] is 3 -``` - -As you can see, arguments are separated with `,`, and KCL also supports positional arguments and key-value arguments. - -```python -print("hello world", end="") -``` - -Note that: - -- Some functions have parameters with default values. -- Some functions accept variadic arguments. - -When an argument is not supplied for a parameter without a default value, an error will be reported. - -#### Selector Expressions - -A selector expression selects the attribute or method of the value. KCL provides a wealth of ways to identify or filter attributes. - -`x.y` - -- dict: it denotes the value of the key `y` in the dict `x` -- schema: it denotes the attribute value of a schema `x` identified by `y` -- package: it denotes the identifier of a package `x` identified by `y` - -Examples: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -name = person.name # "Alice" -age = person.age # 18 - -myDict = { - key = "value" -} -result = myDict.key # "value" -``` - -`x?.y` - -`x` can be a schema instance or a dict. This is extremely helpful when the value of `x` might be `None` or when the key `y` might not exist in `x`. - -```python -# Example of dict: -data = {key = "value"} -a = data?.key # "value" -b = data?.name # Undefined - -# example of schema instance: -schema Company: - name: str - address: str - -schema Person: - name: str - job?: Company - -alice = Person { - name = "alice" -} - -if alice?.job?.name == "Group": - print("work in Group") -``` - -#### Quantifier Expressions - -Quantifier expressions act on collection: list or dict, generally used to obtain a certain result after processing the collection, mainly in the following four forms: - -- **all** - - Used to detect that all elements in the collection satisfy the given logical expression, and return a boolean value as the result. - - Only when all elements in the collection satisfy the expression true, the `all` expression is true, otherwise it is false. - - If the original collection is empty, return true. - - Supports short-circuiting of logical expressions during expression execution. -- **any** - - Used to detect that at least one element in the collection satisfies the given logical expression, and returns a boolean value as the result. - - When at least one element in the collection satisfies the expression true, the `any` expression is true, otherwise it is false. - - If the original collection is empty, return false. - - Supports short-circuiting of logical expressions during expression execution. -- **map** - - Generate a new **list** by mapping the elements in the original collection. - - The length of the new list is exactly the same as the original collection. -- **filter** - - By logically judging and filtering the elements in the original collection, and returning the filtered sub-collection. - - Only when the element judges the expression to be true, it is added to the sub-collection. - - The type (list, dict and schema) of the new collection is exactly the same as the original collection, and the length range is `[0, len(original-collection)]`. - -**all** and **any** expression sample codes: - -```python -schema Config: - volumes: [{str:}] - services: [{str:}] - - check: - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - }, "invalid cluster ip" - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } -``` - -**map** and **filter** expression sample codes: - -```python -a = map e in [{name = "1", value = 1}, {name = "2", value = 2}] { - {name = e.name, value = int(e.value) ** 2} -} # [{"name": "1", value: 1}, {"name": "2", "value": 4}] - -b = map k, v in {a = "foo", b = "bar"} { v } # ["foo", "bar"] - -c = filter e in [{name = "1", value = 1}, {name = "2", value = 2}] { - int(e.value) > 1 -} # [{"name": "2", "value": 2}] - -d = filter _, v in {a = "foo", b = "bar"} { - v == "foo" -} # {"a": "foo"} -``` - -Please pay attention to distinguish the difference between any expression and any type. When `any` is used in type annotations, it means that the value of the variable is arbitrary, while the any expression means that one of the elements in a set satisfies the condition. - -### Control Flow Statements - -#### If and Else - -KCL supports `if` statements with optional `elif` and `else` statements, as the next sample shows. - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - print("maybe a is negative") -else: - print("a >= 100") -``` - -The `elif` example: - -```python -_result = 0 -if condition == "one": - _result = 1 -elif condition == "two": - _result = 2 -elif condition == "three": - _result = 3 -else: - _result = 4 -``` - -`if-elif-else` statements can be nested. For example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - if a < 0: - print("a is negative") - print("No matter a is negative or positive, this message is printed") -else: - print("a >= 100") -``` - -In addition, for simple `if` statements as follows: - -```python -if success: - _result = "success" -else: - _result = "failed" -``` - -We can have it in one line using the ` if else ` pattern: - -```python -_result = "success" if success else "failed" -``` - -An `if` or `elif` statement evaluates a given expression. When the expression is evaluated to `True`, a list of statements following `:` are executed and when the expression is evaluated to `False` and statements will not be executed. - -Please note that the false name constant `False`, `None`, the zero number `0`, the empty list `[]`, the empty dict `{}` and the empty string `""` are all seen as `False` expressions. - -```python -_emptyStr = "" -_emptyList = [] -_emptyDict = {} -isEmptyStr = False if _emptyStr else True -isEmptyList = False if _emptyList else True -isEmptyDict = False if _emptyDict else True -``` - -The output is - -```yaml -isEmptyStr: true -isEmptyList: true -isEmptyDict: true -``` - -### Assert - -When errors happen, developers should be able to detect the error and abort execution. Thus, KCL introduce the `assert` syntax. The following is an example: - -```python -a = 1 -b = 3 -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -``` - -In addition, we can declare a condition for the assert statement and make an assertion when the condition is met. The usual way of writing is - -```python -a = None -if a: - assert a > 2: -``` - -In KCL, it can also be simplified to the following form using the **if** expression to compose more complex conditional assert logic: - -```python -a = None -assert a > 2 if a -``` - -### Function - -KCL supports using the lambda keyword to define a function. - -```python -func = lambda x: int, y: int -> int { - x + y -} -a = func(1, 1) # 2 -``` - -- The value of the last expression is used as the return value of the function, and the empty function body returns `None`. -- The return value type annotation can be omitted, and the return value type is the type of the last expression value. -- There is no order-independent feature in the function body, all expressions are executed in order. - -```python -_func = lambda x: int, y: int -> int { - x + y -} # Define a function using the lambda expression -_func = lambda x: int, y: int -> int { - x - y -} # Ok -_func = lambda x: int, y: int -> str { - str(x + y) -} # Error (int, int) -> str can't be assigned to (int, int) -> int -``` - -The function type variables cannot participate in any calculations and can only be used in assignment statements and call statements. - -```python -func = lambda x: int, y: int -> int { - x + y -} -x = func + 1 # Error: unsupported operand type(s) for +: 'function' and 'int(1)' -``` - -The lambda function supports the capture of external variables, which can be passed as parameters of other functions. - -```python -a = 1 -func = lambda x: int { - x + a -} -funcOther = lambda f, para: int { - f(para) -} -r0 = funcOther(func, 1) # 2 -r1 = funcOther(lambda x: int { - x + a -}, 1) # 2 -``` - -The output is - -```yaml -a: 1 -r: 2 -``` - -Further, we can define an anonymous function through lambda expression and call it. - -```python -result = (lambda x, y { - z = 2 * x - z + y -})(1, 1) # 3 -``` - -We can also use anonymous functions in the for loop. - -```python -result = [(lambda x, y { - x + y -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 3, 3, 4] -``` - -Note that the functions defined in the KCL are pure functions: - -- The return result of a function depends only on its arguments. -- There are no side effects in the function execution process. - -Therefore, KCL functions cannot modify external variables, but can only reference external variables. For example, the following code will cause an error: - -```python -globalVar = 1 -func = lambda { - x = globalVar # Ok - globalVar = 1 # Error -} -``` - -### Type System - -#### Type Annotation - -Type annotations can be used on top level variables, schema attributes and arguments. - -- An attribute can be of a basic type, such as a string (`str`), a floating-point number (`float`), a fixed-point number (`int`) or a boolean (`bool`). -- An attribute can be a literal type, such as a string literal (`"TCP"` and `"UDP"`), a number literal (`"1"` and `"1.2"`), a boolean literal (`True` and `False`) -- An attribute can also be a list or an ordinary dict: - - A list with unspecified type of elements is `[]`. - - A list with elements of type `t` is `[t]`. Here `t` is another type. - - A dict with keys of type `kt` and values of type `vt` is `{kt:vt}`. - - `kt`, `vt` or both of them can be missing, like a list with unspecified type of elements. -- An attribute can be a **union type** defined by `|`, such as `a | b`, which means the type of the member could be a or b. - - A union type can include any types of `int`, `str`, `float`, `bool`, `list`, `dict`, literal and schema type, and supports type nesting e.g. `{str:str|int}`, `[[int|str]|str|float]` and `2 | 4 | 6`, etc. -- An attribute can also be of a type generated from other schema. In such a case, the name of the other schema (including the package path prefix) is used as the type name. -- An attribute can annotated an any type e.g., `any`. - -Examples: - -- Basic type - -```python -"""Top level variable type annotation""" -a: int = 1 # Declare a variable `a` that has the type `int` and the value `1` -b: str = "s" # Declare a variable `b` that has the type `str` and the value `"s"` -c: float = 1.0 # Declare a variable `c` that has the type `float` and the value `1.0` -d: bool = True # Declare a variable `d` that has the type `bool` and the value `True` -``` - -- List/Dict/Schema Type - -```python -schema Person: - name: str = "Alice" - age: int = 10 - -a: [int] = [1, 2, 3] # Declare a variable `a` that has the list type `[int]` and the value `[1, 2, 3]` -b: {str:str} = {k1 = "v1", k2 = "v2"} # Declare a variable `b` that has the dict type `{str:str}` and the value `{k1 = "v1", k2 = "v2"}` -c: Person = Person {} # Declare a variable `c` that has the schema type `Person` and the value `Person {}` -``` - -- Union Type - -```python -# Basic union types -schema x[argc: int]: # Schema argument type annotation - p: int | str # Schema attribute type annotation -``` - -```python -# Literal union types -schema LiteralType: - # String literal union types, x_01 can be one of "TCP" and "UDP" - x_01: "TCP" | "UDP" - # Number literal union types, x_02 can be one of 2, 4, and 6 - x_02: 2 | 4 | 6 - # Unit union types, x_03 can be one of 1Gi, 2Gi and 4Gi - x_03: 1Gi | 2Gi | 4Gi - -x = LiteralType { - x_01 = "TCP" - x_02 = 2 - x_03 = 1Gi -} -``` - -The compiler throws an error when the value of a property does not conform to the union type definition: - -```python -# Literal union types -schema LiteralType: - # String literal union types, x_01 can be one of "TCP" and "UDP" - x_01: "TCP" | "UDP" - -x = LiteralType { - x_01 = "HTTP" # Error: the type got is inconsistent with the type expected, expect str(TCP)|str(UDP), got str(HTTP) -} -``` - -- Any Type - -```python -# Any type -schema Config: - literalConf: any = 1 - dictConf: {str:any} = {key = "value"} - listConf: [any] = [1, "2", True] - -config = Config {} -``` - -In KCL, changing the type of a variable is not allowed. If the type is not satisfied when reassigning the value, the type error will be raised. - -```python -_a = 1 # The type of `_a` is `int` -_a = "s" # Error: expect int, got str(s) -``` - -The type of a variable can be assigned to its upper bound type, but cannot be assigned to its specialized type. - -`None` and `Undefined` can be assigned to any type: - -- All types can be assigned to `any` type, `None` and `Undefined` can be assigned to `any` type. - -```python -a: int = None -b: str = Undefined -c: any = 1 -d: any = "s" -e: any = None -``` - -- The `int` type can be assigned to the `float` type, and the `float` type cannot be assigned to the `int` type. - -```python -a: float = 1 -b: int = 1.0 # Error: expect int, got float(1.0) -``` - -- The `int` type can be assigned to the `int|str` type, and the `int|str` type cannot be assigned to the `int` type. - -```python -a: int | str = 1 -b: int = 1 if a else "s" # Error: expect int, got int(1)|str(s) -``` - -Note that although the any type is provided in the KCl, it is still a static type, and the types of all variables are immutable during compilation. - -#### Type Inference - -If a variable or constant declaration in the top level or in the schema is not annotated explicitly with a type, the declaration's type is inferred from the initial value. - -- Integer literals are inferred to type `int`. - -```python -a = 1 # The variable `a` has the type `int` -``` - -- Float literals are inferred to type `float`. - -```python -a = 1.0 # The variable `a` has the type `float` -``` - -- String literals are inferred to type `str`. - -```python -a = "s" # The variable `a` has the type `str` -``` - -- Boolean literals are inferred to type `bool` - -```python -a = True # The variable `a` has the type `bool` -b = False # The variable `b` has the type `bool` -``` - -- `None` and `Undefined` are inferred to type `any` - -```python -a = None # The variable `a` has the type `any` -b = Undefined # The variable `b` has the type `any` -``` - -- List literals are inferred based on the elements of the literal, and to be variable-size. - -```python -a = [1, 2, 3] # The variable `a` has the type `[int]` -b = [1, 2, True] # The variable `b` has the list union type `[int|bool]` -c = ["s", 1] # The variable `c` has the list union type `[int|str]` -``` - -Please note that a empty list will be inferred to `[any]` - -```python -a = [] # The variable `a` has the type `[any]` -``` - -- Dict literals are inferred based on the keys and values of the literal, and to be variable-size. - -```python -a = {key = "value"} # The variable `a` has the type `{str:str}` -b = {key = 1} # The variable `b` has the type `{str:int}` -c = {key1 = 1, key2 = "s"} # The variable `c` has the type `{str:int|str}` -``` - -Please note that a empty dict will be inferred to `{any:any}` - -```python -a = {} # The variable `a` has the type `{any:any}` -``` - -- The type of the if conditional expression carrying the runtime value will be statically inferred as a union type of all possible results. - -```python -a: bool = True # The variable `a` has the type `bool` -b = 1 if a else "s" # The variable `b` has the type `int|str` -``` - -When a variable is deduced to a certain type, its type cannot be changed - -```python -_a = 1 -_a = "s" # Error: expect int, got str(1) -``` - -#### Type Alias - -We can use the `type` keyword to declare a type alias for all types in KCL to simplify the writing and use of complex types. - -```python -type Int = int -type String = str -type StringOrInt = String | Int -type IntList = [int] -type StringAnyDict = {str:} -``` - -We can import a type through import and define an alias for it. - -```py -import pkg - -type Data = pkg.Data -``` - -In addition, we can use type aliases and union types to achieve similar enumeration functions. - -```python -# A type alias of string literal union types -type Color = "Red" | "Yellow" | "Blue" - -schema Config: - color: Color = "Red" # The type of color is `"Red" | "Yellow" | "Blue"`, and it has an alias `Color`, whose default value is `"Red"` - -config = Config { - color = "Blue" -} -``` - -The output YAML is - -```yaml -config: - color: Blue -``` - -Please note that the type alias name cannot be one of `any`, `int`, `float`, `bool` and `str` because of ambiguity. - -```python -type any = int | str # Error -type int = str # Error -type float = int # Error -type bool = True # Error -type str = "A" | "B" | "C" # Error -``` - -#### Type Guards - -KCL supports the `typeof` function which can give very basic information about the type of values we have at runtime. In KCL, checking against the value returned by `typeof` is a type guard. KCL expects this to return a certain set of strings: - -Example: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person {} -t3 = typeof(_x1) - -_x2 = pkg.Person {} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# Output -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -In addition, we can use the `as` keyword in conjunction with type guards to complete defensive type conversion programming. - -Only types with partial order can be downcast converted, the use of the as keyword is as follows: - -- Basic types of partial order relations, e.g., `float -> int` -- Partial order relation of union type, e.g., `int | str -> str` and `[int | str] -> [str]` -- Contains the partial order relation of the upper bound of the type, e.g., `any -> int` -- Partial order relationship of structure type, e.g., `base-schema -> sub-schema` - -```python -schema Data1: - id?: int - -schema Data2: - name?: str - -data: Data1 | Data2 = Data1 {} - -if typeof(a) == "Data1": - data1 = data as Data1 # The type of `data1` is `Data1` -elif typeof(a) == "Data2": - data2 = data as Data2 # The type of `data2` is `Data2` -``` - -When a runtime error occurs in the `as` type conversion, a runtime error is thrown. - -```python -a: any = "s" -b: int = a as int # Error: The `str` type cannot be converted to the `int` type -``` - -If we don’t want to throw a runtime error, we can use the type guard for defensive coding with `if` expressions. - -```python -a: any = "s" -b = a as int if typeof(a) == "int" else None # The type of b is `int` -``` - -Note that the `as` conversion of literal type and union type is not supported, because they are not a certain runtime object, only int, float and other objects at runtime, there is no int literal, float literal object, and no union object. - -### Schema - -#### Overview - -A schema is a language element to define a complex configuration. -We can define typed attributes, initialization assignment, and verification rules. In addition, KCL supports schema single inheritance, mixin and protocol to realize the reuse of complex configuration. - -#### Basic - -##### Attribute - -The followings are some basic examples: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 -``` - -In KCL, we can use type annotations to define some attributes in the schema, each attribute can be set with an optional default value (such as the `age` attribute in the above code, its default value is `0`), attributes that are not set default values have an initial value of `Undefined`, which are not output in YAML. - -Note, the immutability of attributes in the schema follows the same rules as the immutability of global variables, only mutable attributes in the schema can be modified in the schema. - -```python -schema Person: - age: int = 1 # Immutable attribute - _name: str = "Alice" # Mutable attribute - - age = 10 # Error - _name = "Bob" # Ok -``` - -###### Optional Attribute - -Each attribute **must** be assigned with a not `None`/`Undefined` value as a schema instance unless it is modified by a question mark as an optional attribute. - -Examples: - -```python -schema Employee: - bankCard: int # bankCard is a required attribute, and it can NOT be None or Undefined - nationality?: str # nationality is an optional attribute, and it can be None or Undefined - -employee = Employee { - bankCard = None # Error, attribute 'bankCard' of Employee is required and can't be None or Undefined - nationality = None # Ok -} -``` - -##### Irrelevant Order Calculation - -The irrelevant order calculation in the schema indicates the reference relationship between the internal attributes of the schema. For example, when we declare an expression of the form `a = b + 1`, the calculation of the value of `a` depends on the calculation of the value of `b`. When the compiler calculate the value of `a` and the value of `a` depends on the value of `b`, the compiler will choose to first calculate the value of `b`, and then calculate the value of a according to the expression `a = b + 1`, which is slightly different from the calculation method of traditional procedural language the difference. - -Since the calculation of values in the schema is based on dependencies, just like a directed acyclic graph traverses each node in the graph according to the order of topological sorting, the order of declaration of attributes in the schema is not so important, so the feature is called the irrelevant order calculation. - -Please note that there can be no circular references between different schema attribute values. - -We can see this feature through the following examples. - -```python -schema Fib: - n1: int = n - 1 # Refers to the attribute `n` declared after `n1` - n2: int = n1 - 1 - n: int - value: int = 1 if n <= 2 else Fib {n = n1}.value + Fib {n = n2}.value - -fib8 = Fib {n = 8}.value -``` - -The output is - -```yaml -fib8: 21 -``` - -We can see that in the schema, we only need to simply specify the dependency between attributes, and the compiler will automatically calculate the value based on the dependency, which can help us save a lot of boilerplate code and reduce configuration difficulty of writing. - -##### Schema Context - -We can define the context of the schema to manage the attributes of the schema, and we can write schema parameters, temporary variables and expressions directly in the schema: - -```python -schema Person[_name: str]: # define a schema argument - name: str = _name # define a schema attribute - age: int = 10 # define a schema attribute with default value - hands: [int] = [i for i in [1, 2, 3]] # define a for statement -``` - -##### Validation - -In addition to using **static typing** (the type annotation) and **immutability** in KCL schema mentioned earlier to ensure code stability, a bunch of validation rules are supported in a simple **check** block (KCL supports almost all authentication capabilities of [OpenAPI](https://www.openapis.org/)): - -```python -import regex - -schema Sample: - foo: str - bar: int - fooList: [str] - - check: - bar > 0 # minimum, also support the exclusive case - bar < 100 # maximum, also support the exclusive case - len(fooList) > 0 # min length, also support exclusive case - len(fooList) < 100 # max length, also support exclusive case - regex.match(foo, "^The.*Foo$") # regex match - isunique(fooList) # unique - bar in range(100) # range - bar in [2, 4, 6, 8] # enum - multiplyof(bar, 2) # multipleOf -``` - -With the schema, all instances will be validated at compile time - -```python -# Ok -goodSample = Sample { - foo = "The Foo" - bar = 2 - fooList = ["foo0", "foo1"] -} - -# Error: validation failure: Check failed on check conditions: bar < 100. -badSample = Sample { - foo = "The Foo" - bar = 123 - fooList = ["foo0", "foo1"] -} -``` - -In addition, we can use **and**, **or**, **if** to compose more complex conditional check logic: - -```python -schema Sample: - bar: int - foo: str - doCheck: bool - - check: - regex.match(foo, "^The.*Foo$") and bar in [2, 4, 6, 8] if doCheck -``` - -In order to ensure that all check rules can play their corresponding roles well, we can test the rationality and correctness of different data combinations by writing KCL test cases, and run all test cases through the kcl test tool. - -##### Documents - -Usually after we write the schema model, we will write documentation comments for the schema, which can be completed by using a three-quoted string as follows: - -```python -schema Server: - """Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - - Attributes - ---------- - workloadType : str, default is Deployment - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - name : str, default is None - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - labels : {str:str}, optional, default is None - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - - Examples - ---------------------- - myCustomApp = AppConfiguration { - name = "componentName" - } - """ - workloadType: str = "Deployment" - name: str - labels?: {str:str} -``` - -##### Config - -Suppose we have the following schema definition: - -```python -schema Person: - firstName: str - lastName: str -``` - -A config could be defined with a JSON-like expression: - -```python -person = Person { - firstName = "firstName" - lastName = "lastName" -} -``` - -At the same time, the schema adheres to strict attribute definitions, -and configuring undefined attributes will trigger a compilation error. - -```python -person = Person { - firstName = "firstName" - lastName = "lastName" - fullName = "fullName" # Error: Cannot add member 'fullName' to schema 'Person', 'fullName' is not defined in schema 'Person' -} -``` - -We can use `if expressions` to dynamically add elements to the schema config, elements that meet the conditions are added to the schema config, and elements that do not meet the conditions are ignored. Besides, the **config selector expressions** can be used to init a schema instance. - -```python -schema Base: - count: int - value: str - -schema Person: - base: Base - labels: {str:str} - name?: str - -env = "prod" - -person1 = Person { - base.count = 2 # Config selector expression - base.value = "value" # A schema variable in schema can use selector expressions - labels.key = "value" # A dict variable in schema can use selector expressions -} - -person2 = Person { - base = { - count = 1 - value = "value" - } - labels.key = "value" - if env == "prod": - labels.env = env - else: - labels.env = "other" -} -``` - -The output YAML is - -```yaml -person1: - base: - count: 2 - value: value - labels: - key: value -person2: - base: - count: 1 - value: value - labels: - key: value - env: prod -``` - -When we instantiate a schema without config parameters, we can generate schema instances in the following three forms: - -```python -schema Data: - id: int = 1 - -data1 = Data {} -data2 = Data() {} -data3 = Data() -``` - -In addition to using a schema type to instantiate a schema, we can also use a schema instance to get a new instance using the config expression. - -```python -schema Config: - id: int - values: [int] - -configOrigin = Config { - id = 1 - values = [0, 1] -} -configNew = configOrigin { - id = 2 - values += [2, 3] -} -``` - -The output is - -```yaml -configOrigin: - id: 1 - values: - - 0 - - 1 -configNew: - id: 2 - values: - - 0 - - 1 - - 2 - - 3 -``` - -In addition, schema attribute default values can be modified by schema config. - -```python -schema Person: - age: int = 1 - name: str = "Alice" - - age = 2 # Error, can't change the default value of the attribute `age` in the schema context - -person = Person { - age = 3 # Ok, can change the default value of the attribute `age` in the schema config -} -``` - -#### Advanced - -##### Protocol & Mixin - -In addition to schema, an additional type definition method `protocol` is provided in KCL, and its properties are as follows: - -- In a protocol, only attributes and their types can be defined, complex logic and check expressions cannot be written, and mixins cannot be used. -- A protocol can only constrain properties that do not start with `_`. -- A protocol can only inherit or refer to other protocols, but cannot inherit or refer to other schemas. - -Besides, we can declare a complex assembly schema with optional **mixin** support and use **protocol** to add an optional host type to the dynamically inserted **mixin**.: - -```python -schema Person: - mixin [FullNameMixin] - - firstName: str # Required - lastName: str # Required - fullName?: str # Optional -``` - -A fullName mixin which generates a fullName as a simple sample: - -```python -protocol PersonProtocol: - firstName: str - lastName: str - fullName?: str - -mixin FullNameMixin for PersonProtocol: - fullName = "{} {}".format(firstName, lastName) -``` - -Then we can get the schema instance by: - -```python -person = Person { - firstName = "John" - lastName = "Doe" -} -``` - -The output is - -```yaml -person: - firstName: John - lastName: Doe - fullName: John Doe -``` - -Please note that the host type **protocol** can only be used for **mixin** definitions (the suffix name is `Mixin`), otherwise an error will be reported. - -```python -protocol DataProtocol: - data: str - -schema Data for DataProtocol: # Error: only schema mixin can inherit from protocol - x: str = data -``` - -##### Index Signature - -Index signatures can be defined in the KCL schema, and it means that the key-value constraints of the index signature can be used to construct a dict with the schema type, or additional checks can be added to the schema attributes to enhance the KCL type and semantic checks. - -- Use the form `[{attr_alias}: {key_type}]: {value_type}` to define an index signature in the schema, and `{attr_alias}` can be omitted. - -```python -schema Map: - """ - Map is a schema with a key of str type and a value of str type - """ - [str]: str # `{attr_alias}` can be omitted. - -data = Map { - key1 = "value1" - key2 = "value2" -} -``` - -- Mandatory all attributes of the schema key and value types - -```python -schema Person: - name: str - age: int # error, conflicts with the index signature definition `[str]: str` - [str]: str # The values of all attributes of the schema can only be strings -``` - -- Mandatory all attribute key and value types are defined in the schema, which is equivalent to restricting all attribute types except the additional attributes. - -```python -schema Person: - name: str - age: int - [...str]: str # Except for the `name` and `age` attributes, the key type of all other attributes of the schema must be `str`, and the value type must also be `str`. -``` - -- Define the index signature attribute alias and use it with the check block. - -```python -schema Data: - [dataName: str]: str - check: - dataName in ["Alice", "Bob", "John"] - -data = Data { - Alice = "10" - Bob = "12" - Jonn = "8" # Error: Jonn not in ["Alice", "Bob", "John"] -} -``` - -```python -import regex - -schema DataMap: - [attr: str]: str - check: - regex.match(attr, r'^[-._a-zA-Z0-9]+$') - -data = DataMap { - key1 = "value1" - "foo.bar" = "value2" # check error -} -``` - -##### Inheritance - -Like some other object-oriented languages, KCL provides fundamental but limited object-oriented support, such as **attribute reuse**, **private and public variables**, and **single inheritance**. Besides, KCL does NOT support multiple inheritances for the schema. - -The following is an example of schema inheritance: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 - -# An employee **is** a person, and has some additional information. -schema Employee(Person): - bankCard: int - nationality?: str - -employee = Employee { - firstName = "Bob" - lastName = "Green" - age = 18 - bankCard = 123456 -} -``` - -The output is - -```yaml -employee: - firstName: Bob - lastName: Green - age: 18 - bankCard: 123456 - nationality: null -``` - -Please note that KCL only allows **single inheritance** on schemas. - -In addition, when the schema has an inheritance relationship, the properties of optional attributes are as follows: - -- If the attribute is optional in the base schema, it could be optional or required in the sub-schema. -- If the attribute is required in the base schema, it must be required in the sub-schema. - -```python -schema Person: - bankCard?: int - nationality: str - -schema Employee(Person): - bankCard: int # Valid, both `bankCard: int` and `bankCard?: int` are allowed - nationality?: str # Error, only `nationality: str` is allowed -``` - -##### Schema Function - -Schema map very nicely onto functions; it can have any number of input and output parameters. For example, the Fibonacci function can be written as follows using the recursive schema config: - -```python -schema Fib[n: int]: - n1 = n - 1 - n2 = n - 2 - if n == 0: - value = 0 - elif n == 1: - value = 1 - else: - value = Fib(n1).value + Fib(n2).value - -fib8 = Fib(8).value # 21 -``` - -##### Decorators - -Just like Python, KCL supports the use of decorators on the schema. KCL Decorators dynamically alter the functionality of a schema without having to directly use sub schema or change the source code of the schema being decorated. And like a function call, the decorator supports passing in additional parameters. - -Built-in decorators of schema - -- `@deprecated` - Mark whether a schema or schema attribute is deprecated. The `@deprecated` decorator supports three parameters: - - **version** - string type, indicating the version information. The default value is empty. - - **reason** - string type, indicating the deprecated reason. The default value is empty. - - **strict** - bool type, indicating whether to report an error or warning. The default value is true. If `strict` is `True` and the error is thrown, the program will be interrupted. If `strict` is `False`, a warning will be output and the program will not be interrupted. - -Examples: - -```python -@deprecated -schema ObsoleteSchema: - attr: str - -schema Person: - name: str = "John" - attrs: ObsoleteSchema = { - attr = "value" - } - -person = Person {} # Error: ObsoleteSchema was deprecated -``` - -```python -schema Person: - firstName: str = "John" - lastName: str - @deprecated(version="1.16", reason="use firstName and lastName instead", strict=True) - name: str - -JohnDoe = Person { # Error: name was deprecated since version 1.16, use firstName and lastName instead - name = "deprecated" -} -``` - -Note that the current version of KCL does not yet support user-defined decorators. - -##### Members - -Built-in functions and members of schema - -- instances() - Return the list of existing instances of a schema. - -```python -schema Person: - name: str - age: int - -alice = Person { - name = "Alice" - age = 18 -} - -bob = Person { - name = "Bob" - age = 10 -} - -aliceAndBob = Person.instances() # Person is a schema type, instances() is its member method -``` - -The output is - -```yaml -alice: - name: Alice - age: 18 -bob: - name: Bob - age: 10 -aliceAndBob: - - name: Alice - age: 18 - - name: Bob - age: 10 -``` - -### Config Operations - -#### Config Unification - -##### | Operators - -In KCL, we can use the union operator `|` to achieve the merging of configurations, the types supported by the union operator are as follows: - -```txt -SchemaInstance | SchemaInstance -SchemaInstance | Dict -Dict | Dict -List | List -``` - -Unioning collection and schema data: - -- Unioning List. Overwrite the list expression on the right side of the operator `|` to the list variable on the left side of the operator one by one according to the **index**. - -```python -_a = [1, 2, 3] -_b = [4, 5, 6, 7] -x = _a | _b # [4, 5, 6, 7] 1 -> 4; 2 -> 5; 3 -> 6; Undefined -> 7 -``` - -Unioning to the specific index or all elements is still under discussion. - -- Unioning Dict. Union the dict expression on the right side of the operator `|` one by one to the dict variable on the left side of the operator according to the **key** - -```python -_a = {key1 = "value1"} -_b = {key1 = "overwrite", key2 = "value2"} -x = _a | _b # {"key1": "overwrite", "key2": "value2"} -``` - -The union of collection and schema is a new one whose attributes are unioning b to a, preserving the order of the attributes of the operands, left before right. - -- Unioning Schema. The union operation for schema is similar to dict. - -Schema union could be done as: - -```python -schema Person: - firstName?: str - lastName?: str - -_a = Person { - firstName = "John" -} -_b = {lastName = "Doe"} -_c = _a | _b # {"firstName": "John", "lastName": "Doe"} -_d = _a | None # {"firstName": "John"} -_e = _a | Undefined # {"firstName": "John"} -_f = None | _a # {"firstName": "John"} -_g = Undefined | _a # {"firstName": "John"} -``` - -Please note that when one of the left and right operands of the union operator is None, the other operand is returned immediately. - -```python -data1 = {key = "value"} | None # {"key": "value"} -data2 = None | [1, 2, 3] # [1, 2, 3] -data3 = None | None # None -``` - -The output is - -```yaml -data1: - key: value -data2: - - 1 - - 2 - - 3 -data3: null -``` - -##### : Operators - -Pattern: `identifier : E` or `identifier : T E` - -The value of the expression `E` with optional type annotation `T` will be unioned into the element value. - -Examples: - -```python -data = { - labels: {key1: "value1"} - # union {key2: "value2"} into the attribute labels. - labels: {key2: "value2"} -} -``` - -Output: - -```yaml -data: - labels: - key1: value1 - key2: value2 -``` - -In addition to using attribute operators on the schema config attributes, variables inside and outside the schema can use attribute operators to perform different operations on the configuration. - -- Using `:` outside the schema - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - data: Data - -# This is one configuration that will be merged. -config: Config { - data.d1 = 1 -} -# This is another configuration that will be merged. -config: Config { - data.d2 = 2 -} -``` - -Its equivalent configuration code can be expressed as - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - data: Data - -config: Config { - data.d1 = 1 - data.d2 = 1 -} -``` - -The output is - -```yaml -config: - data: - d1: 1 - d2: 1 -``` - -- Using `:` inside the schema - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - # This is one configuration that will be merged. - data: Data { - d1 = 1 - } - # This is another configuration that will be merged. - data: Data { - d2 = 1 - } - -config: Config {} -``` - -#### Config Override - -##### = Operators - -Pattern: `identifier = E` or `identifier : T = E` - -The value of the expression `E` with optional type annotation `T` will override the attribute value. - -Examples: - -```python -schema Data: - labels: {str:} = {key1 = "value1"} - -data = Data { - # override {key2: "value2"} into the attribute labels of the schema Data. - labels = {key2 = "value2"} -} -``` - -Output: - -```yaml -data: - labels: - key2: value2 -``` - -Note: - -- Especially, we can "delete" its content by overriding the attribute to `Undefined`, such as `{ a = Undefined }`. - -#### Insert - -##### += Operators - -Pattern: `identifier += E` or `identifier : T += E` - -Insert only works for list type `identifier`. - -`E` will be inserted just after the specified index of the list `identifier`, and the following attributes after the index will be automatically shifted. - -Examples: - -```python -schema Data: - labels: {str:} = {key1 = [0]} - -data = Data { - # insert [1] into the attribute labels.key1 of the schema Data. - labels: {key1 += [1]} -} -``` - -Output: - -```yaml -data: - labels: - key1: - - 0 - - 1 -``` - -If no index is specified, the last index will be used. - -#### Notice - -Please note that the calculations of the `=` and `+=` attribute operators of the same attribute are sequential, and the latter ones have a higher priority. - -```python -x = { - a = 1 # 1 -} | { - a = 2 # 1 -> 2 -} | { - a = 3 # 2 -> 3 -} # The final value of attribute `a` is 3 -``` - -Please note that the `:` attribute operator represents an idempotent merge operation, and an error will be thrown when the values that need to be merged conflict. - -Therefore, when we need a configuration to override or add and delete operations, it is best to use the `=` and `+=` operators - -```python -data0 = {id: 1} | {id: 2} # Error:conflicting values between {'id': 2} and {'id': 1} -data1 = {id: 1} | {id = 2} # Ok, the value of `data` is {"id": 2} -``` - -The check rules for `:` operator for KCL value conflicts are as follows: - -- For `None` and `Undefined` variables, they do not conflict with any value. - -```python -data0 = None | {id: 1} # Ok -``` - -- For `int`, `float`, `str` and `bool` types, when their values are different, they are considered as conflicts. - -```python -data0 = 1 | 1 # Ok -data1 = 1 | "s" # Error -``` - -- For list type - - When their lengths are not equal, they are regarded as conflicts. - - When their lengths are equal, as long as there is a conflict in the value of a child element, it is regarded as a conflict. - -```python -data0 = [1] | [1] # Ok -data1 = [1, 2] | [1] # Error -``` - -- For dict/schema type - - When the values of the same key conflict, they are regarded as conflicts - -```python -data0 = {id: 1} | {id: 1} # Ok -data1 = {id: 1} | {id: 2} # Error -data1 = {id: 1} | {idAnother: 1} # Ok -``` - -### Rule - -In addition to using the check keyword for verification and writing in the schema, KCL also supports the use of the `rule` keyword to define a set of rules for policy verification - -The KCL rule is the same as the schema/mixin/protocol and it is defined by indentation. We need write a rule per line and we can write if filter conditions and verification failure information for each rule. Different conditions are connected with logic `and` (similar to the way of writing in check block). - -```python -rule SomeRule: - age > 0, "rule check failure message" -``` - -We can call a KCL rule like instantiating a schema: - -```python -age = 1 -name = "Alice" - -rule SomeRule: - age > 0, "rule check failure message" - name == "Alice" - -rule1 = SomeRule() # Rule call -rule2 = SomeRule {} # Rule call -``` - -We can use protocol to implement type checking of rule structure: - -```python -# Schema definition -protocol Service: - clusterIp: str - $type: str - -# Schema definition -protocol Volume: - mountPath: [str] - -# Protocol -protocol SomeProtocol: - id: int - env: {str: any} - services: [Service] - volumes: [Volume] - -rule SomeChecker for SomeProtocol: - id > 0, "id must >0" - - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - } - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } - -# Call rule to check with config parameter -SomeChecker { - id = 1 - env = { - MY_ENV = "MY_ENV_VALUE" - } - services = [ - { - type = "ClusterIP" - clusterIP = "NONE" - } - ] - volumes = [ - { - mountPath = "/home/admin" - } - { - mountPath = "/home/myapp" - } - ] -} -``` - -Please note that the combination of `protocol` and `rule` can separate attributes from their constraint definitions. We can define different rules and protocols in different packages and combine them as needed. This is different from check expressions in schema, which can only be combined with schema attributes. - -Besides, the following two ways can be used to achieve the multiplexing of different Rules: - -- Inline Call - -```python -weather = "sunny" -day = "wednesday" - -rule IsSunny: - weather == "sunny" - -rule IsWednesday: - day == "wednesday" - -rule Main: - IsSunny() # Rule inline call - IsWednesday() # Rule inline call - -Main() # Rule call -``` - -- Inherit - -```python -weather = "sunny" -day = "wednesday" - -rule IsSunny: - weather == "sunny" - -rule IsWednesday: - day == "wednesday" - -rule Main(IsSunny, IsWednesday): - id == 1 - -Main() -``` - -We can obtain external data or input from the `option` function and the CLI parameter `-D` for verification: - -- A simple example - -```python -schema Day: - day: str - homework: str - -days: [Day] = option("days") - -rule Main: - filter d in days { - d.day not in ["saturday", "sunday"] and d.homework - } - -Main() -``` - -- A complex example - -```python -data = option("data") -input = option("input") - -rule Allow: - UserIsAdmin() - any grant in UserIsGranted() { - input.action == grant.action and input.type == grant.type - } - -rule UserIsAdmin: - any user in data.user_roles[input.user] { - user == "admin" - } - -rule UserIsGranted: - [ - grant - for role in data.user_roles[input.user] - for grant in data.role_grants[role] - ] - -allow = Allow() or False -``` - -Further, the above KCL rule code can be compiled into a target such as WASM and used at runtime. - -### Module - -KCL config files are organized as **modules**. A single KCL file is considered as a module, and a directory is considered as a package, which is a special module. - -The modules in the same package are visible and cross-package references need to be visible through import. - -Code structure: - -```bash -. -└── root - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -model1.k: - -```python -# schema CatalogItem in model1.k - -schema CatalogItem: - id: int - image: CatalogItemImage # CatalogItemImage is defined in the module of the same package e.g., model2.k in package model - title: str -``` - -service1.k: - -```python -import ..model as model # cross-package references - -schema ImageService: - image: model.CatalogItemImage # CatalogItemImage is imported from another package e.g., model2.k in package model - name: str -``` - -#### Relative Path Import - -We can use the operator `.` to realize the relative path import of KCL entry files. - -main.k: - -```python -import .model1 # Current directory module -import ..service # Parent directory -import ...root # Parent of parent directory - -s = service.ImageService {} -m = root.Schema {} -``` - -#### Absolute Path Import - -The semantics of `import a.b.c.d` is - -1. If `kcl.mod` not exist, regard the current directory as the package root and search the path `a/b/c/d` from the current directory. -2. If the current directory search fails, search from the root path `ROOT_PATH/a/b/c/d`, else raise an import error. - -The definition of the root path `ROOT_PATH` is the directory corresponding to the `kcl.mod` file from the current directory. - -Code structure: - -```bash -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -main.k: - -```python -import service # `root package` and `kcl.mod` are in the same directory -import mixin # `root package` and `kcl.mod` are in the same directory - -myModel = model.CatalogItem {} -``` - -Note that for the KCL entry file `main.k`, it cannot be imported into the folder where it is located, otherwise a recursive import error will occur: - -```python -import model # Error: recursively loading -``` - -### Top-Level Argument - -Assume some field need to be passed in dynamically like user input, we can define a top-level argument in a module: - -```python -bankCard = option("bankCard") # Get bankCard through the option function. -``` - -Then we can use the module as below: - -```bash -kcl employee.k -D bankCard=123 -``` - -Currently, supported types of top-level argument are number, string, bool, list and dict. - -```bash -kcl main.k -D list_key='[1,2,3]' -D dict_key='{"key":"value"}' -``` - -We need to pay attention to the escape of quotation marks `"` and other symbols in the command line - -#### Arguments with Setting Files - -In addition, it also supports inputting a YAML file as top-level arguments. - -```yaml -kcl_options: - - key: key_number - value: 1 - - key: key_dict - value: - innerDictKey: innerDictValue - - key: key_list - value: - - 1 - - 2 - - 3 - - key: bankCard - value: 123 -``` - -```bash -kcl -Y setting.yaml employee.k -``` - -In addition, the setting file also supports configuring command-line compilation parameters as follows: - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - disable_none: true - strict_range_check: true - debug: 1 - verbose: 1 - sort_keys: true - output: ./stdout.golden - overrides: - - app.image=new_image - path_selector: - - config - package_maps: - k8s: /Users/.kcl/kpm/k8s_1.24 -kcl_options: - - key: image - value: docker.io/kcllang/kcl:latest -``` - -KCL CLI -Y parameters also support multi-file configuration, and support separate writing and merging of compilation parameters and option top level arguments parameter configuration. - -```bash -kcl -Y compile_setting.yaml option_setting.yaml -``` - -- `compile_setting.yaml` - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - disable_none: true - strict_range_check: true - debug: 1 - verbose: 1 - output: ./stdout.golden -``` - -- `option_setting.yaml` - -```yaml -kcl_options: - - key: image - value: docker.io/kcllang/kcl:latest -``` - -We can use the following command line to get the meaning of each configuration parameter or see KCL Quick Start - -```bash -kcl --help -``` - -#### Option Functions - -We can use the `option` function in the KCL code to get the top-level arguments. - -```python -value = option(key="key", type='str', default="default_value", required=True, help="Set key value") -``` - -Parameters - -- **key**: The argument key. -- **type**: The argument type to be converted. -- **default**: The argument default value when the key-value argument is not provided -- **required**: Report an error when the key-value argument is not provided and required is True. -- **help**: The help message. - -### Multi-file Compilation - -In addition to the above KCL single file execution, we can compile multiple KCL entry files at the same time using the following command: - -```bash -kcl main_1.k main_2.k ... main_n.k -``` - -main_1.k - -```python -a = 1 -b = 2 -``` - -main_2.k - -```python -c = 3 -d = 4 -``` - -The output is: - -```yaml -a: 1 -b: 2 -c: 3 -d: 4 -``` - -Taking advantage of the **multi-file combination**, we can assemble multiple KCL files without the need to use import management files. Let us see an example of combining **multi-file compilation** and **schema instance**. - -model.k - -```python -schema Model: - name: str - labels?: {str:} - annotations?: {str:} - replicas: int - -_model1 = Model { - name = "model1" - labels.key1 = "value1" - labels.key2 = "value2" - annotations.key = "value" - replicas = 2 -} - -_model2 = Model { - name = "model2" - replicas = 3 -} -``` - -backend.k - -```python -import yaml - -schema Backend: - apiVersion: str = "v1" - kind: str = "Deployment" - metadata: {str:} - spec: {str:} = { - minReadySeconds = 0 - paused = False - progressDeadlineSeconds = 600 - replicas = 1 - revisionHistoryLimit = 10 - selector = {} - } - -_backends = [Backend { - metadata.name = model.name - metadata.labels = model.labels - metadata.annotations = model.annotations - spec.selector.matchLabels: model.labels - spec.replicas = model.replicas -} for model in Model.instances()] # Schema Model is defined in model.k -print("---\n".join([yaml.encode(_b, ignore_private=True) for _b in _backends])) -``` - -The command is - -```bash -kcl model.k backend.k -``` - -The output is - -```yaml -apiVersion: v1 -kind: Deployment -metadata: - name: model1 - labels: - key1: value1 - key2: value2 - annotations: - key: value -spec: - minReadySeconds: 0 - paused: false - progressDeadlineSeconds: 600 - replicas: 2 - revisionHistoryLimit: 10 - selector: - matchLabels: - key1: value1 - key2: value2 ---- -apiVersion: v1 -kind: Deployment -metadata: - name: model2 -spec: - minReadySeconds: 0 - paused: false - progressDeadlineSeconds: 600 - replicas: 3 - revisionHistoryLimit: 10 - selector: {} -``` - -### KCL CLI Path Selector - -We can use KCL CLI `-S|--path-selector` parameter to select one or more values out of a KCL model. - -The path selector looks like this: - -`var.name` - -#### Examples - -Code structure: - -```bash -. -├── kcl.mod -└── main.k - └── pkg - └── model.k -``` - -pkg/model.k: - -```python -schema Person: - name: str - age: int - -var = Person { - name = "Alice" - age = 18 -} -``` - -main.k - -```python -import pkg - -var = pkg.Person { - name = "Bob" - age = 10 -} -``` - -The command is - -```bash -kcl main.k -S var -``` - -The output is - -```yaml -name: Alice -age: 18 -``` - -### KCL CLI Variable Override - -In addition to **Variable Selector**, KCL also allows us to directly modify the values in the configuration model through the KCL CLI `-O|--overrides` parameter. - -The use of **Variable Override** is similar to [**Variable Selector**](#variable-selector), and the parameter contains three parts e.g., `pkg`, `identifier`, `attribute` and `override_value`. - -```bash -kcl main.k -O override_spec -``` - -- `override_spec` represents a unified representation of the configuration model fields and values that need to be modified - -```txt -override_spec: [[pkgpath] ":"] identifier ("=" value | "-") -``` - -- `pkgpath`: Indicates the path of the package whose identifier needs to be modified, usually in the form of `a.b.c`. For the main package, `pkgpath` is expressed as `__main__`, which can be omitted. If omitted, it means the main package. -- `identifier`: Indicates the identifier that needs to modify the configuration, usually in the form of `a.b.c`. -- `value`: Indicates the value of the configuration that needs to be modified, which can be any legal KCL expression, such as number/string literal value, list/dict/schema expression, etc. -- `=`: means to modify the value of identifier. - - When the identifier exists, modify the value of the existing identifier to value. - - When identifier does not exist, add the identifier attribute and set its value to value. -- `-`: means to delete the identifier attribute. - - When the identifier exists, delete it directly. - - When the identifier does not exist, no modification is made to the configuration. - -Note: When `identifier` appears multiple times, modify/delete all `identifier` values - -#### Examples - -##### Override Update Sample - -KCL code: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -``` - -The command is - -```bash -kcl main.k -O :person.name=\"Bob\" -O :person.age=10 -``` - -The output is - -```yaml -person: - name: Bob - age: 10 -``` - -Besides, when we use KCL CLI `-d` argument, the KCL file will be modified to the following content at the same time - -```bash -kcl main.k -O :person.name=\"Bob\" -O :person.age=10 -d -``` - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Bob" - age = 10 -} -``` - -Another more complicated example: - -```python -schema Person: - name: str - age: int - ids?: [int] - -person = Person { - name = "Alice" - age = 10 -} -``` - -The command is - -```bash -kcl main.k -O :person.ids=\[1,2\] -``` - -The output is - -```yaml -person: - name: Alice - age: 10 - ids: - - 1 - - 2 -``` - -##### Override Delete Sample - -KCL code: - -```python -schema Config: - x?: int = 1 - y?: str = "s" - -config = Config { - x = 2 -} -``` - -The command is - -```bash -kcl main.k -O config.x- -``` - -The output is - -```yaml -config: - x: 1 - y: s -``` - -### Summary - -This page summarized the commonly used features in the KCL language. As a new language, KCL will gradually increase the functional features according to the requirements of the configuration scenario. - -For more information, please try further resources: - -- KCL codelabs -- KCL language specification -- KCL OpenAPI specification diff --git a/versioned_docs/version-0.5.3/reference/model/crypto.md b/versioned_docs/version-0.5.3/reference/model/crypto.md deleted file mode 100644 index 7fab7e50..00000000 --- a/versioned_docs/version-0.5.3/reference/model/crypto.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "crypto" -linkTitle: "crypto" -type: "docs" -description: crypto system module -weight: 100 ---- - -## md5 - -`md5(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `MD5` and the codec registered for encoding. - -## sha1 - -`sha1(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA1` and the codec registered for encoding. - -## sha224 - -`sha224(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA224` and the codec registered for encoding. - -## sha256 - -`sha256(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA256` and the codec registered for encoding. - -## sha384 - -`sha384(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA384` and the codec registered for encoding. - -## sha512 - -`sha512(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA512` and the codec registered for encoding. diff --git a/versioned_docs/version-0.5.3/reference/model/datetime.md b/versioned_docs/version-0.5.3/reference/model/datetime.md deleted file mode 100644 index 5b829890..00000000 --- a/versioned_docs/version-0.5.3/reference/model/datetime.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: "datetime" -linkTitle: "datetime" -type: "docs" -description: datetime system module -weight: 100 ---- - -## time - -`ticks() -> float` - -Return the current time in seconds since the Epoch. Fractions of a second may be present if the system clock provides them. - -## date - -`date() -> str` - -Return the `%Y-%m-%d %H:%M:%S` format date. - -## now - -`now() -> str` - -Return the local time. e.g. `'Sat Jun 06 16:26:11 1998'` - -## today - -`today() -> str` - -Return the `%Y-%m-%d %H:%M:%S.%{ticks}` format date. diff --git a/versioned_docs/version-0.5.3/reference/model/index.md b/versioned_docs/version-0.5.3/reference/model/index.md deleted file mode 100644 index 163e8db3..00000000 --- a/versioned_docs/version-0.5.3/reference/model/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# System Package - -KCL provides engineering extensibility through system modules, user modules and plug-in modules. This section describes the basic concepts of system modules. diff --git a/versioned_docs/version-0.5.3/reference/model/json.md b/versioned_docs/version-0.5.3/reference/model/json.md deleted file mode 100644 index 44ec8c73..00000000 --- a/versioned_docs/version-0.5.3/reference/model/json.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: "json" -linkTitle: "json" -type: "docs" -description: json system module -weight: 100 ---- - -## encode - -``` -encode( - data: any, - sort_keys: bool = False, - indent: int = None, - ignore_private: bool = False, - ignore_none: bool = False -) -> str -``` - -Serialize a KCL object `data` to a JSON formatted str. - -## decode - -`decode(value: str) -> any` - -Deserialize `value` (a string instance containing a JSON document) to a KCL object. - -## dump_to_file - -``` -dump_to_file( - data: any, - filename: str, - ignore_private: bool = False, - ignore_none: bool = False -) -> None -``` - -Serialize a KCL object `data` to a JSON formatted str and write it into the file `filename`. diff --git a/versioned_docs/version-0.5.3/reference/model/math.md b/versioned_docs/version-0.5.3/reference/model/math.md deleted file mode 100644 index dae369af..00000000 --- a/versioned_docs/version-0.5.3/reference/model/math.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: "math" -linkTitle: "math" -type: "docs" -description: math system module -weight: 100 ---- - -## ceil - -`ceil(x) -> int` - -Return the ceiling of `x` as an Integral. This is the smallest integer >= x. - -## factorial - -`factorial(x) -> int` - -Return `x!`. Raise a error if `x` is negative or non-integral. - -## floor - -`floor(x) -> int` - -Return the floor of `x` as an Integral. This is the largest integer <= x. - -## gcd - -`gcd(a: int, b: int) -> int` - -Return the greatest common divisor of `x` and `y` - -## isfinite - -`isfinite(x) -> bool` - -Return `True` if `x` is neither an infinity nor a `NaN`, and `False` otherwise. - -## isinf - -`isinf(x) -> bool` - -Return `True` if `x` is a positive or negative infinity, and `False` otherwise. - -## isnan - -`isnan(x) -> bool` - -Return `True` if `x` is a `NaN` (not a number), and `False` otherwise. - -## modf - -`modf(x) -> List[float, float]` - -Return the fractional and integer parts of `x`. Both results carry the sign of `x` and are floats. - -## exp - -`exp(x) -> float` - -Return `e` raised to the power of `x`. - -## expm1 - -`expm1(x) -> float` - -Return `exp(x) - 1`. This function avoids the loss of precision involved in the direct evaluation of `exp(x) - 1` for small `x`. - -## log - -`log(x, base=2.71828182845904523536028747135266250) -> float` - -Return the logarithm of `x` to the base `e`. - -## log1p - -`log1p(x) -> float` - -Return the natural logarithm of `1+x` (base `e`). The result is computed in a way which is accurate for `x` near zero. - -## log2 - -`log2(x) -> float` -Return the base 2 logarithm of `x`. - -## log10 - -`log10(x) -> float` - -Return the base 10 logarithm of `x`. - -## pow - -`pow(x, y) -> float` - -Return `x**y` (`x` to the power of `y`). - -## sqrt - -`sqrt(x) -> float` - -Return the square root of `x`. diff --git a/versioned_docs/version-0.5.3/reference/model/overview.md b/versioned_docs/version-0.5.3/reference/model/overview.md deleted file mode 100644 index 36365ac1..00000000 --- a/versioned_docs/version-0.5.3/reference/model/overview.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -sidebar_position: 0 ---- - -# Overview - -KCL provides engineering extensibility through built-in modules, system modules and plug-in modules. - -![](/img/docs/reference/lang/model/kcl-module.png) - -The user code does not need to import functions that directly use builtin functions (such as calculating the length of a list with `len`, obtaining the type of value through `typeof`, etc.), and for basic types such as strings, it also provides some built-in methods (such as converting the case of strings, etc.). - -For relatively complex general logic, it is provided through the system modules. For example, by importing the `math` module, we can use related mathematical functions, and we can use the regular expression by importing the `regex` module. For KCL code, it can also be organized into different user modules. - -In addition, Python and Go can be used to develop plug-ins for KCL through the plugin mechanism. For example, there are the app-context plug-in can be used to obtain the context information of the current application to simplify code writing. diff --git a/versioned_docs/version-0.5.3/reference/model/yaml.md b/versioned_docs/version-0.5.3/reference/model/yaml.md deleted file mode 100644 index 4b952dcf..00000000 --- a/versioned_docs/version-0.5.3/reference/model/yaml.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: "yaml" -linkTitle: "yaml" -type: "docs" -description: yaml encode and decode function -weight: 300 ---- - -## encode - -``` -encode( - data: any, - sort_keys: bool = False, - ignore_private: bool = False, - ignore_none: bool = False -) -> str -``` - -Serialize a KCL object `data` to a YAML formatted str. - -## decode - -`decode(value: str) -> any` - -Deserialize `value` (a string instance containing a YAML document) to a KCL object. - -## dump_to_file - -``` -dump_to_file( - data: any, - filename: str, - ignore_private: bool = False, - ignore_none: bool = False -) -> None -``` - -Serialize a KCL object `data` to a YAML formatted str and write it into the file `filename`. diff --git a/versioned_docs/version-0.5.3/reference/package-management/_category_.json b/versioned_docs/version-0.5.3/reference/package-management/_category_.json deleted file mode 100644 index 7848e437..00000000 --- a/versioned_docs/version-0.5.3/reference/package-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Package Management Tools", - "position": 4 -} diff --git a/versioned_docs/version-0.5.3/reference/package-management/command-reference/1.init.md b/versioned_docs/version-0.5.3/reference/package-management/command-reference/1.init.md deleted file mode 100644 index 6a46976a..00000000 --- a/versioned_docs/version-0.5.3/reference/package-management/command-reference/1.init.md +++ /dev/null @@ -1,45 +0,0 @@ -# kpm init - -Init a kcl package. - -## Usage - -```shell -kpm init [options][package_name] -``` - -## Description - -`kpm init` will initialize a kcl package in the current directory. If the package name is not provided, the name of the current directory will be used. - -If the package name is provided, a subdirectory with the name of the package will be created and the package will be initialized in that directory. - -`kpm init` will create `kcl.mod`, `kcl.mod.lock` and `main.k` under the package directory. - -## Options - -### --help, -h - -Show help for `kpm init` command. - -## Examples - -### Init the current directory into a kcl package - -```shell -# create an empty directory -$ mkdir my_package - -# cd into the directory -$ cd my_package - -# init the current directory into a kcl package -$ kpm init -``` - -### Init a kcl package with a name - -```shell -# init a kcl package with a name 'my_package' -kpm init my_package -``` diff --git a/versioned_docs/version-0.5.3/reference/package-management/command-reference/10.help.md b/versioned_docs/version-0.5.3/reference/package-management/command-reference/10.help.md deleted file mode 100644 index 94c078f5..00000000 --- a/versioned_docs/version-0.5.3/reference/package-management/command-reference/10.help.md +++ /dev/null @@ -1,21 +0,0 @@ -# kpm help - -Print help information for kpm commands. - -## Usage - -```shell -kpm help -``` - -## Description - -`kpm help` will print help information for kpm commands. - -## Examples - -Use `kpm help` to print help information for kpm commands. - -```shell -kpm help -``` diff --git a/versioned_docs/version-0.5.3/reference/package-management/command-reference/2.add.md b/versioned_docs/version-0.5.3/reference/package-management/command-reference/2.add.md deleted file mode 100644 index 1d2517fb..00000000 --- a/versioned_docs/version-0.5.3/reference/package-management/command-reference/2.add.md +++ /dev/null @@ -1,53 +0,0 @@ -# kpm add - -Add a dependency to a kcl package. - -## Usage - -```shell -kpm add [options][package_reference] -``` - -## Description - -`kpm add` will add a dependency to a kcl package. The dependency can be from a git repository, or a kcl registry. - -`package_reference` is a kcl package reference, looks like `package_name:version`. - -## options - -### --git - -Specify the git url of the dependency from a git repository. - -### --tag - -Specify the tag of the dependency from a git repository. - -### --help, -h - -Show help for `kpm add` command. - -## Examples - -### Add a dependency from kcl registry - -Add kcl dependency named `k8s` to the current package.The version of the dependency will be the latest version. - -```shell -kpm add k8s -``` - -Add kcl dependency named 'k8s' with version 'v1.27.2'. - -```shell -kpm add k8s:v1.27.2 -``` - -### Add a dependency from git repository - -Add kcl dependency named `konfig` with version `v0.1.0` from git repository. - -```shell -kpm add --git https://github.com/awesome-kusion/konfig.git --tag v0.1.0 -``` diff --git a/versioned_docs/version-0.5.3/reference/package-management/command-reference/3.pkg.md b/versioned_docs/version-0.5.3/reference/package-management/command-reference/3.pkg.md deleted file mode 100644 index 9b4298a5..00000000 --- a/versioned_docs/version-0.5.3/reference/package-management/command-reference/3.pkg.md +++ /dev/null @@ -1,33 +0,0 @@ -# kpm pkg - -Package a kcl package into `*.tar`. - -## Usage - -```shell -kpm pkg [options] -``` - -## Description - -`kpm pkg` will package a kcl package into `*.tar`. - -Option `--target` is required to specify the tar file path of the package. - -## options - -### --target - -Specify the tar file path of the package. - -### --help, -h - -Show help for `kpm pkm` command. - -## Examples - -### Package a kcl package - -```shell -kpm pkg --target /Users/my_package_tar -``` diff --git a/versioned_docs/version-0.5.3/reference/package-management/command-reference/4.metadata.md b/versioned_docs/version-0.5.3/reference/package-management/command-reference/4.metadata.md deleted file mode 100644 index 3074a8d5..00000000 --- a/versioned_docs/version-0.5.3/reference/package-management/command-reference/4.metadata.md +++ /dev/null @@ -1,41 +0,0 @@ -# kpm metadata - -Print the metadata of a kcl package. - -## Usage - -```shell -kpm metadata [options] -``` - -## Description - -`kpm metadata` will print the metadata of a kcl package. The metadata includes the dependency information of the package. - -`--update` option is used to automatically download the missing dependency packages. - -## options - -### --update - -Automatically download the missing dependency packages. - -### --help, -h - -Show help for `kpm metadata` command. - -## Examples - -### Print the metadata of a kcl package - -Print the metadata of a kcl package. - -```shell -kpm metadata -``` - -Print the metadata of a kcl package and automatically download the missing dependency packages. - -```shell -kpm metadata --update -``` diff --git a/versioned_docs/version-0.5.3/reference/package-management/command-reference/5.run.md b/versioned_docs/version-0.5.3/reference/package-management/command-reference/5.run.md deleted file mode 100644 index b5001185..00000000 --- a/versioned_docs/version-0.5.3/reference/package-management/command-reference/5.run.md +++ /dev/null @@ -1,69 +0,0 @@ -# kpm run - -Compile a kcl package. - -## Usage - -```shell -kpm run [options][package_source] -``` - -## Description - -`kpm run` will compile a kcl package. - -## options - -### --input - -Specify the entry file path of the package. - -### --tag - -Specify the tag of the package specified by oci url `package_source`. - -### --vendor - -`--vendor` will move the dependency packages into the current packages and automatically download the missing dependency packages. - -### --kcl_args - -`--kcl_args` specifies the arguments passed to the kcl compiler. - -### --help, -h - -Show help for `kpm run` command. - -## Examples - -### compile the current kcl package - -Under the kcl package directory, `kpm run` can be used to compile the current kcl package. - -```shell -kpm run -``` - -### compile a kcl package tar file - -`kpm run` can be used to compile a kcl package tar file. - -```shell -kpm run /Users/demo/my_package.tar -``` - -### compile a kcl package from oci url - -`kpm run` can be used to compile a kcl package from oci url. - -```shell -kpm run --tag 0.0.1 oci://localhost:5001/test/my_package -``` - -### compile a kcl package from oci ref - -`kpm run` can be used to compile a kcl package from oci ref. - -```shell -kpm run test/my_package:0.0.1 -``` diff --git a/versioned_docs/version-0.5.3/reference/package-management/command-reference/6.login.md b/versioned_docs/version-0.5.3/reference/package-management/command-reference/6.login.md deleted file mode 100644 index 68ca0f1b..00000000 --- a/versioned_docs/version-0.5.3/reference/package-management/command-reference/6.login.md +++ /dev/null @@ -1,68 +0,0 @@ -# kpm login - -Login to the kpm registry. - -## Usage - -```shell -kpm login [options][kpm_registry] -``` - -## Description - -`kpm login` will login the kpm registry. - -## options - -### --username - -Specify the username of the kpm registry. - -### --password - -Specify the password of the kpm registry. - -### --help, -h - -Show help for `kpm login` command. - -## Examples - -### login to a registry with account and password - -```shell -kpm login -u -p -``` - -The output is - -```shell -Login succeeded -``` - -### login to a registry with account, and enter the password interactively - -```shell -kpm login -u -``` - -The output is - -```shell -Password: -Login succeeded -``` - -### login to a registry, and enter the account and password interactively - -```shell -kpm login -``` - -The output is - -```shell -Username: -Password: -Login succeeded -``` diff --git a/versioned_docs/version-0.5.3/reference/package-management/command-reference/7.logout.md b/versioned_docs/version-0.5.3/reference/package-management/command-reference/7.logout.md deleted file mode 100644 index 6c5d9aec..00000000 --- a/versioned_docs/version-0.5.3/reference/package-management/command-reference/7.logout.md +++ /dev/null @@ -1,27 +0,0 @@ -# kpm logout - -Logout from the kpm registry. - -## Usage - -```shell -kpm logout [options][kpm_registry] -``` - -## Description - -`kpm logout` will logout from the kpm registry. - -## options - -### --help, -h - -Show help for `kpm logout` command. - -## Examples - -### logout from oci registry - -```shell -kpm logout -``` diff --git a/versioned_docs/version-0.5.3/reference/package-management/command-reference/8.push.md b/versioned_docs/version-0.5.3/reference/package-management/command-reference/8.push.md deleted file mode 100644 index a70c5bc1..00000000 --- a/versioned_docs/version-0.5.3/reference/package-management/command-reference/8.push.md +++ /dev/null @@ -1,46 +0,0 @@ -# kpm push - -Push a package to the kpm registry. - -## Usage - -```shell -kpm push [options][kpm_registry] -``` - -## Description - -`kpm push` will push a package to the kpm registry. - -## options - -### --tar_path - -The path to the tar file to push. - -### --help, -h - -Show help for `kpm push` command. - -## Examples - -### push the current package - -You can use `kpm push` under the kcl package root directory to upload a kcl package to an OCI-based registry. - -```shell -# create a new kcl package. -$ kpm init -# enter the kcl package root directory -$ cd -# push it to an oci registry -$ kpm push -``` - -### push a tar to the registry - -You can also use `kpm push` to upload a tar file to an OCI-based registry. - -```shell -kpm push --tar_path -``` diff --git a/versioned_docs/version-0.5.3/reference/package-management/command-reference/9.pull.md b/versioned_docs/version-0.5.3/reference/package-management/command-reference/9.pull.md deleted file mode 100644 index b0126bcf..00000000 --- a/versioned_docs/version-0.5.3/reference/package-management/command-reference/9.pull.md +++ /dev/null @@ -1,42 +0,0 @@ -# kpm pull - -Pull a package from the kpm registry. - -## Usage - -```shell -kpm pull [options][package_source] -``` - -## Description - -`kpm pull` will pull a package from the kpm registry. - -## options - -### --tag - -The tag of the package to pull. - -### --help, -h - -Show help for `kpm push` command. - -## Examples - -### pull the package by package name - -You can use `kpm pull` to download a kcl package from the default OCI registry by kcl package name. -`kpm` will download the kcl package from the default OCI registry specified in the configuration file `kpm.json`. - -```shell -kpm pull : -``` - -### pull the package by oci url - -You can download a kcl package from an OCI-based registry url. - -```shell -kpm pull --tag -``` diff --git a/versioned_docs/version-0.5.3/reference/package-management/command-reference/index.md b/versioned_docs/version-0.5.3/reference/package-management/command-reference/index.md deleted file mode 100644 index ab6cc90c..00000000 --- a/versioned_docs/version-0.5.3/reference/package-management/command-reference/index.md +++ /dev/null @@ -1,36 +0,0 @@ -# kpm - -The kpm cli - -## Usage - -```shell -kpm [arguments]... -``` - -## Description - -`kpm` is a kcl package manager. It is used to install, remove, and update kcl packages. - -## Options - -### --help, -h - -Show help for kpm command - -### --version, -v - -Print the version of kpm - -## Subcommands - -- [kpm init](./1.init.md) - Init a kcl package -- [kpm add](./2.add.md) - Add a dependency to a kcl package -- [kpm pkg](./3.pkg.md) - Package a kcl package into `\*.tar`` -- [kpm metadata](./4.metadata.md) - Print the metadata of a kcl package -- [kpm run](./5.run.md) - Compile a kcl package into yaml -- [kpm login](./6.login.md) - Login to a kcl registry -- [kpm logout](./7.logout.md) - Logout from a kcl registry -- [kpm push](./8.push.md) - Push a kcl package to a registry -- [kpm pull](./9.pull.md) - Pull a kcl package from a registry -- [kpm help](./10.help.md) - print help for kpm command diff --git a/versioned_docs/version-0.5.3/reference/plugin/index.md b/versioned_docs/version-0.5.3/reference/plugin/index.md deleted file mode 100644 index df299e93..00000000 --- a/versioned_docs/version-0.5.3/reference/plugin/index.md +++ /dev/null @@ -1 +0,0 @@ -# Plugin System diff --git a/versioned_docs/version-0.5.3/reference/plugin/overview.md b/versioned_docs/version-0.5.3/reference/plugin/overview.md deleted file mode 100644 index f9561ddc..00000000 --- a/versioned_docs/version-0.5.3/reference/plugin/overview.md +++ /dev/null @@ -1,187 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Introduction - -KCL provides plugin support through a plugin agent and auxiliary command line tools, and the KCL plugin framework supports different general-purpose languages to develop plugins. Here we take Python as an example to briefly explain the use of plugins. - -KCL plugin Git repository: [https://github.com/kcl-lang/kcl-plugin](https://github.com/kcl-lang/kcl-plugin) - -## 0. Prerequisites - -Using the KCL Python plugin requires the presence of `Python 3.7+` in your `PATH`. - -## 1. Hello Plugin - -KCL plugins are installed in the `plugins` subdirectory of KCL (usually installed in the `$HOME/.kcl/plugins` directory), or set through the `$KCL_PLUGINS_ROOT` environment variable. Besides, the `plugins` directory could also be placed at the `pwd` path. KCL plugins are managed in the Git repository: [https://github.com/kcl-lang/kcl-plugin](https://github.com/kcl-lang/kcl-plugin), we can clone the repository for development. - -Enter the `kcl-plugin info` command to view the plugin directory (replace `/Users/kcl_user` with the local `$HOME` path): - -```shell -$ kcl-plugin info -# plugin_root: /Users/kcl_user/.kcl/plugins -``` - -View the list of plugins with the `kcl-plugin list` subcommand: - -```shell -$ kcl-plugin list -hello: hello doc - 0.0.1 -``` - -Where `hello` is an example builtin plugin (do not modify the plugin). - -In KCL code, the `hello` plugin can be imported via `import kcl_plugin.hello`. `main.k` code is as follows: - -```python -import kcl_plugin.hello - -name = "kcl" -three = hello.add(1,2) -``` - -The output result is - -```shell -$ python3 -m kclvm main.k -name: kcl -three: 3 -``` - -## 2. `kcl-plugin` Command - -`kcl-plugin` is a plugin helper command line tool, the command line help is as follows: - -```shell -$ kcl-plugin -usage: kcl-plugin [-h] {list,info,init,gendoc,test} ... -positional arguments: - {list,info,init,gendoc,test} - kcl plugin sub commands - list list all plugins - info show plugin document - init init a new plugin - gendoc gen all plugins document - test test plugin -optional arguments: - -h, --help show this help message and exit -``` - -- The `list` subcommand is used to view the list of plugins. -- The `info` subcommand is used to view the plugin directory and information about each plugin. -- The `init` subcommand is used to initialize new plugins. -- The `gendoc` subcommand is used to update the API documentation of all plugins. -- The `test` subcommand is used to test specified plugins. - -## 3. Plugin Information and Documentation - -Enter `kcl-plugin info hello` to view the `hello` plugin information: - -```shell -$ kcl-plugin info hello -{ - "name": "hello", - "describe": "hello doc", - "long_describe": "long describe", - "version": "0.0.1", - "method": { - "add": "add two numbers, and return result", - "foo": "no doc", - "list_append": "no doc", - "say_hello": "no doc", - "tolower": "no doc", - "update_dict": "no doc" - } -} -``` - -The information of the plugin mainly includes the name and version information of the plugin, and the function information provided by the plugin. This information is consistent with the automatically generated `api.md` file in the plugin directory (regenerate the `api.md` file for all plugins via `kcl-plugin gendoc` when the plugin API document changes). - -## 4. Plugin Directory Structure - -The directory structure of the plugin is as follows (replace `/Users/kcl_user` with the local `$HOME` path): - -```shell -$ tree /Users/kcl_user/.kcl/plugins/ -/Users/kcl_user/.kcl/plugins/ -├── _examples -├── _test -└── hello - ├── api.md - ├── plugin.py - └── plugin_test.py -$ -``` - -The `_examples` directory is the sample code of the plugin, the `_test` directory is the KCL test code of the plugin, and the other directories starting with letters are ordinary plugins. The content of the plugin is as follows: - -```shell -$ cat ./hello/plugin.py -# Copyright 2020 The KCL Authors. All rights reserved. -INFO = { - 'name': 'hello', - 'describe': 'hello doc', - 'long_describe': 'long describe', - 'version': '0.0.1', -} -def add(a: int, b: int) -> int: - """add two numbers, and return result""" - return a + b -... -``` - -Where `INFO` specifies the name of the plugin, a brief description, a detailed description and version information. And all the functions whose names start with letters are the functions provided by the plugin, so the `add` function can be called directly in KCL. - -> Note: KCL plugins are implemented in an independent pure Python code file, and plugins cannot directly call each other. - -## 5. Create Plugin - -A plugin can be created with the `kcl-plugin init` command: - -``` -$ kcl-plugin init hi -$ kcl-plugin list -hello: hello doc - 0.0.1 -hi: hi doc - 0.0.1 -``` - -The `kcl-plugin init` command will construct a new plugin from the built-in template, and then we can view the created plugin information with the `kcl-plugin list` command. - -## 6. Remove Plugin - -KCL plugins are located in the `plugins` subdirectory of KCL (usually installed in the `$HOME/.kcl/plugins` directory). -We can query the plugin installation directory with the command `kcl-plugin info`. - -```shell -$ kcl-plugin info -/Users/kcl_user/.kcl/plugins/ -$ tree /Users/kcl_user/.kcl/plugins/ -/Users/kcl_user/.kcl/plugins/ -├── _examples -├── _test -└── hello -- Delete this directory to delete the hello plugin - ├── api.md - ├── plugin.py - └── plugin_test.py -$ -``` - -## 7. Test Plugin - -There is a `plugin_test.py` file in the plugin directory, which is the unit test file of the plugin (based on the `pytest` testing framework). Also placed in the `_test` directory are plugin integration tests for KCL files. The `plugin_test.py` unit test is required, and the KCL integration tests in the `_test` directory can be added as needed. - -Unit tests for plugins can be executed via `kcl-plugin test`: - -```shell -$ kcl-plugin test hello -============================= test session starts ============================== -platform darwin -- Python 3.7.6+, pytest-5.3.5, py-1.9.0, pluggy-0.13.1 -rootdir: /Users/kcl_user -collected 5 items -.kcl/plugins/hello/plugin_test.py ..... [100%] -============================== 5 passed in 0.03s =============================== -$ -``` - -Integration tests can be tested by executing the `python3 -m pytest` command in the `_test` directory. diff --git a/versioned_docs/version-0.5.3/reference/plugin/project_context.md b/versioned_docs/version-0.5.3/reference/plugin/project_context.md deleted file mode 100644 index 0be02e78..00000000 --- a/versioned_docs/version-0.5.3/reference/plugin/project_context.md +++ /dev/null @@ -1,59 +0,0 @@ -# project_context - -project_context extract base info from project.yaml&stack.yaml - -_version: 0.0.1_ - -## `get_project_current_path` - -return the relative path of first file - -Example: - -```py -import kcl_plugin.project_context as ctx - -path = ctx.get_project_current_path() -print(path) -``` - -## `get_project_input_file` - -return compiling file list - -Example: - -```py -import kcl_plugin.project_context as ctx - -input_file = ctx.get_project_input_file() -print(input_file) -``` - -## `get_project_context` - -return the current project context from project.yaml - -Example: - -```py -import kcl_plugin.project_context as ctx - -project = ctx.get_project_context() -# Get project name -print(project?.name) -``` - -## `get_stack_context` - -return the current stack context from stack.yaml - -Example: - -```py -import kcl_plugin.project_context as ctx - -stack = ctx.get_stack_context() -# Get stack name -print(stack?.name) -``` diff --git a/versioned_docs/version-0.5.3/reference/xlang-api/go-api.md b/versioned_docs/version-0.5.3/reference/xlang-api/go-api.md deleted file mode 100644 index 2a978250..00000000 --- a/versioned_docs/version-0.5.3/reference/xlang-api/go-api.md +++ /dev/null @@ -1,665 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Go API - -```go -import kcl "kcl-lang.io/kcl-go" -``` - -## KCL Go SDK - -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ kcl files │ │ KCL-Go-API │ │ KCLResultList │ -│ ┌───────────┐ │ │ │ │ │ -│ │ 1.k │ │ │ │ │ │ -│ └───────────┘ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ ┌───────────┐ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.Get("a.b.c") │ -│ │ 2.k │ │ │ │ Run(path) │ │ │ └───────────┘ │ └───────────────┘ -│ └───────────┘ │────┐ │ └───────────┘ │ │ │ -│ ┌───────────┐ │ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ │ 3.k │ │ │ │ │ │ │ KCLResult │──┼────────▶│x.Get("k", &v) │ -│ └───────────┘ │ │ │ │ │ └───────────┘ │ └───────────────┘ -│ ┌───────────┐ │ ├───▶│ ┌───────────┐ │──────────▶│ │ -│ │setting.yml│ │ │ │ │RunFiles() │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ └───────────┘ │ │ │ └───────────┘ │ │ │ KCLResult │──┼────────▶│x.JSONString() │ -└─────────────────┘ │ │ │ │ └───────────┘ │ └───────────────┘ - │ │ │ │ │ -┌─────────────────┐ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ Options │ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.YAMLString() │ -│WithOptions │ │ │ │MustRun() │ │ │ └───────────┘ │ └───────────────┘ -│WithOverrides │────┘ │ └───────────┘ │ │ │ -│WithWorkDir │ │ │ │ │ -│WithDisableNone │ │ │ │ │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ -``` - -
Example -

- -```go -{ - const k_code = ` -name = "kcl" -age = 1 - -two = 2 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {} -x1 = Person { - age = 101 -} -` - - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First().YAMLString() - fmt.Println(yaml) - - fmt.Println("----") - - result := kcl.MustRun("./testdata/main.k").First() - fmt.Println(result.JSONString()) - - fmt.Println("----") - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - - fmt.Println("----") - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x1", &person)) -} -``` - -

-
- -## Index - -- [Go API](#go-api) - - [KCL Go SDK](#kcl-go-sdk) - - [Index](#index) - - [Constants](#constants) - - [func FormatCode](#func-formatcode) - - [func FormatPath](#func-formatpath) - - [func InitKclvmPath](#func-initkclvmpath) - - [func InitKclvmRuntime](#func-initkclvmruntime) - - [func LintPath](#func-lintpath) - - [func ListDepFiles](#func-listdepfiles) - - [func ListDownStreamFiles](#func-listdownstreamfiles) - - [func ListUpStreamFiles](#func-listupstreamfiles) - - [func OverrideFile](#func-overridefile) - - [func ValidateCode](#func-validatecode) - - [type KCLResult](#type-kclresult) - - [type KCLResultList](#type-kclresultlist) - - [func MustRun](#func-mustrun) - - [func Run](#func-run) - - [func RunFiles](#func-runfiles) - - [type KclType](#type-kcltype) - - [func GetSchemaType](#func-getschematype) - - [type ListDepFilesOption](#type-listdepfilesoption) - - [type ListDepsOptions](#type-listdepsoptions) - - [type Option](#type-option) - - [func WithCode](#func-withcode) - - [func WithDisableNone](#func-withdisablenone) - - [func WithKFilenames](#func-withkfilenames) - - [func WithOptions](#func-withoptions) - - [func WithOverrides](#func-withoverrides) - - [func WithPrintOverridesAST](#func-withprintoverridesast) - - [func WithSettings](#func-withsettings) - - [func WithSortKeys](#func-withsortkeys) - - [func WithWorkDir](#func-withworkdir) - - [type ValidateOptions](#type-validateoptions) - -## Constants - -KclvmAbiVersion is the current kclvm ABI version. - -```go -const KclvmAbiVersion = scripts.KclvmAbiVersion -``` - -## func [FormatCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L110) - -```go -func FormatCode(code interface{}) ([]byte, error) -``` - -FormatCode returns the formatted code. - -
Example -

- -```go -{ - out, err := kcl.FormatCode(`a = 1+2`) - if err != nil { - log.Fatal(err) - } - fmt.Println(string(out)) - -} -``` - -``` -a = 1 + 2 -``` - -

-
- -## func [FormatPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L122) - -```go -func FormatPath(path string) (changedPaths []string, err error) -``` - -FormatPath formats files from the given path path: if path is \`.\` or empty string, all KCL files in current directory will be formatted, not recursively if path is \`path/file.k\`, the specified KCL file will be formatted if path is \`path/to/dir\`, all KCL files in the specified dir will be formatted, not recursively if path is \`path/to/dir/...\`, all KCL files in the specified dir will be formatted recursively - -the returned changedPaths are the changed file paths \(relative path\) - -
Example -

- -```go -{ - changedPaths, err := kcl.FormatPath("testdata/fmt") - if err != nil { - log.Fatal(err) - } - fmt.Println(changedPaths) -} -``` - -

-
- -## func [InitKclvmPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L54) - -```go -func InitKclvmPath(kclvmRoot string) -``` - -InitKclvmPath init kclvm path. - -## func [InitKclvmRuntime](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L59) - -```go -func InitKclvmRuntime(n int) -``` - -InitKclvmRuntime init kclvm process. - -## func [LintPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L142) - -```go -func LintPath(paths []string) (results []string, err error) -``` - -LintPath lint files from the given path - -
Example -

- -```go -{ - - results, err := kcl.LintPath([]string{"testdata/lint/import.k"}) - if err != nil { - log.Fatal(err) - } - for _, s := range results { - fmt.Println(s) - } - -} -``` - -``` -Module 'a' is reimported multiple times -Module 'a' imported but unused -``` - -

-
- -## func [ListDepFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L127) - -```go -func ListDepFiles(workDir string, opt *ListDepFilesOption) (files []string, err error) -``` - -ListDepFiles return the depend files from the given path - -## func [ListDownStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L137) - -```go -func ListDownStreamFiles(workDir string, opt *ListDepsOptions) ([]string, error) -``` - -ListDownStreamFiles return a list of downstream depend files from the given changed path list. - -## func [ListUpStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L132) - -```go -func ListUpStreamFiles(workDir string, opt *ListDepsOptions) (deps []string, err error) -``` - -ListUpStreamFiles return a list of upstream depend files from the given path list - -## func [OverrideFile](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L154) - -```go -func OverrideFile(file string, specs, importPaths []string) (bool, error) -``` - -OverrideFile rewrites a file with override spec file: string. The File that need to be overridden specs: \[\]string. List of specs that need to be overridden. - -``` -Each spec string satisfies the form: := or :- -When the pkgpath is '__main__', it can be omitted. -``` - -importPaths. List of import statements that need to be added - -## func [ValidateCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L159) - -```go -func ValidateCode(data, code string, opt *ValidateOptions) (ok bool, err error) -``` - -ValidateCode validate data match code - -## type [KCLResult](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L47) - -```go -type KCLResult = kcl.KCLResult -``` - -
Example -

- -```go -{ - const k_code = ` -name = "kcl" -age = 1 - -two = 2 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {name = "kcl-go"} -x1 = Person {age = 101} -` - - result := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First() - - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - -} -``` - -``` -x0.name: kcl-go -x1.age: 101 -``` - -

-
- -
Example ('et_struct) -

- -```go -{ - const k_code = ` -schema Person: - name: str = "kcl" - age: int = 1 - X: int = 2 - -x = { - "a": Person {age = 101} - "b": 123 -} -` - - result := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First() - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x.a", &person)) - fmt.Printf("person: %+v\n", person) - -} -``` - -``` -person: &{Name:kcl Age:101} -person: {Name:kcl Age:101} -``` - -

-
- -## type [KCLResultList](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L48) - -```go -type KCLResultList = kcl.KCLResultList -``` - -### func [MustRun](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L64) - -```go -func MustRun(path string, opts ...Option) *KCLResultList -``` - -MustRun is like Run but panics if return any error. - -
Example -

- -```go -{ - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(`name = "kcl"`)).First().YAMLString() - fmt.Println(yaml) - -} -``` - -``` -name: kcl -``` - -

-
- -
Example (Raw Yaml) -

- -```go -{ - const code = ` -b = 1 -a = 2 -` - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(code)).GetRawYamlResult() - fmt.Println(yaml) - - yaml_sorted := kcl.MustRun("testdata/main.k", kcl.WithCode(code), kcl.WithSortKeys(true)).GetRawYamlResult() - fmt.Println(yaml_sorted) - -} -``` - -``` -b: 1 -a: 2 -a: 2 -b: 1 -``` - -

-
- -
Example (Schema Type) -

- -```go -{ - const code = ` -schema Person: - name: str = "" - -x = Person() -` - json := kcl.MustRun("testdata/main.k", kcl.WithCode(code)).First().JSONString() - fmt.Println(json) - -} -``` - -``` -{ - "x": { - "name": "" - } -} -``` - -

-
- -
Example (Settings) -

- -```go -{ - yaml := kcl.MustRun("./testdata/app0/kcl.yaml").First().YAMLString() - fmt.Println(yaml) -} -``` - -

-
- -### func [Run](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L69) - -```go -func Run(path string, opts ...Option) (*KCLResultList, error) -``` - -Run evaluates the KCL program with path and opts, then returns the object list. - -
Example (Get Field) -

- -```go -{ - - x, err := kcl.Run("./testdata/app0/kcl.yaml") - assert(err == nil, err) - - fmt.Println(x.First().Get("deploy_topology.1.zone")) - -} -``` - -``` -R000A -``` - -

-
- -### func [RunFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L74) - -```go -func RunFiles(paths []string, opts ...Option) (*KCLResultList, error) -``` - -RunFiles evaluates the KCL program with multi file path and opts, then returns the object list. - -
Example -

- -```go -{ - result, _ := kcl.RunFiles([]string{"./testdata/app0/kcl.yaml"}) - fmt.Println(result.First().YAMLString()) -} -``` - -

-
- -## type [KclType](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L50) - -```go -type KclType = kcl.KclType -``` - -### func [GetSchemaType](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L176) - -```go -func GetSchemaType(file, code, schemaName string) ([]*KclType, error) -``` - -GetSchemaType returns schema types from a kcl file or code. - -file: string - -``` -The kcl filename -``` - -code: string - -``` -The kcl code string -``` - -schema_name: string - -``` -The schema name got, when the schema name is empty, all schemas are returned. -``` - -## type [ListDepFilesOption](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L45) - -```go -type ListDepFilesOption = list.Option -``` - -## type [ListDepsOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L44) - -```go -type ListDepsOptions = list.DepOptions -``` - -## type [Option](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L43) - -```go -type Option = kcl.Option -``` - -### func [WithCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L79) - -```go -func WithCode(codes ...string) Option -``` - -WithCode returns a Option which hold a kcl source code list. - -### func [WithDisableNone](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L97) - -```go -func WithDisableNone(disableNone bool) Option -``` - -WithDisableNone returns a Option which hold a disable none switch. - -### func [WithKFilenames](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L82) - -```go -func WithKFilenames(filenames ...string) Option -``` - -WithKFilenames returns a Option which hold a filenames list. - -### func [WithOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L85) - -```go -func WithOptions(key_value_list ...string) Option -``` - -WithOptions returns a Option which hold a key=value pair list for option function. - -
Example -

- -```go -{ - const code = ` -name = option("name") -age = option("age") -` - x, err := kcl.Run("hello.k", kcl.WithCode(code), - kcl.WithOptions("name=kcl", "age=1"), - ) - if err != nil { - log.Fatal(err) - } - - fmt.Println(x.First().YAMLString()) - -} -``` - -``` -age: 1 -name: kcl -``` - -

-
- -### func [WithOverrides](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L88) - -```go -func WithOverrides(override_list ...string) Option -``` - -WithOverrides returns a Option which hold a override list. - -### func [WithPrintOverridesAST](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L100) - -```go -func WithPrintOverridesAST(printOverridesAST bool) Option -``` - -WithPrintOverridesAST returns a Option which hold a printOverridesAST switch. - -### func [WithSettings](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L91) - -```go -func WithSettings(filename string) Option -``` - -WithSettings returns a Option which hold a settings file. - -### func [WithSortKeys](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L105) - -```go -func WithSortKeys(sortKeys bool) Option -``` - -WithSortKeys returns a Option which hold a sortKeys switch. - -### func [WithWorkDir](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L94) - -```go -func WithWorkDir(workDir string) Option -``` - -WithWorkDir returns a Option which hold a work dir. - -## type [ValidateOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L46) - -```go -type ValidateOptions = validate.ValidateOptions -``` diff --git a/versioned_docs/version-0.5.3/reference/xlang-api/index.md b/versioned_docs/version-0.5.3/reference/xlang-api/index.md deleted file mode 100644 index f6f8e076..00000000 --- a/versioned_docs/version-0.5.3/reference/xlang-api/index.md +++ /dev/null @@ -1 +0,0 @@ -# Multi-Language diff --git a/versioned_docs/version-0.5.3/reference/xlang-api/overview.md b/versioned_docs/version-0.5.3/reference/xlang-api/overview.md deleted file mode 100644 index e63422d4..00000000 --- a/versioned_docs/version-0.5.3/reference/xlang-api/overview.md +++ /dev/null @@ -1,293 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Introduction - -The KCL language provides general programming language interfaces such as C/Rust/Go/Python/Java, and the related languages are under development. - -## C/Rust API - -The core of KCL is developed in Rust, and the C language API is exported externally for packaging and integration in high-level languages such as Go/Python/Java. - -## Go API - -Go API is a C-API provided by CGO wrapping KCL, while providing deeper customization features to meet the needs of upper-level tools. - -### Abstract Model - -The abstract model of the KCL Go API is as follows: - -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ kcl files │ │ KCL-Go-API │ │ KCLResultList │ -│ ┌───────────┐ │ │ │ │ │ -│ │ 1.k │ │ │ │ │ │ -│ └───────────┘ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ ┌───────────┐ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.Get("a.b.c") │ -│ │ 2.k │ │ │ │ Run(path) │ │ │ └───────────┘ │ └───────────────┘ -│ └───────────┘ │────┐ │ └───────────┘ │ │ │ -│ ┌───────────┐ │ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ │ 3.k │ │ │ │ │ │ │ KCLResult │──┼────────▶│x.Get("k", &v) │ -│ └───────────┘ │ │ │ │ │ └───────────┘ │ └───────────────┘ -│ ┌───────────┐ │ ├───▶│ ┌───────────┐ │──────────▶│ │ -│ │setting.yml│ │ │ │ │RunFiles() │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ └───────────┘ │ │ │ └───────────┘ │ │ │ KCLResult │──┼────────▶│x.JSONString() │ -└─────────────────┘ │ │ │ │ └───────────┘ │ └───────────────┘ - │ │ │ │ │ -┌─────────────────┐ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ Options │ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.YAMLString() │ -│WithOptions │ │ │ │MustRun() │ │ │ └───────────┘ │ └───────────────┘ -│WithOverrides │────┘ │ └───────────┘ │ │ │ -│WithWorkDir │ │ │ │ │ -│WithDisableNone │ │ │ │ │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ -``` - -The input file contains the KCL file and the `setting.yml` configuration file, and `Options` can be used to specify additional parameters and information such as working directory. The "KCL-Go-API" part is the provided KCL execution function. The execution function executes the KCL program according to the input file and additional parameters, and finally outputs the result of `KCLResultList`. `KCLResultList` is a list of `KCLResult`, each `KCLResult` corresponding to a generated configuration file or `map[string]interface{}`. - -### Example - -```go -package main - -import ( - "fmt" - - kcl "kcl-lang.io/kcl-go" -) - - -func main() { - const k_code = ` -name = "kcl" -age = 1 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person{} -x1 = Person{age:101} -` - - result := kcl.MustRun("hello.k", kcl.WithCode(k_code)).First() - fmt.Println(result.YAMLString()) - - fmt.Println("----") - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - - fmt.Println("----") - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x1", &person)) -} -``` - -Output result: - -```yaml -age: 1 -name: kcl -x0: - age: 1 - name: kcl -x1: - age: 101 - name: kcl - ----- -x0.name: kcl -x1.age: 101 ----- -person: &{Name:kcl Age:101} -``` - -## Python API - -Using the Python SDK requires that you have a local Python version higher than 3.7.3 and a local pip package management tool. You can use the following command to install and obtain helpful information. - -```bash -python3 -m pip install kclvm --user && python3 -m kclvm --help -``` - -### Command Line Tool - -Prepare a KCL file named `main.k` - -```python -name = "kcl" -age = 1 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {} -x1 = Person { - age = 101 -} -``` - -Execute the following command and get the output: - -```shell -$ python3 -m kclvm hello.k -name: kcl -age: 1 -x0: - name: kcl - age: 1 -x1: - name: kcl - age: 101 -``` - -### API - -In addition, we can also execute KCL files through Python code. - -Prepare a KCL file named `main.py` - -```python -import kclvm.program.exec as kclvm_exec -import kclvm.vm.planner as planner - -print(planner.plan(kclvm_exec.Run(["hello.k"]).filter_by_path_selector())) -``` - -Execute the following command and get the output: - -```shell -$ python3 main.py -name: kcl -age: 1 -x0: - name: kcl - age: 1 -x1: - name: kcl - age: 101 -``` - -You can see that the same output can be obtained through command line tools and APIs. - -At present, the KCL Python SDK is still in the early preview version. The KCL team will continue to update and provide more functions in the future. For more information, see [https://github.com/kcl-lang/kcl-py](https://github.com/kcl-lang/kcl-py) - -## REST-API - -The C-API provided by KCL does not have a REST-API. The REST-API is defined by Protobuf. - -### Start REST Service - -The RestAPI service can be started in the following way: - -```shell -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -The service can then be requested via the POST protocol: - -```shell -$ curl -X POST http://127.0.0.1:2021/api:protorpc/BuiltinService.Ping --data '{}' -{ - "error": "", - "result": {} -} -``` - -The POST request and the returned JSON data are consistent with the structure defined by Protobuf. - -### `BuiltinService` - -Where the `/api:protorpc/BuiltinService.Ping` path represents the `Ping` method of the `BuiltinService` service. - -The complete `BuiltinService` is defined by Protobuf: - -```protobuf -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} -``` - -The `Ping` method can verify whether the service is normal, and the `ListMethod` method can query the list of all services and functions provided. - -### `KclvmService` - -The `KclvmService` service is a service related to KCL functionality. The usage is the same as the `BuiltinService` service. - -For example, there is the following `Person` structure definition: - -```python -schema Person: - key: str - - check: - "value" in key # 'key' is required and 'key' must contain "value" -``` - -Then we want to use `Person` to verify the following JSON data: - -```json -{ "key": "value" } -``` - -This can be done through the `ValidateCode` method of the `KclvmService` service. Refer to the `ValidateCode_Args` structure of the `ValidateCode` method: - -```protobuf -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} -``` - -Construct the JSON data required by the POST request according to the `ValidateCode_Args` structure, which contains the `Person` definition and the JSON data to be verified: - -```json -{ - "code": "\nschema Person:\n key: str\n\n check:\n \"value\" in key # 'key' is required and 'key' must contain \"value\"\n", - "data": "{\"key\": \"value\"}" -} -``` - -Save this JSON data to the `vet-hello.json` file and verify it with the following command: - -```shell -$ curl -X POST \ - http://127.0.0.1:2021/api:protorpc/KclvmService.ValidateCode \ - -H "accept: application/json" \ - --data @./vet-hello.json -{ - "error": "", - "result": { - "success": true - } -} -``` - -## APIs in other languages - -Coming soon diff --git a/versioned_docs/version-0.5.3/reference/xlang-api/rest-api.md b/versioned_docs/version-0.5.3/reference/xlang-api/rest-api.md deleted file mode 100644 index 4723280f..00000000 --- a/versioned_docs/version-0.5.3/reference/xlang-api/rest-api.md +++ /dev/null @@ -1,443 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Rest API - -## 1. Start REST Service - -The RestAPI service can be started in the following ways: - -```shell -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -or - -```shell -go install kcl-lang.io/kcl-go/cmds/kcl-go@main -kcl-go rest-server -``` - -The service can then be requested via the POST protocol: - -```shell -$ curl -X POST http://127.0.0.1:2021/api:protorpc/BuiltinService.Ping --data '{}' -{ - "error": "", - "result": {} -} -``` - -The POST request and the returned JSON data are consistent with the structure defined by Protobuf. - -## 2. `BuiltinService` - -Where the `/api:protorpc/BuiltinService.Ping` path represents the `Ping` method of the `BuiltinService` service. - -The complete `BuiltinService` is defined by Protobuf: - -```protobuf -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} -``` - -The `Ping` method can verify whether the service is normal, and the `ListMethod` method can query the list of all services and functions provided. - -## 3. `KclvmService` - -The `KclvmService` service is a service related to KCL functionality. The usage is the same as the `BuiltinService` service. - -For example, there is the following `Person` structure definition: - -```python -schema Person: - key: str - - check: - "value" in key # 'key' is required and 'key' must contain "value" -``` - -Then we want to use `Person` to verify the following JSON data: - -```json -{ "key": "value" } -``` - -This can be done through the `ValidateCode` method of the `KclvmService` service. Refer to the `ValidateCode_Args` structure of the `ValidateCode` method: - -```protobuf -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} -``` - -Construct the JSON data required by the POST request according to the `ValidateCode_Args` structure, which contains the `Person` definition and the JSON data to be verified: - -```json -{ - "code": "\nschema Person:\n key: str\n\n check:\n \"value\" in key # 'key' is required and 'key' must contain \"value\"\n", - "data": "{\"key\": \"value\"}" -} -``` - -Save this JSON data to the `vet-hello.json` file and verify it with the following command: - -```shell -$ curl -X POST \ - http://127.0.0.1:2021/api:protorpc/KclvmService.ValidateCode \ - -H "accept: application/json" \ - --data @./vet-hello.json -{ - "error": "", - "result": { - "success": true - } -} -``` - -## 4. Complete Protobuf Service Definition - -Cross-language APIs defined via Protobuf([https://github.com/kcl-lang/kcl-go/blob/main/pkg/spec/gpyrpc/gpyrpc.proto](https://github.com/kcl-lang/kcl-go/blob/main/pkg/spec/gpyrpc/gpyrpc.proto)): - -```protobuf -// Copyright 2023 The KCL Authors. All rights reserved. -// -// This file defines the request parameters and return structure of the KCL RPC server. -// We can use the following command to start a KCL RPC server. - -syntax = "proto3"; - -package gpyrpc; - -import "google/protobuf/any.proto"; -import "google/protobuf/descriptor.proto"; - -// ---------------------------------------------------------------------------- - -// kcl main.k -D name=value -message CmdArgSpec { - string name = 1; - string value = 2; -} - -// kcl main.k -O pkgpath:path.to.field=field_value -message CmdOverrideSpec { - string pkgpath = 1; - string field_path = 2; - string field_value = 3; - string action = 4; -} - -// ---------------------------------------------------------------------------- -// gpyrpc request/response/error types -// ---------------------------------------------------------------------------- - -message RestResponse { - google.protobuf.Any result = 1; - string error = 2; - KclError kcl_err = 3; -} - -message KclError { - string ewcode = 1; // See kclvm/kcl/error/kcl_err_msg.py - string name = 2; - string msg = 3; - repeated KclErrorInfo error_infos = 4; -} - -message KclErrorInfo { - string err_level = 1; - string arg_msg = 2; - string filename = 3; - string src_code = 4; - string line_no = 5; - string col_no = 6; -} - -// ---------------------------------------------------------------------------- -// service requset/response -// ---------------------------------------------------------------------------- - -// gpyrpc.BuiltinService -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -// gpyrpc.KclvmService -service KclvmService { - rpc Ping(Ping_Args) returns(Ping_Result); - - rpc ExecProgram(ExecProgram_Args) returns(ExecProgram_Result); - - rpc FormatCode(FormatCode_Args) returns(FormatCode_Result); - rpc FormatPath(FormatPath_Args) returns(FormatPath_Result); - rpc LintPath(LintPath_Args) returns(LintPath_Result); - rpc OverrideFile(OverrideFile_Args) returns (OverrideFile_Result); - - rpc GetSchemaType(GetSchemaType_Args) returns(GetSchemaType_Result); - rpc GetSchemaTypeMapping(GetSchemaTypeMapping_Args) returns(GetSchemaTypeMapping_Result); - rpc ValidateCode(ValidateCode_Args) returns(ValidateCode_Result); - - rpc ListDepFiles(ListDepFiles_Args) returns(ListDepFiles_Result); - rpc LoadSettingsFiles(LoadSettingsFiles_Args) returns(LoadSettingsFiles_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} - -message ParseFile_AST_Args { - string filename = 1; - string source_code = 2; -} -message ParseFile_AST_Result { - string ast_json = 1; // json value - KclError kcl_err = 2; -} - -message ParseProgram_AST_Args { - repeated string k_filename_list = 1; -} -message ParseProgram_AST_Result { - string ast_json = 1; // json value - KclError kcl_err = 2; -} - -message ExecProgram_Args { - string work_dir = 1; - - repeated string k_filename_list = 2; - repeated string k_code_list = 3; - - repeated CmdArgSpec args = 4; - repeated CmdOverrideSpec overrides = 5; - - bool disable_yaml_result = 6; - - bool print_override_ast = 7; - - // -r --strict-range-check - bool strict_range_check = 8; - - // -n --disable-none - bool disable_none = 9; - // -v --verbose - int32 verbose = 10; - - // -d --debug - int32 debug = 11; - - // yaml/json: sort keys - bool sort_keys = 12; - // include schema type path in JSON/YAML result - bool include_schema_type_path = 13; -} -message ExecProgram_Result { - string json_result = 1; - string yaml_result = 2; - - string escaped_time = 101; -} - -message ResetPlugin_Args { - string plugin_root = 1; -} -message ResetPlugin_Result { - // empty -} - -message FormatCode_Args { - string source = 1; -} - -message FormatCode_Result { - bytes formatted = 1; -} - -message FormatPath_Args { - string path = 1; -} - -message FormatPath_Result { - repeated string changed_paths = 1; -} - -message LintPath_Args { - repeated string paths = 1; -} - -message LintPath_Result { - repeated string results = 1; -} - -message OverrideFile_Args { - string file = 1; - repeated string specs = 2; - repeated string import_paths = 3; -} - -message OverrideFile_Result { - bool result = 1; -} - -message EvalCode_Args { - string code = 1; -} -message EvalCode_Result { - string json_result = 2; -} - -message ResolveCode_Args { - string code = 1; -} - -message ResolveCode_Result { - bool success = 1; -} - -message GetSchemaType_Args { - string file = 1; - string code = 2; - string schema_name = 3; -} -message GetSchemaType_Result { - repeated KclType schema_type_list = 1; -} - -message GetSchemaTypeMapping_Args { - string file = 1; - string code = 2; - string schema_name = 3; -} -message GetSchemaTypeMapping_Result { - map schema_type_mapping = 1; -} - -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} - -message ValidateCode_Result { - bool success = 1; - string err_message = 2; -} - -message Position { - int64 line = 1; - int64 column = 2; - string filename = 3; -} - -message ListDepFiles_Args { - string work_dir = 1; - bool use_abs_path = 2; - bool include_all = 3; - bool use_fast_parser = 4; -} - -message ListDepFiles_Result { - string pkgroot = 1; - string pkgpath = 2; - repeated string files = 3; -} - -// --------------------------------------------------------------------------------- -// LoadSettingsFiles API -// Input work dir and setting files and return the merged kcl singleton config. -// --------------------------------------------------------------------------------- - -message LoadSettingsFiles_Args { - string work_dir = 1; - repeated string files = 2; -} - -message LoadSettingsFiles_Result { - CliConfig kcl_cli_configs = 1; - repeated KeyValuePair kcl_options = 2; -} - -message CliConfig { - repeated string files = 1; - string output = 2; - repeated string overrides = 3; - repeated string path_selector = 4; - bool strict_range_check = 5; - bool disable_none = 6; - int64 verbose = 7; - bool debug = 8; -} - -message KeyValuePair { - string key = 1; - string value = 2; -} - -// ---------------------------------------------------------------------------- -// JSON Schema Lit -// ---------------------------------------------------------------------------- - -message KclType { - string type = 1; // schema, dict, list, str, int, float, bool, any, union, number_multiplier - repeated KclType union_types = 2 ; // union types - string default = 3; // default value - - string schema_name = 4; // schema name - string schema_doc = 5; // schema doc - map properties = 6; // schema properties - repeated string required = 7; // required schema properties, [property_name1, property_name2] - - KclType key = 8; // dict key type - KclType item = 9; // dict/list item type - - int32 line = 10; - - repeated Decorator decorators = 11; // schema decorators -} - -message Decorator { - string name = 1; - repeated string arguments = 2; - map keywords = 3; -} - -// ---------------------------------------------------------------------------- -// END -// ---------------------------------------------------------------------------- -``` diff --git a/versioned_docs/version-0.5.3/tools/Ide/index.md b/versioned_docs/version-0.5.3/tools/Ide/index.md deleted file mode 100644 index aec7245a..00000000 --- a/versioned_docs/version-0.5.3/tools/Ide/index.md +++ /dev/null @@ -1,6 +0,0 @@ -# IDE - -We have provided two simple kinds of plugins for KCL. You can get more help information at the following link: - -- IntelliJ Plugin: https://github.com/kcl-lang/intellij-kcl -- VSCode Plugin: https://github.com/kcl-lang/vscode-kcl diff --git a/versioned_docs/version-0.5.3/tools/Ide/intellij.md b/versioned_docs/version-0.5.3/tools/Ide/intellij.md deleted file mode 100644 index be637514..00000000 --- a/versioned_docs/version-0.5.3/tools/Ide/intellij.md +++ /dev/null @@ -1,3 +0,0 @@ -# IntelliJ IDEA - -- IntelliJ Plugin: https://github.com/kcl-lang/intellij-kcl diff --git a/versioned_docs/version-0.5.3/tools/Ide/vs-code.md b/versioned_docs/version-0.5.3/tools/Ide/vs-code.md deleted file mode 100644 index 6b00815c..00000000 --- a/versioned_docs/version-0.5.3/tools/Ide/vs-code.md +++ /dev/null @@ -1,55 +0,0 @@ -# KCL Extension for Visual Studio Code - -## Quick Start - -- **Step 1.** [Install KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) on your system. Please check that `kcl` and `kcl-language-server` are installed and have been added to your PATH: - - ```bash - which kcl - which kcl-language-server - ``` - -- **Step 2.** Install the [KCL extension](https://marketplace.visualstudio.com/items?itemName=kcl.kcl-vscode-extension) for Visual Studio Code. This extension requires the VS Code 1.50+. -- **Step 3.** Reopen VS Code and create a KCL file and begin your KCL tour! - -## Features - -This extension provides some coding assistance, including the following features: - -- **Syntax Highlight:** - ![Highlight](/img/docs/tools/Ide/vs-code/Highlight.png) -- **Goto Definition:** Goto definition of schema, variable, schema attribute, and import pkg. - ![Goto Definition](/img/docs/tools/Ide/vs-code/GotoDef.gif) -- **Completion:** Keywords completions and dot(`.`) completion. - ![Completion](/img/docs/tools/Ide/vs-code/Completion.gif) -- **Outline:** Main definition(schema def) and variables in KCL file. - ![Outline](/img/docs/tools/Ide/vs-code/Outline.gif) -- **Hover:** Identifier information (type and schema documentation). - ![Hover](/img/docs/tools/Ide/vs-code/Hover.gif) -- **Diagnostics:** Warnings and errors in KCL file. - - > Tips: You can enhance the effect of diagnostics by installing another plugin: [Error Lens](https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens). - - ![Diagnostics](/img/docs/tools/Ide/vs-code/Diagnostics.gif) - -Other useful features such as refactoring and testing are in development. - -## Dependencies - -We recommend that you use the latest version of KCL, but the minimum required version for this extension is 0.4.6. If you are using an earlier version, the extension may not work properly. - -## Known Issues - -See [here](https://github.com/kcl-lang/kcl/issues/524). - -## Ask for help - -If the extension isn't working as you expect, please contact us with [community](https://kcl-lang.io/docs/community/intro/support) for help. - -## Contributing - -We are working actively on improving the KCL development on VS Code. All kinds of contributions are welcomed. You can refer to our [contribution guide](https://kcl-lang.io/docs/community/contribute). It introduces how to build and run the extension locally, and describes the process of sending a contribution. - -## License - -Apache License 2.0 diff --git a/versioned_docs/version-0.5.3/tools/cli/kcl/docgen.md b/versioned_docs/version-0.5.3/tools/cli/kcl/docgen.md deleted file mode 100644 index ca647228..00000000 --- a/versioned_docs/version-0.5.3/tools/cli/kcl/docgen.md +++ /dev/null @@ -1,317 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Docgen - -The KCL Docgen tool supports extracting model documents from KCL source code and supports multiple output formats: JSON, YAML and Markdown. This article introduces the document specification of the KCL language, gives an example of how to use the KCL Docgen tool to extract documents, and shows the process of importing localization documents. - -## 1. Document Specification of KCL - -The documentation of the KCL file mainly contains the following two parts: - -- Current KCL Module document: description of the current KCL file -- All schema documents contained in the KCL file: a description of the current schema, including schema description, schema attribute descriptions, and Examples. The specific format is as follows: - -1. Schema description - -```python -"""This is a brief description of the Schema -""" -``` - -2. Description of each attribute of Schema: including attribute description, attribute type, default value, optional or required - -```python -""" -Attributes ----------- -x : type, default is a, optional. - Description of parameter `x`. -y : type, default is b, required. - Description of parameter `y`. -""" -``` - -`----------` indicates that `Attributes` is a title (the length of the symbol `-` is the same as the length of the title), the attribute name and attribute type are separated by a colon `:`, the description of the attribute is written on another line with indentation. The default value of the attribute is separated by a comma `,` after the attribute type, and it is written in the form of `default is {default value}`. In addition, it is necessary to indicate whether the attribute is optional/required. Write `optional` after the default value for an optional attribute, and write `required` after the default value for a required attribute. - -3. Examples - -```python -""" -Examples --------- -val = Schema { - name = "Alice" - age = 18 -} -""" -``` - -In addition, the KCL docstring syntax should use a subset of the [re-structured text (reST)](https://docutils.sourceforge.io/rst.html) and be rendered using the [Sphinx](https://www.sphinx-doc.org/en/master/). - -## 2. Generating Documentation From KCL - -Use the `kcl-doc generate` command to extract documentation from a user-specified file or directory and output it to the specified directory. - -1. Args - -``` -usage: kcl-doc generate [-h] [--format YAML] [-o OUTPUT] [--r] - [--i18n-locale LOCALE] [--repo-url REPO_URL] - [files [files ...]] - -positional arguments: - files KCL file paths. If there's more than one files to - generate, separate them by space - -optional arguments: - -h, --help show this help message and exit - --format YAML Doc file format, support YAML, JSON and MARKDOWN. - Defaults to MARKDOWN - -o OUTPUT, --output-path OUTPUT - Specify the output directory. Defaults to ./kcl_doc - --r, -R, --recursive Search directory recursively - --i18n-locale LOCALE I18n locale, e.g.: zh, zh_cn, en, en_AS. Defaults to - en - --repo-url REPO_URL The source code repository url. It will be displayed in - the generated doc to link to the source code. -``` - -2. Extract documents from the file(s) and output them to the specified directory - -```text -kcl-doc generate your_config.k your_another_config.k -o your_docs_output_dir -``` - -3. From the specified directory, recursively find the KCL file(s) and extract the documentation - -```text -kcl-doc generate your_config_dir -r -o your_docs_output_dir -``` - -4. When generating documentation, specify the source code repository address. The generated documentation will contain links to source files - -```text -kcl-doc generate your_config.k -o your_docs_output_dir --repo-url https://url/to/source_code -``` - -## 3. Add Documentation for Localized Languages - -As shown before, by default, the documentation extracted by the documentation generation tool is based on the content of the source docstring, and thus the language of the documentation depends on the language in which the docstring was written. If you need to add localized language documentation to the source file, you can follow the steps below: - -1. Initialize the i18n configuration file. This step generates the corresponding i18n configuration file based on the specified KCL file. The file format can be JSON/YAML, and the default is YAML. The output profile name will end in the specified target localization language - -```text -kcl-doc init-i18n your_config.k --format JSON --i18n-locale your_target_locale -``` - -2. Modify the i18n configuration file and update each doc field in your locale language - -3. Generate localized documents from the modified i18n configuration file - -```text -kcl-doc generate your_config_dir --i18n-locale your_target_locale --format Markdown -``` - -Next, a simple example is used to demonstrate the process of adding localized language documents. - -3.1 Prepare the KCL file, such as `server.k`: - - ```python - schema Server: - """Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - - Attributes - ---------- - workloadType : str, default is "Deployment", required - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - name : str, required - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - labels : {str:str}, optional - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - - Examples - ---------------------- - myCustomApp = AppConfiguration { - name = "componentName" - } - """ - - workloadType: str = "Deployment" - name: str - labels?: {str: str} - ``` - -3.2 Get the initialized i18n configuration file from the `server.k`. For example, if you want to add Chinese documents to it, specify the format of the generated configuration file as YAML - - ```text - kcl-doc init-i18n server.k --format YAML --i18n-locale zh_cn - ``` - - This command will create the directory `kcl_doc` under the current directory and generate the i18n configuration file `kcl_doc/i18n_server_zh_cn.yaml`. Its contents are as follows: - - ```yaml - name: server - relative_path: ./server.k - schemas: - - name: Server - doc: | - Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - attributes: - - name: workloadType - doc: | - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - default_value: '"Deployment"' - is_optional: false - - name: name - doc: | - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: false - default_value: '' - - name: labels - doc: | - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - type: - type_str: '{str: str}' - type_category: DICT - dict_type: - key_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - value_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: true - default_value: '' - examples: | - myCustomApp = AppConfiguration { - name = "componentName" - } - doc: '' - source_code_url: '' - ``` - -3.3 Modify all the `doc` fields to the Chinese description. The modified configuration is as follows: - - ```yaml - name: server - relative_path: ./server.k - schemas: - - name: Server - doc: | - Server 模型定义了采用 Kubernetes 最佳实践的持续运行的服务的通用配置接口 - attributes: - - name: workloadType - doc: | - workloadType 属性定义了服务的类型,是服务级别的属性。合法的取值有:Deployment, CafeDeployment. - 另请查看:k8s/core/v1/workload_metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - default_value: '"Deployment"' - is_optional: false - - name: name - doc: | - name 为服务的名称,是服务级别的属性。 - 另请查看:k8s/core/v1/metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: false - default_value: '' - - name: labels - doc: | - labels 为服务的标签,是服务级别的属性。 - 另请查看:k8s/core/v1/metadata.k. - type: - type_str: '{str: str}' - type_category: DICT - dict_type: - key_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - value_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: true - default_value: '' - examples: | - myCustomApp = AppConfiguration { - name = "componentName" - } - doc: '' - source_code_url: '' - ``` - -3.4 Based on the modified i18n configuration, generate documents in localized languages. Execute the following command to output the Chinese document `kcl_doc/doc_server_zh_cn.md`. The commands and the contents of the generated documents are as follows: - -```text -kcl-doc generate server.k --i18n-locale zh_cn --format Markdown -``` - -````markdown -# server - -## Schema Server - -Server 模型定义了采用 Kubernetes 最佳实践的持续运行的服务的通用配置接口 - -### Attributes - -| Name and Description | Type | Default Value | Required | -| -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | ------------- | ------------ | -| **workloadType**
workloadType 属性定义了服务的类型,是服务级别的属性。合法的取值有:Deployment, CafeDeployment.
另请查看:k8s/core/v1/workload_metadata.k. | str | "Deployment" | **required** | -| **name**
name 为服务的名称,是服务级别的属性。
另请查看:k8s/core/v1/metadata.k. | str | Undefined | **required** | -| **labels**
labels 为服务的标签,是服务级别的属性。
另请查看:k8s/core/v1/metadata.k. | {str: str} | Undefined | optional | - -### Examples - -``` -myCustomApp = AppConfiguration { - name = "componentName" -} -``` - - -```` - -## 4. Appendix - -### 1. Concept of reST - -For documents in reST format, paragraphs and indentation are important, new paragraphs are marked with blank lines, and indentation is the indentation indicated in the output. Font styles can be expressed as follows: - -- \*Italic\* -- \*\*Bold\*\* -- \`\`Monospaced\`\` - -Refer to [reST](https://docutils.sourceforge.io/rst.html) for more information. diff --git a/versioned_docs/version-0.5.3/tools/cli/kcl/fmt.md b/versioned_docs/version-0.5.3/tools/cli/kcl/fmt.md deleted file mode 100644 index eaf562cd..00000000 --- a/versioned_docs/version-0.5.3/tools/cli/kcl/fmt.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Format - -The KCL Format tool supports reformatting KCL files to the standard code style. This article demonstrates the KCL code style and how to use the KCL Format tool. - -## Code Style - -The KCL Format tool modifies the files according to the KCL code style: [Style Guide for KCL Code](/docs/reference/lang/spec/codestyle) - -## How to use - -- Formatting Single File - -```text -kcl-fmt your_config.k -``` - -- Formatting multiple files - -```text -kcl-fmt your_config_path -R -``` - -- Args - - `-R|--recursive` Whether to recursively traverse subfolders - - `-w|--fmt-output` Whether to output to STDOUT, without `-w` indicates in-place modification. - -## Display of formatting files - -- Before formatting - -```py -import math -mixin DeploymentMixin: - service:str ="my-service" -schema DeploymentBase: - name: str - image : str -schema Deployment[replicas] ( DeploymentBase ) : - mixin[DeploymentMixin] - replicas : int = replicas - command: [str ] - labels: {str: str} -deploy = Deployment(replicas = 3){} -``` - -- After formatting - -```py -import math - -mixin DeploymentMixin: - service: str = "my-service" - -schema DeploymentBase: - name: str - image: str - -schema Deployment[replicas](DeploymentBase): - mixin [DeploymentMixin] - replicas: int = replicas - command: [str] - labels: {str:str} - -deploy = Deployment(replicas=3) {} - -``` diff --git a/versioned_docs/version-0.5.3/tools/cli/kcl/index.md b/versioned_docs/version-0.5.3/tools/cli/kcl/index.md deleted file mode 100644 index b750f652..00000000 --- a/versioned_docs/version-0.5.3/tools/cli/kcl/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# KCL Language Tools - -KCL not only provides the command `kcl` to compile and execute configuration programs but also provides fmt, lint, test, vet, docgen and other supporting tools. diff --git a/versioned_docs/version-0.5.3/tools/cli/kcl/lint.md b/versioned_docs/version-0.5.3/tools/cli/kcl/lint.md deleted file mode 100644 index 627177a9..00000000 --- a/versioned_docs/version-0.5.3/tools/cli/kcl/lint.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Lint - -The KCL Lint tool supports checking some warning-level defects in KCL code and supports multiple output formats. This document shows how to use the KCL Lint tool. - -## Example - -### Project Struct - -```text -. -└── Test - └── kcl.mod - └── a.k - └── b.k - └── dir - └── c.k - └── test.k -``` - -`a.k`, `b.k`, `c.k` and `test.k` are the kcl file to be checked. - -Args: - -```shell -kcl-lint your_config.k -``` - -or - -```shell -kcl-lint your_config_path -``` - -## KCL Lint Tool - -### Args - -```shell -USAGE: - kcl-lint [OPTIONS] [--] [input]... - -ARGS: - ... Sets the input file to use - -OPTIONS: - --emit_warning Emit warning message - -h, --help Print help information - -v, --verbose Print test information verbosely - -Y, --setting ... Sets the input file to use -``` - -- input: the path of a single `*.k` file or directory to be checked. Support the absolute path or relative path of the current directory. diff --git a/versioned_docs/version-0.5.3/tools/cli/kcl/overview.md b/versioned_docs/version-0.5.3/tools/cli/kcl/overview.md deleted file mode 100644 index b1354b8c..00000000 --- a/versioned_docs/version-0.5.3/tools/cli/kcl/overview.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Overview - -KCL toolchain is a toolset of KCL language, which aims to improve the efficiency of batch migration, writing, compiling and running of KCL. - -| | Name | Description | -| ---------- | ------------------------ | ------------------------------------------------------------------- | -| Main Tools | **kcl** | Provide support for KCL in coding, compiling and running | -| | kcl-test | Coming soon | -| | kcl-lint | Check code style for KCL | -| | kcl-doc | Parses the KCL code and generate documents | -| | kcl-fmt | Format the kcl code | -| | kcl-vet | Validate data files such as JSON and YAML using KCL | -| IDE Plugin | IntelliJ IDEA KCL plugin | Provide assistance for KCL in coding and compiling on IntelliJ IDEA | -| | VS Code KCL plugin | Provide assistance for KCL in coding and compiling on VS Code | - -## KCL Tool - -### Args - -```shell -USAGE: - kcl [OPTIONS] [--] [input]... - -Arguments: - [input]... Specify the input files to run - -Options: - -o, --output - Specify the YAML output file path - -Y, --setting ... - Specify the input setting file - -v, --verbose... - Print test information verbosely - -n, --disable_none - Disable dumping None values - -r, --strict_range_check - Do perform strict numeric range checks - -d, --debug - Run in debug mode (for developers only) - -k, --sort_keys - Sort result keys - -D, --argument ... - Specify the top-level argument - -S, --path_selector ... - Specify the path selector - -O, --overrides ... - Specify the configuration override path and value - --target - Specify the target type - -E, --external ... - Mapping of package name and path where the package is located - -h, --help - Print help -``` diff --git a/versioned_docs/version-0.5.3/tools/cli/kcl/test.md b/versioned_docs/version-0.5.3/tools/cli/kcl/test.md deleted file mode 100644 index 4f99e53d..00000000 --- a/versioned_docs/version-0.5.3/tools/cli/kcl/test.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Test Tool - -Coming soon. diff --git a/versioned_docs/version-0.5.3/tools/cli/kcl/vet.md b/versioned_docs/version-0.5.3/tools/cli/kcl/vet.md deleted file mode 100644 index d2f2220e..00000000 --- a/versioned_docs/version-0.5.3/tools/cli/kcl/vet.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Validation - -## Intro - -The KCL Validation tool supports basic configuration data verification capabilities. You can write a KCL schema to verify the type and value of the input JSON/YAML files. - -## How to use - -There is a JSON format file `data.json`: - -```json -{ - "name": "Alice", - "age": 18, - "message": "This is Alice", - "data": { - "id": 1, - "value": "value1" - }, - "labels": { - "key": "value" - }, - "hc": [1, 2, 3] -} -``` - -Build a validated KCL file `schema.k`: - -```py -schema User: - name: str - age: int - message?: str - data: Data - labels: {str:} - hc: [int] - - check: - age > 10 - -schema Data: - id: int - value: str -``` - -Execute the following command: - -```shell -kcl-vet data.json schema.k -``` - -## Specify the schema for validation - -When multiple schema definitions exist in the KCL file, by default, the KCL Validation tool will use the first schema to check. If you need to specify a schema for verification, you can use the `-d|--schema` parameter - -```shell -kcl-vet data.json schema.k -d User -``` - -## Args - -```shell -$ kcl-vet -h -USAGE: - kcl-vet [OPTIONS] [ARGS] - -ARGS: - Validation data file - KCL file - -OPTIONS: - -d, --schema - Iterate through subdirectories recursively - - --format - Validation data file format, support YAML and JSON, default is JSON - - -h, --help - Print help information - - -n, --attribute_name - The attribute name for the data loading -``` diff --git a/versioned_docs/version-0.5.3/tools/cli/openapi/crd-to-kcl.md b/versioned_docs/version-0.5.3/tools/cli/openapi/crd-to-kcl.md deleted file mode 100644 index aafebcd9..00000000 --- a/versioned_docs/version-0.5.3/tools/cli/openapi/crd-to-kcl.md +++ /dev/null @@ -1,118 +0,0 @@ -# CRD to KCL - -To convert from models defined in the Kubernetes CRD file to KCL schema, we could run the following script: - -```shell -kcl-openapi generate model --crd -f ${your_CRD.yaml} -t ${the_kcl_files_output_dir} --skip-validation -``` - -## Example - -- There is the Kubernetes CRD file that we need to convert: `test_crontab_CRD.yaml`: - -```yaml -# Deprecated in v1.16 in favor of apiextensions.k8s.io/v1 -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - # name must match the spec fields below, and be in the form: . - name: crontabs.stable.example.com -spec: - # group name to use for REST API: /apis// - group: stable.example.com - # list of versions supported by this CustomResourceDefinition - versions: - - name: v1 - # Each version can be enabled/disabled by Served flag. - served: true - # One and only one version must be marked as the storage version. - storage: true - # either Namespaced or Cluster - scope: Namespaced - names: - # plural name to be used in the URL: /apis/// - plural: crontabs - # singular name to be used as an alias on the CLI and for display - singular: crontab - # kind is normally the CamelCased singular type. Your resource manifests use this. - kind: CronTab - # shortNames allow shorter string to match your resource on the CLI - shortNames: - - ct - preserveUnknownFields: false - validation: - openAPIV3Schema: - type: object - properties: - spec: - type: object - properties: - cronSpec: - type: string - image: - type: string - replicas: - type: integer -``` - -- The script will be: - -```shell -kcl-openapi generate model -f test_crontab_CRD.yaml -t ~/ --skip-validation --crd -``` - -- Then we can find the generated file here: `~/models/stable_example_com_v1_cron_tab.k` - -```python -""" -This file was generated by the KCL auto-gen tool. DO NOT EDIT. -Editing this file might prove futile when you re-run the KCL auto-gen generate command. -""" -import kusion_kubernetes.apimachinery.apis - - -schema CronTab: - """stable example com v1 cron tab - - Attributes - ---------- - apiVersion : str, default is "stable.example.com/v1", required - APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - kind : str, default is "CronTab", required - Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - metadata : apis.ObjectMeta, default is Undefined, optional - metadata - spec : StableExampleComV1CronTabSpec, default is Undefined, optional - spec - """ - - - apiVersion: "stable.example.com/v1" = "stable.example.com/v1" - - kind: "CronTab" = "CronTab" - - metadata?: apis.ObjectMeta - - spec?: StableExampleComV1CronTabSpec - - -schema StableExampleComV1CronTabSpec: - """stable example com v1 cron tab spec - - Attributes - ---------- - cronSpec : str, default is Undefined, optional - cron spec - image : str, default is Undefined, optional - image - replicas : int, default is Undefined, optional - replicas - """ - - - cronSpec?: str - - image?: str - - replicas?: int -``` diff --git a/versioned_docs/version-0.5.3/tools/cli/openapi/index.md b/versioned_docs/version-0.5.3/tools/cli/openapi/index.md deleted file mode 100644 index 236d6e36..00000000 --- a/versioned_docs/version-0.5.3/tools/cli/openapi/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# OpenAPI Tools - -The KCL OpenAPI tool can not only convert common models but also support CRD and other models. diff --git a/versioned_docs/version-0.5.3/tools/cli/openapi/openapi-to-kcl.md b/versioned_docs/version-0.5.3/tools/cli/openapi/openapi-to-kcl.md deleted file mode 100644 index bef582ec..00000000 --- a/versioned_docs/version-0.5.3/tools/cli/openapi/openapi-to-kcl.md +++ /dev/null @@ -1,64 +0,0 @@ -# OpenAPI to KCL - -To convert from models defined in the OpenAPI spec file to KCL schema, we could run the following script: - -```shell -kcl-openapi generate model -f ${your_open_api_spec.yaml} -t ${the_kcl_files_output_dir} -``` - -For example: - -- There is the OpenAPI spec file that we need to convert: `test_open_api_spec.yaml` - -```yaml -definitions: - v1.TestInt: - type: object - properties: - name: - type: string - format: int-or-string - required: - - name - x-kcl-type: - import: - package: v1.test_int - alias: test_int - type: TestInt -swagger: "2.0" -info: - title: KCL - version: v0.0.2 -paths: {} -``` - -- The script will be: - -```shell -kcl-openapi generate model -f test_open_api_spec.yaml -t ~/ --skip-validation -``` - -- Then we can find the generated file here: `~/models/v1/test_int.k` - -```python -""" -This is the test_int module in v1 package. -This file was generated by the KCL auto-gen tool. DO NOT EDIT. -Editing this file might prove futile when you re-run the KCL auto-gen generate command. -""" - - -schema TestInt: - """v1 test int - - Attributes - ---------- - name : int | str, default is Undefined, required - name - """ - - - name: int | str - - -``` diff --git a/versioned_docs/version-0.5.3/tools/cli/openapi/quick-start.md b/versioned_docs/version-0.5.3/tools/cli/openapi/quick-start.md deleted file mode 100644 index d5812e3a..00000000 --- a/versioned_docs/version-0.5.3/tools/cli/openapi/quick-start.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Quick Start - -## 1. Install KCLOpenAPI Tool - -The kcl-openapi tool can be installed in following ways: - -- [go install](#11-go-install) -- [curl|sh install (MacOS & Linux)](#12-curlsh-install-macos--linux) -- [download from release](#13-dowload-from-release) - -## 1.1 go install - -```shell -go install kcl-lang.io/kcl-openapi@latest -``` - -## 1.2 Curl|sh install (MacOS & Linux) - -If you don't have go, you can install the CLI with this one-liner: - -```shell -curl -fsSL https://kcl-lang.io/script/install-kcl-openapi.sh | /bin/bash -``` - -## 1.3 Download from release - -```shell -# 1. download the released binary from: -# https://github.com/kcl-lang/kcl-openapi/releases - -# 2. Unzip the package and add the binary location to PATH -export PATH=":$PATH" -``` - -## 1.4 Verify your installation - -```shell -➜ kcl-openapi -v -kcl-openapi 0.5.0 -``` - -## 2. Generate KCL Files - -- [OpenAPI to KCL](../openapi/openapi-to-kcl.md) -- [CRD to KCL](../openapi/crd-to-kcl.md) diff --git a/versioned_docs/version-0.5.3/tools/cli/openapi/spec.md b/versioned_docs/version-0.5.3/tools/cli/openapi/spec.md deleted file mode 100644 index 7a144e4c..00000000 --- a/versioned_docs/version-0.5.3/tools/cli/openapi/spec.md +++ /dev/null @@ -1,438 +0,0 @@ -# KCL OpenAPI Spec - -[OpenAPI](https://www.openapis.org/) defines the API Specification for API providers to describe their operations and models in a normative way and provides generating tools to automatically convert to client codes in specific languages. - -The KCL OpenAPI Spec describes the rules about how the OpenAPI definitions are translated to the KCL schemas. - -## The File Structure of the KCL OpenAPI - -According to the OpenAPI 3.0 specification, an OpenAPI file should at least contains four root objects: `openapi`, `components`, `info`, `paths`. The KCL OpenAPI focuses on the part in which the models are defined in the `definitions` object. Yet the `paths` part which describes the Restful API operations is not considered by the KCL OpenAPI Spec. - -:::info -Note: In addition to the objects listed above, the OpenAPI spec also supports `servers`, `security`, `tags`, and `externalDocs` as optional root objects, but none of them are concerned by KCL OpenAPI when generating model codes, so we do not need to fill in this section. Yet it won't make any difference if you do. -::: - -To put it more comprehensible for beginners, let's take a quick look at the root objects that forms the typical KCL OpenAPI file (snippets from swagger example [Petstore](https://petstore.swagger.io/). The KCL OpenAPI tool only focuses on the `definitions` object which describes two data models (`Pet` and `Category`), and the model `Pet` contains three attributes: `name`, `id`, and `category`) - -## KCL schema - -The KCL schema structure defines the "type" of configuration data. - -:::info -More information about KCL schema, see [KCL Language Tour#Schema](../../../reference/lang/tour.md) -::: - -In the OpenAPI spec, a KCL schema can be defined by adding a `definition` element within the `definitions` object. - -Example: -The following example defines two schemas in KCL: `Pet` and `Category`, followed by the corresponding data models defined in OpenAPI: - -```python -# KCL schema -schema Pet: - name: str - id?: int - category?: Category - -schema Category: - name?: str - -# The corresponding OpenAPI spec -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "id": { - "type": "integer", - "format": "int64" - }, - "category": { - "$ref": "#/definitions/Category" - } - }, - "required": [ - "name" - ] - }, - "Category": { - "type": "object", - "properties": { - "name": { - "type": "string" - } - } - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### Schema Name - -In KCL, the schema name is declared immediately after the schema keyword, and in OpenAPI, the name of the model is defined by the key of the definition element. - -### Schema Type - -The type of KCL schema in OpenAPI is always "object". As in the previous example, the value of the `type` object in `Pet` should be `object`. - -### Schema Attribute - -Zero or more attributes can be defined in the KCL schema. The declaration of attributes generally includes the following parts: - -- Attribute annotation: Optional, starting with `@`, such as `@deprecated` to indicate a deprecated attribute -- Attribute name: Required -- Attribute optional modifiers(`?`): Optional. A question mark indicates that the current attribute is optional and may not be assigned. Conversely, the absence of a question mark indicates a required attribute -- Attribute type: Required. The attribute can be a primitive data type, a schema type, or a combination of the two preceding types -- Attribute default value: Optional - -The mapping between them and the OpenAPI spec is as follows: - -| Elements of KCL Schema Attribute | Corresponding Elements in OpenAPI | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| attribute annotation | Not supported. We are planning to add an extension `deprecate` field to the KCL-OpenAPI | -| attribute name | The key of the property under the `property` object | -| attribute optional modifiers(`?`) | In each element in the `definition` object, here's an optional `required` field which lists the all the required attributes of that model, and the attributes not listed are optional | -| attribute type | The basic types can be declared by a combination of `type` and `format`, and the schema type is declared by a `$ref` to the schema definition. KCL-OpenAPI spec adds a `x-kcl-types` extension to indicate a type union. `enum` indicates a union of several literal types. For the type declaration in KCL-OpenAPI, see the chapter - [basic data types](#basic-data-types) | -| attribute default value | The value of the `default` field is used to set the default value for the attribute | - -Example: - -The following KCL code defines a Pet model which contains two attributes: name (`string` type, `required`, with no attribute annotation and no default value) and id (`int64` type, optional, with no attribute annotation, and the default value is -1). - -```python -# the KCL schema Pet defines two attributes: name, id -schema Pet: - name: str - id?: int = -1 - -# The corresponding OpenAPI spec -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - "id": { - "type": "integer", - "format": "int64", - "default": -1 - } - }, - "required": [ - "name" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### Schema Index Signature - -In the KCL schema, the index signatures can be used to define attributes with undefined attribute names. The KCL schema index signature contains the following elements: - -- Type of the key in the index signature: Declared in square brackets. It must be the basic type -- Type of value in the index signature: Declared after the colon in the square brackets. It can be any valid KCL type -- Ellipses(`...`) in the index signature: In the square brackets, before the type declaration of the key. It indicates that the index signature is only used to constrain attributes not defined in the schema. The absentation of the symbol indicates that all defined and undefined attributes in the schema are constrained by the index signature. -- Alias for key in index signature: Declared in square brackets, immediately after the left square bracket and takes the form of `:`. The alias can then be used to reference the index signature by name -- The default value of the index signature: Assign a value to the index signature as the default value - -The index signature with its key in `string` type can be described based on the field `additionalProperties`. Other index signatures with a key in types besides `string`, and the `check` expressions used to validate the index signature are not supported by the KCL OpenAPI spec. - -The mapping between them and the OpenAPI spec is as follows: - -| Elements of KCL Index Signature | Corresponding Elements in OpenAPI | -| -------------------------------------------- | ----------------------------------------------------------------------------------------------- | -| Type of the key in the KCL index signature | Only string type is allowed in OpenAPI | -| Type of the value in the KCL index signature | Declared by the `type` in the `additionalProperties` field | -| Ellipses(`...`) in the index signature | Only the corresponding meaning of the attendance of the `...` symbol is allowed in OpenAPI | -| Alias for key in index signature | Not supported in KCL-OpenAPI yet. We are planning to add an `x-alias` extension to support that | -| Default value of the index signature | Not supported in KCL-OpenAPI | - -Example: - -The following KCL code defines a Pet model which contains two pre-declared attributes(`name` and `id`) and allows users to add attributes with `string` type keys and `bool` type values. - -```python -# the KCL schema Pet. Besides the pre-declared attributes name and id, it allows to add attributes with key in string type and value in bool type -schema Pet: - name: str - id?: int - [...str]: bool - -# The corresponding OpenAPI spec -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - "id": { - "type": "integer", - "format": "int64", - } - }, - "additionalProperties": { - "type": "bool" - }, - "required": [ - "name" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### Schema Inherit - -working in progress - -### Inline schema - -OpenAPI supports models to be declared inline. But KCL currently does not support that. The model defined inline in OpenAPI will be converted to a schema with a name in KCL. And the naming convention will be: - -| element to define an inline schema in OpenAPI | the name of the corresponding KCL schema | -| --------------------------------------------- | -------------------------------------------------------------- | -| inline Property | add the Property name at the end of the outer schema Name | -| AdditionalProperties | add "AdditionalProperties" at the end of the outer schema Name | - -We are planning to support inline schema in KCL, and when supported, the naming convention will be updated then. - -Example-1: - -The following KCL code defines a `Deployment` model which contains two attributes(`kind` and `spec`). And the schema of the `spec` attribute is defined inline. - -```python -# The OpenAPI spec -{ - "definitions": { - "Deployment": { - "type": "object", - "properties": { - "kind": { - "type": "string", - }, - "spec": { - "type": "object", - "properties": { - "replicas": { - "type": "integer", - "format": "int64" - } - } - } - }, - "required": [ - "kind", - "spec" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -# The corresponding KCL schemas -schema Deployment: - kind: str - spec: DeploymentSpec - -schema DeploymentSpec: - replicas?: int -``` - -Example-2: - -The following KCL code defines a Person model which contains a pre-declared attribute(`name`) and allows some `additionalProperties` to be assigned by user. And the type of the values in the `additionalProperties` is defined inline. - -```python -# The OpenAPI spec -{ - "definitions": { - "Person": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - }, - "required": [ - "name", - "spec" - ], - "additionalProperties": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "description": { - "type": "string" - } - }, - "required": [ - "name" - ] - }, - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -# The corresponding KCL schemas -schema Person: - name: str - [...str]: [PersonAdditionalProperties] - -schema PersonAdditionalProperties: - name: str - description?: str -``` - -## KCL Doc - -:::info -More information about KCL doc specification, please refer to the [KCL Document Specification](../kcl/docgen.md) -::: - -KCL documents consist of module documents and schema documents. And only the schema documents can be extracted from OpenAPI. The KCL schema document contains four parts: - -- Schema Description: Declared right after the schema declaration and before the schema attribute declaration. It provides an overview of schemas -- Schema Attribute Doc: Declared right after the schema Description and separated by `Attributes` + `---` delimiters. It describes the attribute -- Additional information about the schema: Declared right after the schema attribute doc and separated by `See Also` + `---` delimiters -- Example information about the schema: Declared right after the schema additional information and separated by `Examples` + `---` delimiters - -The mapping between them and the OpenAPI spec is as follows: - -| Elements of KCL Schema Document | Corresponding Elements in OpenAPI | -| --------------------------------------- | ------------------------------------------------------- | -| Schema Description | The value of the `description` field of the data model | -| Schema Attribute Doc | The value of the `description` field of the property | -| Additional information about the schema | The value of the `externalDocs` field of the data model | -| Example information about the schema | The value of the `example` field of the data model | - -Example: - -The following KCL code defines a Pet model with a schema description `The schema Pet definition`, and two attributes `name` and `id` with their attribute doc `The name of the pet` and `The id of the pet`; The additional information about the Pet schema is [here](https://petstore.swagger.io/) and the example to use the Pet schema are provided, too. - -```python -# The KCL schema Pet, with doc following the KCL Document Specification -schema Pet: - """The schema Pet definition - - Attributes - ---------- - name : str, default is Undefined, required - The name of the pet - id : int, default is -1, optional - The age of the pet - - See Also - -------- - Find more info here. https://petstore.swagger.io/ - - Examples - -------- - pet = Pet { - name = "doggie" - id = 123 - } - """ - name: str - id?: int = -1 - -# The corresponding OpenAPI Spec -{ - "definitions": { - "Pet": { - "description": "The schema Pet definition", - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "The name of the pet" - }, - "id": { - "type": "integer", - "format": "int64", - "default": -1, - "description": "The age of the pet" - } - }, - "required": [ - "name" - ], - "externalDocs": { - "description": "Find more info here", - "url": "https://petstore.swagger.io/" - }, - "example": { - "name": "doggie", - "id": 123 - } - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -## Basic Data Types - -| JSON Schema type | swagger type | KCL type | comment | -| ---------------- | --------------------------- | --------------- | --------------------------------------------------------------------------- | -| boolean | boolean | bool | | -| number | number | float | | -| | number format double | **unsupported** | | -| | number format float | float | | -| integer | integer | int (32) | | -| | integer format int64 | **unsupported** | | -| | integer format int32 | int (32) | | -| string | string | str | | -| | string format byte | str | | -| | string format int-or-string | int \| str | | -| | string format binay | str | | -| | string format date | unsupported | As defined by full-date - [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) | -| | string format date-time | unsupported | As defined by date-time - [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) | -| | string format password | unsupported | for swagger: A hint to UIs to obscure input | -| | datetime | datetime | | - -## Reference - -- OpenAPI spec 2.0: [https://swagger.io/specification/v2/](https://swagger.io/specification/v2/) -- OpenAPI spec 3.0: [https://spec.openapis.org/oas/v3.1.0](https://spec.openapis.org/oas/v3.1.0) -- OpenAPI spec 3.0: [https://swagger.io/specification/](https://swagger.io/specification/) -- OpenAPI spec 2.0: [https://swagger.io/specification/v2/#schemaObject](https://swagger.io/specification/v2/#schemaObject) -- Go swagger: [https://goswagger.io/use/models/schemas.html](https://goswagger.io/use/models/schemas.html) -- Swagger data models: [https://swagger.io/docs/specification/data-models/](https://swagger.io/docs/specification/data-models/) diff --git a/versioned_docs/version-0.5.3/user_docs/concepts/concepts.md b/versioned_docs/version-0.5.3/user_docs/concepts/concepts.md deleted file mode 100644 index 627212ad..00000000 --- a/versioned_docs/version-0.5.3/user_docs/concepts/concepts.md +++ /dev/null @@ -1,3 +0,0 @@ -# Concepts - -Learn more about KCL concepts. diff --git a/versioned_docs/version-0.5.3/user_docs/getting-started/index.md b/versioned_docs/version-0.5.3/user_docs/getting-started/index.md deleted file mode 100644 index c50dbaa6..00000000 --- a/versioned_docs/version-0.5.3/user_docs/getting-started/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# Get Started - -Get started include a quick overview of the KCL programming language. diff --git a/versioned_docs/version-0.5.3/user_docs/getting-started/install.md b/versioned_docs/version-0.5.3/user_docs/getting-started/install.md deleted file mode 100644 index 261ab804..00000000 --- a/versioned_docs/version-0.5.3/user_docs/getting-started/install.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Installation - -## 1. Install KCL - -### From the Binary Releases - -Each release of KCL includes various OSes and architectures. These binary versions can be manually downloaded and installed from [Github](https://github.com/kcl-lang/kcl/releases/) or [Gitee](https://gitee.com/kusionstack/kcl/releases) and add `{install-location}/kclvm/bin` to the environment PATH. - -> ⚠️ If you cannot successfully access Github, you can also access Gitee to obtain binaries for installation. - -#### MacOS & Linux - -```bash -export PATH=$PATH:{install-location}/kclvm/bin -``` - -#### Windows - -```powershell -$env:PATH += ";{install-location}\kclvm\bin;" -``` - -### Using script to install the latest release - -#### MacOS - -Install or upgrade the latest darwin KCL to /usr/local/kclvm/bin - -```bash -curl -fsSL https://kcl-lang.io/script/install.sh | /bin/bash -``` - -#### Linux - -Install or upgrade the latest linux KCL to /usr/local/kclvm/bin - -```bash -wget -q https://kcl-lang.io/script/install.sh -O - | /bin/bash -``` - -#### Windows - -Install or upgrade the latest windows KCL to $Env:SystemDrive\kclvm\bin and add this directory to User PATH environment variable. - -```bash -powershell -Command "iwr -useb https://kcl-lang.io/script/install.ps1 | iex" -``` - -### Homebrew (MacOS) - -- Install - -```bash -brew install kcl-lang/tap/kcl -``` - -- Upgrade - -```bash -brew upgrade kcl-lang/tap/kcl -``` - -- Uninstall - -```bash -brew uninstall kcl-lang/tap/kcl -``` - -### Scoop (Windows) - -Install [Scoop](https://scoop.sh/) first, then add this bucket and install `kcl` by running: - -```bash -scoop bucket add kcl-lang https://github.com/kcl-lang/scoop-bucket.git -scoop install kcl-lang/kcl -``` - -### From Go - -Install `kcl` through the `Go` command (`Go` requires 1.18+). - -```bash -go install kcl-lang.io/kcl-go/cmds/kcl-go@main -``` - -Add an alias for the kcl command (optional). - -```bash -alias kcl='kcl-go run' -``` - -> Note: `kcl-go` does not rely on the installation of `kcl`, but if `kcl` exists in PATH, it will be used by `kcl-go` first. - -### From Docker - -- Command - -```bash -docker run --rm -it kcllang/kcl -``` - -- Update image - -```bash -docker pull kcllang/kcl -``` - -### Note - -We can execute the following command to ensure that KCL has been installed correctly. - -```bash -kcl -V -``` - -The output may looks like this: - -```bash -Version: {kcl version} -Platform: {your platform} -GitCommit: {git commit} -``` - -For all the above operating systems and installation methods, if you want to use [KCL Python Plugin](/docs/reference/plugin/overview), you need to ensure that Python 3.7+ is installed and add the python3 command to your PATH environment variable. - -## 2. Install KCL IDE Extension - -### VS Code - -The KCL Extension extension provides some coding assistance, e.g., highlight, goto definition, completion, hover, outline, and diagnostics. You can go [here](/docs/tools/Ide/vs-code) for more information about the installation. - -![Completion](/img/docs/tools/Ide/vs-code/Completion.gif) - -### IntelliJ IDEA - -Download the distribution from [here](https://github.com/kcl-lang/intellij-kcl/releases) and in IntelliJ IDEA, click Preference -> plugins -> install Plugin from Disk... -> select kcl-idea-plugin zip -> restart IDE. This plugin requires the IntelliJ IDEA 2020.2+ diff --git a/versioned_docs/version-0.5.3/user_docs/getting-started/intro.md b/versioned_docs/version-0.5.3/user_docs/getting-started/intro.md deleted file mode 100644 index c4515840..00000000 --- a/versioned_docs/version-0.5.3/user_docs/getting-started/intro.md +++ /dev/null @@ -1,199 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Introduction - -## What is KCL? - -[KCL](https://github.com/kcl-lang/kcl) is an open-source, constraint-based record and functional language that enhances the writing of complex configurations, including those for cloud-native scenarios. With its advanced programming language technology and practices, KCL is dedicated to promoting better modularity, scalability, and stability for configurations. It enables simpler logic writing and offers ease of automation APIs and integration with homegrown systems. - -## Why Use KCL? - -KCL expects to solve the following problems: - -- Hide infrastructure and platform details by defining more appropriate **API abstractions** to reduce the burden of developers. -- **Mutate** and **validate** existing config files or manifests. -- Manage large-scale configuration data across teams without side effects through configuration language. - - Use **production level high-performance programming language** to **write code** to improve the flexibility of configuration, such as conditional statements, loops, functions, package management and other features to improve the ability of configuration reuse. - - Improve the ability of **configuration semantic verification** at the code level, such as optional/required fields, types, ranges, and other configuration checks. - - Provide the **ability to write, combine and abstract configuration blocks**, such as structure definition, structure inheritance, constraint definition, etc. - -You can use KCL to - -- **Generate** low-level static configuration data like JSON, YAML, etc. -- Reduce boilerplate in configuration data with the **schema modeling**. -- Define transformers and constraints for configuration data and templates and **mutate/validate** them automatically. -- Organize, simplify, unify and manage large configurations scalably without side effects. -- Used as a platform engineering language to deliver modern app with [KusionStack](https://kusionstack.io/). - -In addition to the language itself, KCL also provides many additional tools, such as formatting, testing, document, package management, to help users use, understand and check the configuration or policy they write. We can reduce the cost of configuration writing and sharing through IDE extensions such as VS Code, playground and package manage tools. In addition, through KCL Rust, Go, and Python multilingual SDKs, the configuration can be automatically managed and executed. - -![](/img/docs/user_docs/intro/kcl-overview.png) - -Besides, KCL is a modern high-level domain language, which is a compiled, static and strongly typed language. It provides developers with the ability to write **configuration (config)**, **modeling abstraction (schema)**, **logic (lambda)**, and **policies (rule)** as the core elements through recording and functional language design. - -![](/img/docs/user_docs/intro/kcl-concepts.png) - -KCL tries to provide runtime-independent programmability and does not natively provide system functions such as threads and IO, but supports functions for cloud-native operation scenarios, and tries to provide stable, secure, low-noise, low-side effect, easy-to-automate and easy-to-govern programming support for solving domain problems. - -In summary, KCL has the following characteristics: - -- **Easy-to-use**: Originated from high-level languages ​​such as Python and Golang, incorporating functional language features with low side effects. -- **Well-designed**: Independent Spec-driven syntax, semantics, runtime and system modules design. -- **Quick modeling**: [Schema](https://kcl-lang.github.io/docs/reference/lang/tour#schema)-centric configuration types and modular abstraction. -- **Rich capabilities**: Configuration with type, logic and policy based on [Config](https://kcl-lang.github.io/docs/reference/lang/codelab/simple), [Schema](https://kcl-lang.github.io/docs/reference/lang/tour/#schema), [Lambda](https://kcl-lang.github.io/docs/reference/lang/tour/#function), [Rule](https://kcl-lang.github.io/docs/reference/lang/tour/#rule). -- **Stability**: Configuration stability built on [static type system](https://kcl-lang.github.io/docs/reference/lang/tour/#type-system), [constraints](https://kcl-lang.github.io/docs/reference/lang/tour/#validation), and [rules](https://kcl-lang.github.io/docs/reference/lang/tour#rule). -- **Scalability**: High scalability through [automatic merge mechanism](https://kcl-lang.github.io/docs/reference/lang/tour/#-operators-1) of isolated config blocks. -- **Fast automation**: Gradient automation scheme of [CRUD APIs](https://kcl-lang.github.io/docs/reference/lang/tour/#kcl-cli-variable-override), [multilingual SDKs](https://kcl-lang.github.io/docs/reference/xlang-api/overview), [language plugin](https://kcl-lang.github.io/docs/reference/plugin/overview) -- **High performance**: High compile time and runtime performance using Rust & C and [LLVM](https://llvm.org/), and support compilation to native code and [WASM](https://webassembly.org/). -- **API affinity**: Native support API ecological specifications such as [OpenAPI](https://kcl-lang.github.io/docs/tools/cli/openapi/), Kubernetes CRD, Kubernetes YAML spec. -- **Development friendly**: Friendly development experiences with rich [language tools](https://kcl-lang.github.io/docs/tools/cli/kcl/overview) (Format, Lint, Test, Vet, Doc, etc.) and [IDE extensions](https://kcl-lang.github.io/docs/tools/Ide/). -- **Safety & maintainable**: Domain-oriented, no system-level functions such as native threads and IO, low noise and security risk, easy maintenance and governance. -- **Rich multi-language SDK**: [Go](https://kcl-lang.io/docs/reference/xlang-api/go-api), [Python](https://kcl-lang.io/docs/reference/xlang-api/python-api), [Java](https://kcl-lang.io/docs/reference/xlang-api/java-api) and [REST APIs](https://kcl-lang.io/docs/reference/xlang-api/rest-api) meet different scenarios and application use prelude. -- **Kubernetes Integrations**: External mutation and validation plugins including [Kustomize KCL Plugin](https://github.com/kcl-lang/kustomize-kcl), [Helm KCL Plugin](https://github.com/kcl-lang/helm-kcl), [KPT KCL SDK](https://github.com/kcl-lang/kpt-kcl-sdk), [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) to separate data and logic. -- **Production-ready**: Widely used in production practice of platform engineering and automation at Ant Group. - -Although KCL is not a general language, it has corresponding application scenarios. Developers can write **config**, **schema**, **function** and **rule** through KCL, where config is used to define data, schema is used to describe the model definition of data, rule is used to validate data, and schema and rule can also be combined to use models and constraints that fully describe data, In addition, we can also use the lambda pure function in KCL to organize data code, encapsulate common code, and call it directly when needed. - -The configuration of attributes in KCL usually meets the simple pattern: - -$$ -k = (T) v -$$ - -where $k$ is the attribute name, $v$ is the attributes value, and $T$ is the type annotation. Since KCL has the ability of the type inference, $T$ is usually omitted. - -This is an example of generating kubernetes manifests. - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = name -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -We can use the KCL code to generate a Kubernetes YAML manifest. - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## How to Choose? - -Communities have been making significant efforts to improve their configuration technologies, which can be categorized into three groups: - -- Low-level data format-based tools that utilize external tools for enhancing reuse and validation, specifically for templating, patching, and validation. -- Domain-Specific Languages (DSLs) and Configuration Languages (CLs), which enhance language abilities. -- General Purpose Language (GPL)-based solutions that utilize Cloud-Development Kit (CDK) or framework to define the configuration. - -To simplify, here are some recommended options: - -- YAML/JSON/Kustomize/Helm are recommended if you need to write structured key-value pairs, or use Kubernetes native tools. -- HCL is recommended if you want to use programming language convenience to remove boilerplate with good human readability, or if you are already a Terraform user. -- CUE is recommended if you want to use type system to improve stability and maintain scalable configurations. -- KCL is recommended if you want types and modeling like a modern language, scalable configurations, in-house pure functions and rules, and production-ready performance and automation. - -### vs. YAML/JSON - -YAML/JSON configurations are suitable for small-scale configuration scenarios. However, if you require frequent modifications in large-scale cloud-native configuration scenarios, KCL is more appropriate. The primary difference between the two is the abstraction of configuration data and deployment. - -The advantages of using KCL for configuration are numerous. First, abstracting one layer for static data provides deployment flexibility, allowing various configuration environments, tenants, and runtime to have distinct requirements for static data. Additionally, different organizations may have different specifications and product requirements. By leveraging KCL, administrators can expose the most important and frequently modified configurations to users. - -### vs. Jsonnet/GCL - -GCL is a declarative configuration programming language implemented in Python, providing necessary language capabilities for template abstraction. However, the compiler itself is written in Python, and the language runs with interpretation, leading to poor performance for large template instances, such as the Kubernetes model. - -On the other hand, Jsonnet is a data template language implemented in C++/Go, suitable for application and tool developers. It can generate configuration data and organize, simplify, and manage large configurations without any side effects. - -Both Jsonnet and GCL are excellent at reducing boilerplate, using code to generate configuration, so engineers can write advanced GPL code instead of manually writing error-prone and difficult-to-understand server binary code. Despite reducing some of the complexities of GCL, Jsonnet largely falls into the same category. Both have runtime errors, insufficient type-checking and constraint capacity. - -### vs. HCL - -HCL is a configuration language implemented in Go that is structured and inspired by the syntax of libucl and nginx configurations. It is designed to be both human and machine-friendly, primarily for use in devops tools, server configurations, and resource configurations as a [Terraform language](https://www.terraform.io/language). - -The user interface of HCL is not readily apparent in the Terraform provider Schema definition and can be cumbersome when defining complex object and required/optional fields. Dynamic parameters are constrained by the condition field of the variable, and resource constraints must be defined either by the provider schema or through the use of Sentinel/Rego and other policy languages. The language itself may not be self-contained. - -### vs. CUE - -CUE can be utilized for modeling through structures without the need for inheritance or other features. This can lead to high abstraction as long as there are no conflicts with model definitions. However, since CUE performs all constraint checks at runtime, there may be performance bottlenecks in large-scale modeling scenarios. Despite this, CUE simplifies constraint writing through various syntax options, eliminating the need for generic types and enumerations. Additionally, configuration merging is supported but is completely idempotent, which may not be suitable for complex multi-tenant and multi-environment configuration scenarios. Writing complex loop and constraint scenarios can be challenging and cumbersome for accurately modifying configurations. - -On the other hand, KCL conducts modeling through the schema and achieves high model abstraction through language-level engineering and some object-oriented features, such as single inheritance. KCL is a statically compiled language with low overhead for large-scale modeling scenarios. Additionally, KCL provides a richer declarative constraint syntax, making it easier to write. Compared to CUE, KCL offers more if guard combination constraints, all/any/map/filter, and other collection constraint writing methods, which simplify configuration field combination constraints. - -### vs. Dhall - -Dhall is a functional, programmable configuration language that incorporates JSON, functions, types and imports. If you have experience with languages like Haskell, you may find Dhall familiar. KCL also offers similar functionality for programmability and abstraction, but has made greater advancements in areas such as modeling, constraint checking, automation and package management for sharing models. KCL's syntax and semantics are more aligned with object-oriented languages, making it more approachable than pure functional styles in some cases. - -### vs. Nickel - -Nickel is the cheap configuration language. Its purpose is to automate the generation of static configuration files and it is in essence JSON with functions and types. - -KCL and Nickel both have a similar gradual type system (static + dynamic), merge strategy, function and constraint definition. The difference is that KCL is a Python-like language, while Nickel is a JSON-like language. In addition, KCL provides the schema keyword to distinguish between configuration definitions and configuration data to avoid mixed use. - -### vs. Starlark - -Starlark is the language of Bazel, which is a dialect of Python. It does not have types and recursion is forbidden. - -KCL can also be regarded as a variant of Python to some extent, but it greatly enhances the design related to static typing and configuration extensibility, and is a compiled language, which is essentially different from Starlark. - -### vs. Kustomize - -The key feature of Kustomize is its ability to overlay files at a granular level. However, it faces challenges with multiple overlay chains as a specific attribute value may not be the final value, as it can be overridden by another value elsewhere. Retrieving the inheritance chain of Kustomize files can be less convenient than retrieving the inheritance chain of KCL code, particularly for complex scenarios where careful consideration of the specified configuration file overwrite order is necessary. Additionally, Kustomize does not address issues related to YAML configuration writing, constraint verification, model abstraction, and development, making it more suited for simpler configuration scenarios. - -In contrast, KCL offers fine-grained configuration merge operations for each attribute in the code, with flexible merge strategy settings that are not limited to overall resources. KCL also allows for static analysis of configuration dependencies through import statements. - -### vs. Helm - -The idea behind Helm can be traced back to the package management system used in operating systems. It is a package management tool that relies on templated YAML files to execute and manage resources within packages. - -KCL provides a greater range of capabilities than Helm, making it a viable alternative. Users who have already adopted Helm can still utilize KCL by packaging the stack compilation results in a Helm format or by using the Helm-KCL plugin to programmatically extend existing Helm charts. - -### vs. CDK - -CDK's high-level language integrates well into application projects, effectively becoming part of the client runtime. In contrast, KCL decouples external configurations and policies written using KCL from the client runtime. - -General-purpose languages can often be over-engineered, going beyond the requirements of the problem being solved. These languages can also present various security issues, such as problems with the ability boundary, such as accessing I/O, network, code infinite looping, and other security risks. In specialized fields, such as music, there are special notes used to communicate effectively, which cannot be expressed clearly in general-purpose languages. - -Furthermore, general-purpose languages come in a variety of styles, which can create challenges in terms of unified maintenance, management, and automation. These languages are generally better suited to writing the client runtime, which is a continuation of the server runtime. They are not ideal for writing configurations that are independent of the runtime, as they are compiled into binaries and started from the process, making stability and scalability challenging to control. In contrast, configuration languages are often used to write data combined with simple logic, and they describe the expected final result, which is then consumed by the compiler or engine. - -### vs. OPA/Rego - -While not originally intended as a data definition language, Rego, the language used for Open Policy Agent (OPA), can also address the issue of adding constraints from multiple sources. - -Rego has its roots in logic programming and is based on Datalog, a restricted form of Prolog. In contrast, KCL is based on a static type structure. Typed-feature structures were developed to address the limitations of Prolog in encoding human languages. Using a Datalog variant for a constraint validation task may seem unusual. Datalog excels as a query language, but it can be cumbersome for constraint enforcement, in that values must be queried before applying constraints. - -KCL's approach to constraint validation is more conducive to finding normalized and simplified representations of constraints, making it well-suited for creating structures generated from OpenAPI. diff --git a/versioned_docs/version-0.5.3/user_docs/guides/_working-with-terraform/1-overview.md b/versioned_docs/version-0.5.3/user_docs/guides/_working-with-terraform/1-overview.md deleted file mode 100644 index c2ec836d..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/_working-with-terraform/1-overview.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -id: overview -sidebar_label: Overview ---- - -# Overview - -Coming Soon diff --git a/versioned_docs/version-0.5.3/user_docs/guides/_working-with-terraform/2-abstraction.md b/versioned_docs/version-0.5.3/user_docs/guides/_working-with-terraform/2-abstraction.md deleted file mode 100644 index 18a25571..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/_working-with-terraform/2-abstraction.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -id: abstraction -sidebar_label: Abstraction ---- - -# Abstract Your Terraform Modules - -Coming Soon diff --git a/versioned_docs/version-0.5.3/user_docs/guides/_working-with-terraform/3-coverter.md b/versioned_docs/version-0.5.3/user_docs/guides/_working-with-terraform/3-coverter.md deleted file mode 100644 index 1dc975bb..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/_working-with-terraform/3-coverter.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -id: converter -sidebar_label: Converter ---- - -# Convert Your Terraform Provider Schema to KCL Schema - -Coming Soon diff --git a/versioned_docs/version-0.5.3/user_docs/guides/_working-with-terraform/_category_.json b/versioned_docs/version-0.5.3/user_docs/guides/_working-with-terraform/_category_.json deleted file mode 100644 index 3e72e820..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/_working-with-terraform/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Terraform", - "position": 13 -} diff --git a/versioned_docs/version-0.5.3/user_docs/guides/ci-integration/_3-jenkins-ci.md b/versioned_docs/version-0.5.3/user_docs/guides/ci-integration/_3-jenkins-ci.md deleted file mode 100644 index f85d231f..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/ci-integration/_3-jenkins-ci.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -id: github-ci -sidebar_label: Github CI ---- - -Coming Soon - -## Introduction - -## How to - -## Summary diff --git a/versioned_docs/version-0.5.3/user_docs/guides/ci-integration/_category_.json b/versioned_docs/version-0.5.3/user_docs/guides/ci-integration/_category_.json deleted file mode 100644 index 3145ed7f..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/ci-integration/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "CI Integration", - "position": 12 -} \ No newline at end of file diff --git a/versioned_docs/version-0.5.3/user_docs/guides/gitops/_category_.json b/versioned_docs/version-0.5.3/user_docs/guides/gitops/_category_.json deleted file mode 100644 index 29a73c67..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/gitops/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "GitOps", - "position": 11 -} \ No newline at end of file diff --git a/versioned_docs/version-0.5.3/user_docs/guides/index.md b/versioned_docs/version-0.5.3/user_docs/guides/index.md deleted file mode 100644 index cd3d4522..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/index.md +++ /dev/null @@ -1 +0,0 @@ -# User Guide diff --git a/versioned_docs/version-0.5.3/user_docs/guides/package-management/1-overview.md b/versioned_docs/version-0.5.3/user_docs/guides/package-management/1-overview.md deleted file mode 100644 index cffccc67..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/package-management/1-overview.md +++ /dev/null @@ -1,3 +0,0 @@ -# Overview - -KCL manages packages through the package management tool [kpm](https://github.com/kcl-lang/kpm). diff --git a/versioned_docs/version-0.5.3/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md b/versioned_docs/version-0.5.3/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md deleted file mode 100644 index aa9c119d..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md +++ /dev/null @@ -1,73 +0,0 @@ -# Share Your Package - -[kpm](https://github.com/kcl-lang/kpm) is a tool for managing kcl packages. This article will guide you on how to use kpm to push your kcl package to an OCI Registry for publication. kpm uses [ghcr.io](https://ghcr.io) as the default OCI Registry, and you can change the default OCI Registry by modifying the kpm configuration file. For information on how to modify the kpm configuration file, see [kpm oci registry](https://github.com/kcl-lang/kpm/blob/main/docs/kpm_oci.md#kpm-registry) - -Here is a simple step-by-step guide on how to use kpm to push your kcl package to ghcr.io. - -## Step 1: Install kpm - -First, you need to install kpm on your computer. You can follow the instructions in the [kpm installation documentation](https://kcl-lang.io/docs/user_docs/guides/package-management/installation). - -## Step 2: Create a ghcr.io token - -If you are using the default OCI Registry of kpm, to push a kcl package to ghcr.io, you need to create a token for authentication. You can follow the instruction. - -- [Creating a ghcr.io access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic) - -## Step 3: Log in to ghcr.io - -After installing kpm and creating a ghcr.io token, you need to log in to ghcr.io using kpm. You can do this using the following command: - -```shell -kpm login ghcr.io -u -p -``` - -Where `` is your GitHub username, `` is the token you created in step 2 - -For more information on how to log in to ghcr.io using kpm, see [kpm login](https://kcl-lang.io/docs/reference/package-management/command-reference/login). - -## Step 4: Push your kcl package - -Now, you can use kpm to push your kcl package to ghcr.io. - -### 1. A valid kcl package - -First, you need to make sure that what you are pushing conforms to the specifications of a kcl package, i.e., it must contain valid kcl.mod and kcl.mod.lock files. - -If you don't know how to get a valid kcl.mod and kcl.mod.lock, you can use the `kpm init` command. - -```shell -# Create a new kcl package named my_package -kpm init my_package -``` - -The `kpm init my_package` command will create a new kcl package `my_package` for you and create the `kcl.mod` and `kcl.mod.lock` files for this package. - -If you already have a directory containing kcl files `exist_kcl_package`, you can use the following command to convert it into a kcl package and create valid `kcl.mod` and `kcl.mod.lock` files for it. - -```shell -# In the exist_kcl_package directory -$ pwd -/home/user/exist_kcl_package - -# Run the `kpm init` command to create the `kcl.mod` and `kcl.mod.lock` files -$ kpm init -``` - -For more information on how to use `kpm init`, see [kpm init](https://kcl-lang.io/docs/reference/package-management/command-reference/init). - -### 2. Pushing the KCL Package - -You can use the following command in the root directory of your `kcl` package: - -```shell -# In the root directory of the exist_kcl_package package -$ pwd -/home/user/exist_kcl_package - -# Pushing the KCL Package to Default OCI Registry -$ kpm push -``` - -After completing these steps, you have successfully pushed your KCL Package to the default OCI Registry. -For more information on how to use `kpm push`, see [kpm push](https://kcl-lang.io/docs/reference/package-management/command-reference/push). diff --git a/versioned_docs/version-0.5.3/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md b/versioned_docs/version-0.5.3/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md deleted file mode 100644 index 3fa5aabe..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md +++ /dev/null @@ -1,66 +0,0 @@ -# Share Your Package to docker.io - -[kpm](https://github.com/KusionStack/kpm) is a tool for managing kcl packages. This article will show you how to use kpm to push your kcl packages to docker.io. - -Here is a simple step-by-step guide on how to use kpm to push your kcl package to docker.io. - -## Step 1: Install kpm - -First, you need to install kpm on your computer. You can follow the instructions in the [kpm installation documentation](https://kcl-lang.io/docs/user_docs/guides/package-management/installation). - -## Step 2: Create a docker.io account - -If you want to use `docker.io` as the OCI registry to share your kcl package with others, you need to create a `docker.io` account to support the push of your kcl package. - -## Step 3: Log in to docker.io - -You can use the following command to log in to docker.io. - -```shell -kpm login -u -p docker.io -``` - -Where `` is your `docker.io` username, and `` is your `docker.io` password. - -For more information on how to log in to docker.io using kpm, see [kpm login](https://kcl-lang.io/docs/reference/package-management/command-reference/login). - -## Step 4: Push your kcl package - -Now, you can use kpm to push your kcl package to `docker.io`. - -### 1. A valid kcl package - -First, you need to make sure that what you are pushing conforms to the specifications of a kcl package, i.e., it must contain valid kcl.mod and kcl.mod.lock files. - -If you don't know how to get a valid kcl.mod and kcl.mod.lock, you can use the `kpm init` command. - -Create a new kcl package named `my_package`. - -```shell -kpm init my_package -``` - -The `kpm init my_package` command will create a new kcl package `my_package` for you and create the `kcl.mod` and `kcl.mod.lock` files for this package. - -If you already have a directory containing kcl files `exist_kcl_package`, you can use the following command to convert it into a kcl package and create valid `kcl.mod` and `kcl.mod.lock` files for it. - -Run the `kpm init` command under the `exist_kcl_package` directory. - -```shell -kpm init -``` - -For more information on how to use `kpm init`, see [kpm init](https://kcl-lang.io/docs/reference/package-management/command-reference/init). - -### 2. Pushing the KCL Package - -You can use the following command in the root directory of your `kcl` package: - -Run the `kpm push` command under the `exist_kcl_package` directory. - -```shell -kpm push oci://docker.io//exist_kcl_package -``` - -After completing these steps, you have successfully pushed your KCL Package `exist_kcl_package` to `docker.io`. -For more information on how to use `kpm push`, see [kpm push](https://kcl-lang.io/docs/reference/package-management/command-reference/push). diff --git a/versioned_docs/version-0.5.3/user_docs/guides/package-management/4-how-to/6-push_github_action.md b/versioned_docs/version-0.5.3/user_docs/guides/package-management/4-how-to/6-push_github_action.md deleted file mode 100644 index de88dbcf..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/package-management/4-how-to/6-push_github_action.md +++ /dev/null @@ -1,81 +0,0 @@ -# Push Your KCL Package by GitHub Action - -[kpm](https://github.com/KusionStack/kpm) is a tool for managing kcl packages. This article will guide you how to use kpm in GitHub Action to push your kcl package to OCI registry. - -## Step 1: Install kpm - -At first, you need to install kpm on your computer. You can follow [kpm installation document](https://kcl-lang.io/docs/user_docs/guides/package-management/installation). - -## Step 2: Create a GitHub account - -If you already have a GitHub account, you can skip this step. - -[Sign up for a new GitHub account](https://docs.github.com/en/get-started/signing-up-for-github/signing-up-for-a-new-github-account) - -## Step 3: Create a GitHub repository for your KCL package - -### 1. Prepare a GitHub repository for your KCL package - -You need to prepare a GitHub repository for your KCL package. - -[Create a GitHub repository](https://docs.github.com/en/get-started/quickstart/create-a-repo) - -In this repository, add your KCL program, take the repository https://github.com/awesome-kusion/catalog.git as an example, - -```bash -├── .github -│ └── workflows -│ └── push.yaml # github action workflow -├── LICENSE -├── README.md -├── kcl.mod # kcl.mod to define your kcl package -├── kcl.mod.lock # kcl.mod.lock generated by kpm -└── main.k # Your KCL program -``` - -### 2. Set OCI Registry, account and password for your Github repository - -Take docker.io as an example, you can set secrets `REG`, `REG_ACCOUNT` and `REG_TOKEN` for your repository. The value of `REG` is `docker.io`, the value of `REG_ACCOUNT` is your `docker.io` account, and the value of `REG_TOKEN` is your `docker.io` login password. - -[Add secrets to the repository](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) - -If you use `ghcr.io` as `Registry`, you need to use GitHub token as secrets. - -[Create a GitHub Token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token#personal-access-tokens-classic) - -## Step 4: Add your KCL package to the repository and write github action workflow - -Add github action file `.github/workflows/push.yml` to this repository, the content is as follows: - -```yaml -name: KPM Push Workflow - -on: - push: - branches: - - main - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Set up Go 1.21 - uses: actions/setup-go@v2 - with: - go-version: 1.21 - - - name: Install kpm - run: go install kcl-lang.io/kpm@latest - - - name: Login and Push - env: - KPM_REG: ${{ secrets.REG }} - KPM_REPO: ${{ secrets.REG_ACCOUNT }} - run: kpm login -u ${{ secrets.REG_ACCOUNT }} -p ${{ secrets.REG_TOKEN }} ${{ secrets.REG }} && kpm push - - - name: Run kpm project from oci registry - run: kpm run oci://${{ secrets.REG }}/${{ secrets.REG_ACCOUNT }}/catalog --tag 0.0.1 -``` diff --git a/versioned_docs/version-0.5.3/user_docs/guides/package-management/4-how-to/_category_.json b/versioned_docs/version-0.5.3/user_docs/guides/package-management/4-how-to/_category_.json deleted file mode 100644 index e3409c62..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/package-management/4-how-to/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "How to", - "position": 4 -} diff --git a/versioned_docs/version-0.5.3/user_docs/guides/secret-management/_category_.json b/versioned_docs/version-0.5.3/user_docs/guides/secret-management/_category_.json deleted file mode 100644 index c57bb30e..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/secret-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Secret Management", - "position": 13 -} diff --git a/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md b/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md deleted file mode 100644 index ac20cd12..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: "Adopt From Kubernetes" -sidebar_position: 1 ---- - -## Introduction - -KCL provides many out of the box support for Kubernetes configuration. Through KCL tools, we can integrate Kubernetes Schema and configuration into KCL. This section will introduce how to use KCL to integrate Kubernetes. - -## Prerequisite - -- Install kcl-openapi - -## Quick Start - -### 1. Kubernetes OpenAPI Spec - -Starting from Kubernetes 1.4, the alpha support for the OpenAPI specification (known as Swagger 2.0 before it was donated to the OpenAPI Initiative) was introduced, and the API descriptions follow the [OpenAPI Spec 2.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md). And since Kubernetes 1.5, Kubernetes supports [directly extracting models from source code and then generating the OpenAPI spec file](https://github.com/kubernetes/kube-openapi) to automatically keep the specifications and documents up to date with the operation and models. - -In addition, Kubernetes CRD uses [OpenAPI V3.0 validation](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation) to describe a custom schema (in addition to the built-in attributes apiVersion, Kind, and metadata), that APIServer uses to validate the CR during the resource creation and update phases. - -### 2. KCL OpenAPI Support - -The `kcl-openapi` tool supports extracting and generating KCL schemas from Kubernetes OpenAPI/CRD. the [KCL OpenAPI Spec](/docs/tools/cli/openapi/spec) defines the mapping between the OpenAPI specification and the KCL language features. - -### 3. Migrate From Kubernetes To KCL - -#### 3.1 Write configurations based on the Kusion_Models package - -``We provide an out-of-the-box `kusion_models` package for you to quickly start. It contains a well-designed frontend model called [`Server schema`](https://github.com/KusionStack/konfig/blob/main/base/pkg/kusion_models/kube/frontend/server.k). You can declare the configurations by initializing the `Server schema`. For the description and usage of the schema and its attributes, please refer to the [Server schema documentation](https://kusionstack.io/docs/reference/model/kusion_models/kube/frontend/doc_server).`` - -#### 3.2 Build Your Custom Frontend Models - -The existing KCL Models may not meet your specific business requirements, then you can also design your custom frontend model package. You can design your custom models based on the pre-generated Kubernetes KCL models among all versions. - -##### 3.2.1 Get the k8s package - -The [Kubernetes KCL models](https://github.com/orgs/KusionStack/packages/container/package/k8s) among all versions are pre-generated, you get it by executing `kpm add k8s:` under your project. For detailed information about kpm usage, please refer to [kpm quick start guide](https://github.com/kcl-lang/kpm#quick-start). - -Alternatively, if you may want to generate them yourself, please refer to [Generate KCL Packages from Kubernetes OpenAPI Specs](https://github.com/kcl-lang/kcl-openapi/blob/main/docs/generate_from_k8s_spec.md). - -##### 3.2.2 Design Custom Frontend Models - -Since the Kubernetes built-in models are atomistic and kind of complex to beginners, we recommend taking the native model of Kubernetes as the backend output model and designing a batch of frontend models which could become a more abstract, friendlier and simpler interface to the user. You can refer to the design pattern in the [`Server Schema in the Konfig repo`](https://github.com/KusionStack/konfig/blob/main/base/pkg/kusion_models/kube/frontend/server.k). - -##### 3.2.3 Migrate The Configuration Data - -You can develop your custom scripts to migrate your configuration data automatically. KCL will later provide writing scaffolding and writing guidelines for this script. - -### 4. Migrate From Kubernetes CRD - -If you developed CRDs, you can generate the KCL version of the CRD schemas and declare CRs based on that. - -- Generate KCL Schema from CRD - - ``` - kcl-openapi generate model --crd --skip-validation -f - ``` - -- Define CR based on CRDs in KCL - - You can initialize the CRD schema to define a CR, or further, you can use the generated schema as a backend model and design a frontend interface for users to initialize. The practice is similar to what `KCL Models` does on Kubernetes built-in models. - -## Summary - -This section provides a quick start guide for using KCL with OpenAPI and Custom Resource Definitions (CRD). KCL also supports OpenAPI through the `kcl-openapi tool`, which maps OpenAPI specifications to KCL language features. diff --git a/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md b/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md deleted file mode 100644 index ea65e2f1..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md +++ /dev/null @@ -1,249 +0,0 @@ ---- -title: "Generate Kubernetes Manifests" -sidebar_position: 2 ---- - -## Introduction - -When we manage the Kubernetes resources, we often maintain it by hand, or use Helm and Kustomize tools to maintain our YAML configurations or configuration templates, and then apply the resources to the cluster through kubectl tools. However, as a "YAML engineer", maintaining YAML configuration every day is undoubtedly trivial and boring, and prone to errors. For example as follows: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: ... # Omit -spec: - selector: - matchlabels: - cell: RZ00A - replicas: 2 - template: - metadata: ... # Omit - spec: - tolerations: - - effect: NoSchedules - key: is-over-quota - operator: Equal - value: 'true' - containers: - - name: test-app - image: images.example/app:v1 # Wrong ident - resources: - limits: - cpu: 2 # Wrong type. The type of cpu should be str - memory: 4Gi - # Field missing: ephemeral-storage - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: is-over-quota - operator: In - values: - - 'true' -``` - -- The structured data in YAML is untyped and lacks validation methods, so the validity of all data cannot be checked immediately. -- YAML has poor programming ability. It is easy to write incorrect indents and has no common code organization methods such as logical judgment. It is easy to write a large number of repeated configurations and difficult to maintain. -- The design of Kubernetes is complex, and it is difficult for users to understand all the details, such as the `toleration` and `affinity` fields in the above configuration. If users do not understand the scheduling logic, it may be wrongly omitted or superfluous added. - -Therefore, KCL expects to solve the following problems in Kubernetes YAML resource management: - -- Use **production level high-performance programming language** to **write code** to improve the flexibility of configuration, such as conditional statements, loops, functions, package management and other features to improve the ability of configuration reuse. -- Improve the ability of **configuration semantic verification** at the code level, such as optional/required fields, types, ranges, and other configuration checks. -- Provide **the ability to write, combine and abstract configuration blocks**, such as structure definition, structure inheritance, constraint definition, etc. - -## Prerequisite - -First, you can visit the [KCL Quick Start](/docs/user_docs/getting-started/kcl-quick-start) to download and install KCL according to the instructions, and then prepare a [Kubernetes](https://kubernetes.io/) environment. - -## Quick Start - -### 1. Generate Kubernetes Resource - -We can write the following KCL code and name it `main.k`. KCL is inspired by Python. Its basic syntax is very close to Python, which is easy to learn. The configuration mode is simple, `k [: T] = v`, where `k` denotes the configured attribute name, `v` denotes the configured attribute value and `: T` denotes an optional type annotation. - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -In the above KCL code, we declare the `apiVersion`, `kind`, `metadata`, `spec` and other variables of a Kubernetes `Deployment` resource, and assign the corresponding contents respectively. In particular, we will assign `metadata.labels` fields are reused in `spec.selector.matchLabels` and `spec.template.metadata.labels` field. It can be seen that, compared with YAML, the data structure defined by KCL is more compact, and configuration reuse can be realized by defining local variables. - -We can get a Kubernetes YAML file by executing the following command line - -```bash -kcl main.k -``` - -The output is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -Of course, we can use KCL together with kubectl and other tools. Let's execute the following commands and see the result: - -```shell -kcl main.k | kubectl apply -f - -``` - -The output is - -```shell -deployment.apps/nginx-deployment configured -``` - -It can be seen from the command line that it is completely consistent with the deployment experience of using YAML configuration and kubectl application directly. - -Check the deployment status through kubectl - -```shell -kubectl get deploy -``` - -The output is - -```shell -NAME READY UP-TO-DATE AVAILABLE AGE -nginx-deployment 3/3 3 3 15s -``` - -### 2. Write Code to Manage Kubernetes resources - -When publishing Kubernetes resources, we often encounter scenarios where configuration parameters need to be dynamically specified. For example, different environments need to set different `image` field values to generate resources in different environments. For this scenario, we can dynamically receive external parameters through KCL conditional statements and `option` functions. Based on the above example, we can adjust the configuration parameters according to different environments. For example, for the following code, we wrote a conditional statement and entered a dynamic parameter named `env`. - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" if option("env") == "prod" else "${metadata.name}:latest" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -Use the KCL command line `-D` flag to receive an external dynamic parameter: - -```bash -kcl main.k -D env=prod -``` - -The output is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -The `image=metadata.name+": 1.14.2" if option ("env")=="prod" else metadata.name + ": latest"` in the above code snippet means that when the value of the dynamic parameter `env` is set to `prod`, the value of the image field is `nginx: 1.14.2`; otherwise, it is' nginx: latest'. Therefore, we can set env to different values as required to obtain Kubernetes resources with different contents. - -KCL also supports maintaining the dynamic parameters of the option function in the configuration file, such as writing the `kcl.yaml` file. - -```yaml -kcl_options: - - key: env - value: prod -``` - -The same YAML output can be obtained by using the following command line to simplify the input process of KCL dynamic parameters. - -```bash -kcl main.k -Y kcl.yaml -``` - -The output is: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## Summary - -KCL can be used to generate and manage Kubernetes resources, addressing the limitations of managing YAML configurations, such as a lack of validation methods and poor programming capabilities. It can also dynamically receive external parameters through conditional statements and option functions, allowing configuration parameters to be adjusted according to different environments. In addition, KCL can be used in conjunction with other tools such as kubectl to apply configuration to the cluster. diff --git a/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md b/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md deleted file mode 100644 index 17918b29..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: "Kubectl KCL Plugin" -sidebar_position: 1 ---- - -## Introduction - -[Kubectl](https://kubernetes.io/docs/reference/kubectl/) is a command line tool for communicating with a Kubernetes cluster's control plane, using the Kubernetes API. You can use the `Kubectl-KCL-Plugin` to - -- Edit the YAML configuration in a hook way to separate data and logic for the Kubernetes manifests management. -- For multi-environment and multi-tenant scenarios, you can maintain these configurations gracefully rather than simply copy and paste. -- Validate all KRM resources using the KCL schema. - -## Prerequisites - -- Install [Kubectl](https://github.com/kubernetes/kubectl) -- Install [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=krm-kcl` only to `Deployment` resources in the helm chart. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/kubectl-kcl.git/ -cd ./kubectl-kcl/examples/ -``` - -### 2. Test and Run - -Run the KCL code via the `Kubectl KCL Plugin`. - -```bash -kubectl kcl run -f ./kcl-run.yaml -``` - -The output yaml is - -```yaml -apiVersion: config.kubernetes.io/v1 -kind: ResourceList -items: - - apiVersion: apps/v1 - kind: Deployment - metadata: - annotations: - managed-by: krm-kcl - labels: - app: nginx - name: nginx-deployment - spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - image: "nginx:1.14.2" - name: nginx - ports: - - containerPort: 80 - - apiVersion: v1 - kind: Service - metadata: - name: test - spec: - ports: - - port: 80 - protocol: TCP - targetPort: 9376 - selector: - app: MyApp -functionConfig: - # kcl-fn-config.yaml - apiVersion: krm.kcl.dev/v1alpha1 - kind: KCLRun - metadata: - # EDIT THE SOURCE! - # This should be your KCL code which preloads the `ResourceList` to `option("resource_list") - spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "krm-kcl"}} for resource in option("resource_list").items] -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) diff --git a/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md b/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md deleted file mode 100644 index 01897f37..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: "Helm KCL Plugin" -sidebar_position: 2 ---- - -## Introduction - -[Helm](https://github.com/helm/helm) is a tool for managing Charts. Charts are packages of pre-configured Kubernetes resources. You can use the `Helm-KCL-Plugin` to - -- Edit the helm charts in a hook way to separate data and logic for the Kubernetes manifests management. -- For multi-environment and multi-tenant scenarios, you can maintain these configurations gracefully rather than simply copy and paste. -- Validate all KRM resources using the KCL schema. - -## Prerequisites - -- Install [Helm](https://github.com/helm/helm) -- Install [Helm KCL Plugin](https://github.com/kcl-lang/helm-kcl) - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=helm-kcl-plugin` only to `Deployment` resources in the helm chart. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/helm-kcl.git/ -cd ./helm-kcl/examples/workload-charts-with-kcl -``` - -### 2. Test and Run - -Run the KCL code via the `Helm KCL Plugin`. - -```bash -helm kcl template --file ./kcl-run.yaml -``` - -The output yaml is - -```yaml -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: workload - app.kubernetes.io/version: 0.1.0 - helm.sh/chart: workload-0.1.0 - name: workload -spec: - ports: - - name: www - port: 80 - protocol: TCP - targetPort: 80 - selector: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - type: ClusterIP ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: workload - app.kubernetes.io/version: 0.1.0 - helm.sh/chart: workload-0.1.0 - name: workload - annotations: - managed-by: helm-kcl-plugin -spec: - selector: - matchLabels: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - template: - metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - spec: - containers: - - image: nginx:alpine - name: frontend -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Helm KCL Plugin](https://github.com/kcl-lang/helm-kcl) diff --git a/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md b/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md deleted file mode 100644 index 3a029bdd..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: "KPT KCL SDK" -sidebar_position: 4 ---- - -## Introduction - -[kpt](https://github.com/GoogleContainerTools/kpt) is a package-centric toolchain that enables a configuration authoring, automation, and delivery experience, which simplifies managing Kubernetes platforms and KRM-driven infrastructure (e.g., Config Connector, Crossplane) at scale by manipulating declarative Configuration as Data for automating Kubernetes configuration editing including transforming and validating. - -KCL can be used to create functions to transform and/or validate the YAML Kubernetes Resource Model (KRM) input/output format, but we provide KPT KCL SDKs to simplify the function authoring process. - -## Prerequisites - -- Install [kpt](https://github.com/GoogleContainerTools/kpt) -- Install [Docker](https://www.docker.com/) - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=kpt` only to Deployment resources. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/kpt-kcl-sdk.git/ -cd ./kpt-kcl-sdk/get-started/set-annotation -``` - -### 2. Show the KRM - -```bash -kpt pkg tree -``` - -The output is - -```bash -set-annotation -├── [kcl-fn-config.yaml] KCLRun set-annotation -└── data - ├── [resources.yaml] Deployment nginx-deployment - └── [resources.yaml] Service test -``` - -### 3. Show and Update the KCL `FunctionConfig` - -```bash -cat ./kcl-fn-config.yaml -``` - -The output is - -```yaml -# kcl-fn-config.yaml -apiVersion: krm.kcl.dev/v1alpha1 -kind: KCLRun -metadata: # kpt-merge: /set-annotation - name: set-annotation -spec: - # EDIT THE SOURCE! - # This should be your KCL code which preloads the `ResourceList` to `option("resource_list")` - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "kpt"}} for resource in option("resource_list").items] -``` - -### 4. Test and Run - -Run the KCL code via kpt - -```bash -kpt fn eval ./data -i docker.io/kcllang/kpt-kcl:v0.2.0 --fn-config kcl-fn-config.yaml - -# Verify that the annotation is added to the `Deployment` resource and the other resource `Service` -# does not have this annotation. -cat ./data/resources.yaml | grep annotations -A1 -B0 -``` - -The output is - -```bash - annotations: - managed-by: kpt -``` - -It can be seen that we have indeed added the annotation `managed-by=kpt`. - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [KPT KCL SDK](https://github.com/kcl-lang/kpt-kcl-sdk) diff --git a/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md b/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md deleted file mode 100644 index 3f3ec2a5..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: "Helmfile KCL Plugin" -sidebar_position: 5 ---- - -## Introduction - -[Helmfile](https://github.com/helmfile/helmfile) is a declarative spec for deploying helm charts. It lets you... - -- Keep a directory of chart value files and maintain changes in version control. -- Apply CI/CD to configuration changes. -- Periodically sync to avoid skew in environments. - -KCL can be used to create functions to mutate and/or validate the YAML Kubernetes Resource Model (KRM) input/output format, and we provide Kustomize KCL functions to simplify the function authoring process. - -## Prerequisites - -- Install [helmfile](https://github.com/helmfile/helmfile) -- Prepare a Kubernetes cluster - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=helmfile-kcl` only to Deployment resources. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/helmfile-kcl.git -cd ./helmfile-kcl/examples/hello-world/ -``` - -We can execute the command to show config - -```bash -cat helmfile.yaml -``` - -The output is - -```yaml -repositories: - - name: prometheus-community - url: https://prometheus-community.github.io/helm-charts - -releases: - - name: prom-norbac-ubuntu - namespace: prometheus - chart: prometheus-community/prometheus - set: - - name: rbac.create - value: false - transformers: - # Use KCL Plugin to mutate or validate Kubernetes manifests. - - apiVersion: krm.kcl.dev/v1alpha1 - kind: KCLRun - metadata: - name: "set-annotation" - annotations: - config.kubernetes.io/function: | - container: - image: docker.io/kcllang/kustomize-kcl:v0.2.0 - spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "helmfile-kcl"}} for resource in option("resource_list").items] -``` - -In the above config, we use a `KCLRun` plugin to assign the `transfomer` field. This means that we will add annotations to all deployment resources in the prometheus helm chart. - -### 2. Test and Run - -Firstly, init the helmfile tool. - -```bash -helmfile init -``` - -The output may looks like this: - -```bash -The helm plugin helm-git is not installed, do you need to install it [y/n]: y -Install helm plugin helm-git -Installed plugin: helm-git - -helmfile initialization completed! -... -``` - -Then apply the configuration. - -```bash -helmfile apply -``` - -The output is - -```bash -Adding repo prometheus-community https://prometheus-community.github.io/helm-charts -"prometheus-community" has been added to your repositories - -... -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Kustomize KCL Plugin](https://github.com/kcl-lang/kustomize-kcl) diff --git a/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json b/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json deleted file mode 100644 index 6e90c03c..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Mutate or Validate Kubernetes Manifests", - "position": 3 -} diff --git a/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/_category_.json b/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/_category_.json deleted file mode 100644 index 42681f2b..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Kubernetes", - "position": 9 -} diff --git a/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/index.md b/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/index.md deleted file mode 100644 index 8d6340de..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/index.md +++ /dev/null @@ -1 +0,0 @@ -# Kubernetes diff --git a/versioned_docs/version-0.5.3/user_docs/guides/working-with-konfig/1-overview.md b/versioned_docs/version-0.5.3/user_docs/guides/working-with-konfig/1-overview.md deleted file mode 100644 index aca119a1..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/working-with-konfig/1-overview.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -id: overview -sidebar_label: Overview ---- - -# Konfig Overview - -In KCL, it is recommended to uniformly manage all configurations and model libraries in the way of **configuration library**, that is, to store not only KCL definitions of the abstract model itself, but also various types of configurations, such as application operation and maintenance configuration, policy, etc. The configuration is recommended to be hosted in various VCS systems to facilitate configuration rollback and drift check. The best practice code of the configuration repository is Konfig, and the repository is hosted in [Github](https://github.com/KusionStack/konfig)。 - -⚡ The Konfig repository mainly includes: - -- KCL module declaration file (kcl.mod) -- KCL domain model libraries (Kubernetes, Prometheus, etc.) -- Directories of various configurations (application operation and maintenance configuration, etc) -- Configuration build and test scripts (Makefile, Github CI file, etc.) - -The reason for using a unified warehouse to manage all KCL configuration codes is that different code packages have different R&D entities, which will lead to package management and version management problems. When the business configuration code and basic configuration code are stored in a unified warehouse, the version dependency management between codes will be relatively simple. By locating the directory and file of the unique code base, the configuration code can be managed uniformly for easy search, modification and maintenance. - -The following is the architecture of Konfig: - -![](/img/docs/user_docs/guides/konfig/konfig-arch.png) - -Konfig provides users with an out-of-the-box and highly abstract configuration interface. The original simple starting point of the model library is to improve the efficiency and experience of Kubernetes YAML users. We hope to simplify the writing of user-side configuration code by abstracting and encapsulating the model with more complex code into a unified model. Konfig consists of the following parts: - -- **Core model**: - - **Front-end model**: The front-end model is the "user interface", which contains all configurable attributes exposed to users on the platform side. Some repetitive and deducible configurations are omitted, and essential attributes are abstracted and exposed to users. It has user-friendly features, such as `server.k`. - - **Back-end model**: The back-end model is "model implementation", which is the model that makes the properties of the front-end model effective. It mainly contains the rendering logic of the front-end model instance. The back-end model can use KCL to write validation, logic judgment, code fragment reuse and other code to improve the reusability and robustness of the configuration code, and is not sensitive to users, such as `server_backend.k`. -- **Domain model**: It is a model that does not contain any implementation logic and abstraction. It is often generated by tool transformation and does not need to be modified. It corresponds to the real effective YAML attribute one by one. The domain model needs to be further abstracted and is generally not directly used by users. For example, `kusion_kubernetes` is the domain model library of Kubernetes scenarios. - -In addition, the core model simplifies the configuration code of front-end users through two layers of abstraction: the front-end model and the back-end model. The domain model is automatically generated through the KCL OpenAPI. diff --git a/versioned_docs/version-0.5.3/user_docs/guides/working-with-konfig/2-structure.md b/versioned_docs/version-0.5.3/user_docs/guides/working-with-konfig/2-structure.md deleted file mode 100644 index 64e74b1d..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/working-with-konfig/2-structure.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -id: structure -sidebar_label: Structure ---- - -# Konfig Structure - -This article mainly explains the directory and code structure of the Konfig repository. - -## Overview - -```bash -. -├── .github # CI Scripts -├── Makefile # Building and testing scripts -├── README.md # Documents -├── appops # Application configuration. This folder is used to place KCL operation and maintenance configuration of all applications -│ ├── clickhouse-operator -│ ├── code-city -│ ├── guestbook -│ ├── http-echo -│ └── nginx-example -├── base # Models -│ ├── examples # Examples -│ │ ├── monitoring # Monitoring example -│ │ ├── native # Kubernetes resource example -│ │ ├── provider # Basic resource configuration example such as Terraform resource -│ │ └── server # Server example. -│ └── pkg -│ ├── kusion_kubernetes # Kubernetes domain models -│ ├── kusion_models # Core models -│ ├── kusion_prometheus # Prometheus domain models -│ └── kusion_provider # Basic resource models such as Terraform resource -└── kcl.mod # The KCL module declaration file -``` - -## Core Model - -The core model library is generally named `kusion_models`, mainly including front-end model, back-end model, renderer, etc. The directory structure is: - -```bash -├── commons # Common models -├── kube # Cloud-native resource core models -│ ├── backend # Back-end models -│ ├── frontend # Front-end models -│ │ ├── common # Common front-end models -│ │ ├── configmap # ConfigMap -│ │ ├── container # Container -│ │ ├── ingress # Ingress -│ │ ├── resource # Resource -│ │ ├── secret # Secret -│ │ ├── service # Service -│ │ ├── sidecar # Sidecar -│ │ ├── strategy # strategy -│ │ ├── volume # Volume -│ │ └── server.k # The `Server` model -│ ├── metadata # Kubernetes metadata -│ ├── mixins # Mixin -│ ├── render # Front-to-back-end renderers. -│ ├── templates # Data template -│ └── utils -└── metadata # Common metadata -``` - -## Project and Stack - -![](/img/docs/user_docs/concepts/project-stack.png) - -Project and Stack are logical isolation concepts used to organize the Konfig. - -### Project - -Any folder that contains the file `project.yaml` will be regarded as a Project, and the `project.yaml` is used to describe the metadata of this Project like `name` and `tenant`. Projects must have clear business semantics and must belong to a tenant. Users can map an application or an operation scenario to a Project. - -### Stack - -Like Project, any folder that contains the file `stack.yaml` will be regarded as a Stack and `stack.yaml` is used to describe the metadata of this Stack. Stack is a set of `.k` files that represents the smallest operation unit that can be configured and deployed individually. It tends to represent different stages in the CI/CD process, such as dev, gray, prod, etc. - -### Relationship between Project and Stack - -A Project contains one or more Stacks, and a Stack must belong to and can only belong to one Project. Users can interpret the meaning of Project and Stack according to their own needs and flexibly organize the Konfig structure. We provide the following example as a best practice according to our experiences: - -```bash -appops/nginx-example -├── README.md # Project readme -├── base # common configurations for all stacks -│ └── base.k -├── dev # dev stack -│ ├── ci-test # CI test configs -│ │ ├── settings.yaml # test data -│ │ └── stdout.golden.yaml # expected test result -│ ├── kcl.yaml # kcl config -│ ├── main.k -│ └── stack.yaml # Stack metadata -└── project.yaml # Project metadata -``` - -The Project represents an application and Stack represents different environments of this application, such as dev, pre, prod, etc. Common configurations can be stored in a `base` directory under this Project. diff --git a/versioned_docs/version-0.5.3/user_docs/guides/working-with-konfig/3-quick-start.md b/versioned_docs/version-0.5.3/user_docs/guides/working-with-konfig/3-quick-start.md deleted file mode 100644 index 82fa6f36..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/working-with-konfig/3-quick-start.md +++ /dev/null @@ -1,198 +0,0 @@ ---- -id: guide -sidebar_label: Quick Start ---- - -# Introduction - -This guide shows you how to use the KCL language and CLIs to complete the deployment of an application running in Kubernetes. We call the abstraction of application operation and maintenance configuration as `Server`, and its instance as `Application`. It is essentially an operation and maintenance model defined by KCL. - -In actual production, the application online generally needs to update several k8s resources: - -- Namespace -- Deployment -- Service - -This guide requires you to have a basic understanding of Kubernetes. If you are not familiar with the relevant concepts, please refer to the links below: - -- [Learn Kubernetes Basics](https://kubernetes.io/docs/tutorials/kubernetes-basics/) -- [Namespace](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/) -- [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) -- [Service](https://kubernetes.io/docs/concepts/services-networking/service/) - -## Prerequisites - -Before we start, we need to complete the following steps: - -1. Install KCL - See [Download and Install](/docs/user_docs/getting-started/install) for more details. - -2. Clone the [Konfig repo](https://github.com/KusionStack/konfig.git) - -```shell -git clone https://github.com/KusionStack/konfig.git && cd konfig -``` - -## Quick Start - -### 1. Compiling - -The programming language of the project is KCL, not JSON/YAML which Kubernetes recognizes, so it needs to be compiled to get the final output. - -Enter stack dir `appops/nginx-example/dev` and compile: - -```bash -cd appops/nginx-example/dev && kcl -Y kcl.yaml -D __konfig_output_format__=raw -``` - -The output YAML is: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-exampledev - namespace: nginx-example -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - template: - metadata: - labels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - spec: - containers: - - image: nginx:1.7.8 - name: main - ports: - - containerPort: 80 - protocol: TCP - resources: - limits: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi - requests: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi ---- -apiVersion: v1 -kind: Namespace -metadata: - name: nginx-example ---- -apiVersion: v1 -kind: Service -metadata: - name: nginx-example - namespace: nginx-example -spec: - ports: - - nodePort: 30201 - port: 80 - targetPort: 80 - selector: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - type: NodePort -``` - -After compiling, we can see three resources: - -- A `Deployment` with the name `nginx-exampledev` -- A `Namespace` with the name `nginx-example` -- A `Service` with the name `nginx-example` - -The above completes the configuration and takes effect. Later, we can use the command `kubectl apply` to apply and check the actual status of resources. This guide will not elaborate. - -### 2. Modification - -The `image` attribute in the `Server` model is used to declare the application's container image. We can modify the `image` value in `base/main.k` to modify or upgrade the image: - -```diff -14c14 -< image = "nginx:1.7.8" ---- -> image = "nginx:latest" -``` - -Recompile the configuration code to obtain the modified YAML output: - -```shell -kcl -Y kcl.yaml -D __konfig_output_format__=raw -``` - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-exampledev - namespace: nginx-example -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - template: - metadata: - labels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - spec: - containers: - - image: nginx:latest - name: main - ports: - - containerPort: 80 - protocol: TCP - resources: - limits: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi - requests: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi ---- -apiVersion: v1 -kind: Namespace -metadata: - name: nginx-example ---- -apiVersion: v1 -kind: Service -metadata: - name: nginx-example - namespace: nginx-example -spec: - ports: - - nodePort: 30201 - port: 80 - targetPort: 80 - selector: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - type: NodePort -``` - -## Summary - -This document mainly introduces how to use the KCL and Konfig library to deploy a Long Running application running in Kubernetes. diff --git a/versioned_docs/version-0.5.3/user_docs/guides/working-with-konfig/_category_.json b/versioned_docs/version-0.5.3/user_docs/guides/working-with-konfig/_category_.json deleted file mode 100644 index a71426f9..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/working-with-konfig/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Konfig", - "position": 10 -} diff --git a/versioned_docs/version-0.5.3/user_docs/guides/working-with-kusion/_category_.json b/versioned_docs/version-0.5.3/user_docs/guides/working-with-kusion/_category_.json deleted file mode 100644 index 9f914498..00000000 --- a/versioned_docs/version-0.5.3/user_docs/guides/working-with-kusion/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KusionStack", - "position": 15 -} diff --git a/versioned_docs/version-0.5.3/user_docs/support/faq-install.md b/versioned_docs/version-0.5.3/user_docs/support/faq-install.md deleted file mode 100644 index 37100c09..00000000 --- a/versioned_docs/version-0.5.3/user_docs/support/faq-install.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Installation Troubleshooting - -## MacOS prompts that 'kcl' cannot be opened because Apple cannot check if it contains malicious software - -MacOS prompts that 'kcl' cannot be opened because Apple cannot check if it contains malicious software. This issue is due to the Gatekeeper security feature in the macOS system preventing the application from running. To solve this issue, follow these steps: - -Open 'System Preferences' and click 'Security and Privacy'. In the "General" tab, you will see a message: '"kcl" cannot be opened'. Click 'Open still'. Alternatively, you can click 'Open any method' to open your application. (You may need to use administrator privileges to open the application.) - -If you don't want to perform these steps every time you open an application, you can add the application to the whitelist to run without being blocked. To add your application to the whitelist: - -Open the terminal and run the following command: - -```shell -xattr -rd com.apple.quarantine /path/to/kcl -``` - -Where `/path/to/kcl` is the complete path of the kcl application. After running the command, the application will be added to the whitelist and Gatekeeper will no longer prevent it from running. - -## program not found or run linker failed error on Windows/Linux/MacOS - -Please ensure that the following dependencies are in your PATH: - -- `clang` for MacOS -- `gcc` for Linux -- `cl.exe` for Windows, which can be obtained by installing MSVC diff --git a/versioned_docs/version-0.5.3/user_docs/support/faq-kcl.md b/versioned_docs/version-0.5.3/user_docs/support/faq-kcl.md deleted file mode 100644 index 860dd15b..00000000 --- a/versioned_docs/version-0.5.3/user_docs/support/faq-kcl.md +++ /dev/null @@ -1,2341 +0,0 @@ ---- -sidebar_position: 2 ---- - -# KCL - -## 1. How to write a simple key-value pair configuration with KCL - -Create a file named `config.k` - -```python -cpu = 256 -memory = 512 -image = "nginx:1.14.2" -service = "my-service" -``` - -In the above KCL code, `cpu` and `memory` are defined to be declared as integer types, and their values are `256` and `512`, while `image` and `service` are string types, their values are `image` and `service`. - -Use the following command to compile the above KCL file into YAML for output - -``` -kcl config.k -``` - -The output YAML is - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -If we want to output the YAML content to a file such as `config.yaml`, we can add the `-o|--output` CLI argument: - -``` -kcl config.k -o config.yaml -``` - -## 2. What are the basic data types in KCL? - -KCL's current basic data types and values include: - -- Integer type `int` - - Examples: decimal positive integer `1`, decimal negative integer `-1`, hexadecimal integer `0x10`, octal integer `0o10`, binary integer `0b10` -- float type `float` - - Examples: positive float `1.10`, `1.0`, negative float `-35.59`, `-90.`, scientific notation float `32.3e+18`, `70.2E-12` -- boolean type `bool` - - Example: true value `True`, false value `False` -- String type `str` - marked with `'`, `"` - - Example: double quoted string `"string"`, `"""string"""`, single quoted string `'string'`, `'''string'''` -- List type `list` - marked with `[`, `]` - - Example: empty list `[]`, string list `["string1", "string2", "string3"]` -- Dictionary type `dict` - marked with `{`, `}` - - Example: empty dictionary `{}`, dictionary whose keys and values ​​are all strings `{"key1": "value1", "key2": "value2"}` -- Structure type `schema` - defined with the keyword `schema` -- Null value type `None` - used to indicate that the value of a variable is null, corresponding to the `null` value of the output YAML -- Undefined value type `Undefined` - used to indicate that a variable has not been assigned a value, and a variable with a value of `Undefined` will not be output to YAML - -```python -schema Person: - name: str - age: int - -alice = Person { - name = "Alice" - age = 18 -} -bob = Person { - name = "Bob" - age = 10 -} -``` - -> Note: All KCL variables can be assigned the null value `None` and the undefined value `Undefined`. - -## 3. What do some KCL variable names prefixed with `_` underscore mean? What's the difference between without the `_` underscore prefix? In what scenarios are they suitable for use? - -A variable with an underscore prefix in KCL represents a **hidden**, **mutable** variable, **hidden** means a variable with an underscore prefix will not be output to YAML, and **mutable** means that a variable with an underscore prefix can be repeatedly assigned multiple times, and a variable without an underscore prefix is immutable after being assigned. - -```python -name = 'Foo' # Exported and immutable variable -name = 'Bar' # Error: An exported variable can only be assigned a value once -``` - -```python -_name = 'Foo' # Hidden and mutable variable -_name = 'Bar' - -schema Person: - _name: str # hidden and mutable -``` - -## 4. How to add elements to a dict? - -We can use the union operator `|` or the dict unpacking operator `**` to add elements into a dict, and we can use `in` and `not in` operators to determine whether the dict variable contains a certain key. - -```python -_left = {key: {key1 = "value1"}, intKey = 1} # Note: `=` denotes override the value. -_right = {key: {key2 = "value2"}, intKey = 2} -dataUnion = _left | _right # {"key": {"key1": "value1", "key2": "value2"}, "intKey": 2} -dataUnpack = {**_left, **_right} # {"key": {"key1": "value1", "key2": "value2"}, "intKey": 2} -``` - -The output YAML is - -```yaml -dataUnion: - key: - key1: value1 - key2: value2 - intKey: 2 -dataUnpack: - key: - key1: value1 - key2: value2 - intKey: 2 -``` - -It is also possible to add key-value pair to a dict using the `string interpolation` or the string `format` method. - -```python -dictKey1 = "key1" -dictKey2 = "key2" -data = { - "${dictKey1}" = "value1" - "{}".format(dictKey2) = "value2" -} -``` - -The output YAML is - -```yaml -dictKey1: key1 -dictKey2: key2 -data: - key1: value1 - key2: value2 -``` - -## 5. How to modify elements in dict? - -We can use the union operator `|`, or the unpacking operator `**` to modify the elements in the dict - -```python -_data = {key = "value"} # {"key": "value"} -_data = _data | {key = "override_value1"} # {"key": "override_value1"} -_data = {**_data, **{key = "override_value2"}} # {"key": "override_value2"} -``` - -If we want to delete a value with a key of `key` in the dict, we can use the unpacking operator `**{key = Undefined}` or the merge operator `| {key = Undefined}` to overwrite, the value of the key is Undefined after overwriting, and no YAML output will be done. - -## 6. How to add elements to list? - -There are two ways to add elements to a list: - -- Use `+`, `+=` and slice to concatenate list variables to add elements to the list - -```python -_args = ["a", "b", "c"] -_args += ["end"] # Add elements "end" to the end of the list: ["a", "b", "c", "end"] -_args = _args[:2] + ["x"] + _args[2:] # Insert element "x" at list index 2: ["a", "b", "x", "c", "end"] -_args = ["start"] + _args # Add elements "start" to the head of the list: ["start", "a", "b", "x", "c", "end"] -``` - -- Use the `*` unpacking operator to concatenate and merge lists - -```python -_args = ["a", "b", "c"] -_args = [*_args, "end"] # Add elements "end" to the end of the list: ["a", "b", "c", "end"] -_args = ["start", *_args] # Add elements "start" to the head of the list: ["start", "a", "b", "x", "c", "end"] -``` - -> Note: When the consecutive variables are `None/Undefined`, using `+` may cause an error, then we can use the list unpacking operator `*` or use the `or` operator to take the default value of the list to avoid null values judge. - -```python -data1 = [1, 2, 3] -data2 = None -data3 = [*data1, *data2] # Ok: [1, 2, 3] -data4 = data1 + data2 or [] # OK: [1, 2, 3], We can use the `or` operator to take the default value of data2 as [], when data2 is None/Undefined, take the empty list [] for calculation. -data5 = data1 + data2 # Error: can only concatenate list (not "NoneType") to list -``` - -## 7. How to modify/delete elements in list? - -There are two ways to modify the elements in the list: - -- Use slice to directly modify the value at an index of a list - -```python -_index = 1 -_args = ["a", "b", "c"] -_args = _args[:index] + ["x"] + _args[index+1:] # Modify the element of list index 1 to "x": ["a", "x", "c"] -``` - -- Use the list comprehension to modify elements in a list - -```python -_args = ["a", "b", "c"] -_args = ["x" if a == "b" else a for a in _args] # Change the value of "b" in the list to "x": ["a", "x", "c"] -``` - -There are two ways to delete elements in a list: - -- Use the list comprehension to delete elements with the `if` condition expressions. -- Use `filter` expression to filter elements. - -For example, if we want to delete a number greater than 2 in a list `[1, 2, 3, 4, 5]`, we can write as follows: - -```python -originList = [1, 2, 3, 4, 5] -oneWayDeleteListItem = [item for item in originList if item <= 2] -anotherWayDeleteListItem = filter item in originList { - item <= 2 -} -``` - -The output YAML is - -```yaml -originList: - - 1 - - 2 - - 3 - - 4 - - 5 -oneWayDeleteListItem: - - 1 - - 2 -anotherWayDeleteListItem: - - 1 - - 2 -``` - -## 8. How to write a for loop in KCL? How to understand and use list comprehension and dict comprehension? - -KCL currently only supports functional/declarative deductive for loops. We can traverse dict and list variables as follows: - -The specific form of a list comprehension is (where `[]` are used on both sides of the comprehension): - -```txt -[expression for expr in sequence1 - if condition1 - for expr2 in sequence2 - if condition2 - for expr3 in sequence3 ... - if condition3 - for exprN in sequenceN - if conditionN] -``` - -The specific form of dict comprehension is (where `{}` are used on both sides of the comprehension): - -```txt -{expression for expr in sequence1 - if condition1 - for expr2 in sequence2 - if condition2 - for expr3 in sequence3 ... - if condition3 - for exprN in sequenceN - if conditionN} -``` - -The `if` in the above forms represents the filter condition, and the expression `expr` that satisfies the condition will be generated into a new list or dict - -List comprehension example: - -```python -_listData = [1, 2, 3, 4, 5, 6] -_listData = [l * 2 for l in _listData] # All elements in _listData are multiplied by 2: [2, 4, 6, 8, 10, 12] -_listData = [l for l in _listData if l % 4 == 0] # Filter out all elements in _listData that are divisible by 4: [4, 8, 12] -_listData = [l + 100 if l % 8 == 0 else l for l in _listData] # Traverse _listData, when the element in it is divisible by 8, add 100 to the element, otherwise keep it unchanged: [4, 108, 12] -``` - -Note the difference between the two `if`s on lines 3 and 4 in the above code: - -- The first `if` represents the filter condition of the variable `_listData` list comprehension itself, and cannot be followed by `else`. Elements that meet the conditions will be added to the list, and elements that do not meet the conditions will be removed. Besides, the process may change the length of the list. -- The second `if` represents the selection condition of the list iteration variable `l`, which means the `if-else` ternary expression, which must be followed by `else`, regardless of whether the condition is met, the resulting element is still in the list, the length of the list does not change. - -Dict comprehension example: - -```python -_dictData = {key1 = "value1", key2 = "value2"} -_dictData = {k = _dictData[k] for k in _dictData if k == "key1" and _dictData[k] == "value1"} # Filter out the elements whose key is "key1" and value is "value1" in _dictData, {"key1": "value1"} -``` - -Use comprehension to get all keys of dict: - -```python -dictData = {key1 = "value1", key2 = "value2"} -dictDataKeys = [k for k in _dictData] # ["key1", "key2"] -``` - -Use comprehension to sort a dict in ascending order by key: - -```python -dictData = {key3 = "value3", key2 = "value2", key1 = "value1"} # {'key3': 'value3', 'key2': 'value2', 'key1': 'value1'} -dictSortedData = {k = dictData[k] for k in sorted(dictData)} # {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'} -``` - -Multi-level comprehension example: - -```python -array1 = [1, 2, 3] -array2 = [4, 5, 6] -data = [a1 + a2 for a1 in array1 for a2 in array2] # [5, 6, 7, 6, 7, 8, 7, 8, 9] len(data) == len(array1) * len(array2) -``` - -Double variable loop (list comprehension supports index iteration of list and value iteration of dict, which can simplify the code writing of list/dict iteration process): - -- list - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use _ to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -- dict - -```python -data = {key1 = "value1", key2 = "value2"} -# Single variable loop -dataKeys1 = [k for k in data] # ["key1", "key2"] -dataValues1 = [data[k] for k in data] # ["value1", "value2"] -# Double variable loop -dataKeys2 = [k for k, v in data] # ["key1", "key2"] -dataValues2 = [v for k, v in data] # ["value1", "value2"] -dataFilter = {k = v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use _ to ignore loop variables -dataKeys3 = [k for k, _ in data] # ["key1", "key2"] -dataValues3 = [v for _, v in data] # ["value1", "value2"] -``` - -## 9. How to write an if conditional statement? - -KCL supports two ways to write if conditional statements: - -- if-elif-else block statement, where both elif and else blocks can be omitted, and the elif block can be used multiple times - -```python -success = True -_result = "failed" -if success: - _result = "success" -``` - -```python -success = True -if success: - _result = "success" -else: - _result = "failed" -``` - -```python -_result = 0 -if condition == "one": - _result = 1 -elif condition == "two": - _result = 2 -elif condition == "three": - _result = 3 -else: - _result = 4 -``` - -- Conditional expression ` if else `, similar to ` ? : ` ternary expression in C language - -```python -success = True -_result = "success" if success else "failed" -``` - -> Note: When writing an if-elif-else block statement, pay attention to the colon `:` after the if condition and keep the indentation consistent. - -In addition, conditional expressions can also be written directly in a list or dict (the difference is that the value to be written in the if expression written in the structure is not a statement): - -- list - -```python -env = "prod" -data = [ - "env_value" - ":" - if env == "prod": - "prod" # Write values that need to be added to data, not statements - else: - "other_prod" -] # ["env_value", ":", "prod"] -``` - -- dict - -```python -env = "prod" -config = { - if env == "prod": - MY_PROD_ENV = "prod_value" # Write key-value pairs that need to be added to config, not statements - else: - OTHER_ENV = "other_value" -} # {"MY_PROD_ENV": "prod_value"} -``` - -## 10. How to express logical operations such as "and" "or" "not"? - -In KCL, use `and` for "logical and", use `or` for "logical or", use `not` for "not", which is similar to `&&`, `||` and `~` semantic in C language. - -```python -done = True -col == 0 -if done and (col == 0 or col == 3): - ok = 1 -``` - -For "bitwise AND", "bitwise OR" and "bitwise XOR" of integers, we can use `&`, `|` and `^` operators in KCL, which is similar to `&`, `|` and `^` semantic in C language. - -```python -value = 0x22 -bitmask = 0x0f - -assert (value & bitmask) == 0x02 -assert (value & ~bitmask) == 0x20 -assert (value | bitmask) == 0x2f -assert (value ^ bitmask) == 0x2d -``` - -When we need to write a pattern such as `A if A else B`, we can use `A or B` to simplify, such as the following code: - -```python -value = [0] -default = [1] -x0 = value if value else default -x1 = value or default # Use `value or default` instead of `value if value else default` -``` - -## 11. How to judge whether a variable is None/Undefined, and whether a string/dict/list is empty? - -Please note that `False`, `None`, `Undefined`, number `0`, empty list `[]`, empty dictionary `{}` and empty string `""`, `''`, `""""""`, `''''''` in the conditional expression, are all treated as `false` expressions. - -For example, when judging a string variable `strData` is neither `None/Undefined` nor an empty string (string length is greater than 0), we can simply use the following expression: - -```python -strData = "value" -if strData: - isEmptyStr = False -``` - -Empty dictionary and empty list judgment examples: - -```python -_emptyList = [] -_emptyDict = {} -isEmptyList = False if _emptyList else True -isEmptyDict = False if _emptyDict else True -``` - -The output YAML is - -```yaml -isEmptyList: true -isEmptyDict: true -``` - -Or use the boolean function `bool` to judge - -```python -_emptyList = [] -_emptyDict = {} -isEmptyList = bool(_emptyList) -isEmptyDict = bool(_emptyDict) -``` - -## 12. How to concatenate strings, format strings, check string prefixes and suffixes and replace string content? - -- The `+` operator can be used to concatenate two strings in KCL - -```python -data1 = "string1" + "string2" # "string1string2" -data2 = "string1" + " " + "string2" # "string1 string2" -``` - -- There are currently two ways to format strings in KCL: - - `format` method for string variables `"{}".format()` - - Using string interpolation `${}` - -```python -hello = "hello" -a = "{} world".format(hello) -b = "${hello} world" -``` - -Note that if we want to use the `{` character or `}` alone in `"{}".format()`, we need to use `{{` and `}}` to convert `{` and `}` respectively, such as escaping a JSON string as follows: - -```python -data = "value" -jsonData = '{{"key": "{}"}}'.format(data) -``` - -The output YAML is - -```yaml -data: value -jsonData: '{"key": "value"}' -``` - -Note that if we want to use the `$` character alone in the `${}` interpolated string, we need to escape the `$` with `$$` - -```python -world = "world" -a = "hello {}".format(world) # "hello world" -b = "hello ${world}" # "hello world" -c = "$$hello ${world}$$" # "$hello world$" -c2 = "$" + "hello ${world}" + "$" # "$hello world$" -``` - -The output YAML is - -```yaml -world: world -a: hello world -b: hello world -c: $hello world$ -c2: $hello world$ -``` - -- Use the `startswith` and `endswith` methods of strings in KCL to check the prefix and suffix of strings - -```python -data = "length" -isEndsWith = data.endswith("th") # True -isStartsWith = "length".startswith('len') # True -``` - -- Use the replace method of the string or the `regex.replace` function to replace the content of the string in KCL - -```python -import regex -data1 = "length".replace("len", "xxx") # Replace "len", "xxxgth" with "xxx" -data2 = regex.replace("abc123", r"\D", "0") # Replace all non-digits in "abc123" with "0", "000123" -``` - -Among them, `r"\D"` means that we do not need to use `\\` to escape the backslash `\` in `\D`, which is mostly used in regular expression strings. - -Besides, we can use index placeholders or keyword placeholders in string formatting expressions to format multiple strings - -- Index placeholders - -```python -x = '{2} {1} {0}'.format('directions', 'the', 'Read') -y = '{0} {0} {0}'.format('string') -``` - -The output YAML is - -```yaml -x: Read the directions -y: string string string -``` - -- Keyword placeholders - -```python -x = 'a: {a}, b: {b}, c: {c}'.format(a = 1, b = 'Two', c = 12.3) -``` - -The output YAML is - -```yaml -x: "a: 1, b: Two, c: 12.3" -``` - -## 13. What is the difference between using single and double quotes in a string? - -There is little difference between KCL single-quoted and double-quoted strings. The only difference is that we don't need to use `\"` to escape `"` in single-quoted strings, and we don't need to use `\'` to escape `'` in double-quoted strings. - -```python -singleQuotedString = 'This is my book named "foo"' # Don’t need to escape double quotes in single quoted strings. -doubleQuotedString = "This is my book named 'foo'" # Don’t need to escape single quotes in double quoted strings. -``` - -In addition, a long string consisting of three single quotes or three double quotes does not need to be escaped (except for the beginning and end of the string), such as the following example: - -```python -longStrWithQuote0 = """Double quotes in long strings "(not at the beginning and end)""" -longStrWithQuote1 = '''Double quotes in long strings "(not at the beginning and end)''' -longStrWithQuote2 = """Single quotes in long strings '(not at the beginning and end)""" -longStrWithQuote3 = '''Single quotes in long strings '(not at the beginning and end)''' -``` - -The output YAML is - -```yaml -longStrWithQuote0: Double quotes in long strings "(not at the beginning and end) -longStrWithQuote1: Double quotes in long strings "(not at the beginning and end) -longStrWithQuote2: Single quotes in long strings '(not at the beginning and end) -longStrWithQuote3: Single quotes in long strings '(not at the beginning and end) -``` - -## 14. How to write a long multiline string? - -In KCL, we can use a single-quoted string and newline characters `\n` or a triple-quoted string to write a multi-line string, and we can use the continuation character `\` to optimize the form of the KCL string. For example, for the three multi-line string variables in the following code, their values are the same: - -```python -string1 = "The first line\nThe second line\nThe third line\n" -string2 = """The first line -The second line -The third line -""" -string3 = """\ -The first line -The second line -The third line -""" # It is recommended to use the long string writing form of `string3`. -``` - -The output YAML is - -```yaml -string1: | - The first line - The second line - The third line -string2: | - The first line - The second line - The third line -string3: | - The first line - The second line - The third line -``` - -## 15. How to use regular expressions in KCL? - -Regular expressions can be used by importing the regular expression system module `import regex` in KCL, which includes the following functions: - -- **match**: Regular expression matching function, which matches the input string according to the regular expression, and returns a bool type to indicate whether the match is successful. -- **split**: Regular expression split function, which splits the string according to the regular expression, and returns a list of split strings. -- **replace**: Regular expression replacement function, which replaces all substrings in the string that satisfies the regular expression, and returns the replaced string. -- **compile**: Regular expression compilation function, which returns bool type to indicate whether it is a valid regular expression. -- **search**: Regular expression search function, which searches all substrings that satisfy the regular expression, and returns a list of substrings. - -Examples: - -```python -import regex - -regex_source = "Apple,Google,Baidu,Xiaomi" -regex_split = regex.split(regex_source, ",") -regex_replace = regex.replace(regex_source, ",", "|") -regex_compile = regex.compile("$^") -regex_search = regex.search("aaaa", "a") -regex_find_all = regex.findall("aaaa", "a") -regex_result = regex.match("192.168.0.1", "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$") # Determine if it is an IP string -regex_result_false = regex.match("192.168.0,1", "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$") # Determine if it is an IP string -``` - -The output YAML is - -```yaml -regex_source: Apple,Google,Baidu,Xiaomi -regex_split: - - Apple - - Google - - Baidu - - Xiaomi -regex_replace: Apple|Google|Baidu|Xiaomi -regex_compile: true -regex_search: true -regex_find_all: - - a - - a - - a - - a -regex_result: true -regex_result_false: false -``` - -For longer regular expressions, we can also use **r-string** to ignore the escape of `\` symbols to simplify the writing of regular expression strings. - -Examples: - -```python -import regex - -isIp = regex.match("192.168.0.1", r"^(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)$") # Determine if it is an IP string -``` - -```python -import regex - -schema Resource: - cpu: str = "1" - memory: str = "1024Mi" - disk: str = "10Gi" - check: - regex.match(cpu, r"^([+-]?[0-9.]+)([m]*[-+]?[0-9]*)$"), "cpu must match specific regular expression" - regex.match(memory, r"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"), "memory must match specific regular expression" - regex.match(disk, r"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"), "disk must match specific regular expression" -``` - -```python -import regex - -schema Env: - name: str - value?: str - check: - len(name) <= 63, "a valid env name must be no more than 63 characters" - regex.match(name, r"[A-Za-z_][A-Za-z0-9_]*"), "a valid env name must start with alphabetic character or '_', followed by a string of alphanumeric characters or '_'" -``` - -## 16. What is the meaning of schema in KCL? - -Schema is a language element in KCL that defines the type of configuration data. Like struct in C language or class in Java, attributes can be defined in it, and each attribute has a corresponding type. - -## 17. How to use schema? - -In KCL, we can use the `schema` keyword to define a structure in which we can declare the various attributes of the schema. - -```python -# A Person structure with firstName of attribute string type, lastName of string type, age of integer type. -schema Person: - firstName: str - lastName: str - # The default value of the age attribute is 0. - age: int = 0 -``` - -A complex example: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels: {str:str} -``` - -In the above code, `cpu` and `memory` are defined as integer types; `name`, `image` and `service` are string types; `command` is a list of string types; labels are dictionaries type whose key type and value type are both strings. - -## 18. How to add "optional" and "required" constraints to the schema attribute? - -The `?` operator is used in KCL to define an "optional" constraint for a schema, and the schema attribute is "required" by default. - -```python -# A Person structure with firstName of attribute string type, lastName of string type, age of integer type. -schema Person: - firstName?: str # firstName is an optional attribute that can be assigned to None/Undefined - lastName?: str # age is an optional attribute that can be assigned to None/Undefined - age: int = 18 # age is an optional attribute that can be assigned to None/Undefined. -``` - -## 19. How to write validation rules for attributes in schema? - -In the schema definition, we can use the `check` keyword to write the validation rules of the schema attribute. As shown below, each line in the check code block corresponds to a conditional expression. When the condition is satisfied, the validation is successful. The conditional expression can be followed by `, "check error message"` to indicate the information to be displayed when the validation fails. - -```python -import regex - -schema Sample: - foo: str # Required, cannot be None/Undefined, and the type must be str - bar: int # Required, cannot be None/Undefined, and the type must be int - fooList: [int] # Required, cannot be None/Undefined, and the type must be int list - color: "Red" | "Yellow" | "Blue" # Required, literal union type, and must be one of "Red", "Yellow", "Blue". - id?: int # Optional, can be None/Undefined, the type must be int - - check: - 0 <= bar < 100 # bar must be greater than or equal to 0 and less than 100 - 0 < len(fooList) < 100 # fooList cannot be None/Undefined, and the length must be greater than 0 and less than 100 - regex.match(foo, "^The.*Foo$") # regular expression matching - bar in range(100) # bar can only range from 1 to 99 - bar in [2, 4, 6, 8] # bar can only take 2, 4, 6, 8 - bar % 2 == 0 # bar must be a multiple of 2 - all foo in fooList { - foo > 1 - } # All elements in fooList must be greater than 1 - any foo in fooList { - foo > 10 - } # At least one element in fooList must be greater than 10 - abs(id) > 10 if id # check expression with if guard, when id is not empty, the absolute value of id must be greater than 10 -``` - -To sum up, the validation kinds supported in KCL schema are: - -| Kind | Method | -| ----------------- | ----------------------------------------------------------------------------------------- | -| Range | Using comparison operators such as `<`, `>` | -| Regex | Using methods such as `match` from the `regex` system module | -| Length | Using the `len` built-in function to get the length of a variable of type `list/dict/str` | -| Enum | Using literal union types | -| Optional/Required | Using optional/required attributes of schema | -| Condition | Using the check if conditional expression | - -## 20. How to add documentation to schema and its attributes? - -A complete schema document is represented as a triple-quoted string, with the following structure: - -```python -schema Person: - """The schema person definition - - Attributes - ---------- - name : str - The name of the person - age : int - The age of the person - - See Also - -------- - Son: - Sub-schema Son of the schema Person. - - Examples - -------- - person = Person { - name = "Alice" - age = 18 - } - """ - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -``` - -## 21. How to write configuration based on schema? How to reuse the common configuration between multiple configurations? - -In the process of schema instantiation, we can use the unpacking operator `**` to expand the public configuration - -```python -schema Boy: - name: str - age: int - hc: int - -schema Girl: - name: str - age: int - hc: int - -config = { - age = 18 - hc = 10 -} - -boy = Boy { - **config - name = "Bob" -} -girl = Girl { - **config - name = "Alice" -} -``` - -The output YAML is - -```yaml -config: - age: 18 - hc: 10 -boy: - name: Bob - age: 18 - hc: 10 -girl: - name: Alice - age: 18 - hc: 10 -``` - -## 22. How to override the default value of schema attribute when writing configuration based on schema? - -After defining a schema, we can use the schema name to instantiate the corresponding configuration, use the `:` operator to union schema attribute default values, and use `=` to override schema attribute default values. - -```python -schema Meta: - labels: {str:str} = {"key1" = "value1"} - annotations: {str:str} = {"key1" = "value1"} - -meta = Meta { - labels: {"key2": "value2"} - annotations = {"key2" = "value2"} -} -``` - -The output YAML is - -```yaml -meta: - labels: - key1: value1 - key2: value2 - annotations: - key2: value2 -``` - -## 23. How to reuse schema definitions? - -We can declare the schema name that the schema needs to inherit at the definition: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 - -# An employee **is** a person, and has some additional information. -schema Employee(Person): - bankCard: int - nationality: str - -employee = Employee { - firstName = "Bob" - lastName = "Green" - age = 18 - bankCard = 123456 - nationality = "China" -} -``` - -The output YAML is - -```yaml -employee: - firstName: Bob - lastName: Green - age: 18 - bankCard: 123456 - nationality: China -``` - -> Note: KCL only allows schema single inheritance. - -## 24. How to reuse schema logic through composition? - -We can use KCL schema mixin to reuse schema logic. Mixins are generally used for functions such as separation of data in schema internal attributes, and data mapping, which can make KCL code more modular and declarative. - -Note that it is not recommended to define dependencies for mixing attributes between different mixins, which will make the use of mixins complicated. - -Examples: - -```python -schema Person: - mixin [FullNameMixin, UpperMixin] - - firstName: str - lastName: str - fullName: str - upper: str - -schema FullNameMixin: - fullName = "{} {}".format(firstName, lastName) - -schema UpperMixin: - upper = fullName.upper() - -person = Person { - firstName = "John" - lastName = "Doe" -} -``` - -The output YAML is - -```yaml -person: - firstName: John - lastName: Doe - fullName: John Doe - upper: JOHN DOE -``` - -## 25. How to import other KCL files? - -Other KCL files can be imported via the `import` keyword, and KCL configuration files are organized into modules. A single KCL file is considered a module, and a directory is considered a package, as a special module. The `import` keyword supports both relative path import and absolute path import - -For example, for the following directory structure: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ │── service1.k - │ └── service2.k - └── mixin - └── mixin1.k -``` - -For `main.k`, relative path import and absolute path import can be expressed as: - -```python -import service # Absolute path import, the root directory is the path where kcl.mod is located -import mixin # Absolute path import, the root directory is the path where kcl.mod is located - -import .model1 # Relative path import, current directory module -import ..service # Relative path import, parent directory -import ...root # Relative path import, parent directory of parent directory -``` - -> Note that for KCL's entry file `main.k`, it cannot import the folder where it is located, otherwise a circular import error will occur: - -```python -import model # Error: recursively loading -``` - -## 26. When can import be omitted? - -KCL files in the same folder the not in the main package can refer to each other without importing each other. For example, for the following directory structure: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ │── service1.k - │ └── service2.k - └── mixin - └── mixin1.k -``` - -When main.k is used as the KCL command line entry file, the variables in main.k, model1.k and model2.k in the model folder cannot refer to each other and need to be imported through import, but service1.k in the service folder and Variables in service2.k can refer to each other, ignoring import - -service1.k - -```python -schema BaseService: - name: str - namespace: str -``` - -service2.k - -```python -schema Service(BaseService): - id: str -``` - -## 27. There is a line of code that is too long, how to wrap it gracefully with correct syntax? - -In KCL, we can use the continuation character `\` for newlines, and we can also use `\` in strings to indicate continuation. - -An example of a long string concatenation continuation line: - -```python -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " -``` - -An example of a continuation in the comprehension expression: - -```python -data = [1, 2, 3, 4] -dataNew = [ - d + 2 \ - for d in data \ - if d % 2 == 0 -] -``` - -An example of a continuation in the if expression: - -```python -condition = 1 -data1 = 1 \ - if condition \ - else 2 -data2 = 2 \ -if condition \ -else 1 -``` - -An example of a continuation in the long string: - -```python -longString = """\ -The first line\ -The continue second line\ -""" -``` - -Note: Use the line continuation character `\` while maintaining indentation, as follows: - -- Error use case: - -```python -data1 = [ - 1, 2, - 3, 4 \ -] # Error, need to keep the indentation of the closing bracket ] - -data2 = [ - 1, 2, - 3, 4 -] # Error, requires uniform indentation of numbers 1 and 3 -``` - -- Right use case: - -```python -data1 = [ - 1, 2, - 3, 4 -] # OK - -data2 = [ \ - 1, 2, \ - 3, 4 \ -] # OK - -data3 = [ \ - 1, 2, \ - 3, 4 \ -] # OK -``` - -## 28. What do these symbols `**` and `*` mean? - -- `**`, `*` appear outside dict/list to represent power operator and multiplication operator respectively. - -```python -data1 = 2 ** 4 # 16 -data2 = 2 * 3 # 6 -``` - -- `**`, `*` appear inside dict/list to indicate unpacking operator, often used for unpacking and merging of list/dict, similar to unpacking operator in Python - -Unpacking of dict: - -```python -data = {"key1" = "value1"} -dataUnpack = {**data, "key2" = "value2"} # {"key1": "value1", "key2": "value2"} -``` - -Unpacking of list: - -```python -data = [1, 2, 3] -dataUnpack = [*data, 4, 5, 6] # [1, 2, 3, 4, 5, 6] -``` - -## 29. How to get child elements of list/dict/schema - -- For list type, we can use `[]` to get an element in the list - -```python -data = [1, 2, 3] # Define an list of integer types -theFirstItem = data[0] # Get the element with index 0 in the list, that is, the first element 1 -theSecondItem = data[1] # Get the element with index 1 in the list, which is the first element 2 -``` - -> Note: The value of the index cannot exceed the length of the list, otherwise an error will occur, we can use the `len` function to get the length of the list. - -```python -data = [1, 2, 3] -dataLength = len(data) # List length is 3 -item = data[3] # Error: Index out of bounds -``` - -In addition, we can also use the negative index to get the elements in the list in reverse order. - -```python -data = [1, 2, 3] -item1 = data[-1] # Get the element with index -1 in the list, which is the last element 3 -item2 = data[-2] # Get the element with index -2 in the list, which is the second-to-last element 2 -``` - -In summary, the value range of the list index is `[-len, len - 1]` - -When we want to get a part of the sub-elements of the list, we can use the slice expression in `[]`, the specific syntax is `[::]`, Note that the value range of the start and end of the index is `left closed right open [, )`, note that the three parameters can be omitted or not written. - -```python -data = [1, 2, 3, 4, 5] -dataSlice0 = data[1:2] # Get the set of elements in the list whose index starts at 1 and ends at 2 [2] -dataSlice1 = data[1:3] # Get the set of elements in the list whose index starts at 1 and ends at 3 [2, 3] -dataSlice2 = data[1:] # Get the set of elements in the list whose index starts at 1 and ends at the last index [2, 3, 4, 5] -dataSlice3 = data[:3] # Get the set of elements in the list whose index starts at the first index and ends at 3 [1, 2, 3] -dataSlice4 = data[::2] # Get the set of elements in the list whose index starts at the first index and ends at the last index (step size is 2) [1, 3, 5] -dataSlice5 = data[::-1] # Reverse the list, [5, 4, 3, 2, 1] -dataSlice6 = data[2:1] # When the start, stop, step combination of three parameters does not meet the conditions, return an empty list []. -``` - -- For dict/schema types, we can use `[]` and `.` to get child elements in dict/schema. - -```python -data = {key1: "value1", key2: "value2"} -data1 = data["key1"] # "value1" -data2 = data.key1 # "value1" -data3 = data["key2"] # "value2" -data4 = data.key2 # "value2" -``` - -```python -schema Person: - name: str = "Alice" - age: int = 18 - -person = Person {} -name1 = person.name # "Alice" -name2 = person["name"] # "Alice" -age1 = person.age # 18 -age2 = person.age # 18 -``` - -When the key value does not exist in the dict, return the value `Undefined`. - -```python -data = {key1 = "value1", key2 = "value2"} -data1 = data["not_exist_key"] # Undefined -data2 = data.not_exist_key # Undefined -``` - -We can use the `in` keyword to determine whether a key value exists in dict/schema - -```python -data = {key1 = "value1", key2 = "value2"} -exist1 = "key1" in data # True -exist2 = "not_exist_key" in data # False -``` - -When there is `.` in the key value or when we need to get the value corresponding to a key value variable at runtime, we can only use the `[]` method. If there is no special case, use `.`: - -```python -name = "key1" -data = {key1 = "value1", key2 = "value2", "contains.dot" = "value3"} -data1 = data[name] # "value1" -data2 = data["contains.dot"] # "value3" -# Note that this is wrong: data3 = data.contains.dot -``` - -> Note: The above sub-element operators cannot operate on values of non-list/dict/schema collection types, such as integers, nulls, etc. - -```python -data = 1 -data1 = 1[0] # Error -``` - -```python -data = None -data1 = None[0] # Error -``` - -When getting the child elements of the collection type, it is often necessary to make a non-null or length judgment: - -```python -data = [] -item = data[0] if data else None -``` - -We can use the `?` operator to make an if non-null judgment, and return None when the condition is not satisfied. For example, the above code can be simplified to: - -```python -data = [] -item1 = data?[0] # When data is empty, return the empty value None -item2 = data?[0] or 1 # When data is empty, return the empty value None, if we don't want to return None, we can also use the or operator to return other default values e.g., "1" in `data?[0] or 1` -``` - -Use more `?` operators to avoid complicated and cumbersome non-null judgments - -```python -data = {key1.key2.key3 = []} -item = data?.key1?.key2?.key3?[0] -``` - -## 30. How to get the type of a variable in KCL code - -The KCL `typeof` built-in function can return the type (string representation) of a variable immediately for type assertion. - -Examples: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person{} -t3 = typeof(_x1) - -_x2 = pkg.Person{} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# Output -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -## 31. How to solve the conflict between keywords and KCL variable names? - -For identifier names that conflict with keywords, we can add a `$` prefix before the identifier to define a keyword identifier. For example, in the following code, keywords such as `if`, `else` can be used as identifiers with the `$` prefix and we can get the corresponding YAML output - -```python -$if = 1 -$else = "s" - -schema Data: - $filter: str = "filter" - -data = Data {} -``` - -The output YAML is - -```yaml -data: - filter: filter -if: 1 -else: s -``` - -> Note: Prefixing non-keyword identifiers with `$` has the same effect as not adding. - -```python -_a = 1 -$_a = 2 # Equivalent to `_a = 2` -``` - -## 32. Are built-in types of KCL a keyword of KCL? Whether they can be used for the definition of variables - -The built-in types of KCL include `int`, `float`, `bool` and `str`, which are not KCL keywords and can be used to define variables, such as the following code: - -```py -int = 1 -str = 2 -``` - -The output YAML is - -```yaml -int: 1 -str: 2 -``` - -> Note: If there are no special requirements, it is not recommended that the names of variables take these built-in types, because in some languages, they exist as keywords. - -## 33. How to implement enumeration in KCL? - -There are two ways to implement enumeration in KCL - -- Use **literal union types** (recommended) - -```python -schema Person: - name: str - gender: "Male" | "Female" - -person = Person { - name = "Alice" - gender = "Male" # gender can only be "Male" or "Female" -} -``` - -```python -schema Config: - colors: ["Red" | "Yellow" | "Blue"] # colors is an enumerated array - -config = Config { - colors = [ - "Red" - "Blue" - ] -} -``` - -- Use schema check expressions - -```python -schema Person: - name: str - gender: "Male" | "Female" - - check: - gender in ["Male", "Female"] - -person = Person { - name = "Alice" - gender = "Male" # gender can only be "Male" or "Female" -} -``` - -## 34. How to get the length of dict - -In KCL, we can use the `len` built-in function to directly find the length of a dict - -```python -len1 = len({k1: "v1"}) # 1 -len2 = len({k1: "v1", k2: "v2"}) # 2 -varDict = {k1 = 1, k2 = 2, k3 = 3} -len3 = len(varDict) # 3 -``` - -In addition, the `len` function can also be used to get the length of `str` and `list` types - -```python -len1 = len("hello") # 5 -len2 = len([1, 2, 3]) # 3 -``` - -## 35. How to write conditional configuration in KCL - -In KCL, in addition to writing `if-elif-else` conditional expressions in top-level statements, it also supports writing conditional expressions in KCL complex structures (list/dict/schema), and supports conditional configuration writing. - -```python -x = 1 -# Conditional configuration in list -dataList = [ - if x == 1: 1 -] -# Conditional configuration in dict -dataDict = { - if x == 1: key1 = "value1" # Inline form - elif x == 2: - key2 = "value2" # Multi-line form -} - -schema Config: - id?: int - -env = "prod" -# Conditional configuration in schema -dataSchema = Config { - if env == "prod": - id = 1 - elif env == "pre": - id = 2 - elif env == "test": - id = 3 -} -``` - -## 36. Does the == operator in KCL do deep comparisons? - -`==` operator in KCL - -- For primitive types `int`, `float`, `bool`, `str` variables are directly compared to see if their values are equal -- Variables of composite types `list`, `dict`, `schema` will deeply recursively compare their sub-elements for equality - - `list` type deep recursive recursive comparison of the value and length of each index - - `dict`/`schema` types deeply recursively compare the value of each attribute (regardless of the order in which the attributes appear) - -```python -print([1, 2] == [1, 2]) # True -print([[0, 1], 1] == [[0, 1], 1]) # True -print({k1 = 1, k2 = 2} == {k2 = 2, k1 = 1}) # True - -print([1, 2] == [1, 2, 3]) # False -print({k1 = 1, k2 = 2, k3 = 3} == {k2 = 2, k1 = 1}) # False -``` - -## 37. How to modify existing configuration blocks in KCL - -In KCL, there are three **attribute operators** `=`, `+=`, `:`, which can be used to modify existing configuration blocks, and can use **unpacking operator** ` **` etc. "inherit" all attribute fields and values ​​of a configuration block. - -- The `=` attribute operator means overriding, use `=` operator to override/delete the attribute with priority, (if it is overwritten with `Undefined`, it means deletion) -- The `+=` attribute operator means adding, which is generally used to add sub-elements to the attributes of the list type. The operand type following the `+=` attribute operator can only be of the list type. -- The `:` attribute operator means idempotent merge. When the value conflicts, an error is reported, and when there is no conflict, the merge is performed - -### Override attribute operator = - -The most commonly used attribute operator is `=`, which indicates the assignment of an attribute. When the same attribute is used multiple times, it means overwriting. For global variables outside `{}` or attributes within `{}`, it means using value overrides this global variable or attribute - -```python -data = { # define a dictionary type variable data - a = 1 # use = to declare a attribute a in data with a value of 1 - b = 2 # use = to declare a attribute b in data with a value of 1 -} # The final data value is {"a": 1, "b": 1} -``` - -we can also use the override attribute operator at the schema instantiation to achieve the effect of overriding the default value of the schema. Generally, when creating a new schema instance, if there is no special requirement, we can generally use `=` - -```python -schema Person: - name: str = "Alice" # schema Person's name attribute has default value "Alice" - age: int = 18 # schema Person's age attribute has a default value of 18 - -bob = Person { - name = "Bob" # "Bob" -> "Alice", the value of the attribute name "Bob" will override the default value "Alice" of the schema Person name attribute - age = 10 # 10 -> 18, the value of the attribute age of 10 will override the default value of the schema Person age attribute of 18 -} # The final value of bob is {"name": "Bob", age: 10} -``` - -### Insert attribute operator += - -The insert attribute operator means to add the value of an attribute in place, such as adding a new element to a list type attribute - -```python -data = { - args = ["kcl"] # use = to declare an attribute in data with value ["kcl"] args - args += ["-Y", "settings.yaml"] # Add two elements "-Y", "settings.yaml" to attribute args using += operator -} # The final data value is {"args": ["kcl", "-Y", "settings.yaml"]} -``` - -### Merge attribute operators : - -The merge attribute operator means idempotent merging of different configuration block values ​​of an attribute. When the values ​​to be merged conflict, an error is reported. It is mostly used in complex configuration merging scenarios. - -```python -data = { - labels: {key1: "value1"} # define a labels, its type is dict, the value is {"key1": "value1"} - labels: {key2: "value2"} # Use : to combine different configuration values ​​of labels -} # The final data value is {"labels": {"key1": "value1", "key2": "value2"}} -``` - -The merge attribute operator is an idempotent operator, and the writing order of the configuration blocks to be merged does not affect the final result. For example, the two `labels` attributes in the above example can also be written in reverse order. - -```python -data = { # The merged writing order of the same attribute labels does not affect the final result - labels: {key2: "value2"} # define a label whose type is dict and the value is {"key2": "value2"} - labels: {key1: "value1"} # Use : to combine different configuration values ​​of labels -} # The final data value is {"labels": {"key1": "value1", "key2": "value2"}} -``` - -Note: The merge attribute operator will check the merged values ​​for conflicts, and report an error when the configuration values ​​that need to be merged conflict. - -```python -data = { - a: 1 # the value of a is 1 - a: 2 # Error: The value 2 of a cannot be merged with the value 1 of a because the results conflict and the merge is not commutative -} -``` - -```python -data = { - labels: {key: "value"} - labels: {key: "override_value"} # Error: The values ​​"value" and "override_value" of the key attributes of two labels are conflicting and cannot be merged -} -``` - -The coalescing operator is used differently for different types - -- Attributes of different types cannot be merged -- When the attribute is a basic type such as int/float/str/bool, the operator will judge whether the values ​​to be merged are equal, and a merge conflict error will occur if they are not equal - -```python -data = { - a: 1 - a: 1 # Ok - a: 2 # Error -} -``` - -- when the attribute is of type list - - Merge conflict error occurs when two lists that need to be merged are not of equal length - - When the lengths of the two lists to be merged are equal, recursively merge each element in the list according to the index - -```python -data = { - args: ["kcl"] - args: ["-Y", "settings.yaml"] # Error: The lengths of the two args attributes are not the same and cannot be merged - env: [{key1: "value1"}] - env: [{key2: "value2"}] # Ok: The value of the final env attribute is [{"key1": "value1"}, {"key2": "value2"}] -} -``` - -- When the attribute is of type dict/schema, recursively merge each element in dict/schema according to key - -```python -data = { - labels: {key1: "value1"} - labels: {key2: "value2"} - labels: {key3: "value3"} -} # The final data value is {"labels": {"key1": "value1", "key2": "value2", "key3": "value3"}} -``` - -- the result of combining an attribute of any type with None/Undefined is itself - -```python -data = { - args: ["kcl"] - args: None # Ok - args: Undefined #Ok -} # The final data value is {"args": ["kcl"]} -``` - -Support declaration and merging of top-level variables using the `:` attribute (we can still declare a configuration block using `config = Config {}`) - -```python -schema Config: - id: int - value: str - -config: Config { - id: 1 -} -config: Config { - value: "1" -} -""" -Two Config configuration blocks are defined here, and the : operator can be used to merge the two configuration blocks together. The equivalent code for the merge is as follows: -config: Config { - id: 1 - value: "1" -} -""" -``` - -To sum up, the usage scenario of the merge attribute operator `:` is mainly the merge operation of the complex data structure list/dict/schema. In general, if there is no special requirement, the two attribute operators `=` and `+=` are used. Yes, so the best practice for attribute operators is as follows - -- For primitive types, use the `=` operator -- For the list type, the `=` and `+=` operators are generally used. Use `=` to completely override the list attribute, and use `+=` to add elements to the list -- For dict/schema types, the `:` operator is generally used - -In addition, when a configuration already exists, we can use the unpacking operator `**` to get all field values ​​of this configuration and modify the fields with different attribute operators, and get a new configuration - -```python -configBase = { - intKey = 1 # A attribute of type int - floatKey = 1.0 # A attribute of type float - listKey = [0] # A attribute of type list - dictKey = {key1: "value1"} # an attribute of type dict -} -configNew = { - **configBase # Unpack and inline configBase into configNew - intKey = 0 # Use override attribute operator = to override intKey attribute to 1 - floatKey = Undefined # Use override attribute operator = remove floatKey attribute - listKey += [1] # Add an attribute 1 to the end of the listKey attribute using the add attribute operator += - dictKey: {key2: "value2"} # Use the merge attribute operator: extend a key-value pair for the dictKey attribute -} -``` - -The output YAML result is: - -```yaml -configBase: - intKey: 1 - floatKey: 1.0 - listKey: - - 0 - dictKey: - key1: value1 -configNew: - intKey: 0 - listKey: - - 0 - - 1 - dictKey: - key1: value1 - key2: value2 -``` - -Alternatively two configuration blocks can be combined using the `|` operator: - -```python -configBase = { - intKey = 1 # A attribute of type int - floatKey = 1.0 # A attribute of type float - listKey = [0] # A attribute of type list - dictKey = {key1: "value1"} # an attribute of type dict -} -configNew = configBase | { # Use | to merge - intKey = 0 # Use override attribute operator = to override intKey attribute to 1 - floatKey = Undefined # Use override attribute operator = remove floatKey attribute - listKey += [1] # Add an attribute 1 to the end of the listKey attribute using the add attribute operator += - dictKey: {key2: "value2"} # Use the merge attribute operator: extend a key-value pair for the dictKey attribute -} -``` - -The output YAML is - -```yaml -configBase: - intKey: 1 - floatKey: 1.0 - listKey: - - 0 - dictKey: - key1: value1 -configNew: - intKey: 0 - listKey: - - 0 - - 1 - dictKey: - key1: value1 - key2: value2 -``` - -### The solution to the conflicting values on the attribute 'attr' between {value1} and {value2} error in KCL - -When an error like conflicting values on the attribute 'attr' between {value1} and {value2} occurs in KCL, it is usually a problem with the use of the merge attribute operator `:`, indicating that when the `value1` and `value2` configurations are merged, the attribute A conflict error occurred at `attr`. In general, modify the attr attribute of value2 to other attribute operators, use `=` to indicate overwrite, and use `+=` to indicate addition - -For example for the following code: - -```python -data = {k: 1} | {k: 2} # Error: conflicting values on the attribute 'k' between {'k': 1} and {'k': 2} -``` - -We can use the `=` attribute operator to modify it to the following form - -```python -data = {k: 1} | {k = 2} # Ok: the value 2 will override the value 1 through the `=` operator -``` - -## 38. How to traverse multiple elements at the same time in the for comprehension? - -In KCL, we can use for comprehension to traverse multiple elements - -- Example 1: two dimension element loop - -```python -dimension1 = [1, 2, 3] # The length of the dimension1 list is 3 -dimension2 = [1, 2, 3] # The length of the dimension2 list is 3 -matrix = [x + y for x in dimension1 for y in dimension2] # The length of the matrix list is 9 = 3 * 3 -``` - -The output YAML is: - -```yaml -dimension1: - - 1 - - 2 - - 3 -dimension2: - - 1 - - 2 - - 3 -matrix: - - 2 - - 3 - - 4 - - 3 - - 4 - - 5 - - 4 - - 5 - - 6 -``` - -- Example 2: Use for loop and `zip` built-in function to traverse multiple lists one by one by index - -```python -dimension1 = [1, 2, 3] # The length of the dimension1 list is 3 -dimension2 = [1, 2, 3] # The length of the dimension2 list is 3 -dimension3 = [d[0] + d[1] for d in zip(dimension1, dimension2)] # The length of the dimension1 list is 3 -``` - -The output YAML is: - -```yaml -dimension1: - - 1 - - 2 - - 3 -dimension2: - - 1 - - 2 - - 3 -dimension3: - - 2 - - 4 - - 6 -``` - -## 39. How to set default value for option function in KCL - -In KCL, when the value of the option attribute is None/Undefined or empty, we can use the logical `or` to directly specify a default value. - -```python -value = option("key") or "default_value" # When the value of key exists, take the value of option("key"), otherwise take "default_value" -``` - -Or use the default parameter of the option function. - -```python -value = option("key", default="default_value") # When the value of key exists, take the value of option("key"), otherwise take "default_value" -``` - -## 40. How to check that multiple attributes cannot be empty or set values at the same time in schema in KCL? - -In KCL, a single attribute of schema cannot be empty by default, unless we use the attribute optional operator `?`. - -```python -schema Person: - name: str # Required. - age: int # Required. - id?: int # Optional. -``` - -When it is necessary to check that the schema attributes cannot be empty at the same time or only one of them is empty, it needs to be written with the help of schema check expressions. The following takes two attributes `a`, `b` of the schema `Config` as an example to illustrate. - -- `a` and `b` attributes cannot be empty at the same time. - -```python -schema Config: - a?: str - b?: str - - check: - a or b -``` - -- `a` and `b` attributes can only have one or both empty (cannot exist at the same time or not empty) - -```python -schema Config: - a?: str - b?: str - - check: - not a or not b -``` - -## 41. A file is imported in KCL, but the schema defined by other KCL files in the same directory cannot be found. What might be the reason? - -It may be caused to import only this file in this folder. In KCL, import statement supports importing the entire folder, and also supports importing a certain KCL file under a certain folder. For the following directory structure. - -``` -. -├── kcl.mod -├── main.k -└── pkg - ├── pkg1.k - ├── pkg2.k - └── pkg3.k -``` - -There is an entry file main.k in the root directory. You can write the following code in main.k to import the entire pkg folder. At this time, all schema definitions in the pkg folder are visible to each other. - -```python -import pkg -``` - -We can also write the following code to import a single file pkg/pkg1.k. At this time, pkg1.k cannot find other files, namely the schema definitions under pkg2.k/pkg3.k - -```python -import pkg.pkg1 -``` - -## 42. How is indentation handled in KCL? - -In KCL, when a colon `:`, square bracket pair `[]` and curly bracket pair `{}` appear, we generally need to use newline + indentation, and the number of indented spaces for the same indentation level needs to be consistent. The indentation level is generally represented by 4 spaces. - -- colon `:` followed by newline and indent - -```python -"""Indentation in if statements""" -_a = 1 -_b = 1 -if _a >= 1: # colon `:` followed by newline and indent - if _a > 8: - _b = 2 - elif a > 6: - _b = 3 - -"""Indentation in schema statements""" -schema Person: # colon `:` followed by newline and indent - name: str - age: int -``` - -- opening bracket `[` followed by newline and indent - -```python -data = [ # opening bracket `[` followed by newline and indent - 1 - 2 - 3 -] # unindent before closing bracket ] -``` - -```python -data = [ # opening bracket `[` followed by newline and indent - i * 2 for i in range(5) -] # unindent before closing bracket `]` -``` - -- opening bracket `{` followed by newline and indent - -```python -data = { # opening bracket `{` followed by newline and indent - k1 = "v1" - k2 = "v2" -} # unindent before closing brace `}` -``` - -```python -data = { # opening bracket `{` followed by newline and indent - str(i): i * 2 for i in range(5) -} # unindent before closing brace `}` -``` - -## 43. How to write simple tests for KCL code? - -The current version of KCL does not support internal program debugging, we can use the assert statement and the print function to achieve data assertion and viewing. - -```python -a = 1 -print("The value of a is", a) -assert a == 1 -``` - -In addition, we can also use the kcl-test test tool to write KCL internal test cases - -Assuming there is a hello.k file, the code is as follows: - -```python -schema Person: - name: str = "kcl" - age: int = 1 - -hello = Person { - name = "hello kcl" - age = 102 -} -``` - -Construct the hello_test.k test file with the following contents: - -```python -schema TestPerson: - a = Person{} - assert a.name == 'kcl' - -schema TestPerson_age: - a = Person{} - assert a.age == 1 - -schema TestPerson_ok: - a = Person{} - assert a.name == "kcl" - assert a.age == 1 -``` - -Then execute the kcl-test command in the directory: - -``` -$ kcl-test -ok /pkg/to/app [365.154142ms] -$ -``` - -## 44. How to define and use functions in KCL? - -The schema structure acts as a function to a certain extent, and this function has the ability to have multiple input parameters and multiple output parameters. For example, the following code can implement the function of a Fibonacci sequence: - -```python -schema Fib: - n: int - value: int = 1 if n <= 2 else (Fib {n: n - 1}).value + (Fib {n: n - 2}).value - -fib8 = (Fib {n: 8}).value -``` - -The output is - -```yaml -fib8: 21 -``` - -A schema function that merges lists into dictionaries - -```python -schema UnionAll[data, n]: - _?: [] = data - value?: {:} = ((UnionAll(data=data, n=n - 1) {}).value | data[n] if n > 0 else data[0]) if data else {} - -schema MergeList[data]: - """Union all elements in a list returns the merged dictionary - - [{"key1": "value1"}, {"key2": "value2"}, {"key3": "value3"}] -> {"key1": "value1", "key2": "value2", "key3": "value3"} - """ - _?: [] = data - value?: {:} = (UnionAll(data=data, n=len(data) - 1) {}).value if data else {} -``` - -In addition, KCL supports defining a function using the `lambda` keyword: - -```python -func = lambda x: int, y: int -> int { - x + y -} -a = func(1, 1) # 2 -``` - -A lambda function has the following properties: - -- A lambda function takes the value of the last expression as the return value of the function, and an empty function body returns None. -- The return value type annotation can be omitted, the return value type is the type of the last expression value. -- There are no order-independent features in the function body, all expressions are executed in order. - -```python -_func = lambda x: int, y: int -> int { - x + y -} # Define a function using the lambda expression -_func = lambda x: int, y: int -> int { - x - y -} # Ok -_func = lambda x: int, y: int -> str { - str(x + y) -} # Error (int, int) -> str can't be assigned to (int, int) -> int -``` - -A lambda function cannot participate in any computation and can only be used in assignment and call statements. - -```python -func = lambda x: int, y: int -> int { - x + y -} -x = func + 1 # Error: unsupported operand type(s) for +: 'function' and 'int(1)' -``` - -```python -a = 1 -func = lambda x: int { - x + a -} -funcOther = lambda f, para: int { - f(para) -} -r = funcOther(func, 1) # 2 -``` - -The output is - -```python -a: 1 -r: 2 -``` - -We can define an anonymous function and call it directly - -```python -result = (lambda x, y { - z = 2 * x - z + y -})(1, 1) # 3 -``` - -Anonymous functions can be also used in for loops - -```python -result = [(lambda x, y { - x + y -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 3, 3, 4] -``` - -Functions can be defined and used in the KCL schema - -```python -_funcOutOfSchema = lambda x: int, y: int { - x + y -} -schema Data: - _funcInSchema = lambda x: int, y: int { - x + y - } - id0: int = _funcOutOfSchema(1, 1) - id1: int = _funcInSchema(1, 1) - id2: int = (lambda x: int, y: int { - x + y - })(1, 1) -``` - -The output YAML is - -```yaml -data: - id0: 2 - id1: 2 - id2: 2 -``` - -## 45. Why do we get an error when a variable is assigned an enumeration type (a literal union type)? - -In KCL, a attribute defined as a literal union type is only allowed to receive a literal value or a variable of the same literal union type during assignment. For example, the following code is correct: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -data = Data { - color = "Red" # Ok, can be assigned as "Red", "Yellow" and "Blue" -} -``` - -However the following code is wrong: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -_color = "Red" - -data = Data { - color = _color # Error: expect str(Red)|str(Yellow)|str(Blue), got str -} -``` - -This is because there is no type declared for the variable `_color`, it will be deduced by the KCL compiler as a `str` string type, so when a "larger" type `str` is assigned to a "smaller" type `"Red" | "Yellow" | "Blue"` will report an error, one solution is to declare a type for the `_color` variable, the following code is correct: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -_color: "Red" | "Yellow" | "Blue" = "Red" - -data = Data { - color = _color # Ok -} -``` - -Further, we can use type aliases to simplify enumeration (writing of literal union types), such as the following code: - -```python -type Color = "Red" | "Yellow" | "Blue" # Define a type alias, which can be reused in different places, reducing the amount of code writing - -schema Data: - color: Color - -_color: Color = "Red" - -data = Data { - color = _color # Ok -} -``` - -## 46. Procedural for loop - -KCL provides comprehensions and all/any/map/filter expressions for processing a collection element, which meets most needs, and provides a procedural for loop body. Providing a procedural for loop body is not very demanding from the current scenario, so there is no procedural for loop support yet. - -In addition, although KCL does not support procedural for loops, it is possible to "construct" corresponding procedural for loops through for loops and lambda functions. - -```python -result = [(lambda x: int, y: int -> int { - # Write procedural for loop logic in the lambda function. - z = x + y - x * 2 -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 2, 4, 4] -``` - -## 47. Default variables are immutable - -The immutability of KCL variables means that the exported variables starting with non-underscore `_` in the KCL top-level structure cannot be changed after initialization. - -```python -schema Person: - name: str - age: int - -a = 1 # a will be output to YAML, once assigned it cannot be modified -_b = 1 # _b The variable is named with an underscore and will not be output to YAML. It can be modified by multiple assignments -_b = 2 -alice = Person { - name = "Alice" - age = 18 -} -``` - -There are two ways of specifying that variables are immutable: - -- non-underscore top-level variables outside the schema - -```python -a = 1 # immutable exported variable -_b = 2 # mutable non-export variable -``` - -## 48. Is there a type like Go `interface{}`/`any` or Java `Object` in KCL? - -In KCL, we can use the `any` type annotation to define a variable to store any values such as integers, strings and schemas. For example: - -```python -schema Data: - id: int = 1 - -var_list: [any] = [1, "12", Data {}] -``` - -The output YAML is - -```yaml -var_list: - - 1 - - "12" - - id: 1 -``` - -In addition, we can also use the `typeof` function to determine the type of variables during KCL code execution: - -```python -schema Data1: - id: int = 1 - -schema Data2: - name: str = "name" - -data_list: [any] = [Data1 {}, Data2 {}] -data_type_list: [str] = [typeof(data) for data in data_list] -``` - -The output YAML is - -```yaml -data_list: - - id: 1 - - name: name -data_type_list: - - Data1 - - Data2 -``` - -## 49. How to develop a KCL plugin? - -KCL plugins are installed in the plugins subdirectory of KCL (usually installed in the `$HOME/.kcl/plugins` directory), or set through the `$KCL_PLUGINS_ROOT` environment variable. Besides, the `plugins` directory could also be placed at the `pwd` path. For plugin developers, plugins are managed in the [Git repository](https://github.com/kcl-lang/kcl-plugin), and the plugin repository can be cloned to this directory for development. - -KCL has built-in kcl-plugin scaffolding command to assist users to write KCL plug-ins in Python language, so that the corresponding plug-ins can be called in the KCL file to enhance the KCL language itself, such as accessing the network, reading and writing IO, CMDB query and encryption and decryption functions. - -``` -usage: kcl-plugin [-h] {list,init,info,gendoc,test} ... - -positional arguments: - {list,init,info,gendoc,test} - kcl plugin sub commands - list list all plugins - init init a new plugin - info show plugin document - gendoc gen all plugins document - test test plugin - -optional arguments: - -h, --help show this help message and exit -``` - -For example, if you want to develop a plugin named io, you can use the following command to successfully create a new io plugin - -``` -kcl-plugin init io -``` - -Then you can use the following command to get the root path of the plugin and cd to the corresponding io plugin directory for development - -``` -kcl-plugin info -``` - -For example, if you want to develop a function read_file to read a file, you can write python code in `plugin.py` of `$plugin_root/io`: - -```python -# Copyright 2020 The KCL Authors. All rights reserved. - -import pathlib - -INFO = { - 'name': 'io', - 'describe': 'my io plugin description test', - 'long_describe': 'my io plugin long description test', - 'version': '0.0.1', -} - - -def read_file(file: str) -> str: - """Read string from file""" - return pathlib.Path(file).read_text() - -``` - -In addition, you can write the corresponding test function in `plugin_test.py`, or you can directly write the following KCL file for testing: - -```python -import kcl_plugin.io - -text = io.read_file('test.txt') -``` - -You can also use the info command to view information about the io plugin - -``` -kcl-plugin info io -``` - -``` -{ - "name": "io", - "describe": "my io plugin description test", - "long_describe": "my io plugin long description test", - "version": "0.0.1", - "method": { - "read_file": "Read string from file" - } -} -``` - -Finally, the plugin that has written the test can be merged with MR in the `kcl_plugins` repository. - -## 50. How to do basic type conversion in KCL - -You can use the `int()`, `float()` function and `str()` function to convert the basic types between `int`, `float` and `str`. - -``` -_t = 1 - -t_str: str = str(_t) # you will get "t_str: '1'" -t_int: int = int(t_str) # you will get "t_int: 1" -t_float: float = float(t_str) # you will get "t_float: 1.0" -``` - -For more information about type conversion, see [KCL Builtin Types](https://kcl-lang.io/docs/reference/lang/tour#built-in-types) and [KCL Type System](https://kcl-lang.io/docs/reference/lang/tour#type-system). diff --git a/versioned_docs/version-0.5.3/user_docs/support/support.md b/versioned_docs/version-0.5.3/user_docs/support/support.md deleted file mode 100644 index fac13ef2..00000000 --- a/versioned_docs/version-0.5.3/user_docs/support/support.md +++ /dev/null @@ -1,3 +0,0 @@ -# FAQ - -KCL frequently asked questions. diff --git a/versioned_docs/version-0.5.4/community/contribute/_category_.json b/versioned_docs/version-0.5.4/community/contribute/_category_.json deleted file mode 100644 index e2dca064..00000000 --- a/versioned_docs/version-0.5.4/community/contribute/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Contribution Guide", - "position": 4 -} diff --git a/versioned_docs/version-0.5.4/community/contribute/contribute-code.md b/versioned_docs/version-0.5.4/community/contribute/contribute-code.md deleted file mode 100644 index f4e9169b..00000000 --- a/versioned_docs/version-0.5.4/community/contribute/contribute-code.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -sidebar_position: 2 ---- - -# How to Contribute Code? - -Welcome to participate in the KCL co construction to improve the code, documentation and testing, and also welcome to provide feedback through Issues. If you want to add KCL language features, please submit through the [KEP](https://github.com/kcl-lang/KEP) process. - -## 1. Misspellings in Code and Comments - -If you only need to modify the typos in the code and comments, you can directly modify and submit the PR to the repository. It is important to keep the code style as consistent as possible. - -## 2. How to Contribute KCL - -See [KCL contribute guide](https://github.com/kcl-lang/kcl/blob/main/docs/dev_guide/1.about_this_guide.md) for more information. - -## 3. How to Contribute VS Code KCL Plugin - -See [VS Code KCL plugin contribute guide](https://github.com/kcl-lang/vscode-kcl/blob/main/docs/CONTRIBUTING.md) for more information. diff --git a/versioned_docs/version-0.5.4/community/contribute/contribute-docs.md b/versioned_docs/version-0.5.4/community/contribute/contribute-docs.md deleted file mode 100644 index 2b400a52..00000000 --- a/versioned_docs/version-0.5.4/community/contribute/contribute-docs.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -sidebar_position: 1 ---- - -# How to Contribute Document? - -This document mainly makes partial modifications to existing documents. If you are submitting blog posts, adding new documents or adjusting the document directory structure, please contact team members first. - -KCL documents are divided into user guides, development documents, internal documents, reference manuals and blog articles. Their differences are as follows: - -- User's Guide: The corresponding usage document allows users to quickly use the KCL tool to complete their work at the minimum cost, without involving too much internal principles and implementation -- Reference: KCL language, tools, IDE and other documents with all features, covering the most extensive but trivial content -- Blog: There are no special restrictions. They can be shared for specific scenarios, technical points or overall development prospects - -When contributing different types of documents, it is better to combine the above positioning to make some appropriate tailoring for different content to give readers the best experience. - -## 1. Basic Specifications - -- In addition to the title, the internal subtitles shall be numbered as much as possible for easy reading -- The document automatically output by the tool needs a link to the source code, and the subtitle can be without number -- Try not to paste large pieces of code (within 30 lines). It is better to provide text explanations and corresponding reference links for the code -- There are diagrams and truths, but overly complex architecture diagrams are not recommended -- Internal link: in the form of [`/docs/user_docs/getting-started/intro`](/docs/user_docs/getting-started/intro) absolute path - -**Punctuation and space** - -- Chinese punctuation is preferred in Chinese documents -- One space is required between Chinese and English -- One space needs to be added between Chinese and numbers -- Chinese uses full width punctuation without adding spaces before and after punctuation -- English content uses half width punctuation, with a space after the punctuation -- You need to leave a space before and after the link, but you do not need to add a space near the beginning of the paragraph and Chinese full width punctuation. - -**Picture and resource file names** - -- The file name and directory name can only use numbers, English letters and underscores`_` And minus sign '-' -- Pictures of the current document are placed in the images directory of the current directory -- Vector pictures can be viewed through [drawio offline version](https://github.com/jgraph/drawio-desktop/releases) (and submit source files at the same time), and export png format pictures at 200% resolution - -## 2. Basic mode of using document content - -Each usage document can be regarded as a relatively complete sharing or blog post (the reference manual is no longer such). Using documents to organize content follows the following pattern: - -1. Overview: What problems do you want to solve and what effects do you want to achieve in this article? You can put a screenshot of the final effect first -2. Dependent environment: what tools need to be installed, and provide relevant links -3. Introduce this article to build a relationship diagram or architecture diagram of resources -4. Give the test method. Try to use community common methods (such as kube, curl command, or browser) to test -5. Summary and Outlook. Briefly review the current operation process and some places that can be expanded (some links can be given) - -## 3. Test and submit PR - -First, clone the document warehouse, and then test the viewing effect locally with the 'npm run start' and 'npm run build' commands to ensure that you can browse normally and then submit PR. diff --git a/versioned_docs/version-0.5.4/community/contribute/contribute.md b/versioned_docs/version-0.5.4/community/contribute/contribute.md deleted file mode 100644 index dd6e2b3f..00000000 --- a/versioned_docs/version-0.5.4/community/contribute/contribute.md +++ /dev/null @@ -1,3 +0,0 @@ -# Contribute Guide - -If it is the first time to participate in the open-source community, you can first check the similar changes in Issue and PR (PullRequest). Then you can fully discuss your own problems with the community or development team classmates, and you can also feedback the problems encountered by creating issues, and then you can provide code patches for related issues. At the beginning, you can start with document improvement and partial code improvement, such as: documentation, Examples, multi-language Binding, etc. At the same time, students who want to participate deeply can contribute to core features such as language functions, language testing, programming frameworks, and various backends. diff --git a/versioned_docs/version-0.5.4/community/contribute/git-guideline.md b/versioned_docs/version-0.5.4/community/contribute/git-guideline.md deleted file mode 100644 index 7d427c01..00000000 --- a/versioned_docs/version-0.5.4/community/contribute/git-guideline.md +++ /dev/null @@ -1,130 +0,0 @@ -# Git Commit Guide - -This document describes the matters needing attention when Git submits changes. If you refuse to accept the contents of this article, the submitted changes will not be accepted. - -## 1. About issue - -Before submitting an issue, please check the closed issue. There may already be an appropriate solution in the closed issue. - -If no suitable solution is found, we provide four templates to use when creating an issue. - -- Bug Report: If a bug is found, you can contact us by creating an issue through the bug report template. -- Enhancement: The developer has enhanced the tool, and can create an issue through the enhancement template to introduce the added content. -- Feature Request: If you want to add some new features or functions to the tool during use, you can create an issue through the Feature Request template to describe the new features. -- Ask a Question: If you have any questions, you can create an issue through the Ask a Question template to contact us. - -After selecting the appropriate template, you only need to fill in the required content on the template. If you find that there is no template or the template content is empty when creating the issue, you can feed back this problem to us through WeChat group, nail group or email. - -## 2. About Git Branch - -To contribute code to KCL, you must have a GitHub account so that you can push the code to your own branch and create pull requests. We recommend reference [Angular Specification]( https://github.com/angular/angular.js/blob/master/DEVELOPERS.md# -Git commit guidelines) name your own branches. - -The recommended format is as follows: - -``` -{type}-{a_short_description} -``` - -The branch name mainly includes two fields, which are separated by "-". Including: - -- `{type}`: the type of the current branch content. -- `{a_short_description}`: A short description of the main content of this branch. - -For example, Alice first transfers the Fork warehouse to his own account, and then creates a branch with the corresponding name 'alice: fix output fmt bug' (Alice's account is before the colon) to fix the output formatting bug. - -## 3. 关于 Git Commit - -We refer to [Commitizen](https://github.com/commitizen/cz-cli) to write a Commit Message. - -``` -Note: If you directly use Commit to generate a Commit Message, please note that -It is a tool for developers to manage commit. It is not related to the project itself, so it is an intermediate product generated by Commiten -(For example, the node_modules file directory) may not be in the project. gitignore file. - -You can git add {filename} select the file to submit and ignore the intermediate product. -Or you can add the following content to the. gitignore file and automatically ignore the intermediate products: -# commitizen -package.json -package-lock.json -node_modules/* -``` - -If you manually write a commit Message, we also recommend [Commiten](https://github.com/commitizen/cz-cli) for the commit message format. - -``` -{type} ( {component_or_file} ) {a_short_description} -{a_longer_description} -BREAKING CHANGE: {breaking_change_description}. -{linked issue} -``` - -It mainly includes 6 fields: - -- `{type}`: the type of the branch corresponding to the current commit. -- `{component_or_file}`: the name of the module or file that the current commit changes. -- `{a_short_description}`: A short description describes the content of the commit. -- `{a_longer_description}`: The detailed description is used to introduce the content in the commit. -- `{breaking_change_description}`: If the commit contains broken compatibility changes, the impact of compatibility changes needs to be introduced. -- `{linked issue}`: the issue associated with the current commit. - -Where `{breaking_change_description}` and `{linked issue}` can be omitted if the commit does not contain compatibility breaking changes and associated issues. - -For example, the commit created by Alice in branch 'alice: fix output fmt bug'. - -``` -fix(kcl-printer): fix an output format bug in kcl-printer - -There is an output format bug in kcl-printer because ..., -So, The calling of method "XXX" is replaced by "HHHH"..., -... - ---If there is no change to break the compatibility and the associated issue, the following contents can be omitted. -BREAKING CHANGE: This change maybe cause ....... - -fix #123 -``` - -## 4. About pull request - -Before submitting a PR, priority may be given to the following issues: - -- Please check the closed PRs first. There may be completed solutions in the closed PRs. -- We suggest that before submitting the change, submit a corresponding issue to describe the problems to be solved in the change, and associate the PR corresponding to the change with the issue. -- After submitting the PR to us, please sign [Contributor License Agreement (CLA)] (# cla). If you refuse to sign, we will not accept the PR. -- Make sure that each change creates a new branch and names the branch according to the specifications mentioned above. -- PR should not exceed two commit at a time. Please compress the extra commit with squash and write a commit message according to the specifications mentioned above. -- We provide [PR template](https://github.com/kcl-lang/.github/blob/main/.github/PULL_REQUEST_TEMPLATE.md). You only need to add the content required in the template. If you find no template or the template content is empty when creating a PR, you can feed back this problem to us through WeChat group, nail group or email. - -We suggest that the PR title be consistent with the branch name and the commit message style: - -``` -{type} ( {component_name_or_file_name} ) :{a_short_description} -``` - -比如,Alice 为分支`fix/alice/fix_output_fmt_bug`创建的PR名称。 - -For example, Alice creates the PR name `fix/alice/fix_output_fmt_bug` for one branch. - -``` -fix(kcl-printer): fix an output format bug in kcl-printer. -``` - -## 5. Supported PR Types - -``` -- feat: -- New features have been added. -- fix: -- Bug is repaired. -- docs: -- The document part has been modified. -- style: -- The modification of code format does not affect the functions of the code, such as deleting redundant spaces, code indentation, etc. -- refactor: -- refactoring code without changing its function. -- perf: -- Performs performance optimization on the code. -- test: -- Add or adjust existing test cases. -- build: -- Adjust the build system or external dependent libraries. -- ci: -- The configuration file or script of the CI has been adjusted. -- choice: -- Adjustments to other parts of the source code and test files. -- reverse: -- Rollback commit. -``` - -## 6. Contributor License Agreement (CLA) - -After the PR is submitted to us for the first time, the CLA check in the PR will fail and prompt to sign the CLA. You can reply "I have read the CLA Document and I hereby sign the CLA" between your accounts in PR to agree to sign the CLA, and then manually restart the failed CLA check action. After PR is successfully merged, it will be locked and cannot be modified. diff --git a/versioned_docs/version-0.5.4/community/intro/_category_.json b/versioned_docs/version-0.5.4/community/intro/_category_.json deleted file mode 100644 index a9646363..00000000 --- a/versioned_docs/version-0.5.4/community/intro/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Community", - "position": 1 -} diff --git a/versioned_docs/version-0.5.4/community/intro/intro.md b/versioned_docs/version-0.5.4/community/intro/intro.md deleted file mode 100644 index 4b1a7f02..00000000 --- a/versioned_docs/version-0.5.4/community/intro/intro.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Community - -Welcome to the KCL open-source community, everyone's participation is the driving force for the healthy growth of all open-source projects! There are many ways to participate in open-source. Everyone can create Issues or fix bugs, improve documentation or modify code by submitting PR (Pull Request), or open new feature discussions by submitting KEP, or share stories about the process of evangelism and use of KCL with surrounding friends. - -See the [community](https://github.com/kcl-lang/community) for ways to join us. diff --git a/versioned_docs/version-0.5.4/community/intro/license.md b/versioned_docs/version-0.5.4/community/intro/license.md deleted file mode 100644 index 4d0097b4..00000000 --- a/versioned_docs/version-0.5.4/community/intro/license.md +++ /dev/null @@ -1,211 +0,0 @@ ---- -sidebar_position: 99 ---- - -# License - -KCL Use [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) License: - -``` - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2023 The KCL Authors. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -``` diff --git a/versioned_docs/version-0.5.4/community/intro/support.md b/versioned_docs/version-0.5.4/community/intro/support.md deleted file mode 100644 index 7ed2e1a8..00000000 --- a/versioned_docs/version-0.5.4/community/intro/support.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Ask for help - -KCL has a developer and user community of many enthusiasts. - -On this page, we list the KCL-related communities you can participate in; see other pages in this section for additional online and offline learning materials. - -Before joining the KCL community, please read the [Contributor Covenant](https://www.contributor-covenant.org/version/2/0/code_of_conduct/) , which is expected to be followed by all community members. - -## Discussions - -- Submit an issue on Github -- Communicate in the Github discussion group -- Get the latest status through official website, Github, Twitter, Slack, Wechat and other accounts. See the [community](https://github.com/kcl-lang/community) for ways to join us. - -## New Features - -Please try to avoid submitting pull requests for new features, we may already have someone working on them, or maybe this feature is already part of our future plans. In conclusion, please contact us before submitting new features! diff --git a/versioned_docs/version-0.5.4/community/release-policy/_category_.json b/versioned_docs/version-0.5.4/community/release-policy/_category_.json deleted file mode 100644 index bc39d651..00000000 --- a/versioned_docs/version-0.5.4/community/release-policy/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Release Policy", - "position": 3 -} diff --git a/versioned_docs/version-0.5.4/community/release-policy/index.md b/versioned_docs/version-0.5.4/community/release-policy/index.md deleted file mode 100644 index c87091d0..00000000 --- a/versioned_docs/version-0.5.4/community/release-policy/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# Release Policy - -The release policy defines the semantics of the release, the release process, etc. In order to maximize the concurrent development process, KCL, etc. adopt independent release strategies. diff --git a/versioned_docs/version-0.5.4/community/release-policy/kcl.md b/versioned_docs/version-0.5.4/community/release-policy/kcl.md deleted file mode 100644 index a24e1509..00000000 --- a/versioned_docs/version-0.5.4/community/release-policy/kcl.md +++ /dev/null @@ -1,39 +0,0 @@ -# KCL Release Policy - -KCL 开发团队采用 [语义化版本](https://semver.org/lang/zh-CN/) 来简化管理。版本格式:主版本号.次版本号.修订号。版本号递增规则如下:主版本号对应不兼容的 API 修改,次版本号对应向下兼容的功能性新增,修订号对应向下兼容的问题修正。总体目标是每一个半月发布一个特性增强的次要版本,根据需要不定期发布其他版本的修订。 - -KCL 项目版本发布策略如下: - -- 主版本号:当进行重大的架构调整或者加入重大的新功能时,需要提升主版本号。对于 KCL 项目来说,目前的主版本号为 0。 -- 次版本号:当添加的功能和特性有较大的变化时,提升次版本号。目前的次版本号为 5,2023 年度会相继发布 0.5, 0.6, 0.7 版本。 -- 修订号:通过修复漏洞或者改进性能来更新程序时,会提升修订号,修订号从 0 开始计数以此加 1。 -- 发布周期:在未达到 v1.0.0 版本之前,计划每隔 3 个月发布一个新的次要版本。在此期间,需要持续收集用户反馈,并进行必要的修复和改进。 -- 发布流程:在发布新版本之前,需要进行严格的测试和审核,确保新版本的质量。封板并测试完成后,会在 Github 上发布新版本的源代码,二进制和镜像,并提供详细的文档和使用指南。 -- 版本支持:我们将对最新的版本提供长期支持,包括漏洞修复和安全更新。对于旧版本,我们将提供有限的支持,仅在必要时进行修复。 - -## 发布流程与规则 - -- 特性开发:main 分支主干开发,分支发布,block 用户使用的问题和严重的 bug, 安全隐患,高优先级解决,尽可能保持在一周内收敛,高于一般的功能研发。 -- 迭代周期:我们的迭代周期通常为 3 个月,即每 3 个月发布一个新的次要版本。 -- 版本规划:发版前两周产出 alpha 版本,前一周产出 beta 版本,alpha 版本仍可进行特性合并,beta 版本只合并错误修复,最终产出正式版本并打 tag 作为长期保存的 release 分支。 -- 发版计划:在每个发布周期开始时制定详细的发版计划(Github Milestone),包括发布日期、版本号、功能列表和测试计划等。需要尽可能地遵守发版计划,确保按时发布新版本。 -- 发布前测试:在发布新版本之前,需要进行全面的测试,包括单元测试、集成测试,模糊测试,压测,用户验收测试等。只有经过测试并无问题后,我们才会发布新版本。 -- 版本回滚:如果在发布后发现了严重的问题,需要立即回滚版本,并尽快修复问题。并通过邮件、社交媒体等渠道及时通知用户,并提供解决方案。 -- 发布文档:需要在发布时提供详细的文档,包括发布说明、更新日志、API 文档和使用指南等,帮助用户了解和使用新版本。在 KCL 中,我们统一在 KCL 网站进行维护。 -- 版本兼容性:在发布新版本时,需要尽可能保持兼容性,以确保用户无需进行过多的修改和适应。KCL 还没有达到 v1,暂时没有兼容性保证。KCL 的目标是尽可能少地进行重大更改,不应轻率地考虑对语言的更改,为了语言自身更好地演进和发展,一般认为更改具有重大好处时才会进行(较好地解决了目标场景的问题或者提升了绝大用户的使用体验)。对于可能引入兼容性问题的功能或变更,提供相应的提示和解决方案,同时会提供逐步升级的指南或提供自动迁移的工具,以帮助用户平滑地迁移到新版本。 - -## 发布组件 - -![](/img/docs/community/release-policy/kcl-components.png) - -每次版本发布时,KCL 相关所有组件保持一个依赖同一个 KCL 核心主要版本,整体采用树形结构组织依赖顺序发布并进行回归测试,直到发布测试完成,尽力避免三角依赖,禁止循环依赖。 - -## 一个 Feature 的生命周期 - -- 设计方案/文档:通过 Issue 回答清楚这个 feature 的动机是什么,它解决什么问题以及目标是什么,用户需求和用户故事是怎样的;这个 feature 做什么,如何做,难度怎样,需要多长时间,依赖项,需要做什么测试等。(Tips: 大的设计尽量拆分成小的设计,通过权衡和广泛的调研找到一个简单且可持续的解决方案,并且具备一定得到可扩展以适应未来的业务或技术变化,通过持续讨论和方案评审确定最终设计)。 -- 编写代码:通过高频小改动进行迭代、持续沟通和协作,提前设计单元测试、集成测试和 benchmark 等测试用例,确保编写代码 100% 测试覆盖,注释完整和逻辑清晰,并通过 Demo 演示持续收集反馈。 -- 文档撰写:在 [KCL 网站](https://kcl-lang.io) 中更新用户文档。 -- 测试和反馈:在发布功能之前,让一些同行/用户通过**随循文档**而不是口述来尝试和测试这些新功能。接收反馈并改进。 -- 发布和公告:撰写 Release Note, PR 文章,场景和新特性解读等以及渠道宣发等。 - -> 注:以上所有信息全是公开的,需要透出给所有社区研发者进行参与、讨论和贡献。 diff --git a/versioned_docs/version-0.5.4/community/release-policy/roadmap.md b/versioned_docs/version-0.5.4/community/release-policy/roadmap.md deleted file mode 100644 index df220576..00000000 --- a/versioned_docs/version-0.5.4/community/release-policy/roadmap.md +++ /dev/null @@ -1,3 +0,0 @@ -# Roadmap - -![](/img/docs/community/release-policy/roadmap.jpg) diff --git a/versioned_docs/version-0.5.4/reference/_advanced-concepts/_category_.json b/versioned_docs/version-0.5.4/reference/_advanced-concepts/_category_.json deleted file mode 100644 index 85a16abb..00000000 --- a/versioned_docs/version-0.5.4/reference/_advanced-concepts/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Advanced-Concepts", - "position": 6 -} diff --git a/versioned_docs/version-0.5.4/reference/_advanced-concepts/build_cache.md b/versioned_docs/version-0.5.4/reference/_advanced-concepts/build_cache.md deleted file mode 100644 index 746e2351..00000000 --- a/versioned_docs/version-0.5.4/reference/_advanced-concepts/build_cache.md +++ /dev/null @@ -1 +0,0 @@ -# Building Cache diff --git a/versioned_docs/version-0.5.4/reference/_category_.json b/versioned_docs/version-0.5.4/reference/_category_.json deleted file mode 100644 index 1b337d5a..00000000 --- a/versioned_docs/version-0.5.4/reference/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Reference", - "position": 5 -} diff --git a/versioned_docs/version-0.5.4/reference/cheatsheets/_category_.json b/versioned_docs/version-0.5.4/reference/cheatsheets/_category_.json deleted file mode 100644 index 80464148..00000000 --- a/versioned_docs/version-0.5.4/reference/cheatsheets/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Cheat Sheet", - "position": 10 -} diff --git a/versioned_docs/version-0.5.4/reference/cheatsheets/index.md b/versioned_docs/version-0.5.4/reference/cheatsheets/index.md deleted file mode 100644 index da4189eb..00000000 --- a/versioned_docs/version-0.5.4/reference/cheatsheets/index.md +++ /dev/null @@ -1,5 +0,0 @@ -# KCL Cheat Sheet - -![](/img/docs/reference/cheatsheets/cheatsheet.png) - -[Download PDF](https://github.com/kcl-lang/kcl-lang.io/blob/main/cheatsheet/cheatsheet.pdf) diff --git a/versioned_docs/version-0.5.4/reference/lang/_category_.json b/versioned_docs/version-0.5.4/reference/lang/_category_.json deleted file mode 100644 index 4c823148..00000000 --- a/versioned_docs/version-0.5.4/reference/lang/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Tutorial", - "position": 1 -} diff --git a/versioned_docs/version-0.5.4/reference/lang/codelab/_category_.json b/versioned_docs/version-0.5.4/reference/lang/codelab/_category_.json deleted file mode 100644 index 2e047bcb..00000000 --- a/versioned_docs/version-0.5.4/reference/lang/codelab/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Code Lab", - "position": 2 -} diff --git a/versioned_docs/version-0.5.4/reference/lang/codelab/collaborative.md b/versioned_docs/version-0.5.4/reference/lang/codelab/collaborative.md deleted file mode 100644 index 84ee8160..00000000 --- a/versioned_docs/version-0.5.4/reference/lang/codelab/collaborative.md +++ /dev/null @@ -1,345 +0,0 @@ ---- -title: "Co-configuration with config operations" -linkTitle: "Co-configuration with config operations" -type: "docs" -weight: 2 -description: Co-configuration with config operations -sidebar_position: 3 ---- - -## 1. Introduction - -KCL is a simple and easy-to-use configuration language, where users can simply write the reusable configuration code. - -In this codelab, we will learn how to write the config in a collaborative way using the KCL config operation features. - -### What We Will Learn - -1. Define schemas and organize project directories. -2. Create multiple environment configurations via the KCL config operation features. -3. Configure compiling parameters and tests. - -## 2. Define Schemas and Organize Project Directories - -### Schema Definitions - -Suppose we want to define a server configuration with certain attributes, we can create a simple config by creating a `server.k`, we can fill in the following code as below which defines a reusable schema of the configuration of a server. - -```python -import units - -type Unit = units.NumberMultiplier - -schema Server: - replicas: int = 1 - image: str - resource: Resource = {} - mainContainer: Main = {} - labels?: {str:str} - annotations?: {str:str} - -schema Main: - name: str = "main" - command?: [str] - args?: [str] - ports?: [Port] - -schema Resource: - cpu?: int = 1 - memory?: Unit = 1024Mi - disk?: Unit = 10Gi - -schema Port: - name?: str - protocol: "HTTP" | "TCP" - port: 80 | 443 - targetPort: int - - check: - targetPort > 1024, "targetPort must be larger than 1024" -``` - -In the code above, we define a schema named `Server`, which represents the configuration type that the user will write, which contains some basic type attributes (e.g., `replicas`, `image`, etc) and some composite type attributes (e.g., `resource`, `main`, etc). In addition to some basic types mentioned in the [schema codelab](./schema.md), we can see two types in the above code `Unit` and `units.NumberMultiplier`. Among them, `units.NumberMultiplier` denotes the KCL number unit type, which means that a natural unit or binary unit can be added after the KCL number, such as `1K` for `1000`, `1Ki` for `1024`. `Unit` is the type alias of `units.NumberMultiplier`, which is used to simplify the writing of type annotations. - -### Project Directories - -In order to complete the collaborative configuration development, we first need a configuration project, which contains the configuration of the test application and the differential configuration of different environments, so we are creating the following project directory: - -``` -. -├── appops -│ └── test_app -│ ├── base -│ │ └── base.k -│ ├── dev -│ │ ├── ci-test -│ │ │ └── stdout.golden.yaml -│ │ ├── kcl.yaml -│ │ └── main.k -│ └── prod -│ ├── ci-test -│ │ └── stdout.golden.yaml -│ ├── kcl.yaml -│ └── main.k -├── kcl.mod -└── pkg - └── sever.k -``` - -The directory of the project mainly contains three parts: - -- `kcl.mod`: The file used to identify the root directory of the KCL project. -- `pkg`: `Server` Schema structure reused by different application configurations. -- `appops`: Server configurations of different applications, currently only one application `test_app` is placed. - - `base`: Application common configurations for all environments. - - `dev`: Application configuration for the development environment. - - `prod`: Application configuration for the production environment. - -The meaning of `base.k`, `main.k`, `kcl.yaml` and `ci-test/stdout.golden.yaml` will be mentioned in subsequent sections. - -## 3. Create multiple environment configurations via the KCL config operation features - -### Create a baseline configuration - -After we have organized the project directory and the basic server configuration model, we can write the configuration of the user application. We can create our own test application folder `test_app` and place it in the application configuration folder `appops`. - -For the configuration of an application, we often divide it into a basic configuration and the differential configuration of multiple environments and merge them. Through the configuration merging feature of KCL, we can easily do this. Assuming that we have two configurations of development environment and production environment, we can create three folders: `base`, `dev` and `prod` to store baseline, development environment and production environment configurations respectively. First, we write the configuration of `base/base.k`: - -```python -import pkg - -server: pkg.Server { - # Set the image with the value "nginx:1.14.2" - image = "nginx:1.14.2" - # Add a label app into labels - labels.app = "test_app" - # Add a mainContainer config, and its ports are [{protocol = "HTTP", port = 80, targetPort = 1100}] - mainContainer.ports = [{ - protocol = "HTTP" - port = 80 - targetPort = 1100 - }] -} -``` - -As in the above code, we use the `import` keyword in `base.k` to import the `Server` schema placed under `pkg` and use it to instantiate a configuration named `server`, in which we set `image` attribute to `"nginx:1.14.2"`, and a label `app` with the value `test_app` is added. In addition, we also added the configuration of the main container `mainContainer` with the value `[{protocol = "HTTP", port = 80, targetPort = 1100}]` for the ports attribute. - -KCL command: - -```bash -kcl appops/test_app/base/base.k -``` - -Output: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2 - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app -``` - -At this point, we have a baseline configuration. - -### Create multiple environment configurations - -Next we configure a differentiated multi-environment configuration. First assume that we want to use a temporary image of our own `nginx:1.14.2-dev` in the development environment, and then use it to override the server configuration in the baseline, we can write the following configuration in `dev/main.k`: - -```python -import pkg - -server: pkg.Server { - # Override the image declared in the base - image = "nginx:1.14.2-dev" -} -``` - -KCL command: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -Output: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app -``` - -It can be seen that the `image` field of the output YAML is overwritten to `nginx:1.14.2-dev`. Suppose we also want to add a label to the `dev` environment with a key of `env` and a value of `dev`, we add the following code to `dev/main.k`: - -```python -import pkg - -server: pkg.Server { - # Override the image declared in the base - image = "nginx:1.14.2-dev" - # Union a new label env into base labels - labels.env = "dev" -} -``` - -KCL command: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app - env: dev -``` - -It can be seen that there are two labels in the `labels` field of the output YAML. - -In addition, we can also use the `+=` operator to add new values to list type attributes, such as the `mainContainer.ports` configuration in the baseline environment, continue to modify the code in `dev/main.k`: - -```python -import pkg - -server: pkg.Server { - # Override the base image. - image = "nginx:1.14.2-dev" - # Union a new label env into base labels. - labels.env = "dev" - # Append a port into base ports. - mainContainer.ports += [{ - protocol = "TCP" - port = 443 - targetPort = 1100 - }] -} -``` - -KCL command: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -Output: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - - protocol: TCP - port: 443 - targetPort: 1100 - labels: - app: test_app - env: dev -``` - -Using the same method, we can build the production configuration, write the code in the `dev/main.k` file, and add a label to it. - -```python -import pkg - -server: pkg.Server { - # Union a new label env into base labels - labels.env = "prod" -} -``` - -KCL command: - -```bash -kcl appops/test_app/base/base.k appops/test_app/prod/main.k -``` - -Output: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2 - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app - env: prod -``` - -## 4. Configure compiling parameters and tests - -In the previous section, we built a multi-environment configuration through code. It can be seen that the KCL command line compilation parameters of different environments are similar, so we can configure these compilation parameters into a file and input them to the KCL command line for invocation. Configure the following code in `dev/kcl.yaml`: - -```yaml -kcl_cli_configs: - files: - - ../base/base.k - - main.k - output: ./ci-test/stdout.golden.yaml -``` - -Then we can compile the configuration in the development environment with the following command: - -```bash -cd appops/test_app/dev && kcl -Y ./kcl.yaml -``` - -In addition, we have configured the `output` field in `dev/kcl.yaml` to output YAML to a file for subsequent configuration distribution or testing. You can verify that the application's configuration is as expected by walking through the `kcl.yaml` builds in each environment and comparing with `./ci-test/stdout.golden.yaml`. - -## 5. The Final Step - -Congratulations! - -We have completed the third lesson about KCL. diff --git a/versioned_docs/version-0.5.4/reference/lang/codelab/index.md b/versioned_docs/version-0.5.4/reference/lang/codelab/index.md deleted file mode 100644 index dbe554a9..00000000 --- a/versioned_docs/version-0.5.4/reference/lang/codelab/index.md +++ /dev/null @@ -1 +0,0 @@ -# Code Lab diff --git a/versioned_docs/version-0.5.4/reference/lang/codelab/schema.md b/versioned_docs/version-0.5.4/reference/lang/codelab/schema.md deleted file mode 100644 index 02f792d4..00000000 --- a/versioned_docs/version-0.5.4/reference/lang/codelab/schema.md +++ /dev/null @@ -1,817 +0,0 @@ ---- -title: "Write complex config using KCL Schema" -linkTitle: "Write complex config using KCL Schema" -type: "docs" -weight: 2 -description: Write complex config using KCL Schema -sidebar_position: 2 ---- - -## 1. Introduction - -KCL is a simple and easy-to-use configuration language, where users can simply write the reusable configuration code. - -In this codelab, we will learn how to write customized config using KCL, such that we can define a schema and write the config in a collaborative way. - -### What We Will Learn - -1. Define a simple schema -2. Set default immutable values to schema fields -3. Create config based on a simple schema -4. Write complex logic in schema -5. Create a new schema via schema combinations -6. Create a config of a deeply nested schema using dict/map -7. Create new schema via schema inheritance -8. Create new schema via multiple mixin schemas -9. Declare validation rules for the schema -10. Config schema output layout -11. Share and reuse schema - -## 2. Write Simple Schema - -Suppose we want to define a workload with certain attributes, we can create a simple config by creating a `my_config.k`, we can fill in the following code as below which defines a reusable schema of the configuration of deploy. - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels: {str:str} -``` - -In the code above, `cpu` and `memory` are defined as int value; `name`, `image` and `service` are string; `command` is a list of string type; `labels` is a dict type, whose key type and value type are both string. - -Besides, each attribute **must** be assigned with a not-None value as a schema instance unless it is modified by a question mark **?** as an optional attribute. - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels?: {str:str} # labels is an optional attribute -``` - -When there is an inheritance relationship: - -- If the attribute is optional in the base schema, it could be optional or required in the sub-schema. -- If the attribute is required in the base schema, it must be required in the sub-schema. - -## 3. Enhance Schema as Needed - -Suppose we need to set default values to service and replica, we can make them as below: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str = "my-service" # defaulting - replica: int = 1 # defaulting - command: [str] - labels?: {str:str} # labels is an optional attribute -``` - -And then we can set the service type annotation as the string literal type to make it immutable: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: "my-service" = "my-service" - replica: int = 1 - command: [str] - labels?: {str:str} -``` - -In the schema, type hint is a `must`, for example we can define cpu as `cpu: int`. - -Specially, we can define a string-interface dict as `{str:}`, and in case we want to define an object or interface, just define as `{:}`. - -## 4. Create Config Based on Simple Schema - -Now we have a simple schema definition, we can use it to define config as: - -```python -nginx = Deployment { - name = "my-nginx" - cpu = 256 - memory = 512 - image = "nginx:1.14.2" - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } -} -``` - -Run with the following KCL command, we should be able to see the generated yaml files as the output as below: - -KCL command: - -``` - kcl my_config.k -``` - -Stdout: - -```yaml -nginx: - name: my-nginx - cpu: 256 - memory: 512 - image: nginx:1.14.2 - service: my-service - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -> Check the manual and specification out for more details about collection data types and block. - -In addition, the **config selector expressions** can be used to init a schema instance, and we can ignore the comma at the end of the line in the config expression. - -```python -nginx = Deployment { - name = "my-nginx" - cpu = 256 - memory = 512 - image = "nginx:1.14.2" - command = ["nginx"] # Ignore the comma at the end of the line - labels.run = "my-nginx" # A dict variable in schema can use selector expressions - labels.env = "pre-prod" # A dict variable in schema can use selector expressions -} -``` - -## 5. Write More Complex Logic in Schema - -Suppose we have some schema logic, we can wrapper it into schema: - -```python -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - image: str - service: "my-service" = "my-service" - replica: int = 1 - command: [str] - labels?: {str:str} - - _cpu = 2048 - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 -``` - -Now, we can define a config by creating a schema instance and pass in priority as an argument to schema: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -Run with kcl, we should see the generated yaml files as output as below: - -KCL command: - -``` -kcl my_config.k -``` - -Stdout: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - image: nginx:1.14.2 - service: my-service - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 6. Create New Schema via Schema Combinations - -Now we want to define a detailed schema with service and volumes, we can do it as follows: - -```python -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - volumes?: [Volume] - image: str - service?: Service - replica: int = 1 - command: [str] - labels?: {str:str} - - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 - -schema Port: - name: str - protocol: str - port: int - targetPort: int - -schema Service: - name: "my-service" = "my-service" - ports: [Port] - -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -In this case, Deployment is composed of Service and a list of Volumes, and Service is composed of a list of Ports. - -## 7. Create Config of Deeply Nested Schema using Dict/Map - -Now we have a new Deployment schema, however, we may notice that it contains multiple layers of nested structures, in fact, this is very common in complex structure definitions, and we often have to write imperative assembly code to generate the final structure. - -With KCL, we can create the config with simple dict declaration, with the capability of full schema initialization and validation. For example, we can simply config nginx by the new Deployment schema as follows: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -Run with KCL, we will see the generated yaml files as below: - -KCL command: - -``` -kcl my_config.k -``` - -Stdout: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -Note that, the dict that we use to define Deployment config must be aligned with the schema definition, otherwise we will get an error. For example, suppose we define a wrong type of service port as below: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = [80] # wrong data type, trying to assign List to int - targetPort = 9376 - }] -} -``` - -Run with KCL, we will see the error message as output as below: - -KCL command: - -```python -kcl my_config.k -``` - -Stderr: - -``` -The type got is inconsistent with the type expected: expect int, got [int(80)] -``` - -## 8. Declare Schema Validation Rules - -Now we have seen a complex schema, in which every field has a type hint to make it less error-prone. But this is not good enough, we want to support more enhanced verifications to our schemas, so that code errors in schemas and configs can be discovered as soon as possible. - -Lots of validation rules, like None type check, range check, value check, length check, regular expression matching, enum check have already been added or in progress. Here is a code sample: - -```python -import regex - -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - volumes?: [Volume] - image: str - service?: Service - replica: int = 1 - command: [str] - labels?: {str:str} - - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 - - check: - multiplyof(cpu, 256), "cpu must be a multiplier of 256" - regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$"), "image name should be like 'nginx:1.14.2'" - 1 <= replica < 100, "replica should be in range (1, 100)" - len(labels) >= 2 if labels, "the length of labels should be large or equal to 2" - "env" in labels, "'env' must be in labels" - len(command) > 0, "the command list should be non-empty" - -schema Port: - name: str - protocol: str - port: int - targetPort: int - - check: - port in [80, 443], "we can only expose 80 and 443 port" - protocol in ["HTTP", "TCP"], "protocol must be either HTTP or TCP" - 1024 < targetPort, "targetPort must be larger than 1024" - -schema Service: - name: "my-service" = "my-service" - ports: [Port] - - check: - len(ports) > 0, "ports list must be non-empty" - -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -Since the attributes defined by the schema are **required** by default, the verification that judges that the variable cannot be None/Undefined can be omitted. - -```python -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -Now we can write the config based on the new schema and expose config errors in time. For example, with the invalid config as below: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1142" # image value is not matching the regex - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -Every field is type-valid, but the image name is invalid. - -Run with KCL, we will see the error message as below: - -KCL command: - -``` -kcl my_config.k -``` - -Stderr: - -``` -Schema check is failed to check condition: regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$"), "image name should be like 'nginx:1.14.2'" -``` - -> The verification capability of KCL covers the verification defined by Openapi so that we can write any API verifications through KCL. - -## 9. Create New Schema via Schema Inheritance - -Now we have a solid Deployment schema definition and we can use it to declare config. - -Usually, schema Deployment will be used in multiple scenarios. We can directly use the schema to declare the configurations in different use cases (see the above section), or we can produce a more specific schema definition through inheritance. - -For example, we can use the Deployment schema as a basis, to define the nginx's base schema, and extend the definition -in each scenario. - -In this case, we define some commonly used attributes. Please note that we mark the name to be immutable with the 'final' keyword to prevent it from being overwritten. - -```python -schema Nginx(Deployment): - """ A base nginx schema """ - name: "my-nginx" = "my-nginx" - image: str = "nginx:1.14.2" - replica: int = 3 - command: [str] = ["nginx"] - -schema NginxProd(Nginx): - """ A prod nginx schema with stable configurations """ - volumes: [Volume] = [{ - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - """ A volume mapped to host path """ - service: Service = { - ports = [{ - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] - } - """ An 80 port to target backend server """ -``` - -Now we have some static configurations for nginx. It is recommended to declare configurations that we think are static there, and put more dynamic configurations as below: - -```python -nginx = Nginx { - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -```python -nginx = NginxProd { - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -Now, we can simply define nginx prod config just with runtime label value "prod" which is not that static. - -In fact, under some complex situation, we can split all configurations into the basic, business, and environment configuration definitions in this way, and achieve collaboration among team members based on this. - -Run with KCL, we will see the generated yaml files as output as below: - -KCL command: - -``` -kcl prod_config.k -``` - -Stdout: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 3 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 10. Create New Schema by Multiple Protocol and Mixin Schemas Inheritance - -Now, we can complete the declaration of the server configuration through the Deployment schema. - -However, usually, the actual situation is more complicated, and the deployment may have a variety of optional variable accessories. - -For example, we want to support a persistent volume claim based on an existing schema, as a reusable Kubernetes schema. In this case, we can just wrapper it with a `mixin` and a `protocol` as follows: - -```python -import k8spkg.api.core.v1 - -protocol PVCProtocol: - pvc?: {str:} - -mixin PersistentVolumeClaimMixin for PVCProtocol: - """ - PersistentVolumeClaim (PVC) sample: - Link: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims - """ - - # Mix in a new attribute `kubernetesPVC` - kubernetesPVC?: v1.PersistentVolumeClaim - - if pvc: - kubernetesPVC = v1.PersistentVolumeClaim { - metadata.name = pvc.name - metadata.labels = pvc.labels - spec = { - accessModes = pvc.accessModes - resources = pvc.resources - storageClassName = pvc.storageClassName - } - } -``` - -With this PersistentVolumeClaimMixin, we define a PVC schema with a clear `user interface`, and use Kubernetes PVC as an implementation. Then, we can define a server schema with Deployment schema, and PVC mixin schema. - -``` -schema Server(Deployment): - mixin [PersistentVolumeClaimMixin] - pvc?: {str:} - """ pvc user interface data defined by PersistentVolumeClaimMixin """ -``` - -In the Server schema, Deployment is the base schema, and PersistentVolumeClaimMixin is an optional add-on whose user interface data is `pvc?: {str:}`. - -Note, the `mixin` is often used to add new attributes to the host schema, or to modify the existing attributes of the host schema. Thus, `mixin` can use the attributes in the host schema. Since the `mixin` is designed to be reusable, we need an additional `protocol` to constrain the attribute names and types in the host schema for the `mixin`. - -Now, if we want a deploy with a PVC, just declare as user interface: - -```python -server = Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] - pvc = { - name = "my_pvc" - accessModes = ["ReadWriteOnce"] - resources.requests.storage = "8Gi" - storageClassName = "slow" - } -} -``` - -Run with kcl, we will see the generated yaml files as output as below: - -KCL command: - -``` -kcl server.k -``` - -Stdout: - -```yaml -server: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod - pvc: - name: my_pvc - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 8Gi - storageClassName: slow ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: my_pvc -spec: - accessModes: - - ReadWriteOnce - storageClassName: slow - resources: - requests: - storage: 8Gi -``` - -If we don't want a persistent volume, just remove the pvc config block. - -## 11. Share and Reuse Schema - -The Server schema could be shared via `import`, we can simply package our code with KCL. - -```python -import pkg - -server = pkg.Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -Another skill we should know about sharing code is, modules under the same package do not need to import each other. - -Suppose we have models in a pkg: - -``` -pkg/ - - deploy.k - - server.k - - pvc.k -``` - -And in `server.k`, we can just use Deployment schema in `deploy.k` and pvc schema in `pvc.k` without import: - -```python -# no import needed -schema Server(Deployment): - mixin [PersistentVolumeClaimMixin] - pvc?: {str:} - """ pvc user interface data defined by PersistentVolumeClaimMixin """ -``` - -And then users must import the pkg to use it as a whole: - -```python -import pkg - -server = pkg.Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [pkg.Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } - service.ports = [pkg.Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -Run kcl command: - -``` -kcl pkg_server.k -``` - -Output: - -```yaml -server: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 12. The Final Step - -Congratulations! - -We have completed the second lesson about KCL, we have used KCL to replace our key-value text file to get better programming support. diff --git a/versioned_docs/version-0.5.4/reference/lang/codelab/simple.md b/versioned_docs/version-0.5.4/reference/lang/codelab/simple.md deleted file mode 100644 index 56be5805..00000000 --- a/versioned_docs/version-0.5.4/reference/lang/codelab/simple.md +++ /dev/null @@ -1,495 +0,0 @@ ---- -title: "Write simple config with KCL" -linkTitle: "Write simple config with KCL" -type: "docs" -weight: 2 -description: Write simple config with KCL -sidebar_position: 1 ---- - -## 1. Introduction - -KCL is a simple and easy-to-use configuration language, where users can simply write the reusable configuration code. - -In this first codelab, we will learn how to write a simple config with KCL. - -Learning this codelab only requires basic programming knowledge, and experience with python will make it even easier. - -### What We Will Learn - -1. Write simple key-value configuration in a programmable way -2. Write simple logic in KCL code -3. Write collections in KCL code -4. Test and debug with KCL code -5. Use built-in support in KCL code -6. Share and reuse KCL code -7. Write config with dynamic input arguments - -## 2. Write Key-Value Pairs - -Generate a simple config by creating a `my_config.k`, we can fill in the following code without strict format which describes the configuration of deploy. - -```python -cpu = 256 -memory = 512 -image = "nginx:1.14.2" -service = "my-service" -``` - -In the code above, cpu and memory are declared as int value, while image and service are string literal. - -Run with KCL, we will see the generated data in yaml format as below: - -KCL command: - -```bash -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -The exported variable is immutable by default so that once it is declared, we can't modify it some where else. - -## 3. Write Simple Logic - -Sometimes we want to write a logic in configuration, then we can use: - -- Mutable and non-exported variable starting with `_` -- If-else statement - -A non-exported variable means it will not appear in the output YAML, and it can be assigned multiple times. - -Here is a sample to show how to adjust the resource with conditions. - -KCL command: - -```python -kcl my_config.k -``` - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -image = "nginx:1.14.2" -service = "my-service" -``` - -Run with KCL, we will see the generated data in yaml format as below: - -```python -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -.. note:: -KCL has rich support of operators and string member functions, please read manual and specification for more details. - -## 4. Write Collections - -We can use collections to represent complex data types. The collections which are already supported are: - -- list -- dict - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -command = ["nginx"] # a list -labels = {run = "my-nginx"} # a dict -image = "nginx:1.14.2" -service = "my-service" -``` - -Run with kcl, we will see the generated data as yaml format as below: - -KCL command: - -```bash -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx -image: nginx:1.14.2 -service: my-service -``` - -> Check manual and specification out for more about collection date type and member functions. - -## 5. Append Items Into Collections - -We can combine logical expressions, comprehensions, slices, unions and other characteristics to dynamically add elements to the collection - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable -_env = "pre-prod" - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -_command = ["nginx"] # a list -_command = _command + ["-f", "file"] # Append items into command using + operator to contact two lists -command = [c.lower() for c in _command] # Take each element in the list to lowercase -_labels = { - run = "my-nginx" - if _env: - env = _env # Append a dict key-value pair when the _env is not None/Undefined or empty using if expressions -} # a dict -labels = _labels -image = "nginx:1.14.2" -service = "my-service" -``` - -Run with kcl, we will see the generated data as yaml format as below: - -```python -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 256 -memory: 512 -command: - - nginx - - -f - - file -labels: - run: my-nginx -image: nginx:1.14.2 -service: my-service -``` - -## 6. Write Assert - -To make code testable and robust, we can verify config data with assertions. - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -command = ["nginx"] # a list -labels = {run = "my-nginx"} # a dict -image = "nginx:1.14.2" -service = "my-service" -assert "env" in labels, "env label is a must" -assert cpu >= 256, "cpu cannot be less than 256" -``` - -Run with KCL, we will see eval failure with an error message as output as below: - -```bash -kcl my_config.k -``` - -Stderr: - -```bash -Assertion failure: env label is a must. -``` - -After adding env:pre-prod pair into labels, we will get the output as: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 7. Use Handy Built-in Support - -What's more, we can use built-in functions to help we debug or simplify coding. - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -_name = "nginx" -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # a list -labels = { - run = "my-{}".format(_name) - env = "pre-prod" -} # a dict -image = "{}:1.14.2".format(_name) # string format -service = "my-service" - -# debugging -print(labels) # debugging by print - -# test -assert len(labels) > 0, "labels can't be empty" # use len() to get list length -assert "env" in labels, "env label is a must" -assert cpu >= 256, "cpu cannot be less than 256" -``` - -This sample shows how we use `format()`, `len()`, `print()` function to help customize the config. - -Run with KCL, we will see the generated data in yaml format as below: - -KCL command: - -```bash -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -run: my-nginx -env: pre-prod -``` - -Note: more built-in functions and modules can be seen in spec/module - -## 8. Reuse Variables in Another Module - -To make our code well-organized, we can simply separate our code to `my_config.k` and `my_config_test.k`. - -Config data defined in `my_config.k`, - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 -_name = "nginx" - -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # a list -labels = { - run = "my-{}".format(_name) - env = "pre-prod" -} # a dict -image = "{}:1.14.2".format(_name) # string format -service = "my-service" -``` - -And test code defined in `my_config_test.k`, in which we can import `my_config.k`: - -```python -import my_config - -# debugging -print(my_config.labels) # debugging by print - -# test -assert len(my_config.labels) > 0, "labels can't be empty" # use len() to get list length -assert "env" in my_config.labels, "env label is a must" -assert my_config.cpu >= 256, "cpu cannot be less than256" -``` - -## 9. Config with Input Arguments - -Sometimes we need to get external input via parameters dynamically from the end user or platform. - -In this case, we can pass in `priority` and `env` on demand: - -- Pass in arguments: `-D priority=1 -D env=pre-prod` -- Get value by `option` keyword in KCL code - -```python -_priority = option("priority") # a non-exported and mutable variable -_env = option("env") # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -_name = "nginx" -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # a list -labels = { - run = "my-{}".format(_name) - env = _env -} # a dict -image = "{}:1.14.2".format(_name) # string format -service = "my-service" -``` - -Run with KCL, we will see the generated data in yaml format as below: - -```bash -kcl my_config.k -D priority=2 -D env=pre-prod -``` - -Stdout: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 10. Simplify Logic Expression using Dict - -When we need to write complex logic, we can use dict to simplify the writing of logic. - -```python -_priority = option("priority") # a non-exported and mutable variable -_env = option("env") # a non-exported and mutable variable -_priorityCpuMap = { - "1" = 256 - "2" = 512 - "3" = 1024 -} -# Using a dict to simplify logic and the default value is 2048 -_cpu = _priorityCpuMap[_priority] or 2048 -_name = "nginx" -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # a list -labels = { - run = "my-{}".format(_name) - env = _env -} # a dict -image = "{}:1.14.2".format(_name) # string format -service = "my-service" -``` - -Run with KCL, we will see the generated data in yaml format as below: - -KCL command: - -```bash -kcl my_config.k -D priority=2 -D env=pre-prod -``` - -Stdout: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 11. The Final Step - -Congratulations! - -We have completed the first lesson about KCL, we have used KCL to replace our key-value text file to get better programming support. - -Please check schema codelab out now to learn how to write an advanced config collaboratively with KCL `schema` mechanism. diff --git a/versioned_docs/version-0.5.4/reference/lang/error/_category_.json b/versioned_docs/version-0.5.4/reference/lang/error/_category_.json deleted file mode 100644 index 95062745..00000000 --- a/versioned_docs/version-0.5.4/reference/lang/error/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Errors and Warnings", - "position": 4 -} diff --git a/versioned_docs/version-0.5.4/reference/lang/error/exception.md b/versioned_docs/version-0.5.4/reference/lang/error/exception.md deleted file mode 100644 index 92c527a6..00000000 --- a/versioned_docs/version-0.5.4/reference/lang/error/exception.md +++ /dev/null @@ -1,1427 +0,0 @@ ---- -title: "KCL Errors and Warnings" -linkTitle: "KCL Errors and Warnings" -type: "docs" -weight: 2 -description: KCL Errors and Warnings ---- - -The articles in this section of the documentation explain the diagnostic error and warning messages that are generated by the KCL. - -**Important:** -**The KCL can report many kinds of errors and warnings. After an error or warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not apply to your project. When you correct issues in your project, always start with the first error or warning that's reported and rebuild often. One fix may make many subsequent errors go away.** - -In the following sections you will find: - -[KCL Syntax Error (E1xxx)](#11-kcl-syntax-error-e1xxx) : The KCL may reports KCL syntax errors when illegal syntax is used in KCL program. - -[KCL Compile Error (E2xxx)](#12-kcl-compile-error-e2xxx): The KCL may reports KCL compile errors when the KCL program conforms to the KCL syntax but does not conform to the KCL semantics. - -[KCL Runtime Error (E3xxx)](#13-kcl-runtime-error-e3xxx): The KCL may report KCL runtime errors when the virtual machine executing a KCL program that passes the compilation. - -[KCL Compile Warning (W2xxx)](#14-kcl-compile-warning-w2xxx): When the compiler compiles KCL programs and finds possible potential errors, such warnings will be reported by KCL. - -## 1.1 KCL Syntax Error (E1xxx) - -This section mainly includes KCL errors: - -| ewcode | KCL exception | messages | -| ------ | ------------------------------------------------------------------- | ----------------------- | -| E1001 | [InvalidSyntaxError](#111-invalidsyntaxerror-e1001) | Invalid syntax | -| E1002 | [KCLTabError](#112-kcltaberror-e1002) | Tab Error | -| E1003 | [KCLIndentationError](#113-kclindentationerrore1003) | Indentation Error | -| E1I37 | [IllegalArgumentSyntaxError](#114-illegalargumentsyntaxerror-e1i37) | Illegal argument syntax | - -### 1.1.1 InvalidSyntaxError (E1001) - -KCL will report `InvalidSyntaxError` when KCL has a syntax error. - -The `ewcode` of `InvalidSyntaxError` is `E1001`. - -For example: - -```python -a, b = 1, 2 # Multiple assign is illegal in KCL syntax -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> /syntax_error/general/multiple_assign/case0/main.k:1:2 - | -1 | a, b = 1, 2 # Multiple assign is illegal in KCL syntax - | ^ expected statement - | -``` - -Possible resolution: - -- Check and fix KCL syntax errors based on the KCL Language Standard - -### 1.1.2 KCLTabError - -KCL will report `KCLTabError` when KCL has a tab and white space syntax error. - -In KCL, it is forbidden to mix tabs and four spaces in one indentation block. And we recommend only using white spaces or tabs for indentation in the entire KCL project, don’t mix them. - -For example: - -```python -schema Person: - name: str # begin with a tab - age: int # begin with four white spaces, - # and four white spaces != tab in the env -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> File /syntax_error/tab/tab_error_0/main.k:6:5 - | -3 | age: int = 1 - | ^ inconsistent use of tabs and spaces in indentation - | -``` - -Possible resolution: - -- Only use a tab or four white spaces in KCL, do not mix them. - -### 1.1.3 KCLIndentationError - -KCL will report `KCLIndentationError` when KCL has an indentation syntax error. - -The KCL syntax includes indentation. A tab or four white spaces in KCL represents an indentation. The other cases will be regarded as syntax errors by KCL. - -For example: - -```python -schema Person: - name: str # a tab or four white spaces is legal. - age: int # three white spaces are illegal - info: str # two white spaces is illegal -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> /syntax_error/indent/indent_error_0/main.k:3:4 - | -3 | age: int # three white spaces are illegal - | ^ unindent 3 does not match any outer indentation level - | -``` - -Possible resolution: - -- Only use a tab or four white spaces in the KCL program for indentation. - -### 1.1.4 IllegalArgumentSyntaxError (E1I37) - -KCL will report `IllegalArgumentSyntaxError` when KCL has an illegal argument in KCL syntax. - -For example: - -```python -# Parameters without default values -# must be in front of parameters with default values. -a = option(type="list", default={"key": "value"}, "key1") -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> /option/type_convert_fail_2/main.k:3:57 - | -3 | a = option(type="list", default={"key": "value"}, "key1") - | ^ positional argument follows keyword argument - | -``` - -Possible resolution: - -```python -func(input_1, ..., input_n, param_with_key_1 = input_with_key_1, ..., param_with_key_n = input_with_key_n) -``` - -## 1.2 KCL Compile Error (E2xxx) - -This section mainly includes KCL errors: - -| ewcode | KCL exception | messages | -| ------ | ---------------------------------------------------------------------- | --------------------------------------------------- | -| E2F04 | [CannotFindModule](#121-cannotfindmodulee2f04) | Cannot find the module | -| E2F05 | [FailedLoadModule](#122-failedloadmodulee2f05) | Failed to load module | -| E2H13 | [UnKnownDecoratorError](#123-unknowndecoratorerrore2h13) | UnKnown decorator | -| E2H14 | [InvalidDecoratorTargetError](#124-invaliddecoratortargeterrore2h14) | Invalid Decorator Target | -| E2C15 | [MixinNamingError](#125-mixinnamingerrore2c15) | Illegal mixin naming | -| E2C16 | [MixinStructureIllegal](#126-mixinstructureillegale2c16) | Illegal mixin structure | -| E2B17 | [CannotAddMembersComplieError](#127-cannotaddmemberscomplieerrore2b17) | Cannot add members to a schema | -| E2B20 | [IndexSignatureError](#128-indexsignatureerrore2b20) | Invalid index signature | -| E2G22 | [TypeComplieError](#129-typecomplieerrore2g22) | The type got is inconsistent with the type expected | -| E2L23 | [CompileError](#1210-compileerrore2l23) | A complie error occurs during compiling | -| E2L25 | [KCLNameError](#1211-kclnameerrore2l25) | Name Error | -| E2L26 | [KCLValueError](#1212-kclvalueerrore2l26) | Value Error | -| E2L27 | [KCLKeyError](#1213-kclkeyerrore2l27) | Key Error | -| E2L28 | [UniqueKeyError](#1214-uniquekeyerrore2l28) | Unique key error | -| E2A29 | [KCLAttributeComplieError](#1215-kclattributecomplieerrore2a29) | Attribute error occurs during compiling | -| E2D32 | [MultiInheritError](#1216-multiinheriterrore2d32) | Multiple inheritance is illegal | -| E2D34 | [IllegalInheritError](#1217-illegalinheriterrore2d34) | Illegal inheritance | -| E2I36 | [IllegalArgumentComplieError](#1218-illegalargumentcomplieerrore2i36) | Illegal argument during compiling | -| E3L41 | [ImmutableCompileError](#1219-immutablecompileerror-e3l41) | Immutable variable is modified | - -### 1.2.1 CannotFindModule(E2F04) - -KCL will report `CannotFindModule` when KCL imports a module that does not exist. - -The `ewcode` of `CannotFindModule` is `E2F04`. - -For example: - -```python -import .some0.pkg1 as some00 # some0 not found in package - -Name1 = some00.Name # some0.pkg1.name -``` - -The KCL program will cause the following error message. - -```shell -error[E2F04]: CannotFindModule - --> import_abs_fail_0/app-main/main.k:1:1 - | -1 | import .some0.pkg1 as some00 # some0 not found in package - | Cannot find the module .some0.pkg1 - | -``` - -Possible resolution: - -- Add the import module file under the import path. - -### 1.2.2 FailedLoadModule(E2F05) - -KCL will report `FailedLoadModule` when an error occurs during loading a KCL external package. - -The `ewcode` of `FailedLoadModule` is `E2F05`. - -Possible resolution: - -- Check whether the module file is readable. -- Check whether the module file is a KCL file. - -### 1.2.3 UnKnownDecoratorError(E2H13) - -KCL will report `UnKnownDecoratorError` when an unknown decorator is used in KCL. - -The `ewcode` of `UnKnownDecoratorError` is `E2H13`. - -For example: - -```python -@err_deprecated # It is an unknown decorator -schema Person: - firstName: str = "John" - lastName: str - name: str - -JohnDoe = Person { - name: "deprecated" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> deprecated/unknown_fail_1/main.k:1:2 - | -1 | @err_deprecated # 这是一个非法的装饰器 - | ^ UnKnown decorator err_deprecated - | -``` - -Possible resolution: - -- Check whether the decorator exists. - -### 1.2.4 InvalidDecoratorTargetError(E2H14) - -KCL will report `InvalidDecoratorTargetError` when the target cannot be the target of the decorator. - -The `ewcode` of `InvalidDecoratorTargetError` is `E2H14`. - -Possible resolution: - -- Check whether the decorator in KCL is illegal. - -### 1.2.5 MixinNamingError(E2C15) - -KCL will report `MixinNamingError` when a mixin name does not end with 'Mixin'. - -The `ewcode` of `MixinNamingError` is `E2C15`. - -For example: - -```python -schema Person: - firstName: str - lastName: str - fullName: str - -schema Fullname: # It is a mixin, but 'Fullname' is not end with 'Mixin - fullName = "{} {}".format(firstName, lastName) - -schema Scholar(Person): - mixin [Fullname] - school: str - -JohnDoe = Scholar { - "firstName": "John", - "lastName": "Doe", - "fullName": "Doe Jon" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2D34]: IllegalInheritError - --> mixin/invalid_name_failure/main.k:10:12 - | -10 | mixin [Fullname] - | ^ illegal schema mixin object type 'Fullname' - | -``` - -Possible resolution: - -- If the schema is a mixin, then the name of the schema should end with Mixin. - -### 1.2.6 MixinStructureIllegal(E2C16) - -KCL will report `MixinStructureIllegal` when the KCL structure is illegal. - -The `ewcode` of `MixinStructureIllegal` is `E2C16`. - -Possible resolution: - -- Check the structure of schema as Mixin. - -### 1.2.7 CannotAddMembersComplieError(E2B17) - -KCL will report `CannotAddMembersComplieError` when members that are not in the schema are used. - -The `ewcode` of `CannotAddMembersComplieError` is `E2B17`. - -For example: - -```python -schema Girl: - gender: str = "female" - -alice = Girl { - "first": "alice", # "first" can not be found in schema Girl - "last": " Green", # "last" can not be found in schema Girl - "age": 10 # "age" can not be found in schema Girl -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:5:5 - | -5 | "first": "alice", - | ^ Cannot add member 'first' to schema 'Girl' - | - -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:6:5 - | -6 | "last": " Green", - | ^ Cannot add member 'last' to schema 'Girl' - | - -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:7:5 - | -7 | "age": 10 - | ^ Cannot add member 'age' to schema 'Girl' - | -``` - -Possible resolution: - -- Add the members to the schema. -- Remove the using of the members not exists - -### 1.2.8 IndexSignatureError(E2B20) - -The `ewcode` of `IndexSignatureError` is `E2B20`. - -KCL will report `IndexSignatureError` when: - -1. Multiple index signatures in one schema. - -For example: - -```python -schema Data: - [str]: str - [str]: int # Multiple index signatures in one schema. - -data = Data { - name: "test" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError ----> index_signature/fail_1/main.k:3:5 - | -3 | [str]: int - | 5 ^ only one index signature is allowed in the schema - | -``` - -Possible resolution: - -- Remove the extra index signature in the schema. - -2. The name of index signature attributes has the same name that conflicts with other attributes in the schema. - -For example: - -```python -schema Data: - name: str # name - [name: str]: str # the same name with the above attribute - -data = Data { - name: "test" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: IndexSignatureError - --> index_signature/fail_2/main.k:3:5 - | -3 | [name: str]: str # the same name with the above attribute - | ^ index signature attribute name 'name' cannot have the same name as schema attributes - | -``` - -Possible resolution: - -- Remove attributes or index signatures that have conflicts with the same name in the schema, or change their names. - -3. Schema index signature value type has conflicts with the instance of schema. - -For example: - -```python -schema Data: - [str]: int - -data = Data { - name: "test" # Conflict with [str]:int, "test" is a string. -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> index_signature/fail_3/main.k:5:5 - | -5 | name: "test" # Conflict with [str]:int, "test" is a string. - | ^ expected int, got str(test) - | -``` - -Possible resolution: - -- Check that the type of schema index signature is consistent with the attribute type in the schema instance. - -4. Schema index signature has conflicts with schema. - -For example: - -```python -schema Data: - count: int # got int - [str]: str # except str - -data = Data { - count: 1 -} -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: IndexSignatureError - --> index_signature/fail_4/main.k:2:5 - | -2 | count: int - | ^ the type 'int' of schema attribute 'count' does not meet the index signature definition [str]: str - | -``` - -Possible resolution: - -- Change schema for index signature or change index signature for schema. - -### 1.2.9 TypeComplieError(E2G22) - -KCL will report `TypeComplieError` when a type error occurs in compiling type check. - -The `ewcode` of `TypeComplieError` is `E2G22`. - -For example: - -```python -schema Person: - firstName: str - lastName: int - -JohnDoe = Person { - "firstName": "John", - "lastName": "Doe" # Type Error,lastName: int,“Doe” is a string. -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> type/type_fail_0/main.k:7:5 - | -7 | "lastName": "Doe" # Type Error,lastName: int,“Doe” is a string. - | ^ expected int, got str(Doe) - | - - --> type/type_fail_0/main.k:3:5 - | -3 | lastName: int - | ^ variable is defined here, its type is int, but got str(Doe) - | -``` - -Possible resolution: - -- Check that the type of value assigned to a variable is consistent with the type of the variable. - -### 1.2.10 CompileError(E2L23) - -The `ewcode` of `CompileError` is `E2L23`. - -KCL will report `CompileError` when: - -1. unsupport type union. - -For example: - -```python -_data = [1, 2, 3] -_data |= "value" -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> union/fail/fail_1/main.k:2:1 - | -2 | _data |= "value" - | ^ unsupported operand type(s) for |: '[int]' and 'str(value)' - | -``` - -Possible resolution: - -1. unsupported operand type. - -For example: - -```python -a = None -b = 1 + None # Unsupport operand type + for int and None -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> operator/operator_fail_0/main.k:2:5 - | -2 | b = 1 + None # Unsupport operand type + for int and None - | ^ unsupported operand type(s) for +: 'int(1)' and 'NoneType' - | -``` - -Possible resolution: - -- Adjust the operator so that it supports both operand types. -- Adjust the operands so that they conform to the constraints of the operator at the same time. - -1. variable is not defined. - -For example: - -```python -a = 1 -b = "${c + 1}" # 'c' is not defined -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> var_not_define_fail_0/main.k:2:8 - | -2 | b = "${c + 1}" # 'c' is not defined - | ^ name 'c' is not defined - | -``` - -Possible resolution: - -- Define undefined variables. -- Remove the undefined variable from the expression. - -1. invalid assign expression. - -For example: - -```python -# pkg.k -a = 1 - -# main.k -import pkg -pkg.a |= 2 -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> pkg_inplace_modify_1/main.k:3:1 - | -6 | pkg |= 2 - | ^ unsupported operand type(s) for |: 'module 'pkg'' and 'int(2)' - | -``` - -Possible resolution: - -- Check the assignment expression. - -1. invalid string expression. - -For example: - -```python -a = 1 -b = "${b = a + 1}" # Invalid string interpolation expression -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> invalid_format_value_fail_0/main.k:2:5 - | -2 | b = "${b = a + 1}" - | 5 ^ invalid string interpolation expression 'b = a + 1' - | -``` - -Possible resolution: - -- Check the string expression. - -1. invalid loop variable. - -For example: - -```python -data = {"key1": "value1", "key2": "value2"} -dataLoop = [i for i, j, k in data] # the number of loop variables can only be 1 or 2 -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> dict/invalid_loop_var_fail_0/main.k:2:25 - | -2 | dataLoop = [i for i, j, k in data] # the number of loop variables can only be 1 or 2 - | ^ the number of loop variables is 3, which can only be 1 or 2 - | -``` - -### 1.2.11 KCLNameError(E2L25) - -KCL will report `KCLNameError` when a name error occurs in compiling. - -The `ewcode` of `KCLNameError` is `E2L25`. - -### 1.2.12 KCLValueError(E2L26) - -KCL will report `KCLValueError` will be raised when a value error occurs in compiling. - -The `ewcode` of `KCLValueError` is `E2L25`. - -### 1.2.13 KCLKeyError(E2L27) - -KCL will report `KCLKeyError` will be raised when a key error occurs in compiling. - -The `ewcode` of `KCLKeyError` is `E2L25`. - -### 1.2.14 UniqueKeyError(E2L28) - -KCL will report `UniqueKeyError` when duplicate names appear in the KCL code. - -The `ewcode` of `UniqueKeyError` is `E2L28`. - -For example: - -```python -schema Person: - name: str = "kcl" - age: int = 1 - -schema Person: - aa: int - -x0 = Person{} -x1 = Person{age:101} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L28]: UniqueKeyError - --> /schema/same_name/main.k:5:8 - | -5 | schema Person: - | ^ Unique key error name 'Person' - | - - --> /schema/same_name/main.k:1:8 - | -1 | schema Person: - | ^ The variable 'Person' is declared here - | -``` - -Possible resolution: - -- Check if the name with error has been used. - -### 1.2.15 KCLAttributeComplieError(E2A29) - -KCL will report `KCLAttributeComplieError` when KCL has an illegal attribute in the schema. - -The `ewcode` of `KCLAttributeComplieError` is `E2A29`. - -For example: - -```python -# pkg -schema A: - field_A: str - -# main -import pkg as p - -a = p.D + 1 -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> /import/module/no_module_attr_fail_0/main.k:4:5 - | -4 | a = p.D + 1 - | ^ module 'pkg' has no attribute D - | -``` - -Possible resolution: - -- Check for the existence of the schema attribute when using it. - -### 1.2.16 MultiInheritError(E2D32) - -KCL will report `MultiInheritError` when multiple inheritance appears in the schema. - -The `ewcode` of `MultiInheritError` is `E2D32`. - -For example: - -```python -schema Person: - firstName: str - lastName: str - -schema KnowledgeMixin: - firstName: int - subject: str - -schema Scholar(KnowledgeMixin, Person): - school: str -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> /schema/inherit/multi_inherit_fail_1/main.k:9:30 - | -9 | schema Scholar(KnowledgeMixin, Person): - | ^ expected one of [")"] got , - | -``` - -Possible resolution: - -- Check the inheritance structure of the program, and multi-inheritance is not supported in KCL. - -### 1.2.17 IllegalInheritError(E2D34) - -KCL will report `IllegalInheritError` when an illegal inheritance occurs in the schema. - -The `ewcode` of `IllegalInheritError` is `E2D34`. - -For example: - -```python -schema FullnameMixin: - fullName = "{} {}".format(firstName, lastName) - -schema Scholar(FullnameMixin): # mixin inheritance is illegal - school: str -``` - -The KCL program will cause the following error message. - -```shell -error[E2D34]: IllegalInheritError - --> /schema/inherit/inherit_mixin_fail/main.k:4:16 - | -4 | schema Scholar(FullnameMixin): - | ^ invalid schema inherit object type, expect schema, got 'FullnameMixin' - | -``` - -Possible resolution: - -- Schema supports single inheritance of schema in KCL. - -### 1.2.18 IllegalArgumentComplieError(E2I36) - -KCL will report `IllegalArgumentComplieError` when the argument of option in KCL is illegal. - -The `ewcode` of `IllegalArgumentComplieError` is `E2I36`. -For example: - -```python -a = option("key") - -# kcl main.k -D key=value= -# key=value= is an illegal expression -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError -Invalid value for top level arguments -``` - -Possible resolution: - -- Check whether the KCL option arguments are legal. - -### 1.2.19 ImmutableCompileError (E3L41) - -KCL will report `ImmutableCompileError` when the value of the immutable variable changes. - -The `ewcode` of `ImmutableCompileError` is `E3L41`. - -For example: - -```python -a = 2147483646 -a += 1 -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: ImmutableError - --> augment_assign/main.k:2:1 - | -2 | a += 1 - | ^ Immutable variable 'a' is modified during compiling - | - - --> augment_assign/main.k:1:1 - | -1 | a = 2147483646 - | ^ The variable 'a' is declared here firstly - | -note: change the variable name to '_a' to make it mutable -``` - -Possible resolution: - -- Set immutable variables changed to private or remove immutable variables. - -## 1.3 KCL Runtime Error (E3xxx) - -This section mainly includes KCL errors: - -| ewcode | KCL exception | messages | -| ------ | ---------------------------------------------------------------------- | --------------------------------------------------- | -| E3F06 | [RecursiveLoad](#131-recursiveload-e3f06) | Recursively loading module | -| E3K04 | [FloatOverflow](#132-floatoverflow-e3k04) | Float overflow | -| E3K09 | [IntOverflow](#133-intoverflow-e3k09) | Integer overflow | -| E3N11 | [DeprecatedError](#134-deprecatederror-e3n11) | Deprecated error | -| E3A30 | [KCLAttributeRuntimeError](#135-kclattributeruntimeerror-e3a30) | Attribute error occurs at runtime | -| E3G21 | [TypeRuntimeError](#136-typeruntimeerror-e3g21) | The type got is inconsistent with the type expected | -| E3B17 | [SchemaCheckFailure](#137-schemacheckfailure-e3b17) | Schema check is failed to check condition | -| E3B19 | [CannotAddMembersRuntimeError](#138-cannotaddmembersruntimeerrore3b19) | Cannot add members to a schema | -| E3M38 | [EvaluationError](#139-evaluationerrore3m38) | Evaluation failure | -| E3M39 | [InvalidFormatSpec](#1310-invalidformatspec-e3m39) | Invalid format specification | -| E3M40 | [KCLAssertionError](#1311-kclassertionerror-e3m40) | Assertion failure | -| E3M44 | [ImmutableRuntimeError](#1312-immutableruntimeerror-e3m44) | Immutable variable is modified | -| E2D33 | [CycleInheritError](#1313-cycleinheriterror-e2d33) | Cycle Inheritance is illegal | -| E3M42 | [KCLRecursionError](#1314-kclrecursionerror-e3m42) | Recursively reference | - -### 1.3.1 RecursiveLoad (E3F06) - -KCL will report `RecursiveLoad` when a cycle import of external packages occurs in KCL. - -The `ewcode` of `RecursiveLoad` is `E2F06`. - -For example: - -```python -# module.k -import main # module.k imports main.k - -print('module') - -# main.k -import module # main.k imports module.k - -print('main') -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /import/recursive_import_fail/main.k:4 - | -2 | import module # main.k imports module.k - | ^ There is a circular import reference between module main and module - | -``` - -Possible resolution: - -- Check whether there is a circle import in KCL. - -### 1.3.2 FloatOverflow (E3K04) - -KCL will report `FloatOverflow` when a floating-point number overflows in KCL. - -The `ewcode` of `FloatOverflow` is `E3K04`. - -For example: - -```python -uplimit = 3.402823466e+39 -epsilon = 2.220446049250313e-16 -a = uplimit * (1 + epsilon) - -# kcl main.k -r -d -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /range_check_float/overflow/number_0/main.k:3:1 - | -3 | a = uplimit * (1 + epsilon) - | 3.4028234660000003e+39: A 32-bit floating point number overflow - | -``` - -Possible resolution: - -- Check whether the value of the float is the float range supported by KCL. - -### 1.3.3 IntOverflow (E3K09) - -KCL will report `IntOverflow` when an integer number overflows in KCL. - -The `ewcode` of `IntOverflow` is `E3K09`. - -For example: - -```python -_a = 9223372036854775807 -_a += 1 - -# kcl test.k -d -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /range_check_int/augment_assign_fail_1/main.k:2:1 - | -2 | _a += 1 - | 9223372036854775808: A 64 bit integer overflow - | -``` - -Possible resolution: - -- Check whether the value of the integer is the integer range supported by KCL. - -### 1.3.4 DeprecatedError (E3N11) - -KCL will report `DeprecatedError` when a deprecated variable is used and the strict is True. - -The `ewcode` of `DeprecatedError` is `E3N11`. - -For example: - -```python -schema Person: - firstName: str = "John" - lastName: str - @deprecated(version="1.16", reason="use firstName and lastName instead", strict=True) - name: str - -JohnDoe = Person { - name: "deprecated" # name is deprecated and strict is True -} -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /range_check_float/overflow/number_0/main.k:7:1 - | -7 | JohnDoe = Person { - | name was deprecated since version 1.16, use firstName and lastName instead - | -``` - -Possible resolution: - -- When strict is set to True, using deprecated code will cause an error and stop KCL. -- You can set the strict to False which will cause a warning insteads of an error. -- Adjust the code without using deprecated code. - -### 1.3.5 KCLAttributeRuntimeError (E3A30) - -KCL will report `KCLAttributeRuntimeError`, if an error occurs during dynamically accessing schema attributes through variables at runtime. - -The `ewcode` of `KCLAttributeRuntimeError` is `E3A30`. - -For example: - -```python -import math - -a = math.err_func(1) # err_func is not found in math -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /import/module/no_module_attr_fail_2/main.k:3:5 - | -3 | a = math.err_func(1) # err_func is not found in math - | ^ module 'math' has no attribute err_func - | -``` - -Possible resolution: - -- Check whether the attributes of schema are correct. - -### 1.3.6 TypeRuntimeError (E3G21) - -KCL will report `TypeRuntimeError` when an type error occurs in the runtime type check. - -The `ewcode` of `TypeRuntimeError` is `E3G21`. - -For example: - -```python -schema Person: - name: str = "Alice" - -_personA = Person {} -_personA |= {"name" = 123.0} # name: str = "Alice" -personA = _personA -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /fail/fail_4/main.k:2:1 - | -2 | name: str = "Alice" - | expect str, got float - | -``` - -Possible resolution: - -- Stop the wrong type union or adjust to the type union supported by KCL. - -### 1.3.7 SchemaCheckFailure (E3B17) - -KCL will report `SchemaCheckFailure` when the schema check conditions are not met. - -The `ewcode` of `SchemaCheckFailure` is `E3B17`. - -For example: - -```python -schema Person: - lastName: str - age: int - check: - age < 140, "age is too large" - -JohnDoe = Person { - "lastName": "Doe", - "age": 1000 # the check condition: age < 140 -} -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /check_block/check_block_fail_1/main.k:7:11 - | -7 | JohnDoe = Person { - | ^ Instance check failed - | - - --> /check_block/check_block_fail_1/main.k:5:1 - | -5 | age < 140, "age is too large" - | Check failed on the condition - | -``` - -Possible resolution: - -- Check whether the attributes of schema can satisfy the conditions in check. - -### 1.3.8 CannotAddMembersRuntimeError(E3B19) - -KCL will report `CannotAddMembersRuntimeError` when members that are not in the schema are used. - -The `ewcode` of `CannotAddMembersRuntimeError` is `E3B19`. - -For example: - -```python -schema Name: - name: str - -schema Person: - name: Name - -person = Person { - name.err_name: "Alice" # err_name is not found in schema Name -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /nest_var/nest_var_fail_1/main.k:8:5 - | -8 | name.err_name: "Alice" # err_name is not found in schema Name - | ^ Cannot add member 'err_name' to schema 'Name' - | -``` - -Possible resolution: - -- Add a non-existent member to the schema. -- Access members that exist in the schema. - -### 1.3.9 EvaluationError(E3M38) - -KCL will report `EvaluationError` when an illegal evaluation occurs in KCL. - -The `ewcode` of `EvaluationError` is `E3M38`. - -For example: - -```python -_list1 = [1, 2, 3] # _list1 is a variable, and its type can only be known at runtime -_list2 = None # _list1 is a variable, and its type can only be known at runtime - -result2 = _list1 + _list2 # list + NoneType is illegal -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /datatype/list/add_None_fail/main.k:1 - | -4 | result2 = _list1 + _list2 # list + NoneType is illegal - | can only concatenate list (not "NoneType") to list - | -``` - -Possible resolution: - -- Check whether the evaluation of the expression is legal. - -### 1.3.10 InvalidFormatSpec (E3M39) - -KCL will report `InvalidFormatSpec` when an illegal string format appears in KCL. - -The `ewcode` of `InvalidFormatSpec` is `E3M39`. - -For example: - -```python -a = 1 -b = 1 -data = "${a: #js}" + " $$ " # #js is illegal string -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /datatype/str_interpolation/invalid_format_spec_fail_0/main.k:3 - | -3 | data = "${a: #js}" + " $$ " # #js is illegal string - | ^ #js is a invalid format spec - | -``` - -Possible resolution: - -- Adjust illegal String to String supported by KCL standards. - -### 1.3.11 KCLAssertionError (E3M40) - -KCL will report `KCLAssertionError` when assert False occurs in KCL. - -The `ewcode` of `KCLAssertionError` is `E3M40`. - -For example: - -```python -assert False -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /assert/invalid/fail_0/main.k:1 - | -1 | assert False - | - | -``` - -Possible resolution: - -- Check the condition of Assert, and when the Assert condition is False, such an error occurs, removing the Assert statement or changing the condition to True. - -### 1.3.12 ImmutableRuntimeError (E3M44) - -KCL will report `ImmutableRuntimeError` when the value of the immutable variable changes. - -The `ewcode` of `ImmutableRuntimeError` is `E3M44`. - -For example: - -```python -schema Person: - final firstName : str - lastName : str - -schema Scholar(Person): - firstName = "CBA" - -scholar = Scholar { - "firstName": "ABC" # firstName in schema Person is final. -} -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /final/fail_lazy_init_0/main.k:8:1 - | -8 | scholar = Scholar { - | attribute 'lastName' of Scholar is required and can't be None or Undefined - | -``` - -Possible resolution: - -- Check if the final variables have been assigned or other changes affect the values of the final variables. - -### 1.3.13 CycleInheritError (E2D33) - -KCL will report `CycleInheritError` when circle inheritance appeared in the schema. - -The `ewcode` of `CycleInheritError` is `E2D33`. - -For example: - -```python -schema Parent(Son): - parent_field: str - -schema Son(GrandSon): - son_field: str - -schema GrandSon(Parent): - grandson_field: str - -parent = Parent { - parent_field: "" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /inherit/cycle_inherit_fail_1/main.k:7:8 - | -7 | schema GrandSon(Parent): - | ^ There is a circular reference between schema GrandSon and Parent - | -``` - -Possible resolution: - -- Check schema inheritance relationship to avoid A inheritance B and B inheritance A at the same time. - -### 1.3.14 KCLRecursionError (E3M42) - -KCL will report `KCLRecursionError` when a circle reference appears in the program. - -The `ewcode` of `KCLRecursionError` is `E3M42`. - -For example: - -```python -schema Parent(Son): - parent_field: str - son: Son = Son { # Parent has attribute Son - parent: Parent { - parent_field: "123" - } - } - -schema Son: - son_field: str - parent: Parent = Parent { # Son has attribute Parent - son: Son { - son_field: "123" - } - } - -parent = Parent { - parent_field: "", -} -``` - -The KCL program will cause the following error message. - -```shell -thread 'main' has overflowed its stack -fatal runtime error: stack overflow -``` - -Possible resolution: - -- Check the members in the schema to avoid the problem of circle references. - -## 1.4 KCL Compile Warning (W2xxx) - -This section mainly includes KCL warnings: - -| ewcode | KCL exception | messages | -| ------ | ------------------------------------------------- | ------------------ | -| W2K04 | [FloatUnderflow](#141-floatunderflow-w2k04) | Float underflow | -| W2P10 | [InvalidDocstring](#142-invaliddocstring-w2p10) | Invalid docstring | -| W2N12 | [DeprecatedWarning](#143-deprecatedwarning-w2n12) | Deprecated warning | - -### 1.4.1 FloatUnderflow (W2K04) - -KCL will report `FloatUnderflow` when a floating-point number underflows in KCL. - -The `ewcode` of `FloatUnderflow` is `W2K08`. - -Possible resolution: - -- Check whether the value of the float number is in the range supported by KCL. - -### 1.4.2 InvalidDocstring (W2P10) - -KCL will report `InvalidDocstring` when a string is illegal in KCL doc. - -The `ewcode` of `InvalidDocstring` is `W2P10`. - -Possible resolution: - -- Please write doc according to KCL standards. - -### 1.4.3 DeprecatedWarning (W2N12) - -KCL will report `DeprecatedWarning` when a deprecated variable is used and the strict is False. - -The `ewcode` of `DeprecatedWarning` is `W2N12`. - -Possible resolution: - -- Try not to use deprecated code. If the strict is True, KCL will output the error and stop running. diff --git a/versioned_docs/version-0.5.4/reference/lang/error/index.md b/versioned_docs/version-0.5.4/reference/lang/error/index.md deleted file mode 100644 index 15fbda6f..00000000 --- a/versioned_docs/version-0.5.4/reference/lang/error/index.md +++ /dev/null @@ -1 +0,0 @@ -# Errors and Warnings diff --git a/versioned_docs/version-0.5.4/reference/lang/spec/_category_.json b/versioned_docs/version-0.5.4/reference/lang/spec/_category_.json deleted file mode 100644 index 7b24faae..00000000 --- a/versioned_docs/version-0.5.4/reference/lang/spec/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Spec", - "position": 3 -} diff --git a/versioned_docs/version-0.5.4/reference/lang/spec/codestyle.md b/versioned_docs/version-0.5.4/reference/lang/spec/codestyle.md deleted file mode 100644 index dd40925e..00000000 --- a/versioned_docs/version-0.5.4/reference/lang/spec/codestyle.md +++ /dev/null @@ -1,608 +0,0 @@ ---- -title: "Code Style" -linkTitle: "Code Style" -type: "docs" -weight: 2 -description: Code Style ---- - -## Introduction - -This document gives the KCL code style conventions. Good code style can play a vital role in the development and maintenance of the project. We can learn the KCL code style by referring to the full text of the description and sample codes, and use KCL format and lint tools to help coding. - -## Source File Encoding - -KCL file encoding should always use **UTF-8**. - -## Code Layout - -### Indentation - -Use **4 spaces** per indentation level such as in the schema statement and if statement. - -```python -schema PersonA: - name: str # non-recommended - age: int - -schema PersonB: - name: str # recommended - age: int - -if True: - a = 1 # recommended -elif True: - b = 2 # non-recommended -else: - c = 3 # non-recommended -``` - -The closing brace/bracket/parenthesis on multiline constructs should line up under **first character** of the line that starts the multiline construct, as in: - -```python -# valid and recommended -my_list = [ - 1, 2, 3, - 4, 5, 6, -] -``` - -```python -# invalid -my_list = [ - 1, 2, 3, - 4, 5, 6, - ] -``` - -### Tabs or Spaces - -- Spaces are the preferred indentation method. -- Tabs should be used solely to remain consistent with code that is already indented with tabs. - -KCL disallows mixing the use of tabs and spaces for indentation and an error will be reported during the compile time. - -### Blank Lines - -- Surround top-level schema definitions with one blank line. -- Keep at most one blank line between two statements and remove redundant blank lines. -- Remove extra blank characters at the end of the line -- Remove extra blank characters in a blank line. -- There is no blank line in the header of the file, start writing from the first line. -- Only one blank line will be left at the end of the KCL file. - -```python -# Remove blank lines in the file header -a = 1 # Remove white space at the end of the line -# Keep at most one blank line between two statements - -b = 2 -# Only leave one blank line at the end of the file - -``` - -### Inline Expressions - -Write indentation of KCL `if`, `elif`, `else` and other conditions on different lines. - -```python -if True: print("") # non-recommended - -if True: # recommended - print("") -``` - -### Line Break and Continuation lines - -- For long expressions, use the line continuation symbol `\` and keep the left end of multiple expressions aligned. -- The 4-space rule is optional for continuation lines. - -```python -anotherString = "Too long expression " + \ - "Too long expression " # non-recommended - -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " # recommended -``` - -### When to Use Trailing Commas - -- Always use trailing commas. - -### Maximum Line Length - -- The general recommendation is **80 characters** but not absolute. - -### Symbol Break White Space - -Try to keep the spaces between different symbols, but not too many, usually one is good. - -```python -a = 1 # recommended -b = 1 + 2 # non-recommended -``` - -### Whitespace in Expressions and Statements - -Avoid extraneous whitespace in the following situations: - -- The parentheses `()`, brackets `[]` and braces `{}` in the expression have no spaces inside. - -```python -a = (1 + 2) # recommended -b = ( 1 + 2 ) # non-recommended - -c = [1, 2, 3] # recommended -d = [ 1, 2, 3 ] # non-recommended - -e = {key = "value"} # recommended -f = { key = "value" } # non-recommended -``` - -```python -spam(ham[1], {eggs = 2}) # recommended -spam( ham[ 1 ], { eggs = 2 } ) # non-recommended -``` - -- Between a trailing comma and a following close parenthesis. - -```python -foo = [0,] # recommended -bar = [0, ] # non-recommended -``` - -- Immediately before the open parenthesis that starts the argument list of a function call. - -```python -print(1) # recommended -print (1) # non-recommended -``` - -- Immediately before the open parenthesis that starts indexing or slicing. - -```python -dct = {key = "value"} -lst = [1, 2, 3] - -a = dct['key'] # recommended -b = dct ['key'] # non-recommended - -c = lst[0] # recommended -d = lst [1] # non-recommended -``` - -- More than one space around an assignment `=` (or other) operator to align it with another. - -```python -# recommended: -x = 1 -y = 2 -long_variable = 3 -``` - -```python -# non-recommended: -x = 1 -y = 2 -long_variable = 3 -``` - -- Always surround these binary operators with a single space on either side: assignment (`=`), augmented assignment (`+=`, `-=`, etc.), comparisons (`==`, `<`, `>`, `!=`, `<=`, `>=`, `in`, `not in`, `is`, `is not`), booleans (`and`, `or`, `not`). - -```python -# recommended: -i = i + 1 -submitted += 1 -x = x * 2 - 1 -hypot2 = x * x + y * y -c = (a + b) * (a - b) -``` - -```python -# non-recommended: -i = i+1 -submitted+=1 -x = x*2 - 1 -hypot2 = x*x + y*y -c = (a+b) * (a-b) -``` - -- Break one blank line between different statements e.g., import, schema and expression statements. - -```python -import math -import net - -schema Person: - name: str - -person = Person { - name = "Alice" -} -``` - -- Compound statements (multiple statements on the same line) are generally discouraged - -```python -# recommended: -if foo == 'blah': - do_blah_thing() -do_one() -do_two() -do_three() -``` - -```python -# non-recommended: -if foo == 'blah': do_blah_thing() -do_one(); do_two(); do_three() -``` - -## Naming Conventions - -### Naming Styles - -The following naming styles are commonly distinguished: - -- `b` (single lowercase letter) -- `B` (single uppercase letter) -- `lowercase` -- `lower_case_with_underscores` -- `UPPERCASE` -- `UPPER_CASE_WITH_UNDERSCORES` -- `CapitalizedWords` (capitalize all letters of the acronym in `CapitalizedWords` e.g., `HTTPServer`.) -- `mixedCase` (differs from `CapitalizedWords` by initial lowercase character) -- `Capitalized_Words_With_Underscores` (ugly and non-recommended) - -### Names to Avoid - -Never use the characters 'l' (lowercase letter el), 'O' (uppercase letter oh), or 'I' (uppercase letter eye) as single-character variable names. - -### Package and Module Names - -Package and module names should have short, all-lowercase names. - -### Schema Names - -Schema names should normally use the `CapWords` convention. - -### Constants - -Constants are usually defined on a module level and written in all capital letters with underscores separating words such as `MAX_OVERFLOW` and `TOTAL`. - -## Import - -- Imports should usually be on separate lines. -- Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants. -- Imports should be grouped in the following order and we should put a blank line between each group of imports. - 1. Standard library imports. - 2. Related third party plugin imports. - 3. Local application/library specific imports. -- Use an alias when we import a package name with a relatively long path. -- Leave only one space between the Import keyword and the package name. - -```python -import net # recommended -import math # non-recommended - -import ..pkg.internal_pkg as alias_pkg # recommended -``` - -## Comments - -- Comments should be complete sentences. The first word should be capitalized unless it is an identifier that begins with a lower-case letter (never alter the case of identifiers!). -- Block comments generally consist of one or more paragraphs built out of complete sentences, with each sentence ending in a period. -- Use two spaces after a sentence-ending period in multi-sentence comments, except after the final sentence. - -### Block Comments - -Block comments generally apply to some (or all) code that follows them, and are indented to the same level as that code. Each line of a block comment starts with a `#` and **a single space**(unless it is indented text inside the comment). - -Paragraphs inside a block comment are separated by a line containing a single `#`. - -```python -# This is a block comment -a = 1 -``` - -### Inline Comments - -Use inline comments sparingly. - -An inline comment is a comment on the same line as a statement. Inline comments should be separated by **at least two spaces** from the statement. They should start with a `#` and **a single space**. - -```python -a = 1 # This is an inline comment -``` - -### Documentation Strings - -Write doc strings for all public schema and schema attributes. - -```python -schema Person: - """ - Person schema doc string - """ - - name: str = "Alice" -``` - -## String - -- Single-quoted strings and double-quoted strings are the same in KCL. -- Use double-quoted string with lowercase prefix -- For triple-quoted strings, always use double quote characters to be consistent with the docstring convention. -- When a string contains single or double quote characters, use the other one to avoid backslashes in the string. - -```python -strC = "'123'" # recommended -strD = "\"123\"" # non-recommended -``` - -## Number - -- Use lowercase for the prefix of non-decimal numbers, and use uppercase for the number itself. - -```python -foo = 0xAB # recommended -bar = 0Xab # non-recommended -``` - -## Operators - -### Binary Operators - -- Leave only one space before and after the assignment `=`. -- Leave only one space before and after the binary operator in the expression. - -```python -a = 1 # recommended -b=2 # non-recommended -c= 3 # non-recommended -d =4 # non-recommended - -_value = (1 + 2 * 3) # recommended -_value = (1+2*3) # non-recommended -``` - -### Unary Operators - -- There is only no space after unary operators e.g., `~`, `+` and `-`. - -```python -_value = 1 + -2 * ~3 # recommended -_value = 1+ - 2 * ~ 3 # non-recommended -``` - -- There is no space after `**` and `*` in the dict/list deduction expressions and argument expressions. - -```python -_list = [1, 2, 3] -_list = [*_list, [4, 5 ,6]] # recommended -_list = [* _list, [4, 5 ,6]] # non-recommended - -_dict = {**{k = "v"}, **{k = "v"}} # recommended -_dict = {** {k = "v"}, ** {k = "v"}} # non-recommended -``` - -- Use `is not` operator rather than `not ... is`. - -```python -# recommended: -if foo is not None: - a = 1 -``` - -```python -# non-recommended: -if not foo is None: - a = 1 -``` - -## Dict - -- There is no space before the colon `:` at the instantiation of KCL dict and schema config, and a space after the colon `:`. - -```python -d1 = {labels: {k1 = "v1"}} # recommended -d2 = {labels : {k1 = "v1"}} # non-recommended -d3 = {labels :{k1 = "v1"}} # non-recommended -``` - -- Always surround the override attribute operator `=` and the insert attribute operator `+=` with a single space on either sid. - -```python -d1 = {key = "value"} # recommended -d2 = {key= "value"} # non-recommended -d3 = {key ="value"} # non-recommended -``` - -```python -d1 = {key += [0, 1, 2]} # recommended -d2 = {key+= [0, 1, 2]} # non-recommended -d3 = {key +=[0, 1, 2]} # non-recommended -``` - -- Remove all commas at the end of the line in the KCL multiline dict because the end commas of each line are optional. - -```python -d = { - key1 = "value1" - key2 = "value2" - key3 = "value3" - key4 = "value4" -} -``` - -## List - -- Keep only **one space** after the comma `,` separating elements in the list - -```python -a = [1, 2, 3] # recommended -b = [1,2,3] # non-recommended -``` - -- Keep only **one space** before and after the comprehension expression token `for` and `in` in the dict and list. - -```python -a = [i for i in range(10)] # recommended -b = [i for i in range(10)] # non-recommended -``` - -## Slice - -- Keep the same number of spaces before and after the colon `:` of the list slice. - -```python -l = [1, 2, 3] -a = l[0:2] # recommended -b = l[0 : 2] # non-recommended -c = l[0: 2] # non-recommended - -d = l[0 + 0 : 1 + 1] # recommended -e = l[0 + 0:1 + 1] # non-recommended -``` - -## Schema - -- Leave only one space before and after the schema attribute assignment `=`. -- Always add a doc string to a schema, which is a good programming habit. - -```python -schema Person: - """ - Schema doc string - """ - name: str = "Alice" # recommended - age : int=12 # non-recommended - -person = Person {} -``` - -- Keep **no spaces** around the schema inheritance operator `()` - -```python -schema Base: - name: str - -schema Person(Base): # recommended - age: int - -schema Schema ( Base ): # non-recommended - age: int -``` - -- Keep **only one space** between the brackets and the schema name of the config at schema instantiation. - -```python -schema Base: - name: str - -schema Person(Base): - age: int - -personA = Person{} # non-recommended -personB = Person {} # recommended -``` - -- Keep **only one space** between the **mixin** keyword and the following `[]` operator - -```python -schema NameMixin: - name: str = "name" - -schema Person: - mixin [NameMixin] # non-recommended - age: int - -schema Parent: - mixin [NameMixin] # recommended - age: int -``` - -### Attribute Annotations - -- Annotations for schema attributes should have a single space after the colon `:` and no space before the colon `:`. - -```python -# recommended: -schema Person: - name: str # No space before the colon `:` - age: int = 18 # Spaces around assignment`=` -``` - -```python -# non-recommended: -schema Person: - codeA:int # No space after the colon `:` - codeB : int # Space before the colon `:` - name: str="Alice" # No spaces around assignment`=` -``` - -- There are no spaces around the colon `:` in the dict type annotation. - -```python -schema Person: - labels: {str:str} # recommended - keyValues: {str : str} # non-recommended -``` - -### Arguments - -- There are no spaces around the assignment `=` in the function/schema/decorator keyword arguments (kwargs). - -```python -schema Person[nameVar]: - # Decorator kwargs - @deprecated(strict=False) # recommended - name: str = nameVar - - @deprecated(strict = False) # non-recommended - age: int - -# Schema kwargs -personA = Person(nameVar="Alice") {} # recommended -personB = Person(nameVar = "Bob") {} # non-recommended - -# Function kwargs -print("", end='') # recommended -print("", end = '') # non-recommended -``` - -## Keywords - -- Only one space is usually reserved around the keyword, such as `schema`, `mixin`, `is` and `not`, etc. - -```python -schema NameMixin: - check: - name not None - -schema Person: - """ - Person schema definition - """ - mixin [NameMixin] - - name: str = "Alice" - age: int - -person = Person { - age = 18 -} -``` - -## Function - -- There are no spaces around the function/package select operator `.` -- There are no spaces between the function name and the parentheses `()`. - -```python -import math - -print(math.log(10)) # recommended -print( math . log (10)) # non-recommended -``` diff --git a/versioned_docs/version-0.5.4/reference/lang/spec/datatypes.md b/versioned_docs/version-0.5.4/reference/lang/spec/datatypes.md deleted file mode 100644 index ef7ea71a..00000000 --- a/versioned_docs/version-0.5.4/reference/lang/spec/datatypes.md +++ /dev/null @@ -1,452 +0,0 @@ ---- -title: "Data Types" -linkTitle: "Data Types" -type: "docs" -weight: 2 -description: Data Types ---- - -## Syntax - -### Bool - -Boolean values are the two constant objects `False` and `True`. They are used to represent truth values (although other values can also be considered false or true). The built-in function bool() can be used to convert any value to a Boolean, if the value can be interpreted as a truth value. - -### Int - -Int, or integer, is an arbitrarily sized integer, positive or negative, without decimals, of 64 binary digits precision(-9,223,372,036,854,775,808~9,223,372,036,854,775,807). Int is created by int literals or as the result of built-in functions and operators. Unadorned integer literals (including `hex`, `octal` and `binary` numbers) yield integers. The constructor int() can be used to produce int of a specific type. - -Besides, integer literals may have an `SI` or `IEC` multiplier. - -- `SI`: General integer or fixed-point number form: `P`, `T`, `G`, `M`, `K`, `k`, `m`, `u`, `n`. -- `IEC`: Corresponding power of 2: `Pi`, `Ti`, `Gi`, `Mi`, `Ki`. - -```python -a = 1 # positive integer: 1 -b = -1 # negative integer: -1 -c = 0x10 # hexadecimal literal: 16 -d = 0o10 # octal literal: 8, or the form `010` -e = 0b10 # binary literal: 2 -f = 10Ki # integer literal with IEC multiplier: 10240 -g = 1M # integer literal with SI multiplier: 1000000 -h = int("10") # int constructor: 10 -i = int("10Ki") # int constructor with multiplier: 10240 -``` - -Notes: - -- Report an error if unable to represent an integer value precisely. - -### Float - -Float, floating-point, approximation to real numbers, positive or negative, containing one or more decimals, of 64 bit IEEE 754 floats. The constructor float() can be used to produce int of a specific type. - -```python -a = 1.10 -b = 1.0 -c = -35.59 -d = 32.3+e18 -f = -90. -g = -32.54e100 -h = 70.2-E12 -i = float("112") # float constructor -``` - -Notes: - -- Report an error if unable to represent a floating-point value due to overflow -- Report a warning if unable to represent a floating-point value due to underflow. Round to the nearest representable value if unable to represent a floating-point value due to limits on precision. These requirements apply to the result of any expression except for built-in functions for which an unusual loss of precision must be explicitly documented. - -#### None - -In KCL, `None` can indicate that the value of the object is empty, which is similar to `nil` in Go or `null` in Java, and corresponds to `null` in YAML and JSON. - -```python -a = None -b = [1, 2, None] -c = {"key1" = "value1", "key2" = None} -``` - -Please note that `None` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + None # error -b = int(None) # error -c = not None # True -d = None == None # True -e = None or 1 # 1 -f = str(None) # None -``` - -#### Undefined - -`Undefined` is similar to None, but its semantics is that a variable is not assigned any value and will not be output to YAML or JSON. - -```python -a = Undefined -b = [1, 2, Undefined] -c = {"key1" = "value1", "key2" = Undefined} -``` - -Please note that `Undefined` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + Undefined # error -b = int(Undefined) # error -c = not Undefined # True -d = Undefined == Undefined # True -e = Undefined or 1 # 1 -f = str(Undefined) # Undefined -``` - -### Common Numeric Operations - -Int and Float support the following operations (see built-in proposal for built-in details): - -- `x + y`: sum of x and y. -- `x - y`: difference of x and y. -- `x * y`: product of x and y. -- `x / y`: quotient of x and y. -- `x // y`: floored quotient of x and y. -- `x % y`: remainder of x / y. -- `x ** y`: x to the power y. -- `-x`: x negated. -- `+x`: x unchanged. -- `~x`: x bitwise negation. -- `abs(x)`: absolute value or magnitude of x. -- `int(x)`: x converted to integer. -- `float(x)`: x converted to floating point. - -KCL supports mixed arithmetic: when a binary arithmetic operator has operands of different numeric types, the operand with the "narrower" type is widened to that of the other, where integer is narrower than floating-point. - -### String - -Strings are immutable sequences of Unicode characters. String literals are written in a variety of ways: - -```python -'allows embedded "double" quotes' # Single quotes -"allows embedded 'single' quotes" # Double quotes -'''Three single quotes''', """Three double quotes""" # Triple quoted -``` - -Triple quoted strings may span multiple lines. - -Indexing a string produces strings of length 1, for a non-empty string s, `s[0] == s[0:1]`. - -```python -a = "Hello, World!" -b = a[2:5] # "llo" -c = a[-5:-2] # "orl" -d = a[::-1] # "'!dlroW ,olleH'" -``` - -- `str(x=None) -> str` - -Return a string. If _x_ is not provided, raise a runtime error. - -```python -x = str(3.5) # "3.5" -``` - -#### Members - -Built-in function and members of a string - -- `str#len() -> int` - Return the number of characters in the string. -- `capitalize() -> str` - Return a copy of the string with its first character (if any) capitalized and the rest lowercased. -- `count(sub: str, start: int = 0, end: int = -1) -> int` - Returns the number of (non-overlapping) occurrences of substring sub in string, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `endswith(suffix: str, start: int = 0, end: int = -1) -> bool` - Returns `True` if the string ends with the specified suffix, otherwise return `False`, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `find(sub: str, start: int = 0, end: int = -1) -> int` - Returns the lowest index where substring sub is found, or -1 if no such index exists, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `format(*args, **kwargs) -> str` - Perform string interpolation. Format strings contain replacement fields surrounded by curly braces {}. Anything that is not contained in braces is considered literal text, which is copied unchanged to the output. If you need to include a bracket character in the literal text, it can be escaped by doubling: A replacement field can be either a name, a number or empty. Values are converted to strings using the str function. -- `index(sub: str, start: int = 0, end: int = -1) -> int` - Returns the first index where sub is found, or raises an error if no such index exists, optionally restricting to `[start:end]` start being inclusive and end being exclusive. -- `isalnum() -> bool` - Returns True if all characters in the string are alphanumeric (`[a-zA-Z0-9]`) and there is at least one character, False otherwise. -- `isalpha() -> bool` - Returns True if all characters in the string are alphabetic (`[a-zA-Z]`) and there is at least one character. -- `isdigit() -> bool` - Returns True if all characters in the string are digits (`[0-9]`) and there is at least one character. -- `islower() -> bool` - Returns True if all cased characters in the string are lowercase and there is at least one character. -- `isspace() -> bool` - Returns True if all characters are white space characters and the string contains at least one character. -- `istitle() -> bool` - Returns True if the string is in title case and it contains at least one character. This means that every uppercase character must follow an uncased one (e.g., whitespace) and every lowercase character must follow a cased one (e.g., uppercase or lowercase). -- `isupper() -> bool` - Returns True if all cased characters in the string are uppercase and there is at least one character. -- `join(iterable: list) -> str` - Return a string which is the concatenation of the strings in iterable. A TypeError will be raised if there are any non-string values in iterable. The separator between elements is the string providing this method. Example: - - ```python - >>> "|".join(["a", "b", "c"]) - "a|b|c" - ``` - -- `lower() -> str` - Returns a copy of the string with all the cased characters converted to lowercase. -- `lstrip(chars: str) -> str` - Return a copy of the string with leading characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.lstrip() - 'spacious ' - >>> 'www.example.com'.lstrip('cmowz.') - 'example.com' - ``` - -- `replace(old: str, new: str, count: int) -> str` - Return a copy of the string with all occurrences of substring old replaced by new. If the optional argument count is given, only the first count occurrences are replaced. -- `rfind(sub: str, start: int = 0, end: int = -1) -> int` - Return the highest index in the string where substring sub is found, such that sub is contained within s[start:end]. Optional arguments start and end are interpreted as in slice notation. Return -1 on failure. -- `rindex(sub: str, start: int = 0, end: int = -1) -> int` - Returns the last index where sub is found, or raises an ValueError if no such index exists, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `rsplit(sep: str, maxsplit: int = -1) -> list` - Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done, the rightmost ones. If sep is not specified or None, any whitespace string is a separator. Except for splitting from the right, rsplit() behaves like split() which is described in detail below. -- `rstrip(chars: str) -> str` - Return a copy of the string with trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a suffix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.rstrip() - ' spacious' - >>> 'mississippi'.rstrip('ipz') - 'mississ' - ``` - -- `split(sep: str, maxsplit: int) -> list` - Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done (thus, the list will have at most maxsplit+1 elements). If maxsplit is not specified or -1, then there is no limit on the number of splits (all possible splits are made). - - If sep is given, consecutive delimiters are not grouped together and are deemed to delimit empty strings (for example, `'1,,2'.split(',')` returns `['1', '', '2']`). The sep argument may consist of multiple characters (for example, `'1<>2<>3'.split('<>')` returns `['1', '2', '3']`). Splitting an empty string with a specified separator returns `['']`. - - For example: - - ```python - >>> '1,2,3'.split(',') - ['1', '2', '3'] - >>> '1,2,3'.split(',', maxsplit=1) - ['1', '2,3'] - >>> '1,2,,3,'.split(',') - ['1', '2', '', '3', ''] - ``` - - If sep is not specified or is None, a different splitting algorithm is applied: runs of consecutive whitespace are regarded as a single separator, and the result will contain no empty strings at the start or end if the string has leading or trailing whitespace. Consequently, splitting an empty string or a string consisting of just whitespace with a `None` separator returns `[]`. - - For example: - - ```python - >>> '1 2 3'.split() - ['1', '2', '3'] - >>> '1 2 3'.split(maxsplit=1) - ['1', '2 3'] - >>> ' 1 2 3 '.split() - ['1', '2', '3'] - ``` - -- `splitlines(keepends: str) -> list` - Return a list of the lines in the string, breaking at line boundaries('\n', '\r\n', '\r'). Line breaks are not included in the resulting list unless keepends is given and true. - - This method splits on the following line boundaries. In particular, the boundaries are a superset of universal newlines. - - For example: - - ```python - >>> 'ab c\n\nde fg\rkl\r\n'.splitlines() - ['ab c', '', 'de fg', 'kl'] - >>> 'ab c\n\nde fg\rkl\r\n'.splitlines(keepends=True) - ['ab c\n', '\n', 'de fg\r', 'kl\r\n'] - ``` - - Unlike `split()` when a delimiter string sep is given, this method returns an empty list for the empty string, and a terminal line break does not result in an extra line: - - ```python - >>> "".splitlines() - [] - >>> "One line\n".splitlines() - ['One line'] - ``` - - For comparison, `split('\n')` gives: - - ```python - >>> ''.split('\n') - [''] - >>> 'Two lines\n'.split('\n') - ['Two lines', ''] - ``` - -- `startswith(prefix: str, start: int = 0, end: int = -1) -> bool` - Return `True` if string starts with the prefix, otherwise return False. prefix can also be a list of prefixes to look for. With optional start, test string beginning at that position. With optional end, stop comparing string at that position. -- `strip(chars: str) -> str` - Return a copy of the string with the leading and trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix or suffix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.strip() - 'spacious' - >>> 'www.example.com'.strip('cmowz.') - 'example' - ``` - - The outermost leading and trailing chars argument values are stripped from the string. Characters are removed from the leading end until reaching a string character that is not contained in the set of characters in chars. A similar action takes place on the trailing end. For example: - - ```python - >>> comment_string = '#....... Section 3.2.1 Issue #32 .......' - >>> comment_string.strip('.#! ') - 'Section 3.2.1 Issue #32' - ``` - -- `title() -> str` - Return a titlecased version of the string where words start with an uppercase character and the remaining characters are lowercase. - - For example: - - ```python - >>> 'Hello world'.title() - 'Hello World' - ``` - - The algorithm uses a simple language-independent definition of a word as groups of consecutive letters. The definition works in many contexts but it means that apostrophes in contractions and possessives form word boundaries, which may not be the desired result: - - ```python - >>> "they're bill's friends from the UK".title() - "They'Re Bill'S Friends From The Uk" - ``` - -- `upper() -> str` - Return a copy of the string with all the cased characters 4 converted to uppercase. Note that `s.upper().isupper()` might be `False` if s contains uncased characters or if the Unicode category of the resulting character(s) is not “Lu” (Letter, uppercase), but e.g., “Lt” (Letter, titlecase). -- `removeprefix(prefix: str) -> str` - If the string starts with the prefix string, return string[len(prefix):]. Otherwise, return a copy of the original string. - ```python - >>> "prefix-data".removeprefix("prefix-") - "data" - ``` -- `rermovesuffix(suffix: str) -> str` - If the string ends with the suffix string and that suffix is not empty, return string[:-len(suffix)]. Otherwise, return a copy of the original string. - ```python - >>> "data-suffix".removesuffix("-suffix") - "data" - ``` - -### List - -Lists are immutable sequences, typically used to store collections of homogeneous items (where the precise degree of similarity will vary by application). - -Lists may be constructed in several ways: - -- Using a pair of square brackets to denote the empty list: `[]` -- Using square brackets, separating items with commas: `[a]`, `[a, b, c]` -- Using a list comprehension: `[x for x in iterable]` -- Using the type constructor: list() or list(iterable) - -The constructor builds a list whose items are the same and in the same order as iterable’s items.Iterable may be either a sequence, a container that supports iteration, or an iterator object. If iterable is already a list, a copy is made and returned, similar to `iterable[:]`. For example, `list('abc')` returns `['a', 'b', 'c']` and `list([1, 2, 3])` returns `[1, 2, 3]`. If no argument is given, the constructor creates a new empty list `[]`. - -Lists implement all of the common sequence operations. - -#### Members - -- `len()` - Return the number of items in the list. - -### Common Sequence Operations - -The operations in the following table are supported by List and Dict. - -This table lists the sequence operations sorted in ascending priority. In the table, s and t are sequences of the same type, n, i, j and k are integers and x is an arbitrary object that meets any type and value restrictions imposed by s. - -The `in` and `not in` operations have the same priorities as the comparison operations. The + -(concatenation) and \* (repetition) operations have the same priority as the corresponding numeric operations. - -| Operation | Result | Notes | -| ------------ | -------------------------------------------------- | ----- | -| `x in s` | `True` if an item of s is equal to x, else `False` | #1 | -| `x not in s` | `False` if an item of s is equal to x, else `True` | #1 | -| `s + t` | the concatenation of s and t | #5 | -| `s[i]` | ith item of s, origin 0 | #2 | -| `s[i:j]` | slice of s from i to j | #2 #3 | -| `s[i:j:k]` | slice of s from i to j with step k | #2 #4 | -| `min(s)` | smallest item of s | | -| `max(s)` | largest item of s | | - -Notes: - -- 1. While the in and not in operations are used only for simple containment testing in the - general case, some specialized sequences (str) also use them for subsequence testing: - -```python ->>> "gg" in "eggs" -True -``` - -- 2. If i or j is negative, the index is relative to the end of sequence s: `s.len() + i` or `s.len() + j` is substituted. But note that -0 is still 0. -- 3. The slice of s from i to j is defined as the sequence of items with index k such that `i <= k < j`. If i or j is greater than `s.len()`, use `s.len()`. If i is omitted or None, use 0. If j is omitted or None, use `s.len()`. If i is greater than or equal to j, the slice is empty. -- 4. The slice of s from i to j with step k is defined as the sequence of items with index `x = i + n*k` such that `0 <= n < (j-i)/k`. In other words, the indices are `i`, `i+k`, `i+2*k`, `i+3*k` and so on, stopping when j is reached (but never including j). When k is positive, i and j are reduced to s.len() if they are greater. When k is negative, i and j are reduced to s.len() - - - If they are greater. If i or j are omitted or None, they become “end” values (which end depends on the sign of k). Note, k cannot be zero. If k is None, it is treated like 1. - -- 5. Concatenating immutable sequences always results in a new object. This means that building up a sequence by repeated concatenation will have a quadratic runtime cost in the total sequence length. To get a linear runtime cost, you must switch to one of the alternatives below: - - - if concatenating str objects, you can build a list and use `str.join()` at the end - -- 6. `index` raises `ValueError` when x is not found in s. Not all implementations support passing the additional arguments i and j. These arguments allow efficient searching of subsections of the sequence. Passing the extra arguments is roughly equivalent to using `s[i:j].index(x)`, only without copying any data and with the returned index being relative to the start of the sequence rather than the start of the slice. - -### Dict - -Dict is an immutable mapping object maps hashable values to arbitrary objects. A dictionary’s keys are almost arbitrary values. Values that are not hashable, that is, values containing lists, dictionaries may not be used as keys. Numeric types used for keys obey the normal rules for numeric comparison: if two numbers compare equal (such as 1 and 1.0) then they can be used interchangeably to index the same dictionary entry. (Note however, that since computers store floating-point numbers as approximations it is usually unwise to use them as dictionary keys.) Dict is ordered. The order of the keys is the order of their declaration. - -Dictionaries can be created by placing a comma-separated list of keys: value pairs within braces, for example: `{'jack': 4098, 'sjoerd': 4127}` or `{4098: 'jack', 4127: 'sjoerd'}`, by the dict constructor, or list/dict comprehension. - -- `dict(obj)` - -Return a new dictionary initialized from an optional positional argument and a possibly empty set of keyword arguments.If no positional argument is given, an empty dictionary is created. If a positional argument is given and it is a mapping object, a dictionary is created with the same key-value pairs as the mapping object. Otherwise, the positional argument must be an iterable object. Each item in the iterable must itself be an iterable with exactly two objects. The first object of each item becomes a key in the new dictionary, and the second object the corresponding value. If a key occurs more than once, the last value for that key becomes the corresponding value in the new dictionary. If keyword arguments are given, the keyword arguments and their values are added to the dictionary created from the positional argument. If a key being added is already present, the value from the keyword argument replaces the value from the positional argument. To illustrate, the following examples all return a dictionary equal to `{"one": 1, "two": 2, "three": 3}`: - -```python ->>> a = {'two': 2, 'one': 1, 'three': 3} ->>> b = {'one': 1, 'two': 2, 'three': 3} ->>> c = {'three': 3, 'one': 1, 'two': 2} ->>> a == b == c -True -``` - -Providing keyword arguments as in the first example only works for keys that are valid KCL identifiers. Otherwise, any valid keys can be used. - -In the dict comprehension, key/value pairs yielded by the generator expression is set in the dictionary in the order yielded: the first occurrence of the key determines its insertion order, and the last determines the value associated to it. - -```python ->>> {str(i): 2 * i for i in range(3)} -{"0": 0, "1": 2, "2": 4} - ->>> a = {"one": 1, "two": 2, "three": 3} ->>> b = {k: v for k, v in a if v >= 2} -{two: 2, three: 3} -``` - -#### Operations & Members - -These are the operations that dictionaries the support. - -- `list(d)` - Return a list of all the keys used in the dictionary d. -- `len()` - Return the number of items in the dictionary d. -- `d[key]` - Return the item of d with key. Return Undefined if key is not in the map. -- `key in d` - Return True if d has a key, else False. -- `key not in d` - Equivalent to not key in d. -- `d.key` - Return the item of d with key. Return Undefined if key is not in the map. - -Dictionaries compare equal if and only if they have the same (key, value) pairs(keys' ordering matters). Order comparisons (‘<’, ‘<=’, ‘>=’, ‘>’) raise TypeError. - -```python ->>> d = {"one": 1, "two": 2, "three": 3, "four": 4} ->>> d -{'one': 1, 'two': 2, 'three': 3, 'four': 4} ->>> list(d) -['one', 'two', 'three', 'four'] -``` diff --git a/versioned_docs/version-0.5.4/reference/lang/spec/error.md b/versioned_docs/version-0.5.4/reference/lang/spec/error.md deleted file mode 100644 index 2a58b553..00000000 --- a/versioned_docs/version-0.5.4/reference/lang/spec/error.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: "Errors" -linkTitle: "Errors" -type: "docs" -weight: 2 -description: Errors ---- - -When errors happen, developers should be able to detect the error and abort -execution. Thus, KCL introduce the `assert` syntax. - -In the previous topic of `schema` syntax. Errors can also be raised when a -schema is violated. - -## Syntax - -The syntax of the `assert` statement is the following. - -```bnf -assert_stmt: 'assert' test ['if' test] [',' test] -``` - -In the basic form, an `assert` statement evaluates an expression. If the -expression is evaluated to `False`, the assertion is failed, and an error -should be reported. - -In the extended form, an error message can be provided. The error message is -another expression. It is only evaluated when the expression to be evaluated -is evaluated to `False`. The evaluation result of the error message is printed -when reporting the error. - -The following is an example: - -```python -a = 1 -b = 3 -condition = False -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -# if condition is True, then assert `a == b`, if failed, the message "error message" will be printed. -assert a == b if condition, "error message" -``` - -## The Implementation - -When an error happens, no matter it is caused by the `assert` or the `schema` syntax, -the virtual machine should exit with an exit code greater than `0`. - -The virtual machine may choose to dump the back trace information, and it is strongly recommended to implement it. - -In practice, KCL can dump back trace by default, and an argument can be introduced to disable it. diff --git a/versioned_docs/version-0.5.4/reference/lang/spec/expressions.md b/versioned_docs/version-0.5.4/reference/lang/spec/expressions.md deleted file mode 100644 index b52c10f3..00000000 --- a/versioned_docs/version-0.5.4/reference/lang/spec/expressions.md +++ /dev/null @@ -1,915 +0,0 @@ ---- -title: "Expressions" -linkTitle: "Expressions" -type: "docs" -weight: 2 -description: Expressions ---- - -## Syntax - -In KCL, an expression specifies the computation of a value. - -The syntax is the following: - -```bnf -expression: test ("," test)* -test: if_expr | primary_expr | unary_expr | binary_expr -``` - -KCL expressions consist of `if` expression, `primary` expression, `unary` expression, and `binary` expression. - -### Primary Expressions - -Primary expressions are the operands for unary and binary expressions. - -Operands are self-delimiting. An **operand** may be followed by any number of selector dot, a function call, or slice suffixes, to form a primary expression. The grammar uses `expression`, where a multiple-component expression is allowed, and `test` where it accepts an expression of only a single component. - -Syntax: - -```bnf -primary_expr: operand | primary_expr select_suffix | primary_expr call_suffix | primary_expr subscript_suffix -``` - -### Operands - -Operand denotes the elementary value in an expression. An operand may be an identifier, a literal, or a parenthesized expression. - -Syntax: - -```bnf -operand: operand_name | number | string | "True" | "False" | "None" | "Undefined" | list_expr | list_comp | dict_expr | dict_comp | "(" expression ")" -operand_name: identifier | qualified_identifier -``` - -### Identifiers - -In KCL, an identifier is a name, may with selectors, that identifies a value. - -Syntax: - -```bnf -identifier: NAME -``` - -Examples: - -```python -x -a -_b -``` - -Use the `$` character prefix to define keyword identifiers. - -```python -$if = 1 -$else = "s" -``` - -Please note: whether the non-keyword identifier is prefixed with `$` has the same effect. - -```python -_a = 1 -$_a = 2 # equal to `_a = 2` -``` - -To simplify the definition of the qualified identifier, such as 'pkg.type', we additionally define `qualified_identifier`: - -Syntax: - -```bnf -qualified_identifier: identifier "." identifier -``` - -Examples: - -```python -pkg.a -``` - -The package name in qualified_identifier must be imported. - -### Basic Literals - -Basic literals supported in KCL are `int`, `float`, `string` and `bool` including `True` and `False`. Evaluation of basic literal yields a value of the given type with the given value. - -Syntax: - -```bnf -operand: number | string | "True" | "False" | "None" | "Undefined" -``` - -Examples: - -```python -1 -2.3 -"abc" -True -False -None -Undefined -``` - -See more details about **data type** spec. - -### Parenthesized Expressions - -An expression enclosed in parentheses yields the result of that expression. - -Syntax: - -```bnf -operand: '(' expression ')' -``` - -Examples: - -```python -x = (1 + 2) * (3 + 4) # 21 -``` - -### Dictionary Expressions - -A dictionary expression is a comma-separated immutable list of colon-separated key/value expression pairs, enclosed in curly brackets, and it yields a new dictionary object. An optional comma may follow the final pair. - -```bnf -config_expr: '{' config_entries '}' -config_entries: config_entry [config_entry*] -config_comp: '{' (config_entry comp_clause+) '}' -config_entry: expr (':' | '=' | '+=') expr | double_star_expr | if_entry -double_star_expr: "**" expression -if_entry: - 'if' expr ';' if_entry_exec_block - ('elif' expr ':' if_entry_exec_block)* - ('else' ':' if_entry_exec_block)? -NEWLINE: '/r?/n' -``` - -Examples: - -```python -{} -{"one": 1} -{"one": 1, "two": 2} -``` - -The key and value expressions are evaluated in left-to-right order. Evaluation fails if the same key is used multiple times. - -Only hashable values may be used as the keys of a dictionary. This includes all built-in types except dictionaries, and lists. - -We can ignore the comma `,` at the end of the line for writing dict key-value pairs in multiple lines: - -```python -data = { - "key1" = "value1" # Ignore the comma ',' at the end of line - "key2" = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -We can ignore the key quotation marks when we writing simple literals on the key. - -```python -data = { - key1 = "value1" # Ignore the comma ',' at the end of line - key2 = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -In addition, the **config selector expressions** can be used to init a schema instance. - -```python -person = { - base.count = 2 - base.value = "value" - labels.key = "value" -} # {"base": {"count": 2, "value": "value"}, "labels": {"key": "value"}} -``` - -We can **merge** dict using the dict unpacking operator `**` like this: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = {**_part1, **_part2} # {"a: "b", "c": "d"} -``` - -We can use `if expressions` to dynamically add elements to the dict element, elements that meet the conditions are added to the dict, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = { - key1 = "value1" - if a == 1: key2 = "value2" - if a > 0: key3 = "value3" - if a < 0: key4 = "value4" -} # {"key1": "value1", "key2": "value2", "key3": "value3"} -``` - -```python -a = 1 # 1 -data1 = { - key1 = "value1" - if a == 1: - key2 = "value2" - elif a > 0: - key3 = "value3" - else: - key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -data2 = { - key1 = "value1" - if a == 1: key2 = "value2" - elif a > 0: key3 = "value3" - else: key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -``` - -### List Expressions - -A list expression is a comma-separated immutable list of element expressions, enclosed in square brackets, and it yields a new list. An optional comma may follow the last element expression. - -```bnf -list_expr: '[' [list_item [',']] ']' -list_item: test | "*" primary_expr | if_expr -``` - -Element expressions are evaluated in left-to-right order. - -Examples: - -```python -[] # [], empty list -[1] # [1], a 1-element list -[1, 2, 3] # [1, 2, 3], a 3-element list -``` - -We can use `if expressions` to dynamically add elements to the list element, elements that meet the conditions are added to the list, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = [ - 1 - if a == 1: 2 - if a > 0: 3 - if a < 0: 4 -] # [1, 2, 3] -``` - -```python -a = 1 # 1 -data1 = [ - 1 - if a == 1: - 2 - elif a == 2: - 3 - else: - 3 -] # [1, 2] -data2 = [ - 1 - if a == 1: 2 - elif a == 2: 2 - else: 3 -] # [1, 2] -``` - -### Comprehensions - -A comprehension constructs a new list or dictionary value by looping over one or more iterables and evaluating a body expression that produces successive elements of the result. - -Syntax: - -```bnf -list_comp: '[' list_item comp_clause+ ']' . -dict_comp: '{' entry comp_clause+ '}' . - -comp_clause: 'for' loop_variables [","] 'in' test ['if' test] -loop_variables: primary_expr (',' primary_expr)* -``` - -A list comprehension consists of a single expression followed by one or more clauses, the first of which must be a `for` clause. Each `for` clause resembles a `for` statement, and specifies an iterable operand and a set of variables to be assigned by successive values of the iterable. An `if` cause resembles an `if` statement, and specifies a condition that must be met for the body expression to be evaluated. A sequence of `for` and `if` clauses acts like a nested sequence of `for` and `if` statements. - -Examples: - -```python -[x * x for x in range(5)] # [0, 1, 4, 9, 16] -[x * x for x in range(5) if x % 2 == 0] # [0, 4, 16] -[[x, y] for x in range(5) \ - if x % 2 == 0 \ - for y in range(5) \ - if y > x] # [[0, 1], [0, 2], [0, 3], [0, 4], [2, 3], [2, 4]] -``` - -Besides, we can use two variables in the list comprehension, the first variable denotes the list index and the second variable denotes the list item. - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use `_` to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -A dict comprehension resembles a list comprehension, but its body is a pair of expressions, key: value, separated by a colon, and its result is a dictionary containing the key/value pairs for which the body expression was evaluated. Evaluation fails if the value of any key is un-hashable. - -Besides, we can use two variables in the dict comprehension, the first variable denotes the dict key and the second variable denotes the dict value of the key. - -```python -data = {"key1" = "value1", "key2" = "value2"} -# Single variable loop -dataKeys1 = {k: k for k in data} # {"key1": "key1", "key2": "key2"} -dataValues1 = {k: data[k] for k in data} # {"key1": "value1", "key2": "value2"} -# Double variable loop -dataKeys2 = {k: k for k, v in data} # {"key1": "key1", "key2": "key2"} -dataValues2 = {v: v for k, v in data} # {"value1": "value1", "value2": "value2"} -dataFilter = {k: v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use `_` to ignore loop variables -dataKeys3 = {k: k for k, _ in data} # {"key1": "key1", "key2": "key2"} -dataValues3 = {v: v for _, v in data} # {"value1": "value1", "value2": "value2"} -``` - -As with a `for` loop, the loop variables may exploit compound assignment: - -```python -[x * y + z for [x, y], z in [[[2, 3], 5], [["o", 2], "!"]]] # [11, 'oo!'] -``` - -KCL does not accept an un-parenthesized list as the operand of a for clause: - -```python -[x * x for x in 1, 2, 3] # parse error: unexpected comma -``` - -Comprehensions defines a new lexical block, so assignments to loop variables have no effect on variables of the same name in an enclosing block: - -```python -x = 1 -_ = [x for x in [2]] # new variable x is local to the comprehension -print(x) # 1 -``` - -The operand of a comprehension's first clause (always a for) is resolved in the lexical block enclosing the comprehension. In the examples below, identifiers referring to the outer variable named x have been distinguished by subscript. - -```python -x0 = [1, 2, 3] -[x * x for x in x0] # [1, 4, 9] -[x * x for x in x0 if x % 2 == 0] # [4] -``` - -All subsequent for and if expressions are resolved within the comprehension's lexical block, as in this rather obscure example: - -```python -x0 = [[1, 2], [3, 4], [5, 6]] -[x * x for x in x0 for x in x if x % 2 == 0] # [4, 16, 36] -``` - -which would be more clearly rewritten as: - -```python -x = [[1, 2], [3, 4], [5, 6]] -[z * z for y in x for z in y if z % 2 == 0] # [4, 16, 36] -``` - -### Conditional Expressions - -A conditional expression has the form `a if cond else b`. It first evaluates the condition `cond`. If it's true, it evaluates `a` and yields its value; otherwise it yields the value of `b`. - -Syntax: - -```bnf -if_expr: test "if" test "else" test -``` - -Examples: - -```python -x = True if enabled else False # if enabled is -``` - -### Unary Expressions - -In KCL, supported unary operators are `+`, `-`, `~`, and `not`. - -Syntax: - -```bnf -unary_expr: ("+" | "-" | "~") primary_expr - | "not" test -``` - -Usage: - -```bnf -+ number unary positive (int, float) -- number unary negation (int, float) -~ number unary bitwise inversion (int) -not x logical negation (any type) -``` - -The `+` and `-` operators may be applied to any number (int or float) and return the number. -The `not` operator returns the negation of the truth value of its operand. - -Examples: - -```python -~1 # -2 -~-1 # 0 -~0 # -1 -not True # False -not 0 # True -``` - -### Binary Expressions - -In KCL, binary expressions consist of `comparisons`, `logical operations`, `arithmetic operations` and `membership tests`. - -Syntax: - -```bnf -binary_expr: test bin_op test -bin_op: 'or' - | 'and' - | '==' | '!=' | '<' | '>' | '<=' | '>=' - | 'in' | 'not' 'in' - | '|' - | '^' - | '&' - | '-' | '+' - | '*' | '%' | '/' | '//' - | '<<' | '>>' -``` - -#### Logical Operations - -The `or` and `and` operators yield the logical disjunction and conjunction of their arguments, which need not be Booleans. - -The expression `x or y` yields the value of `x` if its truth value is `True`, or the value of `y` otherwise. - -```python -False or False # False -False or True # True -True or True # True -1 or "hello" # 1 -``` - -Similarly, `x` and `y` yields the value of `x` if its truth value is `False`, or the value of `y` otherwise. - -```python -False and False # False -False and True # False -True and True # True -1 and "hello" # "hello" -``` - -These operators use "short circuit" evaluation, so the second expression is not evaluated if the value of the first expression has already determined the result, allowing constructions like these: - -```python -x and x[0] == 1 # x[0] is not evaluated if x is empty -len(x) == 0 or x[0] == "" -not x or not x[0] -``` - -#### Comparisons - -The `==` operator reports whether its operands are equal; the `!=` operator is its negation. - -The operators `<`, `>`, `<=`, and `>=` perform an ordered comparison of their operands. It is an error to apply these operators to operands of unequal type, unless one of the operands is an `int` and the other is a `float`. Of the built-in types, only the following support ordered comparison, using the ordering relation shown: - -```bnf -NoneType # None <= None -bool # False < True -int # mathematical -float # as defined by IEEE 754 -string # lexicographical -list # lexicographical -``` - -Comparison of floating-point values follows the IEEE 754 standard, which breaks several mathematical identities. For example, if `x` is a `NaN` value, the comparisons `x < y`, `x == y`, and `x > y` all yield false for all values of `y`. - -The remaining built-in types support only equality comparisons. Values of type `dict` and `schema` compare equal if their elements compare equal, and values of type function or `builtin_function_or_method` are equal only to themselves. - -```bnf -dict # equal contents -schema # equal exported-attributes -function # identity -builtin_function_or_method # identity -``` - -#### Arithmetic Operations - -The following table summarizes the binary arithmetic operations available for built-in types: - -```bnf -Arithmetic (int or float; result has type float unless both operands have type int) - number + number # addition - number - number # subtraction - number * number # multiplication - number / number # real division (result is always a float) - number // number # floored division - number % number # remainder of floored division - number ^ number # bitwise XOR - number << number # bitwise left shift - number >> number # bitwise right shift - -Concatenation - string + string - list + list - -Repetition (string/list) - int * sequence - sequence * int - -Union - int | int - list | list - dict | dict - schema | schema - schema | dict -basictype | basictype -``` - -The operands of the arithmetic operators `+`, `-`, `*`, `//`, and `%` must both be numbers (`int` or `float`) but need not have the same type. The type of the result has type `int` only if both operands have that type. The result of real division / always has type `float`. - -The `+` operator may be applied to non-numeric operands of the same type, such as two lists, or two strings, in which case it computes the concatenation of the two operands and yields a new value of the same type. - -```python -"Hello, " + "world" # "Hello, world" -[1, 2] + [3, 4] # [1, 2, 3, 4] -``` - -The `*` operator may be applied to an integer n and a value of type `string`, `list`, in which case it yields a new value of the same sequence type consisting of n repetitions of the original sequence. The order of the operands is immaterial. Negative values of n behave like zero. - -```python -'mur' * 2 # 'murmur' -3 * range(3) # [0, 1, 2, 0, 1, 2, 0, 1, 2] -``` - -The `&` operator requires two operands of the same type, such as `int`. For integers, it yields the bitwise intersection (AND) of its operands. - -The `|` operator likewise computes bitwise, unions basic types and unions collection and schema data, such as **list**, **dict** and **schema**. - -Computing bitwise examples: - -```python -0x12345678 | 0xFF # 0x123456FF -``` - -Unioning basic types examples: - -```python -schema x: - a: int | str # attribute a could be a int or string -``` - -A union type is used to define a schema attribute type. See more details in **schema** spec. -Supported types in a union type are `int`, `str`, `float`, `bool`, `list` and `dict`. - -Unioning collection and schema data: - -- Unioning List. Overwrite the list expression on the right side of the operator `|` to the list variable on the left side of the operator one by one according to the **index**. - -```python -_a = [1, 2, 3] -_b = [4, 5, 6, 7] -x = _a | _b # [4, 5, 6, 7] 4 -> 1; 5 -> 2; 6 -> 3; 7 -> None -``` - -Unioning to the specific index or all elements is still under discussion. - -- Unioning Dict. Union the dict expression on the right side of the operator `|` one by one to the dict variable on the left side of the operator according to the **key** - -```python -_a = {key1 = "value1"} -_b = {key1 = "overwrite", key2 = "value2"} -_c = _a | _b # {"key1": "overwrite", "key2": "value2"} -``` - -The union of collection and schema is a new one whose attributes are unioning b to a, preserving the order of the attributes of the operands, left before right. - -Unioning to the specific key or all keys is still under discussion. - -- Unioning Schema. - -The union operation for schema is similar to dict. - -Schema union could be done as: - -```bnf -schema Person: - firstName: str - lastName: str - -_a = Person { - firstName = "John" -} -_b = {lastName = "Doe"} -_a = _a | _b # {"firstName": "John", "lastName": "Doe"} -``` - -Unioning to a specific attribute is still under discussion. Unioning to all attributes is not applicable to schema instances. - -See **selector expression** in **expression** spec for more details. - -The `^` operator accepts operands of `int`. For integers, it yields the bitwise XOR (exclusive OR) of its operands. - -The `<<` and `>>` operators require operands of `int` type both. They shift the first operand to the left or right by the number of bits given by the second operand. It is a dynamic error if the second operand is negative. Implementations may impose a limit on the second operand of a left shift. - -```python -0x12345678 & 0xFF # 0x00000078 -0b01011101 ^ 0b110101101 # 0b111110000 -0b01011101 >> 2 # 0b010111 -0b01011101 << 2 # 0b0101110100 -``` - -#### Membership Tests - -Usage: - -```bnf - any in sequence (list, dict, schema, string) - any not in sequence -``` - -The `in` operator reports whether its first operand is a member of its second operand, which must be a list, dict, schema, or string. The `not in` operator is its negation. Both return a Boolean. - -The meaning of membership varies by the type of the second operand: the members of a list are its elements; the members of a dict are its keys; the members of a string are all its substrings. - -```python -1 in [1, 2, 3] # True - -d = {"one" = 1, "two" = 2} -"one" in d # True -"three" in d # False -1 in d # False -[] in d # False - -"nasty" in "dynasty" # True -"a" in "banana" # True -"f" not in "way" # True - -d = data {one = 1, two = 2} # data is a schema with attributes one and two -"one" in d # True -"three" in d # False -``` - -### Function Invocations - -KCL allows calling built-in functions and functions from built-in and system modules. Whether KCL allows defining new functions is under discussion. - -Syntax: - -```bnf -call_suffix: "(" [arguments [","]] ")" -arguments: argument ("," argument)* -argument: test | identifier "=" test | "*" test | "**" test -``` - -To call a function, the basic way is shown as the following code excerpt: - -```python -print("An argument") - -import math -# 2 powers 3 is 8. -a = math.pow(2, 3) -``` - -As you can see, arguments are separated with `,`. Arguments can only be passed in this way. KCL supports positional arguments and key-value arguments. - -Note that: - -- Some functions have parameters with default values. -- Some functions accept variadic arguments. - -When an argument is not supplied for a parameter without a default value, -an error will be reported. - -### Selector Expressions - -A selector expression selects the attribute or method of the value. - -#### Select Attributes - -Syntax: - -```bnf -select_suffix: ["?"] "." identifier -``` - -KCL provides a wealth of ways to identify or filter attributes. - -x.y - -- schema: it denotes the attribute value of a schema `x` identified by `y` -- package: it denotes the identifier of a package `x` identified by `y` - -Examples: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -name = person.name # "Alice" -age = person.age # 18 -``` - -x?.y - -If the x if None/Undefined or empty(empty list or dict), just return None, otherwise behave as x.y. - -Examples - -```python -noneData = None -data?.name # None - -emptyDict = {} -emptyDict?.name # None - -emptyList = [] -emptyList?[0] # None -``` - -As a supplementary of the `selector` expression in KCL code, the KCL compiler needs to provide corresponding identifying and filtering features through the command line and api form. - -#### Select Methods - -Syntax: - -```bnf -select_suffix: "." identifier -``` - -A `identifier` identifies method belongs to the built-in types `string`, `list`, `dict`, and `schema`. - -- A selector expression fails if the value does not have an attribute of the specified name. -- A selector expression that selects a method typically appears within a call expression, as in these examples: - -Examples: - -```python -["able", "baker", "charlie"].index("baker") # 1 -"banana".count("a") # 3 -"banana".reverse() # error: string has no .reverse field or method -Person.instances() # all instances of schema Person -``` - -But when not called immediately, the selector expression evaluates to a bound method, that is, a method coupled to a specific receiver value. A bound method can be called like an ordinary function, without a receiver argument: - -```bnf -f = "banana".count -f # -f("a") # 3 -f("n") # 2 -``` - -### Index Expressions - -An index expression `a[i]` yields the `i` th element of an indexable type such as a string or list. The index `i` must be an `int` value in the range `-n` ≤ `i` < `n`, where `n` is `len(a)`; any other index results in an error. - -Syntax: - -```bnf -subscript_suffix: "[" [test] "]" -``` - -A valid negative index `i` behaves like the non-negative index `n+i`, allowing for convenient indexing relative to the end of the sequence. - -```python -"abc"[0] # "a" -"abc"[1] # "b" -"abc"[-1] # "c" - -["zero", "one", "two"][0] # "zero" -["zero", "one", "two"][1] # "one" -["zero", "one", "two"][-1] # "two" -``` - -An index expression `d[key]` may also be applied to a dictionary `d`, to obtain the value associated with the specified key. It returns `Undefined` if the dictionary contains no such key. - -An index expression appearing on the left side of an assignment causes the specified list or dictionary element to be updated: - -```python -a = range(3) # a == [0, 1, 2] -b = a[2] # 2 - - -``` - -It is a dynamic error to attempt to update an element of an immutable type, such as a list or string, or a frozen value of a mutable type. - -### Slice Expressions - -A slice expression `a[start:stop:stride]` yields a new value containing a sub-sequence of `a`, which must be a string, or list. - -```bnf -subscript_suffix: "[" [test] [":" [test] [":" [test]]] "]" -``` - -Each of the `start`, `stop`, and `stride` operands is optional; if present, and not `None`, each must be an integer. -The `stride` value defaults to 1. If the stride is not specified, the colon preceding it may be omitted too. It is an error to specify a stride of zero. - -Conceptually, these operands specify a sequence of values `i` starting at start and successively adding `stride` until `i` reaches or passes `stop`. The result consists of the concatenation of values of `a[i]` for which `i` is valid.` - -The effective start and stop indices are computed from the three operands as follows. Let `n` be the length of the sequence. - -**If the stride is positive**: If the `start` operand was omitted, it defaults to -infinity. If the `end` operand was omitted, it defaults to +infinity. For either operand, if a negative value was supplied, `n` is added to it. The `start` and `end` values are then "clamped" to the nearest value in the range 0 to `n`, inclusive. - -**If the stride is negative**: If the `start` operand was omitted, it defaults to +infinity. If the `end` operand was omitted, it defaults to -infinity. For either operand, if a negative value was supplied, `n` is added to it. The `start` and `end` values are then "clamped" to the nearest value in the range -1 to `n`-1, inclusive. - -```python -"abc"[1:] # "bc" (remove first element) -"abc"[:-1] # "ab" (remove last element) -"abc"[1:-1] # "b" (remove first and last element) -"banana"[1::2] # "aaa" (select alternate elements starting at index 1) -"banana"[4::-2] # "nnb" (select alternate elements in reverse, starting at index 4) -``` - -It's not allowed to define a slice expression as a left value in KCL. -Cause list and string are immutable, re-slicing can directly operate to operand to ensure better performance. - -#### Quantifier Expressions - -Quantifier expressions act on collection: list or dict, generally used to obtain a certain result after processing the collection, mainly in the following four forms: - -```bnf -quant_expr: quant_op [ identifier ',' ] identifier 'in' quant_target '{' expr ['if' expr] '}' -quant_target: string | identifier | list_expr |list_comp | dict_expr | dict_comp -quant_op: 'all' | 'any' | 'filter' | 'map' -``` - -- **all** - - Used to detect that all elements in the collection satisfy the given logical expression, and return a boolean value as the result. - - Only when all elements in the collection satisfy the expression true, the `all` expression is true, otherwise it is false. - - If the original collection is empty, return true. - - Supports short-circuiting of logical expressions during expression execution. -- **any** - - Used to detect that at least one element in the collection satisfies the given logical expression, and returns a boolean value as the result. - - When at least one element in the collection satisfies the expression true, the `any` expression is true, otherwise it is false. - - If the original collection is empty, return false. - - Supports short-circuiting of logical expressions during expression execution. -- **map** - - Generate a new **list** by mapping the elements in the original collection. - - The length of the new list is exactly the same as the original collection. -- **filter** - - By logically judging and filtering the elements in the original collection, and returning the filtered sub-collection. - - Only when the element judges the expression to be true, it is added to the sub-collection. - - The type (list, dict and schema) of the new collection is exactly the same as the original collection, and the length range is `[0, len(original-collection)]`. - -**all** and **any** expression sample codes: - -```python -schema Config: - volumes: [{str:}] - services: [{str:}] - - check: - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - }, "invalid cluster ip" - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } -``` - -**map** and **filter** expression sample codes: - -```python -a = map e in [{name = "1", value = 1}, {name = "2", value = 2}] { - {name = e.name, value = int(e.value) ** 2} -} # [{"name": "1", value: 1}, {"name": "2", "value": 4}] - -b = map k, v in {a = "foo", b = "bar"} { v } # ["foo", "bar"] - -c = filter e in [{name = "1", value = 1}, {name = "2", value = 2}] { - int(e.value) > 1 -} # [{"name": "2", "value": 2}] - -d = filter _, v in {a = "foo", b = "bar"} { - v == "foo" -} # {"a": "foo"} -``` - -Please pay attention to distinguish the difference between any expression and any type. When `any` is used in type annotations, it means that the value of the variable is arbitrary, while the any expression means that one of the elements in a set satisfies the condition. diff --git a/versioned_docs/version-0.5.4/reference/lang/spec/index.md b/versioned_docs/version-0.5.4/reference/lang/spec/index.md deleted file mode 100644 index 88bbaa59..00000000 --- a/versioned_docs/version-0.5.4/reference/lang/spec/index.md +++ /dev/null @@ -1 +0,0 @@ -# KCL Spec diff --git a/versioned_docs/version-0.5.4/reference/lang/spec/kcl-spec.md b/versioned_docs/version-0.5.4/reference/lang/spec/kcl-spec.md deleted file mode 100644 index 63a9d6e7..00000000 --- a/versioned_docs/version-0.5.4/reference/lang/spec/kcl-spec.md +++ /dev/null @@ -1,343 +0,0 @@ ---- -title: "KCL Spec" -linkTitle: "KCL Spec" -type: "docs" -weight: 2 -description: KCL Spec ---- - -## Lexical rules - -### Keywords and reserved words - -The following are the keywords of the KCL: - -```python -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -The following are reserved words for the KCL: - -```python -pass return validate rule flow -def del raise except try -finally while from with yield -global nonlocal struct class final -``` - -### Line comment - -```python -# a comment -``` - -### Operators - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != = -+= -= *= **= /= //= %= -<<= >>= &= ^= -``` - -### Delimiters - -```python -( ) [ ] { } -, : . ; @ -``` - -### Operator precedence - -The following list of operators is ordered from **highest to lowest**: - -| Operator | Description | -| -------------------------------------------------------------------------------- | -------------------------------------------------------- | -| `**` | Exponentiation (highest priority) | -| `+x` `-x` `~x` | Positive, negative, bitwise NOT | -| `*` `/` `%` `//` | Multiplication, division, floor division and remainder | -| `+` `-` | Addition and subtraction | -| `<<` `>>` | Left and right shifts | -| `&` | Bitwise AND | -| `^` | Bitwise XOR | -| \| | Bitwise OR | -| `in`, `not in`, `is`, `is not`, `<`, `<=`, `>`, `>=`, `!=`, `==` | Comparisons, including membership and identity operators | -| `not` | Boolean NOT | -| `and` | Boolean AND | -| `or` | Boolean OR | -| `if – else` | Conditional expression = | -| `=`, `+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `=`, `^=`, `\*\*=`, `//=`, `<<=`, `>>=` | Assign | - -## Grammar - -KCL uses Python's [LarkParser](https://lark-parser.readthedocs.io/en/latest/) tool to describe the grammar, and the specification rules are as follows: - -```bnf -//////////// KCL grammar //////////// -start: (NEWLINE | statement)* - -statement: simple_stmt | compound_stmt -simple_stmt: (assign_stmt | unification_stmt | expr_stmt | assert_stmt | import_stmt | type_alias_stmt) NEWLINE -compound_stmt: if_stmt | schema_stmt | rule_stmt - -//////////// import_stmt //////////// -import_stmt: IMPORT dot_name (AS NAME)? -dot_name: (leading_dots identifier) | identifier -leading_dots: DOT+ - -/////////// assert_stmt //////////// -assert_stmt: ASSERT simple_expr (IF simple_expr)? (COMMA test)? - -//////////// if_stmt //////////// -if_stmt: IF test COLON execution_block (ELIF test COLON execution_block)* (ELSE COLON execution_block)? -execution_block: if_simple_stmt | NEWLINE _INDENT schema_init_stmt+ _DEDENT -if_simple_stmt: (simple_assign_stmt | unification_stmt | expr_stmt | assert_stmt) NEWLINE - -//////////// assign_stmt //////////// -assign_stmt: identifier [COLON type] (ASSIGN identifier)* ASSIGN test - | identifier (COMP_PLUS | COMP_MINUS | COMP_MULTIPLY | COMP_DOUBLE_STAR | COMP_DIVIDE - | COMP_DOUBLE_DIVIDE | COMP_MOD | COMP_AND | COMP_OR | COMP_XOR | COMP_SHIFT_LEFT - | COMP_SHIFT_RIGHT) test - -simple_assign_stmt: identifier ASSIGN test - | identifier (COMP_PLUS | COMP_MINUS | COMP_MULTIPLY | COMP_DOUBLE_STAR | COMP_DIVIDE - | COMP_DOUBLE_DIVIDE | COMP_MOD | COMP_AND | COMP_OR | COMP_XOR | COMP_SHIFT_LEFT - | COMP_SHIFT_RIGHT) test - -//////////// unification_stmt //////////// -unification_stmt: identifier COLON schema_expr - -//////////// schema_stmt //////////// -schema_stmt: [decorators] (SCHEMA|MIXIN|PROTOCOL) NAME [LEFT_BRACKETS [schema_arguments] RIGHT_BRACKETS] [LEFT_PARENTHESES identifier (COMMA identifier)* RIGHT_PARENTHESES] [for_host] COLON NEWLINE [schema_body] -schema_arguments: schema_argument (COMMA schema_argument)* -schema_argument: NAME [COLON type] [ASSIGN test] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt|schema_init_stmt|schema_index_signature)* [check_block] _DEDENT -schema_attribute_stmt: attribute_stmt NEWLINE -attribute_stmt: [decorators] identifier [QUESTION] COLON type [(ASSIGN|COMP_OR) test] -schema_init_stmt: if_simple_stmt | if_stmt -schema_index_signature: LEFT_BRACKETS [NAME COLON] [ELLIPSIS] basic_type RIGHT_BRACKETS COLON type [ASSIGN test] NEWLINE - -//////////// rule_stmt //////////// -rule_stmt: [decorators] RULE NAME [LEFT_BRACKETS [schema_arguments] RIGHT_BRACKETS] [LEFT_PARENTHESES identifier (COMMA identifier)* RIGHT_PARENTHESES] [for_host] COLON NEWLINE [rule_body] -rule_body: _INDENT (string NEWLINE)* check_expr+ _DEDENT - -for_host: FOR identifier - -/////////// decorators //////////// -decorators: (AT decorator_expr NEWLINE)+ -decorator_expr: identifier [call_suffix] - -//////////// type //////////// -type: type_element (OR type_element)* -type_element: schema_type | basic_type | compound_type | literal_type -schema_type: identifier -basic_type: STRING_TYPE | INT_TYPE | FLOAT_TYPE | BOOL_TYPE | ANY_TYPE -compound_type: list_type | dict_type -list_type: LEFT_BRACKETS (type)? RIGHT_BRACKETS -dict_type: LEFT_BRACE (type)? COLON (type)? RIGHT_BRACE -literal_type: string | number | TRUE | FALSE | NONE - -//////////// type alias //////////// -type_alias_stmt: TYPE NAME ASSIGN type - -//////////// check_stmt //////////// -check_block: CHECK COLON NEWLINE _INDENT check_expr+ _DEDENT -check_expr: simple_expr [IF simple_expr] [COMMA primary_expr] NEWLINE - -//////////// mixin_stmt //////////// -mixin_stmt: MIXIN LEFT_BRACKETS [mixins | multiline_mixins] RIGHT_BRACKETS NEWLINE -multiline_mixins: NEWLINE _INDENT mixins NEWLINE _DEDENT -mixins: identifier (COMMA (NEWLINE mixins | identifier))* - - -//////////// expression_stmt //////////// -expr_stmt: testlist_expr -testlist_expr: test (COMMA test)* -test: if_expr | simple_expr -if_expr: simple_expr IF simple_expr ELSE test - -simple_expr: unary_expr | binary_expr | primary_expr - -unary_expr: un_op simple_expr -binary_expr: simple_expr bin_op simple_expr - -bin_op: L_OR | L_AND - | OR | XOR | AND - | SHIFT_LEFT | SHIFT_RIGHT - | PLUS | MINUS | MULTIPLY | DIVIDE | MOD | DOUBLE_DIVIDE - | DOUBLE_STAR - | EQUAL_TO | NOT_EQUAL_TO - | LESS_THAN | GREATER_THAN | LESS_THAN_OR_EQUAL_TO | GREATER_THAN_OR_EQUAL_TO - | IN | L_NOT IN | IS | IS L_NOT | L_NOT | AS -un_op: L_NOT | PLUS | MINUS | NOT - -primary_expr: identifier call_suffix | operand | primary_expr select_suffix | primary_expr call_suffix | primary_expr slice_suffix -operand: identifier | number | string | constant | quant_expr | list_expr | list_comp | config_expr | dict_comp | schema_expr | lambda_expr | LEFT_PARENTHESES test RIGHT_PARENTHESES -select_suffix: [QUESTION] DOT NAME -call_suffix: LEFT_PARENTHESES [arguments [COMMA]] RIGHT_PARENTHESES -slice_suffix: [QUESTION] LEFT_BRACKETS (test | [test] COLON [test] [COLON [test]]) RIGHT_BRACKETS -arguments: argument (COMMA argument)* -argument: test | NAME ASSIGN test | MULTIPLY test | DOUBLE_STAR test - - -//////////// operand //////////// -identifier: NAME (DOT NAME)* -quant_expr: quant_op [ identifier COMMA ] identifier IN quant_target LEFT_BRACE (simple_expr [IF simple_expr] | NEWLINE _INDENT simple_expr [IF simple_expr] NEWLINE _DEDENT)? RIGHT_BRACE -quant_target: string | identifier | list_expr | list_comp | config_expr | dict_comp -quant_op: ALL | ANY | FILTER | MAP -list_expr: LEFT_BRACKETS [list_items | NEWLINE [_INDENT list_items _DEDENT]] RIGHT_BRACKETS -list_items: list_item ((COMMA [NEWLINE] | [NEWLINE]) list_item)* [COMMA] [NEWLINE] -list_item: test | star_expr | if_item -list_comp: LEFT_BRACKETS (list_item comp_clause+ | NEWLINE _INDENT list_item comp_clause+ _DEDENT) RIGHT_BRACKETS -dict_comp: LEFT_BRACE (entry comp_clause+ | NEWLINE _INDENT entry comp_clause+ _DEDENT) RIGHT_BRACE -entry: test (COLON | ASSIGN | COMP_PLUS) test -comp_clause: FOR loop_variables [COMMA] IN simple_expr [NEWLINE] [IF test [NEWLINE]] -if_entry: IF test COLON if_entry_exec_block (ELIF test COLON if_entry_exec_block)* (ELSE COLON if_entry_exec_block)? -if_entry_exec_block: (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry) [NEWLINE] | NEWLINE _INDENT (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry) ((COMMA [NEWLINE] | [NEWLINE]) (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry))* [COMMA] [NEWLINE] _DEDENT -if_item: IF test COLON if_item_exec_block (ELIF test COLON if_item_exec_block)* (ELSE COLON if_item_exec_block)? -if_item_exec_block: list_item [NEWLINE] | NEWLINE _INDENT list_item ((COMMA [NEWLINE] | NEWLINE) list_item)* [COMMA] [NEWLINE] _DEDENT - -star_expr: MULTIPLY test -double_star_expr: DOUBLE_STAR test -loop_variables: primary_expr (COMMA primary_expr)* -schema_expr: identifier (LEFT_PARENTHESES [arguments] RIGHT_PARENTHESES)? config_expr -config_expr: LEFT_BRACE [config_entries | NEWLINE [_INDENT config_entries _DEDENT]] RIGHT_BRACE -config_entries: config_entry ((COMMA [NEWLINE] | [NEWLINE]) config_entry)* [COMMA] [NEWLINE] -config_entry: test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry - -//////////// lambda_expr //////////// -lambda_expr: LAMBDA [schema_arguments] [RIGHT_ARROW type] LEFT_BRACE [expr_stmt | NEWLINE _INDENT schema_init_stmt+ _DEDENT] RIGHT_BRACE - -//////////// misc //////////// -number: DEC_NUMBER [multiplier] | HEX_NUMBER | BIN_NUMBER | OCT_NUMBER | FLOAT_NUMBER -multiplier: SI_N_L | SI_U_L | SI_M_L | SI_K_L | SI_K | SI_M | SI_G | SI_T | SI_P - | SI_K_IEC | SI_M_IEC | SI_G_IEC | SI_T_IEC | SI_P_IEC -string: STRING | LONG_STRING -constant : TRUE | FALSE | NONE | UNDEFINED -// Tokens - -ASSIGN: "=" -COLON: ":" -SEMI_COLON: ";" -COMMA: "," -QUESTION: "?" -ELLIPSIS: "..." -RIGHT_ARROW: "->" -LEFT_PARENTHESES: "(" -RIGHT_PARENTHESES: ")" -LEFT_BRACKETS: "[" -RIGHT_BRACKETS: "]" -LEFT_BRACE: "{" -RIGHT_BRACE: "}" -PLUS: "+" -MINUS: "-" -MULTIPLY: "*" -DIVIDE: "/" -MOD: "%" -DOT: "." -AND: "&" -OR: "|" -XOR: "^" -NOT: "~" -LESS_THAN: "<" -GREATER_THAN: ">" -EQUAL_TO: "==" -NOT_EQUAL_TO: "!=" -GREATER_THAN_OR_EQUAL_TO: ">=" -LESS_THAN_OR_EQUAL_TO: "<=" -DOUBLE_STAR: "**" -DOUBLE_DIVIDE: "//" -SHIFT_LEFT: "<<" -SHIFT_RIGHT: ">>" -AT: "@" - -COMP_PLUS: "+=" -COMP_MINUS: "-=" -COMP_MULTIPLY: "*=" -COMP_DIVIDE: "/=" -COMP_MOD: "%=" -COMP_AND: "&=" -COMP_OR: "|=" -COMP_XOR: "^=" -COMP_DOUBLE_STAR: "**=" -COMP_DOUBLE_DIVIDE: "//=" -COMP_SHIFT_LEFT: "<<=" -COMP_SHIFT_RIGHT: ">>=" - -// Special tokens -IMPORT: "import" -AS: "as" -RULE: "rule" -SCHEMA: "schema" -MIXIN: "mixin" -PROTOCOL: "protocol" -CHECK: "check" -FOR: "for" -ASSERT: "assert" -IF: "if" -ELIF: "elif" -ELSE: "else" -L_OR: "or" -L_AND: "and" -L_NOT: "not" -IN: "in" -IS: "is" -LAMBDA: "lambda" -ALL: "all" -ANY: "any" -FILTER: "filter" -MAP: "map" -TYPE: "type" - -ANY_TYPE: "any" -STRING_TYPE: "str" -INT_TYPE: "int" -FLOAT_TYPE: "float" -BOOL_TYPE: "bool" - -// Constant tokens -TRUE: "True" -FALSE: "False" -NONE: "None" -UNDEFINED: "Undefined" - -// Binary prefix -SI_N_L: "n" -SI_U_L: "u" -SI_M_L: "m" -SI_K_L: "k" -SI_K: "K" -SI_M: "M" -SI_G: "G" -SI_T: "T" -SI_P: "P" -SI_K_IEC: "Ki" -SI_M_IEC: "Mi" -SI_G_IEC: "Gi" -SI_T_IEC: "Ti" -SI_P_IEC: "Pi" -IEC: "i" - -NAME: /\$?[a-zA-Z_]\w*/ -COMMENT: /#[^\n]*/ -NEWLINE: ( /\r?\n[\t ]*/ | COMMENT )+ - -STRING: /r?("(?!"").*?(? **note** -> -> Any character except the ASCII space, tab (`\t`) and formfeed (`\f`) is considered a none-space character. - -- A line ending in a backslash cannot carry a comment (, which will be introduced shortly afterwards). -- A backslash does not continue a comment. -- A backslash does not continue a token except for string literals (i.e., tokens other than string literals cannot be split across physical lines using a backslash). -- A backslash is illegal elsewhere on a line outside a string literal. - -### Implicit Line Joining - -Expressions in parentheses, square brackets or curly braces can be split over more than one physical line without using backslashes. - -- Implicitly continued lines can carry comments. -- The indentation of the continuation lines is not important. -- Blank continuation lines are allowed. -- There is no `NEWLINE` token between implicit continuation lines. -- Implicitly continued lines can also occur within triple-quoted strings (see below); in that case they cannot carry comments. - -### Blank Lines - -### Indentation - -### Comments - -Starting with a `#` character that is not part of a string literal is a comment. A comment ends at the end of the physical line. - -A comment signifies the end of the logical line unless the implicit line joining rules are invoked. - -Comments are ignored by the syntax. - -### Identifiers and Keywords - -Identifiers (also referred to as names) are described by the following lexical definitions. - -Within the ASCII range (from `U+0001` to `U+007F`), the valid characters for identifiers are the uppercase and lowercase letters `A` through `Z`, the underscore `_` and, except for the first character, the digits `0` through `9`. - -Identifiers are unlimited in length. The case is significant. - -### Keywords - -The following identifiers are used as reserved words, or keywords of the language, and cannot be used as ordinary identifiers. They must be spelled exactly as written here: - -``` -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -The following tokens are not used, but they are reserved as possible future keywords: - -``` -pass return validate rule flow -def del raise except try -finally while from with yield -global nonlocal struct class final -``` - -### Literals - -Literals are notations for constant values of some built-in types. - -### String Literals - -String literals are described by the following lexical definitions: - -``` -stringliteral ::= [stringprefix](shortstring | longstring) -stringprefix ::= "r" | "R" -shortstring ::= "'" shortstringitem* "'" | '"' shortstringitem* '"' -longstring ::= "'''" longstringitem* "'''" | '"""' longstringitem* '"""' -shortstringitem ::= shortstringchar | stringescapeseq -longstringitem ::= longstringchar | stringescapeseq -shortstringchar ::= -longstringchar ::= -stringescapeseq ::= "\" -``` - -Multiple adjacent string or bytes literals (delimited by whitespace),possibly using different quoting conventions, are allowed, and their meaning is the same as their concatenation. - -### Numeric Literals - -There are two types of numeric literals: integers and floating-point numbers. - -Integer literals are described by the following lexical definitions: - -``` -integer ::= decinteger | bininteger | octinteger | hexinteger -decinteger ::= nonzerodigit (["_"] digit)* | "0"+ (["_"] "0")* -bininteger ::= "0" ("b" | "B") (["_"] bindigit)+ -octinteger ::= "0" ("o" | "O") (["_"] octdigit)+ -hexinteger ::= "0" ("x" | "X") (["_"] hexdigit)+ -nonzerodigit ::= "1"..."9" -digit ::= "0"..."9" -bindigit ::= "0" | "1" -octdigit ::= "0"..."7" -hexdigit ::= digit | "a"..."f" | "A"..."F" -``` - -Floating-point literals are described by the following lexical definitions: - -``` -floatnumber ::= pointfloat | exponentfloat -pointfloat ::= [digitpart] fraction | digitpart "." -exponentfloat ::= (digitpart | pointfloat) exponent -digitpart ::= digit (["_"] digit)* -fraction ::= "." digitpart -exponent ::= ("e" | "E") ["+" | "-"] digitpart -``` - -## Operators and Delimiters - -### Operators - -The following tokens are operators: - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != @ -``` - -### Delimiters - -The following tokens serve as delimiters in the grammar: - -```python -( ) [ ] { } -, : . ; = += --= *= **= /= //= %= -<<= >>= &= |= ^= -``` - -The period can also occur in floating-point literals. - -The following printing ASCII characters have special meaning as part of other tokens or are otherwise significant to the lexical analyzer: - -``` -' " # \ -``` - -The following printing ASCII characters are not used in KCL. Their occurrence outside string literals and comments is an unconditional error: - -``` -? ` -``` - -## Reference - -Since the lexical conventions of KCL is very similar to that of Python, we use the following document as the reference when writing this chapter. - -- [https://docs.python.org/3/reference/lexical_analysis.html](https://docs.python.org/3/reference/lexical_analysis.html) diff --git a/versioned_docs/version-0.5.4/reference/lang/spec/modules.md b/versioned_docs/version-0.5.4/reference/lang/spec/modules.md deleted file mode 100644 index f8608619..00000000 --- a/versioned_docs/version-0.5.4/reference/lang/spec/modules.md +++ /dev/null @@ -1,621 +0,0 @@ ---- -title: "Modules" -linkTitle: "Modules" -type: "docs" -weight: 2 -description: Modules ---- - -## Modules and the Import System - -KCL code is organized in **modules**. For code in one module to access the code defined in another module, a process called **importing** must be used. - -Importing is undertaken at compile-time in KCL. The advantage is to have static checking enabled. - -A regular KCL module is a file on the file system. It is required to have a `.k` suffix. - -## Packages - -To help manage modules and provide a naming hierarchy, KCL has the concept of packages. In KCL, a package maps to exactly a file system directory, and a regular module maps to a file. - -Files directly under a package are considered parts of the package, instead of individual regular modules. - -Packages can have sub-packages. - -Packages are special modules: - -- All packages in KCL are modules. -- A single-file module can never be a package. - -All modules have a name. - -Sub package names are separated from their parent package name by dots. - -To summary, a regular KCL module is a `.k` file, and a package is a directory on the file system. All `.k` files directly under the directory are included in the package, other files are ignored. If the directory has subdirectories, they become sub-packages as long as there are `.k` files underneath. - -### Intra-Package Name Space Sharing - -Inside a package, all `.k` files are considered parts of the package, instead of regular modules. Code in these files share a single name space and can access names defined in other files, without explicitly granted. - -### Package Initialization - -A package can have the initialization code. The code must exist in only one of the `.k` files under this package. The interpreter guarantees that the initialization code is executed after all definitions. - -## Searching - -The searching begins when an `import` statement is used to import a module. - -### Module Cache - -In KCL, only standard system modules are cached. When a cached module is imported, the cached version is used. In other words, KCL runtime would not create another copy of the standard system module in memory. - -However, other modules are uncached. Importing a module multiple time would create multiple instances of the module. - -### Module Names - -An `import` statement specifies the name of the module to import. The syntax is: - -``` -import [as ] -``` - -The rule to search with the module name is very simple: - -- **Step 1**: Searches the module name from the **standard system modules**, then **plugins modules**. - - See **standard system modules** and **plugins modules** for more details. If matched, the module is imported. Otherwise, continue to **Step 2**. -- **Step 2**. Whether a module name starts with a `.` is checked. If yes, the name is a so-called relative pathname, and we go to **Step 5**. Otherwise, continue to **Step 3**. -- **Step 3**: If the module name does not start with any `.`, then the compiler searches the nearest `root path` directory from this directory to the parent, and find the module according to the name just from the `root path`. If no `root path` is found, find the module according to the name from the folder the `.k` file including this `import` statement exists. - - **root path**: the directory contains a `kcl.mod` file. If matched, the module is imported. Otherwise, continue to **Step 4**. -- **Step 4**: Then the compiler checks if the name is the name of any library module that requires explicit loading. If matched, the library module is imported. Otherwise, continue to **Step 6**. -- **Step 5**. For relative importing, find the module according to the name from the folder the `.k` file including this `import` statement exists. Interpret leading dots using the following rule: -- One dot: Ignore. -- Tow or more dots: Suppose there are `n` leading dots, then the searching starts at `n - 1` levels above this folder. If matched, the module is imported. Otherwise, continue to **Step 6**. -- **Step 6**. Module not found, report an error. - -Do case-sensitive search when the operating system allows. If case-sensitive search is not allowed, search directories before regular files. - -In KCL, the `from <> import <>` is unsupported, and relative import is performed with the `import <>` syntax. - -### Uniqueness of Module - -Each module has a unique location path in its scope, so that a module or package could be located with a unique location path, such as `a.b.c`. - -Searching by location path should be supported by the kcl compiler, which needs to provide corresponding searching features through the command line and api form. - -## Standard System Packages - -KCL supports a few standard system modules. The following is the full list of these standard system modules: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PackageMember
datetimetoday
now
ticks
date
mathceil
exp
expm1
factorial
floor
gcd
isfinite
isinf
isnan
log
log1p
log2
log10
modf
pow
sqrt
regexreplace
match
compile
findall
search
split
unitsn
u
m
k
K
M
G
T
P
Ki
Mi
Gi
Ti
Pi
to_n
to_u
to_m
to_K
to_M
to_G
to_T
to_P
to_Ki
to_Mi
to_Gi
to_Ti
to_Pi
jsonencode
decode
dump_to_file
yamlencode
decode
dump_to_file
netsplit_host_port
join_host_port
fqdn
parse_IP
to_IP4
to_IP16
IP_string
is_IPv4
is_IP
is_loopback_IP
is_multicast_IP
is_interface_local_multicast_IP
is_link_local_multicast_IP
is_link_local_unicast_IP
is_global_unicast_IP
is_unspecified_IP
base64encode
decode
cryptomd5
sha1
sha224
sha256
sha384
sha512
- -- datetime - - ticks() -> float - Return the current time in seconds since the Epoch. Fractions of a second may be present if the system clock provides them. - - date() -> str - return the `%Y-%m-%d %H:%M:%S` format date. - - now() -> str - return the local time. e.g. `'Sat Jun 06 16:26:11 1998'` - - today() -> str - return the `%Y-%m-%d %H:%M:%S.%{ticks}` format date. -- math - - ceil(x) -> int - Return the ceiling of x as an Integral. This is the smallest integer >= x. - - factorial(x) -> int - Return x!. Raise a error if x is negative or non-integral. - - floor(x) -> int - Return the floor of x as an Integral. This is the largest integer <= x. - - gcd(a: int, b: int) -> int - Return the greatest common divisor of x and y - - isfinite(x) -> bool - Return True if x is neither an infinity nor a NaN, and False otherwise. - - isinf(x) -> bool - Return True if x is a positive or negative infinity, and False otherwise. - - isnan(x) -> bool - Return True if x is a NaN (not a number), and False otherwise. - - modf(x) -> Listfloat, float] - Return the fractional and integer parts of x. Both results carry the sign of x and are floats. - - exp(x) -> float - Return e raised to the power of x. - - expm1(x) -> float - Return exp(x)-1. This function avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small x. - - log(x, base=2.71828182845904523536028747135266250) -> float - Return the logarithm of x to the base e. - - log1p(x) -> float - Return the natural logarithm of 1+x (base e). The result is computed in a way which is accurate for x near zero. - - log2(x) -> float - Return the base 2 logarithm of x. - - log10(x) -> float - Return the base 10 logarithm of x. - - pow(x, y) -> float - Return x\*\*y (x to the power of y). - - sqrt(x) -> float - Return the square root of x. -- regex - - replace(string: str, pattern: str, replace: str, count=0) -> str - Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement. - - match(string: str, pattern: str) -> bool - Try to apply the pattern at the start of the string, returning a bool value True if any match was found, or False if no match was found. - - compile(pattern: str) -> bool - Compile a regular expression pattern, returning a bool value denoting whether the pattern is valid. - - findall(string: str, pattern: str) -> List[str] - Return a list of all non-overlapping matches in the string. - - search(string: str, pattern: str) -> bool - Scan through string looking for a match to the pattern, returning a bool value True if any match was found, or False if no match was found. - - split(string: str, pattern: str, maxsplit=0) -> List[str] - Scan through string looking for a match to the pattern, returning a Match object, or None if no match was found. -- units - - Unit constants - - Fixed point: `n`, `u`, `m`, `k`, `K`, `G`, `T` and `P`. - - Power of 2: `Ki`, `Mi`, `Gi`, `Ti` and `Pi`. - - Functions - - to_n(num: int) -> str - Int literal to string with `n` suffix - - to_u(num: int) -> str - Int literal to string with `u` suffix - - to_m(num: int) -> str - Int literal to string with `m` suffix - - to_K(num: int) -> str - Int literal to string with `K` suffix - - to_M(num: int) -> str - Int literal to string with `M` suffix - - to_G(num: int) -> str - Int literal to string with `G` suffix - - to_T(num: int) -> str - Int literal to string with `T` suffix - - to_P(num: int) -> str - Int literal to string with `P` suffix - - to_Ki(num: int) -> str - Int literal to string with `Ki` suffix - - to_Mi(num: int) -> str - Int literal to string with `Mi` suffix - - to_Gi(num: int) -> str - Int literal to string with `Gi` suffix - - to_Ti(num: int) -> str - Int literal to string with `Ti` suffix - - to_Pi(num: int) -> str - Int literal to string with `Pi` suffix -- json - - encode(data: any, sort_keys: bool = False, indent: int = None, ignore_private: bool = False, ignore_none: bool = False) -> str - Serialize a KCL object `data` to a JSON formatted str. - - decode(value: str) -> any - Deserialize `value` (a string instance containing a JSON document) to a KCL object. - - dump_to_file(data: any, filename: str, ignore_private: bool = False, ignore_none: bool = False) -> None - Serialize a KCL object `data` to a JSON formatted str and write it into the file `filename`. -- yaml - - encode(data: any, sort_keys: bool = False, ignore_private: bool = False, ignore_none: bool = False) -> str - Serialize a KCL object `data` to a YAML formatted str. - - decode(value: str) -> any - Deserialize `value` (a string instance containing a YAML document) to a KCL object. - - dump_to_file(data: any, filename: str, ignore_private: bool = False, ignore_none: bool = False) -> None - Serialize a KCL object `data` to a YAML formatted str and write it into the file `filename`. -- net - - split_host_port(ip_end_point: str) -> List[str] - Split the 'host' and 'port' from the ip end point. - - join_host_port(host, port) -> str - Merge the 'host' and 'port'. - - fqdn(name: str = '') -> str - Return Fully Qualified Domain Name (FQDN). - - parse_IP(ip) -> str - Parse 'ip' to a real IP address - - to_IP4(ip) -> str - Get the IP4 form of 'ip'. - - to_IP16(ip) -> int - Get the IP16 form of 'ip'. - - IP_string(ip: str | int) -> str - Get the IP string. - - is_IPv4(ip: str) -> bool - Whether 'ip' is a IPv4 one. - - is_IP(ip: str) -> bool - Whether ip is a valid ip address. - - is_loopback_IP(ip: str) -> bool - Whether 'ip' is a loopback one. - - is_multicast_IP(ip: str) -> bool - Whether 'ip' is a multicast one. - - is_interface_local_multicast_IP(ip: str) -> bool - Whether 'ip' is a interface, local and multicast one. - - is_link_local_multicast_IP(ip: str) -> bool - Whether 'ip' is a link local and multicast one. - - is_link_local_unicast_IP(ip: str) -> bool - Whether 'ip' is a link local and unicast one. - - is_global_unicast_IP(ip: str) -> bool - Whether 'ip' is a global and unicast one. - - is_unspecified_IP(ip: str) -> bool - Whether 'ip' is a unspecified one. -- base64 - - encode(value: str, encoding: str = "utf-8") -> str - Encode the string `value` using the codec registered for encoding. - - decode(value: str, encoding: str = "utf-8") -> str - Decode the string `value` using the codec registered for encoding. -- crypto - - md5(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `MD5` and the codec registered for encoding. - - sha1(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA1` and the codec registered for encoding. - - sha224(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA224` and the codec registered for encoding. - - sha256(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA256` and the codec registered for encoding. - - sha384(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA384` and the codec registered for encoding. - - sha512(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA512` and the codec registered for encoding. -- manifests - - `yaml_stream(values: [any], opts: {str:} = {sort_keys = False, ignore_private = True, ignore_none = False, sep = "---"}`. This function is used to serialize the KCL object list into YAML output with the `---` separator - -### The Built-in System Package - -KCL provides a list of built-in system modules, which are loaded automatically and can be directly used without providing any module name. For example, `print` is a widely used built-in module. - -The following is the full list of these built-in system modules: - -- print() - - The print function. -- multiplyof(a, b) - - Check if the modular result of a and b is 0 -- isunique(inval) - - Check if a list has duplicated elements -- len(inval) - Return the length of a value -- abs(x) - Return the absolute value of the argument. -- all(iterable) - Return True if bool(x) is True for all values x in the iterable. If the iterable is empty, return True. -- any(iterable) - Return True if bool(x) is True for any x in the iterable. If the iterable is empty, return False. -- bin(number) - Return the binary representation of an integer. -- hex(number) - Return the hexadecimal representation of an integer. -- oct(number) - Return the octal representation of an integer. -- ord(c) -> int - Return the Unicode code point for a one-character string. -- sorted(iterable) - Return a new list containing all items from the iterable in ascending order. A custom key function can be supplied to customize the sort order, and the reverse flag can be set to request the result in descending order. -- range(start, end, step=1) - Return the range of a value with start, end and step parameter. -- min(iterable) - With a single iterable argument, return its smallest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the smallest argument. -- max(iterable) - With a single iterable argument, return its biggest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the largest argument. -- sum(iterable, start) - Return the sum of a 'start' value (default: 0) plus an iterable of numbers. When the iterable is empty, return the start value. This function is intended specifically for use with numeric values and may reject non-numeric types. -- pow(x, y, z) - Equivalent to `x**y` (with two arguments) or `x**y % z` (with three arguments). Some types, such as ints, are able to use a more efficient algorithm when invoked using the three argument form. -- round(number, ndigits) - Round a number to a given precision in decimal digits. The return value is an integer if ndigits is omitted or None. Otherwise the return value has the same type as the number. ndigits may be negative. -- typeof(x: any, \*, full_name: bool = False) -> str - Return the type of the value 'x' at runtime. When the 'full_name' is 'True', return the full package type name such as `pkg.schema`. - -### Plugin Modules - -KCL compiler needs to provide the ability to dynamically expand and load plugin modules without modifying the compiler itself. KCL compiler needs to support flexible pluggable module extension mechanism, so that KCL users can use more abundant built-in function capabilities to simplify writing. - -KCL compiler needs to ensure the stability and safety of the expansion mechanism, without affecting the core of the compiler. - -Searching extended plugin module is performed after the standard system module. The standard system module has a higher priority in naming. If it exists a standard or built-in system module with the same name, the extended plugin module will be ignored. - -Importing and using the extended plugin module should be consistent with the standard or built-in system module. - -### Replacing Standard System Packages - -Replacing standard system modules is not allowed. - -## Examples - -We show more module features through an example. - -Suppose we have the following directories and files: - -``` - . - ├── mod1.k - ├── mod2.k - ├── pkg1 - │   ├── def1.k - │   ├── def2.k - │   └── def3init.k - └── pkg2 - ├── file2.k - └── subpkg3 - └── file3.k -``` - -From the structure we can see that `pkg1` and `pkg2` are two packages, `subpkg3` is a subpackage of `pkg2`, and `mod1.k` and `mod2.k` are regular modules. - -### Importing a Standard System Package - -The following statement can import the standard system module `math` - -```python -import math -``` - -This is the only way to import a standard system module. After importing a standard system module, functions, variables and schemas defined in it can be used. For example, the following statement uses the `log10` function -defined in `math` - -```python -a = math.log10(100) # a is 2 after computation. -``` - -### Importing a Regular Module - -In `mod1.k`, we can import `mod2` using one of the following syntaxes. - -```python -import mod2 -``` - -```python -import .mod2 -``` - -The difference is that in the first syntax, the KCL compiler will first try to check if `mod2` matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where `mod1.k` resists in, like what the second statement does. - -Suppose in `mod2.k` there is a definition of a variable:: - -```python -a = 100 -``` - -After importing `mod2`, we can access `a` in `mod1.k` using the following syntax - -```python -b = mod2.a -``` - -### Importing a Package - -In `mod1.k`, we can import `pkg1` using one of the following syntaxes. - -```python -import pkg1 -``` - -```python -import .pkg1 -``` - -The difference is that in the first syntax, the KCL compiler will first try to check if `pkg1` matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where `mod1.k` resists in, like what the second statement does. - -We can use similar statements to import `pkg2`. Note that importing `pkg2` will not import `subpkg3`. - -The name of the package is the name of the imported module. - -Suppose in `file2.k` that is inside `pkg2` there is a definition to variable `foo` - -```python -foo = 100 -``` - -This variable can be used in `mod1.k` after importing `pkg2` like the following - -```python -bar = pkg2.foo -``` - -### Importing a Subpackage - -To import `subpkg3` from `mod1.k`, one of the following statements can be used. - -```python -import pkg2.subpkg3 -``` - -```python -import .pkg2.subpkg3 -``` - -The behaviors of these statements are identical. - -The name of the subpackage is the name of the imported module. - -Suppose in `file3.k` that is inside `subpkg3` there is a definition to variable `foo` - -```python -foo = 100 -``` - -This variable can be used in `mod1.k` after importing `subpkg3` like the following - -```python -bar = subpkg3.foo -``` - -### Relative Importing - -Relative importing is useful when there is code trying to import modules that does not exist recursively inside the current directory. - -For example, the following statements, if written in `file3.k`, can be used to import `pkg2`, `pkg1` and `mod2` respectively. - -```python -import ...pkg2 # Go two levels up then import pkg2 -import ...pkg1 # Go two levels up then import pkg1 -import ...mod2 # Go two levels up then import mod2 -``` - -### Importing from a Root Path - -Suppose we have a `kcl.mod` file in the directory to mark it as a root path, then we have the following files: - -``` - . - |── kcl.mod - ├── mod1.k - ├── mod2.k - ├── pkg1 - │   ├── def1.k - │   ├── def2.k - │   └── def3init.k - └── pkg2 - ├── file2.k - └── subpkg3 - └── file3.k -``` - -In `pkg1` `def1.k`, we can import `pkg2.subpkg3` `file3` using the following syntaxes. - -```python -import pkg2.subpkg3.file3 -``` - -Importing from the root path is very convenient when the code is trying to import modules from a directory needs to look up multiple directories above this directory. At also, it is helpful to organize a large number of files in a root directory. - -### Importing a Module Inside a Package - -Note that `subpkg3` is only implemented with one file `file3.k`. The file can be regarded as a regular module and imported directly. - -In `mod1.k`, the importing statement would be:: - -```python -import pkg2.subpkg3.file3 -``` - -Different from importing `subpkg3`, now the name of the module is `file3`. We can access the variable `foo` defined in this module with the following -statement - -```python -bar = file3.foo -``` - -### Precedence of Importing - -When an import statement specifies a package to import, the virtual machine first looks for a directory named according to the import statement in the file system. - -If such a directory is not found, the virtual machine looks for a single file module. - -For example, when the statement `import a.b.c` appears, the virtual machine first looks for the directory `a/b/c` from the directory of the current file. If `a/b/c` is not found, the virtual machine looks for a file named `a/b/c.k`. If the file is also absent, an error is reported. - -### Package Implemented with Multiple Files - -Package `pkg1` is implemented with multiple KCL files. - -Multiple files can be used to define variables, schemas and functions, and they can access names defined in other files of this package. - -For example, suppose `def1.k` defines a variable `foo`, `def2.k` defines `bar`, and `def3init.k` defines a variable `baz`, when `pkg1` is imported by `mod1.k`, all these variable can be used - -```python -import pkg1 -a = pkg1.foo + pkg1.bar + pkg1.baz -``` - -Inside a module, names defined in a file can be accessed in another file without further importing. For example, suppose `bar` in `def2.k` would invoke `foo` defined in `def1.k`, it can directly use `foo` like the following - -```python -bar = foo + 1 -``` diff --git a/versioned_docs/version-0.5.4/reference/lang/spec/schema.md b/versioned_docs/version-0.5.4/reference/lang/spec/schema.md deleted file mode 100644 index c3d09f65..00000000 --- a/versioned_docs/version-0.5.4/reference/lang/spec/schema.md +++ /dev/null @@ -1,916 +0,0 @@ ---- -title: "Schema" -linkTitle: "Schema" -type: "docs" -weight: 2 -description: Schema ---- - -## Syntax - -### Schema Definition - -A schema is a language element to define a type of configuration data. - -To define a schema, the syntax is the following: - -```bnf -schema_stmt: [decorators] "schema" ["relaxed"] identifier ["[" [arguments] "]"] ["(" operand_name ")"] ":" NEWLINE [schema_body] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt | schema_index_signature | statement)* [check_block] _DEDENT -``` - -Attributes could be defined in a schema, the syntax is the following: - -```bnf -schema_attribute_stmt: [decorators] identifier ["?"] ":" type [(ASSIGN | augassign) test] NEWLINE -``` - -Index signature could be defined in a schema, the syntax is the following: - -```bnf -schema_index_signature: LEFT_BRACKETS [NAME COLON] [ELLIPSIS] basic_type RIGHT_BRACKETS COLON type [ASSIGN test] NEWLINE -``` - -Once defined, an attribute must have a valid type: - -```bnf -type: type_element ("|" type_element)* -type_element: schema_type | basic_type | list_type | dict_type -schema_type: operand_name -basic_type: "str" | "int" | "float" | "bool" -list_type: "[" (type)? "]" -dict_type: "{" (type)? COLON (type)? "}" -``` - -The followings are some basic examples: - -```python -# A person has a first name, a last name and an age. -schema person: - firstName: str - lastName: str - # fullName is generated by firstName and lastName - fullName: str = firstName + ' ' + lastName - # The default value of age is 0 - age: int = 0 - -# An employee IS a person, and has some additional information. -schema employee(person): - bankCard: int - nationality: str - -# A company has a name and many employees. -schema company: - name: str - employees: [employee] -``` - -More complex schema definitions will be elaborated after other concepts are -introduced. - -#### Optional Attribute - -Each attribute **must** be assigned with a not-None value as a schema instance unless it is modified by a question mark as an optional attribute. - -Examples: - -```bnf -schema employee(person): - bankCard?: int # bankCard is an optional attribute - nationality?: str # # nationality is an optional attribute -``` - -When there is an inheritance relationship: - -- If the attribute is optional in the base schema, it could be optional or required in the sub-schema. -- If the attribute is required in the base schema, it must be required in the sub-schema. - -### Configuration Definition - -A configuration is structured data stored in a dict-like structure. In KCL, we have introduced -the configuration definition syntax as a variant of dict definition syntax. - -```bnf -schema_expr: operand_name ("(" [arguments] ")")? dict_expr -``` - -As can be seen, apart from having an identifier as schema type, a configuration definition -is just an ordinary dict definition, and each key in the dict matches an attribute in the schema. - -To simplify configuration, schema attribute key is much easier to define as: - -- schema attribute key can be unquoted. When the attribute key has the same name as a variable, it must be quoted as a normal dict to avoid naming conflict. -- schema attribute key can be defined nested through `select expression`, such as `a.b.c`. - -The comma at the end of each line can be omitted. - -For example, we can define a `person` named `John Doe` using the following statement: - -```python -johnDoe = person { - # In the result, 'lastName' appears later than 'firstName', according the schema - lastName = 'Doe' - firstName = 'John' - # If we don't specify the 'age', the default value 0 is used. - # 'age': 20 -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' - 'age': 0 -} -``` - -Compared to the ordinary dict definition, a configuration definition has the following features: - -- Each attribute defined in the schema (or one of the schemas) could be configured, and config data has higher priority than the default value. -- When an attribute defined in the schema (or one of the schemas) is not configured in the configuration definition statement, and it has a default value, the default value is used. -- Unless the schema (or one of the schemas) is a **relaxed schema**, no more attributes can be defined. -- The quotation marks of dict key can be omitted. -- The comma at the end of each line can be omitted. -- Cases of **inheritance** will be discussed separately. - -For attributes of list, dict and schema types, the config data is added by **union** instead of reassignment. For instance: - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name = { - firstNam = "John" - lastName = "default" - } - -JohnDoe = Person { - name.lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' -} -``` - -#### Attribute Identify - -Each key identifier in the configuration expr identifies an element or a range of elements in a schema. The key identifier may consist of multiple attribute identifiers, and each attribute may be a basic type value, a list, a dict or schema. For example, the key identifier 'a.b.c' identifies the element 'c' in the 'A' schema: - -```python - -schema C: - c: int - -schema B: - b: C - -schema A: - a: B - -A { - a.b.c: 5 -} -``` - -To make the key identifier usage rules as clear as possible, we define the way of identifying with complex data types as follows. - -##### List - -Suppose we have a list attribute a. - -Identify an element in a: - -```python -a[0] # the first element -a[3] # the 4th element -a[-1] # the last element -a[-2] # the penultimate element -``` - -Identify a range of elements in the list: - -```python -a[2:5] # a slice of the third, 4th, and 5th elements -a[:5] # a slice of the first to 5th elements -``` - -#### Attribute Operator - -Once we identified the element(s), we can declare operation on it. It follows the pattern of `identifier op E`. - -#### Union - -Pattern: `identifier : E` - -The value of the expression `E` will be unioned into the element value. - -Examples: - -```python -a = A { - # union {d:4} into the element b.c, suppose c is a schema with an int type attribute d. - b.c : { - d : 4 - } -} -``` - -See 'union' in `expressions` spec for more details. - -#### Override - -Pattern: `identifier = E` - -The value of the expression `E` will override the element value. - -Examples: - -```python -a = A { - # override {c:4} to the element b, suppose b is a schema with an int type attribute c. - b = { - c: 4 - } -} -``` - -Unlike union, the override operation will reassign the element with a brand new value. -For basic type value, `union` and `override` have equivalent effects. - -Note: - -- Especially, we can "delete" its content by overriding the element to `Undefined`, such as `{ a = Undefined }`. - -#### Insert - -Pattern: `identifier += E` -Insert only works for list type `identifier`. - -List `E` will be inserted just after the specified index of the list `identifier`, and the following elements after the index will be automatically shifted. - -Examples: - -```python -a = A { - # insert {c:4} to the end position(just after index=1), suppose b is a list of schema with an int type attribute c. - b += { - c: 4 - } -} -``` - -If no index is specified, the last index will be used. - -The type of 'E' must be compatible with the type of list. See `types` for more details. - -#### Index Signature - -Index signatures can be defined in the KCL schema, and it means that the key-value constraints of the index signature can be used to construct a dict with the schema type, or additional checks can be added to the relaxed schema attributes to enhance the KCL type and semantic checks. - -- Use the form `[{attr_alias}: {key_type}]: {value_type}` to define an index signature in the schema, and `{attr_alias}` can be omitted. - -```python -schema Map: - """ - Map is a relaxed schema with a key of str type and a value of str type - """ - [str]: str # `{attr_alias}` can be omitted. - -data = Map { - key1 = "value1" - key2 = "value2" -} -``` - -- Mandatory all attributes of the schema key and value types - -```python -schema Person: - name: str - age: int # error, conflicts with the index signature definition `[str]: str` - [str]: str # The values of all attributes of the schema can only be strings -``` - -- Mandatory all attribute key and value types are defined in the schema, which is equivalent to restricting all attribute types except the relaxed attributes. - -```python -schema Person: - name: str - age: int - [...str]: str # Except for the `name` and `age` attributes, the key type of all other attributes of the schema must be `str`, and the value type must also be `str`. -``` - -- Define the index signature attribute alias and use it with the check block. - -```python -schema Data: - [dataName: str]: str - check: - dataName in ["Alice", "Bob", "John"] - -data = Data { - Alice = "10" - Bob = "12" - Jonn = "8" # error Jonn not in ["Alice", "Bob", "John"] -} -``` - -```python -import regex - -schema DataMap: - [attr: str]: str - check: - regex.match(attr, r'^[-._a-zA-Z0-9]+$') - -data = DataMap { - key1 = "value1" - "foo.bar" = "value2" # check error -} -``` - -### Schema Context - -The schema definition space can be regarded as a separate function context. - -Init statement could be defined inside the schema, the syntax is the following: - -```bnf -statement: small_stmt NEWLINE | if_stmt -``` - -The following is an example: - -```python -schema Person: - firstName: str = "John" - lastName: str - # fullName is generated by firstName and lastName in a separate init statement - fullName: str = firstName + ' ' + lastName - -JohnDoe = Person { - lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' -} -``` - -If statement, expr statement and assert statement are supported as a schema init -statement. See more in statement spec. - -- The attributes must be defined first, including inherited ones, and then used in the init statement. -- Statements in the schema context will be executed sequentially. -- The value of attributes referenced in the init statement will be evaluated at runtime. - See the **Configuration Definition** section for the assignment rules of non-referenced attributes. For example, `"fullName"` in Person is generated by `"firstName"` and `"lastName"` evaluated at runtime, in which firstName is 'John', and lastName is "Doe". - -The immutability of attributes in the schema context follows the same rules as the immutability of global variables: - -```python -schema Person: - age: int = 1 # Immutable attribute - _name: str = "Alice" # Mutable attribute - - age = 10 # Error - _name = "Bob" # Ok -``` - -#### Arguments - -Schema context can also have arguments. The following is an example. - -```python -schema Person[separator]: - firstName: str = "John" - lastName: str - fullName: str = firstName + separator + lastName - -JohnDoe = Person('_') { - lastName = "Doe" -} -``` - -The example is similar to the previous one, except that the separator character used in -the `"fullName"` member is passed in as an argument. The way to perform a schema generation -when the schema has an initialization function with arguments is demonstrated in the code. - -### Check Block - -Optionally, a check block can be added to a schema definition to allow -additional checking to be performed. - -The syntax is the following: - -```bnf -check_block: "check" ":" NEWLINE _INDENT check_expr+ _DEDENT -check_expr: test (IF test)? [":" primary_expr] NEWLINE -``` - -In terms of grammatical definition, a check block consists of a list of conditional expressions. The following is an example: - -```python -schema employee(person): - bankCard: int - gender: str - - check: - len(str(bankCard)) == 16 - gender in ['male', 'female'], "The gender {} is unsupported".format(gender) -``` - -The ability of KCL check expressions covers the abilities that can be defined by OpenAPI spec and is aligned with the ability of logical expressions. We consider further aligning the syntax with `CEL` spec. -Whether to support `lambda expressions` is still under discussion. - -Summary: - -- A check block consists of one or more logical **expressions**. -- When defining a configuration, the expressions in the check block are evaluated - in any order. If any of the expression is `False`, an error is reported. -- A custom error message can be provided after an expression. - -### Specifying Types - -Optionally, the type of any member of a schema can be specified. As previous examples have shown. - -A member can be of a basic type, such as a string (`str`), a floating-point number (`float`), a fixed-point number (`int`) or a boolean number (`bool`). - -A member can also be of a dictionary generated from another schema. In such a case, the name of the other schema is used as the type name. - -A member can also be a list or an ordinary dict: - -- A list with unspecified type of elements is `[]`. -- A list with elements of type `t` is `[t]`. Here `t` is another type. -- A dict with keys of type `kt` and values of type `vt` is `{kt:vt}`. -- `kt`, `vt` or both of them can be missing, like a list with unspecified type of elements. - -The followings are some more examples: - -- A list of lists of strings: `[[str]]`. -- A dict of keys with the type string and unspecified value types: `{str:}`. - -A member can be a **union type** defined by `|`, such as `a | b`, which means the type of the member could be a or b. - -A union type can include types of `int`, `str`, `float`, `bool`, `list` and `dict` and support type nesting e.g. `{str:str|int}` and `[[int|str]|str|float]`, etc. - -Examples: - -```python -schema x: - p: int | str # p could be defined as a int or string -``` - -### Immutability - -KCL pursues strict immutability of schema attributes. It's generally followed the rules: - -- For the attributes of the basic type, such as string, int and float, it's allowed to be reassigned - through the init statement in **schema context** or by the **configuration definition**. -- For the attributes of list, dict and schema type, it's allowed to be reassigned only by the init statement in **schema context**. The content of it is allowed to be operated in **schema context** or by the **configuration definition**. -- Any other attempt to reassign or modify schema attribute will report an error. - -#### Assign by Value - -When using a schema variable to assign the value to another variable, we can only get a deep copy of its value, not a pointer or reference. That is, modifying the assigned value will not change the assigned schema variable. - -```python -schema Person: - name: str - -person = { - name = "Alice" -} -personCopy = person # 'personCopy' is a deep copy of 'person' and modifying 'personCopy' will not affect 'person' -``` - -### Union Operator - -For list, dict and schema, we can union delta to existing data. For example: - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name = { - firstName = "John" - } - - # union a schema and a dict - name: Name { - lastName = "Doe" - } - -person = Person {} -``` - -The result is a **dict**: - -```python -{ - 'person': { - 'name': { - 'firstName': 'Jhon', - 'lastName': 'Doe' - } - } -} -``` - -### Other Operators - -Except for `assignment` and `union assignment`, it's not support other operators on schema type data. -Report an error if trying to use other operators on schema type data. - -### Deprecated - -The schema attribute can be marked as deprecated once it's considered invalid. - -```python -schema Person: - @deprecated(version="1.1.0", reason="use fullName instead", strict=True) - name: str - ... # Omitted contents - -person = Person { - # report an error on configing a deprecated attribute - name = "name" -} -``` - -- Deprecated attributes cannot be configured under any circumstances. Report an error or warning once the attribute is assigned. -- Define the expired version of the attribute through **version**, and define the reason for the attribute expired through **reason**. -- When strict is true, the attribute assignment will cause an error, otherwise it will report a warning and ignore the attribute assignment. - -### Composition - -The composition is a common way to define complex structures. KCL provides simplified means for the configuration definition of combined structures. - -Assuming we have the following schemas, which is defined by a combination of multiple schemas. - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name - age: int - -schema Group: - name: str - persons: [Person] -``` - -To config a group: - -```python -group = Group { - name = "group" - persons = [{ - name = { - firstName = "John" - lastName = "Doe" - } - age = 24 - }] -} -``` - -- Top-level schema name is required to config a schema. -- The schema of the attributes in the schema can be omitted. - -Multi-level nested schemas will make the configuration verbose. KCL supports defining attributes in the schema through `selector expression`. The selector form is **x.y.z**, see the following example: - -```python -group = Group { - name = "group" - persons = [{ - name.firstName = "John" - name.lastName = "Doe" - age = 24 - }] -} -``` - -- Selector can be used to represent attribute in a schema - -### Inheritance - -Inheritance is an effective means to define a hierarchical structure definition, and KCL supports limited **single inheritance** of the schema. - -```python -schema Person: - firstName: str - lastName: str - -# schema Scholar inherits schema Person -schema Scholar(Person): - fullName: str = firstName + '_' + lastName - subject: str - -JohnDoe = Scholar { - firstName = "John", - lastName = "Doe", - subject = "CS" -} -``` - -The result is a **dict**: - -```python -{ - 'JohnDoe': { - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' - 'subject': 'CS' - } -} -``` - -Each schema can be treated as a separated function context. Statements, including attribute statements and init statements, in the context of schemas will be evaluated from base schema to subschema according to the inheritance order. Each schema context is evaluated only once sequentially. The same goes for expressions in the check block. In the example, firstName and lastName are configured in the context of Person schema, and fullName is formed by splicing firstName and lastName in the context of Scholar schema. - -The default value can be modified in each schema. Value defined in **Configuration Definition** has a higher priority than the default value. Attributes with default values in any schema context ​​will eventually be unioned by configuration data. References to attributes in the schema context statements will use the value with unioned configuration data on evaluating at runtime. For example: - -```python -schema a: - x = 1 - y = x * 2 - -schema b(a): - x = 2 - -v = a { - x = 3 -} - -``` - -The result is a **dict**: - -```python -{ - 'v': { - 'x': 3 - 'y': 6 - } -} -``` - -Notes: - -- Report an error if inheriting more than one base schema. -- The type of the base schema attribute cannot be modified in the subschema. -- Report an error if inheriting a **mixin**. -- Report an error when a circular dependency occurs. - -Limitations: - -Since inheritance will derive some complex demands, we are cautious about these complex demands. There are still some restrictions on inheritance, and it's still under discussion. - -- KCL provides limited and deterministic polymorphism support, more complex and flexible polymorphism support, such as **self**, **super** keywords, are temporarily not included in the schema definition. -- Currently, KCL only supports the polymorphism of the inherited attributes of the schema, and does not support the polymorphism of the expressions in the check block. -- For the case of multiple levels of schema inheritance, the schema arguments can only be passed to the last level of sub-schema. - -### Mixin - -In addition to **composition** and **inheritance**, KCL supports declarative reuse of schema code through the **mixin** mechanism. To use a mixin, we only need to declare the **mixin** in the schema definition. - -The **mixin** syntax is the following: - -```bnf -//////////// mixin_stmt //////////// -mixin_stmt: "mixin" "[" [mixins | multiline_mixins] "]" "\n" -multiline_mixins: "\n" _INDENT mixins "\n" _DEDENT -mixins: operand_name ("," ("\n" mixins | operand_name))* -``` - -Here is a simple example: - -```python -schema Person: - mixin [FullNameMixin] - firstName: str = "default" - lastName: str - -schema FullNameMixin: - fullName: str = "{} {}".format(firstName, lastName) - -JohnDoe = Person { - firstName = "John" - lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'JohnDoe': { - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' - } -} -``` - -Multiple mixins can be added to a single schema, and mixins context will be evaluated after the host schema context at runtime. In the inheritance scenario, the mixin context can be regarded as a part of the host schema context, and the overall evaluation of schema context order is not affected. - -Notes: - -- The name of **mixin** schema must end with 'Mixin', otherwise an error will be reported. -- The attributes referenced in the **mixin** must be defined in the **mixin** itself or host schema, otherwise an error will be reported. - -### Protocol - -In addition to schema, an additional type definition method `protocol` is provided in KCL, and its properties are as follows: - -- In a protocol, only attributes and their types can be defined, complex logic and check expressions cannot be written, and mixins cannot be used. -- A protocol can only inherit or refer to other protocols, but cannot inherit or refer to other schemas. - -We can use **protocol** to add an optional host type to the dynamically inserted **mixin**. - -The **mixin** can define its host type through the `for` keyword, and internally it will query the type corresponding to the attribute from the host type. - -```python -protocol DataProtocol: # A mixin host type - data: str - -mixin DataMixin for DataProtocol: # Using the `for` keyword to define a mixin host type - x: int = data # The type of `data` is `str`, which is from `data` of `DataProtocol` -``` - -In `DataMixin`, the `data` attribute is obtained according to the `DataProtocol` host type as `str` type, and then a type error will occur when the value is assigned to `x` of type `int`: - -```python -protocol DataProtocol: - data: str - -mixin DataMixin for DataProtocol: - x: int = data # Error: expect int, got str - x: str = data # Error: can't change schema field type of 'x' from int to str -``` - -Please note that the host type **protocol** can only be used for **mixin** definitions (the suffix name is `Mixin`), otherwise an error will be reported. - -```python -protocol DataProtocol: - data: str - -schema Data for DataProtocol: # Error: only schema mixin can inherit from protocol - x: str = data -``` - -### Schema Context Evaluation - -The schema definition is composed of attribute statements, configuration data, init statements, mixins, and checks. In a separate schema context, the evaluation top-down order is as follows: - -``` -|------------------------------------------| -| attribute defaulting | -|------------------------------------------| -| configuration union | -|------------------------------------------| -| attribute templating | -|------------------------------------------| -| statements in declaration order | -|------------------------------------------| -| mixins in declaration order | -|------------------------------------------| -| check expressions in any order | -|------------------------------------------| -``` - -In the case of schema inheritance, each schema context is evaluated from the base schema in the order of inheritance, and each context is evaluated only once. -Suppose there are schemas a, b, and c, where c inherits b and b inherits a. Schema contexts will be evaluated in top-down order as: - -``` -|-----------------| -| schema a | -|-----------------| -| schema b | -|-----------------| -| schema c | -|-----------------| -``` - -### Members - -Built-in function and members of schema - -- instances() - Return the list of existing instances of a schema. - -### Irrelevant Order Calculation - -The irrelevant order calculation in the schema indicates the reference relationship between the internal attributes of the schema. For example, when we declare an expression of the form `a = b + 1`, the calculation of the value of `a` depends on the calculation of the value of `b`. When the compiler calculate the value of `a` and the value of `a` depends on the value of `b`, the compiler will choose to first calculate the value of `b`, and then calculate the value of a according to the expression `a = b + 1`, which is slightly different from the calculation method of traditional procedural language the difference. - -Since the calculation of values in the schema is based on dependencies, just like a directed acyclic graph traverses each node in the graph according to the order of topological sorting, the order of declaration of attributes in the schema is not so important, so the feature is called the irrelevant order calculation. - -Please note that there can be no circular references between different schema attribute values. - -We can see this feature through the following examples. - -```python -schema Person: - name?: str - age: int = _age - - _age = 10 - - if name == "Son": - _age = 18 - -schema Son(Person): - name: str = "Son" - -person = Person {} -son = Son {} -``` - -The output is - -```yaml -person: - name: null - age: 10 -son: - name: Son - age: 18 -``` - -Besides, we can achieve KCL polymorphism such as - -```python -schema Person: - name?: str - _age: int = _age - - _age = 10 - if name == "Son": - _age = 18 - elif name == "SonConf": - _age = 24 - -schema Son(Person): - name: str = "Son" - -person = Person() {} -son = Son() { - name = "SonConf" -} -``` - -The output is - -```yaml -person: - name: null - age: 10 -son: - name: SonConf - age: 24 -``` - -More examples: - -```python -schema Fib: - n1: int = n - 1 - n2: int = n1 - 1 - n: int - value: int = _value - - if n <= 2: - _value = 1 - else: - _value = (Fib {n = n1}).value + (Fib {n = n2}).value - -fib8 = (Fib {n = 8}).value -``` - -The output is - -```yaml -fib8: 21 -``` - -As in the above examples, we can see that in the schema, we only need to simply specify the dependency between attributes, and the compiler will automatically calculate the value based on the dependency, which can help us save a lot of boilerplate code and reduce configuration difficulty of writing. diff --git a/versioned_docs/version-0.5.4/reference/lang/spec/statements.md b/versioned_docs/version-0.5.4/reference/lang/spec/statements.md deleted file mode 100644 index b09488b9..00000000 --- a/versioned_docs/version-0.5.4/reference/lang/spec/statements.md +++ /dev/null @@ -1,185 +0,0 @@ ---- -title: "Statements" -linkTitle: "Statements" -type: "docs" -weight: 2 -description: Statements ---- - -## Syntax - -In KCL, statements consist of small statements and compound statements. The syntax is the following: - -```bnf -preamble_statement: preamble_small_stmt | preamble_compound_stmt -preamble_small_stmt: (small_stmt | import_stmt) NEWLINE -preamble_compound_stmt: compound_stmt | schema_stmt -statement: small_stmt NEWLINE | compound_stmt -compound_stmt: if_stmt -small_stmt: assign_stmt | expr_stmt | assert_stmt -``` - -The preamble statement is used to define the module level statements, consist of `statement`, `import_stmt`, and `schema_stmt`. The statement is used to define the block level statements, which are used in the `if` statement and `schema` statement. - -### Small Statements - -A small statement is comprised of a single logical line. Multiple statements in one-line are not allowed. - -#### Assignment Statements - -Generally, assign_stmt is divided into assignment and augmented assignment. The syntax is the following: - -```bnf -assign_stmt: target_primary ("=" target_primary)* "=" test | target_primary augassign test -augassign: "+=" | "-=" | "*=" | "**=" | "/=" | "//=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>=" | "or" | "and" -target_primary: identifier | target_primary DOT identifier -``` - -An assignment statement has the form `lhs = rhs`. It evaluates the expression on the right-hand side then assigns its value (or values) to the variable (or variables) on the left-hand side. - -The **target_primary** on the left-hand side is an `identifier` or an `identifier` followed by select dots. - -Note: When using **target_primary** will cause collisions, use **primary_expr** as an alternative. - -Examples: - -```python -k = 1 -a.b = "a.b" -``` - -To keep it simple, the compound target is not supported as **target_primary**. - -The right value of an assignment statement is a conditional expression, which is discussed separately. - -An augmented assignment, which has the form `lhs op= rhs` updates the variable `lhs` by applying a binary arithmetic operator op (one of +, -, \*, /, //, %, &, |, ^, <<, >>) to the previous value of `lhs` and the value of `rhs`. - -The **target_primary** on the left-hand side is the same as assignment statement. Examples: - -```python -_x -= 1 -_filename += ".k" -``` - -There is no concept of in-place modification in KCL. The `augassign` statement will modify a copy of the **target_primary** and assign the copy to **target_primary**. - -In particular, in KCL, the `|=` symbol represents the **union** operation, which is defined as follows: - -- The behavior of the **union** operation needs to be consistent with the behavior of the **configuration definition**. - -See **expressions** spec for more details of union operator in **Arithmetic Operations**. - -#### Expression Statements - -An expression statement evaluates an expression and discards its result. - -Syntax: - -```bnf -expr_stmt: expression -``` - -An expression statement supported in KCL is function invocation expression, which is discussed in **expression** spec. - -```python -print(k) # print a variable -``` - -#### Import Statements - -Import statements are used to **search** and **load** a module, and define a name or names in the local namespace for the scope where the import statement occurs. - -Syntax: - -```bnf -import_stmt: "import" dot_name ("as" NAME)? -dot_name: [leading_dots] identifier (DOT identifier)* -leading_dots: "."+ -``` - -Examples: - -```python -import math # import a built-in module math -import pkg # import pkg -import pkg.foo # import pkg.foo -import pkg.subpkg # import a subpkg in a pkg -import .pkg2.subpkg3 # import a subpkg in a pkg inside of current pkg -import ...pkg2 # Go two levels up then import pkg2 -``` - -See **module** spec for more details of module spec. - -#### Assert Statements - -Assert statements are a convenient way to insert debugging assertions into KCL code. - -The syntax is the following: - -``` -assert_stmt: ASSERT test ("," test)? -``` - -The conditional expression in assert will be evaluated and get a boolean. Report an error if returning a `False`. - -Examples: - -```python -assert: x > 1 # report an error on x <= 1 -``` - -#### Conditional Statements - -KCL allows using conditional statements to control the instructions to -be executed. They are also called the control-flow statements. - -The only type of control-flow syntax is the well-known `if-elif-else` syntax. - -The syntax of the `if-elif-else` statement is the following. - -```bnf -if_stmt: "if" test ":" suite ("elif" test ":" suite)* (ELSE ":" suite)? -suite: small_stmt | NEWLINE _INDENT statement+ _DEDENT -``` - -An `if` or `elif` statement evaluates a given expression. When the expression -is evaluated to `True`, a list of statements following `:` are executed. - -The following is an example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - print("maybe a is negative") -else: - print("a >= 100") -``` - -`if-elif-else` statements can be nested. For example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - if a < 0: - print("a is negative") - print("No matter a is negative or positive, this message is printed") -else: - print("a >= 100") -``` - -#### Schema Statements - -Schema statements are used to define a type of configuration data. The syntax is the following: - -```bnf -schema_stmt: [decorators] "schema" ["relaxed"] identifier ["[" [arguments] "]"] ["(" operand_name ")"] ":" NEWLINE [schema_body] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt | statement)* [check_block] _DEDENT -``` - -See **schema** spec for more details of schema spec. diff --git a/versioned_docs/version-0.5.4/reference/lang/spec/variables.md b/versioned_docs/version-0.5.4/reference/lang/spec/variables.md deleted file mode 100644 index b3e1c539..00000000 --- a/versioned_docs/version-0.5.4/reference/lang/spec/variables.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: "Variables" -linkTitle: "Variable" -type: "docs" -weight: 2 -description: Variable ---- - -In KCL, variables can be defined using assign statements. For example, the following statement defines a variable `spam` to a string `"ham"`. - -```python -spam = "ham" -``` - -There are two types of variables, which are global variables and list comprehension local variables. - -- A global variable is defined not within any context. -- A comprehension local variable is defined inside a comprehension. - -A variable can be used after definition, until the end of the current scope. - -For a global variable, the scope is the module it is defined in. Note that a module can consists of multiple source files. - -For a list comprehension local variable, the scope is the list comprehension it is defined in. - -More information on modules, list comprehensions and scopes will be discussed in later chapters. - -## Immutability - -Global variables are immutable. In other words, once defined such a variable cannot be redefined (or, i.e., modified). - -The following code is illegal, and KCL will report an error during evaluation. - -```python -spam = "ham" -spam = "eggs" # Error: The immutability rule is violated! -``` - -- A variable starts with the `_` character is mutable. - -```python -_spam -cond = True -if cond: - _spam = "ham" -else: - _spam = "eggs" -``` - -## Variable Exporting - -As shown in the preview chapter, KCL is able to export evaluation results to the standard output according to a target data format. - -The rules are the followings: - -- Living global variables at the end of an evaluation will be dumped out. -- If the name of a variable starts with the `_` character, it will not be dumped out. - -## Uniqueness of Exported Variable Identifier - -Each exported variable identifier must be unique in its package, so that an exported variable could be located uniquely by package location path and variable identifier, such as 'a.b.c:var', in which 'a.b.c' locates a package. - -Two variable identifiers are different if: - -- they are spelled differently -- they are defined in different packages and are not compiled in a single execution - -Identifying an exported variable should be supported by the kcl compiler, which needs to provide corresponding identifying features through the command line and api form. diff --git a/versioned_docs/version-0.5.4/reference/lang/tour.md b/versioned_docs/version-0.5.4/reference/lang/tour.md deleted file mode 100644 index f7acf49c..00000000 --- a/versioned_docs/version-0.5.4/reference/lang/tour.md +++ /dev/null @@ -1,3324 +0,0 @@ ---- -title: "KCL Tour" -sidebar_position: 1 ---- - -This page shows how to use major KCL features, from variables and operators to schemas and libraries, with the assumption that you have already known how to program in another language. KCL is mainly inspired by Python, and knowing Python is very helpful for learning KCL. - -### Important Concepts - -As we learn about the KCL language, keep these facts and concepts in mind: - -- KCL is a configuration and policy language. It provides simplified and self-contained language design and library support for writing configurations and policies. It cannot be used for application development or other purposes supported by General Purpose Language (GPL). -- KCL absorbs classic **OOP** elements and provides simple, developer-friendly and reliable configuration writing practice with **type**, **reusing**, and **union**. -- KCL prefers **immutability** and recommend to add up incremental updates through the **union**. Immutability reduces side effects like unpredictable issues. -- KCL **schema** struct defines strict attributes, static types, and it also supports validation expressions. The **schema** struct is mainly composed of typed attributes, the schema context and the check block. -- KCL **config** is a **json**-like expression, by which we can reuse a full definition of the schema. KCL provides support for definition and configuration by separating schema and config. -- KCL **rule** is a structure for writing rule constraint expressions, which can be used for data verification and policy writing. -- KCL code files are managed as packages(directories) and modules(files). The schema types in the same package are visible to each other; the data cross packages need to be imported through the **import statement**. The package-level variables can be exported, but they are immutable for other packages. -- The KCL syntax definition mainly uses declarative expressions, and only provides a small number of necessary and imperative statements, such as import, if .. else, assert, assignment and schema. -- No main function, each `.k` file could be executed as a separate configuration. -- **Built-in functions** and **plugins** are supported to simplify coding. - -### Keywords - -The following table lists the words that the KCL language treats specially. - -```txt -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -### Identifiers - -In KCL, an identifier is a name, may with selectors, that identifies a value. - -- Identifiers consist of letters, numbers, underscores or the prefix `$`. -- Identifiers cannot be repeated with keywords unless they have a `$` prefix. -- Identifiers must not contain any embedded spaces or symbols. -- Letters and underscores can be used anywhere in the identifier. -- Numbers cannot be placed in the first place of the identifier. -- The `$` character can only be placed in the first position of the identifier. - -Examples: - -```python -x -a -b1 -b_2 -_c -$if -``` - -To simplify the definition of the qualified identifier, such as `pkg.type`, we additionally define `qualified identifier`: - -Examples: - -```python -pkg.a -``` - -The package name in `qualified identifier` must be imported. - -#### Identifier Prefix - -Use the `$` character prefix to define keyword identifiers. - -```python -$if = 1 -$else = "s" -``` - -Please note: whether the non-keyword identifier is prefixed with `$` has the same effect. - -```python -_a = 1 -$_a = 2 # equal to `_a = 2` -``` - -### Variables - -Here’s an example of how to create a variable and initialize it: - -```python -name = "Foo" # Declare a variable named `name` and its value is a string literal "Foo" -``` - -It corresponds to the following YAML output: - -```yaml -name: Foo -``` - -In KCL, we can export variables as config data by defining package-level variables. To make it direct, clear, and maintainable. Exported variables are immutable so that once we declare it, we can't modify it. For example, assume we have a config file named `example.k`, the variable `name` can't be modified after the declaration, just like the standard imperative language. - -```python -name = "Foo" # exported - -... - -name = "Bar" # error: a exported declaration variable can only be set once. -``` - -As a complement, we can define a non-exported variable in module level which is mutable, which won't show up in YAML output: - -```python -_name = "Foo" # _ variables are not output to YAML and are mutable -_name = "Bar" -``` - -Please note that the variable name cannot be one of `True`, `False`, `None`, `Undefined` because of ambiguity. - -```python -False = 1 # Error -True = False # Error -None = Undefined # Error -Undefined = None # Error -``` - -### Built-in Types - -The KCL language has special support for the following types: - -- number -- string -- boolean -- list -- dict - -#### Number - -KCL number comes into two flavors: - -- **Int**: 64 bits signed integer values. Values can be from -9223372036854775808~9223372036854775807. -- **Float**: 64-bit floating-point numbers, as specified by the IEEE 754 standard. We do not recommend using the float type in the configuration, we can use a string instead and parse it during runtime processing. - -Both int and float support basic operators such as `+`, `-`, `/`, and `*`, while complex operations, such as `abs()`, `ceil()`, and `floor()`, are supported through the built-in math library. - -Integers are numbers without a decimal point. Here are some examples of defining integer literals: - -```python -a = 1 -b = -1 -c = 0x10 # hexadecimal literal -d = 0o10 # octal literal -e = 010 # octal literal -f = 0b10 # binary literal -g = int("10") # int constructor -``` - -If a number includes a decimal point, it is a float number. Here are some examples of defining float literals: - -```python -a = 1.10 -b = 1.0 -c = -35.59 -d = 32.3e+18 -f = -90. -h = 70.2E-12 -i = float("112") # float constructor -``` - -Built-in math libraries can be used with numbers: - -```python -import math - -assert abs(-40) == 40 -assert round(70.23456) == 70 -assert min(80, 100, 1000) == 80 -assert max(80, 100, 1000) == 1000 -assert sum([0,1,2]) == 3 -assert math.ceil(100.12) == 101.0 -assert math.floor(100.12) == 100.0 -assert math.pow(100, 2) == 10000.0 -``` - -In addition, please note that the KCL number is 64-bit by default. We can perform a stricter 32-bit range check by adding the `-r` parameter to the KCL command-line tool. - -```bash -kcl main.k -r -d -``` - -Please note that the value range check is only enabled in `debug` mode - -##### Units - -In KCL, we can add a unit suffix to an integer denomination to indicate that it does not affect its true value as follows. - -- General integer or fixed-point number form: `P`, `T`, `G`, `M`, `K`, `k`, `m`, `u`, `n` -- Corresponding power of 2: `Pi`, `Ti`, `Gi`, `Mi`, `Ki` - -```python -# SI -n = 1n # 1e-09 -u = 1u # 1e-06 -m = 1m # 1e-03 -k = 1k # 1000 -K = 1K # 1000 -M = 1M # 1000000 -G = 1G # 1000000000 -T = 1T # 100000000000 -P = 1P # 1000000000000000 -# IEC -Ki = 1Ki # 1024 -Mi = 1Mi # 1024 ** 2 -Gi = 1Gi # 1024 ** 3 -Ti = 1Ti # 1024 ** 4 -Pi = 1Pi # 1024 ** 5 -``` - -Besides, And we can also use the unit constants defined in the `units` module as follows: - -```python -import units - -n = 1 * units.n # 1e-09 -u = 1 * units.u # 1e-06 -m = 1 * units.m # 1e-03 -k = 1 * units.k # 1000 -K = 1 * units.K # 1000 -M = 1 * units.M # 1000000 -G = 1 * units.G # 1000000000 -T = 1 * units.T # 1000000000000 -P = 1 * units.P # 1000000000000000 -# IEC -Ki = 1 * units.Ki # 1024 -Mi = 1 * units.Mi # 1024 ** 2 -Gi = 1 * units.Gi # 1024 ** 3 -Ti = 1 * units.Ti # 1024 ** 4 -Pi = 1 * units.Pi # 1024 ** 5 -``` - -We can also use the methods in the `units` module to convert between integers and unit strings. - -```python -import units -# SI -K = units.to_K(1000) # "1K" -M = units.to_M(1000000) # "1M" -G = units.to_G(1000000000) # "1G" -T = units.to_T(1000000000000) # "1T" -P = units.to_P(1000000000000000) # "1P" -# IEC -Ki = units.to_Ki(1024) # "1Ki" -Mi = units.to_Mi(1024 ** 2) # "1Mi" -Gi = units.to_Gi(1024 ** 3) # "1Gi" -Ti = units.to_Ti(1024 ** 4) # "1Ti" -Pi = units.to_Pi(1024 ** 5) # "1Pi" -``` - -```python -import units -# SI -K = units.to_K(int("1M")) # "1000K" -M = units.to_M(int("1G")) # "1000M" -G = units.to_G(int("1T")) # "1000G" -T = units.to_T(int("1P")) # "1000T" -P = units.to_P(int("10P")) # "10P" -# IEC -Ki = units.to_Ki(int("1Mi")) # "1024Ki" -Mi = units.to_Mi(int("1Gi")) # "1024Mi" -Gi = units.to_Gi(int("1Ti")) # "1024Gi" -Ti = units.to_Ti(int("1Pi")) # "1024Ti" -Pi = units.to_Pi(int("10Pi")) # "10Pi" -``` - -The unit value type is defined in the units module, and the unit value type does not allow any four calculations. - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -x0: NumberMultiplier = 1M # Ok -x1: NumberMultiplier = x0 # Ok -x2 = x0 + x1 # Error: unsupported operand type(s) for +: 'number_multiplier(1M)' and 'number_multiplier(1M)' -``` - -We can use the `int()`, `float()` function and `str()` function to convert the numeric unit type to the normal integer type and string type. - -```python -a: int = int(1Ki) # 1024 -b: float = float(1Ki) # 1024.0 -c: str = str(1Mi) # "1Mi" -``` - -#### String - -The string is an immutable sequence of Unicode characters. We can use either single or double quotes to create a string: - -```python -'allows embedded "double" quotes' # Single quotes -"allows embedded 'single' quotes" # Double quotes -'''Three single quotes''', """Three double quotes""" # Triple quoted -``` - -Triple quoted strings may span multiple lines. - -```python -"""This is a long triple quoted string -may span multiple lines. -""" -``` - -Please note that there is almost no difference in the use of KCL single-quoted and double-quoted strings. The only thing that can be simplified is that we don’t need to escape double quotes in single quoted strings, and we don’t need to escape single quotes in double quoted strings. - -```python -'This is my book named "foo"' # Don’t need to escape double quotes in single quoted strings. -"This is my book named 'foo'" # Don’t need to escape single quotes in double quoted strings. -``` - -We can concatenate strings using the `+` operator: - -```python -x = 'The + operator ' + 'works, as well.' -``` - -We can cast an int or float to a string using the built-in function `str`: - -```python -x = str(3.5) # "3.5" -``` - -A lot of handy built-in functions and members of a string could be used: - -```python -x = "length" -assert len(x) == 6 # True -assert x.capitalize() == "Length" -assert x.count("gt") == 1 -assert x.endswith("th") == True -assert x.find("gth") == 3 -assert "{} {}".format("hello", "world") == 'hello world' -assert x.index("gth") == 3 -assert x.isalnum() == True -assert x.isalpha() == True -assert "123456".isdigit() == True -assert x.islower() == True -assert " ".isspace() == True -assert "This Is Title Example".istitle() == True -assert x.isupper() == False -assert "|".join(["a", "b", "c"]) == "a|b|c" -assert "LENGTH".lower() == "length" -assert ' spacious '.lstrip() == 'spacious ' -assert x.replace("th", "ht") == "lenght" -assert "lengthlength".rfind("le") == 6 -assert "lengthlength".rindex("le") == 6 -assert "length length".rsplit() == ["length", "length"] -assert "length ".rstrip() == "length" -assert "length length".split() == ["length", "length"] -assert 'ab c\n\nde fg\rkl\r\n'.splitlines() == ['ab c', '', 'de fg', 'kl'] -assert "length".startswith('len') == True -assert "***length***".strip('*') == "length" -assert "length length".title() == "Length Length" -assert x.upper() == "LENGTH" -``` - -There are 2 different ways to format a string: to use the `"{}".format()` built-in function, or to specify the variable between the curly braces and use a `$` mark to tell KCL to extract its value. This is called **string interpolation** in KCL. In following example, both `a` and `b` will be assigned to string `"hello world"`. - -Besides, the variable to serialized can be extracted in special data format, such as YAML or JSON. In this case, a `#yaml` or `#json` can be included within the curly braces. - -Specifically, when the dollar sign `$` itself is needed in a **string interpolation**, it needs to be escaped and use `$$` instead. Or in another way, `+` can be used to concat the dollar sign with the **string interpolation** to avoid that escape. In following example, both `c` and `c2` will be assigned to string `$hello world$` - -```python -world = "world" -a = "hello {}".format(world) # "hello world" -b = "hello ${world}" # "hello world" -c = "$$hello ${world}$$" # "$hello world$" -c2 = "$" + "hello ${world}" + "$" # "$hello world$" - -myDict = { - "key1" = "value1" - "key2" = "value2" -} - -d = "here is myDict in json: ${myDict: #json}" -# d: 'here is myDict in json: {"key1": "value1", "key2": "value2"}' - -e = "here is myDict in yaml:\n${myDict: #yaml}" -# e: | -# here is myDict in yaml: -# key1: value1 -# key2: value2 -``` - -Besides, we can see some symbols in the example code output **YAML string** above such as `|`, `>`, `+`, `-`. - -- `|` denotes the **block literal style** that indicates how newlines inside the block should behave. -- `>` denotes the **block folded style** in the block scalar that the newlines will be replaced by spaces. -- `+` and `-` are the **block chomping indicators** that control what should happen with newlines at the end of the string. The default value **clip** puts a single newline at the end of the string. To remove all newlines, **strip** them by putting a `-` after the style indicators `|` or `>`. Both clip and strip ignore how many newlines are actually at the end of the block; to **keep** them all put a `+` after the style indicator. - -For example, a **strip block literal style** yaml string is - -```yaml -example: |- - Several lines of text, - with some "quotes" of various 'types', - and also a blank line: - - plus another line at the end. -``` - -The result is - -```plain -Several lines of text, -with some "quotes" of various 'types', -and also a blank line: - -plus another line at the end. -``` - -See [Yaml Multiline String](https://yaml-multiline.info/) and [YAML Specification v1.2](https://yaml.org/spec/1.2.1/) for more information. - -##### Raw String - -KCL raw string is created by prefixing a string literal with `'r'` or `'R'`. KCL raw string treats backslash (`\`) and string interpolation (`${}`) as a literal character. This is useful when we want to have a string that contains backslash, string interpolation and don’t want them to be treated as an escape character. - -- For backslash (`\`), the KCL code and output YAML are as follows: - -```python -s = "Hi\nHello" -raw_s = r"Hi\nHello" # This is a KCL raw string with the `r` prefix. -``` - -```yaml -s: |- - Hi - Hello -raw_s: Hi\nHello -``` - -- For string interpolation (`${}`), the KCL code and output YAML are as follows: - -```python -worldString = "world" -s = "Hello ${worldString}" -raw_s = r"Hello ${worldString}" # This is a KCL raw string with the `r` prefix. -``` - -```yaml -worldString: world -s: Hello world -raw_s: Hello ${worldString} -``` - -In addition, the most common scenario for raw strings is to be used with regular expressions: - -```python -import regex - -key = "key" -result = regex.match(key, r"[A-Za-z0-9_.-]*") # True -``` - -#### Boolean - -Boolean values are the two constant objects `False` and `True`. - -```python -a = True -b = False -``` - -#### List - -The list is a sequence, typically used to store collections of homogeneous items. Here’s a simple KCL list: - -```python -list = [1, 2, 3] -assert len(list) == 3 # True -assert list[0] == 1 # True -``` - -We can declare a list with list comprehension: - -```python -list = [ _x for _x in range(20) if _x % 2 == 0] -assert list == [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] # True -``` - -We can perform nested list comprehension: - -```python -matrix = [[1, 2], [3,4], [5,6], [7,8]] -transpose = [[row[_i] for row in matrix] for _i in range(2)] -assert transpose == [[1, 3, 5, 7], [2, 4, 6, 8]] # True -``` - -Besides, we can use two variables in the list comprehension, the first variable denotes the list index and the second variable denotes the list item. - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use `_` to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -We can merge list like this: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -joined_list = _list0 + _list1 # [1, 2, 3, 4, 5, 6] -``` - -We can also use the list unpacking operator `*` to merge multiple lists: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -union_list = [*_list0, *_list1] # [1, 2, 3, 4, 5, 6] -``` - -We can use `if expressions` to dynamically add elements to the list element, elements that meet the conditions are added to the list, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = [ - 1 - if a == 1: 2 - if a > 0: 3 - if a < 0: 4 -] # [1, 2, 3] -``` - -```python -a = 1 # 1 -data1 = [ - 1 - if a == 1: - 2 - elif a == 2: - 3 - else: - 3 -] # [1, 2] -data2 = [ - 1 - if a == 1: 2 - elif a == 2: 2 - else: 3 -] # [1, 2] -``` - -Please note that in the above `if expressions`, nested use is not supported. - -We can union two lists like this: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -union_list = _list0 | _list1 # [4, 5, 6] -``` - -We can use the expression `for k in list_var` to traverse a list. - -```python -data = [1, 2, 3] -dataAnother = [val * 2 for val in data] # [2, 4, 6] -``` - -#### Dict - -Dict is a mapping object that maps hashable values to arbitrary objects. Dict is ordered. The order of the keys follows the order of their declaration. - -Here are a couple of simple KCL dict, created using dict literals: - -```python -a = {"one" = 1, "two" = 2, "three" = 3} -b = {'one' = 1, 'two' = 2, 'three' = 3} -assert a == b # True -assert len(a) == 3 # True -``` - -We can ignore the comma `,` at the end of the line for writing dict key-value pairs in multiple lines: - -```python -data = { - "key1" = "value1" # Ignore the comma ',' at the end of line - "key2" = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -We can ignore the key quotation marks when we writing simple literals on the key. - -```python -data = { - key1 = "value1" # Ignore key quotation '"' - key2 = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -In addition, the **config selector expressions** can be used to init a dict instance with nested keys. - -```python -person = { - base.count = 2 - base.value = "value" - labels.key = "value" -} # {"base": {"count": 2, "value": "value"}, "labels": {"key": "value"}} -``` - -The output YAML is - -```yaml -person: - base: - count: 2 - value: value - labels: - key: value -``` - -In KCL, different fields in dict can be referenced, such as the following example. - -```python -config = { - name = "me" - metadata.name = name # Reference `name` with the value `"me"` in `config` directly. -} -``` - -The output YAML is - -```yaml -config: - name: me - metadata: - name: me -``` - -We can declare a dict with dict comprehension: - -```python -x = {str(i): 2 * i for i in range(3)} -assert x == {"0" = 0, "1" = 2, "2" = 4} -``` - -Besides, we can use two variables in the dict comprehension, the first variable denotes the dict key and the second variable denotes the dict value of the key. - -```python -data = {key1 = "value1", key2 = "value2"} -# Single variable loop -dataKeys1 = {k: k for k in data} # {"key1": "key1", "key2": "key2"} -dataValues1 = {k: data[k] for k in data} # {"key1": "value1", "key2": "value2"} -# Double variable loop -dataKeys2 = {k: k for k, v in data} # {"key1": "key1", "key2": "key2"} -dataValues2 = {v: v for k, v in data} # {"value1": "value1", "value2": "value2"} -dataFilter = {k: v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use `_` to ignore loop variables -dataKeys3 = {k: k for k, _ in data} # {"key1": "key1", "key2": "key2"} -dataValues3 = {v: v for _, v in data} # {"value1": "value1", "value2": "value2"} -``` - -We can **merge** dict using the dict unpacking operator `**` like this: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = {**_part1, **_part2} # {"a: "b", "c": "d"} -``` - -In addition, the same effect can be achieved by using the union operator `|`: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = _part1 | _part2 # {"a: "b", "c": "d"} -``` - -We can use `if expressions` to dynamically add elements to the dict element, elements that meet the conditions are added to the dict, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = { - key1 = "value1" - if a == 1: key2 = "value2" - if a > 0: key3 = "value3" - if a < 0: key4 = "value4" -} # {"key1": "value1", "key2": "value2", "key3": "value3"} -``` - -```python -a = 1 # 1 -data1 = { - key1 = "value1" - if a == 1: - key2 = "value2" - elif a > 0: - key3 = "value3" - else: - key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -data2 = { - key1 = "value1" - if a == 1: key2 = "value2" - elif a > 0: key3 = "value3" - else: key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -``` - -We can use the expression `for k in dict_var` to traverse a dict, and we can use the `in` operator to determine whether a dict contains a certain key - -```python -data = {key1 = "value1", key2 = "value2"} -dataAnother = {k: data[k] + "suffix" for k in data} # {"key1": "value1suffix", "key2": "value2suffix"} -containsKey1 = "key1" in data # True -containsKey2 = "key" in data # False -``` - -#### None - -In KCL, `None` can indicate that the value of the object is empty, which is similar to `nil` in Go or `null` in Java, and corresponds to `null` in YAML. - -```python -a = None -b = [1, 2, None] -c = {key1 = value1, key2 = None} -``` - -The output is as follows: - -```yaml -a: null -b: - - 1 - - 2 - - null -c: - key1: value1 - key2: null -``` - -Please note that `None` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + None # error -b = int(None) # error -c = not None # True -d = None == None # True -e = None or 1 # 1 -f = str(None) # None -``` - -#### Undefined - -`Undefined` is similar to `None`, but its semantics is that a variable is not assigned any value and will not be output to YAML - -```python -a = Undefined -b = [1, 2, Undefined] -c = {key1 = "value1", key2 = Undefined} -``` - -The output is as follows: - -```yaml -b: - - 1 - - 2 -c: - key1: value1 -``` - -Please note that `Undefined` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + Undefined # error -b = int(Undefined) # error -c = not Undefined # True -d = Undefined == Undefined # True -e = Undefined or 1 # 1 -f = str(Undefined) # Undefined -``` - -### Operators - -The following character sequences represent operators: - -```txt -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != @ \ -``` - -#### Arithmetic Operators - -KCL supports the common arithmetic operators: - -```python -assert 2 + 3 == 5 -assert 2 - 3 == -1 -assert 2 * 3 == 6 -assert 5 / 2 == 2.5 -assert 5 // 2 == 2 -assert 5 % 2 == 1 -``` - -#### Equality and Relational Operators - -KCL supports the meanings of equality and relational operators: - -```python -assert 2 == 2 -assert 2 != 3 -assert 3 > 2 -assert 2 < 3 -assert 3 >= 3 -assert 2 <= 3 -``` - -#### Logical Operators - -We can invert or combine boolean expressions using the logical operators e.g., `and` and `or`: - -```python -if not done and (col == 0 or col == 3): - # ...Do something... - -``` - -#### Bitwise and Shift Operators - -Here are examples of using bitwise and shift operators: - -```python -value = 0x22 -bitmask = 0x0f - -assert (value & bitmask) == 0x02 -assert (value & ~bitmask) == 0x20 -assert (value | bitmask) == 0x2f -assert (value ^ bitmask) == 0x2d -assert (value << 4) == 0x220 -assert (value >> 4) == 0x02 -``` - -The `|` operator likewise computes bitwise, unions basic types and unions collection and schema data, such as **list**, **dict** and **schema**. - -Computing bitwise examples: - -```python -0x12345678 | 0xFF # 0x123456FF -``` - -Unioning basic types examples: - -```python -schema x: - a: int | str # attribute a could be a int or string -``` - -#### Assignment Operators - -The following tokens serve as delimiters in the grammar: - -```bash - ( ) [ ] { } - , : . ; = -> - += -= *= /= //= %= - &= ^= >>= <<= **= -``` - -The following examples use assignment and argument assignment operators: - -```python -_a = 2 -_a *= 3 -_a += 1 -assert _a == 7 -``` - -#### Identity Operators - -The following keywords serve as identity operators in the grammar: - -```python -is, is not -``` - -The identity operators check whether the right hand side and the left hand side are the very same object. They are usually used to check if some variable is `None/Undefined/True/False`. Here are some examples: - -```python -empty_String = "" -empty_String is not None # True -``` - -#### Membership Operators - -The following keywords serve as membership operators in the grammar: - -```python -in, not in -``` - -- The `in` operator reports whether its first operand is a member of its second operand, which must be a list, dict, schema, or string. -- The `not in` operator is its negation. Both return a Boolean. - -The meaning of membership varies by the type of the second operand: the members of a list are its elements; the members of a dict are its keys; the members of a string are all its substrings. - -```python -1 in [1, 2, 3] # True - -d = {one = 1, two = 2} -"one" in d # True -"three" in d # False -1 in d # False -[] in d # False - -"nasty" in "dynasty" # True -"a" in "banana" # True -"f" not in "way" # True - -d = Data {one = 1, two = 2} # Data is a schema with attributes one and two -"one" in d # True -"three" in d # False -``` - -#### Comprehension - -A comprehension constructs a new list or dictionary value by looping over one or more iterables and evaluating a body expression that produces successive elements of the result. - -We can declare list and dict by comprehension as: - -```python -listVar = [_x for _x in range(20) if _x % 2 == 0] # list comprehension -dictVar = {str(_i): 2 * _i for _i in range(3)} # dict comprehension -``` - -#### Other Operators - -We can: - -- Represents a function call with **()**, like `"{} {}".format("hello", world)` -- Refers to the value at the specified index in the list with **[]** -- Define a type hint with **:** -- Refers to a member field with **.** -- Use the line continuation symbol `\` to write long expressions - -```python -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " -``` - -### Expressions - -#### Conditional Expressions - -A conditional expression has the form `a if cond else b`. It first evaluates the condition `cond`. If it's true, it evaluates `a` and yields its value; otherwise, it yields the value of `b`. - -Examples: - -```python -x = True if enabled else False # If enabled is True, x is True, otherwise x is False -``` - -#### Index Expressions - -An index expression `a[i]` yields the `i` th element of an indexable type such as a string or list. The index `i` must be an `int` value in the range `-n` ≤ `i` < `n`, where `n` is `len(a)`; any other index results in an error. - -A valid negative index `i` behaves like the non-negative index `n+i`, allowing for convenient indexing relative to the end of the sequence. - -```python -val = "abc" -list = ["zero", "one", "two"] -str_0 = val[0] # "a" -str_1 = val[1] # "b" -str_n1 = val[-1] # "c" - -list_0 = list[0] # "zero" -list_1 = list[1] # "one" -list_n1 = list[-1] # "two" -``` - -An index expression `d[key]` may also be applied to a dictionary `d`, to obtain the value associated with the specified key. It returns `Undefined` if the dictionary contains no such key. - -An index expression appearing on the left side of an assignment causes the specified list or dictionary element to be updated: - -```python -d = {key1 = "value1", key2 = "value2"} -key1value = d["key1"] # value1 -key2value = d["key2"] # value2 -``` - -It is a dynamic error to attempt to update an element of an immutable type, such as a list or string, or a frozen value of a mutable type. - -#### Slice Expressions - -A slice expression `a[start:stop:step]` yields a new value containing a sub-sequence of `a`, which must be a string, or list. - -Each of the `start`, `stop`, and `step` operands is optional; if present, each must be an integer. The `step` value defaults to 1. If the step is not specified, the colon preceding it may be omitted too. It is an error to specify a step of zero. - -Conceptually, these operands specify a sequence of values `i` starting at start and successively adding 'step' until `i` reaches or passes `stop`. The result consists of the concatenation of values of `a[i]` for which `i` is valid. - -The effective start and stop indices are computed from the three operands as follows. Let `n` be the length of the sequence. - -```python -val = "abc" -len = len(val) -a = val[1:len] # "bc" (remove first element) -b = val[0:-1] # "ab" (remove last element) -c = val[1:-1] # "b" (remove first and last element) -``` - -```python -"abc"[1:] # "bc" (remove first element) -"abc"[:-1] # "ab" (remove last element) -"abc"[1:-1] # "b" (remove first and last element) -"banana"[1::2] # "aaa" (select alternate elements starting at index 1) -"banana"[4::-2] # "nnb" (select alternate elements in reverse, starting at index 4) -``` - -It's not allowed to define a slice expression as a left value in KCL. Cause list and string are immutable, re-slicing can directly operate to operand to ensure better performance. - -#### Function Invocations - -KCL allows calling built-in functions and functions from built-in and system modules. - -To call a function, the basic way is shown as the following code excerpt: - -```python -import math - -a = math.pow(2, 3) # 2 powers 3 is 8. -b = len([1, 2, 3]) # the length of [1, 2, 3] is 3 -``` - -As you can see, arguments are separated with `,`, and KCL also supports positional arguments and key-value arguments. - -```python -print("hello world", end="") -``` - -Note that: - -- Some functions have parameters with default values. -- Some functions accept variadic arguments. - -When an argument is not supplied for a parameter without a default value, an error will be reported. - -#### Selector Expressions - -A selector expression selects the attribute or method of the value. KCL provides a wealth of ways to identify or filter attributes. - -`x.y` - -- dict: it denotes the value of the key `y` in the dict `x` -- schema: it denotes the attribute value of a schema `x` identified by `y` -- package: it denotes the identifier of a package `x` identified by `y` - -Examples: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -name = person.name # "Alice" -age = person.age # 18 - -myDict = { - key = "value" -} -result = myDict.key # "value" -``` - -`x?.y` - -`x` can be a schema instance or a dict. This is extremely helpful when the value of `x` might be `None` or when the key `y` might not exist in `x`. - -```python -# Example of dict: -data = {key = "value"} -a = data?.key # "value" -b = data?.name # Undefined - -# example of schema instance: -schema Company: - name: str - address: str - -schema Person: - name: str - job?: Company - -alice = Person { - name = "alice" -} - -if alice?.job?.name == "Group": - print("work in Group") -``` - -#### Quantifier Expressions - -Quantifier expressions act on collection: list or dict, generally used to obtain a certain result after processing the collection, mainly in the following four forms: - -- **all** - - Used to detect that all elements in the collection satisfy the given logical expression, and return a boolean value as the result. - - Only when all elements in the collection satisfy the expression true, the `all` expression is true, otherwise it is false. - - If the original collection is empty, return true. - - Supports short-circuiting of logical expressions during expression execution. -- **any** - - Used to detect that at least one element in the collection satisfies the given logical expression, and returns a boolean value as the result. - - When at least one element in the collection satisfies the expression true, the `any` expression is true, otherwise it is false. - - If the original collection is empty, return false. - - Supports short-circuiting of logical expressions during expression execution. -- **map** - - Generate a new **list** by mapping the elements in the original collection. - - The length of the new list is exactly the same as the original collection. -- **filter** - - By logically judging and filtering the elements in the original collection, and returning the filtered sub-collection. - - Only when the element judges the expression to be true, it is added to the sub-collection. - - The type (list, dict and schema) of the new collection is exactly the same as the original collection, and the length range is `[0, len(original-collection)]`. - -**all** and **any** expression sample codes: - -```python -schema Config: - volumes: [{str:}] - services: [{str:}] - - check: - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - }, "invalid cluster ip" - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } -``` - -**map** and **filter** expression sample codes: - -```python -a = map e in [{name = "1", value = 1}, {name = "2", value = 2}] { - {name = e.name, value = int(e.value) ** 2} -} # [{"name": "1", value: 1}, {"name": "2", "value": 4}] - -b = map k, v in {a = "foo", b = "bar"} { v } # ["foo", "bar"] - -c = filter e in [{name = "1", value = 1}, {name = "2", value = 2}] { - int(e.value) > 1 -} # [{"name": "2", "value": 2}] - -d = filter _, v in {a = "foo", b = "bar"} { - v == "foo" -} # {"a": "foo"} -``` - -Please pay attention to distinguish the difference between any expression and any type. When `any` is used in type annotations, it means that the value of the variable is arbitrary, while the any expression means that one of the elements in a set satisfies the condition. - -### Control Flow Statements - -#### If and Else - -KCL supports `if` statements with optional `elif` and `else` statements, as the next sample shows. - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - print("maybe a is negative") -else: - print("a >= 100") -``` - -The `elif` example: - -```python -_result = 0 -if condition == "one": - _result = 1 -elif condition == "two": - _result = 2 -elif condition == "three": - _result = 3 -else: - _result = 4 -``` - -`if-elif-else` statements can be nested. For example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - if a < 0: - print("a is negative") - print("No matter a is negative or positive, this message is printed") -else: - print("a >= 100") -``` - -In addition, for simple `if` statements as follows: - -```python -if success: - _result = "success" -else: - _result = "failed" -``` - -We can have it in one line using the ` if else ` pattern: - -```python -_result = "success" if success else "failed" -``` - -An `if` or `elif` statement evaluates a given expression. When the expression is evaluated to `True`, a list of statements following `:` are executed and when the expression is evaluated to `False` and statements will not be executed. - -Please note that the false name constant `False`, `None`, the zero number `0`, the empty list `[]`, the empty dict `{}` and the empty string `""` are all seen as `False` expressions. - -```python -_emptyStr = "" -_emptyList = [] -_emptyDict = {} -isEmptyStr = False if _emptyStr else True -isEmptyList = False if _emptyList else True -isEmptyDict = False if _emptyDict else True -``` - -The output is - -```yaml -isEmptyStr: true -isEmptyList: true -isEmptyDict: true -``` - -### Assert - -When errors happen, developers should be able to detect the error and abort execution. Thus, KCL introduce the `assert` syntax. The following is an example: - -```python -a = 1 -b = 3 -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -``` - -In addition, we can declare a condition for the assert statement and make an assertion when the condition is met. The usual way of writing is - -```python -a = None -if a: - assert a > 2: -``` - -In KCL, it can also be simplified to the following form using the **if** expression to compose more complex conditional assert logic: - -```python -a = None -assert a > 2 if a -``` - -### Function - -KCL supports using the lambda keyword to define a function. - -```python -func = lambda x: int, y: int -> int { - x + y -} -a = func(1, 1) # 2 -``` - -- The value of the last expression is used as the return value of the function, and the empty function body returns `None`. -- The return value type annotation can be omitted, and the return value type is the type of the last expression value. -- There is no order-independent feature in the function body, all expressions are executed in order. - -```python -_func = lambda x: int, y: int -> int { - x + y -} # Define a function using the lambda expression -_func = lambda x: int, y: int -> int { - x - y -} # Ok -_func = lambda x: int, y: int -> str { - str(x + y) -} # Error (int, int) -> str can't be assigned to (int, int) -> int -``` - -The function type variables cannot participate in any calculations and can only be used in assignment statements and call statements. - -```python -func = lambda x: int, y: int -> int { - x + y -} -x = func + 1 # Error: unsupported operand type(s) for +: 'function' and 'int(1)' -``` - -The lambda function supports the capture of external variables, which can be passed as parameters of other functions. - -```python -a = 1 -func = lambda x: int { - x + a -} -funcOther = lambda f, para: int { - f(para) -} -r0 = funcOther(func, 1) # 2 -r1 = funcOther(lambda x: int { - x + a -}, 1) # 2 -``` - -The output is - -```yaml -a: 1 -r: 2 -``` - -Further, we can define an anonymous function through lambda expression and call it. - -```python -result = (lambda x, y { - z = 2 * x - z + y -})(1, 1) # 3 -``` - -We can also use anonymous functions in the for loop. - -```python -result = [(lambda x, y { - x + y -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 3, 3, 4] -``` - -Note that the functions defined in the KCL are pure functions: - -- The return result of a function depends only on its arguments. -- There are no side effects in the function execution process. - -Therefore, KCL functions cannot modify external variables, but can only reference external variables. For example, the following code will cause an error: - -```python -globalVar = 1 -func = lambda { - x = globalVar # Ok - globalVar = 1 # Error -} -``` - -### Type System - -#### Type Annotation - -Type annotations can be used on top level variables, schema attributes and arguments. - -- An attribute can be of a basic type, such as a string (`str`), a floating-point number (`float`), a fixed-point number (`int`) or a boolean (`bool`). -- An attribute can be a literal type, such as a string literal (`"TCP"` and `"UDP"`), a number literal (`"1"` and `"1.2"`), a boolean literal (`True` and `False`) -- An attribute can also be a list or an ordinary dict: - - A list with unspecified type of elements is `[]`. - - A list with elements of type `t` is `[t]`. Here `t` is another type. - - A dict with keys of type `kt` and values of type `vt` is `{kt:vt}`. - - `kt`, `vt` or both of them can be missing, like a list with unspecified type of elements. -- An attribute can be a **union type** defined by `|`, such as `a | b`, which means the type of the member could be a or b. - - A union type can include any types of `int`, `str`, `float`, `bool`, `list`, `dict`, literal and schema type, and supports type nesting e.g. `{str:str|int}`, `[[int|str]|str|float]` and `2 | 4 | 6`, etc. -- An attribute can also be of a type generated from other schema. In such a case, the name of the other schema (including the package path prefix) is used as the type name. -- An attribute can annotated an any type e.g., `any`. - -Examples: - -- Basic type - -```python -"""Top level variable type annotation""" -a: int = 1 # Declare a variable `a` that has the type `int` and the value `1` -b: str = "s" # Declare a variable `b` that has the type `str` and the value `"s"` -c: float = 1.0 # Declare a variable `c` that has the type `float` and the value `1.0` -d: bool = True # Declare a variable `d` that has the type `bool` and the value `True` -``` - -- List/Dict/Schema Type - -```python -schema Person: - name: str = "Alice" - age: int = 10 - -a: [int] = [1, 2, 3] # Declare a variable `a` that has the list type `[int]` and the value `[1, 2, 3]` -b: {str:str} = {k1 = "v1", k2 = "v2"} # Declare a variable `b` that has the dict type `{str:str}` and the value `{k1 = "v1", k2 = "v2"}` -c: Person = Person {} # Declare a variable `c` that has the schema type `Person` and the value `Person {}` -``` - -- Union Type - -```python -# Basic union types -schema x[argc: int]: # Schema argument type annotation - p: int | str # Schema attribute type annotation -``` - -```python -# Literal union types -schema LiteralType: - # String literal union types, x_01 can be one of "TCP" and "UDP" - x_01: "TCP" | "UDP" - # Number literal union types, x_02 can be one of 2, 4, and 6 - x_02: 2 | 4 | 6 - # Unit union types, x_03 can be one of 1Gi, 2Gi and 4Gi - x_03: 1Gi | 2Gi | 4Gi - -x = LiteralType { - x_01 = "TCP" - x_02 = 2 - x_03 = 1Gi -} -``` - -The compiler throws an error when the value of a property does not conform to the union type definition: - -```python -# Literal union types -schema LiteralType: - # String literal union types, x_01 can be one of "TCP" and "UDP" - x_01: "TCP" | "UDP" - -x = LiteralType { - x_01 = "HTTP" # Error: the type got is inconsistent with the type expected, expect str(TCP)|str(UDP), got str(HTTP) -} -``` - -- Any Type - -```python -# Any type -schema Config: - literalConf: any = 1 - dictConf: {str:any} = {key = "value"} - listConf: [any] = [1, "2", True] - -config = Config {} -``` - -In KCL, changing the type of a variable is not allowed. If the type is not satisfied when reassigning the value, the type error will be raised. - -```python -_a = 1 # The type of `_a` is `int` -_a = "s" # Error: expect int, got str(s) -``` - -The type of a variable can be assigned to its upper bound type, but cannot be assigned to its specialized type. - -`None` and `Undefined` can be assigned to any type: - -- All types can be assigned to `any` type, `None` and `Undefined` can be assigned to `any` type. - -```python -a: int = None -b: str = Undefined -c: any = 1 -d: any = "s" -e: any = None -``` - -- The `int` type can be assigned to the `float` type, and the `float` type cannot be assigned to the `int` type. - -```python -a: float = 1 -b: int = 1.0 # Error: expect int, got float(1.0) -``` - -- The `int` type can be assigned to the `int|str` type, and the `int|str` type cannot be assigned to the `int` type. - -```python -a: int | str = 1 -b: int = 1 if a else "s" # Error: expect int, got int(1)|str(s) -``` - -Note that although the any type is provided in the KCl, it is still a static type, and the types of all variables are immutable during compilation. - -#### Type Inference - -If a variable or constant declaration in the top level or in the schema is not annotated explicitly with a type, the declaration's type is inferred from the initial value. - -- Integer literals are inferred to type `int`. - -```python -a = 1 # The variable `a` has the type `int` -``` - -- Float literals are inferred to type `float`. - -```python -a = 1.0 # The variable `a` has the type `float` -``` - -- String literals are inferred to type `str`. - -```python -a = "s" # The variable `a` has the type `str` -``` - -- Boolean literals are inferred to type `bool` - -```python -a = True # The variable `a` has the type `bool` -b = False # The variable `b` has the type `bool` -``` - -- `None` and `Undefined` are inferred to type `any` - -```python -a = None # The variable `a` has the type `any` -b = Undefined # The variable `b` has the type `any` -``` - -- List literals are inferred based on the elements of the literal, and to be variable-size. - -```python -a = [1, 2, 3] # The variable `a` has the type `[int]` -b = [1, 2, True] # The variable `b` has the list union type `[int|bool]` -c = ["s", 1] # The variable `c` has the list union type `[int|str]` -``` - -Please note that a empty list will be inferred to `[any]` - -```python -a = [] # The variable `a` has the type `[any]` -``` - -- Dict literals are inferred based on the keys and values of the literal, and to be variable-size. - -```python -a = {key = "value"} # The variable `a` has the type `{str:str}` -b = {key = 1} # The variable `b` has the type `{str:int}` -c = {key1 = 1, key2 = "s"} # The variable `c` has the type `{str:int|str}` -``` - -Please note that a empty dict will be inferred to `{any:any}` - -```python -a = {} # The variable `a` has the type `{any:any}` -``` - -- The type of the if conditional expression carrying the runtime value will be statically inferred as a union type of all possible results. - -```python -a: bool = True # The variable `a` has the type `bool` -b = 1 if a else "s" # The variable `b` has the type `int|str` -``` - -When a variable is deduced to a certain type, its type cannot be changed - -```python -_a = 1 -_a = "s" # Error: expect int, got str(1) -``` - -#### Type Alias - -We can use the `type` keyword to declare a type alias for all types in KCL to simplify the writing and use of complex types. - -```python -type Int = int -type String = str -type StringOrInt = String | Int -type IntList = [int] -type StringAnyDict = {str:} -``` - -We can import a type through import and define an alias for it. - -```py -import pkg - -type Data = pkg.Data -``` - -In addition, we can use type aliases and union types to achieve similar enumeration functions. - -```python -# A type alias of string literal union types -type Color = "Red" | "Yellow" | "Blue" - -schema Config: - color: Color = "Red" # The type of color is `"Red" | "Yellow" | "Blue"`, and it has an alias `Color`, whose default value is `"Red"` - -config = Config { - color = "Blue" -} -``` - -The output YAML is - -```yaml -config: - color: Blue -``` - -Please note that the type alias name cannot be one of `any`, `int`, `float`, `bool` and `str` because of ambiguity. - -```python -type any = int | str # Error -type int = str # Error -type float = int # Error -type bool = True # Error -type str = "A" | "B" | "C" # Error -``` - -#### Type Guards - -KCL supports the `typeof` function which can give very basic information about the type of values we have at runtime. In KCL, checking against the value returned by `typeof` is a type guard. KCL expects this to return a certain set of strings: - -Example: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person {} -t3 = typeof(_x1) - -_x2 = pkg.Person {} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# Output -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -In addition, we can use the `as` keyword in conjunction with type guards to complete defensive type conversion programming. - -Only types with partial order can be downcast converted, the use of the as keyword is as follows: - -- Basic types of partial order relations, e.g., `float -> int` -- Partial order relation of union type, e.g., `int | str -> str` and `[int | str] -> [str]` -- Contains the partial order relation of the upper bound of the type, e.g., `any -> int` -- Partial order relationship of structure type, e.g., `base-schema -> sub-schema` - -```python -schema Data1: - id?: int - -schema Data2: - name?: str - -data: Data1 | Data2 = Data1 {} - -if typeof(a) == "Data1": - data1 = data as Data1 # The type of `data1` is `Data1` -elif typeof(a) == "Data2": - data2 = data as Data2 # The type of `data2` is `Data2` -``` - -When a runtime error occurs in the `as` type conversion, a runtime error is thrown. - -```python -a: any = "s" -b: int = a as int # Error: The `str` type cannot be converted to the `int` type -``` - -If we don’t want to throw a runtime error, we can use the type guard for defensive coding with `if` expressions. - -```python -a: any = "s" -b = a as int if typeof(a) == "int" else None # The type of b is `int` -``` - -Note that the `as` conversion of literal type and union type is not supported, because they are not a certain runtime object, only int, float and other objects at runtime, there is no int literal, float literal object, and no union object. - -### Schema - -#### Overview - -A schema is a language element to define a complex configuration. -We can define typed attributes, initialization assignment, and verification rules. In addition, KCL supports schema single inheritance, mixin and protocol to realize the reuse of complex configuration. - -#### Basic - -##### Attribute - -The followings are some basic examples: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 -``` - -In KCL, we can use type annotations to define some attributes in the schema, each attribute can be set with an optional default value (such as the `age` attribute in the above code, its default value is `0`), attributes that are not set default values have an initial value of `Undefined`, which are not output in YAML. - -Note, the immutability of attributes in the schema follows the same rules as the immutability of global variables, only mutable attributes in the schema can be modified in the schema. - -```python -schema Person: - age: int = 1 # Immutable attribute - _name: str = "Alice" # Mutable attribute - - age = 10 # Error - _name = "Bob" # Ok -``` - -###### Optional Attribute - -Each attribute **must** be assigned with a not `None`/`Undefined` value as a schema instance unless it is modified by a question mark as an optional attribute. - -Examples: - -```python -schema Employee: - bankCard: int # bankCard is a required attribute, and it can NOT be None or Undefined - nationality?: str # nationality is an optional attribute, and it can be None or Undefined - -employee = Employee { - bankCard = None # Error, attribute 'bankCard' of Employee is required and can't be None or Undefined - nationality = None # Ok -} -``` - -##### Irrelevant Order Calculation - -The irrelevant order calculation in the schema indicates the reference relationship between the internal attributes of the schema. For example, when we declare an expression of the form `a = b + 1`, the calculation of the value of `a` depends on the calculation of the value of `b`. When the compiler calculate the value of `a` and the value of `a` depends on the value of `b`, the compiler will choose to first calculate the value of `b`, and then calculate the value of a according to the expression `a = b + 1`, which is slightly different from the calculation method of traditional procedural language the difference. - -Since the calculation of values in the schema is based on dependencies, just like a directed acyclic graph traverses each node in the graph according to the order of topological sorting, the order of declaration of attributes in the schema is not so important, so the feature is called the irrelevant order calculation. - -Please note that there can be no circular references between different schema attribute values. - -We can see this feature through the following examples. - -```python -schema Fib: - n1: int = n - 1 # Refers to the attribute `n` declared after `n1` - n2: int = n1 - 1 - n: int - value: int = 1 if n <= 2 else Fib {n = n1}.value + Fib {n = n2}.value - -fib8 = Fib {n = 8}.value -``` - -The output is - -```yaml -fib8: 21 -``` - -We can see that in the schema, we only need to simply specify the dependency between attributes, and the compiler will automatically calculate the value based on the dependency, which can help us save a lot of boilerplate code and reduce configuration difficulty of writing. - -##### Schema Context - -We can define the context of the schema to manage the attributes of the schema, and we can write schema parameters, temporary variables and expressions directly in the schema: - -```python -schema Person[_name: str]: # define a schema argument - name: str = _name # define a schema attribute - age: int = 10 # define a schema attribute with default value - hands: [int] = [i for i in [1, 2, 3]] # define a for statement -``` - -##### Validation - -In addition to using **static typing** (the type annotation) and **immutability** in KCL schema mentioned earlier to ensure code stability, a bunch of validation rules are supported in a simple **check** block (KCL supports almost all authentication capabilities of [OpenAPI](https://www.openapis.org/)): - -```python -import regex - -schema Sample: - foo: str - bar: int - fooList: [str] - - check: - bar > 0 # minimum, also support the exclusive case - bar < 100 # maximum, also support the exclusive case - len(fooList) > 0 # min length, also support exclusive case - len(fooList) < 100 # max length, also support exclusive case - regex.match(foo, "^The.*Foo$") # regex match - isunique(fooList) # unique - bar in range(100) # range - bar in [2, 4, 6, 8] # enum - multiplyof(bar, 2) # multipleOf -``` - -With the schema, all instances will be validated at compile time - -```python -# Ok -goodSample = Sample { - foo = "The Foo" - bar = 2 - fooList = ["foo0", "foo1"] -} - -# Error: validation failure: Check failed on check conditions: bar < 100. -badSample = Sample { - foo = "The Foo" - bar = 123 - fooList = ["foo0", "foo1"] -} -``` - -In addition, we can use **and**, **or**, **if** to compose more complex conditional check logic: - -```python -schema Sample: - bar: int - foo: str - doCheck: bool - - check: - regex.match(foo, "^The.*Foo$") and bar in [2, 4, 6, 8] if doCheck -``` - -In order to ensure that all check rules can play their corresponding roles well, we can test the rationality and correctness of different data combinations by writing KCL test cases, and run all test cases through the kcl test tool. - -##### Documents - -Usually after we write the schema model, we will write documentation comments for the schema, which can be completed by using a three-quoted string as follows: - -```python -schema Server: - """Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - - Attributes - ---------- - workloadType : str, default is Deployment - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - name : str, default is None - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - labels : {str:str}, optional, default is None - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - - Examples - ---------------------- - myCustomApp = AppConfiguration { - name = "componentName" - } - """ - workloadType: str = "Deployment" - name: str - labels?: {str:str} -``` - -##### Config - -Suppose we have the following schema definition: - -```python -schema Person: - firstName: str - lastName: str -``` - -A config could be defined with a JSON-like expression: - -```python -person = Person { - firstName = "firstName" - lastName = "lastName" -} -``` - -At the same time, the schema adheres to strict attribute definitions, -and configuring undefined attributes will trigger a compilation error. - -```python -person = Person { - firstName = "firstName" - lastName = "lastName" - fullName = "fullName" # Error: Cannot add member 'fullName' to schema 'Person', 'fullName' is not defined in schema 'Person' -} -``` - -We can use `if expressions` to dynamically add elements to the schema config, elements that meet the conditions are added to the schema config, and elements that do not meet the conditions are ignored. Besides, the **config selector expressions** can be used to init a schema instance. - -```python -schema Base: - count: int - value: str - -schema Person: - base: Base - labels: {str:str} - name?: str - -env = "prod" - -person1 = Person { - base.count = 2 # Config selector expression - base.value = "value" # A schema variable in schema can use selector expressions - labels.key = "value" # A dict variable in schema can use selector expressions -} - -person2 = Person { - base = { - count = 1 - value = "value" - } - labels.key = "value" - if env == "prod": - labels.env = env - else: - labels.env = "other" -} -``` - -The output YAML is - -```yaml -person1: - base: - count: 2 - value: value - labels: - key: value -person2: - base: - count: 1 - value: value - labels: - key: value - env: prod -``` - -When we instantiate a schema without config parameters, we can generate schema instances in the following three forms: - -```python -schema Data: - id: int = 1 - -data1 = Data {} -data2 = Data() {} -data3 = Data() -``` - -In addition to using a schema type to instantiate a schema, we can also use a schema instance to get a new instance using the config expression. - -```python -schema Config: - id: int - values: [int] - -configOrigin = Config { - id = 1 - values = [0, 1] -} -configNew = configOrigin { - id = 2 - values += [2, 3] -} -``` - -The output is - -```yaml -configOrigin: - id: 1 - values: - - 0 - - 1 -configNew: - id: 2 - values: - - 0 - - 1 - - 2 - - 3 -``` - -In addition, schema attribute default values can be modified by schema config. - -```python -schema Person: - age: int = 1 - name: str = "Alice" - - age = 2 # Error, can't change the default value of the attribute `age` in the schema context - -person = Person { - age = 3 # Ok, can change the default value of the attribute `age` in the schema config -} -``` - -#### Advanced - -##### Protocol & Mixin - -In addition to schema, an additional type definition method `protocol` is provided in KCL, and its properties are as follows: - -- In a protocol, only attributes and their types can be defined, complex logic and check expressions cannot be written, and mixins cannot be used. -- A protocol can only constrain properties that do not start with `_`. -- A protocol can only inherit or refer to other protocols, but cannot inherit or refer to other schemas. - -Besides, we can declare a complex assembly schema with optional **mixin** support and use **protocol** to add an optional host type to the dynamically inserted **mixin**.: - -```python -schema Person: - mixin [FullNameMixin] - - firstName: str # Required - lastName: str # Required - fullName?: str # Optional -``` - -A fullName mixin which generates a fullName as a simple sample: - -```python -protocol PersonProtocol: - firstName: str - lastName: str - fullName?: str - -mixin FullNameMixin for PersonProtocol: - fullName = "{} {}".format(firstName, lastName) -``` - -Then we can get the schema instance by: - -```python -person = Person { - firstName = "John" - lastName = "Doe" -} -``` - -The output is - -```yaml -person: - firstName: John - lastName: Doe - fullName: John Doe -``` - -Please note that the host type **protocol** can only be used for **mixin** definitions (the suffix name is `Mixin`), otherwise an error will be reported. - -```python -protocol DataProtocol: - data: str - -schema Data for DataProtocol: # Error: only schema mixin can inherit from protocol - x: str = data -``` - -##### Index Signature - -Index signatures can be defined in the KCL schema, and it means that the key-value constraints of the index signature can be used to construct a dict with the schema type, or additional checks can be added to the schema attributes to enhance the KCL type and semantic checks. - -- Use the form `[{attr_alias}: {key_type}]: {value_type}` to define an index signature in the schema, and `{attr_alias}` can be omitted. - -```python -schema Map: - """ - Map is a schema with a key of str type and a value of str type - """ - [str]: str # `{attr_alias}` can be omitted. - -data = Map { - key1 = "value1" - key2 = "value2" -} -``` - -- Mandatory all attributes of the schema key and value types - -```python -schema Person: - name: str - age: int # error, conflicts with the index signature definition `[str]: str` - [str]: str # The values of all attributes of the schema can only be strings -``` - -- Mandatory all attribute key and value types are defined in the schema, which is equivalent to restricting all attribute types except the additional attributes. - -```python -schema Person: - name: str - age: int - [...str]: str # Except for the `name` and `age` attributes, the key type of all other attributes of the schema must be `str`, and the value type must also be `str`. -``` - -- Define the index signature attribute alias and use it with the check block. - -```python -schema Data: - [dataName: str]: str - check: - dataName in ["Alice", "Bob", "John"] - -data = Data { - Alice = "10" - Bob = "12" - Jonn = "8" # Error: Jonn not in ["Alice", "Bob", "John"] -} -``` - -```python -import regex - -schema DataMap: - [attr: str]: str - check: - regex.match(attr, r'^[-._a-zA-Z0-9]+$') - -data = DataMap { - key1 = "value1" - "foo.bar" = "value2" # check error -} -``` - -##### Inheritance - -Like some other object-oriented languages, KCL provides fundamental but limited object-oriented support, such as **attribute reuse**, **private and public variables**, and **single inheritance**. Besides, KCL does NOT support multiple inheritances for the schema. - -The following is an example of schema inheritance: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 - -# An employee **is** a person, and has some additional information. -schema Employee(Person): - bankCard: int - nationality?: str - -employee = Employee { - firstName = "Bob" - lastName = "Green" - age = 18 - bankCard = 123456 -} -``` - -The output is - -```yaml -employee: - firstName: Bob - lastName: Green - age: 18 - bankCard: 123456 - nationality: null -``` - -Please note that KCL only allows **single inheritance** on schemas. - -In addition, when the schema has an inheritance relationship, the properties of optional attributes are as follows: - -- If the attribute is optional in the base schema, it could be optional or required in the sub-schema. -- If the attribute is required in the base schema, it must be required in the sub-schema. - -```python -schema Person: - bankCard?: int - nationality: str - -schema Employee(Person): - bankCard: int # Valid, both `bankCard: int` and `bankCard?: int` are allowed - nationality?: str # Error, only `nationality: str` is allowed -``` - -##### Schema Function - -Schema map very nicely onto functions; it can have any number of input and output parameters. For example, the Fibonacci function can be written as follows using the recursive schema config: - -```python -schema Fib[n: int]: - n1 = n - 1 - n2 = n - 2 - if n == 0: - value = 0 - elif n == 1: - value = 1 - else: - value = Fib(n1).value + Fib(n2).value - -fib8 = Fib(8).value # 21 -``` - -##### Decorators - -Just like Python, KCL supports the use of decorators on the schema. KCL Decorators dynamically alter the functionality of a schema without having to directly use sub schema or change the source code of the schema being decorated. And like a function call, the decorator supports passing in additional parameters. - -Built-in decorators of schema - -- `@deprecated` - Mark whether a schema or schema attribute is deprecated. The `@deprecated` decorator supports three parameters: - - **version** - string type, indicating the version information. The default value is empty. - - **reason** - string type, indicating the deprecated reason. The default value is empty. - - **strict** - bool type, indicating whether to report an error or warning. The default value is true. If `strict` is `True` and the error is thrown, the program will be interrupted. If `strict` is `False`, a warning will be output and the program will not be interrupted. - -Examples: - -```python -@deprecated -schema ObsoleteSchema: - attr: str - -schema Person: - name: str = "John" - attrs: ObsoleteSchema = { - attr = "value" - } - -person = Person {} # Error: ObsoleteSchema was deprecated -``` - -```python -schema Person: - firstName: str = "John" - lastName: str - @deprecated(version="1.16", reason="use firstName and lastName instead", strict=True) - name: str - -JohnDoe = Person { # Error: name was deprecated since version 1.16, use firstName and lastName instead - name = "deprecated" -} -``` - -Note that the current version of KCL does not yet support user-defined decorators. - -##### Members - -Built-in functions and members of schema - -- instances() - Return the list of existing instances of a schema. - -```python -schema Person: - name: str - age: int - -alice = Person { - name = "Alice" - age = 18 -} - -bob = Person { - name = "Bob" - age = 10 -} - -aliceAndBob = Person.instances() # Person is a schema type, instances() is its member method -``` - -The output is - -```yaml -alice: - name: Alice - age: 18 -bob: - name: Bob - age: 10 -aliceAndBob: - - name: Alice - age: 18 - - name: Bob - age: 10 -``` - -### Config Operations - -#### Config Unification - -##### | Operators - -In KCL, we can use the union operator `|` to achieve the merging of configurations, the types supported by the union operator are as follows: - -```txt -SchemaInstance | SchemaInstance -SchemaInstance | Dict -Dict | Dict -List | List -``` - -Unioning collection and schema data: - -- Unioning List. Overwrite the list expression on the right side of the operator `|` to the list variable on the left side of the operator one by one according to the **index**. - -```python -_a = [1, 2, 3] -_b = [4, 5, 6, 7] -x = _a | _b # [4, 5, 6, 7] 1 -> 4; 2 -> 5; 3 -> 6; Undefined -> 7 -``` - -Unioning to the specific index or all elements is still under discussion. - -- Unioning Dict. Union the dict expression on the right side of the operator `|` one by one to the dict variable on the left side of the operator according to the **key** - -```python -_a = {key1 = "value1"} -_b = {key1 = "overwrite", key2 = "value2"} -x = _a | _b # {"key1": "overwrite", "key2": "value2"} -``` - -The union of collection and schema is a new one whose attributes are unioning b to a, preserving the order of the attributes of the operands, left before right. - -- Unioning Schema. The union operation for schema is similar to dict. - -Schema union could be done as: - -```python -schema Person: - firstName?: str - lastName?: str - -_a = Person { - firstName = "John" -} -_b = {lastName = "Doe"} -_c = _a | _b # {"firstName": "John", "lastName": "Doe"} -_d = _a | None # {"firstName": "John"} -_e = _a | Undefined # {"firstName": "John"} -_f = None | _a # {"firstName": "John"} -_g = Undefined | _a # {"firstName": "John"} -``` - -Please note that when one of the left and right operands of the union operator is None, the other operand is returned immediately. - -```python -data1 = {key = "value"} | None # {"key": "value"} -data2 = None | [1, 2, 3] # [1, 2, 3] -data3 = None | None # None -``` - -The output is - -```yaml -data1: - key: value -data2: - - 1 - - 2 - - 3 -data3: null -``` - -##### : Operators - -Pattern: `identifier : E` or `identifier : T E` - -The value of the expression `E` with optional type annotation `T` will be unioned into the element value. - -Examples: - -```python -data = { - labels: {key1: "value1"} - # union {key2: "value2"} into the attribute labels. - labels: {key2: "value2"} -} -``` - -Output: - -```yaml -data: - labels: - key1: value1 - key2: value2 -``` - -In addition to using attribute operators on the schema config attributes, variables inside and outside the schema can use attribute operators to perform different operations on the configuration. - -- Using `:` outside the schema - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - data: Data - -# This is one configuration that will be merged. -config: Config { - data.d1 = 1 -} -# This is another configuration that will be merged. -config: Config { - data.d2 = 2 -} -``` - -Its equivalent configuration code can be expressed as - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - data: Data - -config: Config { - data.d1 = 1 - data.d2 = 1 -} -``` - -The output is - -```yaml -config: - data: - d1: 1 - d2: 1 -``` - -- Using `:` inside the schema - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - # This is one configuration that will be merged. - data: Data { - d1 = 1 - } - # This is another configuration that will be merged. - data: Data { - d2 = 1 - } - -config: Config {} -``` - -#### Config Override - -##### = Operators - -Pattern: `identifier = E` or `identifier : T = E` - -The value of the expression `E` with optional type annotation `T` will override the attribute value. - -Examples: - -```python -schema Data: - labels: {str:} = {key1 = "value1"} - -data = Data { - # override {key2: "value2"} into the attribute labels of the schema Data. - labels = {key2 = "value2"} -} -``` - -Output: - -```yaml -data: - labels: - key2: value2 -``` - -Note: - -- Especially, we can "delete" its content by overriding the attribute to `Undefined`, such as `{ a = Undefined }`. - -#### Insert - -##### += Operators - -Pattern: `identifier += E` or `identifier : T += E` - -Insert only works for list type `identifier`. - -`E` will be inserted just after the specified index of the list `identifier`, and the following attributes after the index will be automatically shifted. - -Examples: - -```python -schema Data: - labels: {str:} = {key1 = [0]} - -data = Data { - # insert [1] into the attribute labels.key1 of the schema Data. - labels: {key1 += [1]} -} -``` - -Output: - -```yaml -data: - labels: - key1: - - 0 - - 1 -``` - -If no index is specified, the last index will be used. - -#### Notice - -Please note that the calculations of the `=` and `+=` attribute operators of the same attribute are sequential, and the latter ones have a higher priority. - -```python -x = { - a = 1 # 1 -} | { - a = 2 # 1 -> 2 -} | { - a = 3 # 2 -> 3 -} # The final value of attribute `a` is 3 -``` - -Please note that the `:` attribute operator represents an idempotent merge operation, and an error will be thrown when the values that need to be merged conflict. - -Therefore, when we need a configuration to override or add and delete operations, it is best to use the `=` and `+=` operators - -```python -data0 = {id: 1} | {id: 2} # Error:conflicting values between {'id': 2} and {'id': 1} -data1 = {id: 1} | {id = 2} # Ok, the value of `data` is {"id": 2} -``` - -The check rules for `:` operator for KCL value conflicts are as follows: - -- For `None` and `Undefined` variables, they do not conflict with any value. - -```python -data0 = None | {id: 1} # Ok -``` - -- For `int`, `float`, `str` and `bool` types, when their values are different, they are considered as conflicts. - -```python -data0 = 1 | 1 # Ok -data1 = 1 | "s" # Error -``` - -- For list type - - When their lengths are not equal, they are regarded as conflicts. - - When their lengths are equal, as long as there is a conflict in the value of a child element, it is regarded as a conflict. - -```python -data0 = [1] | [1] # Ok -data1 = [1, 2] | [1] # Error -``` - -- For dict/schema type - - When the values of the same key conflict, they are regarded as conflicts - -```python -data0 = {id: 1} | {id: 1} # Ok -data1 = {id: 1} | {id: 2} # Error -data1 = {id: 1} | {idAnother: 1} # Ok -``` - -### Rule - -In addition to using the check keyword for verification and writing in the schema, KCL also supports the use of the `rule` keyword to define a set of rules for policy verification - -The KCL rule is the same as the schema/mixin/protocol and it is defined by indentation. We need write a rule per line and we can write if filter conditions and verification failure information for each rule. Different conditions are connected with logic `and` (similar to the way of writing in check block). - -```python -rule SomeRule: - age > 0, "rule check failure message" -``` - -We can call a KCL rule like instantiating a schema: - -```python -age = 1 -name = "Alice" - -rule SomeRule: - age > 0, "rule check failure message" - name == "Alice" - -rule1 = SomeRule() # Rule call -rule2 = SomeRule {} # Rule call -``` - -We can use protocol to implement type checking of rule structure: - -```python -# Schema definition -protocol Service: - clusterIp: str - $type: str - -# Schema definition -protocol Volume: - mountPath: [str] - -# Protocol -protocol SomeProtocol: - id: int - env: {str: any} - services: [Service] - volumes: [Volume] - -rule SomeChecker for SomeProtocol: - id > 0, "id must >0" - - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - } - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } - -# Call rule to check with config parameter -SomeChecker { - id = 1 - env = { - MY_ENV = "MY_ENV_VALUE" - } - services = [ - { - type = "ClusterIP" - clusterIP = "NONE" - } - ] - volumes = [ - { - mountPath = "/home/admin" - } - { - mountPath = "/home/myapp" - } - ] -} -``` - -Please note that the combination of `protocol` and `rule` can separate attributes from their constraint definitions. We can define different rules and protocols in different packages and combine them as needed. This is different from check expressions in schema, which can only be combined with schema attributes. - -Besides, the following two ways can be used to achieve the multiplexing of different Rules: - -- Inline Call - -```python -weather = "sunny" -day = "wednesday" - -rule IsSunny: - weather == "sunny" - -rule IsWednesday: - day == "wednesday" - -rule Main: - IsSunny() # Rule inline call - IsWednesday() # Rule inline call - -Main() # Rule call -``` - -- Inherit - -```python -weather = "sunny" -day = "wednesday" - -rule IsSunny: - weather == "sunny" - -rule IsWednesday: - day == "wednesday" - -rule Main(IsSunny, IsWednesday): - id == 1 - -Main() -``` - -We can obtain external data or input from the `option` function and the CLI parameter `-D` for verification: - -- A simple example - -```python -schema Day: - day: str - homework: str - -days: [Day] = option("days") - -rule Main: - filter d in days { - d.day not in ["saturday", "sunday"] and d.homework - } - -Main() -``` - -- A complex example - -```python -data = option("data") -input = option("input") - -rule Allow: - UserIsAdmin() - any grant in UserIsGranted() { - input.action == grant.action and input.type == grant.type - } - -rule UserIsAdmin: - any user in data.user_roles[input.user] { - user == "admin" - } - -rule UserIsGranted: - [ - grant - for role in data.user_roles[input.user] - for grant in data.role_grants[role] - ] - -allow = Allow() or False -``` - -Further, the above KCL rule code can be compiled into a target such as WASM and used at runtime. - -### Module - -KCL config files are organized as **modules**. A single KCL file is considered as a module, and a directory is considered as a package, which is a special module. - -The modules in the same package are visible and cross-package references need to be visible through import. - -Code structure: - -```bash -. -└── root - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -model1.k: - -```python -# schema CatalogItem in model1.k - -schema CatalogItem: - id: int - image: CatalogItemImage # CatalogItemImage is defined in the module of the same package e.g., model2.k in package model - title: str -``` - -service1.k: - -```python -import ..model as model # cross-package references - -schema ImageService: - image: model.CatalogItemImage # CatalogItemImage is imported from another package e.g., model2.k in package model - name: str -``` - -#### Relative Path Import - -We can use the operator `.` to realize the relative path import of KCL entry files. - -main.k: - -```python -import .model1 # Current directory module -import ..service # Parent directory -import ...root # Parent of parent directory - -s = service.ImageService {} -m = root.Schema {} -``` - -#### Absolute Path Import - -The semantics of `import a.b.c.d` is - -1. If `kcl.mod` not exist, regard the current directory as the package root and search the path `a/b/c/d` from the current directory. -2. If the current directory search fails, search from the root path `ROOT_PATH/a/b/c/d`, else raise an import error. - -The definition of the root path `ROOT_PATH` is the directory corresponding to the `kcl.mod` file from the current directory. - -Code structure: - -```bash -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -main.k: - -```python -import service # `root package` and `kcl.mod` are in the same directory -import mixin # `root package` and `kcl.mod` are in the same directory - -myModel = model.CatalogItem {} -``` - -Note that for the KCL entry file `main.k`, it cannot be imported into the folder where it is located, otherwise a recursive import error will occur: - -```python -import model # Error: recursively loading -``` - -### Top-Level Argument - -Assume some field need to be passed in dynamically like user input, we can define a top-level argument in a module: - -```python -bankCard = option("bankCard") # Get bankCard through the option function. -``` - -Then we can use the module as below: - -```bash -kcl employee.k -D bankCard=123 -``` - -Currently, supported types of top-level argument are number, string, bool, list and dict. - -```bash -kcl main.k -D list_key='[1,2,3]' -D dict_key='{"key":"value"}' -``` - -We need to pay attention to the escape of quotation marks `"` and other symbols in the command line - -#### Arguments with Setting Files - -In addition, it also supports inputting a YAML file as top-level arguments. - -```yaml -kcl_options: - - key: key_number - value: 1 - - key: key_dict - value: - innerDictKey: innerDictValue - - key: key_list - value: - - 1 - - 2 - - 3 - - key: bankCard - value: 123 -``` - -```bash -kcl -Y setting.yaml employee.k -``` - -In addition, the setting file also supports configuring command-line compilation parameters as follows: - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - disable_none: true - strict_range_check: true - debug: 1 - verbose: 1 - sort_keys: true - output: ./stdout.golden - overrides: - - app.image=new_image - path_selector: - - config - package_maps: - k8s: /Users/.kcl/kpm/k8s_1.24 -kcl_options: - - key: image - value: docker.io/kcllang/kcl:latest -``` - -KCL CLI -Y parameters also support multi-file configuration, and support separate writing and merging of compilation parameters and option top level arguments parameter configuration. - -```bash -kcl -Y compile_setting.yaml option_setting.yaml -``` - -- `compile_setting.yaml` - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - disable_none: true - strict_range_check: true - debug: 1 - verbose: 1 - output: ./stdout.golden -``` - -- `option_setting.yaml` - -```yaml -kcl_options: - - key: image - value: docker.io/kcllang/kcl:latest -``` - -We can use the following command line to get the meaning of each configuration parameter or see KCL Quick Start - -```bash -kcl --help -``` - -#### Option Functions - -We can use the `option` function in the KCL code to get the top-level arguments. - -```python -value = option(key="key", type='str', default="default_value", required=True, help="Set key value") -``` - -Parameters - -- **key**: The argument key. -- **type**: The argument type to be converted. -- **default**: The argument default value when the key-value argument is not provided -- **required**: Report an error when the key-value argument is not provided and required is True. -- **help**: The help message. - -### Multi-file Compilation - -In addition to the above KCL single file execution, we can compile multiple KCL entry files at the same time using the following command: - -```bash -kcl main_1.k main_2.k ... main_n.k -``` - -main_1.k - -```python -a = 1 -b = 2 -``` - -main_2.k - -```python -c = 3 -d = 4 -``` - -The output is: - -```yaml -a: 1 -b: 2 -c: 3 -d: 4 -``` - -Taking advantage of the **multi-file combination**, we can assemble multiple KCL files without the need to use import management files. Let us see an example of combining **multi-file compilation** and **schema instance**. - -model.k - -```python -schema Model: - name: str - labels?: {str:} - annotations?: {str:} - replicas: int - -_model1 = Model { - name = "model1" - labels.key1 = "value1" - labels.key2 = "value2" - annotations.key = "value" - replicas = 2 -} - -_model2 = Model { - name = "model2" - replicas = 3 -} -``` - -backend.k - -```python -import yaml - -schema Backend: - apiVersion: str = "v1" - kind: str = "Deployment" - metadata: {str:} - spec: {str:} = { - minReadySeconds = 0 - paused = False - progressDeadlineSeconds = 600 - replicas = 1 - revisionHistoryLimit = 10 - selector = {} - } - -_backends = [Backend { - metadata.name = model.name - metadata.labels = model.labels - metadata.annotations = model.annotations - spec.selector.matchLabels: model.labels - spec.replicas = model.replicas -} for model in Model.instances()] # Schema Model is defined in model.k -print("---\n".join([yaml.encode(_b, ignore_private=True) for _b in _backends])) -``` - -The command is - -```bash -kcl model.k backend.k -``` - -The output is - -```yaml -apiVersion: v1 -kind: Deployment -metadata: - name: model1 - labels: - key1: value1 - key2: value2 - annotations: - key: value -spec: - minReadySeconds: 0 - paused: false - progressDeadlineSeconds: 600 - replicas: 2 - revisionHistoryLimit: 10 - selector: - matchLabels: - key1: value1 - key2: value2 ---- -apiVersion: v1 -kind: Deployment -metadata: - name: model2 -spec: - minReadySeconds: 0 - paused: false - progressDeadlineSeconds: 600 - replicas: 3 - revisionHistoryLimit: 10 - selector: {} -``` - -### KCL CLI Path Selector - -We can use KCL CLI `-S|--path-selector` parameter to select one or more values out of a KCL model. - -The path selector looks like this: - -`var.name` - -#### Examples - -Code structure: - -```bash -. -├── kcl.mod -└── main.k - └── pkg - └── model.k -``` - -pkg/model.k: - -```python -schema Person: - name: str - age: int - -var = Person { - name = "Alice" - age = 18 -} -``` - -main.k - -```python -import pkg - -var = pkg.Person { - name = "Bob" - age = 10 -} -``` - -The command is - -```bash -kcl main.k -S var -``` - -The output is - -```yaml -name: Alice -age: 18 -``` - -### KCL CLI Variable Override - -In addition to **Variable Selector**, KCL also allows us to directly modify the values in the configuration model through the KCL CLI `-O|--overrides` parameter. - -The use of **Variable Override** is similar to [**Variable Selector**](#variable-selector), and the parameter contains three parts e.g., `pkg`, `identifier`, `attribute` and `override_value`. - -```bash -kcl main.k -O override_spec -``` - -- `override_spec` represents a unified representation of the configuration model fields and values that need to be modified - -```txt -override_spec: [[pkgpath] ":"] identifier ("=" value | "-") -``` - -- `pkgpath`: Indicates the path of the package whose identifier needs to be modified, usually in the form of `a.b.c`. For the main package, `pkgpath` is expressed as `__main__`, which can be omitted. If omitted, it means the main package. -- `identifier`: Indicates the identifier that needs to modify the configuration, usually in the form of `a.b.c`. -- `value`: Indicates the value of the configuration that needs to be modified, which can be any legal KCL expression, such as number/string literal value, list/dict/schema expression, etc. -- `=`: means to modify the value of identifier. - - When the identifier exists, modify the value of the existing identifier to value. - - When identifier does not exist, add the identifier attribute and set its value to value. -- `-`: means to delete the identifier attribute. - - When the identifier exists, delete it directly. - - When the identifier does not exist, no modification is made to the configuration. - -Note: When `identifier` appears multiple times, modify/delete all `identifier` values - -#### Examples - -##### Override Update Sample - -KCL code: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -``` - -The command is - -```bash -kcl main.k -O :person.name=\"Bob\" -O :person.age=10 -``` - -The output is - -```yaml -person: - name: Bob - age: 10 -``` - -Besides, when we use KCL CLI `-d` argument, the KCL file will be modified to the following content at the same time - -```bash -kcl main.k -O :person.name=\"Bob\" -O :person.age=10 -d -``` - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Bob" - age = 10 -} -``` - -Another more complicated example: - -```python -schema Person: - name: str - age: int - ids?: [int] - -person = Person { - name = "Alice" - age = 10 -} -``` - -The command is - -```bash -kcl main.k -O :person.ids=\[1,2\] -``` - -The output is - -```yaml -person: - name: Alice - age: 10 - ids: - - 1 - - 2 -``` - -##### Override Delete Sample - -KCL code: - -```python -schema Config: - x?: int = 1 - y?: str = "s" - -config = Config { - x = 2 -} -``` - -The command is - -```bash -kcl main.k -O config.x- -``` - -The output is - -```yaml -config: - x: 1 - y: s -``` - -### Summary - -This page summarized the commonly used features in the KCL language. As a new language, KCL will gradually increase the functional features according to the requirements of the configuration scenario. - -For more information, please try further resources: - -- KCL codelabs -- KCL language specification -- KCL OpenAPI specification diff --git a/versioned_docs/version-0.5.4/reference/lang/types/_category_.json b/versioned_docs/version-0.5.4/reference/lang/types/_category_.json deleted file mode 100644 index 8b257445..00000000 --- a/versioned_docs/version-0.5.4/reference/lang/types/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Types", - "position": 4 -} diff --git a/versioned_docs/version-0.5.4/reference/lang/types/types.md b/versioned_docs/version-0.5.4/reference/lang/types/types.md deleted file mode 100644 index ee88c64d..00000000 --- a/versioned_docs/version-0.5.4/reference/lang/types/types.md +++ /dev/null @@ -1,1381 +0,0 @@ -# Type System - -This document describes the type system of KCL, including: - -- Type rules -- Type checking -- Type conversion -- Type inference - -## Type Rules - -### Basic Definition - -#### Assertion - -All free variables of $S$ are defined in $\Gamma$ - -$$ -\Gamma \vdash S -$$ - -$\Gamma$ is a variable's well-formed environment, such as $x_1:T_1$, ..., $x_n:T_n$ - -The assertion of $S$ has three forms: - -**Environment assertion** indicates that $\Gamma$ is a well-formed type. - -$$ -\Gamma \vdash ◇ -$$ - -**Well-formed type assertion**. In the environment $\Gamma$, $nat$ is a type expression. - -$$ -\Gamma \vdash nat -$$ - -**Typing judgment assertion**. In the environment $\Gamma$,$E$ has the type $T$. - -$$ -\Gamma \vdash E: T -$$ - -#### Inference Rules - -Representation - -$$ -\frac{\Gamma \vdash S_1, ..., \Gamma \vdash S_n}{\Gamma \vdash S} -$$ - -In the inference rules, $u$, $v$, and $w$ are used to represent variables, $i$, $j$, $k$ are used to represent integers, $a$ and $b$ are used to represent floating point numbers, $s$ is used to represent strings, $c$ is used to represent literal values of constants (integers, floating point numbers, strings, boolean), $f$ is used to represent functions, $T$, $S$, $U$ are used to represent types. - -## Environment Rules - -Env ⌀ - -$$ -\frac{}{⌀ \vdash ◇ } -$$ - -## Type Definitions - -Type Bool - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash boolean} -$$ - -Type Int - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash integer} -$$ - -Type Float - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash float} -$$ - -Type String - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash string} -$$ - -Type Literal - -$$ -\frac{ c \in \{boolean, integer, float, string\}}{\Gamma \vdash literalof(c)} -$$ - -Type List - -$$ -\frac{\Gamma \vdash T \ T \neq Void}{\Gamma \vdash listof(T) } -$$ - -Type Dict - -$$ -\frac{\Gamma \vdash T_1 \ \Gamma \vdash T_2\ T_1 \neq Void \ \ T_2 \neq Void}{\Gamma \vdash dictof(T_k=T_1, T_v=T_2)} -$$ - -Type Struct - -$$ -\frac{\Gamma \vdash T_{1} \ ... \ \Gamma \vdash T_{n} \ \ T_i \neq Void \ K_1 \neq K_n}{\Gamma \vdash structof(K_1 : T_{1}, ... , K_n : T_{n})} -$$ - -Type Union - -$$ -\frac{\Gamma \vdash T_1 \ ... \ \Gamma \vdash T_n \ \ T_i \neq Void}{\Gamma \vdash unionof(T_1, ..., T_n)} -$$ - -Type None - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash None} -$$ - -Type Undefined - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Undefined} -$$ - -Type Void - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Void} -$$ - -Type Any - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Any} -$$ - -Type Nothing - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Nothing} -$$ - -## Typing Judgment Rules - -### Operand Expr - -Exp Truth - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash true: boolean} -$$ - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash false: boolean} -$$ - -Exp Int - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash int: integer} -$$ - -Exp Flt - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash flt: float} -$$ - -Exp Str - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash str: string} -$$ - -Exp None - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash none: none} -$$ - -Exp Undefined - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash undefined: undefined} -$$ - -Expr ListExp - -$$ -\frac{\Gamma \vdash E_1: T_1 \ E_2: T_2 \ ... \ E_n: T_n}{\Gamma \vdash [E_1, E_2, ..., E_n]: listof \ sup(T_1, T_2, ..., T_n)} -$$ - -Expr ListComp - -$$ -\frac{\Gamma \vdash E_1: T_1 \ \Gamma \vdash v: T \ \Gamma \vdash E_2: listof \ T \ \Gamma \vdash E_3: boolean}{\Gamma \vdash [E_1 \ for \ v \ in \ E_2 \ if \ E_3]: listof(T_1) } -$$ - -Expr DictExp - -$$ -\frac{\Gamma \vdash E_{k1}: T_{k1} \ \Gamma \vdash E_{v1}: T_{v1} \ ... \ \Gamma \vdash E_{kn}: T_{kN} \ \Gamma \vdash E_{vn}: T_{vN}}{\Gamma \vdash \{E_{k1}: E_{v1}, ..., E_{{kn}}: E_{vn}\}: dictof(T_{k}=sup(T_{k1}, T_{k2}, ... T_{kn}), \ T_{v}=sup(T_{v1}, T_{v2}, ..., T_{vn}))} -$$ - -Expr DictComp - -$$ -\frac{\Gamma \vdash E_1: T_{rki} \ \Gamma \vdash E_2: T_{rvi} \ \Gamma \vdash v_1: T_k \ \Gamma \vdash v_2: T_v \ \Gamma \vdash E_3: dictof(T_{k}, \ T_{v}) \ \Gamma \vdash E_4: boolean}{\Gamma \vdash \{E_1:E_2 \ for \ (v_1, v_2) \ in \ E_3 \ if \ E_4\}: dictof(T_{k}=sup(T_{rk1}, T_{rk2}, ..., T_{rkn}), T_{v}=sup(T_{rv1}, T_{rv2}, ..., T_{rvn})) } -$$ - -Expr StructExpr - -$$ -\frac{\Gamma \vdash E_{1}: T_{1} \ ... \ \Gamma \vdash E_{n}: T_{n} \ K_1 \neq K_n}{\Gamma \vdash \{K_{1} = E_{1}, ..., K_{{n}} = E_{n}\}: structof(K_1 : T_{1}, ... , K_n : T_{n})} -$$ - -The literal type is the value type of basic type, the union type is the combination type of types, void, any, nothing are special type references, and there is no direct value expression correspondence. - -### Primary Expr - -Expr Index - -$$ -\frac{\Gamma \vdash E: listof(T) \ \Gamma \vdash Index: integer}{\Gamma \vdash E[Index]: T} -$$ - -Expr Call - -$$ -\frac{\Gamma \vdash E_1: T_1 \rightarrow T_2 \ \Gamma \vdash E_2: T_1}{\Gamma \vdash E_1 \ (E_2): T_2} -$$ - -Expr List Selector - -$$ -\frac{\Gamma \vdash E: listof(T) \ \Gamma \vdash Index: integer}{\Gamma \vdash E.[Index]: T} -$$ - -Expr Dict Selector - -$$ -\frac{\Gamma \vdash E: dictof(T_k = T_1, T_v=T_2) \ \Gamma \vdash S_1: string \ ... \ \Gamma \vdash S_n: string}{\Gamma \vdash E.\{S_1, ..., S_n\}: dictof(T_k = T_1, T_v=T_2)} -$$ - -Expr Struct Selector - -$$ -\frac{\Gamma \vdash E: structof(K_1 : T_{1}, ... , K_n : T_{n}) \ \Gamma \vdash K_i: string}{\Gamma \vdash E.K_i: T_{i}} -$$ - -### Unary Expr - -Expr + - -$$ -\frac{\Gamma \vdash E: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash \ +E: T} -$$ - -Expr - - -$$ -\frac{\Gamma \vdash E: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash \ -E: T} -$$ - -Expr ~ - -$$ -\frac{\Gamma \vdash E: integer}{\Gamma \vdash \ ~E: integer} -$$ - -Expr not - -$$ -\frac{\Gamma \vdash E: boolean}{\Gamma \vdash \ not \ E: boolean} -$$ - -### Binary Expr - -Expr op, op $\in$ {-, /, %, \*\*, //} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash E_1 \ op \ E_2: T} -$$ - -Expr + - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, float, string, listof(T_1)\}}{\Gamma \vdash E_1 \ + \ E_2: T} -$$ - -Expr \* - -$$ -\frac{\Gamma \vdash E_1: T_1 \ \ \ \Gamma \vdash E_2: T_2 \ \ \ \ (T_1==T_2 \in \{integer, float\}) \ or \ (T_1 == interger \ and \ T_2 \ \in \ \{string, listof(T_3)\}) \ or \ (T_2 == interger \ and \ T_1 \ \in \ \{string, listof(T_3)\})} {\Gamma \vdash E_1 \ * \ E_2: T} -$$ - -Expr % - -$$ -\frac{\Gamma \vdash E_1: interger \ \ \ \Gamma \vdash E_2: integer}{\Gamma \vdash E_1 \ \% \ E_2: interger} -$$ - -Expr op, op $\in$ \{or, and\} - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ op \ E_2: boolean} -$$ - -示例 - -Expr and - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ and \ E_2: boolean} -$$ - -Expr op, op $\in$ \{==, !=, <, >, <=, >=\} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T}{\Gamma \vdash E_1 \ op \ E_2: boolean} -$$ - -Expr > - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ > \ E_2: boolean} -$$ - -Expr op, op $\in$ {&, ^, ~, <<, >>} - -$$ -\frac{\Gamma \vdash E_1: integer \ \ \ \Gamma \vdash E_2: integer}{\Gamma \vdash E_1 \ op \ E_2: integer} -$$ - -Expr | - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, listof(T_1), dictof(T_k, T_v), structof(K_1=T_1, ..., K_n=T_n)\}}{\Gamma \vdash E_1 \ | \ E_2: T} -$$ - -Expr op, op $\in$ {in, not in} - -$$ -\frac{\Gamma \vdash E_1: string \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{dictof, structof\}}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: listof(S), T \sqsubseteq S}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -Expr op $\in$ {is, is not} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -### IF Expr - -Expr If - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: T \ \ \ \Gamma \vdash E_3: T}{\Gamma \vdash if \ E_1 \ then \ E_2 \ else \ E_3: T} -$$ - -### Stmt - -Stmt If - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash S_1: Void \ \ \ \Gamma \vdash S_2: Void}{\Gamma \vdash if \ E_1 \ then \ S_1 \ else \ S_2: Void} -$$ - -Stmt Assign - -$$ -\frac{\Gamma \vdash id: T_0 \ \ \ \Gamma \vdash T_1 \ \ \ \Gamma \vdash E: T_2}{\Gamma \vdash id: T_1 \ = \ E : Void} -$$ - -Type Alias - -$$ -\frac{\Gamma \vdash id: T_0 \ \ \ \Gamma \vdash T_1}{\Gamma \vdash type \ id \ = \ T_1 : Void} -$$ - -## Union - -List Union - -$$ -\frac{\Gamma \vdash \ listof(T) \ \ \ \Gamma \vdash \ listof(S)}{\Gamma \vdash \ listof(unionof(T, S))} -$$ - -Dict Union - -$$ -\frac{\Gamma \vdash \ dictof(T_1, T_2) \ \ \ \Gamma \vdash \ dictof(S_1, S_2)}{\Gamma \vdash \ dictof(unionof(T_1, S_1), unionof(T_2, S_2))} -$$ - -Struct Union - -Define two structures: $structof(K_{1}: T_{1}, ..., K_{n}: T_{n}),structof(H_{1}: S_{1}, ..., H_{m}: S_{n})$ - -Define their union types: - -$$ -structof(J_{1}: U_{1}, ..., J_{p}: U_{n}) = structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \bigcup structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) -$$ - -Example - -$$ -structof() \ \bigcup \ structof(H_{1}: T_{1}, ..., H_{m}: T_{n}) = structof(H_{1}: T_{1}, ..., H_{m}: T_{n}) -$$ - -$$ -structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \ \bigcup \ structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) = structof(K_1: T_1) :: (structof(K_{2}: T_{2}, ..., K_{n}: T_{n}) \ \bigcup \ structof(H_{1}: S_{1}, ..., H_{m}: S_{n})) -$$ - -where "::" denotes the operation of adding a dual to a structure, which is defined as follows: - -$$ -structof(K_{1}: T_{1}) :: structof() = structof(K_{1}: T_{1}) -$$ - -$$ -structof(K_{1}: T_{1}) :: structof(K_{1}: T_{1}', ..., K_n: T_{n}) = structof(K_{1}: union\_op(T_{1}, T_{1}'), ..., K_{n}: T_{n}) -$$ - -$$ -structof(K_{1}: T_{1}) :: structof(K_{2}: T_{2}, ..., K_n: T_{n}) = structof(K_{2}: T_2) :: structof(K_{1}: T_1) :: structof(K_{3}: T_3, ..., K_{n}: T_{n}) -$$ - -Based on this, the union of two structures is defined as: - -$$ -\frac{\Gamma \vdash structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \ \Gamma \vdash structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) \ structof(J_{1}: U_{1}, ..., J_{p}: U_{n}) = structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \bigcup structof(H_{1}: S_{1}, ..., H_{m}: S_{n})}{\Gamma \vdash structof(J_{1}: U_{1}, ..., J_{p}: U_{n}))} -$$ - -where $union\_op(T_1, T_2)$ denotes different types of judgment operations for the same $K_i$. - -- When $T_1$ and $T_2$ have the partial order relation. If $T_1 \sqsubseteq T_2$, return $T_2$, otherwise return $T_1$, which is the minimum upper bound -- When $T_1$ and $T_2$ have no partial order relationship, there are three optional processing logic: - - Structure union failed, return a type error. - - Return the type of the latter $T_2$. - - Return the type $unionof (T_1, T_2)$. - -Here, we need to choose the appropriate processing method according to the actual needs. - -Structure inheritance can be regarded as a special union. The overall logic is similar to that of union, but in $union\_op(T_1, T_2)$ for the same $K_i$, the different types of judgment operations are as follows: - -- When $T_1$ and $T_2$ have the partial order relation and $T_1 \sqsubseteq T_2$, return $T_1$, that is, only if $T_1$ is the lower bound of $T_2$, the lower bound of $T_1$ shall prevail. -- Otherwise, a type error is returned. - -Through such inheritance design, we can achieve hierarchical, bottom-up and layer-by-layer contraction of type definition. - -## Operation - -KCL supports operations on structure attributes in the form of $p op E$. That is, for the given structure $A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})$, the path $p$ in the structure is specified with the value of $E$ (such as union, assign, insert, etc.). - -Define the following update operations: - -$$ -\frac{{\Gamma\vdash A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})}  {\Gamma\vdash p \in (K_{1}, ..., K_{n})} \ {\Gamma\vdash e:T}   k \neq k_1, ..., k \neq k_n} -{ A \{p \ op \ e\}:\{K_1:T_1, ..., K_n:T_n\}∪\{p:T\}} -$$ - -That is to say, the operation on the path $p$ is essentially a union of two structures. The rules for the same name attribute type union depend on the situation. For example, the path $p$ is an identifier $p=k_1$ that can be used as a field name $k_1$, and the field name in structure A is also $k_1$, its type is $T_1$, and the type of the expression $e$ is also $T_1$, then - -$$ -\frac{{\Gamma\vdash A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})}  {\Gamma\vdash p = K_{1}} \ {\Gamma\vdash e:T_1}   k \neq k_1, ..., k \neq k_n} -{ A \{p \ op \ e\}:\{K_1:T_1, ..., K_n:T_n\}} -$$ - -Note: - -- The type $T_1$ of the expression $e$ have the same type with the original attribute of the same name $K_1$. It can be relaxed appropriately according to the actual situation, such as the type of $e$ $\sqsubseteq T_1$ is enough. -- For the operation of nested multi-layer structures, the above rules can be used recursively. - -## Type Partial Order - -### Basic Types - -$$ -Type \ T \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ T -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Bool \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Int \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Float \sqsubseteq Type \ Any -$$ - -$$ -Type \ Int \sqsubseteq Type \ Float -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ String \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Literal \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ List \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Dict \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Struct \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ None \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Void \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Any -$$ - -### Literal Type - -$$ -Type \ Literal(Bool) \sqsubseteq Type \ Bool -$$ - -$$ -Type \ Literal(Int) \sqsubseteq Type \ Int -$$ - -$$ -Type \ Literal(Float) \sqsubseteq Type \ Float -$$ - -$$ -Type \ Literal(String) \sqsubseteq Type \ String -$$ - -### Union Type - -$$ -Type \ X \sqsubseteq Type \ Union(X, Y) -$$ - -### Introspect - -$$ -Type \ X \sqsubseteq Type \ X -$$ - -Example - -$$ -Type \ Bool \sqsubseteq Type \ Bool -$$ - -$$ -Type \ Int \sqsubseteq Type \ Int -$$ - -$$ -Type \ Float \sqsubseteq Type \ Float -$$ - -$$ -Type \ String \sqsubseteq Type \ String -$$ - -$$ -Type \ List \sqsubseteq Type \ List -$$ - -$$ -Type \ Dict \sqsubseteq Type \ Dict -$$ - -$$ -Type \ Struct \sqsubseteq Type \ Struct -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Nothing -$$ - -$$ -Type \ Any \sqsubseteq Type \ Any -$$ - -$$ -Type \ Union(Type Int, Type Bool) \sqsubseteq Type \ Union(Type Int, Type Bool) -$$ - -### Transmit - -$$ -Type \ X \sqsubseteq Type \ Z \ if \ Type \ X \sqsubseteq Type \ Y \ and \ Type \ Y \sqsubseteq \ Type \ Z -$$ - -### Contained - -$$ -Type \ List(T_1) \sqsubseteq Type \ List(T_2) \ if \ T_1 \sqsubseteq T_2 -$$ - -$$ -Type \ Dict(T_{k1}, T_{v1}) \sqsubseteq Type \ Dict(T_{k2}, T_{v2}) \ if \ T_{k1} \sqsubseteq T_{k2} \ and \ T_{v1} \sqsubseteq T_{v1} -$$ - -$$ -Type \ Structure(K_1: T_{a1}, K_2: T_{a2}, ..., K_n: T_{an}) \sqsubseteq Type \ Structure(K_1: T_{b1}, K_2: T_{b2}, ..., K_n: T_{bn}) \ if \ T_{a1} \sqsubseteq T_{b1} \ and \ T_{a2} \sqsubseteq T_{b2} \ and \ ... \ and \ T_{an} \sqsubseteq T_{bn} -$$ - -### Inheritance - -$$ -Type \ Struct \ A \sqsubseteq Type \ Struct \ B \ if \ A \ inherits \ B -$$ - -### None - -$$ -Type \ None \sqsubseteq Type \ X, X \notin \{Type \ Nothing, \ Type \ Void\} -$$ - -### Undefined - -$$ -Type \ Undefined \sqsubseteq Type \ X, X \notin \{Type \ Nothing, \ Type \ Void\} -$$ - -## Equality - -- Commutative law - -$$ -Type \ Union(X, Y) == Type \ Union(Y, X) -$$ - -Example - -$$ -Type \ Union(Int, Bool) == Type \ Union(Bool, Int) -$$ - -- Associative law - -$$ -Type \ Union(Union(X, Y), Z) == Type \ Union(X, Union(Y, Z)) -$$ - -Example - -$$ -Type \ Union(Union(Int, String), Bool) == Type \ Union(Int, Union(String, Bool)) -$$ - -- Idempotent - -$$ -Type \ Union(X, X) == Type \ X -$$ - -Example - -$$ -Type \ Union(Int, Int) == Type \ Int -$$ - -Partial order derivation - -$$ -Type \ Union(X, Y) == Type \ Y \ if \ X \sqsubseteq Y -$$ - -Example - -Assume that Struct A inherits Struct B - -$$ -Type \ Union(A, B) == Type \ B -$$ - -Idempotency is a special case of partial order reflexivity - -### List - -$$ -Type \ List(X) == Type \ List(Y) \ if \ X == Y -$$ - -### Dict - -$$ -Type \ Dict(T_k, T_v) == Type \ Dict(S_k, S_v) \ if \ T_k == S_k \ and \ T_v == S_v -$$ - -### Struct - -$$ -Type \ Struct(K_1: T_{1}, K_2: T_{2}, ..., K_n: T_{n}) == Type \ Struct(K_1: S_{1}, K_2: S_{2}, ..., K_n: S_{n}) \ if \ T_{1} == S_{1} \ and \ ... \ and \ T_{n} == S_{n} -$$ - -### Partial Order Checking - -$$ -Type \ X == Type \ Y \ if \ Type \ X \sqsubseteq Type \ Y \ and \ Type \ Y \sqsubseteq \ Type \ X -$$ - -## Basic Methods - -- `sup(t1: T, t2: T) -> T`: Calculate the minimum upper bound of two types `t1` and `t2` according to the type partial order. The union type needs to be created dynamically. -- `typeEqual(t1: T, t2: T) -> bool`: Compare whether the two types `t1` and `t2` are equal. -- `typeToString(t: T) -> string`: Resolve and convert the type to the corresponding string type recursively from top to bottom. - -### Sup Function - -- Type parameters, condition types and other characteristics are not considered temporarily. -- Use an ordered collection to store all types of `UnionType`. -- Use a global map to store all generated union types according to the name of `UnionType`. -- Calculate the inclusion relationship between types according to the partial order relationship. - -```go -// The Sup function returns the minimum supremum of all types in an array of types -func Sup(types: T[]) -> T { - typeOf(types, removeSubTypes=true) -} - -// Build a sup type from types [T1, T2, ... , Tn] -func typeOf(types: T[], removeSubTypes: bool = false) -> T { - assert isNotNullOrEmpty(types) - // 1. Initialize an ordered set to store the type array - typeSet: Set[T] = {} - // 2. Add the type array to the ordered set for sorting by the type id and de-duplication - addTypesToTypeSet(typeSet, types) - // 3. Remove sub types according to partial order relation rules e.g. sub schema types - if removeSubTypes { - removeSubTypes(typeSet) - } - if len(typeSet) == 1 { - // If the typeSet has only one type, return it - return typeSet[0] - } - // 4. Get or set the union type from the global union type map - id := getIdentifierFromTypeSet(typeSet) - unionType := globalUnionTypeMap.get(id) - if !unionType { - unionType = createUnionType(typeSet) // Build a new union type - globalUnionTypeMap.set(id, unionType) - } - return unionType -} - -// Add many types into the type set -func addTypesToTypeSet(typeSet: Set[T], types: T[]) -> void { - for type in types { - addTypeToTypeSet(typeSet, type) - } -} - -// Add one type into the type set -func addTypeToTypeSet(typeSet: Set[T], type: T) -> void { - if isUnion(type) { - return addTypesToTypeSet(typeSet, toUnionOf(type).types) - } - // Ignore the void type check - if !isVoid(type) { - // De-duplication according to the type of id - typeSet.add(type) - } -} - -func removeSubTypes(types: Set[T]) -> void { - for source in types { - for target in types { - if !typeEqual(source, target) { - // If the two types have an inheritance relationship, the base class is retained, or if the two types have a partial order relationship according to the relation table. - if (isPartialOrderRelatedTo(source, target)) { - types.remove(source) - } - } - } - } -} - -// isPartialOrderRelatedTo function Determine whether two types have a partial order relationship `source \sqsubseteq target` -// according to the partial order relationship table and rules -func isPartialOrderRelatedTo(source: T, target: T) -> bool { - assert isNotNullOrEmpty(source) - assert isNotNullOrEmpty(target) - if isNoneOrUndefined(source) and !isNothing(target) and !isVoid(target) { - return true - } - if isAny(target) { - return true - } - if typeEqual(source, target) { - return true - } - if isUnion(target) and source in target.types { - return true - } - // Literal Type - if (isStringLiteral(source) and isString(target)) or \ - (isBooleanLiteral(source) and isBool(target)) or \ - (isIntLiteral(source) and isInt(target)) or \ - (isFloatLiteral(source) and isFloat(target)) { - return true - } - if isInt(source) and isFloat(target) { - return true - } - if isList(source) and isList(target) { - return isPartialOrderRelatedTo(toListOf(source).eleType, toListOf(target).eleType - } - if isDict(source) and isDict(target) { - return isPartialOrderRelatedTo(toDictOf(source).keyType, toDictOf(target).keyType) and isPartialOrderRelatedTo(toDictOf(source).valueType, toDictOf(target).valueType) - } - if isStruct(source) and isStruct(target) { - if isTypeDerivedFrom(source, target) { - return true - } - // Empty Object - if len(target.keys) == 0 { - return true - } - if any([key Not in source.keys for key in target.keys]) { - return false - } - for key, sourceType in (source.keys, source.types) { - targetType = getKeyType(target, key) ? getKeyType(target, key) : anyTypeOf() - if !isPartialOrderRelatedTo(sourceType, targetType) { - return false - } - } - return true - } - return false -} -``` - -## Type Checking - -### Checker - -The type checker traverses the syntax tree from top to bottom through syntax-directed translation, and determines whether the program structure is a well-typed program according to context-sensitive training rules. - -The type checker depends on type rules, and the information of type environment $\Gamma$ is recorded in the symbol table. Use abstract syntax for type expressions, such as `listof (T)`. When the type check fails, a type mismatch error is generated, and the error message is generated according to the syntax context. - -### Basic Methods - -1. `isUpperBound(t1, t2): supUnify(t1, t2) == t2` -2. `supUnify(t1, t2):` - -- For the foundation type, `sup(t1, t2)` is calculated according to the partial order relationship -- For list, dict, Struct, recursively `supUnify` the types of elements -- When there is no partial order relationship, return `Nothing` - -### Checking Logic - -#### Operand Expr - -$D \to id: T$ - -``` -env.addtype(id.entry, T.type) -``` - -$T \to boolean$ - -``` -T.type = boolean -``` - -$T \to integer$ - -``` -T.type = integer -``` - -$T \to float$ - -``` -T.type = float -``` - -$T \to string$ - -``` -T.type = string -``` - -$T \to c, \ c \in \{boolean, integer, float, string\}$ - -``` -T.type = literalof(c) -``` - -$T \to None$ - -``` -T.type = None -``` - -$T \to Undefined$ - -``` -T.type = Undefined -``` - -$T \to \ [T_1]$ - -``` -T.type = listof (T1.type) -``` - -$T \to { \{T_1: T_2\} }$ - -``` -T.type = dictof (T1.type: T2.type) -``` - -$T \to { \{N_1: T_1, N2: T_2, ..., N_n: T_n\} }$ - -``` -T.type = structof (N1: T1.type, N2: T2.type, ..., Nn: Tn.type) -``` - -$E \to id$ - -``` -E.type = env.lookup(id.entry) -``` - -$E \to [E_1, E_2, ..., E_n]$ - -``` -func listExpr(E) { - supe = sup([e.type for e in E]]) - E.type = listof(type) -} -``` - -$E \to [E_1 \ for \ E_2 \ in \ E_3 \ if \ E_4]$ - -``` -func listComp(E) { - if !typeEqual(E4.type, boolean) { - raise type_error - } - if !isUpperBound(listof(Any), E3.type) { - raise type_error(E) - } - if !isUpperBound(E3.type, E2.type) { - raise type_error(E) - } - E.type = listof(E1.type) -} -``` - -$E \to \{E_{k1}: E_{v1}, ..., E_{kn}: E_{vn}\}$ - -``` -func dictExpr(E) { - supk := sup([e.type for e in E.keys()]]) - supv := sup([e.type for e in E.values()]]) - E.type = dictof(supk, supv) -} -``` - -$E \to \{E_1:E_2 \ for \ (E_3, E_4) \ in \ E_5 \ if \ E_6\}$ - -``` -func dictComp(E) { - if !typeEqual(E6.type, boolean) { - raise type_error(E) - } - if !isUpperBound(dictof(Any, Any), E5.type) { - raise type_error(E) - } - if !isUpperBound(E5.type, dictof(E3.type, E4.type)) { - raise type_error(E) - } - E.type = dictof(E1.type, E2.type) -} -``` - -$E \to \{E_{k1}: E_{v1}, ..., E_{kn}: E_{vn}\}$ - -``` -func dictExpr(E) { - supk := sup(Ek1, ..., Ekn) - supv = sup(Ev1, ..., Evn) - E.type = dictof(supk, supv) -} -``` - -$E \to \{N_{1} = E_{1}, ..., N_{{n}} = E_{n}\}$ - -``` -func structExpr(E) { - Struct = structof() - for n, e in E { - Struct.add(n, e.type) - } - E.type = Struct -} -``` - -#### Primary Expr - -$E \to E_1[E_2]$ - -``` -func sliceSuffix(E) { - if !isUpperBound(listof(Any), E.E1.type) { - raise type_error(E) - } - if typeEqual(E.E2.type, integer) { - raise type_error(E) - } - E.type = E.E1.type.eleType -} -``` - -$E \to E_1(E_2)$ - -``` -func callSuffix(E) { - if !typeEqual(E.E1.type, func) { - raise type_error(E) - } - if !isUpperBound(listof(E.E1.arguType), E.E2.type) { - raise type_error(E) - } - E.type = E.E1.returnType -} -``` - -#### Unary Expr - -According to the reasoning rules of each binocular operator, take `+` as an example. - -$E \to + E_1$ - -``` -func Plus(E) { - if !typeEqual(E.E1.type, [integer, float]) { - raise type_error(E) - } - E.type = E.E1.type -} -``` - -#### Binary Expr - -According to the reasoning rules of each binocular operator, take `%` as an example. - -$E \to E_1 \ % \ E_2$ - -``` -func Mod(E) { - if !(typeEqual(E.E1.type, [integer, float]) && typeEqual(E.E2.type, [integer, float])) { - raise type_error(E) - } - E.type = E.E1.type -} -``` - -#### IF Binary Expr - -$E \to if E_1 \ then \ E_2 else \ E_3$ - -``` -func ifExpr(E) { - if !typeEqual(E.type, boolean) { - raise type_error(E) - } - if !typeEqual(E_2.type, E_3.type) { - raise type_error(E) - } - E.type = E_2.type -} -``` - -#### Stmt - -$S \to if \ E \ then \ S_1 \ else \ S_2$ - -``` -func ifStmt(S) { - if !typeEqual(S.E.type, boolean) { - raise type_error(E) - } - if !typeEqual(S.S1.type, S.S2.type) { - raise type_error(E) - } - S.type = S.S1.type -} -``` - -$S \to id: T = E$ - -$S \to id = T E$ - -``` -func assignStmt(S) { - tpe := env.lookup(id.entry) - if tpe != nil && tpe != S.T { - raise type_error(E) - } - if isUpperBound(tpe, E.type) { - raise type_error(E) - } - env.addtype(id.entry, T.type) -} -``` - -## Type Conversion - -### Basic Definition - -Through syntax-directed translation, the value types involved in the operation are automatically converted according to the operator characteristics. - -### Conversion Rules - -$E \to E_1 \ op \ E_2, , op \in \{+, -, *, /, \%, **, //\}$ - -``` -func binOp(E) { - if E.E1.type == integer and E.E2.type == integer { - E.type = integer - } else if E.E1.type == integer and E.E2.type == float { - E.type = float - } else if E.E1.type == float and E.E2.type == integer { - E.type = float - } else if E.E1.type == float and E.E2.type == float { - E.type = float - } -} -``` - -## Type Inference - -### Basic Definition - -- Type rule derivation and type reconstruction in case of incomplete type information -- Derive and reconstruct the data structure types in the program from the bottom up, such as basic type, e.g., list, dict and struct types. - -### Basic Methods - -1. `typeOf(expr, subst)`: The input is the expression and substitution rule set, and the type of expr and the new substitution rule set are returned. -2. `unifier(t1, t2, subst, expr)`: Try substitution with `t1=t2`. If the substitution is successful (no occurrence and no conflict), add `t1=t2` to the subst and return the subst. Otherwise, an error has occurred or there is a conflict. - -### Inferential Logic - -$E \to id = E_1$ - -``` -func assignExpr(E, subst) { - return unifier(E.id.type, E.E_1.type, subst, E) -} -``` - -$unifier(t1, t2, subst, expr) \rightarrow subst$ - -``` -func unifier(t1, t2, subst, expr) { - t1 = applySubstToTypeEquation(t1, subst) - t2 = applySubstToTypeEquation(t2, subst) - - if t1 == t2 { - return subst - } - - if isTypeVar(t1) { - if isNoOccur(t1, t2) { - addTypeEquationToSubst(subst, t1, t2) - return subst - } else { - raise occurrence_violation_error(t1, t2, expr) - } - } - - if isTypeVar(t2) { - if isNoOccur(t2, t1) { - addTypeEquationToSubst(subst, t2, t1) - return subst - } else { - raise occurrence_violation_error(t2, t1, expr) - } - } - - if isList(t1) and isList(t2) { - return unifier(toListOf(t1).eleType, toListOf(t2).eleType, subst, expr) - } - if isDict(t1) and isDict(t2) { - dict1of := toDictOf(t1) - dict2of := toDictOf(t2) - subst = unifier(dict1of.keyType, dict2of.keyType, subst, expr) - subst = unifier(dict1of.valueType, dict2of.valueType, subst, expr) - return subst - } - if isStruct(t1) and isStruct(t2) { - Struct1of := tostructof(t1) - Struct2of := tostructof(t2) - for key, _ in Struct1of { - subst = unifier(t1[key].type, t2[key].type, subst, expr) - } - return subst - } - - raise unification_error(t1, t2, expr) -} - -func applySubstToTypeEquation(t, subst) { - // walks through the type t, replacing each type variable by its binding in the substitution -σ. If a variable is Not bound in the substitution, then it is left unchanged. - if isBasicType(t) { - return t - } - if isList(t) { - return listOf(applySubstToTypeEquation(toListOf(t).eleType, subst)) - } - if isDict(t) { - dictof := toDictOf(t) - kT := applySubstToTypeEquation(dictof.keyType, subst) - vT := applySubstToTypeEquation(dictof.valueType, subst) - return dictOf(kT, vT) - } - if isStruct(t) { - structof := tostructof(t) - s := structof() - for key, type in Struct1of { - kT := applySubstToTypeEquation(type, subst) - s.add(key, kT) - } - return s - } - if hasTypeVar(t) { - for tvar in t.vars { - if tvar in subst { - *tvar = subst[tvar] - } - } - } - return t -} - -func addTypeEquationToSubst(subst, tvar, t) { - // takes the substitution σ and adds the equation tv = t to it - for _, t in subst { - for tvar in t.vars { - tmp := applyOneSubst(tsvar, tvar, t) - *tvar = tmp - } - } - subst.add(tvar, t) -} - -func applyOneSubst(t0, tvar, t1) { - // substituting t1 for every occurrence of tv in t0. - if isBasicType(t0) { - return t0 - } - if isList(t0) { - return listOf(applyOneSubst(toListOf(t).eleType, tvar, t1)) - } - if isDict(t0) { - dictof := toDictOf(t) - kT := applyOneSubst(dictof.keyType, tvar, t1) - vT := applyOneSubst(dictof.valueType, tvar, t1) - return dictOf(kT, vT) - } - if isStruct(t0) { - structof := tostructof(t) - s := structof() - for key, type in Struct1of { - kT := applyOneSubst(type, tvar, t1) - s.add(key, kT) - } - return s - } - if t0 == tvar { - return t1 - } - return t0 -} - -func isNoOccur(tvar, t) { - // No variable bound in the substitution occurs in any of the right-hand sides of the substitution. - if isBasicType(t) { - return true - } - if isList(t) { - return isNoOccur(tvar, toListOf(t).eleType) - } - if isDict(t) { - dictof := toDictOf(t) - return isNoOccur(tvar, dictof.keyType) and isNoOccur(tvar, dictof.valueType) - } - if isStruct(t) { - structof := tostructof(t) - noOccur := true - for _, type in structof { - noOccur = noOccur and isNoOccur(tvar, type) - } - return noOccur - } - return tvar != t -} -``` - -### Example - -#### Normal Inference - -``` -T : { - a = 1 - b = "2" - c = a * 2 - d = { - d0 = [a, c] - } -} - -x: T = { - a = 10 -} -``` - -#### Occurrence Violation Error - -``` -T = { - a = a -} -``` - -#### Type Unification Error - -``` -T : { - a = 1 -} - -T : { - a = "1" -} -``` - -## Reference - -- [https://en.wikipedia.org/wiki/Type_system](https://en.wikipedia.org/wiki/Type_system) -- Pierce, Benjamin C. (2002). Types and Programming Languages. MIT Press. -- [https://www.cs.cornell.edu/courses/cs4110/2010fa/](https://www.cs.cornell.edu/courses/cs4110/2010fa/) -- [https://www.typescriptlang.org/docs/handbook/basic-types.html](https://www.typescriptlang.org/docs/handbook/basic-types.html) -- [https://www.typescriptlang.org/docs/handbook/advanced-types.html](https://www.typescriptlang.org/docs/handbook/advanced-types.html) diff --git a/versioned_docs/version-0.5.4/reference/model/_category_.json b/versioned_docs/version-0.5.4/reference/model/_category_.json deleted file mode 100644 index 398617be..00000000 --- a/versioned_docs/version-0.5.4/reference/model/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "System Package", - "position": 2 -} diff --git a/versioned_docs/version-0.5.4/reference/model/base64.md b/versioned_docs/version-0.5.4/reference/model/base64.md deleted file mode 100644 index 3f6e617b..00000000 --- a/versioned_docs/version-0.5.4/reference/model/base64.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: "base64" -linkTitle: "base64" -type: "docs" -description: base64 system module - base64 encode and decode function -weight: 100 ---- - -## encode - -`encode(value: str, encoding: str = "utf-8") -> str` - -Encode the string `value` using the codec registered for encoding. - -## decode - -`decode(value: str, encoding: str = "utf-8") -> str` - -Decode the string `value` using the codec registered for encoding. diff --git a/versioned_docs/version-0.5.4/reference/model/builtin.md b/versioned_docs/version-0.5.4/reference/model/builtin.md deleted file mode 100644 index 4bb34766..00000000 --- a/versioned_docs/version-0.5.4/reference/model/builtin.md +++ /dev/null @@ -1,386 +0,0 @@ ---- -title: "builtin" -sidebar_position: 1 ---- - -KCL provides a list of built-in functions that are automatically loaded and can be used directly without providing any module name. For example, `print` is a function provided by a widely used built-in module. - -## Type Conversion Functions - -KCL's `bool`, `int`, `float`, `str`, `list`, `dict` and other types have built-in conversion functions of the same name. Among them, `int` can not only be used to truncate floating-point numbers, but also can be used to convert strings to integers (decimal when parsing, other values can also be specified). - -The following are common uses of type-related functions: - -```py -b1 = bool(1) # true -b2 = bool(1.5) # true -b3 = bool("true") # true -b4 = bool("") # false -b5 = bool([]) # false -b6 = bool({}) # false - -i1 = int("11") # 11 -i2 = int("11", base=8) # 9 -i3 = int("11", base=2) # 3 - -f1 = float(1) # 1.0 -f2 = float("1.5") # 1.5 - -s1 = str(1) # 1 - -l1 = list([1, 2, 3]) -``` - -## String Builtin Member Functions - -- [String Spec](/docs/reference/lang/spec/datatypes) - -## print - -`print(*args:any, end:str='\n')` - -The built-in print function, which provides different types of variable parameter printing, adds a newline at the end by default. The following are common usages: - -```python -print("hello KCL") -print() -print(None, end=':') -print(None) -print(True) -print(False) -print(123) -print(123.0) -print('abc ${123}') -print("abc ${456}") -print([1,'a', True]) -print(1,'a', True) -print({}) -print({a: 123}) -``` - -The output is: - -```shell -hello KCL - -None:None -True -False -123 -123.0 -abc 123 -abc 456 -[1, 'a', True] -1 a True -{} -{'a': 123} -``` - -If you do not want the default newline, you can re-specify the ending string with the `end=''` named parameter. - -```python -print("Hello KCL", end='') -``` - -## multiplyof - -`multiplyof(a:int, b:int) -> bool` - -Check whether the integer `a` is an integer multiple of `b`, and return a boolean value: - -```python -print(multiplyof(2, 1)) # True -print(multiplyof(1, 2)) # False -print(multiplyof(0, 1)) # True -print(multiplyof(0, 2)) # True -print(multiplyof(1, 0)) # Error -``` - -`0` is a multiple of any number. But `b` cannot be `0`, otherwise an exception will be thrown. - -## isunique - -`isunique(list: [any]) -> bool` - -Check if there are duplicate elements in an array, and return a boolean value: - -```python -print(isunique([])) # True -print(isunique([1])) # True -print(isunique([1, 2])) # True - -print(isunique([1, 1])) # False -print(isunique([1, 1.0])) # False -print(isunique([1.1, 1.1])) # False - -print(isunique(['abc', "abc"])) # False -print(isunique(['abc', "a${'bc'}"])) # False -``` - -It should be noted that integers and floating-point numbers ignore the type difference and judge whether the values are equal. - -## len - -`len(x: str | [any] | {:}) -> int` - -Return the length of strings, lists, and arrays: - -```python -print(len([])) # 0 -print(len({})) # 0 - -print(len([1])) # 1 -print(len({abc:123})) # 1 - -print("abc") # 3 -``` - -Note: Calculating lengths on `schema` objects is not supported. - -## abs - -`abs(x: number) -> number` - -Calculate the absolute value of `x`. - -## all_true - -`all_true(x:str|[]|{:}) -> bool` - -Judging that all elements of a list or dictionary class are true, the usage is as follows: - -```python -print(all_true([])) # True -print(all_true({})) # True - -print(all_true([True])) # True -print(all_true([1])) # True - -print(all_true([True, False])) # False -print(all_true([True, None])) # False -``` - -Returns true when the list is empty. - -## any_true - -`any_true(x:str|[]|{:}) -> bool` - -Judging that at least one element in the iterable object is true, the usage is as follows: - -```python -print(any_true([])) # False -print(any_true([1])) # True -``` - -## bin - -`bin(x:number) -> str` - -A string that returns the binary representation of an integer, used as follows: - -```python -print(bin(8)) # 0b1000 -``` - -## hex - -`hex(number)` - -A string that returns the hexadecimal representation of an integer, used as follows: - -```python -print(hex(18)) # 0x12 -``` - -## oct - -`oct(number)` - -A string that returns the octal representation of an integer, used as follows: - -```python -print(oct(10)) # 0o12 -``` - -## option - -`option(key:str, type:str='', required=False, default=None, help="") -> any` - -Gets the value of the command line top level argument input. - -## ord - -`ord(c) -> int` - -Get the Unicode code point value of the character, the usage is as follows: - -```python -print(ord('A')) # 65 -print(ord('B')) # 66 -print(ord('C')) # 67 -``` - -## sorted - -`sorted(x: []) -> []` - -Returns the sorted list, used as follows: - -```python -_a = [] -_b = [2, 1] - -_c = sorted(_a) -_d = sorted(_b) - -print(_a) # [] -print(_b) # [2, 1] -print(_c) # [] -print(_d) # [1, 2] -``` - -## range - -`range(start:int, end:int, step=1) -> [int]` - -Generates an iterable list, used as follows: - -```python -print(range(1,5)) # [1, 2, 3, 4] -print(range(1,5, 2)) # [1, 3] -print(range(5, 1, -1)) # [5, 4, 3, 2] -``` - -## min - -`min(x:[number]) -> number` - -Returns the smallest element in the list, used as follows: - -```python -print(min([1,2])) # 1 -print(min([2,1])) # 1 -``` - -## max - -`max(x:[number]) -> number` - -Returns the largest element in the list, used as follows: - -```python -print(max([1,2])) # 2 -print(max([2,1])) # 2 -``` - -## sum - -`sum(x:[number], init_value=0) -> number` - -Returns the sum of all elements in the list, used as follows: - -``` -print(sum([1,2])) # 3 -print(sum([2,1], 1000)) # 1003 -``` - -## pow - -`pow(x: number, y: number, z: number = None) -> number` - -Computes `x**y`, or `(x**y)%z` if `z` is not empty, supports integer and floating point numbers, used as follows: - -```python -print(pow(2,3)) # 8 -print(pow(2, 3, 5)) # 8%5 == 3 - -print(pow(2, 0.5)) # 1.414 -``` - -## round - -`round(number: int|float, ndigits:int|None) -> float | int` - -Returns the rounded approximation of `number`. If `ndigits` is not `None` returns a float with the specified number of decimal places (cannot be negative), otherwise returns an integer structure, used as follows: - -```python -print(round(1)) # 1 -print(round(1.4)) # 1 -print(round(1.5)) # 2 - -print(round(1.5555, 1)) # 1.6 -print(round(1.5555, 2)) # 1.56 - -print(round(1.5555)) # 2 -print(round(1.5555, 0)) # 2.0 -``` - -It should be noted that the difference between `ndigits` being `None` and `0` is that the prefix returns `int` type, the latter returns `float` type. - -## typeof - -`typeof(x: any, full_name: bool = False) -> str` - -Output the type of `x` at runtime. When the `full_name` parameter is set to `True`, the package prefix of the form `pkg.schema` will be returned, used as follows: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person{} -t3 = typeof(_x1) - -_x2 = pkg.Person{} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# Output -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -## zip - -`zip(*args: str|list|dict)` - -It is used to take an iterable object as a parameter, pack the corresponding elements in the object into tuples, and then return a list composed of these tuples, used as follows: - -```py -a = zip([0, 1, 2], [3, 4, 5]) -b = zip([0, 1], [3, 4, 5]) -c = zip([0, 1, 2], [3, 4, 5, 6]) - -# Output -# a: -# - - 0 -# - 3 -# - - 1 -# - 4 -# - - 2 -# - 5 -# b: -# - - 0 -# - 3 -# - - 1 -# - 4 -# c: -# - - 0 -# - 3 -# - - 1 -# - 4 -# - - 2 -``` diff --git a/versioned_docs/version-0.5.4/reference/model/crypto.md b/versioned_docs/version-0.5.4/reference/model/crypto.md deleted file mode 100644 index 7fab7e50..00000000 --- a/versioned_docs/version-0.5.4/reference/model/crypto.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "crypto" -linkTitle: "crypto" -type: "docs" -description: crypto system module -weight: 100 ---- - -## md5 - -`md5(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `MD5` and the codec registered for encoding. - -## sha1 - -`sha1(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA1` and the codec registered for encoding. - -## sha224 - -`sha224(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA224` and the codec registered for encoding. - -## sha256 - -`sha256(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA256` and the codec registered for encoding. - -## sha384 - -`sha384(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA384` and the codec registered for encoding. - -## sha512 - -`sha512(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA512` and the codec registered for encoding. diff --git a/versioned_docs/version-0.5.4/reference/model/datetime.md b/versioned_docs/version-0.5.4/reference/model/datetime.md deleted file mode 100644 index 5b829890..00000000 --- a/versioned_docs/version-0.5.4/reference/model/datetime.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: "datetime" -linkTitle: "datetime" -type: "docs" -description: datetime system module -weight: 100 ---- - -## time - -`ticks() -> float` - -Return the current time in seconds since the Epoch. Fractions of a second may be present if the system clock provides them. - -## date - -`date() -> str` - -Return the `%Y-%m-%d %H:%M:%S` format date. - -## now - -`now() -> str` - -Return the local time. e.g. `'Sat Jun 06 16:26:11 1998'` - -## today - -`today() -> str` - -Return the `%Y-%m-%d %H:%M:%S.%{ticks}` format date. diff --git a/versioned_docs/version-0.5.4/reference/model/index.md b/versioned_docs/version-0.5.4/reference/model/index.md deleted file mode 100644 index 163e8db3..00000000 --- a/versioned_docs/version-0.5.4/reference/model/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# System Package - -KCL provides engineering extensibility through system modules, user modules and plug-in modules. This section describes the basic concepts of system modules. diff --git a/versioned_docs/version-0.5.4/reference/model/json.md b/versioned_docs/version-0.5.4/reference/model/json.md deleted file mode 100644 index 44ec8c73..00000000 --- a/versioned_docs/version-0.5.4/reference/model/json.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: "json" -linkTitle: "json" -type: "docs" -description: json system module -weight: 100 ---- - -## encode - -``` -encode( - data: any, - sort_keys: bool = False, - indent: int = None, - ignore_private: bool = False, - ignore_none: bool = False -) -> str -``` - -Serialize a KCL object `data` to a JSON formatted str. - -## decode - -`decode(value: str) -> any` - -Deserialize `value` (a string instance containing a JSON document) to a KCL object. - -## dump_to_file - -``` -dump_to_file( - data: any, - filename: str, - ignore_private: bool = False, - ignore_none: bool = False -) -> None -``` - -Serialize a KCL object `data` to a JSON formatted str and write it into the file `filename`. diff --git a/versioned_docs/version-0.5.4/reference/model/manifests.md b/versioned_docs/version-0.5.4/reference/model/manifests.md deleted file mode 100644 index ab31ad47..00000000 --- a/versioned_docs/version-0.5.4/reference/model/manifests.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: "manifests" -linkTitle: "manifests" -type: "docs" -description: manifests system module -weight: 100 ---- - -## yaml_stream - -```python -yaml_stream(values: [any], opts: {str:} = { - sort_keys = False - ignore_private = True - ignore_none = False - sep = "---" -}) -``` - -This function is used to serialize the KCL object list into YAML output with the --- separator. It has two parameters: - -- `values` - A list of KCL objects -- `opts` - The YAML serialization options - - `sort_keys`: Whether to sort the serialized results in the dictionary order of attribute names (the default is `False`). - - `ignore_private`: Whether to ignore the attribute output whose name starts with the character `_` (the default value is `True`). - - `ignore_none`: Whether to ignore the attribute with the value of' None '(the default value is `False`). - - `sep`: Set the separator between multiple YAML documents (the default value is `"---"`). - -Here's an example: - -```python -# Use the `import` keyword to import the `manifests` module. -import manifests - -# The schema `Deployment` definition. -schema Deployment: - apiVersion: str = "v1" - kind: str = "Deployment" - metadata: {str:} = { - name = "deploy" - } - spec: {str:} = { - replica = 2 - } - -# The schema `Service` definition. -schema Service: - apiVersion: str = "v1" - kind: str = "Service" - metadata: {str:} = { - name = "svc" - } - spec: {str:} = {} - -# Define two `Deployment` resources. -deployments = [Deployment {}, Deployment {}] -# Define two `Service` resources. -services = [Service {}, Service {}] -# Put them into a KCL list and call the `manifests.yaml_stream` function. -manifests.yaml_stream(deployments + services) -``` - -First, we use the `import` keyword to import the `manifests` module and define two deployment resources and two service resources. When we want to output these four resources in YAML stream format with `---` as the separator, we can put them into a KCL list and use the `manifests.yaml_stream` function pass it to the `values` parameter (if there is no special requirement, the `opts` parameter can generally use the default value). Finally, the YAML output is: - -```yaml -apiVersion: v1 -kind: Deployment -metadata: - name: deploy -spec: - replica: 2 ---- -apiVersion: v1 -kind: Deployment -metadata: - name: deploy -spec: - replica: 2 ---- -apiVersion: v1 -kind: Service -metadata: - name: svc ---- -apiVersion: v1 -kind: Service -metadata: - name: svc -``` diff --git a/versioned_docs/version-0.5.4/reference/model/math.md b/versioned_docs/version-0.5.4/reference/model/math.md deleted file mode 100644 index dae369af..00000000 --- a/versioned_docs/version-0.5.4/reference/model/math.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: "math" -linkTitle: "math" -type: "docs" -description: math system module -weight: 100 ---- - -## ceil - -`ceil(x) -> int` - -Return the ceiling of `x` as an Integral. This is the smallest integer >= x. - -## factorial - -`factorial(x) -> int` - -Return `x!`. Raise a error if `x` is negative or non-integral. - -## floor - -`floor(x) -> int` - -Return the floor of `x` as an Integral. This is the largest integer <= x. - -## gcd - -`gcd(a: int, b: int) -> int` - -Return the greatest common divisor of `x` and `y` - -## isfinite - -`isfinite(x) -> bool` - -Return `True` if `x` is neither an infinity nor a `NaN`, and `False` otherwise. - -## isinf - -`isinf(x) -> bool` - -Return `True` if `x` is a positive or negative infinity, and `False` otherwise. - -## isnan - -`isnan(x) -> bool` - -Return `True` if `x` is a `NaN` (not a number), and `False` otherwise. - -## modf - -`modf(x) -> List[float, float]` - -Return the fractional and integer parts of `x`. Both results carry the sign of `x` and are floats. - -## exp - -`exp(x) -> float` - -Return `e` raised to the power of `x`. - -## expm1 - -`expm1(x) -> float` - -Return `exp(x) - 1`. This function avoids the loss of precision involved in the direct evaluation of `exp(x) - 1` for small `x`. - -## log - -`log(x, base=2.71828182845904523536028747135266250) -> float` - -Return the logarithm of `x` to the base `e`. - -## log1p - -`log1p(x) -> float` - -Return the natural logarithm of `1+x` (base `e`). The result is computed in a way which is accurate for `x` near zero. - -## log2 - -`log2(x) -> float` -Return the base 2 logarithm of `x`. - -## log10 - -`log10(x) -> float` - -Return the base 10 logarithm of `x`. - -## pow - -`pow(x, y) -> float` - -Return `x**y` (`x` to the power of `y`). - -## sqrt - -`sqrt(x) -> float` - -Return the square root of `x`. diff --git a/versioned_docs/version-0.5.4/reference/model/net.md b/versioned_docs/version-0.5.4/reference/model/net.md deleted file mode 100644 index a4e83659..00000000 --- a/versioned_docs/version-0.5.4/reference/model/net.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: "net" -linkTitle: "net" -type: "docs" -description: net system module -weight: 100 ---- - -## split_host_port - -`split_host_port(ip_end_point: str) -> List[str]` - -Split the `host` and `port` from the `ip_end_point`. - -## join_host_port - -`join_host_port(host, port) -> str` - -Merge the `host` and `port`. - -## fqdn - -`fqdn(name: str = '') -> str` - -Return Fully Qualified Domain Name (FQDN). - -## parse_IP - -`parse_IP(ip) -> str` - -Parse `ip` to a real IP address - -## to_IP4 - -`to_IP4(ip) -> str` - -Get the IP4 form of `ip`. - -## to_IP16 - -`to_IP16(ip) -> int` - -Get the IP16 form of `ip`. - -## IP_string - -`IP_string(ip: str | int) -> str` - -Get the IP string. - -## is_IPv4 - -`is_IPv4(ip: str) -> bool` - -Whether `ip` is a IPv4 one. - -## is_IP - -`is_IP(ip: str) -> bool` - -Whether `ip` is a valid ip address. - -## is_loopback_IP - -`is_loopback_IP(ip: str) -> bool` - -Whether `ip` is a loopback one. - -## is_multicast_IP - -`is_multicast_IP(ip: str) -> bool` - -Whether `ip` is a multicast one. - -## is_interface_local_multicast_IP - -`is_interface_local_multicast_IP(ip: str) -> bool` - -Whether `ip` is a interface, local and multicast one. - -## is_link_local_multicast_IP - -`is_link_local_multicast_IP(ip: str) -> bool` - -Whether `ip` is a link local and multicast one. - -## is_link_local_unicast_IP - -`is_link_local_unicast_IP(ip: str) -> bool` - -Whether `ip` is a link local and unicast one. - -## is_global_unicast_IP - -`is_global_unicast_IP(ip: str) -> bool` - -Whether `ip` is a global and unicast one. - -## is_unspecified_IP - -`is_unspecified_IP(ip: str) -> bool` - -Whether `ip` is a unspecified one. diff --git a/versioned_docs/version-0.5.4/reference/model/overview.md b/versioned_docs/version-0.5.4/reference/model/overview.md deleted file mode 100644 index 36365ac1..00000000 --- a/versioned_docs/version-0.5.4/reference/model/overview.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -sidebar_position: 0 ---- - -# Overview - -KCL provides engineering extensibility through built-in modules, system modules and plug-in modules. - -![](/img/docs/reference/lang/model/kcl-module.png) - -The user code does not need to import functions that directly use builtin functions (such as calculating the length of a list with `len`, obtaining the type of value through `typeof`, etc.), and for basic types such as strings, it also provides some built-in methods (such as converting the case of strings, etc.). - -For relatively complex general logic, it is provided through the system modules. For example, by importing the `math` module, we can use related mathematical functions, and we can use the regular expression by importing the `regex` module. For KCL code, it can also be organized into different user modules. - -In addition, Python and Go can be used to develop plug-ins for KCL through the plugin mechanism. For example, there are the app-context plug-in can be used to obtain the context information of the current application to simplify code writing. diff --git a/versioned_docs/version-0.5.4/reference/model/regex.md b/versioned_docs/version-0.5.4/reference/model/regex.md deleted file mode 100644 index adde0630..00000000 --- a/versioned_docs/version-0.5.4/reference/model/regex.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "regex" -linkTitle: "regex" -type: "docs" -description: regex system module -weight: 100 ---- - -## replace - -`replace(string: str, pattern: str, replace: str, count=0) -> str` - -Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement. - -## match - -`match(string: str, pattern: str) -> bool` - -Try to apply the pattern at the start of the string, returning a bool value `True` if any match was found, or `False` if no match was found. - -## compile - -`compile(pattern: str) -> bool` - -Compile a regular expression pattern, returning a bool value denoting whether the pattern is valid. - -## findall - -`findall(string: str, pattern: str) -> List[str]` - -Return a list of all non-overlapping matches in the string. - -## search - -`search(string: str, pattern: str) -> bool` - -Scan through string looking for a match to the pattern, returning a bool value `True` if any match was found, or `False` if no match was found. - -## split - -`split(string: str, pattern: str, maxsplit=0) -> List[str]` - -Return a list composed of words from the string, splitting up to a maximum of `maxsplit` times using `pattern` as the separator. diff --git a/versioned_docs/version-0.5.4/reference/model/units.md b/versioned_docs/version-0.5.4/reference/model/units.md deleted file mode 100644 index 34465a53..00000000 --- a/versioned_docs/version-0.5.4/reference/model/units.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: "units" -linkTitle: "units" -type: "docs" -description: units system module - Unit handlers -weight: 100 ---- - -## Constants - -- Fixed point unit constants: `n`, `u`, `m`, `k`, `K`, `G`, `T` and `P`. -- Power of 2 unit constants: `Ki`, `Mi`, `Gi`, `Ti` and `Pi`. - -## Functions - -- `to_n(num: int) -> str` - Int literal to string with `n` suffix -- `to_u(num: int) -> str` - Int literal to string with `u` suffix -- `to_m(num: int) -> str` - Int literal to string with `m` suffix -- `to_K(num: int) -> str` - Int literal to string with `K` suffix -- `to_M(num: int) -> str` - Int literal to string with `M` suffix -- `to_G(num: int) -> str` - Int literal to string with `G` suffix -- `to_T(num: int) -> str` - Int literal to string with `T` suffix -- `to_P(num: int) -> str` - Int literal to string with `P` suffix -- `to_Ki(num: int) -> str` - Int literal to string with `Ki` suffix -- `to_Mi(num: int) -> str` - Int literal to string with `Mi` suffix -- `to_Gi(num: int) -> str` - Int literal to string with `Gi` suffix -- `to_Ti(num: int) -> str` - Int literal to string with `Ti` suffix -- `to_Pi(num: int) -> str` - Int literal to string with `Pi` suffix diff --git a/versioned_docs/version-0.5.4/reference/model/yaml.md b/versioned_docs/version-0.5.4/reference/model/yaml.md deleted file mode 100644 index 4b952dcf..00000000 --- a/versioned_docs/version-0.5.4/reference/model/yaml.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: "yaml" -linkTitle: "yaml" -type: "docs" -description: yaml encode and decode function -weight: 300 ---- - -## encode - -``` -encode( - data: any, - sort_keys: bool = False, - ignore_private: bool = False, - ignore_none: bool = False -) -> str -``` - -Serialize a KCL object `data` to a YAML formatted str. - -## decode - -`decode(value: str) -> any` - -Deserialize `value` (a string instance containing a YAML document) to a KCL object. - -## dump_to_file - -``` -dump_to_file( - data: any, - filename: str, - ignore_private: bool = False, - ignore_none: bool = False -) -> None -``` - -Serialize a KCL object `data` to a YAML formatted str and write it into the file `filename`. diff --git a/versioned_docs/version-0.5.4/reference/package-management/_category_.json b/versioned_docs/version-0.5.4/reference/package-management/_category_.json deleted file mode 100644 index 7848e437..00000000 --- a/versioned_docs/version-0.5.4/reference/package-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Package Management Tools", - "position": 4 -} diff --git a/versioned_docs/version-0.5.4/reference/package-management/command-reference/1.init.md b/versioned_docs/version-0.5.4/reference/package-management/command-reference/1.init.md deleted file mode 100644 index 6a46976a..00000000 --- a/versioned_docs/version-0.5.4/reference/package-management/command-reference/1.init.md +++ /dev/null @@ -1,45 +0,0 @@ -# kpm init - -Init a kcl package. - -## Usage - -```shell -kpm init [options][package_name] -``` - -## Description - -`kpm init` will initialize a kcl package in the current directory. If the package name is not provided, the name of the current directory will be used. - -If the package name is provided, a subdirectory with the name of the package will be created and the package will be initialized in that directory. - -`kpm init` will create `kcl.mod`, `kcl.mod.lock` and `main.k` under the package directory. - -## Options - -### --help, -h - -Show help for `kpm init` command. - -## Examples - -### Init the current directory into a kcl package - -```shell -# create an empty directory -$ mkdir my_package - -# cd into the directory -$ cd my_package - -# init the current directory into a kcl package -$ kpm init -``` - -### Init a kcl package with a name - -```shell -# init a kcl package with a name 'my_package' -kpm init my_package -``` diff --git a/versioned_docs/version-0.5.4/reference/package-management/command-reference/10.help.md b/versioned_docs/version-0.5.4/reference/package-management/command-reference/10.help.md deleted file mode 100644 index 94c078f5..00000000 --- a/versioned_docs/version-0.5.4/reference/package-management/command-reference/10.help.md +++ /dev/null @@ -1,21 +0,0 @@ -# kpm help - -Print help information for kpm commands. - -## Usage - -```shell -kpm help -``` - -## Description - -`kpm help` will print help information for kpm commands. - -## Examples - -Use `kpm help` to print help information for kpm commands. - -```shell -kpm help -``` diff --git a/versioned_docs/version-0.5.4/reference/package-management/command-reference/2.add.md b/versioned_docs/version-0.5.4/reference/package-management/command-reference/2.add.md deleted file mode 100644 index 1d2517fb..00000000 --- a/versioned_docs/version-0.5.4/reference/package-management/command-reference/2.add.md +++ /dev/null @@ -1,53 +0,0 @@ -# kpm add - -Add a dependency to a kcl package. - -## Usage - -```shell -kpm add [options][package_reference] -``` - -## Description - -`kpm add` will add a dependency to a kcl package. The dependency can be from a git repository, or a kcl registry. - -`package_reference` is a kcl package reference, looks like `package_name:version`. - -## options - -### --git - -Specify the git url of the dependency from a git repository. - -### --tag - -Specify the tag of the dependency from a git repository. - -### --help, -h - -Show help for `kpm add` command. - -## Examples - -### Add a dependency from kcl registry - -Add kcl dependency named `k8s` to the current package.The version of the dependency will be the latest version. - -```shell -kpm add k8s -``` - -Add kcl dependency named 'k8s' with version 'v1.27.2'. - -```shell -kpm add k8s:v1.27.2 -``` - -### Add a dependency from git repository - -Add kcl dependency named `konfig` with version `v0.1.0` from git repository. - -```shell -kpm add --git https://github.com/awesome-kusion/konfig.git --tag v0.1.0 -``` diff --git a/versioned_docs/version-0.5.4/reference/package-management/command-reference/3.pkg.md b/versioned_docs/version-0.5.4/reference/package-management/command-reference/3.pkg.md deleted file mode 100644 index 9b4298a5..00000000 --- a/versioned_docs/version-0.5.4/reference/package-management/command-reference/3.pkg.md +++ /dev/null @@ -1,33 +0,0 @@ -# kpm pkg - -Package a kcl package into `*.tar`. - -## Usage - -```shell -kpm pkg [options] -``` - -## Description - -`kpm pkg` will package a kcl package into `*.tar`. - -Option `--target` is required to specify the tar file path of the package. - -## options - -### --target - -Specify the tar file path of the package. - -### --help, -h - -Show help for `kpm pkm` command. - -## Examples - -### Package a kcl package - -```shell -kpm pkg --target /Users/my_package_tar -``` diff --git a/versioned_docs/version-0.5.4/reference/package-management/command-reference/4.metadata.md b/versioned_docs/version-0.5.4/reference/package-management/command-reference/4.metadata.md deleted file mode 100644 index 3074a8d5..00000000 --- a/versioned_docs/version-0.5.4/reference/package-management/command-reference/4.metadata.md +++ /dev/null @@ -1,41 +0,0 @@ -# kpm metadata - -Print the metadata of a kcl package. - -## Usage - -```shell -kpm metadata [options] -``` - -## Description - -`kpm metadata` will print the metadata of a kcl package. The metadata includes the dependency information of the package. - -`--update` option is used to automatically download the missing dependency packages. - -## options - -### --update - -Automatically download the missing dependency packages. - -### --help, -h - -Show help for `kpm metadata` command. - -## Examples - -### Print the metadata of a kcl package - -Print the metadata of a kcl package. - -```shell -kpm metadata -``` - -Print the metadata of a kcl package and automatically download the missing dependency packages. - -```shell -kpm metadata --update -``` diff --git a/versioned_docs/version-0.5.4/reference/package-management/command-reference/5.run.md b/versioned_docs/version-0.5.4/reference/package-management/command-reference/5.run.md deleted file mode 100644 index b5001185..00000000 --- a/versioned_docs/version-0.5.4/reference/package-management/command-reference/5.run.md +++ /dev/null @@ -1,69 +0,0 @@ -# kpm run - -Compile a kcl package. - -## Usage - -```shell -kpm run [options][package_source] -``` - -## Description - -`kpm run` will compile a kcl package. - -## options - -### --input - -Specify the entry file path of the package. - -### --tag - -Specify the tag of the package specified by oci url `package_source`. - -### --vendor - -`--vendor` will move the dependency packages into the current packages and automatically download the missing dependency packages. - -### --kcl_args - -`--kcl_args` specifies the arguments passed to the kcl compiler. - -### --help, -h - -Show help for `kpm run` command. - -## Examples - -### compile the current kcl package - -Under the kcl package directory, `kpm run` can be used to compile the current kcl package. - -```shell -kpm run -``` - -### compile a kcl package tar file - -`kpm run` can be used to compile a kcl package tar file. - -```shell -kpm run /Users/demo/my_package.tar -``` - -### compile a kcl package from oci url - -`kpm run` can be used to compile a kcl package from oci url. - -```shell -kpm run --tag 0.0.1 oci://localhost:5001/test/my_package -``` - -### compile a kcl package from oci ref - -`kpm run` can be used to compile a kcl package from oci ref. - -```shell -kpm run test/my_package:0.0.1 -``` diff --git a/versioned_docs/version-0.5.4/reference/package-management/command-reference/6.login.md b/versioned_docs/version-0.5.4/reference/package-management/command-reference/6.login.md deleted file mode 100644 index 68ca0f1b..00000000 --- a/versioned_docs/version-0.5.4/reference/package-management/command-reference/6.login.md +++ /dev/null @@ -1,68 +0,0 @@ -# kpm login - -Login to the kpm registry. - -## Usage - -```shell -kpm login [options][kpm_registry] -``` - -## Description - -`kpm login` will login the kpm registry. - -## options - -### --username - -Specify the username of the kpm registry. - -### --password - -Specify the password of the kpm registry. - -### --help, -h - -Show help for `kpm login` command. - -## Examples - -### login to a registry with account and password - -```shell -kpm login -u -p -``` - -The output is - -```shell -Login succeeded -``` - -### login to a registry with account, and enter the password interactively - -```shell -kpm login -u -``` - -The output is - -```shell -Password: -Login succeeded -``` - -### login to a registry, and enter the account and password interactively - -```shell -kpm login -``` - -The output is - -```shell -Username: -Password: -Login succeeded -``` diff --git a/versioned_docs/version-0.5.4/reference/package-management/command-reference/7.logout.md b/versioned_docs/version-0.5.4/reference/package-management/command-reference/7.logout.md deleted file mode 100644 index 6c5d9aec..00000000 --- a/versioned_docs/version-0.5.4/reference/package-management/command-reference/7.logout.md +++ /dev/null @@ -1,27 +0,0 @@ -# kpm logout - -Logout from the kpm registry. - -## Usage - -```shell -kpm logout [options][kpm_registry] -``` - -## Description - -`kpm logout` will logout from the kpm registry. - -## options - -### --help, -h - -Show help for `kpm logout` command. - -## Examples - -### logout from oci registry - -```shell -kpm logout -``` diff --git a/versioned_docs/version-0.5.4/reference/package-management/command-reference/8.push.md b/versioned_docs/version-0.5.4/reference/package-management/command-reference/8.push.md deleted file mode 100644 index a70c5bc1..00000000 --- a/versioned_docs/version-0.5.4/reference/package-management/command-reference/8.push.md +++ /dev/null @@ -1,46 +0,0 @@ -# kpm push - -Push a package to the kpm registry. - -## Usage - -```shell -kpm push [options][kpm_registry] -``` - -## Description - -`kpm push` will push a package to the kpm registry. - -## options - -### --tar_path - -The path to the tar file to push. - -### --help, -h - -Show help for `kpm push` command. - -## Examples - -### push the current package - -You can use `kpm push` under the kcl package root directory to upload a kcl package to an OCI-based registry. - -```shell -# create a new kcl package. -$ kpm init -# enter the kcl package root directory -$ cd -# push it to an oci registry -$ kpm push -``` - -### push a tar to the registry - -You can also use `kpm push` to upload a tar file to an OCI-based registry. - -```shell -kpm push --tar_path -``` diff --git a/versioned_docs/version-0.5.4/reference/package-management/command-reference/9.pull.md b/versioned_docs/version-0.5.4/reference/package-management/command-reference/9.pull.md deleted file mode 100644 index b0126bcf..00000000 --- a/versioned_docs/version-0.5.4/reference/package-management/command-reference/9.pull.md +++ /dev/null @@ -1,42 +0,0 @@ -# kpm pull - -Pull a package from the kpm registry. - -## Usage - -```shell -kpm pull [options][package_source] -``` - -## Description - -`kpm pull` will pull a package from the kpm registry. - -## options - -### --tag - -The tag of the package to pull. - -### --help, -h - -Show help for `kpm push` command. - -## Examples - -### pull the package by package name - -You can use `kpm pull` to download a kcl package from the default OCI registry by kcl package name. -`kpm` will download the kcl package from the default OCI registry specified in the configuration file `kpm.json`. - -```shell -kpm pull : -``` - -### pull the package by oci url - -You can download a kcl package from an OCI-based registry url. - -```shell -kpm pull --tag -``` diff --git a/versioned_docs/version-0.5.4/reference/package-management/command-reference/_category_.json b/versioned_docs/version-0.5.4/reference/package-management/command-reference/_category_.json deleted file mode 100644 index 8c705ed9..00000000 --- a/versioned_docs/version-0.5.4/reference/package-management/command-reference/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Command Reference", - "position": 4 -} diff --git a/versioned_docs/version-0.5.4/reference/package-management/command-reference/index.md b/versioned_docs/version-0.5.4/reference/package-management/command-reference/index.md deleted file mode 100644 index ab6cc90c..00000000 --- a/versioned_docs/version-0.5.4/reference/package-management/command-reference/index.md +++ /dev/null @@ -1,36 +0,0 @@ -# kpm - -The kpm cli - -## Usage - -```shell -kpm [arguments]... -``` - -## Description - -`kpm` is a kcl package manager. It is used to install, remove, and update kcl packages. - -## Options - -### --help, -h - -Show help for kpm command - -### --version, -v - -Print the version of kpm - -## Subcommands - -- [kpm init](./1.init.md) - Init a kcl package -- [kpm add](./2.add.md) - Add a dependency to a kcl package -- [kpm pkg](./3.pkg.md) - Package a kcl package into `\*.tar`` -- [kpm metadata](./4.metadata.md) - Print the metadata of a kcl package -- [kpm run](./5.run.md) - Compile a kcl package into yaml -- [kpm login](./6.login.md) - Login to a kcl registry -- [kpm logout](./7.logout.md) - Logout from a kcl registry -- [kpm push](./8.push.md) - Push a kcl package to a registry -- [kpm pull](./9.pull.md) - Pull a kcl package from a registry -- [kpm help](./10.help.md) - print help for kpm command diff --git a/versioned_docs/version-0.5.4/reference/plugin/_category_.json b/versioned_docs/version-0.5.4/reference/plugin/_category_.json deleted file mode 100644 index e77dfb1c..00000000 --- a/versioned_docs/version-0.5.4/reference/plugin/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Plugin System", - "position": 4 -} diff --git a/versioned_docs/version-0.5.4/reference/plugin/index.md b/versioned_docs/version-0.5.4/reference/plugin/index.md deleted file mode 100644 index df299e93..00000000 --- a/versioned_docs/version-0.5.4/reference/plugin/index.md +++ /dev/null @@ -1 +0,0 @@ -# Plugin System diff --git a/versioned_docs/version-0.5.4/reference/plugin/overview.md b/versioned_docs/version-0.5.4/reference/plugin/overview.md deleted file mode 100644 index f9561ddc..00000000 --- a/versioned_docs/version-0.5.4/reference/plugin/overview.md +++ /dev/null @@ -1,187 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Introduction - -KCL provides plugin support through a plugin agent and auxiliary command line tools, and the KCL plugin framework supports different general-purpose languages to develop plugins. Here we take Python as an example to briefly explain the use of plugins. - -KCL plugin Git repository: [https://github.com/kcl-lang/kcl-plugin](https://github.com/kcl-lang/kcl-plugin) - -## 0. Prerequisites - -Using the KCL Python plugin requires the presence of `Python 3.7+` in your `PATH`. - -## 1. Hello Plugin - -KCL plugins are installed in the `plugins` subdirectory of KCL (usually installed in the `$HOME/.kcl/plugins` directory), or set through the `$KCL_PLUGINS_ROOT` environment variable. Besides, the `plugins` directory could also be placed at the `pwd` path. KCL plugins are managed in the Git repository: [https://github.com/kcl-lang/kcl-plugin](https://github.com/kcl-lang/kcl-plugin), we can clone the repository for development. - -Enter the `kcl-plugin info` command to view the plugin directory (replace `/Users/kcl_user` with the local `$HOME` path): - -```shell -$ kcl-plugin info -# plugin_root: /Users/kcl_user/.kcl/plugins -``` - -View the list of plugins with the `kcl-plugin list` subcommand: - -```shell -$ kcl-plugin list -hello: hello doc - 0.0.1 -``` - -Where `hello` is an example builtin plugin (do not modify the plugin). - -In KCL code, the `hello` plugin can be imported via `import kcl_plugin.hello`. `main.k` code is as follows: - -```python -import kcl_plugin.hello - -name = "kcl" -three = hello.add(1,2) -``` - -The output result is - -```shell -$ python3 -m kclvm main.k -name: kcl -three: 3 -``` - -## 2. `kcl-plugin` Command - -`kcl-plugin` is a plugin helper command line tool, the command line help is as follows: - -```shell -$ kcl-plugin -usage: kcl-plugin [-h] {list,info,init,gendoc,test} ... -positional arguments: - {list,info,init,gendoc,test} - kcl plugin sub commands - list list all plugins - info show plugin document - init init a new plugin - gendoc gen all plugins document - test test plugin -optional arguments: - -h, --help show this help message and exit -``` - -- The `list` subcommand is used to view the list of plugins. -- The `info` subcommand is used to view the plugin directory and information about each plugin. -- The `init` subcommand is used to initialize new plugins. -- The `gendoc` subcommand is used to update the API documentation of all plugins. -- The `test` subcommand is used to test specified plugins. - -## 3. Plugin Information and Documentation - -Enter `kcl-plugin info hello` to view the `hello` plugin information: - -```shell -$ kcl-plugin info hello -{ - "name": "hello", - "describe": "hello doc", - "long_describe": "long describe", - "version": "0.0.1", - "method": { - "add": "add two numbers, and return result", - "foo": "no doc", - "list_append": "no doc", - "say_hello": "no doc", - "tolower": "no doc", - "update_dict": "no doc" - } -} -``` - -The information of the plugin mainly includes the name and version information of the plugin, and the function information provided by the plugin. This information is consistent with the automatically generated `api.md` file in the plugin directory (regenerate the `api.md` file for all plugins via `kcl-plugin gendoc` when the plugin API document changes). - -## 4. Plugin Directory Structure - -The directory structure of the plugin is as follows (replace `/Users/kcl_user` with the local `$HOME` path): - -```shell -$ tree /Users/kcl_user/.kcl/plugins/ -/Users/kcl_user/.kcl/plugins/ -├── _examples -├── _test -└── hello - ├── api.md - ├── plugin.py - └── plugin_test.py -$ -``` - -The `_examples` directory is the sample code of the plugin, the `_test` directory is the KCL test code of the plugin, and the other directories starting with letters are ordinary plugins. The content of the plugin is as follows: - -```shell -$ cat ./hello/plugin.py -# Copyright 2020 The KCL Authors. All rights reserved. -INFO = { - 'name': 'hello', - 'describe': 'hello doc', - 'long_describe': 'long describe', - 'version': '0.0.1', -} -def add(a: int, b: int) -> int: - """add two numbers, and return result""" - return a + b -... -``` - -Where `INFO` specifies the name of the plugin, a brief description, a detailed description and version information. And all the functions whose names start with letters are the functions provided by the plugin, so the `add` function can be called directly in KCL. - -> Note: KCL plugins are implemented in an independent pure Python code file, and plugins cannot directly call each other. - -## 5. Create Plugin - -A plugin can be created with the `kcl-plugin init` command: - -``` -$ kcl-plugin init hi -$ kcl-plugin list -hello: hello doc - 0.0.1 -hi: hi doc - 0.0.1 -``` - -The `kcl-plugin init` command will construct a new plugin from the built-in template, and then we can view the created plugin information with the `kcl-plugin list` command. - -## 6. Remove Plugin - -KCL plugins are located in the `plugins` subdirectory of KCL (usually installed in the `$HOME/.kcl/plugins` directory). -We can query the plugin installation directory with the command `kcl-plugin info`. - -```shell -$ kcl-plugin info -/Users/kcl_user/.kcl/plugins/ -$ tree /Users/kcl_user/.kcl/plugins/ -/Users/kcl_user/.kcl/plugins/ -├── _examples -├── _test -└── hello -- Delete this directory to delete the hello plugin - ├── api.md - ├── plugin.py - └── plugin_test.py -$ -``` - -## 7. Test Plugin - -There is a `plugin_test.py` file in the plugin directory, which is the unit test file of the plugin (based on the `pytest` testing framework). Also placed in the `_test` directory are plugin integration tests for KCL files. The `plugin_test.py` unit test is required, and the KCL integration tests in the `_test` directory can be added as needed. - -Unit tests for plugins can be executed via `kcl-plugin test`: - -```shell -$ kcl-plugin test hello -============================= test session starts ============================== -platform darwin -- Python 3.7.6+, pytest-5.3.5, py-1.9.0, pluggy-0.13.1 -rootdir: /Users/kcl_user -collected 5 items -.kcl/plugins/hello/plugin_test.py ..... [100%] -============================== 5 passed in 0.03s =============================== -$ -``` - -Integration tests can be tested by executing the `python3 -m pytest` command in the `_test` directory. diff --git a/versioned_docs/version-0.5.4/reference/plugin/project_context.md b/versioned_docs/version-0.5.4/reference/plugin/project_context.md deleted file mode 100644 index 0be02e78..00000000 --- a/versioned_docs/version-0.5.4/reference/plugin/project_context.md +++ /dev/null @@ -1,59 +0,0 @@ -# project_context - -project_context extract base info from project.yaml&stack.yaml - -_version: 0.0.1_ - -## `get_project_current_path` - -return the relative path of first file - -Example: - -```py -import kcl_plugin.project_context as ctx - -path = ctx.get_project_current_path() -print(path) -``` - -## `get_project_input_file` - -return compiling file list - -Example: - -```py -import kcl_plugin.project_context as ctx - -input_file = ctx.get_project_input_file() -print(input_file) -``` - -## `get_project_context` - -return the current project context from project.yaml - -Example: - -```py -import kcl_plugin.project_context as ctx - -project = ctx.get_project_context() -# Get project name -print(project?.name) -``` - -## `get_stack_context` - -return the current stack context from stack.yaml - -Example: - -```py -import kcl_plugin.project_context as ctx - -stack = ctx.get_stack_context() -# Get stack name -print(stack?.name) -``` diff --git a/versioned_docs/version-0.5.4/reference/xlang-api/_category_.json b/versioned_docs/version-0.5.4/reference/xlang-api/_category_.json deleted file mode 100644 index c2aafb21..00000000 --- a/versioned_docs/version-0.5.4/reference/xlang-api/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Multi-Language", - "position": 4 -} diff --git a/versioned_docs/version-0.5.4/reference/xlang-api/go-api.md b/versioned_docs/version-0.5.4/reference/xlang-api/go-api.md deleted file mode 100644 index 2a978250..00000000 --- a/versioned_docs/version-0.5.4/reference/xlang-api/go-api.md +++ /dev/null @@ -1,665 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Go API - -```go -import kcl "kcl-lang.io/kcl-go" -``` - -## KCL Go SDK - -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ kcl files │ │ KCL-Go-API │ │ KCLResultList │ -│ ┌───────────┐ │ │ │ │ │ -│ │ 1.k │ │ │ │ │ │ -│ └───────────┘ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ ┌───────────┐ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.Get("a.b.c") │ -│ │ 2.k │ │ │ │ Run(path) │ │ │ └───────────┘ │ └───────────────┘ -│ └───────────┘ │────┐ │ └───────────┘ │ │ │ -│ ┌───────────┐ │ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ │ 3.k │ │ │ │ │ │ │ KCLResult │──┼────────▶│x.Get("k", &v) │ -│ └───────────┘ │ │ │ │ │ └───────────┘ │ └───────────────┘ -│ ┌───────────┐ │ ├───▶│ ┌───────────┐ │──────────▶│ │ -│ │setting.yml│ │ │ │ │RunFiles() │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ └───────────┘ │ │ │ └───────────┘ │ │ │ KCLResult │──┼────────▶│x.JSONString() │ -└─────────────────┘ │ │ │ │ └───────────┘ │ └───────────────┘ - │ │ │ │ │ -┌─────────────────┐ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ Options │ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.YAMLString() │ -│WithOptions │ │ │ │MustRun() │ │ │ └───────────┘ │ └───────────────┘ -│WithOverrides │────┘ │ └───────────┘ │ │ │ -│WithWorkDir │ │ │ │ │ -│WithDisableNone │ │ │ │ │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ -``` - -
Example -

- -```go -{ - const k_code = ` -name = "kcl" -age = 1 - -two = 2 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {} -x1 = Person { - age = 101 -} -` - - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First().YAMLString() - fmt.Println(yaml) - - fmt.Println("----") - - result := kcl.MustRun("./testdata/main.k").First() - fmt.Println(result.JSONString()) - - fmt.Println("----") - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - - fmt.Println("----") - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x1", &person)) -} -``` - -

-
- -## Index - -- [Go API](#go-api) - - [KCL Go SDK](#kcl-go-sdk) - - [Index](#index) - - [Constants](#constants) - - [func FormatCode](#func-formatcode) - - [func FormatPath](#func-formatpath) - - [func InitKclvmPath](#func-initkclvmpath) - - [func InitKclvmRuntime](#func-initkclvmruntime) - - [func LintPath](#func-lintpath) - - [func ListDepFiles](#func-listdepfiles) - - [func ListDownStreamFiles](#func-listdownstreamfiles) - - [func ListUpStreamFiles](#func-listupstreamfiles) - - [func OverrideFile](#func-overridefile) - - [func ValidateCode](#func-validatecode) - - [type KCLResult](#type-kclresult) - - [type KCLResultList](#type-kclresultlist) - - [func MustRun](#func-mustrun) - - [func Run](#func-run) - - [func RunFiles](#func-runfiles) - - [type KclType](#type-kcltype) - - [func GetSchemaType](#func-getschematype) - - [type ListDepFilesOption](#type-listdepfilesoption) - - [type ListDepsOptions](#type-listdepsoptions) - - [type Option](#type-option) - - [func WithCode](#func-withcode) - - [func WithDisableNone](#func-withdisablenone) - - [func WithKFilenames](#func-withkfilenames) - - [func WithOptions](#func-withoptions) - - [func WithOverrides](#func-withoverrides) - - [func WithPrintOverridesAST](#func-withprintoverridesast) - - [func WithSettings](#func-withsettings) - - [func WithSortKeys](#func-withsortkeys) - - [func WithWorkDir](#func-withworkdir) - - [type ValidateOptions](#type-validateoptions) - -## Constants - -KclvmAbiVersion is the current kclvm ABI version. - -```go -const KclvmAbiVersion = scripts.KclvmAbiVersion -``` - -## func [FormatCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L110) - -```go -func FormatCode(code interface{}) ([]byte, error) -``` - -FormatCode returns the formatted code. - -
Example -

- -```go -{ - out, err := kcl.FormatCode(`a = 1+2`) - if err != nil { - log.Fatal(err) - } - fmt.Println(string(out)) - -} -``` - -``` -a = 1 + 2 -``` - -

-
- -## func [FormatPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L122) - -```go -func FormatPath(path string) (changedPaths []string, err error) -``` - -FormatPath formats files from the given path path: if path is \`.\` or empty string, all KCL files in current directory will be formatted, not recursively if path is \`path/file.k\`, the specified KCL file will be formatted if path is \`path/to/dir\`, all KCL files in the specified dir will be formatted, not recursively if path is \`path/to/dir/...\`, all KCL files in the specified dir will be formatted recursively - -the returned changedPaths are the changed file paths \(relative path\) - -
Example -

- -```go -{ - changedPaths, err := kcl.FormatPath("testdata/fmt") - if err != nil { - log.Fatal(err) - } - fmt.Println(changedPaths) -} -``` - -

-
- -## func [InitKclvmPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L54) - -```go -func InitKclvmPath(kclvmRoot string) -``` - -InitKclvmPath init kclvm path. - -## func [InitKclvmRuntime](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L59) - -```go -func InitKclvmRuntime(n int) -``` - -InitKclvmRuntime init kclvm process. - -## func [LintPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L142) - -```go -func LintPath(paths []string) (results []string, err error) -``` - -LintPath lint files from the given path - -
Example -

- -```go -{ - - results, err := kcl.LintPath([]string{"testdata/lint/import.k"}) - if err != nil { - log.Fatal(err) - } - for _, s := range results { - fmt.Println(s) - } - -} -``` - -``` -Module 'a' is reimported multiple times -Module 'a' imported but unused -``` - -

-
- -## func [ListDepFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L127) - -```go -func ListDepFiles(workDir string, opt *ListDepFilesOption) (files []string, err error) -``` - -ListDepFiles return the depend files from the given path - -## func [ListDownStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L137) - -```go -func ListDownStreamFiles(workDir string, opt *ListDepsOptions) ([]string, error) -``` - -ListDownStreamFiles return a list of downstream depend files from the given changed path list. - -## func [ListUpStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L132) - -```go -func ListUpStreamFiles(workDir string, opt *ListDepsOptions) (deps []string, err error) -``` - -ListUpStreamFiles return a list of upstream depend files from the given path list - -## func [OverrideFile](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L154) - -```go -func OverrideFile(file string, specs, importPaths []string) (bool, error) -``` - -OverrideFile rewrites a file with override spec file: string. The File that need to be overridden specs: \[\]string. List of specs that need to be overridden. - -``` -Each spec string satisfies the form: := or :- -When the pkgpath is '__main__', it can be omitted. -``` - -importPaths. List of import statements that need to be added - -## func [ValidateCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L159) - -```go -func ValidateCode(data, code string, opt *ValidateOptions) (ok bool, err error) -``` - -ValidateCode validate data match code - -## type [KCLResult](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L47) - -```go -type KCLResult = kcl.KCLResult -``` - -
Example -

- -```go -{ - const k_code = ` -name = "kcl" -age = 1 - -two = 2 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {name = "kcl-go"} -x1 = Person {age = 101} -` - - result := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First() - - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - -} -``` - -``` -x0.name: kcl-go -x1.age: 101 -``` - -

-
- -
Example ('et_struct) -

- -```go -{ - const k_code = ` -schema Person: - name: str = "kcl" - age: int = 1 - X: int = 2 - -x = { - "a": Person {age = 101} - "b": 123 -} -` - - result := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First() - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x.a", &person)) - fmt.Printf("person: %+v\n", person) - -} -``` - -``` -person: &{Name:kcl Age:101} -person: {Name:kcl Age:101} -``` - -

-
- -## type [KCLResultList](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L48) - -```go -type KCLResultList = kcl.KCLResultList -``` - -### func [MustRun](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L64) - -```go -func MustRun(path string, opts ...Option) *KCLResultList -``` - -MustRun is like Run but panics if return any error. - -
Example -

- -```go -{ - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(`name = "kcl"`)).First().YAMLString() - fmt.Println(yaml) - -} -``` - -``` -name: kcl -``` - -

-
- -
Example (Raw Yaml) -

- -```go -{ - const code = ` -b = 1 -a = 2 -` - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(code)).GetRawYamlResult() - fmt.Println(yaml) - - yaml_sorted := kcl.MustRun("testdata/main.k", kcl.WithCode(code), kcl.WithSortKeys(true)).GetRawYamlResult() - fmt.Println(yaml_sorted) - -} -``` - -``` -b: 1 -a: 2 -a: 2 -b: 1 -``` - -

-
- -
Example (Schema Type) -

- -```go -{ - const code = ` -schema Person: - name: str = "" - -x = Person() -` - json := kcl.MustRun("testdata/main.k", kcl.WithCode(code)).First().JSONString() - fmt.Println(json) - -} -``` - -``` -{ - "x": { - "name": "" - } -} -``` - -

-
- -
Example (Settings) -

- -```go -{ - yaml := kcl.MustRun("./testdata/app0/kcl.yaml").First().YAMLString() - fmt.Println(yaml) -} -``` - -

-
- -### func [Run](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L69) - -```go -func Run(path string, opts ...Option) (*KCLResultList, error) -``` - -Run evaluates the KCL program with path and opts, then returns the object list. - -
Example (Get Field) -

- -```go -{ - - x, err := kcl.Run("./testdata/app0/kcl.yaml") - assert(err == nil, err) - - fmt.Println(x.First().Get("deploy_topology.1.zone")) - -} -``` - -``` -R000A -``` - -

-
- -### func [RunFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L74) - -```go -func RunFiles(paths []string, opts ...Option) (*KCLResultList, error) -``` - -RunFiles evaluates the KCL program with multi file path and opts, then returns the object list. - -
Example -

- -```go -{ - result, _ := kcl.RunFiles([]string{"./testdata/app0/kcl.yaml"}) - fmt.Println(result.First().YAMLString()) -} -``` - -

-
- -## type [KclType](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L50) - -```go -type KclType = kcl.KclType -``` - -### func [GetSchemaType](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L176) - -```go -func GetSchemaType(file, code, schemaName string) ([]*KclType, error) -``` - -GetSchemaType returns schema types from a kcl file or code. - -file: string - -``` -The kcl filename -``` - -code: string - -``` -The kcl code string -``` - -schema_name: string - -``` -The schema name got, when the schema name is empty, all schemas are returned. -``` - -## type [ListDepFilesOption](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L45) - -```go -type ListDepFilesOption = list.Option -``` - -## type [ListDepsOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L44) - -```go -type ListDepsOptions = list.DepOptions -``` - -## type [Option](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L43) - -```go -type Option = kcl.Option -``` - -### func [WithCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L79) - -```go -func WithCode(codes ...string) Option -``` - -WithCode returns a Option which hold a kcl source code list. - -### func [WithDisableNone](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L97) - -```go -func WithDisableNone(disableNone bool) Option -``` - -WithDisableNone returns a Option which hold a disable none switch. - -### func [WithKFilenames](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L82) - -```go -func WithKFilenames(filenames ...string) Option -``` - -WithKFilenames returns a Option which hold a filenames list. - -### func [WithOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L85) - -```go -func WithOptions(key_value_list ...string) Option -``` - -WithOptions returns a Option which hold a key=value pair list for option function. - -
Example -

- -```go -{ - const code = ` -name = option("name") -age = option("age") -` - x, err := kcl.Run("hello.k", kcl.WithCode(code), - kcl.WithOptions("name=kcl", "age=1"), - ) - if err != nil { - log.Fatal(err) - } - - fmt.Println(x.First().YAMLString()) - -} -``` - -``` -age: 1 -name: kcl -``` - -

-
- -### func [WithOverrides](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L88) - -```go -func WithOverrides(override_list ...string) Option -``` - -WithOverrides returns a Option which hold a override list. - -### func [WithPrintOverridesAST](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L100) - -```go -func WithPrintOverridesAST(printOverridesAST bool) Option -``` - -WithPrintOverridesAST returns a Option which hold a printOverridesAST switch. - -### func [WithSettings](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L91) - -```go -func WithSettings(filename string) Option -``` - -WithSettings returns a Option which hold a settings file. - -### func [WithSortKeys](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L105) - -```go -func WithSortKeys(sortKeys bool) Option -``` - -WithSortKeys returns a Option which hold a sortKeys switch. - -### func [WithWorkDir](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L94) - -```go -func WithWorkDir(workDir string) Option -``` - -WithWorkDir returns a Option which hold a work dir. - -## type [ValidateOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L46) - -```go -type ValidateOptions = validate.ValidateOptions -``` diff --git a/versioned_docs/version-0.5.4/reference/xlang-api/index.md b/versioned_docs/version-0.5.4/reference/xlang-api/index.md deleted file mode 100644 index f6f8e076..00000000 --- a/versioned_docs/version-0.5.4/reference/xlang-api/index.md +++ /dev/null @@ -1 +0,0 @@ -# Multi-Language diff --git a/versioned_docs/version-0.5.4/reference/xlang-api/java-api.md b/versioned_docs/version-0.5.4/reference/xlang-api/java-api.md deleted file mode 100644 index 52c8cf34..00000000 --- a/versioned_docs/version-0.5.4/reference/xlang-api/java-api.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Java API - -At present, the KCL Java SDK is still in the early preview version. The KCL team will continue to update and provide more functions in the future. For more information, see [https://github.com/kcl-lang/kcl-java](https://github.com/kcl-lang/kcl-java) diff --git a/versioned_docs/version-0.5.4/reference/xlang-api/overview.md b/versioned_docs/version-0.5.4/reference/xlang-api/overview.md deleted file mode 100644 index e63422d4..00000000 --- a/versioned_docs/version-0.5.4/reference/xlang-api/overview.md +++ /dev/null @@ -1,293 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Introduction - -The KCL language provides general programming language interfaces such as C/Rust/Go/Python/Java, and the related languages are under development. - -## C/Rust API - -The core of KCL is developed in Rust, and the C language API is exported externally for packaging and integration in high-level languages such as Go/Python/Java. - -## Go API - -Go API is a C-API provided by CGO wrapping KCL, while providing deeper customization features to meet the needs of upper-level tools. - -### Abstract Model - -The abstract model of the KCL Go API is as follows: - -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ kcl files │ │ KCL-Go-API │ │ KCLResultList │ -│ ┌───────────┐ │ │ │ │ │ -│ │ 1.k │ │ │ │ │ │ -│ └───────────┘ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ ┌───────────┐ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.Get("a.b.c") │ -│ │ 2.k │ │ │ │ Run(path) │ │ │ └───────────┘ │ └───────────────┘ -│ └───────────┘ │────┐ │ └───────────┘ │ │ │ -│ ┌───────────┐ │ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ │ 3.k │ │ │ │ │ │ │ KCLResult │──┼────────▶│x.Get("k", &v) │ -│ └───────────┘ │ │ │ │ │ └───────────┘ │ └───────────────┘ -│ ┌───────────┐ │ ├───▶│ ┌───────────┐ │──────────▶│ │ -│ │setting.yml│ │ │ │ │RunFiles() │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ └───────────┘ │ │ │ └───────────┘ │ │ │ KCLResult │──┼────────▶│x.JSONString() │ -└─────────────────┘ │ │ │ │ └───────────┘ │ └───────────────┘ - │ │ │ │ │ -┌─────────────────┐ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ Options │ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.YAMLString() │ -│WithOptions │ │ │ │MustRun() │ │ │ └───────────┘ │ └───────────────┘ -│WithOverrides │────┘ │ └───────────┘ │ │ │ -│WithWorkDir │ │ │ │ │ -│WithDisableNone │ │ │ │ │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ -``` - -The input file contains the KCL file and the `setting.yml` configuration file, and `Options` can be used to specify additional parameters and information such as working directory. The "KCL-Go-API" part is the provided KCL execution function. The execution function executes the KCL program according to the input file and additional parameters, and finally outputs the result of `KCLResultList`. `KCLResultList` is a list of `KCLResult`, each `KCLResult` corresponding to a generated configuration file or `map[string]interface{}`. - -### Example - -```go -package main - -import ( - "fmt" - - kcl "kcl-lang.io/kcl-go" -) - - -func main() { - const k_code = ` -name = "kcl" -age = 1 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person{} -x1 = Person{age:101} -` - - result := kcl.MustRun("hello.k", kcl.WithCode(k_code)).First() - fmt.Println(result.YAMLString()) - - fmt.Println("----") - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - - fmt.Println("----") - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x1", &person)) -} -``` - -Output result: - -```yaml -age: 1 -name: kcl -x0: - age: 1 - name: kcl -x1: - age: 101 - name: kcl - ----- -x0.name: kcl -x1.age: 101 ----- -person: &{Name:kcl Age:101} -``` - -## Python API - -Using the Python SDK requires that you have a local Python version higher than 3.7.3 and a local pip package management tool. You can use the following command to install and obtain helpful information. - -```bash -python3 -m pip install kclvm --user && python3 -m kclvm --help -``` - -### Command Line Tool - -Prepare a KCL file named `main.k` - -```python -name = "kcl" -age = 1 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {} -x1 = Person { - age = 101 -} -``` - -Execute the following command and get the output: - -```shell -$ python3 -m kclvm hello.k -name: kcl -age: 1 -x0: - name: kcl - age: 1 -x1: - name: kcl - age: 101 -``` - -### API - -In addition, we can also execute KCL files through Python code. - -Prepare a KCL file named `main.py` - -```python -import kclvm.program.exec as kclvm_exec -import kclvm.vm.planner as planner - -print(planner.plan(kclvm_exec.Run(["hello.k"]).filter_by_path_selector())) -``` - -Execute the following command and get the output: - -```shell -$ python3 main.py -name: kcl -age: 1 -x0: - name: kcl - age: 1 -x1: - name: kcl - age: 101 -``` - -You can see that the same output can be obtained through command line tools and APIs. - -At present, the KCL Python SDK is still in the early preview version. The KCL team will continue to update and provide more functions in the future. For more information, see [https://github.com/kcl-lang/kcl-py](https://github.com/kcl-lang/kcl-py) - -## REST-API - -The C-API provided by KCL does not have a REST-API. The REST-API is defined by Protobuf. - -### Start REST Service - -The RestAPI service can be started in the following way: - -```shell -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -The service can then be requested via the POST protocol: - -```shell -$ curl -X POST http://127.0.0.1:2021/api:protorpc/BuiltinService.Ping --data '{}' -{ - "error": "", - "result": {} -} -``` - -The POST request and the returned JSON data are consistent with the structure defined by Protobuf. - -### `BuiltinService` - -Where the `/api:protorpc/BuiltinService.Ping` path represents the `Ping` method of the `BuiltinService` service. - -The complete `BuiltinService` is defined by Protobuf: - -```protobuf -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} -``` - -The `Ping` method can verify whether the service is normal, and the `ListMethod` method can query the list of all services and functions provided. - -### `KclvmService` - -The `KclvmService` service is a service related to KCL functionality. The usage is the same as the `BuiltinService` service. - -For example, there is the following `Person` structure definition: - -```python -schema Person: - key: str - - check: - "value" in key # 'key' is required and 'key' must contain "value" -``` - -Then we want to use `Person` to verify the following JSON data: - -```json -{ "key": "value" } -``` - -This can be done through the `ValidateCode` method of the `KclvmService` service. Refer to the `ValidateCode_Args` structure of the `ValidateCode` method: - -```protobuf -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} -``` - -Construct the JSON data required by the POST request according to the `ValidateCode_Args` structure, which contains the `Person` definition and the JSON data to be verified: - -```json -{ - "code": "\nschema Person:\n key: str\n\n check:\n \"value\" in key # 'key' is required and 'key' must contain \"value\"\n", - "data": "{\"key\": \"value\"}" -} -``` - -Save this JSON data to the `vet-hello.json` file and verify it with the following command: - -```shell -$ curl -X POST \ - http://127.0.0.1:2021/api:protorpc/KclvmService.ValidateCode \ - -H "accept: application/json" \ - --data @./vet-hello.json -{ - "error": "", - "result": { - "success": true - } -} -``` - -## APIs in other languages - -Coming soon diff --git a/versioned_docs/version-0.5.4/reference/xlang-api/python-api.md b/versioned_docs/version-0.5.4/reference/xlang-api/python-api.md deleted file mode 100644 index e6ce67dc..00000000 --- a/versioned_docs/version-0.5.4/reference/xlang-api/python-api.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Python API - -At present, the KCL Python SDK is still in the early preview version. The KCL team will continue to update and provide more functions in the future. For more information, see [https://github.com/kcl-lang/kcl-py](https://github.com/kcl-lang/kcl-py) diff --git a/versioned_docs/version-0.5.4/reference/xlang-api/rest-api.md b/versioned_docs/version-0.5.4/reference/xlang-api/rest-api.md deleted file mode 100644 index 4723280f..00000000 --- a/versioned_docs/version-0.5.4/reference/xlang-api/rest-api.md +++ /dev/null @@ -1,443 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Rest API - -## 1. Start REST Service - -The RestAPI service can be started in the following ways: - -```shell -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -or - -```shell -go install kcl-lang.io/kcl-go/cmds/kcl-go@main -kcl-go rest-server -``` - -The service can then be requested via the POST protocol: - -```shell -$ curl -X POST http://127.0.0.1:2021/api:protorpc/BuiltinService.Ping --data '{}' -{ - "error": "", - "result": {} -} -``` - -The POST request and the returned JSON data are consistent with the structure defined by Protobuf. - -## 2. `BuiltinService` - -Where the `/api:protorpc/BuiltinService.Ping` path represents the `Ping` method of the `BuiltinService` service. - -The complete `BuiltinService` is defined by Protobuf: - -```protobuf -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} -``` - -The `Ping` method can verify whether the service is normal, and the `ListMethod` method can query the list of all services and functions provided. - -## 3. `KclvmService` - -The `KclvmService` service is a service related to KCL functionality. The usage is the same as the `BuiltinService` service. - -For example, there is the following `Person` structure definition: - -```python -schema Person: - key: str - - check: - "value" in key # 'key' is required and 'key' must contain "value" -``` - -Then we want to use `Person` to verify the following JSON data: - -```json -{ "key": "value" } -``` - -This can be done through the `ValidateCode` method of the `KclvmService` service. Refer to the `ValidateCode_Args` structure of the `ValidateCode` method: - -```protobuf -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} -``` - -Construct the JSON data required by the POST request according to the `ValidateCode_Args` structure, which contains the `Person` definition and the JSON data to be verified: - -```json -{ - "code": "\nschema Person:\n key: str\n\n check:\n \"value\" in key # 'key' is required and 'key' must contain \"value\"\n", - "data": "{\"key\": \"value\"}" -} -``` - -Save this JSON data to the `vet-hello.json` file and verify it with the following command: - -```shell -$ curl -X POST \ - http://127.0.0.1:2021/api:protorpc/KclvmService.ValidateCode \ - -H "accept: application/json" \ - --data @./vet-hello.json -{ - "error": "", - "result": { - "success": true - } -} -``` - -## 4. Complete Protobuf Service Definition - -Cross-language APIs defined via Protobuf([https://github.com/kcl-lang/kcl-go/blob/main/pkg/spec/gpyrpc/gpyrpc.proto](https://github.com/kcl-lang/kcl-go/blob/main/pkg/spec/gpyrpc/gpyrpc.proto)): - -```protobuf -// Copyright 2023 The KCL Authors. All rights reserved. -// -// This file defines the request parameters and return structure of the KCL RPC server. -// We can use the following command to start a KCL RPC server. - -syntax = "proto3"; - -package gpyrpc; - -import "google/protobuf/any.proto"; -import "google/protobuf/descriptor.proto"; - -// ---------------------------------------------------------------------------- - -// kcl main.k -D name=value -message CmdArgSpec { - string name = 1; - string value = 2; -} - -// kcl main.k -O pkgpath:path.to.field=field_value -message CmdOverrideSpec { - string pkgpath = 1; - string field_path = 2; - string field_value = 3; - string action = 4; -} - -// ---------------------------------------------------------------------------- -// gpyrpc request/response/error types -// ---------------------------------------------------------------------------- - -message RestResponse { - google.protobuf.Any result = 1; - string error = 2; - KclError kcl_err = 3; -} - -message KclError { - string ewcode = 1; // See kclvm/kcl/error/kcl_err_msg.py - string name = 2; - string msg = 3; - repeated KclErrorInfo error_infos = 4; -} - -message KclErrorInfo { - string err_level = 1; - string arg_msg = 2; - string filename = 3; - string src_code = 4; - string line_no = 5; - string col_no = 6; -} - -// ---------------------------------------------------------------------------- -// service requset/response -// ---------------------------------------------------------------------------- - -// gpyrpc.BuiltinService -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -// gpyrpc.KclvmService -service KclvmService { - rpc Ping(Ping_Args) returns(Ping_Result); - - rpc ExecProgram(ExecProgram_Args) returns(ExecProgram_Result); - - rpc FormatCode(FormatCode_Args) returns(FormatCode_Result); - rpc FormatPath(FormatPath_Args) returns(FormatPath_Result); - rpc LintPath(LintPath_Args) returns(LintPath_Result); - rpc OverrideFile(OverrideFile_Args) returns (OverrideFile_Result); - - rpc GetSchemaType(GetSchemaType_Args) returns(GetSchemaType_Result); - rpc GetSchemaTypeMapping(GetSchemaTypeMapping_Args) returns(GetSchemaTypeMapping_Result); - rpc ValidateCode(ValidateCode_Args) returns(ValidateCode_Result); - - rpc ListDepFiles(ListDepFiles_Args) returns(ListDepFiles_Result); - rpc LoadSettingsFiles(LoadSettingsFiles_Args) returns(LoadSettingsFiles_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} - -message ParseFile_AST_Args { - string filename = 1; - string source_code = 2; -} -message ParseFile_AST_Result { - string ast_json = 1; // json value - KclError kcl_err = 2; -} - -message ParseProgram_AST_Args { - repeated string k_filename_list = 1; -} -message ParseProgram_AST_Result { - string ast_json = 1; // json value - KclError kcl_err = 2; -} - -message ExecProgram_Args { - string work_dir = 1; - - repeated string k_filename_list = 2; - repeated string k_code_list = 3; - - repeated CmdArgSpec args = 4; - repeated CmdOverrideSpec overrides = 5; - - bool disable_yaml_result = 6; - - bool print_override_ast = 7; - - // -r --strict-range-check - bool strict_range_check = 8; - - // -n --disable-none - bool disable_none = 9; - // -v --verbose - int32 verbose = 10; - - // -d --debug - int32 debug = 11; - - // yaml/json: sort keys - bool sort_keys = 12; - // include schema type path in JSON/YAML result - bool include_schema_type_path = 13; -} -message ExecProgram_Result { - string json_result = 1; - string yaml_result = 2; - - string escaped_time = 101; -} - -message ResetPlugin_Args { - string plugin_root = 1; -} -message ResetPlugin_Result { - // empty -} - -message FormatCode_Args { - string source = 1; -} - -message FormatCode_Result { - bytes formatted = 1; -} - -message FormatPath_Args { - string path = 1; -} - -message FormatPath_Result { - repeated string changed_paths = 1; -} - -message LintPath_Args { - repeated string paths = 1; -} - -message LintPath_Result { - repeated string results = 1; -} - -message OverrideFile_Args { - string file = 1; - repeated string specs = 2; - repeated string import_paths = 3; -} - -message OverrideFile_Result { - bool result = 1; -} - -message EvalCode_Args { - string code = 1; -} -message EvalCode_Result { - string json_result = 2; -} - -message ResolveCode_Args { - string code = 1; -} - -message ResolveCode_Result { - bool success = 1; -} - -message GetSchemaType_Args { - string file = 1; - string code = 2; - string schema_name = 3; -} -message GetSchemaType_Result { - repeated KclType schema_type_list = 1; -} - -message GetSchemaTypeMapping_Args { - string file = 1; - string code = 2; - string schema_name = 3; -} -message GetSchemaTypeMapping_Result { - map schema_type_mapping = 1; -} - -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} - -message ValidateCode_Result { - bool success = 1; - string err_message = 2; -} - -message Position { - int64 line = 1; - int64 column = 2; - string filename = 3; -} - -message ListDepFiles_Args { - string work_dir = 1; - bool use_abs_path = 2; - bool include_all = 3; - bool use_fast_parser = 4; -} - -message ListDepFiles_Result { - string pkgroot = 1; - string pkgpath = 2; - repeated string files = 3; -} - -// --------------------------------------------------------------------------------- -// LoadSettingsFiles API -// Input work dir and setting files and return the merged kcl singleton config. -// --------------------------------------------------------------------------------- - -message LoadSettingsFiles_Args { - string work_dir = 1; - repeated string files = 2; -} - -message LoadSettingsFiles_Result { - CliConfig kcl_cli_configs = 1; - repeated KeyValuePair kcl_options = 2; -} - -message CliConfig { - repeated string files = 1; - string output = 2; - repeated string overrides = 3; - repeated string path_selector = 4; - bool strict_range_check = 5; - bool disable_none = 6; - int64 verbose = 7; - bool debug = 8; -} - -message KeyValuePair { - string key = 1; - string value = 2; -} - -// ---------------------------------------------------------------------------- -// JSON Schema Lit -// ---------------------------------------------------------------------------- - -message KclType { - string type = 1; // schema, dict, list, str, int, float, bool, any, union, number_multiplier - repeated KclType union_types = 2 ; // union types - string default = 3; // default value - - string schema_name = 4; // schema name - string schema_doc = 5; // schema doc - map properties = 6; // schema properties - repeated string required = 7; // required schema properties, [property_name1, property_name2] - - KclType key = 8; // dict key type - KclType item = 9; // dict/list item type - - int32 line = 10; - - repeated Decorator decorators = 11; // schema decorators -} - -message Decorator { - string name = 1; - repeated string arguments = 2; - map keywords = 3; -} - -// ---------------------------------------------------------------------------- -// END -// ---------------------------------------------------------------------------- -``` diff --git a/versioned_docs/version-0.5.4/tools/Ide/_category_.json b/versioned_docs/version-0.5.4/tools/Ide/_category_.json deleted file mode 100644 index d9bfcdd7..00000000 --- a/versioned_docs/version-0.5.4/tools/Ide/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "IDE", - "position": 2 -} diff --git a/versioned_docs/version-0.5.4/tools/Ide/index.md b/versioned_docs/version-0.5.4/tools/Ide/index.md deleted file mode 100644 index aec7245a..00000000 --- a/versioned_docs/version-0.5.4/tools/Ide/index.md +++ /dev/null @@ -1,6 +0,0 @@ -# IDE - -We have provided two simple kinds of plugins for KCL. You can get more help information at the following link: - -- IntelliJ Plugin: https://github.com/kcl-lang/intellij-kcl -- VSCode Plugin: https://github.com/kcl-lang/vscode-kcl diff --git a/versioned_docs/version-0.5.4/tools/Ide/intellij.md b/versioned_docs/version-0.5.4/tools/Ide/intellij.md deleted file mode 100644 index be637514..00000000 --- a/versioned_docs/version-0.5.4/tools/Ide/intellij.md +++ /dev/null @@ -1,3 +0,0 @@ -# IntelliJ IDEA - -- IntelliJ Plugin: https://github.com/kcl-lang/intellij-kcl diff --git a/versioned_docs/version-0.5.4/tools/Ide/vs-code.md b/versioned_docs/version-0.5.4/tools/Ide/vs-code.md deleted file mode 100644 index 6b00815c..00000000 --- a/versioned_docs/version-0.5.4/tools/Ide/vs-code.md +++ /dev/null @@ -1,55 +0,0 @@ -# KCL Extension for Visual Studio Code - -## Quick Start - -- **Step 1.** [Install KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) on your system. Please check that `kcl` and `kcl-language-server` are installed and have been added to your PATH: - - ```bash - which kcl - which kcl-language-server - ``` - -- **Step 2.** Install the [KCL extension](https://marketplace.visualstudio.com/items?itemName=kcl.kcl-vscode-extension) for Visual Studio Code. This extension requires the VS Code 1.50+. -- **Step 3.** Reopen VS Code and create a KCL file and begin your KCL tour! - -## Features - -This extension provides some coding assistance, including the following features: - -- **Syntax Highlight:** - ![Highlight](/img/docs/tools/Ide/vs-code/Highlight.png) -- **Goto Definition:** Goto definition of schema, variable, schema attribute, and import pkg. - ![Goto Definition](/img/docs/tools/Ide/vs-code/GotoDef.gif) -- **Completion:** Keywords completions and dot(`.`) completion. - ![Completion](/img/docs/tools/Ide/vs-code/Completion.gif) -- **Outline:** Main definition(schema def) and variables in KCL file. - ![Outline](/img/docs/tools/Ide/vs-code/Outline.gif) -- **Hover:** Identifier information (type and schema documentation). - ![Hover](/img/docs/tools/Ide/vs-code/Hover.gif) -- **Diagnostics:** Warnings and errors in KCL file. - - > Tips: You can enhance the effect of diagnostics by installing another plugin: [Error Lens](https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens). - - ![Diagnostics](/img/docs/tools/Ide/vs-code/Diagnostics.gif) - -Other useful features such as refactoring and testing are in development. - -## Dependencies - -We recommend that you use the latest version of KCL, but the minimum required version for this extension is 0.4.6. If you are using an earlier version, the extension may not work properly. - -## Known Issues - -See [here](https://github.com/kcl-lang/kcl/issues/524). - -## Ask for help - -If the extension isn't working as you expect, please contact us with [community](https://kcl-lang.io/docs/community/intro/support) for help. - -## Contributing - -We are working actively on improving the KCL development on VS Code. All kinds of contributions are welcomed. You can refer to our [contribution guide](https://kcl-lang.io/docs/community/contribute). It introduces how to build and run the extension locally, and describes the process of sending a contribution. - -## License - -Apache License 2.0 diff --git a/versioned_docs/version-0.5.4/tools/_category_.json b/versioned_docs/version-0.5.4/tools/_category_.json deleted file mode 100644 index 5ecd522f..00000000 --- a/versioned_docs/version-0.5.4/tools/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Tools", - "position": 3 -} diff --git a/versioned_docs/version-0.5.4/tools/cli/_category_.json b/versioned_docs/version-0.5.4/tools/cli/_category_.json deleted file mode 100644 index 887061ef..00000000 --- a/versioned_docs/version-0.5.4/tools/cli/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Command Line Tools", - "position": 1 -} diff --git a/versioned_docs/version-0.5.4/tools/cli/index.md b/versioned_docs/version-0.5.4/tools/cli/index.md deleted file mode 100644 index ef4f69dc..00000000 --- a/versioned_docs/version-0.5.4/tools/cli/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# Command Line Tools - -KCL provides IDE plug-ins, rich language tools and OpenAPI tools. These tools provide a complete set of solutions, including configuration languages, model interfaces, automation tools, and best practices. diff --git a/versioned_docs/version-0.5.4/tools/cli/kcl/_category_.json b/versioned_docs/version-0.5.4/tools/cli/kcl/_category_.json deleted file mode 100644 index 4c605bd0..00000000 --- a/versioned_docs/version-0.5.4/tools/cli/kcl/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KCL Tools", - "position": 2 -} diff --git a/versioned_docs/version-0.5.4/tools/cli/kcl/docgen.md b/versioned_docs/version-0.5.4/tools/cli/kcl/docgen.md deleted file mode 100644 index ca647228..00000000 --- a/versioned_docs/version-0.5.4/tools/cli/kcl/docgen.md +++ /dev/null @@ -1,317 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Docgen - -The KCL Docgen tool supports extracting model documents from KCL source code and supports multiple output formats: JSON, YAML and Markdown. This article introduces the document specification of the KCL language, gives an example of how to use the KCL Docgen tool to extract documents, and shows the process of importing localization documents. - -## 1. Document Specification of KCL - -The documentation of the KCL file mainly contains the following two parts: - -- Current KCL Module document: description of the current KCL file -- All schema documents contained in the KCL file: a description of the current schema, including schema description, schema attribute descriptions, and Examples. The specific format is as follows: - -1. Schema description - -```python -"""This is a brief description of the Schema -""" -``` - -2. Description of each attribute of Schema: including attribute description, attribute type, default value, optional or required - -```python -""" -Attributes ----------- -x : type, default is a, optional. - Description of parameter `x`. -y : type, default is b, required. - Description of parameter `y`. -""" -``` - -`----------` indicates that `Attributes` is a title (the length of the symbol `-` is the same as the length of the title), the attribute name and attribute type are separated by a colon `:`, the description of the attribute is written on another line with indentation. The default value of the attribute is separated by a comma `,` after the attribute type, and it is written in the form of `default is {default value}`. In addition, it is necessary to indicate whether the attribute is optional/required. Write `optional` after the default value for an optional attribute, and write `required` after the default value for a required attribute. - -3. Examples - -```python -""" -Examples --------- -val = Schema { - name = "Alice" - age = 18 -} -""" -``` - -In addition, the KCL docstring syntax should use a subset of the [re-structured text (reST)](https://docutils.sourceforge.io/rst.html) and be rendered using the [Sphinx](https://www.sphinx-doc.org/en/master/). - -## 2. Generating Documentation From KCL - -Use the `kcl-doc generate` command to extract documentation from a user-specified file or directory and output it to the specified directory. - -1. Args - -``` -usage: kcl-doc generate [-h] [--format YAML] [-o OUTPUT] [--r] - [--i18n-locale LOCALE] [--repo-url REPO_URL] - [files [files ...]] - -positional arguments: - files KCL file paths. If there's more than one files to - generate, separate them by space - -optional arguments: - -h, --help show this help message and exit - --format YAML Doc file format, support YAML, JSON and MARKDOWN. - Defaults to MARKDOWN - -o OUTPUT, --output-path OUTPUT - Specify the output directory. Defaults to ./kcl_doc - --r, -R, --recursive Search directory recursively - --i18n-locale LOCALE I18n locale, e.g.: zh, zh_cn, en, en_AS. Defaults to - en - --repo-url REPO_URL The source code repository url. It will be displayed in - the generated doc to link to the source code. -``` - -2. Extract documents from the file(s) and output them to the specified directory - -```text -kcl-doc generate your_config.k your_another_config.k -o your_docs_output_dir -``` - -3. From the specified directory, recursively find the KCL file(s) and extract the documentation - -```text -kcl-doc generate your_config_dir -r -o your_docs_output_dir -``` - -4. When generating documentation, specify the source code repository address. The generated documentation will contain links to source files - -```text -kcl-doc generate your_config.k -o your_docs_output_dir --repo-url https://url/to/source_code -``` - -## 3. Add Documentation for Localized Languages - -As shown before, by default, the documentation extracted by the documentation generation tool is based on the content of the source docstring, and thus the language of the documentation depends on the language in which the docstring was written. If you need to add localized language documentation to the source file, you can follow the steps below: - -1. Initialize the i18n configuration file. This step generates the corresponding i18n configuration file based on the specified KCL file. The file format can be JSON/YAML, and the default is YAML. The output profile name will end in the specified target localization language - -```text -kcl-doc init-i18n your_config.k --format JSON --i18n-locale your_target_locale -``` - -2. Modify the i18n configuration file and update each doc field in your locale language - -3. Generate localized documents from the modified i18n configuration file - -```text -kcl-doc generate your_config_dir --i18n-locale your_target_locale --format Markdown -``` - -Next, a simple example is used to demonstrate the process of adding localized language documents. - -3.1 Prepare the KCL file, such as `server.k`: - - ```python - schema Server: - """Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - - Attributes - ---------- - workloadType : str, default is "Deployment", required - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - name : str, required - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - labels : {str:str}, optional - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - - Examples - ---------------------- - myCustomApp = AppConfiguration { - name = "componentName" - } - """ - - workloadType: str = "Deployment" - name: str - labels?: {str: str} - ``` - -3.2 Get the initialized i18n configuration file from the `server.k`. For example, if you want to add Chinese documents to it, specify the format of the generated configuration file as YAML - - ```text - kcl-doc init-i18n server.k --format YAML --i18n-locale zh_cn - ``` - - This command will create the directory `kcl_doc` under the current directory and generate the i18n configuration file `kcl_doc/i18n_server_zh_cn.yaml`. Its contents are as follows: - - ```yaml - name: server - relative_path: ./server.k - schemas: - - name: Server - doc: | - Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - attributes: - - name: workloadType - doc: | - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - default_value: '"Deployment"' - is_optional: false - - name: name - doc: | - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: false - default_value: '' - - name: labels - doc: | - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - type: - type_str: '{str: str}' - type_category: DICT - dict_type: - key_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - value_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: true - default_value: '' - examples: | - myCustomApp = AppConfiguration { - name = "componentName" - } - doc: '' - source_code_url: '' - ``` - -3.3 Modify all the `doc` fields to the Chinese description. The modified configuration is as follows: - - ```yaml - name: server - relative_path: ./server.k - schemas: - - name: Server - doc: | - Server 模型定义了采用 Kubernetes 最佳实践的持续运行的服务的通用配置接口 - attributes: - - name: workloadType - doc: | - workloadType 属性定义了服务的类型,是服务级别的属性。合法的取值有:Deployment, CafeDeployment. - 另请查看:k8s/core/v1/workload_metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - default_value: '"Deployment"' - is_optional: false - - name: name - doc: | - name 为服务的名称,是服务级别的属性。 - 另请查看:k8s/core/v1/metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: false - default_value: '' - - name: labels - doc: | - labels 为服务的标签,是服务级别的属性。 - 另请查看:k8s/core/v1/metadata.k. - type: - type_str: '{str: str}' - type_category: DICT - dict_type: - key_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - value_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: true - default_value: '' - examples: | - myCustomApp = AppConfiguration { - name = "componentName" - } - doc: '' - source_code_url: '' - ``` - -3.4 Based on the modified i18n configuration, generate documents in localized languages. Execute the following command to output the Chinese document `kcl_doc/doc_server_zh_cn.md`. The commands and the contents of the generated documents are as follows: - -```text -kcl-doc generate server.k --i18n-locale zh_cn --format Markdown -``` - -````markdown -# server - -## Schema Server - -Server 模型定义了采用 Kubernetes 最佳实践的持续运行的服务的通用配置接口 - -### Attributes - -| Name and Description | Type | Default Value | Required | -| -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | ------------- | ------------ | -| **workloadType**
workloadType 属性定义了服务的类型,是服务级别的属性。合法的取值有:Deployment, CafeDeployment.
另请查看:k8s/core/v1/workload_metadata.k. | str | "Deployment" | **required** | -| **name**
name 为服务的名称,是服务级别的属性。
另请查看:k8s/core/v1/metadata.k. | str | Undefined | **required** | -| **labels**
labels 为服务的标签,是服务级别的属性。
另请查看:k8s/core/v1/metadata.k. | {str: str} | Undefined | optional | - -### Examples - -``` -myCustomApp = AppConfiguration { - name = "componentName" -} -``` - - -```` - -## 4. Appendix - -### 1. Concept of reST - -For documents in reST format, paragraphs and indentation are important, new paragraphs are marked with blank lines, and indentation is the indentation indicated in the output. Font styles can be expressed as follows: - -- \*Italic\* -- \*\*Bold\*\* -- \`\`Monospaced\`\` - -Refer to [reST](https://docutils.sourceforge.io/rst.html) for more information. diff --git a/versioned_docs/version-0.5.4/tools/cli/kcl/fmt.md b/versioned_docs/version-0.5.4/tools/cli/kcl/fmt.md deleted file mode 100644 index eaf562cd..00000000 --- a/versioned_docs/version-0.5.4/tools/cli/kcl/fmt.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Format - -The KCL Format tool supports reformatting KCL files to the standard code style. This article demonstrates the KCL code style and how to use the KCL Format tool. - -## Code Style - -The KCL Format tool modifies the files according to the KCL code style: [Style Guide for KCL Code](/docs/reference/lang/spec/codestyle) - -## How to use - -- Formatting Single File - -```text -kcl-fmt your_config.k -``` - -- Formatting multiple files - -```text -kcl-fmt your_config_path -R -``` - -- Args - - `-R|--recursive` Whether to recursively traverse subfolders - - `-w|--fmt-output` Whether to output to STDOUT, without `-w` indicates in-place modification. - -## Display of formatting files - -- Before formatting - -```py -import math -mixin DeploymentMixin: - service:str ="my-service" -schema DeploymentBase: - name: str - image : str -schema Deployment[replicas] ( DeploymentBase ) : - mixin[DeploymentMixin] - replicas : int = replicas - command: [str ] - labels: {str: str} -deploy = Deployment(replicas = 3){} -``` - -- After formatting - -```py -import math - -mixin DeploymentMixin: - service: str = "my-service" - -schema DeploymentBase: - name: str - image: str - -schema Deployment[replicas](DeploymentBase): - mixin [DeploymentMixin] - replicas: int = replicas - command: [str] - labels: {str:str} - -deploy = Deployment(replicas=3) {} - -``` diff --git a/versioned_docs/version-0.5.4/tools/cli/kcl/index.md b/versioned_docs/version-0.5.4/tools/cli/kcl/index.md deleted file mode 100644 index b750f652..00000000 --- a/versioned_docs/version-0.5.4/tools/cli/kcl/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# KCL Language Tools - -KCL not only provides the command `kcl` to compile and execute configuration programs but also provides fmt, lint, test, vet, docgen and other supporting tools. diff --git a/versioned_docs/version-0.5.4/tools/cli/kcl/lint.md b/versioned_docs/version-0.5.4/tools/cli/kcl/lint.md deleted file mode 100644 index 627177a9..00000000 --- a/versioned_docs/version-0.5.4/tools/cli/kcl/lint.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Lint - -The KCL Lint tool supports checking some warning-level defects in KCL code and supports multiple output formats. This document shows how to use the KCL Lint tool. - -## Example - -### Project Struct - -```text -. -└── Test - └── kcl.mod - └── a.k - └── b.k - └── dir - └── c.k - └── test.k -``` - -`a.k`, `b.k`, `c.k` and `test.k` are the kcl file to be checked. - -Args: - -```shell -kcl-lint your_config.k -``` - -or - -```shell -kcl-lint your_config_path -``` - -## KCL Lint Tool - -### Args - -```shell -USAGE: - kcl-lint [OPTIONS] [--] [input]... - -ARGS: - ... Sets the input file to use - -OPTIONS: - --emit_warning Emit warning message - -h, --help Print help information - -v, --verbose Print test information verbosely - -Y, --setting ... Sets the input file to use -``` - -- input: the path of a single `*.k` file or directory to be checked. Support the absolute path or relative path of the current directory. diff --git a/versioned_docs/version-0.5.4/tools/cli/kcl/overview.md b/versioned_docs/version-0.5.4/tools/cli/kcl/overview.md deleted file mode 100644 index b1354b8c..00000000 --- a/versioned_docs/version-0.5.4/tools/cli/kcl/overview.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Overview - -KCL toolchain is a toolset of KCL language, which aims to improve the efficiency of batch migration, writing, compiling and running of KCL. - -| | Name | Description | -| ---------- | ------------------------ | ------------------------------------------------------------------- | -| Main Tools | **kcl** | Provide support for KCL in coding, compiling and running | -| | kcl-test | Coming soon | -| | kcl-lint | Check code style for KCL | -| | kcl-doc | Parses the KCL code and generate documents | -| | kcl-fmt | Format the kcl code | -| | kcl-vet | Validate data files such as JSON and YAML using KCL | -| IDE Plugin | IntelliJ IDEA KCL plugin | Provide assistance for KCL in coding and compiling on IntelliJ IDEA | -| | VS Code KCL plugin | Provide assistance for KCL in coding and compiling on VS Code | - -## KCL Tool - -### Args - -```shell -USAGE: - kcl [OPTIONS] [--] [input]... - -Arguments: - [input]... Specify the input files to run - -Options: - -o, --output - Specify the YAML output file path - -Y, --setting ... - Specify the input setting file - -v, --verbose... - Print test information verbosely - -n, --disable_none - Disable dumping None values - -r, --strict_range_check - Do perform strict numeric range checks - -d, --debug - Run in debug mode (for developers only) - -k, --sort_keys - Sort result keys - -D, --argument ... - Specify the top-level argument - -S, --path_selector ... - Specify the path selector - -O, --overrides ... - Specify the configuration override path and value - --target - Specify the target type - -E, --external ... - Mapping of package name and path where the package is located - -h, --help - Print help -``` diff --git a/versioned_docs/version-0.5.4/tools/cli/kcl/test.md b/versioned_docs/version-0.5.4/tools/cli/kcl/test.md deleted file mode 100644 index 4f99e53d..00000000 --- a/versioned_docs/version-0.5.4/tools/cli/kcl/test.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Test Tool - -Coming soon. diff --git a/versioned_docs/version-0.5.4/tools/cli/kcl/vet.md b/versioned_docs/version-0.5.4/tools/cli/kcl/vet.md deleted file mode 100644 index d2f2220e..00000000 --- a/versioned_docs/version-0.5.4/tools/cli/kcl/vet.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Validation - -## Intro - -The KCL Validation tool supports basic configuration data verification capabilities. You can write a KCL schema to verify the type and value of the input JSON/YAML files. - -## How to use - -There is a JSON format file `data.json`: - -```json -{ - "name": "Alice", - "age": 18, - "message": "This is Alice", - "data": { - "id": 1, - "value": "value1" - }, - "labels": { - "key": "value" - }, - "hc": [1, 2, 3] -} -``` - -Build a validated KCL file `schema.k`: - -```py -schema User: - name: str - age: int - message?: str - data: Data - labels: {str:} - hc: [int] - - check: - age > 10 - -schema Data: - id: int - value: str -``` - -Execute the following command: - -```shell -kcl-vet data.json schema.k -``` - -## Specify the schema for validation - -When multiple schema definitions exist in the KCL file, by default, the KCL Validation tool will use the first schema to check. If you need to specify a schema for verification, you can use the `-d|--schema` parameter - -```shell -kcl-vet data.json schema.k -d User -``` - -## Args - -```shell -$ kcl-vet -h -USAGE: - kcl-vet [OPTIONS] [ARGS] - -ARGS: - Validation data file - KCL file - -OPTIONS: - -d, --schema - Iterate through subdirectories recursively - - --format - Validation data file format, support YAML and JSON, default is JSON - - -h, --help - Print help information - - -n, --attribute_name - The attribute name for the data loading -``` diff --git a/versioned_docs/version-0.5.4/tools/cli/openapi/_category_.json b/versioned_docs/version-0.5.4/tools/cli/openapi/_category_.json deleted file mode 100644 index 58e4c68a..00000000 --- a/versioned_docs/version-0.5.4/tools/cli/openapi/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "OpenAPI Tools", - "position": 3 -} diff --git a/versioned_docs/version-0.5.4/tools/cli/openapi/crd-to-kcl.md b/versioned_docs/version-0.5.4/tools/cli/openapi/crd-to-kcl.md deleted file mode 100644 index aafebcd9..00000000 --- a/versioned_docs/version-0.5.4/tools/cli/openapi/crd-to-kcl.md +++ /dev/null @@ -1,118 +0,0 @@ -# CRD to KCL - -To convert from models defined in the Kubernetes CRD file to KCL schema, we could run the following script: - -```shell -kcl-openapi generate model --crd -f ${your_CRD.yaml} -t ${the_kcl_files_output_dir} --skip-validation -``` - -## Example - -- There is the Kubernetes CRD file that we need to convert: `test_crontab_CRD.yaml`: - -```yaml -# Deprecated in v1.16 in favor of apiextensions.k8s.io/v1 -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - # name must match the spec fields below, and be in the form: . - name: crontabs.stable.example.com -spec: - # group name to use for REST API: /apis// - group: stable.example.com - # list of versions supported by this CustomResourceDefinition - versions: - - name: v1 - # Each version can be enabled/disabled by Served flag. - served: true - # One and only one version must be marked as the storage version. - storage: true - # either Namespaced or Cluster - scope: Namespaced - names: - # plural name to be used in the URL: /apis/// - plural: crontabs - # singular name to be used as an alias on the CLI and for display - singular: crontab - # kind is normally the CamelCased singular type. Your resource manifests use this. - kind: CronTab - # shortNames allow shorter string to match your resource on the CLI - shortNames: - - ct - preserveUnknownFields: false - validation: - openAPIV3Schema: - type: object - properties: - spec: - type: object - properties: - cronSpec: - type: string - image: - type: string - replicas: - type: integer -``` - -- The script will be: - -```shell -kcl-openapi generate model -f test_crontab_CRD.yaml -t ~/ --skip-validation --crd -``` - -- Then we can find the generated file here: `~/models/stable_example_com_v1_cron_tab.k` - -```python -""" -This file was generated by the KCL auto-gen tool. DO NOT EDIT. -Editing this file might prove futile when you re-run the KCL auto-gen generate command. -""" -import kusion_kubernetes.apimachinery.apis - - -schema CronTab: - """stable example com v1 cron tab - - Attributes - ---------- - apiVersion : str, default is "stable.example.com/v1", required - APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - kind : str, default is "CronTab", required - Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - metadata : apis.ObjectMeta, default is Undefined, optional - metadata - spec : StableExampleComV1CronTabSpec, default is Undefined, optional - spec - """ - - - apiVersion: "stable.example.com/v1" = "stable.example.com/v1" - - kind: "CronTab" = "CronTab" - - metadata?: apis.ObjectMeta - - spec?: StableExampleComV1CronTabSpec - - -schema StableExampleComV1CronTabSpec: - """stable example com v1 cron tab spec - - Attributes - ---------- - cronSpec : str, default is Undefined, optional - cron spec - image : str, default is Undefined, optional - image - replicas : int, default is Undefined, optional - replicas - """ - - - cronSpec?: str - - image?: str - - replicas?: int -``` diff --git a/versioned_docs/version-0.5.4/tools/cli/openapi/index.md b/versioned_docs/version-0.5.4/tools/cli/openapi/index.md deleted file mode 100644 index 236d6e36..00000000 --- a/versioned_docs/version-0.5.4/tools/cli/openapi/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# OpenAPI Tools - -The KCL OpenAPI tool can not only convert common models but also support CRD and other models. diff --git a/versioned_docs/version-0.5.4/tools/cli/openapi/openapi-to-kcl.md b/versioned_docs/version-0.5.4/tools/cli/openapi/openapi-to-kcl.md deleted file mode 100644 index bef582ec..00000000 --- a/versioned_docs/version-0.5.4/tools/cli/openapi/openapi-to-kcl.md +++ /dev/null @@ -1,64 +0,0 @@ -# OpenAPI to KCL - -To convert from models defined in the OpenAPI spec file to KCL schema, we could run the following script: - -```shell -kcl-openapi generate model -f ${your_open_api_spec.yaml} -t ${the_kcl_files_output_dir} -``` - -For example: - -- There is the OpenAPI spec file that we need to convert: `test_open_api_spec.yaml` - -```yaml -definitions: - v1.TestInt: - type: object - properties: - name: - type: string - format: int-or-string - required: - - name - x-kcl-type: - import: - package: v1.test_int - alias: test_int - type: TestInt -swagger: "2.0" -info: - title: KCL - version: v0.0.2 -paths: {} -``` - -- The script will be: - -```shell -kcl-openapi generate model -f test_open_api_spec.yaml -t ~/ --skip-validation -``` - -- Then we can find the generated file here: `~/models/v1/test_int.k` - -```python -""" -This is the test_int module in v1 package. -This file was generated by the KCL auto-gen tool. DO NOT EDIT. -Editing this file might prove futile when you re-run the KCL auto-gen generate command. -""" - - -schema TestInt: - """v1 test int - - Attributes - ---------- - name : int | str, default is Undefined, required - name - """ - - - name: int | str - - -``` diff --git a/versioned_docs/version-0.5.4/tools/cli/openapi/quick-start.md b/versioned_docs/version-0.5.4/tools/cli/openapi/quick-start.md deleted file mode 100644 index d5812e3a..00000000 --- a/versioned_docs/version-0.5.4/tools/cli/openapi/quick-start.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Quick Start - -## 1. Install KCLOpenAPI Tool - -The kcl-openapi tool can be installed in following ways: - -- [go install](#11-go-install) -- [curl|sh install (MacOS & Linux)](#12-curlsh-install-macos--linux) -- [download from release](#13-dowload-from-release) - -## 1.1 go install - -```shell -go install kcl-lang.io/kcl-openapi@latest -``` - -## 1.2 Curl|sh install (MacOS & Linux) - -If you don't have go, you can install the CLI with this one-liner: - -```shell -curl -fsSL https://kcl-lang.io/script/install-kcl-openapi.sh | /bin/bash -``` - -## 1.3 Download from release - -```shell -# 1. download the released binary from: -# https://github.com/kcl-lang/kcl-openapi/releases - -# 2. Unzip the package and add the binary location to PATH -export PATH=":$PATH" -``` - -## 1.4 Verify your installation - -```shell -➜ kcl-openapi -v -kcl-openapi 0.5.0 -``` - -## 2. Generate KCL Files - -- [OpenAPI to KCL](../openapi/openapi-to-kcl.md) -- [CRD to KCL](../openapi/crd-to-kcl.md) diff --git a/versioned_docs/version-0.5.4/tools/cli/openapi/spec.md b/versioned_docs/version-0.5.4/tools/cli/openapi/spec.md deleted file mode 100644 index 7a144e4c..00000000 --- a/versioned_docs/version-0.5.4/tools/cli/openapi/spec.md +++ /dev/null @@ -1,438 +0,0 @@ -# KCL OpenAPI Spec - -[OpenAPI](https://www.openapis.org/) defines the API Specification for API providers to describe their operations and models in a normative way and provides generating tools to automatically convert to client codes in specific languages. - -The KCL OpenAPI Spec describes the rules about how the OpenAPI definitions are translated to the KCL schemas. - -## The File Structure of the KCL OpenAPI - -According to the OpenAPI 3.0 specification, an OpenAPI file should at least contains four root objects: `openapi`, `components`, `info`, `paths`. The KCL OpenAPI focuses on the part in which the models are defined in the `definitions` object. Yet the `paths` part which describes the Restful API operations is not considered by the KCL OpenAPI Spec. - -:::info -Note: In addition to the objects listed above, the OpenAPI spec also supports `servers`, `security`, `tags`, and `externalDocs` as optional root objects, but none of them are concerned by KCL OpenAPI when generating model codes, so we do not need to fill in this section. Yet it won't make any difference if you do. -::: - -To put it more comprehensible for beginners, let's take a quick look at the root objects that forms the typical KCL OpenAPI file (snippets from swagger example [Petstore](https://petstore.swagger.io/). The KCL OpenAPI tool only focuses on the `definitions` object which describes two data models (`Pet` and `Category`), and the model `Pet` contains three attributes: `name`, `id`, and `category`) - -## KCL schema - -The KCL schema structure defines the "type" of configuration data. - -:::info -More information about KCL schema, see [KCL Language Tour#Schema](../../../reference/lang/tour.md) -::: - -In the OpenAPI spec, a KCL schema can be defined by adding a `definition` element within the `definitions` object. - -Example: -The following example defines two schemas in KCL: `Pet` and `Category`, followed by the corresponding data models defined in OpenAPI: - -```python -# KCL schema -schema Pet: - name: str - id?: int - category?: Category - -schema Category: - name?: str - -# The corresponding OpenAPI spec -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "id": { - "type": "integer", - "format": "int64" - }, - "category": { - "$ref": "#/definitions/Category" - } - }, - "required": [ - "name" - ] - }, - "Category": { - "type": "object", - "properties": { - "name": { - "type": "string" - } - } - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### Schema Name - -In KCL, the schema name is declared immediately after the schema keyword, and in OpenAPI, the name of the model is defined by the key of the definition element. - -### Schema Type - -The type of KCL schema in OpenAPI is always "object". As in the previous example, the value of the `type` object in `Pet` should be `object`. - -### Schema Attribute - -Zero or more attributes can be defined in the KCL schema. The declaration of attributes generally includes the following parts: - -- Attribute annotation: Optional, starting with `@`, such as `@deprecated` to indicate a deprecated attribute -- Attribute name: Required -- Attribute optional modifiers(`?`): Optional. A question mark indicates that the current attribute is optional and may not be assigned. Conversely, the absence of a question mark indicates a required attribute -- Attribute type: Required. The attribute can be a primitive data type, a schema type, or a combination of the two preceding types -- Attribute default value: Optional - -The mapping between them and the OpenAPI spec is as follows: - -| Elements of KCL Schema Attribute | Corresponding Elements in OpenAPI | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| attribute annotation | Not supported. We are planning to add an extension `deprecate` field to the KCL-OpenAPI | -| attribute name | The key of the property under the `property` object | -| attribute optional modifiers(`?`) | In each element in the `definition` object, here's an optional `required` field which lists the all the required attributes of that model, and the attributes not listed are optional | -| attribute type | The basic types can be declared by a combination of `type` and `format`, and the schema type is declared by a `$ref` to the schema definition. KCL-OpenAPI spec adds a `x-kcl-types` extension to indicate a type union. `enum` indicates a union of several literal types. For the type declaration in KCL-OpenAPI, see the chapter - [basic data types](#basic-data-types) | -| attribute default value | The value of the `default` field is used to set the default value for the attribute | - -Example: - -The following KCL code defines a Pet model which contains two attributes: name (`string` type, `required`, with no attribute annotation and no default value) and id (`int64` type, optional, with no attribute annotation, and the default value is -1). - -```python -# the KCL schema Pet defines two attributes: name, id -schema Pet: - name: str - id?: int = -1 - -# The corresponding OpenAPI spec -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - "id": { - "type": "integer", - "format": "int64", - "default": -1 - } - }, - "required": [ - "name" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### Schema Index Signature - -In the KCL schema, the index signatures can be used to define attributes with undefined attribute names. The KCL schema index signature contains the following elements: - -- Type of the key in the index signature: Declared in square brackets. It must be the basic type -- Type of value in the index signature: Declared after the colon in the square brackets. It can be any valid KCL type -- Ellipses(`...`) in the index signature: In the square brackets, before the type declaration of the key. It indicates that the index signature is only used to constrain attributes not defined in the schema. The absentation of the symbol indicates that all defined and undefined attributes in the schema are constrained by the index signature. -- Alias for key in index signature: Declared in square brackets, immediately after the left square bracket and takes the form of `:`. The alias can then be used to reference the index signature by name -- The default value of the index signature: Assign a value to the index signature as the default value - -The index signature with its key in `string` type can be described based on the field `additionalProperties`. Other index signatures with a key in types besides `string`, and the `check` expressions used to validate the index signature are not supported by the KCL OpenAPI spec. - -The mapping between them and the OpenAPI spec is as follows: - -| Elements of KCL Index Signature | Corresponding Elements in OpenAPI | -| -------------------------------------------- | ----------------------------------------------------------------------------------------------- | -| Type of the key in the KCL index signature | Only string type is allowed in OpenAPI | -| Type of the value in the KCL index signature | Declared by the `type` in the `additionalProperties` field | -| Ellipses(`...`) in the index signature | Only the corresponding meaning of the attendance of the `...` symbol is allowed in OpenAPI | -| Alias for key in index signature | Not supported in KCL-OpenAPI yet. We are planning to add an `x-alias` extension to support that | -| Default value of the index signature | Not supported in KCL-OpenAPI | - -Example: - -The following KCL code defines a Pet model which contains two pre-declared attributes(`name` and `id`) and allows users to add attributes with `string` type keys and `bool` type values. - -```python -# the KCL schema Pet. Besides the pre-declared attributes name and id, it allows to add attributes with key in string type and value in bool type -schema Pet: - name: str - id?: int - [...str]: bool - -# The corresponding OpenAPI spec -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - "id": { - "type": "integer", - "format": "int64", - } - }, - "additionalProperties": { - "type": "bool" - }, - "required": [ - "name" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### Schema Inherit - -working in progress - -### Inline schema - -OpenAPI supports models to be declared inline. But KCL currently does not support that. The model defined inline in OpenAPI will be converted to a schema with a name in KCL. And the naming convention will be: - -| element to define an inline schema in OpenAPI | the name of the corresponding KCL schema | -| --------------------------------------------- | -------------------------------------------------------------- | -| inline Property | add the Property name at the end of the outer schema Name | -| AdditionalProperties | add "AdditionalProperties" at the end of the outer schema Name | - -We are planning to support inline schema in KCL, and when supported, the naming convention will be updated then. - -Example-1: - -The following KCL code defines a `Deployment` model which contains two attributes(`kind` and `spec`). And the schema of the `spec` attribute is defined inline. - -```python -# The OpenAPI spec -{ - "definitions": { - "Deployment": { - "type": "object", - "properties": { - "kind": { - "type": "string", - }, - "spec": { - "type": "object", - "properties": { - "replicas": { - "type": "integer", - "format": "int64" - } - } - } - }, - "required": [ - "kind", - "spec" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -# The corresponding KCL schemas -schema Deployment: - kind: str - spec: DeploymentSpec - -schema DeploymentSpec: - replicas?: int -``` - -Example-2: - -The following KCL code defines a Person model which contains a pre-declared attribute(`name`) and allows some `additionalProperties` to be assigned by user. And the type of the values in the `additionalProperties` is defined inline. - -```python -# The OpenAPI spec -{ - "definitions": { - "Person": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - }, - "required": [ - "name", - "spec" - ], - "additionalProperties": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "description": { - "type": "string" - } - }, - "required": [ - "name" - ] - }, - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -# The corresponding KCL schemas -schema Person: - name: str - [...str]: [PersonAdditionalProperties] - -schema PersonAdditionalProperties: - name: str - description?: str -``` - -## KCL Doc - -:::info -More information about KCL doc specification, please refer to the [KCL Document Specification](../kcl/docgen.md) -::: - -KCL documents consist of module documents and schema documents. And only the schema documents can be extracted from OpenAPI. The KCL schema document contains four parts: - -- Schema Description: Declared right after the schema declaration and before the schema attribute declaration. It provides an overview of schemas -- Schema Attribute Doc: Declared right after the schema Description and separated by `Attributes` + `---` delimiters. It describes the attribute -- Additional information about the schema: Declared right after the schema attribute doc and separated by `See Also` + `---` delimiters -- Example information about the schema: Declared right after the schema additional information and separated by `Examples` + `---` delimiters - -The mapping between them and the OpenAPI spec is as follows: - -| Elements of KCL Schema Document | Corresponding Elements in OpenAPI | -| --------------------------------------- | ------------------------------------------------------- | -| Schema Description | The value of the `description` field of the data model | -| Schema Attribute Doc | The value of the `description` field of the property | -| Additional information about the schema | The value of the `externalDocs` field of the data model | -| Example information about the schema | The value of the `example` field of the data model | - -Example: - -The following KCL code defines a Pet model with a schema description `The schema Pet definition`, and two attributes `name` and `id` with their attribute doc `The name of the pet` and `The id of the pet`; The additional information about the Pet schema is [here](https://petstore.swagger.io/) and the example to use the Pet schema are provided, too. - -```python -# The KCL schema Pet, with doc following the KCL Document Specification -schema Pet: - """The schema Pet definition - - Attributes - ---------- - name : str, default is Undefined, required - The name of the pet - id : int, default is -1, optional - The age of the pet - - See Also - -------- - Find more info here. https://petstore.swagger.io/ - - Examples - -------- - pet = Pet { - name = "doggie" - id = 123 - } - """ - name: str - id?: int = -1 - -# The corresponding OpenAPI Spec -{ - "definitions": { - "Pet": { - "description": "The schema Pet definition", - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "The name of the pet" - }, - "id": { - "type": "integer", - "format": "int64", - "default": -1, - "description": "The age of the pet" - } - }, - "required": [ - "name" - ], - "externalDocs": { - "description": "Find more info here", - "url": "https://petstore.swagger.io/" - }, - "example": { - "name": "doggie", - "id": 123 - } - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -## Basic Data Types - -| JSON Schema type | swagger type | KCL type | comment | -| ---------------- | --------------------------- | --------------- | --------------------------------------------------------------------------- | -| boolean | boolean | bool | | -| number | number | float | | -| | number format double | **unsupported** | | -| | number format float | float | | -| integer | integer | int (32) | | -| | integer format int64 | **unsupported** | | -| | integer format int32 | int (32) | | -| string | string | str | | -| | string format byte | str | | -| | string format int-or-string | int \| str | | -| | string format binay | str | | -| | string format date | unsupported | As defined by full-date - [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) | -| | string format date-time | unsupported | As defined by date-time - [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) | -| | string format password | unsupported | for swagger: A hint to UIs to obscure input | -| | datetime | datetime | | - -## Reference - -- OpenAPI spec 2.0: [https://swagger.io/specification/v2/](https://swagger.io/specification/v2/) -- OpenAPI spec 3.0: [https://spec.openapis.org/oas/v3.1.0](https://spec.openapis.org/oas/v3.1.0) -- OpenAPI spec 3.0: [https://swagger.io/specification/](https://swagger.io/specification/) -- OpenAPI spec 2.0: [https://swagger.io/specification/v2/#schemaObject](https://swagger.io/specification/v2/#schemaObject) -- Go swagger: [https://goswagger.io/use/models/schemas.html](https://goswagger.io/use/models/schemas.html) -- Swagger data models: [https://swagger.io/docs/specification/data-models/](https://swagger.io/docs/specification/data-models/) diff --git a/versioned_docs/version-0.5.4/user_docs/concepts/_category_.json b/versioned_docs/version-0.5.4/user_docs/concepts/_category_.json deleted file mode 100644 index d40bb9de..00000000 --- a/versioned_docs/version-0.5.4/user_docs/concepts/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Concepts", - "position": 5 -} diff --git a/versioned_docs/version-0.5.4/user_docs/concepts/concepts.md b/versioned_docs/version-0.5.4/user_docs/concepts/concepts.md deleted file mode 100644 index 627212ad..00000000 --- a/versioned_docs/version-0.5.4/user_docs/concepts/concepts.md +++ /dev/null @@ -1,3 +0,0 @@ -# Concepts - -Learn more about KCL concepts. diff --git a/versioned_docs/version-0.5.4/user_docs/concepts/package-and-module.md b/versioned_docs/version-0.5.4/user_docs/concepts/package-and-module.md deleted file mode 100644 index a36e45c9..00000000 --- a/versioned_docs/version-0.5.4/user_docs/concepts/package-and-module.md +++ /dev/null @@ -1,156 +0,0 @@ -# Module and Package - -This section mainly describes how to organize files in KCL. - -## Overview - -Within a **module**, KCL organizes files grouped by **package**. A package can be defined within a module or be imported externally (through KCL package manager `kpm`). In the latter case, KCL maintains a copy of the package within the module in a dedicated location. - -## Module - -A KCL module contains a configuration laid out in a directory hierarchy. It contains everything that is needed to deterministically determine the outcome of a KCL configuration. The root of this directory is marked by containing a `kcl.mod` directory. The contents of this directory are mostly managed by the kcl tool such as `kpm`, etc. In that sense, `kcl.mod` is analogous to the `.git` directory marking the root directory of a repo, but where its contents are mostly managed by the git tool. Besides, a KCL module is the largest unit of the file organization, has a fixed location of all KCL files and dependencies. - -> Note: The use of a KCL module e.g., `kcl.mod` is optional, but required if one wants to manage, distribute, share and reuse code with a semantic version. - -### Creating a module - -A module can be created by running the following command within the module root: - -```bash -kpm init [module name] -``` - -The module name is **required** if a package within the module needs to import another package within the module. A module can also be created by setting up the `kcl.mod` file manually. - -## Package - -In KCL, a package is usually composed of a "folder" containing KCL files. This folder can be a real disk physical path, or it can be composed of multiple KCL files (usually main package). Different packages are uniquely located by different package paths (such as `kubernetes.core.v1`) - -Within the same module, different packages can be imported from each other through the import statement of relative or absolute path. During the KCL parsing process, the relative import will be replaced by absolute import and the corresponding KCL code will be found through the package path. - -### Relative Import Path - -We can use the operator `.` to realize the relative path import of KCL entry files. - -main.k: - -```python -import .model1 # Current directory module -import ..service # Parent directory -import ...root # Parent of parent directory - -s = service.ImageService {} -m = root.Schema {} -``` - -### Absolute Import Path - -The semantics of `import a.b.c.d` is - -1. If `kcl.mod` not exist, regard the current directory as the package root and search the path `a/b/c/d` from the current directory. -2. If the current directory search fails, search from the root path `ROOT_PATH/a/b/c/d`, else raise an import error. - -The definition of the root path `ROOT_PATH` is the directory corresponding to the `kcl.mod` file from the current directory. - -Code structure: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -### Builtin Package - -KCL has a collection of builtin packages such as `math`, `regex`, etc. To use a builtin package, import it directly and invoke the functions using its qualified identifier. For instance, - -```python -import regex - -image = "nginx:1.14.2" -is_match = regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$") - -``` - -The output YAML is - -```yaml -image: nginx:1.14.2 -is_match: true -``` - -### Plugin Package - - - -KCL also has a collection of plugin packages such as `hello`, `project_context`, etc. To use a plugin package, import it with a `kcl_plugin.` package path prefix and invoke the functions using its qualified identifier. For instance, - -```python -import kcl_plugin.hello - -result = hello.add(1, 1) -``` - -The output YAML is - -```yaml -result: 2 -``` - -### Main Package - -In KCL, the composition of the main package is usually determined by the compiler parameters. This is because the KCL schema and constraints can be split across files in the package, or even organized across directories, considering the convenience of writing and maintaining the configuration in isolated blocks. - -#### Files belonging to a main package - -It is up to the user to decide which configurations and constraints to use using the KCL command line. For example, - -```bash -kcl file1.k file2.k -``` - -Thus, the main package contains two KCL files named `file1.k` and `file2.k`. - -If KCL is told to load the files for a specific directory, for example: - -```bash -kcl ./path/to/package -``` - -It will only look KCL files with `.k` suffix and ignore files with `_` prefix or `_test.k` into the main package. Besides, if the `./path/to/package` contains `kcl.yaml` files, `kcl.yaml` files be ignored. - -In addition, we can set main package files through configuring the command-line compilation setting file (e.g., `kcl.yaml`) as follows: - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k -``` - -```bash -kcl -Y kcl.yaml -``` - -> Note: If we do not specify any input files for KCL, KCL will find the default `kcl.yaml` from the command line execution path to read the input file. Besides, if we tell KCL both the input files and the compilation setting file, KCL will take input files entered by the user as the final value. - -```bash -# Whether the 'files' field is configured in `kcl.yaml` or not, the final value of input files is ["file1.k", "file2.k"] -kcl -Y kcl.yaml file1.k file2.k -``` - -## The relationship and difference between `kcl.mod` and `kcl.yaml` - -First of all, in KCL, `kcl.mod` and `kcl.yaml` are both optional. The difference is that `kcl.mod` determines the root path of the package path and whether a KCL module has the requirement of distribution and reuse, and `kcl.yaml` determines the KCL file composition of the main package. - -Secondly, for a kcl module for external use only, `kcl.yaml` is optional but `kcl.mod` is required, because it needs to declare the KCL version, module version, dependency and other information. - -Finally, for the KCL IDE plug-in, it needs to know the main package information to form a complete compilation process, so it needs to automatically look up the composition of the main package according to the position of the cursor, because no one can specify this information through the KCL command line. The general query logic is to find whether `kcl.yaml` exists. If it is found, the main package consists of the `files` attribute in `kcl.yaml`, and if not found, the main package consists of the current file. The KCL IDE plug-in is selectively aware of the `kcl.mod` file. When the `kcl.mod` file exists, the IDE plug-in reads the corresponding information of all package paths and their real paths in the external dependencies. diff --git a/versioned_docs/version-0.5.4/user_docs/getting-started/_category_.json b/versioned_docs/version-0.5.4/user_docs/getting-started/_category_.json deleted file mode 100644 index 1bf165d4..00000000 --- a/versioned_docs/version-0.5.4/user_docs/getting-started/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Get Started", - "position": 1 -} diff --git a/versioned_docs/version-0.5.4/user_docs/getting-started/index.md b/versioned_docs/version-0.5.4/user_docs/getting-started/index.md deleted file mode 100644 index c50dbaa6..00000000 --- a/versioned_docs/version-0.5.4/user_docs/getting-started/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# Get Started - -Get started include a quick overview of the KCL programming language. diff --git a/versioned_docs/version-0.5.4/user_docs/getting-started/install.md b/versioned_docs/version-0.5.4/user_docs/getting-started/install.md deleted file mode 100644 index 261ab804..00000000 --- a/versioned_docs/version-0.5.4/user_docs/getting-started/install.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Installation - -## 1. Install KCL - -### From the Binary Releases - -Each release of KCL includes various OSes and architectures. These binary versions can be manually downloaded and installed from [Github](https://github.com/kcl-lang/kcl/releases/) or [Gitee](https://gitee.com/kusionstack/kcl/releases) and add `{install-location}/kclvm/bin` to the environment PATH. - -> ⚠️ If you cannot successfully access Github, you can also access Gitee to obtain binaries for installation. - -#### MacOS & Linux - -```bash -export PATH=$PATH:{install-location}/kclvm/bin -``` - -#### Windows - -```powershell -$env:PATH += ";{install-location}\kclvm\bin;" -``` - -### Using script to install the latest release - -#### MacOS - -Install or upgrade the latest darwin KCL to /usr/local/kclvm/bin - -```bash -curl -fsSL https://kcl-lang.io/script/install.sh | /bin/bash -``` - -#### Linux - -Install or upgrade the latest linux KCL to /usr/local/kclvm/bin - -```bash -wget -q https://kcl-lang.io/script/install.sh -O - | /bin/bash -``` - -#### Windows - -Install or upgrade the latest windows KCL to $Env:SystemDrive\kclvm\bin and add this directory to User PATH environment variable. - -```bash -powershell -Command "iwr -useb https://kcl-lang.io/script/install.ps1 | iex" -``` - -### Homebrew (MacOS) - -- Install - -```bash -brew install kcl-lang/tap/kcl -``` - -- Upgrade - -```bash -brew upgrade kcl-lang/tap/kcl -``` - -- Uninstall - -```bash -brew uninstall kcl-lang/tap/kcl -``` - -### Scoop (Windows) - -Install [Scoop](https://scoop.sh/) first, then add this bucket and install `kcl` by running: - -```bash -scoop bucket add kcl-lang https://github.com/kcl-lang/scoop-bucket.git -scoop install kcl-lang/kcl -``` - -### From Go - -Install `kcl` through the `Go` command (`Go` requires 1.18+). - -```bash -go install kcl-lang.io/kcl-go/cmds/kcl-go@main -``` - -Add an alias for the kcl command (optional). - -```bash -alias kcl='kcl-go run' -``` - -> Note: `kcl-go` does not rely on the installation of `kcl`, but if `kcl` exists in PATH, it will be used by `kcl-go` first. - -### From Docker - -- Command - -```bash -docker run --rm -it kcllang/kcl -``` - -- Update image - -```bash -docker pull kcllang/kcl -``` - -### Note - -We can execute the following command to ensure that KCL has been installed correctly. - -```bash -kcl -V -``` - -The output may looks like this: - -```bash -Version: {kcl version} -Platform: {your platform} -GitCommit: {git commit} -``` - -For all the above operating systems and installation methods, if you want to use [KCL Python Plugin](/docs/reference/plugin/overview), you need to ensure that Python 3.7+ is installed and add the python3 command to your PATH environment variable. - -## 2. Install KCL IDE Extension - -### VS Code - -The KCL Extension extension provides some coding assistance, e.g., highlight, goto definition, completion, hover, outline, and diagnostics. You can go [here](/docs/tools/Ide/vs-code) for more information about the installation. - -![Completion](/img/docs/tools/Ide/vs-code/Completion.gif) - -### IntelliJ IDEA - -Download the distribution from [here](https://github.com/kcl-lang/intellij-kcl/releases) and in IntelliJ IDEA, click Preference -> plugins -> install Plugin from Disk... -> select kcl-idea-plugin zip -> restart IDE. This plugin requires the IntelliJ IDEA 2020.2+ diff --git a/versioned_docs/version-0.5.4/user_docs/getting-started/intro.md b/versioned_docs/version-0.5.4/user_docs/getting-started/intro.md deleted file mode 100644 index c4515840..00000000 --- a/versioned_docs/version-0.5.4/user_docs/getting-started/intro.md +++ /dev/null @@ -1,199 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Introduction - -## What is KCL? - -[KCL](https://github.com/kcl-lang/kcl) is an open-source, constraint-based record and functional language that enhances the writing of complex configurations, including those for cloud-native scenarios. With its advanced programming language technology and practices, KCL is dedicated to promoting better modularity, scalability, and stability for configurations. It enables simpler logic writing and offers ease of automation APIs and integration with homegrown systems. - -## Why Use KCL? - -KCL expects to solve the following problems: - -- Hide infrastructure and platform details by defining more appropriate **API abstractions** to reduce the burden of developers. -- **Mutate** and **validate** existing config files or manifests. -- Manage large-scale configuration data across teams without side effects through configuration language. - - Use **production level high-performance programming language** to **write code** to improve the flexibility of configuration, such as conditional statements, loops, functions, package management and other features to improve the ability of configuration reuse. - - Improve the ability of **configuration semantic verification** at the code level, such as optional/required fields, types, ranges, and other configuration checks. - - Provide the **ability to write, combine and abstract configuration blocks**, such as structure definition, structure inheritance, constraint definition, etc. - -You can use KCL to - -- **Generate** low-level static configuration data like JSON, YAML, etc. -- Reduce boilerplate in configuration data with the **schema modeling**. -- Define transformers and constraints for configuration data and templates and **mutate/validate** them automatically. -- Organize, simplify, unify and manage large configurations scalably without side effects. -- Used as a platform engineering language to deliver modern app with [KusionStack](https://kusionstack.io/). - -In addition to the language itself, KCL also provides many additional tools, such as formatting, testing, document, package management, to help users use, understand and check the configuration or policy they write. We can reduce the cost of configuration writing and sharing through IDE extensions such as VS Code, playground and package manage tools. In addition, through KCL Rust, Go, and Python multilingual SDKs, the configuration can be automatically managed and executed. - -![](/img/docs/user_docs/intro/kcl-overview.png) - -Besides, KCL is a modern high-level domain language, which is a compiled, static and strongly typed language. It provides developers with the ability to write **configuration (config)**, **modeling abstraction (schema)**, **logic (lambda)**, and **policies (rule)** as the core elements through recording and functional language design. - -![](/img/docs/user_docs/intro/kcl-concepts.png) - -KCL tries to provide runtime-independent programmability and does not natively provide system functions such as threads and IO, but supports functions for cloud-native operation scenarios, and tries to provide stable, secure, low-noise, low-side effect, easy-to-automate and easy-to-govern programming support for solving domain problems. - -In summary, KCL has the following characteristics: - -- **Easy-to-use**: Originated from high-level languages ​​such as Python and Golang, incorporating functional language features with low side effects. -- **Well-designed**: Independent Spec-driven syntax, semantics, runtime and system modules design. -- **Quick modeling**: [Schema](https://kcl-lang.github.io/docs/reference/lang/tour#schema)-centric configuration types and modular abstraction. -- **Rich capabilities**: Configuration with type, logic and policy based on [Config](https://kcl-lang.github.io/docs/reference/lang/codelab/simple), [Schema](https://kcl-lang.github.io/docs/reference/lang/tour/#schema), [Lambda](https://kcl-lang.github.io/docs/reference/lang/tour/#function), [Rule](https://kcl-lang.github.io/docs/reference/lang/tour/#rule). -- **Stability**: Configuration stability built on [static type system](https://kcl-lang.github.io/docs/reference/lang/tour/#type-system), [constraints](https://kcl-lang.github.io/docs/reference/lang/tour/#validation), and [rules](https://kcl-lang.github.io/docs/reference/lang/tour#rule). -- **Scalability**: High scalability through [automatic merge mechanism](https://kcl-lang.github.io/docs/reference/lang/tour/#-operators-1) of isolated config blocks. -- **Fast automation**: Gradient automation scheme of [CRUD APIs](https://kcl-lang.github.io/docs/reference/lang/tour/#kcl-cli-variable-override), [multilingual SDKs](https://kcl-lang.github.io/docs/reference/xlang-api/overview), [language plugin](https://kcl-lang.github.io/docs/reference/plugin/overview) -- **High performance**: High compile time and runtime performance using Rust & C and [LLVM](https://llvm.org/), and support compilation to native code and [WASM](https://webassembly.org/). -- **API affinity**: Native support API ecological specifications such as [OpenAPI](https://kcl-lang.github.io/docs/tools/cli/openapi/), Kubernetes CRD, Kubernetes YAML spec. -- **Development friendly**: Friendly development experiences with rich [language tools](https://kcl-lang.github.io/docs/tools/cli/kcl/overview) (Format, Lint, Test, Vet, Doc, etc.) and [IDE extensions](https://kcl-lang.github.io/docs/tools/Ide/). -- **Safety & maintainable**: Domain-oriented, no system-level functions such as native threads and IO, low noise and security risk, easy maintenance and governance. -- **Rich multi-language SDK**: [Go](https://kcl-lang.io/docs/reference/xlang-api/go-api), [Python](https://kcl-lang.io/docs/reference/xlang-api/python-api), [Java](https://kcl-lang.io/docs/reference/xlang-api/java-api) and [REST APIs](https://kcl-lang.io/docs/reference/xlang-api/rest-api) meet different scenarios and application use prelude. -- **Kubernetes Integrations**: External mutation and validation plugins including [Kustomize KCL Plugin](https://github.com/kcl-lang/kustomize-kcl), [Helm KCL Plugin](https://github.com/kcl-lang/helm-kcl), [KPT KCL SDK](https://github.com/kcl-lang/kpt-kcl-sdk), [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) to separate data and logic. -- **Production-ready**: Widely used in production practice of platform engineering and automation at Ant Group. - -Although KCL is not a general language, it has corresponding application scenarios. Developers can write **config**, **schema**, **function** and **rule** through KCL, where config is used to define data, schema is used to describe the model definition of data, rule is used to validate data, and schema and rule can also be combined to use models and constraints that fully describe data, In addition, we can also use the lambda pure function in KCL to organize data code, encapsulate common code, and call it directly when needed. - -The configuration of attributes in KCL usually meets the simple pattern: - -$$ -k = (T) v -$$ - -where $k$ is the attribute name, $v$ is the attributes value, and $T$ is the type annotation. Since KCL has the ability of the type inference, $T$ is usually omitted. - -This is an example of generating kubernetes manifests. - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = name -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -We can use the KCL code to generate a Kubernetes YAML manifest. - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## How to Choose? - -Communities have been making significant efforts to improve their configuration technologies, which can be categorized into three groups: - -- Low-level data format-based tools that utilize external tools for enhancing reuse and validation, specifically for templating, patching, and validation. -- Domain-Specific Languages (DSLs) and Configuration Languages (CLs), which enhance language abilities. -- General Purpose Language (GPL)-based solutions that utilize Cloud-Development Kit (CDK) or framework to define the configuration. - -To simplify, here are some recommended options: - -- YAML/JSON/Kustomize/Helm are recommended if you need to write structured key-value pairs, or use Kubernetes native tools. -- HCL is recommended if you want to use programming language convenience to remove boilerplate with good human readability, or if you are already a Terraform user. -- CUE is recommended if you want to use type system to improve stability and maintain scalable configurations. -- KCL is recommended if you want types and modeling like a modern language, scalable configurations, in-house pure functions and rules, and production-ready performance and automation. - -### vs. YAML/JSON - -YAML/JSON configurations are suitable for small-scale configuration scenarios. However, if you require frequent modifications in large-scale cloud-native configuration scenarios, KCL is more appropriate. The primary difference between the two is the abstraction of configuration data and deployment. - -The advantages of using KCL for configuration are numerous. First, abstracting one layer for static data provides deployment flexibility, allowing various configuration environments, tenants, and runtime to have distinct requirements for static data. Additionally, different organizations may have different specifications and product requirements. By leveraging KCL, administrators can expose the most important and frequently modified configurations to users. - -### vs. Jsonnet/GCL - -GCL is a declarative configuration programming language implemented in Python, providing necessary language capabilities for template abstraction. However, the compiler itself is written in Python, and the language runs with interpretation, leading to poor performance for large template instances, such as the Kubernetes model. - -On the other hand, Jsonnet is a data template language implemented in C++/Go, suitable for application and tool developers. It can generate configuration data and organize, simplify, and manage large configurations without any side effects. - -Both Jsonnet and GCL are excellent at reducing boilerplate, using code to generate configuration, so engineers can write advanced GPL code instead of manually writing error-prone and difficult-to-understand server binary code. Despite reducing some of the complexities of GCL, Jsonnet largely falls into the same category. Both have runtime errors, insufficient type-checking and constraint capacity. - -### vs. HCL - -HCL is a configuration language implemented in Go that is structured and inspired by the syntax of libucl and nginx configurations. It is designed to be both human and machine-friendly, primarily for use in devops tools, server configurations, and resource configurations as a [Terraform language](https://www.terraform.io/language). - -The user interface of HCL is not readily apparent in the Terraform provider Schema definition and can be cumbersome when defining complex object and required/optional fields. Dynamic parameters are constrained by the condition field of the variable, and resource constraints must be defined either by the provider schema or through the use of Sentinel/Rego and other policy languages. The language itself may not be self-contained. - -### vs. CUE - -CUE can be utilized for modeling through structures without the need for inheritance or other features. This can lead to high abstraction as long as there are no conflicts with model definitions. However, since CUE performs all constraint checks at runtime, there may be performance bottlenecks in large-scale modeling scenarios. Despite this, CUE simplifies constraint writing through various syntax options, eliminating the need for generic types and enumerations. Additionally, configuration merging is supported but is completely idempotent, which may not be suitable for complex multi-tenant and multi-environment configuration scenarios. Writing complex loop and constraint scenarios can be challenging and cumbersome for accurately modifying configurations. - -On the other hand, KCL conducts modeling through the schema and achieves high model abstraction through language-level engineering and some object-oriented features, such as single inheritance. KCL is a statically compiled language with low overhead for large-scale modeling scenarios. Additionally, KCL provides a richer declarative constraint syntax, making it easier to write. Compared to CUE, KCL offers more if guard combination constraints, all/any/map/filter, and other collection constraint writing methods, which simplify configuration field combination constraints. - -### vs. Dhall - -Dhall is a functional, programmable configuration language that incorporates JSON, functions, types and imports. If you have experience with languages like Haskell, you may find Dhall familiar. KCL also offers similar functionality for programmability and abstraction, but has made greater advancements in areas such as modeling, constraint checking, automation and package management for sharing models. KCL's syntax and semantics are more aligned with object-oriented languages, making it more approachable than pure functional styles in some cases. - -### vs. Nickel - -Nickel is the cheap configuration language. Its purpose is to automate the generation of static configuration files and it is in essence JSON with functions and types. - -KCL and Nickel both have a similar gradual type system (static + dynamic), merge strategy, function and constraint definition. The difference is that KCL is a Python-like language, while Nickel is a JSON-like language. In addition, KCL provides the schema keyword to distinguish between configuration definitions and configuration data to avoid mixed use. - -### vs. Starlark - -Starlark is the language of Bazel, which is a dialect of Python. It does not have types and recursion is forbidden. - -KCL can also be regarded as a variant of Python to some extent, but it greatly enhances the design related to static typing and configuration extensibility, and is a compiled language, which is essentially different from Starlark. - -### vs. Kustomize - -The key feature of Kustomize is its ability to overlay files at a granular level. However, it faces challenges with multiple overlay chains as a specific attribute value may not be the final value, as it can be overridden by another value elsewhere. Retrieving the inheritance chain of Kustomize files can be less convenient than retrieving the inheritance chain of KCL code, particularly for complex scenarios where careful consideration of the specified configuration file overwrite order is necessary. Additionally, Kustomize does not address issues related to YAML configuration writing, constraint verification, model abstraction, and development, making it more suited for simpler configuration scenarios. - -In contrast, KCL offers fine-grained configuration merge operations for each attribute in the code, with flexible merge strategy settings that are not limited to overall resources. KCL also allows for static analysis of configuration dependencies through import statements. - -### vs. Helm - -The idea behind Helm can be traced back to the package management system used in operating systems. It is a package management tool that relies on templated YAML files to execute and manage resources within packages. - -KCL provides a greater range of capabilities than Helm, making it a viable alternative. Users who have already adopted Helm can still utilize KCL by packaging the stack compilation results in a Helm format or by using the Helm-KCL plugin to programmatically extend existing Helm charts. - -### vs. CDK - -CDK's high-level language integrates well into application projects, effectively becoming part of the client runtime. In contrast, KCL decouples external configurations and policies written using KCL from the client runtime. - -General-purpose languages can often be over-engineered, going beyond the requirements of the problem being solved. These languages can also present various security issues, such as problems with the ability boundary, such as accessing I/O, network, code infinite looping, and other security risks. In specialized fields, such as music, there are special notes used to communicate effectively, which cannot be expressed clearly in general-purpose languages. - -Furthermore, general-purpose languages come in a variety of styles, which can create challenges in terms of unified maintenance, management, and automation. These languages are generally better suited to writing the client runtime, which is a continuation of the server runtime. They are not ideal for writing configurations that are independent of the runtime, as they are compiled into binaries and started from the process, making stability and scalability challenging to control. In contrast, configuration languages are often used to write data combined with simple logic, and they describe the expected final result, which is then consumed by the compiler or engine. - -### vs. OPA/Rego - -While not originally intended as a data definition language, Rego, the language used for Open Policy Agent (OPA), can also address the issue of adding constraints from multiple sources. - -Rego has its roots in logic programming and is based on Datalog, a restricted form of Prolog. In contrast, KCL is based on a static type structure. Typed-feature structures were developed to address the limitations of Prolog in encoding human languages. Using a Datalog variant for a constraint validation task may seem unusual. Datalog excels as a query language, but it can be cumbersome for constraint enforcement, in that values must be queried before applying constraints. - -KCL's approach to constraint validation is more conducive to finding normalized and simplified representations of constraints, making it well-suited for creating structures generated from OpenAPI. diff --git a/versioned_docs/version-0.5.4/user_docs/getting-started/kcl-quick-start.md b/versioned_docs/version-0.5.4/user_docs/getting-started/kcl-quick-start.md deleted file mode 100644 index 2316d9a6..00000000 --- a/versioned_docs/version-0.5.4/user_docs/getting-started/kcl-quick-start.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Quick Start - -KCL is a cloud-native domain configuration and policy language. At the beginning of its design, KCL was inspired by Python3, and at the same time absorbed the conceptual design of declarative and OOP programming paradigms. In this section we will quickly demonstrate the basic features of the KCL language. - -## 1. Hello KCL - -The best way to learn a new language is to write a few small programs, and the same goes for configuring languages. We can write KCL programs just like writing configuration. - -Here is a simple `hello.k`: - -```python -hello = "KCL" -``` - -Set the `hello` attribute to the `"KCL"` string. Then save the code to the `hello.k` file. - -How to execute this program depends on the specific development environment, we first assume that the local macOS or Linux system has installed the `kcl` command (or enter the **Docker** environment test by `docker run --rm -it kcllang/kcl`) and then run the following command: - -```shell -kcl hello.k -``` - -The output is - -```yaml -hello: KCL -``` - -The effect of command line execution is shown as follows: - -![](/img/docs/user_docs/getting-started/hello.gif) - -The output is configuration data in YAML format. Although this program is simple, we can verify the basic usage of the development environment and the `kcl` command line by executing the KCL configuration program to the output. - -## 2. A little more complicated configuration - -In addition to the common key-value pairs, common configuration data also has nested dictionary and list types, and the value basic type includes boolean and numeric types in addition to strings. Here's a slightly more complex `server.k` configuration: - -```python -# This is a KCL document - -title = "KCL Example" - -owner = { - name = "The KCL Authors" - data = "2020-01-02T03:04:05" -} - -database = { - enabled = True - ports = [8000, 8001, 8002] - data = [["delta", "phi"], [3.14]] - temp_targets = {cpu = 79.5, case = 72.0} -} - -servers = [ - {ip = "10.0.0.1", role = "frontend"} - {ip = "10.0.0.2", role = "backend"} -] -``` - -where `#` begins with a line comment. The value of `owner` is a dictionary. The value of the dictionary contains the content in the form of `{}`. The key-value inside the dictionary is similar to the `hello = "KCL"` example. `database` is another dictionary in which the value of the dictionary attribute appears boolean `True`, list `[]` and dictionary `{}`, in which the value of the numeric type also appears in the list and dictionary. The `servers` attribute is a list with dictionaries nested inside the list (dictionaries and lists, as well as the `schema` that will be discussed later, can be nested within each other). - -The YAML output of this configuration is as follows: - -```yaml -$ kcl server.k -title: KCL Example -owner: - name: The KCL Authors - data: '2020-01-02T03:04:05' -database: - enabled: true - ports: - - 8000 - - 8001 - - 8002 - data: - - - delta - - phi - - - 3.14 - temp_targets: - cpu: 79.5 - case: 72.0 -servers: -- ip: 10.0.0.1 - role: frontend -- ip: 10.0.0.2 - role: backend -``` - -## 3. Define the structure of the configuration using KCL schema - -The KCL provides abstract support for attributes with a fixed attribute structure and default value behavior through the `schema` syntax. - -For example, the configuration of `database` in the above example is generally the default value. We can define a structure for the default configuration of the database: - -```python -schema DatabaseConfig: - enabled: bool = True - ports: [int] = [8000, 8001, 8002] - data: [[str|float]] = [["delta", "phi"], [3.14]] - temp_targets: {str: float} = {cpu = 79.5, case = 72.0} -``` - -`enabled` is a boolean type; `ports` is an integer list type; `data` is a list of lists, and the inner list elements are strings or floats; `temp_targets` is a dictionary type, and the attribute value of the dictionary is floating point type. And each attribute of `DatabaseConfig` defines a default value. - -Then pass `database = DatabaseConfig {}` to generate a structure with the same attributes as the default values. We can also modify the default value: - -```python -database = DatabaseConfig { - ports = [2020, 2021] -} -``` - -`schema DatabaseConfig` not only provides default values for attributes, but also adds type information to attributes. Therefore, if we accidentally writes the wrong attribute value type, KCL will give a friendly error prompt, such as the following example where `ports` is wrongly written as a floating point type: - -```python -database = DatabaseConfig { - ports = [1.2, 1.3] -} -``` - -When executed, an error similar to the following will be generated (the displayed file path depends on the local environment): - -```shell -kcl server.k -``` - -The output is - -```shell -error[E2G22]: TypeError - --> /path/to/server.k:8:5 - | -8 | ports = [1.2, 1.3] - | ^ expected [int], got [float(1.2)|float(1.3)] - | - - --> /path/to/server.k:3:5 - | -3 | ports: [int] = [8000, 8001, 8002] - | ^ variable is defined here, its type is [int], but got [float(1.2)|float(1.3)] - | -``` - -Similarly we can encapsulate the attributes of the `servers` section with the following code: - -```python -schema ServerConfig: - ip: str - role: "frontend" | "backend" - -servers = [ - ServerConfig {ip = "10.0.0.1", role = "frontend"} - ServerConfig {ip = "10.0.0.2", role = "backend"} -] -``` - -The attribute `ip` of `ServerConfig` is a string type, and no default value is given. We must manually add the value of the `ip` attribute when generating the `ServerConfig` type attribute, otherwise the KCL will report a missing required attribute error. The `role` attribute is a `"frontend" | "backend"` enumerated string type. - -In addition, `schema` can also combine `check`, `mixin`, optional attributes, inheritance and extension modules to achieve more complex configuration and policy data abstraction, full language details can be found at [here](/docs/reference/lang/tour). diff --git a/versioned_docs/version-0.5.4/user_docs/guides/_category_.json b/versioned_docs/version-0.5.4/user_docs/guides/_category_.json deleted file mode 100644 index 40b1340d..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "User Guide", - "position": 4 -} diff --git a/versioned_docs/version-0.5.4/user_docs/guides/_working-with-terraform/1-overview.md b/versioned_docs/version-0.5.4/user_docs/guides/_working-with-terraform/1-overview.md deleted file mode 100644 index c2ec836d..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/_working-with-terraform/1-overview.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -id: overview -sidebar_label: Overview ---- - -# Overview - -Coming Soon diff --git a/versioned_docs/version-0.5.4/user_docs/guides/_working-with-terraform/2-abstraction.md b/versioned_docs/version-0.5.4/user_docs/guides/_working-with-terraform/2-abstraction.md deleted file mode 100644 index 18a25571..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/_working-with-terraform/2-abstraction.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -id: abstraction -sidebar_label: Abstraction ---- - -# Abstract Your Terraform Modules - -Coming Soon diff --git a/versioned_docs/version-0.5.4/user_docs/guides/_working-with-terraform/3-coverter.md b/versioned_docs/version-0.5.4/user_docs/guides/_working-with-terraform/3-coverter.md deleted file mode 100644 index 1dc975bb..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/_working-with-terraform/3-coverter.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -id: converter -sidebar_label: Converter ---- - -# Convert Your Terraform Provider Schema to KCL Schema - -Coming Soon diff --git a/versioned_docs/version-0.5.4/user_docs/guides/_working-with-terraform/_category_.json b/versioned_docs/version-0.5.4/user_docs/guides/_working-with-terraform/_category_.json deleted file mode 100644 index 3e72e820..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/_working-with-terraform/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Terraform", - "position": 13 -} diff --git a/versioned_docs/version-0.5.4/user_docs/guides/automation.md b/versioned_docs/version-0.5.4/user_docs/guides/automation.md deleted file mode 100644 index 561b3302..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/automation.md +++ /dev/null @@ -1,189 +0,0 @@ ---- -title: "Automation" -sidebar_position: 6 ---- - -## Introduction - -KCL provides many automation related capabilities, mainly including tools and multilingual APIs. Via `package_identifier : key_identifier` mode, KCL supports the indexing of any configured key value, thus completing the addition, deletion, modification and query of any key value. For example, the following figure shows that we can directly execute the following command to modify the image. The code diff before and after modification is also shown in the figure. - -![](/img/blog/2022-09-15-declarative-config-overview/14-kcl-image-update.png) - -In addition, the automation capability of KCL can be realized and integrated into CI/CD. - -![](/img/blog/2022-09-15-declarative-config-overview/15-kcl-automation.png) - -## Use KCL for Automation - -### 0. Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/automation -``` - -We can run the following command to show the config. - -```bash -cat main.k -``` - -The output is - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "app" - replicas = 1 - labels.key = "value" -} -``` - -We can run the command to get the config - -```bash -kcl main.k -``` - -The output is - -```yaml -app: - name: app - replicas: 1 - labels: - app: app - key: value -``` - -### 2. Use KCL CLI for Automation - -KCL allows us to directly modify the values in the configuration model through the KCL CLI `-O|--overrides` parameter. The parameter contains three parts e.g., `pkg`, `identifier`, `attribute` and `override_value`. - -```bash -kcl main.k -O override_spec -``` - -- `override_spec` represents a unified representation of the configuration model fields and values that need to be modified - -```bash -override_spec: [[pkgpath] ":"] identifier ("=" value | "-") -``` - -- `pkgpath`: indicates the package path where the identifier needs to be modified, usually in the form of `a.b.c`. For the main package,`pkgpath` is represented as `__ main__`. When omitted or not written, it indicates the main package -- `identifier` indicates the identifier that needs to modify the configuration, usually in the form of `a.b.c`. -- `value` indicates the value of the configuration that needs to be modified, which can be any legal KCL expression, such as number/string literal value, list/dict/schema expression, etc. -- `=` denotes modifying of the value of the identifier. -- `-` denotes deleting of the identifier. - -#### Override Configuration - -Run the command to update the application name. - -```bash -kcl main.k -O app.name='new_app' -``` - -The output is - -```yaml -app: - name: new_app - replicas: 1 - labels: - app: new_app - key: value -``` - -We can see the `name` attribute of the `app` config is updated to `new_app`. - -Besides, when we use KCL CLI `-d` argument, the KCL file will be modified to the following content at the same time. - -```bash -kcl main.k -O app.name='new_app' -d -``` - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "new_app" - replicas = 1 - labels: {key = "value"} -} -``` - -#### Delete Configuration - -Run the command to delete the `key` attribute of `labels`. - -```bash -kcl main.k -O app.labels.key- -``` - -The output is - -```yaml -app: - name: app - replicas: 1 - labels: - app: app -``` - -### 3. Use KCL API for Automation - -In addition, we can automatically modify the configuration attributes through the [multilingual API](/docs/reference/xlang-api/overview). - -Take the RestAPI as an example. The RestAPI service can be started in the following way: - -```bash -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -The service can then be requested via the POST protocol: - -```bash -curl -X POST http://127.0.0.1:2021/api:protorpc/KclvmService.OverrideFile -H 'content-type: accept/json' -d '{ - "file": "main.k", - "specs": ["app.name=\"nginx\""] -}' -``` - -After the service call is completed, main.k will be modified as follows: - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "nginx" - replicas = 1 - labels: { - "key" = "value" - } -} -``` - -## Summary - -The document introduces the automation capabilities of KCL, including tools and multilingual APIs. It supports indexing of any configured key value, allowing for the addition, deletion, modification, and querying of any key value. It can also be integrated into CI/CD. The document provides an example of using KCL to automate configuration management, including using the KCL CLI to override and delete configurations, and using the KCL API to modify configuration attributes. For more information about KCL automation and Override API, please refer to [here](/docs/reference/lang/tour#kcl-cli-variable-override). diff --git a/versioned_docs/version-0.5.4/user_docs/guides/ci-integration/_3-jenkins-ci.md b/versioned_docs/version-0.5.4/user_docs/guides/ci-integration/_3-jenkins-ci.md deleted file mode 100644 index f85d231f..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/ci-integration/_3-jenkins-ci.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -id: github-ci -sidebar_label: Github CI ---- - -Coming Soon - -## Introduction - -## How to - -## Summary diff --git a/versioned_docs/version-0.5.4/user_docs/guides/ci-integration/_category_.json b/versioned_docs/version-0.5.4/user_docs/guides/ci-integration/_category_.json deleted file mode 100644 index 3145ed7f..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/ci-integration/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "CI Integration", - "position": 12 -} \ No newline at end of file diff --git a/versioned_docs/version-0.5.4/user_docs/guides/configuration.md b/versioned_docs/version-0.5.4/user_docs/guides/configuration.md deleted file mode 100644 index e6060815..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/configuration.md +++ /dev/null @@ -1,129 +0,0 @@ ---- -title: "Configuration" -sidebar_position: 1 ---- - -## Introduction - -Configuration is a vital aspect of software systems that are constantly in flux due to evolving business requirements, infrastructure demands, and other factors. Often, changing these systems' behavior quickly can be challenging, especially when doing so requires a costly and time-consuming reconstruction and redeployment process. In such cases, making changes to the business code may not be sufficient. Fortunately, the configuration provides a low-overhead way to modify system functions. For instance, many developers write JSON or YAML files to configure their systems. - -We can store the static configuration in JSON and YAML files as needed. Moreover, the configuration can also be stored in a high-level language that allows for more flexible configuration. This language can be coded, rendered, and statically configured. KCL is a configuration language that offers such functionality. Developers can write KCL code to generate JSON/YAML and other configurations. - -## Use KCL for Configuration - -KCL's core features are its modeling and constraint capabilities, and its basic functions revolve around these two key elements. Additionally, KCL follows a user-centric configuration concept when designing its basic functions. Configuration code has requirements for configuration data constraints, such as type constraints and required/optional constraints on configuration attributes, range constraints, and immutability constraints. These are also some of the core issues that KCL is committed to resolving. - -Now that we have an understanding of KCL's capabilities, let's explore how to use it to generate configurations. - -### 0. Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. Get the Example - -Firstly, let's get the example. - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/configuration -``` - -We can run the following command to show the config. - -```bash -cat nginx.k -``` - -The output is - -```python -schema Nginx: - """Schema for Nginx configuration files""" - http: Http - -schema Http: - server: Server - -schema Server: - listen: int | str # The attribute `listen` can be int type or a string type. - location?: Location # Optional, but must be non-empty when specified - -schema Location: - root: str - index: str - -nginx = Nginx { - http.server = { - listen = 80 - location = { - root = "/var/www/html" - index = "index.html" - } - } -} -``` - -### 2. Generate YAML using KCL - -Run the following command - -```bash -kcl nginx.k -``` - -We can get the output YAML - -```yaml -nginx: - http: - server: - listen: 80 - location: - root: /var/www/html - index: index.html -``` - -### 3. Configuration with Dynamic Parameters - -Besides, we can dynamically receive external parameters through the KCL builtin function `option`. For example, for the following KCL file (db.k), we can use the KCL command line `-D` flag to receive an external dynamic parameter. - -```python -env: str = option("env") or "dev" # The attribute `env` has a default value "den" -database: str = option("database") -hosts = { - dev = "postgres.dev" - stage = "postgres.stage" - prod = "postgres.prod" -} -dbConfig = { - host = hosts[env] - database = database - port = "2023" - conn = "postgres://${host}:${port}/${database}" -} -``` - -```bash -# Use the `-D` flag to input external parameters. -kcl db.k -D database="foo" -``` - -The output is - -```yaml -env: dev -database: foo -hosts: - dev: postgres.dev - stage: postgres.stage - prod: postgres.prod -dbConfig: - host: postgres.dev - database: foo - port: "2023" - conn: "postgres://postgres.dev:2023/foo" -``` - -## Summary - -By using KCL, we can generate low-level data configurations. For different situations, we set dynamic parameters through the `-D` flag to meet the scene requirements. For more KCL features, please refer to [here](/docs/reference/lang/tour). diff --git a/versioned_docs/version-0.5.4/user_docs/guides/gitops/_category_.json b/versioned_docs/version-0.5.4/user_docs/guides/gitops/_category_.json deleted file mode 100644 index 29a73c67..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/gitops/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "GitOps", - "position": 11 -} \ No newline at end of file diff --git a/versioned_docs/version-0.5.4/user_docs/guides/index.md b/versioned_docs/version-0.5.4/user_docs/guides/index.md deleted file mode 100644 index cd3d4522..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/index.md +++ /dev/null @@ -1 +0,0 @@ -# User Guide diff --git a/versioned_docs/version-0.5.4/user_docs/guides/package-management/1-overview.md b/versioned_docs/version-0.5.4/user_docs/guides/package-management/1-overview.md deleted file mode 100644 index cffccc67..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/package-management/1-overview.md +++ /dev/null @@ -1,3 +0,0 @@ -# Overview - -KCL manages packages through the package management tool [kpm](https://github.com/kcl-lang/kpm). diff --git a/versioned_docs/version-0.5.4/user_docs/guides/package-management/2-installation.md b/versioned_docs/version-0.5.4/user_docs/guides/package-management/2-installation.md deleted file mode 100644 index 11d1da5d..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/package-management/2-installation.md +++ /dev/null @@ -1,55 +0,0 @@ -# Installation - -## Install `kpm` - -Before installing and using kpm, ensure that KCL has been installed successfully. - -[How to install KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### Go install - -You can download kpm via go install. - -```shell -go install kcl-lang.io/kpm@latest -``` - -### Download from GITHUB release page - -You can get `kpm` from the [kpm github release](https://github.com/kcl-lang/kpm/releases) and set the `kpm` binary path to the environment variable PATH. - -```shell -# KPM_INSTALLATION_PATH is the path of the `kpm` binary. -export PATH=$KPM_INSTALLATION_PATH:$PATH -``` - -Use the following command to ensure that you install `kpm` successfully. - -```shell -kpm --help -``` - -If you get the following output, you have successfully installed `kpm` and you can proceed to the following steps. - -```shell -NAME: - kpm - kpm is a kcl package manager - -USAGE: - kpm [arguments]... - -COMMANDS: - init initialize new module in current directory - add add new dependency - pkg package a kcl package into tar - metadata output the resolved dependencies of a package - run compile kcl package. - login login to a registry - logout logout from a registry - push push kcl package to OCI registry. - pull pull kcl package from OCI registry. - help, h Shows a list of commands or help for one command - -GLOBAL OPTIONS: - --help, -h show help -``` diff --git a/versioned_docs/version-0.5.4/user_docs/guides/package-management/3-quick-start.md b/versioned_docs/version-0.5.4/user_docs/guides/package-management/3-quick-start.md deleted file mode 100644 index 689e9530..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/package-management/3-quick-start.md +++ /dev/null @@ -1,112 +0,0 @@ -# Quick Start - -## 0. Prerequisite - -- Install [kpm](https://kcl-lang.io/docs/user_docs/guides/package-management/installation) - -## 1. Init an Empty KCL Package - -Create a new kcl package named `my_package`. And after we have created the package `my_package`, we need to go inside the package by `cd my_package` to complete the following operations. - -```shell -kpm init my_package && cd my_package -``` - -![kpm_init](/img/docs/user_docs/guides/package-management/gifs/kpm_init.gif) - -`kpm` will create two kcl package configuration files: `kcl.mod` and `kcl.mod.lock` in the directory where you executed the command. - -```shell -- my_package - |- kcl.mod - |- kcl.mod.lock - |- # You can write your kcl program directly in this directory. -``` - -`kcl.mod.lock` is the file generated by `kpm` to fix the dependency version. Do not modify this file manually. - -`kpm` initializes `kcl.mod` for an empty project as shown below: - -```shell -[package] -name = "my_package" -edition = "0.0.1" -version = "0.0.1" -``` - -## 2. Add a Dependency from OCI Registry - -You can then add a dependency to the current kcl package using the `kpm add` command - -As shown below, taking the example of adding a package dependency named `k8s`, the version of the package is `1.27.2`. - -```shell -kpm add k8s:1.27.2 -``` - -![kpm_add_k8s](/img/docs/user_docs/guides/package-management/gifs/kpm_add_k8s.gif) - -You can see that `kpm` adds the dependency you just added to kcl.mod. - -```shell -[package] -name = "my_package" -edition = "0.0.1" -version = "0.0.1" - -[dependencies] -k8s = "1.27.2" # The dependency 'k8s' with version '1.27.2' -``` - -### Write a kcl program that uses the content in `k8s` - -Create the `main.k` file in the current package. - -```shell -- my_package - |- kcl.mod - |- kcl.mod.lock - |- main.k # Your KCL program. -``` - -And write the following into the `main.k` file. - -```kcl -# Import and use the contents of the external dependency 'k8s'. -import k8s.api.core.v1 as k8core - -k8core.Pod { - metadata.name = "web-app" - spec.containers = [{ - name = "main-container" - image = "nginx" - ports = [{containerPort = 80}] - }] -} - -``` - -## 3. Run the KCL Code - -In the `my_package` directory, you can use `kpm` to compile the `main.k` file you just wrote. - -```shell -kpm run -``` - -The output is - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: web-app -spec: - containers: - - image: nginx - name: main-container - ports: - - containerPort: 80 -``` - -![kpm_run](/img/docs/user_docs/guides/package-management/gifs/kpm_run.gif) diff --git a/versioned_docs/version-0.5.4/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md b/versioned_docs/version-0.5.4/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md deleted file mode 100644 index aa9c119d..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md +++ /dev/null @@ -1,73 +0,0 @@ -# Share Your Package - -[kpm](https://github.com/kcl-lang/kpm) is a tool for managing kcl packages. This article will guide you on how to use kpm to push your kcl package to an OCI Registry for publication. kpm uses [ghcr.io](https://ghcr.io) as the default OCI Registry, and you can change the default OCI Registry by modifying the kpm configuration file. For information on how to modify the kpm configuration file, see [kpm oci registry](https://github.com/kcl-lang/kpm/blob/main/docs/kpm_oci.md#kpm-registry) - -Here is a simple step-by-step guide on how to use kpm to push your kcl package to ghcr.io. - -## Step 1: Install kpm - -First, you need to install kpm on your computer. You can follow the instructions in the [kpm installation documentation](https://kcl-lang.io/docs/user_docs/guides/package-management/installation). - -## Step 2: Create a ghcr.io token - -If you are using the default OCI Registry of kpm, to push a kcl package to ghcr.io, you need to create a token for authentication. You can follow the instruction. - -- [Creating a ghcr.io access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic) - -## Step 3: Log in to ghcr.io - -After installing kpm and creating a ghcr.io token, you need to log in to ghcr.io using kpm. You can do this using the following command: - -```shell -kpm login ghcr.io -u -p -``` - -Where `` is your GitHub username, `` is the token you created in step 2 - -For more information on how to log in to ghcr.io using kpm, see [kpm login](https://kcl-lang.io/docs/reference/package-management/command-reference/login). - -## Step 4: Push your kcl package - -Now, you can use kpm to push your kcl package to ghcr.io. - -### 1. A valid kcl package - -First, you need to make sure that what you are pushing conforms to the specifications of a kcl package, i.e., it must contain valid kcl.mod and kcl.mod.lock files. - -If you don't know how to get a valid kcl.mod and kcl.mod.lock, you can use the `kpm init` command. - -```shell -# Create a new kcl package named my_package -kpm init my_package -``` - -The `kpm init my_package` command will create a new kcl package `my_package` for you and create the `kcl.mod` and `kcl.mod.lock` files for this package. - -If you already have a directory containing kcl files `exist_kcl_package`, you can use the following command to convert it into a kcl package and create valid `kcl.mod` and `kcl.mod.lock` files for it. - -```shell -# In the exist_kcl_package directory -$ pwd -/home/user/exist_kcl_package - -# Run the `kpm init` command to create the `kcl.mod` and `kcl.mod.lock` files -$ kpm init -``` - -For more information on how to use `kpm init`, see [kpm init](https://kcl-lang.io/docs/reference/package-management/command-reference/init). - -### 2. Pushing the KCL Package - -You can use the following command in the root directory of your `kcl` package: - -```shell -# In the root directory of the exist_kcl_package package -$ pwd -/home/user/exist_kcl_package - -# Pushing the KCL Package to Default OCI Registry -$ kpm push -``` - -After completing these steps, you have successfully pushed your KCL Package to the default OCI Registry. -For more information on how to use `kpm push`, see [kpm push](https://kcl-lang.io/docs/reference/package-management/command-reference/push). diff --git a/versioned_docs/version-0.5.4/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md b/versioned_docs/version-0.5.4/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md deleted file mode 100644 index 3fa5aabe..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md +++ /dev/null @@ -1,66 +0,0 @@ -# Share Your Package to docker.io - -[kpm](https://github.com/KusionStack/kpm) is a tool for managing kcl packages. This article will show you how to use kpm to push your kcl packages to docker.io. - -Here is a simple step-by-step guide on how to use kpm to push your kcl package to docker.io. - -## Step 1: Install kpm - -First, you need to install kpm on your computer. You can follow the instructions in the [kpm installation documentation](https://kcl-lang.io/docs/user_docs/guides/package-management/installation). - -## Step 2: Create a docker.io account - -If you want to use `docker.io` as the OCI registry to share your kcl package with others, you need to create a `docker.io` account to support the push of your kcl package. - -## Step 3: Log in to docker.io - -You can use the following command to log in to docker.io. - -```shell -kpm login -u -p docker.io -``` - -Where `` is your `docker.io` username, and `` is your `docker.io` password. - -For more information on how to log in to docker.io using kpm, see [kpm login](https://kcl-lang.io/docs/reference/package-management/command-reference/login). - -## Step 4: Push your kcl package - -Now, you can use kpm to push your kcl package to `docker.io`. - -### 1. A valid kcl package - -First, you need to make sure that what you are pushing conforms to the specifications of a kcl package, i.e., it must contain valid kcl.mod and kcl.mod.lock files. - -If you don't know how to get a valid kcl.mod and kcl.mod.lock, you can use the `kpm init` command. - -Create a new kcl package named `my_package`. - -```shell -kpm init my_package -``` - -The `kpm init my_package` command will create a new kcl package `my_package` for you and create the `kcl.mod` and `kcl.mod.lock` files for this package. - -If you already have a directory containing kcl files `exist_kcl_package`, you can use the following command to convert it into a kcl package and create valid `kcl.mod` and `kcl.mod.lock` files for it. - -Run the `kpm init` command under the `exist_kcl_package` directory. - -```shell -kpm init -``` - -For more information on how to use `kpm init`, see [kpm init](https://kcl-lang.io/docs/reference/package-management/command-reference/init). - -### 2. Pushing the KCL Package - -You can use the following command in the root directory of your `kcl` package: - -Run the `kpm push` command under the `exist_kcl_package` directory. - -```shell -kpm push oci://docker.io//exist_kcl_package -``` - -After completing these steps, you have successfully pushed your KCL Package `exist_kcl_package` to `docker.io`. -For more information on how to use `kpm push`, see [kpm push](https://kcl-lang.io/docs/reference/package-management/command-reference/push). diff --git a/versioned_docs/version-0.5.4/user_docs/guides/package-management/4-how-to/6-push_github_action.md b/versioned_docs/version-0.5.4/user_docs/guides/package-management/4-how-to/6-push_github_action.md deleted file mode 100644 index de88dbcf..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/package-management/4-how-to/6-push_github_action.md +++ /dev/null @@ -1,81 +0,0 @@ -# Push Your KCL Package by GitHub Action - -[kpm](https://github.com/KusionStack/kpm) is a tool for managing kcl packages. This article will guide you how to use kpm in GitHub Action to push your kcl package to OCI registry. - -## Step 1: Install kpm - -At first, you need to install kpm on your computer. You can follow [kpm installation document](https://kcl-lang.io/docs/user_docs/guides/package-management/installation). - -## Step 2: Create a GitHub account - -If you already have a GitHub account, you can skip this step. - -[Sign up for a new GitHub account](https://docs.github.com/en/get-started/signing-up-for-github/signing-up-for-a-new-github-account) - -## Step 3: Create a GitHub repository for your KCL package - -### 1. Prepare a GitHub repository for your KCL package - -You need to prepare a GitHub repository for your KCL package. - -[Create a GitHub repository](https://docs.github.com/en/get-started/quickstart/create-a-repo) - -In this repository, add your KCL program, take the repository https://github.com/awesome-kusion/catalog.git as an example, - -```bash -├── .github -│ └── workflows -│ └── push.yaml # github action workflow -├── LICENSE -├── README.md -├── kcl.mod # kcl.mod to define your kcl package -├── kcl.mod.lock # kcl.mod.lock generated by kpm -└── main.k # Your KCL program -``` - -### 2. Set OCI Registry, account and password for your Github repository - -Take docker.io as an example, you can set secrets `REG`, `REG_ACCOUNT` and `REG_TOKEN` for your repository. The value of `REG` is `docker.io`, the value of `REG_ACCOUNT` is your `docker.io` account, and the value of `REG_TOKEN` is your `docker.io` login password. - -[Add secrets to the repository](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) - -If you use `ghcr.io` as `Registry`, you need to use GitHub token as secrets. - -[Create a GitHub Token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token#personal-access-tokens-classic) - -## Step 4: Add your KCL package to the repository and write github action workflow - -Add github action file `.github/workflows/push.yml` to this repository, the content is as follows: - -```yaml -name: KPM Push Workflow - -on: - push: - branches: - - main - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Set up Go 1.21 - uses: actions/setup-go@v2 - with: - go-version: 1.21 - - - name: Install kpm - run: go install kcl-lang.io/kpm@latest - - - name: Login and Push - env: - KPM_REG: ${{ secrets.REG }} - KPM_REPO: ${{ secrets.REG_ACCOUNT }} - run: kpm login -u ${{ secrets.REG_ACCOUNT }} -p ${{ secrets.REG_TOKEN }} ${{ secrets.REG }} && kpm push - - - name: Run kpm project from oci registry - run: kpm run oci://${{ secrets.REG }}/${{ secrets.REG_ACCOUNT }}/catalog --tag 0.0.1 -``` diff --git a/versioned_docs/version-0.5.4/user_docs/guides/package-management/4-how-to/_category_.json b/versioned_docs/version-0.5.4/user_docs/guides/package-management/4-how-to/_category_.json deleted file mode 100644 index e3409c62..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/package-management/4-how-to/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "How to", - "position": 4 -} diff --git a/versioned_docs/version-0.5.4/user_docs/guides/package-management/_category_.json b/versioned_docs/version-0.5.4/user_docs/guides/package-management/_category_.json deleted file mode 100644 index 1211443e..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/package-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Package Management Tools", - "position": 7 -} diff --git a/versioned_docs/version-0.5.4/user_docs/guides/secret-management/_category_.json b/versioned_docs/version-0.5.4/user_docs/guides/secret-management/_category_.json deleted file mode 100644 index c57bb30e..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/secret-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Secret Management", - "position": 13 -} diff --git a/versioned_docs/version-0.5.4/user_docs/guides/validation.md b/versioned_docs/version-0.5.4/user_docs/guides/validation.md deleted file mode 100644 index f589d7fa..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/validation.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: "Validation" -sidebar_position: 2 ---- - -## Introduction - -Validation is the process of verifying that data is accurate, reliable, and meets certain requirements or constraints. This includes checking the data for completeness, consistency, accuracy, and relevance. Data validation is performed to ensure that the data is fit for its intended purpose and that it can be used effectively and efficiently. - -We can use KCL and its vet tools to manually or automatically perform data validation to ensure data consistency. - -## Use KCL for Validation - -In addition to using KCL code to generate configuration formats such as JSON/YAML, KCL also supports format validation of JSON/YAML data. As a configuration language, KCL covers almost all features of [OpenAPI](https://www.openapis.org/). - -In KCL, a structure definition can be used to validate configuration data. At the same time, it supports user-defined constraint rules through the check block, and writes validation expressions in the schema to check and validate the attributes defined by the schema. It is very clear and simple to check whether the input JSON/YAML satisfies the corresponding schema structure definition and constraints. - -### 0. Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. Get the Example - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/validation -``` - -We can run the following command to show the config. - -```bash -cat schema.k -``` - -```python -schema User: - name: str - age: int - message?: str - data: Data - labels: {str:} - hc: [int] - - check: - age > 10, "age must > 10" - -schema Data: - id: int - value: str -``` - -In the schema, we can use the `check` keyword to write the validation rules of every schema attribute. Each line in the check block corresponds to a conditional expression. When the condition is satisfied, the validation is successful. The conditional expression can be followed by `, "check error message"` to indicate the message to be displayed when the check fails. - -To sum up, the validation kinds supported in KCL schema are: - -| Kind | Method | -| ----------------- | ----------------------------------------------------------------------------------------- | -| Range | Using comparison operators such as `<`, `>` | -| Regex | Using methods such as `match` from the `regex` system module | -| Length | Using the `len` built-in function to get the length of a variable of type `list/dict/str` | -| Enum | Using literal union types | -| Optional/Required | Using optional/required attributes of schema | -| Condition | Using the check if conditional expression | - -### 2. Validate the Data - -There is a JSON format file `data.json`: - -```json -{ - "name": "Alice", - "age": 18, - "message": "This is Alice", - "data": { - "id": 1, - "value": "value1" - }, - "labels": { - "key": "value" - }, - "hc": [1, 2, 3] -} -``` - -Execute the following command: - -```bash -kcl-vet data.json schema.k -``` - -## Summary - -KCL is a configuration language that supports data validation through its structure definition and user-defined constraint rules. Validation kinds supported in KCL schema include range, regex, length, enum, optional/required, and condition. To validate data, a schema is defined with validation rules written using the check keyword, and the data is validated using the validation tool or a visualization product built on top of it. - -## Further Information - -The improvement of KCL validation capabilities will gradually focus on the "static" aspect, that is, at compile time, combined with the ability of formal validation, it can directly analyze whether the data meets the constraints, whether the constraints conflict with each other, etc., and can be exposed in real-time through the IDE. - -We also expect that KCL models and constraints can be managed as a package (this package has only KCL files). For example, the Kubernetes models and constraints can be used out of the box. Users can generate configurations or verify existing configurations, and can simply extend the models and constraints users want through KCL inheritance. diff --git a/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md b/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md deleted file mode 100644 index ac20cd12..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: "Adopt From Kubernetes" -sidebar_position: 1 ---- - -## Introduction - -KCL provides many out of the box support for Kubernetes configuration. Through KCL tools, we can integrate Kubernetes Schema and configuration into KCL. This section will introduce how to use KCL to integrate Kubernetes. - -## Prerequisite - -- Install kcl-openapi - -## Quick Start - -### 1. Kubernetes OpenAPI Spec - -Starting from Kubernetes 1.4, the alpha support for the OpenAPI specification (known as Swagger 2.0 before it was donated to the OpenAPI Initiative) was introduced, and the API descriptions follow the [OpenAPI Spec 2.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md). And since Kubernetes 1.5, Kubernetes supports [directly extracting models from source code and then generating the OpenAPI spec file](https://github.com/kubernetes/kube-openapi) to automatically keep the specifications and documents up to date with the operation and models. - -In addition, Kubernetes CRD uses [OpenAPI V3.0 validation](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation) to describe a custom schema (in addition to the built-in attributes apiVersion, Kind, and metadata), that APIServer uses to validate the CR during the resource creation and update phases. - -### 2. KCL OpenAPI Support - -The `kcl-openapi` tool supports extracting and generating KCL schemas from Kubernetes OpenAPI/CRD. the [KCL OpenAPI Spec](/docs/tools/cli/openapi/spec) defines the mapping between the OpenAPI specification and the KCL language features. - -### 3. Migrate From Kubernetes To KCL - -#### 3.1 Write configurations based on the Kusion_Models package - -``We provide an out-of-the-box `kusion_models` package for you to quickly start. It contains a well-designed frontend model called [`Server schema`](https://github.com/KusionStack/konfig/blob/main/base/pkg/kusion_models/kube/frontend/server.k). You can declare the configurations by initializing the `Server schema`. For the description and usage of the schema and its attributes, please refer to the [Server schema documentation](https://kusionstack.io/docs/reference/model/kusion_models/kube/frontend/doc_server).`` - -#### 3.2 Build Your Custom Frontend Models - -The existing KCL Models may not meet your specific business requirements, then you can also design your custom frontend model package. You can design your custom models based on the pre-generated Kubernetes KCL models among all versions. - -##### 3.2.1 Get the k8s package - -The [Kubernetes KCL models](https://github.com/orgs/KusionStack/packages/container/package/k8s) among all versions are pre-generated, you get it by executing `kpm add k8s:` under your project. For detailed information about kpm usage, please refer to [kpm quick start guide](https://github.com/kcl-lang/kpm#quick-start). - -Alternatively, if you may want to generate them yourself, please refer to [Generate KCL Packages from Kubernetes OpenAPI Specs](https://github.com/kcl-lang/kcl-openapi/blob/main/docs/generate_from_k8s_spec.md). - -##### 3.2.2 Design Custom Frontend Models - -Since the Kubernetes built-in models are atomistic and kind of complex to beginners, we recommend taking the native model of Kubernetes as the backend output model and designing a batch of frontend models which could become a more abstract, friendlier and simpler interface to the user. You can refer to the design pattern in the [`Server Schema in the Konfig repo`](https://github.com/KusionStack/konfig/blob/main/base/pkg/kusion_models/kube/frontend/server.k). - -##### 3.2.3 Migrate The Configuration Data - -You can develop your custom scripts to migrate your configuration data automatically. KCL will later provide writing scaffolding and writing guidelines for this script. - -### 4. Migrate From Kubernetes CRD - -If you developed CRDs, you can generate the KCL version of the CRD schemas and declare CRs based on that. - -- Generate KCL Schema from CRD - - ``` - kcl-openapi generate model --crd --skip-validation -f - ``` - -- Define CR based on CRDs in KCL - - You can initialize the CRD schema to define a CR, or further, you can use the generated schema as a backend model and design a frontend interface for users to initialize. The practice is similar to what `KCL Models` does on Kubernetes built-in models. - -## Summary - -This section provides a quick start guide for using KCL with OpenAPI and Custom Resource Definitions (CRD). KCL also supports OpenAPI through the `kcl-openapi tool`, which maps OpenAPI specifications to KCL language features. diff --git a/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md b/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md deleted file mode 100644 index ea65e2f1..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md +++ /dev/null @@ -1,249 +0,0 @@ ---- -title: "Generate Kubernetes Manifests" -sidebar_position: 2 ---- - -## Introduction - -When we manage the Kubernetes resources, we often maintain it by hand, or use Helm and Kustomize tools to maintain our YAML configurations or configuration templates, and then apply the resources to the cluster through kubectl tools. However, as a "YAML engineer", maintaining YAML configuration every day is undoubtedly trivial and boring, and prone to errors. For example as follows: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: ... # Omit -spec: - selector: - matchlabels: - cell: RZ00A - replicas: 2 - template: - metadata: ... # Omit - spec: - tolerations: - - effect: NoSchedules - key: is-over-quota - operator: Equal - value: 'true' - containers: - - name: test-app - image: images.example/app:v1 # Wrong ident - resources: - limits: - cpu: 2 # Wrong type. The type of cpu should be str - memory: 4Gi - # Field missing: ephemeral-storage - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: is-over-quota - operator: In - values: - - 'true' -``` - -- The structured data in YAML is untyped and lacks validation methods, so the validity of all data cannot be checked immediately. -- YAML has poor programming ability. It is easy to write incorrect indents and has no common code organization methods such as logical judgment. It is easy to write a large number of repeated configurations and difficult to maintain. -- The design of Kubernetes is complex, and it is difficult for users to understand all the details, such as the `toleration` and `affinity` fields in the above configuration. If users do not understand the scheduling logic, it may be wrongly omitted or superfluous added. - -Therefore, KCL expects to solve the following problems in Kubernetes YAML resource management: - -- Use **production level high-performance programming language** to **write code** to improve the flexibility of configuration, such as conditional statements, loops, functions, package management and other features to improve the ability of configuration reuse. -- Improve the ability of **configuration semantic verification** at the code level, such as optional/required fields, types, ranges, and other configuration checks. -- Provide **the ability to write, combine and abstract configuration blocks**, such as structure definition, structure inheritance, constraint definition, etc. - -## Prerequisite - -First, you can visit the [KCL Quick Start](/docs/user_docs/getting-started/kcl-quick-start) to download and install KCL according to the instructions, and then prepare a [Kubernetes](https://kubernetes.io/) environment. - -## Quick Start - -### 1. Generate Kubernetes Resource - -We can write the following KCL code and name it `main.k`. KCL is inspired by Python. Its basic syntax is very close to Python, which is easy to learn. The configuration mode is simple, `k [: T] = v`, where `k` denotes the configured attribute name, `v` denotes the configured attribute value and `: T` denotes an optional type annotation. - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -In the above KCL code, we declare the `apiVersion`, `kind`, `metadata`, `spec` and other variables of a Kubernetes `Deployment` resource, and assign the corresponding contents respectively. In particular, we will assign `metadata.labels` fields are reused in `spec.selector.matchLabels` and `spec.template.metadata.labels` field. It can be seen that, compared with YAML, the data structure defined by KCL is more compact, and configuration reuse can be realized by defining local variables. - -We can get a Kubernetes YAML file by executing the following command line - -```bash -kcl main.k -``` - -The output is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -Of course, we can use KCL together with kubectl and other tools. Let's execute the following commands and see the result: - -```shell -kcl main.k | kubectl apply -f - -``` - -The output is - -```shell -deployment.apps/nginx-deployment configured -``` - -It can be seen from the command line that it is completely consistent with the deployment experience of using YAML configuration and kubectl application directly. - -Check the deployment status through kubectl - -```shell -kubectl get deploy -``` - -The output is - -```shell -NAME READY UP-TO-DATE AVAILABLE AGE -nginx-deployment 3/3 3 3 15s -``` - -### 2. Write Code to Manage Kubernetes resources - -When publishing Kubernetes resources, we often encounter scenarios where configuration parameters need to be dynamically specified. For example, different environments need to set different `image` field values to generate resources in different environments. For this scenario, we can dynamically receive external parameters through KCL conditional statements and `option` functions. Based on the above example, we can adjust the configuration parameters according to different environments. For example, for the following code, we wrote a conditional statement and entered a dynamic parameter named `env`. - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" if option("env") == "prod" else "${metadata.name}:latest" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -Use the KCL command line `-D` flag to receive an external dynamic parameter: - -```bash -kcl main.k -D env=prod -``` - -The output is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -The `image=metadata.name+": 1.14.2" if option ("env")=="prod" else metadata.name + ": latest"` in the above code snippet means that when the value of the dynamic parameter `env` is set to `prod`, the value of the image field is `nginx: 1.14.2`; otherwise, it is' nginx: latest'. Therefore, we can set env to different values as required to obtain Kubernetes resources with different contents. - -KCL also supports maintaining the dynamic parameters of the option function in the configuration file, such as writing the `kcl.yaml` file. - -```yaml -kcl_options: - - key: env - value: prod -``` - -The same YAML output can be obtained by using the following command line to simplify the input process of KCL dynamic parameters. - -```bash -kcl main.k -Y kcl.yaml -``` - -The output is: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## Summary - -KCL can be used to generate and manage Kubernetes resources, addressing the limitations of managing YAML configurations, such as a lack of validation methods and poor programming capabilities. It can also dynamically receive external parameters through conditional statements and option functions, allowing configuration parameters to be adjusted according to different environments. In addition, KCL can be used in conjunction with other tools such as kubectl to apply configuration to the cluster. diff --git a/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md b/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md deleted file mode 100644 index 17918b29..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: "Kubectl KCL Plugin" -sidebar_position: 1 ---- - -## Introduction - -[Kubectl](https://kubernetes.io/docs/reference/kubectl/) is a command line tool for communicating with a Kubernetes cluster's control plane, using the Kubernetes API. You can use the `Kubectl-KCL-Plugin` to - -- Edit the YAML configuration in a hook way to separate data and logic for the Kubernetes manifests management. -- For multi-environment and multi-tenant scenarios, you can maintain these configurations gracefully rather than simply copy and paste. -- Validate all KRM resources using the KCL schema. - -## Prerequisites - -- Install [Kubectl](https://github.com/kubernetes/kubectl) -- Install [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=krm-kcl` only to `Deployment` resources in the helm chart. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/kubectl-kcl.git/ -cd ./kubectl-kcl/examples/ -``` - -### 2. Test and Run - -Run the KCL code via the `Kubectl KCL Plugin`. - -```bash -kubectl kcl run -f ./kcl-run.yaml -``` - -The output yaml is - -```yaml -apiVersion: config.kubernetes.io/v1 -kind: ResourceList -items: - - apiVersion: apps/v1 - kind: Deployment - metadata: - annotations: - managed-by: krm-kcl - labels: - app: nginx - name: nginx-deployment - spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - image: "nginx:1.14.2" - name: nginx - ports: - - containerPort: 80 - - apiVersion: v1 - kind: Service - metadata: - name: test - spec: - ports: - - port: 80 - protocol: TCP - targetPort: 9376 - selector: - app: MyApp -functionConfig: - # kcl-fn-config.yaml - apiVersion: krm.kcl.dev/v1alpha1 - kind: KCLRun - metadata: - # EDIT THE SOURCE! - # This should be your KCL code which preloads the `ResourceList` to `option("resource_list") - spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "krm-kcl"}} for resource in option("resource_list").items] -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) diff --git a/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md b/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md deleted file mode 100644 index 01897f37..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: "Helm KCL Plugin" -sidebar_position: 2 ---- - -## Introduction - -[Helm](https://github.com/helm/helm) is a tool for managing Charts. Charts are packages of pre-configured Kubernetes resources. You can use the `Helm-KCL-Plugin` to - -- Edit the helm charts in a hook way to separate data and logic for the Kubernetes manifests management. -- For multi-environment and multi-tenant scenarios, you can maintain these configurations gracefully rather than simply copy and paste. -- Validate all KRM resources using the KCL schema. - -## Prerequisites - -- Install [Helm](https://github.com/helm/helm) -- Install [Helm KCL Plugin](https://github.com/kcl-lang/helm-kcl) - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=helm-kcl-plugin` only to `Deployment` resources in the helm chart. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/helm-kcl.git/ -cd ./helm-kcl/examples/workload-charts-with-kcl -``` - -### 2. Test and Run - -Run the KCL code via the `Helm KCL Plugin`. - -```bash -helm kcl template --file ./kcl-run.yaml -``` - -The output yaml is - -```yaml -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: workload - app.kubernetes.io/version: 0.1.0 - helm.sh/chart: workload-0.1.0 - name: workload -spec: - ports: - - name: www - port: 80 - protocol: TCP - targetPort: 80 - selector: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - type: ClusterIP ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: workload - app.kubernetes.io/version: 0.1.0 - helm.sh/chart: workload-0.1.0 - name: workload - annotations: - managed-by: helm-kcl-plugin -spec: - selector: - matchLabels: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - template: - metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - spec: - containers: - - image: nginx:alpine - name: frontend -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Helm KCL Plugin](https://github.com/kcl-lang/helm-kcl) diff --git a/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md b/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md deleted file mode 100644 index ae0c7a07..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: "Kustomize KCL Plugin" -sidebar_position: 3 ---- - -## Introduction - -[Kustomize](https://github.com/kubernetes-sigs/kustomize) lets you customize raw, template-free YAML files for multiple purposes, leaving the original YAML untouched and usable as is. - -KCL can be used to create functions to mutate and/or validate the YAML Kubernetes Resource Model (KRM) input/output format, and we provide Kustomize KCL functions to simplify the function authoring process. - -## Prerequisites - -- Install [kustomize](https://github.com/kubernetes-sigs/kustomize) -- Install [Docker](https://www.docker.com/) - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=kustomize-kcl` only to Deployment resources. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/kustomize-kcl.git -cd ./kustomize-kcl/examples/set-annotation/ -``` - -### 2. Test and Run - -```bash -kustomize fn run ./local-resource/ --dry-run -``` - -The output YAML is - -```yaml -apiVersion: krm.kcl.dev/v1alpha1 -kind: KCLRun -metadata: - name: set-annotation - annotations: - config.kubernetes.io/function: | - container: - image: docker.io/kcllang/kustomize-kcl:v0.2.0 - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml -# EDIT THE SOURCE! -# This should be your KCL code which preloads the `ResourceList` to `option("resource_list") -spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "kustomize-kcl"}} for resource in option("resource_list").items] ---- -apiVersion: v1 -kind: Service -metadata: - name: test - annotations: - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml -spec: - selector: - app: MyApp - ports: - - protocol: TCP - port: 80 - targetPort: 9376 ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx - annotations: - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml - managed-by: kustomize-kcl -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Kustomize KCL Plugin](https://github.com/kcl-lang/kustomize-kcl) diff --git a/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md b/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md deleted file mode 100644 index 3a029bdd..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: "KPT KCL SDK" -sidebar_position: 4 ---- - -## Introduction - -[kpt](https://github.com/GoogleContainerTools/kpt) is a package-centric toolchain that enables a configuration authoring, automation, and delivery experience, which simplifies managing Kubernetes platforms and KRM-driven infrastructure (e.g., Config Connector, Crossplane) at scale by manipulating declarative Configuration as Data for automating Kubernetes configuration editing including transforming and validating. - -KCL can be used to create functions to transform and/or validate the YAML Kubernetes Resource Model (KRM) input/output format, but we provide KPT KCL SDKs to simplify the function authoring process. - -## Prerequisites - -- Install [kpt](https://github.com/GoogleContainerTools/kpt) -- Install [Docker](https://www.docker.com/) - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=kpt` only to Deployment resources. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/kpt-kcl-sdk.git/ -cd ./kpt-kcl-sdk/get-started/set-annotation -``` - -### 2. Show the KRM - -```bash -kpt pkg tree -``` - -The output is - -```bash -set-annotation -├── [kcl-fn-config.yaml] KCLRun set-annotation -└── data - ├── [resources.yaml] Deployment nginx-deployment - └── [resources.yaml] Service test -``` - -### 3. Show and Update the KCL `FunctionConfig` - -```bash -cat ./kcl-fn-config.yaml -``` - -The output is - -```yaml -# kcl-fn-config.yaml -apiVersion: krm.kcl.dev/v1alpha1 -kind: KCLRun -metadata: # kpt-merge: /set-annotation - name: set-annotation -spec: - # EDIT THE SOURCE! - # This should be your KCL code which preloads the `ResourceList` to `option("resource_list")` - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "kpt"}} for resource in option("resource_list").items] -``` - -### 4. Test and Run - -Run the KCL code via kpt - -```bash -kpt fn eval ./data -i docker.io/kcllang/kpt-kcl:v0.2.0 --fn-config kcl-fn-config.yaml - -# Verify that the annotation is added to the `Deployment` resource and the other resource `Service` -# does not have this annotation. -cat ./data/resources.yaml | grep annotations -A1 -B0 -``` - -The output is - -```bash - annotations: - managed-by: kpt -``` - -It can be seen that we have indeed added the annotation `managed-by=kpt`. - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [KPT KCL SDK](https://github.com/kcl-lang/kpt-kcl-sdk) diff --git a/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json b/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json deleted file mode 100644 index 6e90c03c..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Mutate or Validate Kubernetes Manifests", - "position": 3 -} diff --git a/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/_category_.json b/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/_category_.json deleted file mode 100644 index 42681f2b..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Kubernetes", - "position": 9 -} diff --git a/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/index.md b/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/index.md deleted file mode 100644 index 8d6340de..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/index.md +++ /dev/null @@ -1 +0,0 @@ -# Kubernetes diff --git a/versioned_docs/version-0.5.4/user_docs/guides/working-with-konfig/1-overview.md b/versioned_docs/version-0.5.4/user_docs/guides/working-with-konfig/1-overview.md deleted file mode 100644 index aca119a1..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/working-with-konfig/1-overview.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -id: overview -sidebar_label: Overview ---- - -# Konfig Overview - -In KCL, it is recommended to uniformly manage all configurations and model libraries in the way of **configuration library**, that is, to store not only KCL definitions of the abstract model itself, but also various types of configurations, such as application operation and maintenance configuration, policy, etc. The configuration is recommended to be hosted in various VCS systems to facilitate configuration rollback and drift check. The best practice code of the configuration repository is Konfig, and the repository is hosted in [Github](https://github.com/KusionStack/konfig)。 - -⚡ The Konfig repository mainly includes: - -- KCL module declaration file (kcl.mod) -- KCL domain model libraries (Kubernetes, Prometheus, etc.) -- Directories of various configurations (application operation and maintenance configuration, etc) -- Configuration build and test scripts (Makefile, Github CI file, etc.) - -The reason for using a unified warehouse to manage all KCL configuration codes is that different code packages have different R&D entities, which will lead to package management and version management problems. When the business configuration code and basic configuration code are stored in a unified warehouse, the version dependency management between codes will be relatively simple. By locating the directory and file of the unique code base, the configuration code can be managed uniformly for easy search, modification and maintenance. - -The following is the architecture of Konfig: - -![](/img/docs/user_docs/guides/konfig/konfig-arch.png) - -Konfig provides users with an out-of-the-box and highly abstract configuration interface. The original simple starting point of the model library is to improve the efficiency and experience of Kubernetes YAML users. We hope to simplify the writing of user-side configuration code by abstracting and encapsulating the model with more complex code into a unified model. Konfig consists of the following parts: - -- **Core model**: - - **Front-end model**: The front-end model is the "user interface", which contains all configurable attributes exposed to users on the platform side. Some repetitive and deducible configurations are omitted, and essential attributes are abstracted and exposed to users. It has user-friendly features, such as `server.k`. - - **Back-end model**: The back-end model is "model implementation", which is the model that makes the properties of the front-end model effective. It mainly contains the rendering logic of the front-end model instance. The back-end model can use KCL to write validation, logic judgment, code fragment reuse and other code to improve the reusability and robustness of the configuration code, and is not sensitive to users, such as `server_backend.k`. -- **Domain model**: It is a model that does not contain any implementation logic and abstraction. It is often generated by tool transformation and does not need to be modified. It corresponds to the real effective YAML attribute one by one. The domain model needs to be further abstracted and is generally not directly used by users. For example, `kusion_kubernetes` is the domain model library of Kubernetes scenarios. - -In addition, the core model simplifies the configuration code of front-end users through two layers of abstraction: the front-end model and the back-end model. The domain model is automatically generated through the KCL OpenAPI. diff --git a/versioned_docs/version-0.5.4/user_docs/guides/working-with-konfig/2-structure.md b/versioned_docs/version-0.5.4/user_docs/guides/working-with-konfig/2-structure.md deleted file mode 100644 index 64e74b1d..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/working-with-konfig/2-structure.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -id: structure -sidebar_label: Structure ---- - -# Konfig Structure - -This article mainly explains the directory and code structure of the Konfig repository. - -## Overview - -```bash -. -├── .github # CI Scripts -├── Makefile # Building and testing scripts -├── README.md # Documents -├── appops # Application configuration. This folder is used to place KCL operation and maintenance configuration of all applications -│ ├── clickhouse-operator -│ ├── code-city -│ ├── guestbook -│ ├── http-echo -│ └── nginx-example -├── base # Models -│ ├── examples # Examples -│ │ ├── monitoring # Monitoring example -│ │ ├── native # Kubernetes resource example -│ │ ├── provider # Basic resource configuration example such as Terraform resource -│ │ └── server # Server example. -│ └── pkg -│ ├── kusion_kubernetes # Kubernetes domain models -│ ├── kusion_models # Core models -│ ├── kusion_prometheus # Prometheus domain models -│ └── kusion_provider # Basic resource models such as Terraform resource -└── kcl.mod # The KCL module declaration file -``` - -## Core Model - -The core model library is generally named `kusion_models`, mainly including front-end model, back-end model, renderer, etc. The directory structure is: - -```bash -├── commons # Common models -├── kube # Cloud-native resource core models -│ ├── backend # Back-end models -│ ├── frontend # Front-end models -│ │ ├── common # Common front-end models -│ │ ├── configmap # ConfigMap -│ │ ├── container # Container -│ │ ├── ingress # Ingress -│ │ ├── resource # Resource -│ │ ├── secret # Secret -│ │ ├── service # Service -│ │ ├── sidecar # Sidecar -│ │ ├── strategy # strategy -│ │ ├── volume # Volume -│ │ └── server.k # The `Server` model -│ ├── metadata # Kubernetes metadata -│ ├── mixins # Mixin -│ ├── render # Front-to-back-end renderers. -│ ├── templates # Data template -│ └── utils -└── metadata # Common metadata -``` - -## Project and Stack - -![](/img/docs/user_docs/concepts/project-stack.png) - -Project and Stack are logical isolation concepts used to organize the Konfig. - -### Project - -Any folder that contains the file `project.yaml` will be regarded as a Project, and the `project.yaml` is used to describe the metadata of this Project like `name` and `tenant`. Projects must have clear business semantics and must belong to a tenant. Users can map an application or an operation scenario to a Project. - -### Stack - -Like Project, any folder that contains the file `stack.yaml` will be regarded as a Stack and `stack.yaml` is used to describe the metadata of this Stack. Stack is a set of `.k` files that represents the smallest operation unit that can be configured and deployed individually. It tends to represent different stages in the CI/CD process, such as dev, gray, prod, etc. - -### Relationship between Project and Stack - -A Project contains one or more Stacks, and a Stack must belong to and can only belong to one Project. Users can interpret the meaning of Project and Stack according to their own needs and flexibly organize the Konfig structure. We provide the following example as a best practice according to our experiences: - -```bash -appops/nginx-example -├── README.md # Project readme -├── base # common configurations for all stacks -│ └── base.k -├── dev # dev stack -│ ├── ci-test # CI test configs -│ │ ├── settings.yaml # test data -│ │ └── stdout.golden.yaml # expected test result -│ ├── kcl.yaml # kcl config -│ ├── main.k -│ └── stack.yaml # Stack metadata -└── project.yaml # Project metadata -``` - -The Project represents an application and Stack represents different environments of this application, such as dev, pre, prod, etc. Common configurations can be stored in a `base` directory under this Project. diff --git a/versioned_docs/version-0.5.4/user_docs/guides/working-with-konfig/3-quick-start.md b/versioned_docs/version-0.5.4/user_docs/guides/working-with-konfig/3-quick-start.md deleted file mode 100644 index 82fa6f36..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/working-with-konfig/3-quick-start.md +++ /dev/null @@ -1,198 +0,0 @@ ---- -id: guide -sidebar_label: Quick Start ---- - -# Introduction - -This guide shows you how to use the KCL language and CLIs to complete the deployment of an application running in Kubernetes. We call the abstraction of application operation and maintenance configuration as `Server`, and its instance as `Application`. It is essentially an operation and maintenance model defined by KCL. - -In actual production, the application online generally needs to update several k8s resources: - -- Namespace -- Deployment -- Service - -This guide requires you to have a basic understanding of Kubernetes. If you are not familiar with the relevant concepts, please refer to the links below: - -- [Learn Kubernetes Basics](https://kubernetes.io/docs/tutorials/kubernetes-basics/) -- [Namespace](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/) -- [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) -- [Service](https://kubernetes.io/docs/concepts/services-networking/service/) - -## Prerequisites - -Before we start, we need to complete the following steps: - -1. Install KCL - See [Download and Install](/docs/user_docs/getting-started/install) for more details. - -2. Clone the [Konfig repo](https://github.com/KusionStack/konfig.git) - -```shell -git clone https://github.com/KusionStack/konfig.git && cd konfig -``` - -## Quick Start - -### 1. Compiling - -The programming language of the project is KCL, not JSON/YAML which Kubernetes recognizes, so it needs to be compiled to get the final output. - -Enter stack dir `appops/nginx-example/dev` and compile: - -```bash -cd appops/nginx-example/dev && kcl -Y kcl.yaml -D __konfig_output_format__=raw -``` - -The output YAML is: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-exampledev - namespace: nginx-example -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - template: - metadata: - labels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - spec: - containers: - - image: nginx:1.7.8 - name: main - ports: - - containerPort: 80 - protocol: TCP - resources: - limits: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi - requests: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi ---- -apiVersion: v1 -kind: Namespace -metadata: - name: nginx-example ---- -apiVersion: v1 -kind: Service -metadata: - name: nginx-example - namespace: nginx-example -spec: - ports: - - nodePort: 30201 - port: 80 - targetPort: 80 - selector: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - type: NodePort -``` - -After compiling, we can see three resources: - -- A `Deployment` with the name `nginx-exampledev` -- A `Namespace` with the name `nginx-example` -- A `Service` with the name `nginx-example` - -The above completes the configuration and takes effect. Later, we can use the command `kubectl apply` to apply and check the actual status of resources. This guide will not elaborate. - -### 2. Modification - -The `image` attribute in the `Server` model is used to declare the application's container image. We can modify the `image` value in `base/main.k` to modify or upgrade the image: - -```diff -14c14 -< image = "nginx:1.7.8" ---- -> image = "nginx:latest" -``` - -Recompile the configuration code to obtain the modified YAML output: - -```shell -kcl -Y kcl.yaml -D __konfig_output_format__=raw -``` - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-exampledev - namespace: nginx-example -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - template: - metadata: - labels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - spec: - containers: - - image: nginx:latest - name: main - ports: - - containerPort: 80 - protocol: TCP - resources: - limits: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi - requests: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi ---- -apiVersion: v1 -kind: Namespace -metadata: - name: nginx-example ---- -apiVersion: v1 -kind: Service -metadata: - name: nginx-example - namespace: nginx-example -spec: - ports: - - nodePort: 30201 - port: 80 - targetPort: 80 - selector: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - type: NodePort -``` - -## Summary - -This document mainly introduces how to use the KCL and Konfig library to deploy a Long Running application running in Kubernetes. diff --git a/versioned_docs/version-0.5.4/user_docs/guides/working-with-konfig/4-best-practice.md b/versioned_docs/version-0.5.4/user_docs/guides/working-with-konfig/4-best-practice.md deleted file mode 100644 index ee0cc576..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/working-with-konfig/4-best-practice.md +++ /dev/null @@ -1,449 +0,0 @@ ---- -id: practice -sidebar_label: Best Practice ---- - -# Best Practice - -This document aims to explain the best practices for integrating new models into the Konfig library and designing, building and writing KCL code models. New models are generally designed and abstracted using the best practice of separating front-end and back-end models. The direct purpose of distinguishing between front-end and back-end models is to separate `"user interface"` and `"model implementation"`, achieving a user-friendly and simple configuration interface as well as automated configuration query and modification interfaces. - -## Workflow - -![](/img/docs/user_docs/guides/konfig/workflow.png) - -1. **Coding**. Use the KCL OpenAPI tool to generate KCL schemas from the Customer Resources Definitions (CRDs) or OpenAPI Swagger models. These schemas define the atomic capabilities of the platform. -1. **Abstraction**. Based on these atomic capabilities, the platform abstracts user-oriented front-end models and provides a set of templates. These front- - end models cannot work independently, and corresponding back-end models are required. These back-end models will eventually obtain an instance of the front-end model at runtime; it parses the input front-end model and converts it into Kubernetes resources. -1. **Configuration**. Developers or SREs describe the requirements of applications based on front-end models. Users can define the base and different environment configurations for different environments e.g., base, development and production and different localities. In most cases, defining configurations only requires declaring key-value pairs. For some complex scenarios, users can define the logic to generate configurations. -1. **Automation**. After defining the user's configuration, all components have been defined and are ready to be automated. The platform can compile, execute, output, modify, query, and perform other automatic works through the KCL CLI or GPL-binding APIs. Users can also deploy the KCL configuration to the Kubernetes cluster with tools. - -## Model Structure - -Just as web applications provide a friendly user interface, and user input is further inferred at the backend of the application to obtain the final data that falls into the database, similarly, using KCL for model design also follows the logic of front-end and back-end separation. In addition, when the downstream required data content changes, we only need to modify the rendering/logic of the user configuration data to the backend model, thereby avoiding large-scale modification of user configurations. - -Taking the sidecar configuration of application services as an example: - -```python -# Config user interface. -user_sidecar_feature_gates: str - -# Downstream config of processing. -sidecars = [ - { - name = "sidecar_name" # Additional template for sidecars parameters, users do not need to configure them. - feature_gates = user_sidecar_feature_gates - } -] -``` - -## Best Practices for Konfig Modeling - -### Use Single Attribute Instead of Configuration Templates - -For some backend models, the configuration attributes that need to be filled in are often large and comprehensive designs, requiring users to actively input more complex configuration templates, and the filling content of this attribute is basically the same for different users. For example, the configuration of logic shown below requires users to fill in a large amount of template data, which has a high mental cost. - -A simple best practice is to abstract such commonly used and complex templates into a simple attribute `overQuota` with the `bool` type in the front-end model, allowing users to do multiple-choice questions instead of filling in blank questions. For example, when the `overQuota` attribute is `True`, the back-end model will render this complex logic. - -- The front-end attribute `overQuota` - -```python -overQuota: bool -``` - -- The back-end YAML output: - -```yaml -spec: - template: - spec: - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: k8s/is-over-quota - operator: In - values: - - "true" -``` - -In addition, different template names can be designed according to specific business scenarios to fill in the blanks, such as designing an attribute template in the code shown below to assist users in template selection instead of directly filling in the template content. The legal template value can be `"success_ratio"` or `"service_cost"`. When the backend model extends more templates, the front-end code does not need to make any modifications, only needs to adapt the corresponding template logic in the backend model. - -```python -schema SLI: - template: str = "success_ratio" -``` - -In addition, it is recommended to avoid using complex structures directly as front-end model attributes to avoid users needing to rely on too many KCL syntax features (such as unpacking, looping, etc.) or writing many temporary variables to complete the instantiation of the structure when using the model. - -### Use Literal Type and Union Type - -In the above section, it was mentioned that a string attribute can be used to represent different template names, and further, a literal type can be used to express the optional content of the template. For example, the following improvements can be made. - -```python -schema SLI: - template: "success_ratio" | "service_cost" = "success_ratio" -``` - -The type of template is a combination of two string types, indicating that the template can only be `"success_ratio"` or `"service_cost"`. When the user fills in the values of other strings, the KCL compiler will report an error. - -In addition to using union types for literal types, KCL also supports union for complex types such as schema types. For the support of this backend **oneof** configuration, KCL has built-in composite structure union types for support. For example, we can define our own SLI front-end types for various scenarios: `CustomSliDataSource`, `PQLSLIDataSource`, and `StackSLIDataSource`. - -```python -schema CustomSLIDataSource: - customPluginUrl: str - -schema PQLSLIDataSource: - total?: str - error?: str - success?: str - cost?: str - count?: str - -schema StackSLIDataSource: - stack: str - groupBy?: str - metric?: str - -# Simplify type definitions using type aliases -type DataSource = CustomSLIDataSource | PQLSLIDataSource | StackSLIDataSource - -schema DataConfiguration: - sources: {str: DataSource} -``` - -The advantage of designing this front-end model is that the compiler can statically check that the type written by the user can only be a certain type. If the back-end model is used directly, it cannot directly obtain the mapping relationship between different types of types and the fields that need to be filled in from the model. - -In addition, the overall design of the front-end model should also consider horizontal scalability, using the union type as much as possible, fully utilizing the advantages of coding, and avoiding unnecessary large amounts of code restructuring and modification when connecting to different backend or backend models. In addition, for the factory pattern commonly used in other GPL languages, union types can also be used instead in KCL. For example, if you want to obtain a constructor of a type based on the content of a string, you can directly use union types for optimization. - -Using the factory pattern in KCL: - -```python -schema DataA: - id?: int = 1 - value?: str = "value" - -schema DataB: - name?: str = "DataB" - -_dataFactory: {str:} = { - DataA = DataA - DataB = DataB -} -dataA = _dataFactory["DataA"]() -dataB = _dataFactory["DataB"]() -``` - -Replacing the factory pattern with the KCL union type. - -```python -schema DataA: - id?: int = 1 - value?: str = "value" - -schema DataB: - name?: str = "DataB" - -# Just use the union type. -dataA: DataA | DataB = DataA() -dataB: DataA | DataB = DataB() -``` - -### Use Dict Instead of List As Much As Possible - -To make it easier to modify configurations on-site or automate queries, it is advisable to define list or array attributes as dictionary types for easy indexing. In many complex configuration scenarios, the index of a list is arbitrary and the order of elements has no impact on the configuration. Using a dictionary type instead of a list type allows for more convenient data querying and modification. For example: - -```python -schema Person: - name: str - age: int - -schema House: - persons: [Person] - -house = House { - persons = [ - Person { - name = "Alice" - age = 18 - } - Person { - name = "Bob" - age = 10 - } - ] -} -``` - -For example, in the above example, if you want to query the age of the person named `"Alice"` from the list of persons in the house, you need to loop through the list to find Alice's age. However, if you define persons as a dictionary like the following code, it not only looks more concise in code, but you can also directly retrieve Alice's age by using house.persons.Alice.age. In addition, the information of the entire configuration is complete and has no redundant information. - -```python -schema Person: - age: int - -schema House: - persons: {str: Person} # Use Dict Instead of List - -house = House { - persons = { - Alice = Person { age = 18 } - Bob = Person { age = 10 } - } -} -``` - -### Write Validation Expressions for Models - -For frontend models, it is often necessary to validate the fields filled in by users. In this case, KCL's check expressions can be used in conjunction with KCL's built-in functions/syntax/system libraries to perform field validation. For frontend model validation, it is recommended to directly write it in the frontend model definition as a prerequisite for validation, in order to avoid unexpected errors that may occur when the errors are passed to the backend model. - -Use all/any expressions and check expressions for validation - -```python -import regex - -schema ConfigMap: - name: str - data: {str:str} - configMounts?: [ConfigMount] - - check: - all k in data { - regex.match(k, r"[A-Za-z0-9_.-]*") - }, "a valid config key must consist of alphanumeric characters, '-', '_' or '.'" - -schema ConfigMount: - containerName: str - mountPath: str - subPath?: str - - check: - ":" not in mountPath, "mount path must not contain ':'" -``` - -### Use Numerical Unit Type - -Numbers with units in KCL have a built-in type of `units.NumberMultiplier`, and any arithmetic operations are not allowed. - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -x0: NumberMultiplier = 1M # Ok -x1: NumberMultiplier = x0 # Ok -x2 = x0 + x1 # Error: unsupported operand type(s) for +: 'number_multiplier(1M)' and 'number_multiplier(1M)' -``` - -We can use the `int()/float()` function and `str()` function to convert the number unit type to integer or string type, and the resulting string retains the units of the original number unit type. - -```python -a: int = int(1Ki) # 1024 -b: str = str(1Mi) # "1Mi" -``` - -The definitions related to Kubernetes Resource in Konfig can be written using numerical unit types - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -schema Resource: - cpu?: NumberMultiplier | int = 1 - memory?: NumberMultiplier = 1024Mi - disk?: NumberMultiplier = 10Gi - epchygontee?: int -``` - -### Automated Modification of Front-end Model Instances - -In KCL, automated modification of front-end model instances can be achieved through the CLI and API. For example, if we want to modify the image content of an application (Konfig Stack Path: apps/nginx example/dev) configuration, we can directly execute the following command to modify the image content. - -```python -kcl -Y kcl.yaml ci-test/settings.yaml -o ci-test/stdout.golden.yaml -d -O :appConfiguration.image=\"test-image-v1\" -``` - -For more documentation related to automation, please refer to the [Automation Documents](/docs/user_docs/guides/automation) section. - -### Use Functions - -```python -# Define a function that adds two numbers and returns the result。 -add = lambda x, y { - x + y -} -# Define a function that subs two numbers and returns the result。 -sub = lambda x, y { - x - y -} -# Call the function, pass in arguments, and obtain the return value. -result = sub(add(2, 3), 2) # The result is 3. -``` - -The output YAML is - -```yaml -result: 3 -``` - -### Use Package and Module - -Create a package called `utils.k`, define a KCL function called `add` in it, and import it into another file for use. - -- `utils.k` - -```python -# utils.k - -# Define a function that adds two numbers and returns the result。 -add = lambda x, y { - x + y -} - -# Define a function that subs two numbers and returns the result。 -sub = lambda x, y { - x - y -} -``` - -- `main.k` - -```python -# main.k -import .utils - -# Call the function, pass in arguments, and obtain the return value. -result = utils.sub(utils.add(2, 3), 2) # The result is 3. -``` - -### Simplify Logical Expressions Using Configuration - -```python -# Complex Logic, `_cpu` is a non-exported and mutable attribute. -_cpu = 256 -_priority = "1" - -if _priority == "1": - _cpu = 256 -elif _priority == "2": - _cpu = 512 -elif _priority == "3": - _cpu = 1024 -else: - _cpu = 2048 - -# Simplify Logic Expression using Config -cpuMap = { - "1" = 256 - "2" = 512 - "3" = 1024 -} -# Get cpu from the cpuMap, when not found, use the default value 2048. -cpu = cpuMap[_priority] or 2048 -``` - -The output is - -```yaml -cpuMap: - "1": 256 - "2": 512 - "3": 1024 -cpu256: 256 -cpu2048: 2048 -``` - -### Separate Logic and Data - -We can use KCL **schema**, **config**, and **lambda** to separate **data** and **logic** as much as possible. - -For example, we can write the following code (main.k). - -```python -schema Student: - """Define a `Student` schema model with documents. - - Attributes - ---------- - name : str, required - The name of the student. - id : int, required. - The id number of the student. - grade : int, required. - The grade of the student. - - Examples - -------- - s = Student { - name = "Alice" - id = 1 - grade = 80 - } - - """ - name: str - id: int - grade: int - - # Define constraints for the `Student` model. - check: - id >= 0 - 0 <= grade <= 100 - -# Student data. -students: [Student] = [ - {name = "Alice", id = 1, grade = 85} - {name = "Bob", id = 2, grade = 70} - {name = "Charlie", id = 3, grade = 90} - {name = "David", id = 4, grade = 80} - {name = "Eve", id = 5, grade = 95} -] - -# Student logic. -query_student_where_name = lambda students: [Student], name: str { - # Query the first student where name is `name` - filter s in students { - s.name == name - }?[0] -} - -alice = query_student_where_name(students, name="Alice") -bob = query_student_where_name(students, name="Bob") -``` - -The output is - -```yaml -students: - - name: Alice - id: 1 - grade: 85 - - name: Bob - id: 2 - grade: 70 - - name: Charlie - id: 3 - grade: 90 - - name: David - id: 4 - grade: 80 - - name: Eve - id: 5 - grade: 95 -alice: - name: Alice - id: 1 - grade: 85 -bob: - name: Bob - id: 2 - grade: 70 -``` - -### Add Comments for Models - -To facilitate user understanding and automatic model documentation generation, it is necessary to write comments for the defined model. The comment content usually includes an explanation of the model, an explanation of model fields, types, default values, usage examples, and more. For detailed KCL schema code commenting guidelines and automatic model documentation generation, please refer to the [KCL Documentation Specification](/docs/tools/cli/kcl/docgen). Additionally, we can use the `kcl-doc generate` command to extract documentation from the user-specified file or directory and output it to the specified directory. - -## Backend Model - -The backend model is an "implementation model," which mainly includes the logical code to map the frontend model to the backend model. After the frontend model is written, we can use the frontend model schema to create frontend model instances, and write the corresponding backend mapping/rendering code to convert these frontend instances into the backend model. By using KCL's multi-file compilation and `Schema.instances()` function, the frontend and backend code can be highly decoupled, so that users only need to focus on frontend configuration without being aware of the complex validation and logical code of the model. diff --git a/versioned_docs/version-0.5.4/user_docs/guides/working-with-konfig/_category_.json b/versioned_docs/version-0.5.4/user_docs/guides/working-with-konfig/_category_.json deleted file mode 100644 index a71426f9..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/working-with-konfig/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Konfig", - "position": 10 -} diff --git a/versioned_docs/version-0.5.4/user_docs/guides/working-with-kusion/_category_.json b/versioned_docs/version-0.5.4/user_docs/guides/working-with-kusion/_category_.json deleted file mode 100644 index 9f914498..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/working-with-kusion/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KusionStack", - "position": 15 -} diff --git a/versioned_docs/version-0.5.4/user_docs/guides/working-with-kusion/index.md b/versioned_docs/version-0.5.4/user_docs/guides/working-with-kusion/index.md deleted file mode 100644 index 2565ad03..00000000 --- a/versioned_docs/version-0.5.4/user_docs/guides/working-with-kusion/index.md +++ /dev/null @@ -1,15 +0,0 @@ -# KusionStack - -**KusionStack is an open-source cloud-native programmable technology stack!** - -KusionStack is a highly flexible programmable technology stack to enable unified application delivery and operation, inspired by the word Fusion, which aims to help enterprises build an application-centric configuration management plane and DevOps ecosystem. - -1. Fusion of hybrid scenarios of **private cloud**, **hybrid cloud**, and **multi-cloud** -2. Fusion of hybrid platform technologies of **cloud-native** and a variety of other platform technologies -3. Fusion of enterprise-level demands of **multi-project**, **multi-team**, **multi-role**, **multi-tenant**, and **multi-environment** - -Based on the concept of Platform as Code, developers can quickly unify the full configuration schemas, constraints, policies and configs across the application life cycle, work with the **hybrid technologies and cloud environment**, go through the **end-to-end workflow** from programming to launching, and truly achieve **write once, deliver anywhere**. - -![](/img/docs/user_docs/intro/kusion-stack-1.png) - -More documents and use cases at [https://kusionstack.io/](https://kusionstack.io/) diff --git a/versioned_docs/version-0.5.4/user_docs/support/_category_.json b/versioned_docs/version-0.5.4/user_docs/support/_category_.json deleted file mode 100644 index 60548d80..00000000 --- a/versioned_docs/version-0.5.4/user_docs/support/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "FAQ", - "position": 6 -} diff --git a/versioned_docs/version-0.5.4/user_docs/support/faq-cli.md b/versioned_docs/version-0.5.4/user_docs/support/faq-cli.md deleted file mode 100644 index ab012a34..00000000 --- a/versioned_docs/version-0.5.4/user_docs/support/faq-cli.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Command Line Tool - -## 1. What is the function of the `settings.yaml` in the application directory of the Konfig? - -The `settings.yaml` in KCL indicates the configuration file of the KCL command line tool. You can put the compiled configuration into it, such as the file to be compiled, the option dynamic parameter that needs to be input(`-d`), whether to ignore the null value(`-n`) and other configurations. - -For example, for the following arguments: - -```shell -kcl main.k -D key=value -n -r -``` - -It can be replaced by the following command line arguments and `settings.yaml` - -```shell -kcl -Y settings.yaml -``` - -settings.yaml - -```yaml -kcl_cli_configs: - files: - - main.k - disable_none: true - strict_range_check: true -kcl_options: - - key: key - value: value -``` - -- `kcl_cli_configs` indicates configurable compilation arguments, `file` indicates the KCL file used for compilation,`disable_none` indicates whether to use `-n`, `strict_range_check` indicates whether to use `-r`. -- `kcl_options` indicates dynamic options that can be configured, `key` indicates option name, `value` indicates option value - -Note: The file name does not need to be `settings.yaml`, but the configuration in it must meet the requirements. - -### 2. How to input dynamic options? How to get dynamic options in code? - -KCL supports multiple ways to input dynamic options - -- `-D`: Use the command line argument `-D` to input dynamic options. It supports basic data types str/int/float/bool and structured data types list/dict - -```shell -kcl main.k -D env-type=TEST -D deploy-topology='[{"cluster":"my-cluster","idc":"my-idc","replicas":2,"workspace":"my-idc","zone":"my-zone"}]' -``` - -- `-Y`: Use the command line argument `-Y` to input dynamic options by configuration file: - -```yaml -kcl_options: - - key: env-type - value: TEST - - key: deploy-topology - value: - - cluster: my-cluster - idc: my-idc - replicas: 2 - workspace: my-workspace - zone: my-zone -``` - -Use the built-in function `option()` to get it: - -```python -env = option("env-type") -deploy_topology = option("deploy-topology") -``` - -Output: - -```yaml -env: TEST -deploy_topology: - - cluster: my-cluster - idc: my-idc - replicas: 2 - workspace: my-workspace - zone: my-zone -``` - -### 3. How to compile multiple files? - -- Input multiple files in the command line: - -```shell -kcl file1.k file2.k file3.k -``` - -- Set multiple files in configuration file and use command line argument `-Y`: - -settings.yaml - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - - file3.k -``` - -```shell -kcl -Y settings.yaml -``` diff --git a/versioned_docs/version-0.5.4/user_docs/support/faq-install.md b/versioned_docs/version-0.5.4/user_docs/support/faq-install.md deleted file mode 100644 index 37100c09..00000000 --- a/versioned_docs/version-0.5.4/user_docs/support/faq-install.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Installation Troubleshooting - -## MacOS prompts that 'kcl' cannot be opened because Apple cannot check if it contains malicious software - -MacOS prompts that 'kcl' cannot be opened because Apple cannot check if it contains malicious software. This issue is due to the Gatekeeper security feature in the macOS system preventing the application from running. To solve this issue, follow these steps: - -Open 'System Preferences' and click 'Security and Privacy'. In the "General" tab, you will see a message: '"kcl" cannot be opened'. Click 'Open still'. Alternatively, you can click 'Open any method' to open your application. (You may need to use administrator privileges to open the application.) - -If you don't want to perform these steps every time you open an application, you can add the application to the whitelist to run without being blocked. To add your application to the whitelist: - -Open the terminal and run the following command: - -```shell -xattr -rd com.apple.quarantine /path/to/kcl -``` - -Where `/path/to/kcl` is the complete path of the kcl application. After running the command, the application will be added to the whitelist and Gatekeeper will no longer prevent it from running. - -## program not found or run linker failed error on Windows/Linux/MacOS - -Please ensure that the following dependencies are in your PATH: - -- `clang` for MacOS -- `gcc` for Linux -- `cl.exe` for Windows, which can be obtained by installing MSVC diff --git a/versioned_docs/version-0.5.4/user_docs/support/faq-kcl.md b/versioned_docs/version-0.5.4/user_docs/support/faq-kcl.md deleted file mode 100644 index 860dd15b..00000000 --- a/versioned_docs/version-0.5.4/user_docs/support/faq-kcl.md +++ /dev/null @@ -1,2341 +0,0 @@ ---- -sidebar_position: 2 ---- - -# KCL - -## 1. How to write a simple key-value pair configuration with KCL - -Create a file named `config.k` - -```python -cpu = 256 -memory = 512 -image = "nginx:1.14.2" -service = "my-service" -``` - -In the above KCL code, `cpu` and `memory` are defined to be declared as integer types, and their values are `256` and `512`, while `image` and `service` are string types, their values are `image` and `service`. - -Use the following command to compile the above KCL file into YAML for output - -``` -kcl config.k -``` - -The output YAML is - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -If we want to output the YAML content to a file such as `config.yaml`, we can add the `-o|--output` CLI argument: - -``` -kcl config.k -o config.yaml -``` - -## 2. What are the basic data types in KCL? - -KCL's current basic data types and values include: - -- Integer type `int` - - Examples: decimal positive integer `1`, decimal negative integer `-1`, hexadecimal integer `0x10`, octal integer `0o10`, binary integer `0b10` -- float type `float` - - Examples: positive float `1.10`, `1.0`, negative float `-35.59`, `-90.`, scientific notation float `32.3e+18`, `70.2E-12` -- boolean type `bool` - - Example: true value `True`, false value `False` -- String type `str` - marked with `'`, `"` - - Example: double quoted string `"string"`, `"""string"""`, single quoted string `'string'`, `'''string'''` -- List type `list` - marked with `[`, `]` - - Example: empty list `[]`, string list `["string1", "string2", "string3"]` -- Dictionary type `dict` - marked with `{`, `}` - - Example: empty dictionary `{}`, dictionary whose keys and values ​​are all strings `{"key1": "value1", "key2": "value2"}` -- Structure type `schema` - defined with the keyword `schema` -- Null value type `None` - used to indicate that the value of a variable is null, corresponding to the `null` value of the output YAML -- Undefined value type `Undefined` - used to indicate that a variable has not been assigned a value, and a variable with a value of `Undefined` will not be output to YAML - -```python -schema Person: - name: str - age: int - -alice = Person { - name = "Alice" - age = 18 -} -bob = Person { - name = "Bob" - age = 10 -} -``` - -> Note: All KCL variables can be assigned the null value `None` and the undefined value `Undefined`. - -## 3. What do some KCL variable names prefixed with `_` underscore mean? What's the difference between without the `_` underscore prefix? In what scenarios are they suitable for use? - -A variable with an underscore prefix in KCL represents a **hidden**, **mutable** variable, **hidden** means a variable with an underscore prefix will not be output to YAML, and **mutable** means that a variable with an underscore prefix can be repeatedly assigned multiple times, and a variable without an underscore prefix is immutable after being assigned. - -```python -name = 'Foo' # Exported and immutable variable -name = 'Bar' # Error: An exported variable can only be assigned a value once -``` - -```python -_name = 'Foo' # Hidden and mutable variable -_name = 'Bar' - -schema Person: - _name: str # hidden and mutable -``` - -## 4. How to add elements to a dict? - -We can use the union operator `|` or the dict unpacking operator `**` to add elements into a dict, and we can use `in` and `not in` operators to determine whether the dict variable contains a certain key. - -```python -_left = {key: {key1 = "value1"}, intKey = 1} # Note: `=` denotes override the value. -_right = {key: {key2 = "value2"}, intKey = 2} -dataUnion = _left | _right # {"key": {"key1": "value1", "key2": "value2"}, "intKey": 2} -dataUnpack = {**_left, **_right} # {"key": {"key1": "value1", "key2": "value2"}, "intKey": 2} -``` - -The output YAML is - -```yaml -dataUnion: - key: - key1: value1 - key2: value2 - intKey: 2 -dataUnpack: - key: - key1: value1 - key2: value2 - intKey: 2 -``` - -It is also possible to add key-value pair to a dict using the `string interpolation` or the string `format` method. - -```python -dictKey1 = "key1" -dictKey2 = "key2" -data = { - "${dictKey1}" = "value1" - "{}".format(dictKey2) = "value2" -} -``` - -The output YAML is - -```yaml -dictKey1: key1 -dictKey2: key2 -data: - key1: value1 - key2: value2 -``` - -## 5. How to modify elements in dict? - -We can use the union operator `|`, or the unpacking operator `**` to modify the elements in the dict - -```python -_data = {key = "value"} # {"key": "value"} -_data = _data | {key = "override_value1"} # {"key": "override_value1"} -_data = {**_data, **{key = "override_value2"}} # {"key": "override_value2"} -``` - -If we want to delete a value with a key of `key` in the dict, we can use the unpacking operator `**{key = Undefined}` or the merge operator `| {key = Undefined}` to overwrite, the value of the key is Undefined after overwriting, and no YAML output will be done. - -## 6. How to add elements to list? - -There are two ways to add elements to a list: - -- Use `+`, `+=` and slice to concatenate list variables to add elements to the list - -```python -_args = ["a", "b", "c"] -_args += ["end"] # Add elements "end" to the end of the list: ["a", "b", "c", "end"] -_args = _args[:2] + ["x"] + _args[2:] # Insert element "x" at list index 2: ["a", "b", "x", "c", "end"] -_args = ["start"] + _args # Add elements "start" to the head of the list: ["start", "a", "b", "x", "c", "end"] -``` - -- Use the `*` unpacking operator to concatenate and merge lists - -```python -_args = ["a", "b", "c"] -_args = [*_args, "end"] # Add elements "end" to the end of the list: ["a", "b", "c", "end"] -_args = ["start", *_args] # Add elements "start" to the head of the list: ["start", "a", "b", "x", "c", "end"] -``` - -> Note: When the consecutive variables are `None/Undefined`, using `+` may cause an error, then we can use the list unpacking operator `*` or use the `or` operator to take the default value of the list to avoid null values judge. - -```python -data1 = [1, 2, 3] -data2 = None -data3 = [*data1, *data2] # Ok: [1, 2, 3] -data4 = data1 + data2 or [] # OK: [1, 2, 3], We can use the `or` operator to take the default value of data2 as [], when data2 is None/Undefined, take the empty list [] for calculation. -data5 = data1 + data2 # Error: can only concatenate list (not "NoneType") to list -``` - -## 7. How to modify/delete elements in list? - -There are two ways to modify the elements in the list: - -- Use slice to directly modify the value at an index of a list - -```python -_index = 1 -_args = ["a", "b", "c"] -_args = _args[:index] + ["x"] + _args[index+1:] # Modify the element of list index 1 to "x": ["a", "x", "c"] -``` - -- Use the list comprehension to modify elements in a list - -```python -_args = ["a", "b", "c"] -_args = ["x" if a == "b" else a for a in _args] # Change the value of "b" in the list to "x": ["a", "x", "c"] -``` - -There are two ways to delete elements in a list: - -- Use the list comprehension to delete elements with the `if` condition expressions. -- Use `filter` expression to filter elements. - -For example, if we want to delete a number greater than 2 in a list `[1, 2, 3, 4, 5]`, we can write as follows: - -```python -originList = [1, 2, 3, 4, 5] -oneWayDeleteListItem = [item for item in originList if item <= 2] -anotherWayDeleteListItem = filter item in originList { - item <= 2 -} -``` - -The output YAML is - -```yaml -originList: - - 1 - - 2 - - 3 - - 4 - - 5 -oneWayDeleteListItem: - - 1 - - 2 -anotherWayDeleteListItem: - - 1 - - 2 -``` - -## 8. How to write a for loop in KCL? How to understand and use list comprehension and dict comprehension? - -KCL currently only supports functional/declarative deductive for loops. We can traverse dict and list variables as follows: - -The specific form of a list comprehension is (where `[]` are used on both sides of the comprehension): - -```txt -[expression for expr in sequence1 - if condition1 - for expr2 in sequence2 - if condition2 - for expr3 in sequence3 ... - if condition3 - for exprN in sequenceN - if conditionN] -``` - -The specific form of dict comprehension is (where `{}` are used on both sides of the comprehension): - -```txt -{expression for expr in sequence1 - if condition1 - for expr2 in sequence2 - if condition2 - for expr3 in sequence3 ... - if condition3 - for exprN in sequenceN - if conditionN} -``` - -The `if` in the above forms represents the filter condition, and the expression `expr` that satisfies the condition will be generated into a new list or dict - -List comprehension example: - -```python -_listData = [1, 2, 3, 4, 5, 6] -_listData = [l * 2 for l in _listData] # All elements in _listData are multiplied by 2: [2, 4, 6, 8, 10, 12] -_listData = [l for l in _listData if l % 4 == 0] # Filter out all elements in _listData that are divisible by 4: [4, 8, 12] -_listData = [l + 100 if l % 8 == 0 else l for l in _listData] # Traverse _listData, when the element in it is divisible by 8, add 100 to the element, otherwise keep it unchanged: [4, 108, 12] -``` - -Note the difference between the two `if`s on lines 3 and 4 in the above code: - -- The first `if` represents the filter condition of the variable `_listData` list comprehension itself, and cannot be followed by `else`. Elements that meet the conditions will be added to the list, and elements that do not meet the conditions will be removed. Besides, the process may change the length of the list. -- The second `if` represents the selection condition of the list iteration variable `l`, which means the `if-else` ternary expression, which must be followed by `else`, regardless of whether the condition is met, the resulting element is still in the list, the length of the list does not change. - -Dict comprehension example: - -```python -_dictData = {key1 = "value1", key2 = "value2"} -_dictData = {k = _dictData[k] for k in _dictData if k == "key1" and _dictData[k] == "value1"} # Filter out the elements whose key is "key1" and value is "value1" in _dictData, {"key1": "value1"} -``` - -Use comprehension to get all keys of dict: - -```python -dictData = {key1 = "value1", key2 = "value2"} -dictDataKeys = [k for k in _dictData] # ["key1", "key2"] -``` - -Use comprehension to sort a dict in ascending order by key: - -```python -dictData = {key3 = "value3", key2 = "value2", key1 = "value1"} # {'key3': 'value3', 'key2': 'value2', 'key1': 'value1'} -dictSortedData = {k = dictData[k] for k in sorted(dictData)} # {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'} -``` - -Multi-level comprehension example: - -```python -array1 = [1, 2, 3] -array2 = [4, 5, 6] -data = [a1 + a2 for a1 in array1 for a2 in array2] # [5, 6, 7, 6, 7, 8, 7, 8, 9] len(data) == len(array1) * len(array2) -``` - -Double variable loop (list comprehension supports index iteration of list and value iteration of dict, which can simplify the code writing of list/dict iteration process): - -- list - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use _ to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -- dict - -```python -data = {key1 = "value1", key2 = "value2"} -# Single variable loop -dataKeys1 = [k for k in data] # ["key1", "key2"] -dataValues1 = [data[k] for k in data] # ["value1", "value2"] -# Double variable loop -dataKeys2 = [k for k, v in data] # ["key1", "key2"] -dataValues2 = [v for k, v in data] # ["value1", "value2"] -dataFilter = {k = v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use _ to ignore loop variables -dataKeys3 = [k for k, _ in data] # ["key1", "key2"] -dataValues3 = [v for _, v in data] # ["value1", "value2"] -``` - -## 9. How to write an if conditional statement? - -KCL supports two ways to write if conditional statements: - -- if-elif-else block statement, where both elif and else blocks can be omitted, and the elif block can be used multiple times - -```python -success = True -_result = "failed" -if success: - _result = "success" -``` - -```python -success = True -if success: - _result = "success" -else: - _result = "failed" -``` - -```python -_result = 0 -if condition == "one": - _result = 1 -elif condition == "two": - _result = 2 -elif condition == "three": - _result = 3 -else: - _result = 4 -``` - -- Conditional expression ` if else `, similar to ` ? : ` ternary expression in C language - -```python -success = True -_result = "success" if success else "failed" -``` - -> Note: When writing an if-elif-else block statement, pay attention to the colon `:` after the if condition and keep the indentation consistent. - -In addition, conditional expressions can also be written directly in a list or dict (the difference is that the value to be written in the if expression written in the structure is not a statement): - -- list - -```python -env = "prod" -data = [ - "env_value" - ":" - if env == "prod": - "prod" # Write values that need to be added to data, not statements - else: - "other_prod" -] # ["env_value", ":", "prod"] -``` - -- dict - -```python -env = "prod" -config = { - if env == "prod": - MY_PROD_ENV = "prod_value" # Write key-value pairs that need to be added to config, not statements - else: - OTHER_ENV = "other_value" -} # {"MY_PROD_ENV": "prod_value"} -``` - -## 10. How to express logical operations such as "and" "or" "not"? - -In KCL, use `and` for "logical and", use `or` for "logical or", use `not` for "not", which is similar to `&&`, `||` and `~` semantic in C language. - -```python -done = True -col == 0 -if done and (col == 0 or col == 3): - ok = 1 -``` - -For "bitwise AND", "bitwise OR" and "bitwise XOR" of integers, we can use `&`, `|` and `^` operators in KCL, which is similar to `&`, `|` and `^` semantic in C language. - -```python -value = 0x22 -bitmask = 0x0f - -assert (value & bitmask) == 0x02 -assert (value & ~bitmask) == 0x20 -assert (value | bitmask) == 0x2f -assert (value ^ bitmask) == 0x2d -``` - -When we need to write a pattern such as `A if A else B`, we can use `A or B` to simplify, such as the following code: - -```python -value = [0] -default = [1] -x0 = value if value else default -x1 = value or default # Use `value or default` instead of `value if value else default` -``` - -## 11. How to judge whether a variable is None/Undefined, and whether a string/dict/list is empty? - -Please note that `False`, `None`, `Undefined`, number `0`, empty list `[]`, empty dictionary `{}` and empty string `""`, `''`, `""""""`, `''''''` in the conditional expression, are all treated as `false` expressions. - -For example, when judging a string variable `strData` is neither `None/Undefined` nor an empty string (string length is greater than 0), we can simply use the following expression: - -```python -strData = "value" -if strData: - isEmptyStr = False -``` - -Empty dictionary and empty list judgment examples: - -```python -_emptyList = [] -_emptyDict = {} -isEmptyList = False if _emptyList else True -isEmptyDict = False if _emptyDict else True -``` - -The output YAML is - -```yaml -isEmptyList: true -isEmptyDict: true -``` - -Or use the boolean function `bool` to judge - -```python -_emptyList = [] -_emptyDict = {} -isEmptyList = bool(_emptyList) -isEmptyDict = bool(_emptyDict) -``` - -## 12. How to concatenate strings, format strings, check string prefixes and suffixes and replace string content? - -- The `+` operator can be used to concatenate two strings in KCL - -```python -data1 = "string1" + "string2" # "string1string2" -data2 = "string1" + " " + "string2" # "string1 string2" -``` - -- There are currently two ways to format strings in KCL: - - `format` method for string variables `"{}".format()` - - Using string interpolation `${}` - -```python -hello = "hello" -a = "{} world".format(hello) -b = "${hello} world" -``` - -Note that if we want to use the `{` character or `}` alone in `"{}".format()`, we need to use `{{` and `}}` to convert `{` and `}` respectively, such as escaping a JSON string as follows: - -```python -data = "value" -jsonData = '{{"key": "{}"}}'.format(data) -``` - -The output YAML is - -```yaml -data: value -jsonData: '{"key": "value"}' -``` - -Note that if we want to use the `$` character alone in the `${}` interpolated string, we need to escape the `$` with `$$` - -```python -world = "world" -a = "hello {}".format(world) # "hello world" -b = "hello ${world}" # "hello world" -c = "$$hello ${world}$$" # "$hello world$" -c2 = "$" + "hello ${world}" + "$" # "$hello world$" -``` - -The output YAML is - -```yaml -world: world -a: hello world -b: hello world -c: $hello world$ -c2: $hello world$ -``` - -- Use the `startswith` and `endswith` methods of strings in KCL to check the prefix and suffix of strings - -```python -data = "length" -isEndsWith = data.endswith("th") # True -isStartsWith = "length".startswith('len') # True -``` - -- Use the replace method of the string or the `regex.replace` function to replace the content of the string in KCL - -```python -import regex -data1 = "length".replace("len", "xxx") # Replace "len", "xxxgth" with "xxx" -data2 = regex.replace("abc123", r"\D", "0") # Replace all non-digits in "abc123" with "0", "000123" -``` - -Among them, `r"\D"` means that we do not need to use `\\` to escape the backslash `\` in `\D`, which is mostly used in regular expression strings. - -Besides, we can use index placeholders or keyword placeholders in string formatting expressions to format multiple strings - -- Index placeholders - -```python -x = '{2} {1} {0}'.format('directions', 'the', 'Read') -y = '{0} {0} {0}'.format('string') -``` - -The output YAML is - -```yaml -x: Read the directions -y: string string string -``` - -- Keyword placeholders - -```python -x = 'a: {a}, b: {b}, c: {c}'.format(a = 1, b = 'Two', c = 12.3) -``` - -The output YAML is - -```yaml -x: "a: 1, b: Two, c: 12.3" -``` - -## 13. What is the difference between using single and double quotes in a string? - -There is little difference between KCL single-quoted and double-quoted strings. The only difference is that we don't need to use `\"` to escape `"` in single-quoted strings, and we don't need to use `\'` to escape `'` in double-quoted strings. - -```python -singleQuotedString = 'This is my book named "foo"' # Don’t need to escape double quotes in single quoted strings. -doubleQuotedString = "This is my book named 'foo'" # Don’t need to escape single quotes in double quoted strings. -``` - -In addition, a long string consisting of three single quotes or three double quotes does not need to be escaped (except for the beginning and end of the string), such as the following example: - -```python -longStrWithQuote0 = """Double quotes in long strings "(not at the beginning and end)""" -longStrWithQuote1 = '''Double quotes in long strings "(not at the beginning and end)''' -longStrWithQuote2 = """Single quotes in long strings '(not at the beginning and end)""" -longStrWithQuote3 = '''Single quotes in long strings '(not at the beginning and end)''' -``` - -The output YAML is - -```yaml -longStrWithQuote0: Double quotes in long strings "(not at the beginning and end) -longStrWithQuote1: Double quotes in long strings "(not at the beginning and end) -longStrWithQuote2: Single quotes in long strings '(not at the beginning and end) -longStrWithQuote3: Single quotes in long strings '(not at the beginning and end) -``` - -## 14. How to write a long multiline string? - -In KCL, we can use a single-quoted string and newline characters `\n` or a triple-quoted string to write a multi-line string, and we can use the continuation character `\` to optimize the form of the KCL string. For example, for the three multi-line string variables in the following code, their values are the same: - -```python -string1 = "The first line\nThe second line\nThe third line\n" -string2 = """The first line -The second line -The third line -""" -string3 = """\ -The first line -The second line -The third line -""" # It is recommended to use the long string writing form of `string3`. -``` - -The output YAML is - -```yaml -string1: | - The first line - The second line - The third line -string2: | - The first line - The second line - The third line -string3: | - The first line - The second line - The third line -``` - -## 15. How to use regular expressions in KCL? - -Regular expressions can be used by importing the regular expression system module `import regex` in KCL, which includes the following functions: - -- **match**: Regular expression matching function, which matches the input string according to the regular expression, and returns a bool type to indicate whether the match is successful. -- **split**: Regular expression split function, which splits the string according to the regular expression, and returns a list of split strings. -- **replace**: Regular expression replacement function, which replaces all substrings in the string that satisfies the regular expression, and returns the replaced string. -- **compile**: Regular expression compilation function, which returns bool type to indicate whether it is a valid regular expression. -- **search**: Regular expression search function, which searches all substrings that satisfy the regular expression, and returns a list of substrings. - -Examples: - -```python -import regex - -regex_source = "Apple,Google,Baidu,Xiaomi" -regex_split = regex.split(regex_source, ",") -regex_replace = regex.replace(regex_source, ",", "|") -regex_compile = regex.compile("$^") -regex_search = regex.search("aaaa", "a") -regex_find_all = regex.findall("aaaa", "a") -regex_result = regex.match("192.168.0.1", "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$") # Determine if it is an IP string -regex_result_false = regex.match("192.168.0,1", "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$") # Determine if it is an IP string -``` - -The output YAML is - -```yaml -regex_source: Apple,Google,Baidu,Xiaomi -regex_split: - - Apple - - Google - - Baidu - - Xiaomi -regex_replace: Apple|Google|Baidu|Xiaomi -regex_compile: true -regex_search: true -regex_find_all: - - a - - a - - a - - a -regex_result: true -regex_result_false: false -``` - -For longer regular expressions, we can also use **r-string** to ignore the escape of `\` symbols to simplify the writing of regular expression strings. - -Examples: - -```python -import regex - -isIp = regex.match("192.168.0.1", r"^(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)$") # Determine if it is an IP string -``` - -```python -import regex - -schema Resource: - cpu: str = "1" - memory: str = "1024Mi" - disk: str = "10Gi" - check: - regex.match(cpu, r"^([+-]?[0-9.]+)([m]*[-+]?[0-9]*)$"), "cpu must match specific regular expression" - regex.match(memory, r"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"), "memory must match specific regular expression" - regex.match(disk, r"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"), "disk must match specific regular expression" -``` - -```python -import regex - -schema Env: - name: str - value?: str - check: - len(name) <= 63, "a valid env name must be no more than 63 characters" - regex.match(name, r"[A-Za-z_][A-Za-z0-9_]*"), "a valid env name must start with alphabetic character or '_', followed by a string of alphanumeric characters or '_'" -``` - -## 16. What is the meaning of schema in KCL? - -Schema is a language element in KCL that defines the type of configuration data. Like struct in C language or class in Java, attributes can be defined in it, and each attribute has a corresponding type. - -## 17. How to use schema? - -In KCL, we can use the `schema` keyword to define a structure in which we can declare the various attributes of the schema. - -```python -# A Person structure with firstName of attribute string type, lastName of string type, age of integer type. -schema Person: - firstName: str - lastName: str - # The default value of the age attribute is 0. - age: int = 0 -``` - -A complex example: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels: {str:str} -``` - -In the above code, `cpu` and `memory` are defined as integer types; `name`, `image` and `service` are string types; `command` is a list of string types; labels are dictionaries type whose key type and value type are both strings. - -## 18. How to add "optional" and "required" constraints to the schema attribute? - -The `?` operator is used in KCL to define an "optional" constraint for a schema, and the schema attribute is "required" by default. - -```python -# A Person structure with firstName of attribute string type, lastName of string type, age of integer type. -schema Person: - firstName?: str # firstName is an optional attribute that can be assigned to None/Undefined - lastName?: str # age is an optional attribute that can be assigned to None/Undefined - age: int = 18 # age is an optional attribute that can be assigned to None/Undefined. -``` - -## 19. How to write validation rules for attributes in schema? - -In the schema definition, we can use the `check` keyword to write the validation rules of the schema attribute. As shown below, each line in the check code block corresponds to a conditional expression. When the condition is satisfied, the validation is successful. The conditional expression can be followed by `, "check error message"` to indicate the information to be displayed when the validation fails. - -```python -import regex - -schema Sample: - foo: str # Required, cannot be None/Undefined, and the type must be str - bar: int # Required, cannot be None/Undefined, and the type must be int - fooList: [int] # Required, cannot be None/Undefined, and the type must be int list - color: "Red" | "Yellow" | "Blue" # Required, literal union type, and must be one of "Red", "Yellow", "Blue". - id?: int # Optional, can be None/Undefined, the type must be int - - check: - 0 <= bar < 100 # bar must be greater than or equal to 0 and less than 100 - 0 < len(fooList) < 100 # fooList cannot be None/Undefined, and the length must be greater than 0 and less than 100 - regex.match(foo, "^The.*Foo$") # regular expression matching - bar in range(100) # bar can only range from 1 to 99 - bar in [2, 4, 6, 8] # bar can only take 2, 4, 6, 8 - bar % 2 == 0 # bar must be a multiple of 2 - all foo in fooList { - foo > 1 - } # All elements in fooList must be greater than 1 - any foo in fooList { - foo > 10 - } # At least one element in fooList must be greater than 10 - abs(id) > 10 if id # check expression with if guard, when id is not empty, the absolute value of id must be greater than 10 -``` - -To sum up, the validation kinds supported in KCL schema are: - -| Kind | Method | -| ----------------- | ----------------------------------------------------------------------------------------- | -| Range | Using comparison operators such as `<`, `>` | -| Regex | Using methods such as `match` from the `regex` system module | -| Length | Using the `len` built-in function to get the length of a variable of type `list/dict/str` | -| Enum | Using literal union types | -| Optional/Required | Using optional/required attributes of schema | -| Condition | Using the check if conditional expression | - -## 20. How to add documentation to schema and its attributes? - -A complete schema document is represented as a triple-quoted string, with the following structure: - -```python -schema Person: - """The schema person definition - - Attributes - ---------- - name : str - The name of the person - age : int - The age of the person - - See Also - -------- - Son: - Sub-schema Son of the schema Person. - - Examples - -------- - person = Person { - name = "Alice" - age = 18 - } - """ - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -``` - -## 21. How to write configuration based on schema? How to reuse the common configuration between multiple configurations? - -In the process of schema instantiation, we can use the unpacking operator `**` to expand the public configuration - -```python -schema Boy: - name: str - age: int - hc: int - -schema Girl: - name: str - age: int - hc: int - -config = { - age = 18 - hc = 10 -} - -boy = Boy { - **config - name = "Bob" -} -girl = Girl { - **config - name = "Alice" -} -``` - -The output YAML is - -```yaml -config: - age: 18 - hc: 10 -boy: - name: Bob - age: 18 - hc: 10 -girl: - name: Alice - age: 18 - hc: 10 -``` - -## 22. How to override the default value of schema attribute when writing configuration based on schema? - -After defining a schema, we can use the schema name to instantiate the corresponding configuration, use the `:` operator to union schema attribute default values, and use `=` to override schema attribute default values. - -```python -schema Meta: - labels: {str:str} = {"key1" = "value1"} - annotations: {str:str} = {"key1" = "value1"} - -meta = Meta { - labels: {"key2": "value2"} - annotations = {"key2" = "value2"} -} -``` - -The output YAML is - -```yaml -meta: - labels: - key1: value1 - key2: value2 - annotations: - key2: value2 -``` - -## 23. How to reuse schema definitions? - -We can declare the schema name that the schema needs to inherit at the definition: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 - -# An employee **is** a person, and has some additional information. -schema Employee(Person): - bankCard: int - nationality: str - -employee = Employee { - firstName = "Bob" - lastName = "Green" - age = 18 - bankCard = 123456 - nationality = "China" -} -``` - -The output YAML is - -```yaml -employee: - firstName: Bob - lastName: Green - age: 18 - bankCard: 123456 - nationality: China -``` - -> Note: KCL only allows schema single inheritance. - -## 24. How to reuse schema logic through composition? - -We can use KCL schema mixin to reuse schema logic. Mixins are generally used for functions such as separation of data in schema internal attributes, and data mapping, which can make KCL code more modular and declarative. - -Note that it is not recommended to define dependencies for mixing attributes between different mixins, which will make the use of mixins complicated. - -Examples: - -```python -schema Person: - mixin [FullNameMixin, UpperMixin] - - firstName: str - lastName: str - fullName: str - upper: str - -schema FullNameMixin: - fullName = "{} {}".format(firstName, lastName) - -schema UpperMixin: - upper = fullName.upper() - -person = Person { - firstName = "John" - lastName = "Doe" -} -``` - -The output YAML is - -```yaml -person: - firstName: John - lastName: Doe - fullName: John Doe - upper: JOHN DOE -``` - -## 25. How to import other KCL files? - -Other KCL files can be imported via the `import` keyword, and KCL configuration files are organized into modules. A single KCL file is considered a module, and a directory is considered a package, as a special module. The `import` keyword supports both relative path import and absolute path import - -For example, for the following directory structure: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ │── service1.k - │ └── service2.k - └── mixin - └── mixin1.k -``` - -For `main.k`, relative path import and absolute path import can be expressed as: - -```python -import service # Absolute path import, the root directory is the path where kcl.mod is located -import mixin # Absolute path import, the root directory is the path where kcl.mod is located - -import .model1 # Relative path import, current directory module -import ..service # Relative path import, parent directory -import ...root # Relative path import, parent directory of parent directory -``` - -> Note that for KCL's entry file `main.k`, it cannot import the folder where it is located, otherwise a circular import error will occur: - -```python -import model # Error: recursively loading -``` - -## 26. When can import be omitted? - -KCL files in the same folder the not in the main package can refer to each other without importing each other. For example, for the following directory structure: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ │── service1.k - │ └── service2.k - └── mixin - └── mixin1.k -``` - -When main.k is used as the KCL command line entry file, the variables in main.k, model1.k and model2.k in the model folder cannot refer to each other and need to be imported through import, but service1.k in the service folder and Variables in service2.k can refer to each other, ignoring import - -service1.k - -```python -schema BaseService: - name: str - namespace: str -``` - -service2.k - -```python -schema Service(BaseService): - id: str -``` - -## 27. There is a line of code that is too long, how to wrap it gracefully with correct syntax? - -In KCL, we can use the continuation character `\` for newlines, and we can also use `\` in strings to indicate continuation. - -An example of a long string concatenation continuation line: - -```python -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " -``` - -An example of a continuation in the comprehension expression: - -```python -data = [1, 2, 3, 4] -dataNew = [ - d + 2 \ - for d in data \ - if d % 2 == 0 -] -``` - -An example of a continuation in the if expression: - -```python -condition = 1 -data1 = 1 \ - if condition \ - else 2 -data2 = 2 \ -if condition \ -else 1 -``` - -An example of a continuation in the long string: - -```python -longString = """\ -The first line\ -The continue second line\ -""" -``` - -Note: Use the line continuation character `\` while maintaining indentation, as follows: - -- Error use case: - -```python -data1 = [ - 1, 2, - 3, 4 \ -] # Error, need to keep the indentation of the closing bracket ] - -data2 = [ - 1, 2, - 3, 4 -] # Error, requires uniform indentation of numbers 1 and 3 -``` - -- Right use case: - -```python -data1 = [ - 1, 2, - 3, 4 -] # OK - -data2 = [ \ - 1, 2, \ - 3, 4 \ -] # OK - -data3 = [ \ - 1, 2, \ - 3, 4 \ -] # OK -``` - -## 28. What do these symbols `**` and `*` mean? - -- `**`, `*` appear outside dict/list to represent power operator and multiplication operator respectively. - -```python -data1 = 2 ** 4 # 16 -data2 = 2 * 3 # 6 -``` - -- `**`, `*` appear inside dict/list to indicate unpacking operator, often used for unpacking and merging of list/dict, similar to unpacking operator in Python - -Unpacking of dict: - -```python -data = {"key1" = "value1"} -dataUnpack = {**data, "key2" = "value2"} # {"key1": "value1", "key2": "value2"} -``` - -Unpacking of list: - -```python -data = [1, 2, 3] -dataUnpack = [*data, 4, 5, 6] # [1, 2, 3, 4, 5, 6] -``` - -## 29. How to get child elements of list/dict/schema - -- For list type, we can use `[]` to get an element in the list - -```python -data = [1, 2, 3] # Define an list of integer types -theFirstItem = data[0] # Get the element with index 0 in the list, that is, the first element 1 -theSecondItem = data[1] # Get the element with index 1 in the list, which is the first element 2 -``` - -> Note: The value of the index cannot exceed the length of the list, otherwise an error will occur, we can use the `len` function to get the length of the list. - -```python -data = [1, 2, 3] -dataLength = len(data) # List length is 3 -item = data[3] # Error: Index out of bounds -``` - -In addition, we can also use the negative index to get the elements in the list in reverse order. - -```python -data = [1, 2, 3] -item1 = data[-1] # Get the element with index -1 in the list, which is the last element 3 -item2 = data[-2] # Get the element with index -2 in the list, which is the second-to-last element 2 -``` - -In summary, the value range of the list index is `[-len, len - 1]` - -When we want to get a part of the sub-elements of the list, we can use the slice expression in `[]`, the specific syntax is `[::]`, Note that the value range of the start and end of the index is `left closed right open [, )`, note that the three parameters can be omitted or not written. - -```python -data = [1, 2, 3, 4, 5] -dataSlice0 = data[1:2] # Get the set of elements in the list whose index starts at 1 and ends at 2 [2] -dataSlice1 = data[1:3] # Get the set of elements in the list whose index starts at 1 and ends at 3 [2, 3] -dataSlice2 = data[1:] # Get the set of elements in the list whose index starts at 1 and ends at the last index [2, 3, 4, 5] -dataSlice3 = data[:3] # Get the set of elements in the list whose index starts at the first index and ends at 3 [1, 2, 3] -dataSlice4 = data[::2] # Get the set of elements in the list whose index starts at the first index and ends at the last index (step size is 2) [1, 3, 5] -dataSlice5 = data[::-1] # Reverse the list, [5, 4, 3, 2, 1] -dataSlice6 = data[2:1] # When the start, stop, step combination of three parameters does not meet the conditions, return an empty list []. -``` - -- For dict/schema types, we can use `[]` and `.` to get child elements in dict/schema. - -```python -data = {key1: "value1", key2: "value2"} -data1 = data["key1"] # "value1" -data2 = data.key1 # "value1" -data3 = data["key2"] # "value2" -data4 = data.key2 # "value2" -``` - -```python -schema Person: - name: str = "Alice" - age: int = 18 - -person = Person {} -name1 = person.name # "Alice" -name2 = person["name"] # "Alice" -age1 = person.age # 18 -age2 = person.age # 18 -``` - -When the key value does not exist in the dict, return the value `Undefined`. - -```python -data = {key1 = "value1", key2 = "value2"} -data1 = data["not_exist_key"] # Undefined -data2 = data.not_exist_key # Undefined -``` - -We can use the `in` keyword to determine whether a key value exists in dict/schema - -```python -data = {key1 = "value1", key2 = "value2"} -exist1 = "key1" in data # True -exist2 = "not_exist_key" in data # False -``` - -When there is `.` in the key value or when we need to get the value corresponding to a key value variable at runtime, we can only use the `[]` method. If there is no special case, use `.`: - -```python -name = "key1" -data = {key1 = "value1", key2 = "value2", "contains.dot" = "value3"} -data1 = data[name] # "value1" -data2 = data["contains.dot"] # "value3" -# Note that this is wrong: data3 = data.contains.dot -``` - -> Note: The above sub-element operators cannot operate on values of non-list/dict/schema collection types, such as integers, nulls, etc. - -```python -data = 1 -data1 = 1[0] # Error -``` - -```python -data = None -data1 = None[0] # Error -``` - -When getting the child elements of the collection type, it is often necessary to make a non-null or length judgment: - -```python -data = [] -item = data[0] if data else None -``` - -We can use the `?` operator to make an if non-null judgment, and return None when the condition is not satisfied. For example, the above code can be simplified to: - -```python -data = [] -item1 = data?[0] # When data is empty, return the empty value None -item2 = data?[0] or 1 # When data is empty, return the empty value None, if we don't want to return None, we can also use the or operator to return other default values e.g., "1" in `data?[0] or 1` -``` - -Use more `?` operators to avoid complicated and cumbersome non-null judgments - -```python -data = {key1.key2.key3 = []} -item = data?.key1?.key2?.key3?[0] -``` - -## 30. How to get the type of a variable in KCL code - -The KCL `typeof` built-in function can return the type (string representation) of a variable immediately for type assertion. - -Examples: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person{} -t3 = typeof(_x1) - -_x2 = pkg.Person{} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# Output -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -## 31. How to solve the conflict between keywords and KCL variable names? - -For identifier names that conflict with keywords, we can add a `$` prefix before the identifier to define a keyword identifier. For example, in the following code, keywords such as `if`, `else` can be used as identifiers with the `$` prefix and we can get the corresponding YAML output - -```python -$if = 1 -$else = "s" - -schema Data: - $filter: str = "filter" - -data = Data {} -``` - -The output YAML is - -```yaml -data: - filter: filter -if: 1 -else: s -``` - -> Note: Prefixing non-keyword identifiers with `$` has the same effect as not adding. - -```python -_a = 1 -$_a = 2 # Equivalent to `_a = 2` -``` - -## 32. Are built-in types of KCL a keyword of KCL? Whether they can be used for the definition of variables - -The built-in types of KCL include `int`, `float`, `bool` and `str`, which are not KCL keywords and can be used to define variables, such as the following code: - -```py -int = 1 -str = 2 -``` - -The output YAML is - -```yaml -int: 1 -str: 2 -``` - -> Note: If there are no special requirements, it is not recommended that the names of variables take these built-in types, because in some languages, they exist as keywords. - -## 33. How to implement enumeration in KCL? - -There are two ways to implement enumeration in KCL - -- Use **literal union types** (recommended) - -```python -schema Person: - name: str - gender: "Male" | "Female" - -person = Person { - name = "Alice" - gender = "Male" # gender can only be "Male" or "Female" -} -``` - -```python -schema Config: - colors: ["Red" | "Yellow" | "Blue"] # colors is an enumerated array - -config = Config { - colors = [ - "Red" - "Blue" - ] -} -``` - -- Use schema check expressions - -```python -schema Person: - name: str - gender: "Male" | "Female" - - check: - gender in ["Male", "Female"] - -person = Person { - name = "Alice" - gender = "Male" # gender can only be "Male" or "Female" -} -``` - -## 34. How to get the length of dict - -In KCL, we can use the `len` built-in function to directly find the length of a dict - -```python -len1 = len({k1: "v1"}) # 1 -len2 = len({k1: "v1", k2: "v2"}) # 2 -varDict = {k1 = 1, k2 = 2, k3 = 3} -len3 = len(varDict) # 3 -``` - -In addition, the `len` function can also be used to get the length of `str` and `list` types - -```python -len1 = len("hello") # 5 -len2 = len([1, 2, 3]) # 3 -``` - -## 35. How to write conditional configuration in KCL - -In KCL, in addition to writing `if-elif-else` conditional expressions in top-level statements, it also supports writing conditional expressions in KCL complex structures (list/dict/schema), and supports conditional configuration writing. - -```python -x = 1 -# Conditional configuration in list -dataList = [ - if x == 1: 1 -] -# Conditional configuration in dict -dataDict = { - if x == 1: key1 = "value1" # Inline form - elif x == 2: - key2 = "value2" # Multi-line form -} - -schema Config: - id?: int - -env = "prod" -# Conditional configuration in schema -dataSchema = Config { - if env == "prod": - id = 1 - elif env == "pre": - id = 2 - elif env == "test": - id = 3 -} -``` - -## 36. Does the == operator in KCL do deep comparisons? - -`==` operator in KCL - -- For primitive types `int`, `float`, `bool`, `str` variables are directly compared to see if their values are equal -- Variables of composite types `list`, `dict`, `schema` will deeply recursively compare their sub-elements for equality - - `list` type deep recursive recursive comparison of the value and length of each index - - `dict`/`schema` types deeply recursively compare the value of each attribute (regardless of the order in which the attributes appear) - -```python -print([1, 2] == [1, 2]) # True -print([[0, 1], 1] == [[0, 1], 1]) # True -print({k1 = 1, k2 = 2} == {k2 = 2, k1 = 1}) # True - -print([1, 2] == [1, 2, 3]) # False -print({k1 = 1, k2 = 2, k3 = 3} == {k2 = 2, k1 = 1}) # False -``` - -## 37. How to modify existing configuration blocks in KCL - -In KCL, there are three **attribute operators** `=`, `+=`, `:`, which can be used to modify existing configuration blocks, and can use **unpacking operator** ` **` etc. "inherit" all attribute fields and values ​​of a configuration block. - -- The `=` attribute operator means overriding, use `=` operator to override/delete the attribute with priority, (if it is overwritten with `Undefined`, it means deletion) -- The `+=` attribute operator means adding, which is generally used to add sub-elements to the attributes of the list type. The operand type following the `+=` attribute operator can only be of the list type. -- The `:` attribute operator means idempotent merge. When the value conflicts, an error is reported, and when there is no conflict, the merge is performed - -### Override attribute operator = - -The most commonly used attribute operator is `=`, which indicates the assignment of an attribute. When the same attribute is used multiple times, it means overwriting. For global variables outside `{}` or attributes within `{}`, it means using value overrides this global variable or attribute - -```python -data = { # define a dictionary type variable data - a = 1 # use = to declare a attribute a in data with a value of 1 - b = 2 # use = to declare a attribute b in data with a value of 1 -} # The final data value is {"a": 1, "b": 1} -``` - -we can also use the override attribute operator at the schema instantiation to achieve the effect of overriding the default value of the schema. Generally, when creating a new schema instance, if there is no special requirement, we can generally use `=` - -```python -schema Person: - name: str = "Alice" # schema Person's name attribute has default value "Alice" - age: int = 18 # schema Person's age attribute has a default value of 18 - -bob = Person { - name = "Bob" # "Bob" -> "Alice", the value of the attribute name "Bob" will override the default value "Alice" of the schema Person name attribute - age = 10 # 10 -> 18, the value of the attribute age of 10 will override the default value of the schema Person age attribute of 18 -} # The final value of bob is {"name": "Bob", age: 10} -``` - -### Insert attribute operator += - -The insert attribute operator means to add the value of an attribute in place, such as adding a new element to a list type attribute - -```python -data = { - args = ["kcl"] # use = to declare an attribute in data with value ["kcl"] args - args += ["-Y", "settings.yaml"] # Add two elements "-Y", "settings.yaml" to attribute args using += operator -} # The final data value is {"args": ["kcl", "-Y", "settings.yaml"]} -``` - -### Merge attribute operators : - -The merge attribute operator means idempotent merging of different configuration block values ​​of an attribute. When the values ​​to be merged conflict, an error is reported. It is mostly used in complex configuration merging scenarios. - -```python -data = { - labels: {key1: "value1"} # define a labels, its type is dict, the value is {"key1": "value1"} - labels: {key2: "value2"} # Use : to combine different configuration values ​​of labels -} # The final data value is {"labels": {"key1": "value1", "key2": "value2"}} -``` - -The merge attribute operator is an idempotent operator, and the writing order of the configuration blocks to be merged does not affect the final result. For example, the two `labels` attributes in the above example can also be written in reverse order. - -```python -data = { # The merged writing order of the same attribute labels does not affect the final result - labels: {key2: "value2"} # define a label whose type is dict and the value is {"key2": "value2"} - labels: {key1: "value1"} # Use : to combine different configuration values ​​of labels -} # The final data value is {"labels": {"key1": "value1", "key2": "value2"}} -``` - -Note: The merge attribute operator will check the merged values ​​for conflicts, and report an error when the configuration values ​​that need to be merged conflict. - -```python -data = { - a: 1 # the value of a is 1 - a: 2 # Error: The value 2 of a cannot be merged with the value 1 of a because the results conflict and the merge is not commutative -} -``` - -```python -data = { - labels: {key: "value"} - labels: {key: "override_value"} # Error: The values ​​"value" and "override_value" of the key attributes of two labels are conflicting and cannot be merged -} -``` - -The coalescing operator is used differently for different types - -- Attributes of different types cannot be merged -- When the attribute is a basic type such as int/float/str/bool, the operator will judge whether the values ​​to be merged are equal, and a merge conflict error will occur if they are not equal - -```python -data = { - a: 1 - a: 1 # Ok - a: 2 # Error -} -``` - -- when the attribute is of type list - - Merge conflict error occurs when two lists that need to be merged are not of equal length - - When the lengths of the two lists to be merged are equal, recursively merge each element in the list according to the index - -```python -data = { - args: ["kcl"] - args: ["-Y", "settings.yaml"] # Error: The lengths of the two args attributes are not the same and cannot be merged - env: [{key1: "value1"}] - env: [{key2: "value2"}] # Ok: The value of the final env attribute is [{"key1": "value1"}, {"key2": "value2"}] -} -``` - -- When the attribute is of type dict/schema, recursively merge each element in dict/schema according to key - -```python -data = { - labels: {key1: "value1"} - labels: {key2: "value2"} - labels: {key3: "value3"} -} # The final data value is {"labels": {"key1": "value1", "key2": "value2", "key3": "value3"}} -``` - -- the result of combining an attribute of any type with None/Undefined is itself - -```python -data = { - args: ["kcl"] - args: None # Ok - args: Undefined #Ok -} # The final data value is {"args": ["kcl"]} -``` - -Support declaration and merging of top-level variables using the `:` attribute (we can still declare a configuration block using `config = Config {}`) - -```python -schema Config: - id: int - value: str - -config: Config { - id: 1 -} -config: Config { - value: "1" -} -""" -Two Config configuration blocks are defined here, and the : operator can be used to merge the two configuration blocks together. The equivalent code for the merge is as follows: -config: Config { - id: 1 - value: "1" -} -""" -``` - -To sum up, the usage scenario of the merge attribute operator `:` is mainly the merge operation of the complex data structure list/dict/schema. In general, if there is no special requirement, the two attribute operators `=` and `+=` are used. Yes, so the best practice for attribute operators is as follows - -- For primitive types, use the `=` operator -- For the list type, the `=` and `+=` operators are generally used. Use `=` to completely override the list attribute, and use `+=` to add elements to the list -- For dict/schema types, the `:` operator is generally used - -In addition, when a configuration already exists, we can use the unpacking operator `**` to get all field values ​​of this configuration and modify the fields with different attribute operators, and get a new configuration - -```python -configBase = { - intKey = 1 # A attribute of type int - floatKey = 1.0 # A attribute of type float - listKey = [0] # A attribute of type list - dictKey = {key1: "value1"} # an attribute of type dict -} -configNew = { - **configBase # Unpack and inline configBase into configNew - intKey = 0 # Use override attribute operator = to override intKey attribute to 1 - floatKey = Undefined # Use override attribute operator = remove floatKey attribute - listKey += [1] # Add an attribute 1 to the end of the listKey attribute using the add attribute operator += - dictKey: {key2: "value2"} # Use the merge attribute operator: extend a key-value pair for the dictKey attribute -} -``` - -The output YAML result is: - -```yaml -configBase: - intKey: 1 - floatKey: 1.0 - listKey: - - 0 - dictKey: - key1: value1 -configNew: - intKey: 0 - listKey: - - 0 - - 1 - dictKey: - key1: value1 - key2: value2 -``` - -Alternatively two configuration blocks can be combined using the `|` operator: - -```python -configBase = { - intKey = 1 # A attribute of type int - floatKey = 1.0 # A attribute of type float - listKey = [0] # A attribute of type list - dictKey = {key1: "value1"} # an attribute of type dict -} -configNew = configBase | { # Use | to merge - intKey = 0 # Use override attribute operator = to override intKey attribute to 1 - floatKey = Undefined # Use override attribute operator = remove floatKey attribute - listKey += [1] # Add an attribute 1 to the end of the listKey attribute using the add attribute operator += - dictKey: {key2: "value2"} # Use the merge attribute operator: extend a key-value pair for the dictKey attribute -} -``` - -The output YAML is - -```yaml -configBase: - intKey: 1 - floatKey: 1.0 - listKey: - - 0 - dictKey: - key1: value1 -configNew: - intKey: 0 - listKey: - - 0 - - 1 - dictKey: - key1: value1 - key2: value2 -``` - -### The solution to the conflicting values on the attribute 'attr' between {value1} and {value2} error in KCL - -When an error like conflicting values on the attribute 'attr' between {value1} and {value2} occurs in KCL, it is usually a problem with the use of the merge attribute operator `:`, indicating that when the `value1` and `value2` configurations are merged, the attribute A conflict error occurred at `attr`. In general, modify the attr attribute of value2 to other attribute operators, use `=` to indicate overwrite, and use `+=` to indicate addition - -For example for the following code: - -```python -data = {k: 1} | {k: 2} # Error: conflicting values on the attribute 'k' between {'k': 1} and {'k': 2} -``` - -We can use the `=` attribute operator to modify it to the following form - -```python -data = {k: 1} | {k = 2} # Ok: the value 2 will override the value 1 through the `=` operator -``` - -## 38. How to traverse multiple elements at the same time in the for comprehension? - -In KCL, we can use for comprehension to traverse multiple elements - -- Example 1: two dimension element loop - -```python -dimension1 = [1, 2, 3] # The length of the dimension1 list is 3 -dimension2 = [1, 2, 3] # The length of the dimension2 list is 3 -matrix = [x + y for x in dimension1 for y in dimension2] # The length of the matrix list is 9 = 3 * 3 -``` - -The output YAML is: - -```yaml -dimension1: - - 1 - - 2 - - 3 -dimension2: - - 1 - - 2 - - 3 -matrix: - - 2 - - 3 - - 4 - - 3 - - 4 - - 5 - - 4 - - 5 - - 6 -``` - -- Example 2: Use for loop and `zip` built-in function to traverse multiple lists one by one by index - -```python -dimension1 = [1, 2, 3] # The length of the dimension1 list is 3 -dimension2 = [1, 2, 3] # The length of the dimension2 list is 3 -dimension3 = [d[0] + d[1] for d in zip(dimension1, dimension2)] # The length of the dimension1 list is 3 -``` - -The output YAML is: - -```yaml -dimension1: - - 1 - - 2 - - 3 -dimension2: - - 1 - - 2 - - 3 -dimension3: - - 2 - - 4 - - 6 -``` - -## 39. How to set default value for option function in KCL - -In KCL, when the value of the option attribute is None/Undefined or empty, we can use the logical `or` to directly specify a default value. - -```python -value = option("key") or "default_value" # When the value of key exists, take the value of option("key"), otherwise take "default_value" -``` - -Or use the default parameter of the option function. - -```python -value = option("key", default="default_value") # When the value of key exists, take the value of option("key"), otherwise take "default_value" -``` - -## 40. How to check that multiple attributes cannot be empty or set values at the same time in schema in KCL? - -In KCL, a single attribute of schema cannot be empty by default, unless we use the attribute optional operator `?`. - -```python -schema Person: - name: str # Required. - age: int # Required. - id?: int # Optional. -``` - -When it is necessary to check that the schema attributes cannot be empty at the same time or only one of them is empty, it needs to be written with the help of schema check expressions. The following takes two attributes `a`, `b` of the schema `Config` as an example to illustrate. - -- `a` and `b` attributes cannot be empty at the same time. - -```python -schema Config: - a?: str - b?: str - - check: - a or b -``` - -- `a` and `b` attributes can only have one or both empty (cannot exist at the same time or not empty) - -```python -schema Config: - a?: str - b?: str - - check: - not a or not b -``` - -## 41. A file is imported in KCL, but the schema defined by other KCL files in the same directory cannot be found. What might be the reason? - -It may be caused to import only this file in this folder. In KCL, import statement supports importing the entire folder, and also supports importing a certain KCL file under a certain folder. For the following directory structure. - -``` -. -├── kcl.mod -├── main.k -└── pkg - ├── pkg1.k - ├── pkg2.k - └── pkg3.k -``` - -There is an entry file main.k in the root directory. You can write the following code in main.k to import the entire pkg folder. At this time, all schema definitions in the pkg folder are visible to each other. - -```python -import pkg -``` - -We can also write the following code to import a single file pkg/pkg1.k. At this time, pkg1.k cannot find other files, namely the schema definitions under pkg2.k/pkg3.k - -```python -import pkg.pkg1 -``` - -## 42. How is indentation handled in KCL? - -In KCL, when a colon `:`, square bracket pair `[]` and curly bracket pair `{}` appear, we generally need to use newline + indentation, and the number of indented spaces for the same indentation level needs to be consistent. The indentation level is generally represented by 4 spaces. - -- colon `:` followed by newline and indent - -```python -"""Indentation in if statements""" -_a = 1 -_b = 1 -if _a >= 1: # colon `:` followed by newline and indent - if _a > 8: - _b = 2 - elif a > 6: - _b = 3 - -"""Indentation in schema statements""" -schema Person: # colon `:` followed by newline and indent - name: str - age: int -``` - -- opening bracket `[` followed by newline and indent - -```python -data = [ # opening bracket `[` followed by newline and indent - 1 - 2 - 3 -] # unindent before closing bracket ] -``` - -```python -data = [ # opening bracket `[` followed by newline and indent - i * 2 for i in range(5) -] # unindent before closing bracket `]` -``` - -- opening bracket `{` followed by newline and indent - -```python -data = { # opening bracket `{` followed by newline and indent - k1 = "v1" - k2 = "v2" -} # unindent before closing brace `}` -``` - -```python -data = { # opening bracket `{` followed by newline and indent - str(i): i * 2 for i in range(5) -} # unindent before closing brace `}` -``` - -## 43. How to write simple tests for KCL code? - -The current version of KCL does not support internal program debugging, we can use the assert statement and the print function to achieve data assertion and viewing. - -```python -a = 1 -print("The value of a is", a) -assert a == 1 -``` - -In addition, we can also use the kcl-test test tool to write KCL internal test cases - -Assuming there is a hello.k file, the code is as follows: - -```python -schema Person: - name: str = "kcl" - age: int = 1 - -hello = Person { - name = "hello kcl" - age = 102 -} -``` - -Construct the hello_test.k test file with the following contents: - -```python -schema TestPerson: - a = Person{} - assert a.name == 'kcl' - -schema TestPerson_age: - a = Person{} - assert a.age == 1 - -schema TestPerson_ok: - a = Person{} - assert a.name == "kcl" - assert a.age == 1 -``` - -Then execute the kcl-test command in the directory: - -``` -$ kcl-test -ok /pkg/to/app [365.154142ms] -$ -``` - -## 44. How to define and use functions in KCL? - -The schema structure acts as a function to a certain extent, and this function has the ability to have multiple input parameters and multiple output parameters. For example, the following code can implement the function of a Fibonacci sequence: - -```python -schema Fib: - n: int - value: int = 1 if n <= 2 else (Fib {n: n - 1}).value + (Fib {n: n - 2}).value - -fib8 = (Fib {n: 8}).value -``` - -The output is - -```yaml -fib8: 21 -``` - -A schema function that merges lists into dictionaries - -```python -schema UnionAll[data, n]: - _?: [] = data - value?: {:} = ((UnionAll(data=data, n=n - 1) {}).value | data[n] if n > 0 else data[0]) if data else {} - -schema MergeList[data]: - """Union all elements in a list returns the merged dictionary - - [{"key1": "value1"}, {"key2": "value2"}, {"key3": "value3"}] -> {"key1": "value1", "key2": "value2", "key3": "value3"} - """ - _?: [] = data - value?: {:} = (UnionAll(data=data, n=len(data) - 1) {}).value if data else {} -``` - -In addition, KCL supports defining a function using the `lambda` keyword: - -```python -func = lambda x: int, y: int -> int { - x + y -} -a = func(1, 1) # 2 -``` - -A lambda function has the following properties: - -- A lambda function takes the value of the last expression as the return value of the function, and an empty function body returns None. -- The return value type annotation can be omitted, the return value type is the type of the last expression value. -- There are no order-independent features in the function body, all expressions are executed in order. - -```python -_func = lambda x: int, y: int -> int { - x + y -} # Define a function using the lambda expression -_func = lambda x: int, y: int -> int { - x - y -} # Ok -_func = lambda x: int, y: int -> str { - str(x + y) -} # Error (int, int) -> str can't be assigned to (int, int) -> int -``` - -A lambda function cannot participate in any computation and can only be used in assignment and call statements. - -```python -func = lambda x: int, y: int -> int { - x + y -} -x = func + 1 # Error: unsupported operand type(s) for +: 'function' and 'int(1)' -``` - -```python -a = 1 -func = lambda x: int { - x + a -} -funcOther = lambda f, para: int { - f(para) -} -r = funcOther(func, 1) # 2 -``` - -The output is - -```python -a: 1 -r: 2 -``` - -We can define an anonymous function and call it directly - -```python -result = (lambda x, y { - z = 2 * x - z + y -})(1, 1) # 3 -``` - -Anonymous functions can be also used in for loops - -```python -result = [(lambda x, y { - x + y -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 3, 3, 4] -``` - -Functions can be defined and used in the KCL schema - -```python -_funcOutOfSchema = lambda x: int, y: int { - x + y -} -schema Data: - _funcInSchema = lambda x: int, y: int { - x + y - } - id0: int = _funcOutOfSchema(1, 1) - id1: int = _funcInSchema(1, 1) - id2: int = (lambda x: int, y: int { - x + y - })(1, 1) -``` - -The output YAML is - -```yaml -data: - id0: 2 - id1: 2 - id2: 2 -``` - -## 45. Why do we get an error when a variable is assigned an enumeration type (a literal union type)? - -In KCL, a attribute defined as a literal union type is only allowed to receive a literal value or a variable of the same literal union type during assignment. For example, the following code is correct: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -data = Data { - color = "Red" # Ok, can be assigned as "Red", "Yellow" and "Blue" -} -``` - -However the following code is wrong: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -_color = "Red" - -data = Data { - color = _color # Error: expect str(Red)|str(Yellow)|str(Blue), got str -} -``` - -This is because there is no type declared for the variable `_color`, it will be deduced by the KCL compiler as a `str` string type, so when a "larger" type `str` is assigned to a "smaller" type `"Red" | "Yellow" | "Blue"` will report an error, one solution is to declare a type for the `_color` variable, the following code is correct: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -_color: "Red" | "Yellow" | "Blue" = "Red" - -data = Data { - color = _color # Ok -} -``` - -Further, we can use type aliases to simplify enumeration (writing of literal union types), such as the following code: - -```python -type Color = "Red" | "Yellow" | "Blue" # Define a type alias, which can be reused in different places, reducing the amount of code writing - -schema Data: - color: Color - -_color: Color = "Red" - -data = Data { - color = _color # Ok -} -``` - -## 46. Procedural for loop - -KCL provides comprehensions and all/any/map/filter expressions for processing a collection element, which meets most needs, and provides a procedural for loop body. Providing a procedural for loop body is not very demanding from the current scenario, so there is no procedural for loop support yet. - -In addition, although KCL does not support procedural for loops, it is possible to "construct" corresponding procedural for loops through for loops and lambda functions. - -```python -result = [(lambda x: int, y: int -> int { - # Write procedural for loop logic in the lambda function. - z = x + y - x * 2 -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 2, 4, 4] -``` - -## 47. Default variables are immutable - -The immutability of KCL variables means that the exported variables starting with non-underscore `_` in the KCL top-level structure cannot be changed after initialization. - -```python -schema Person: - name: str - age: int - -a = 1 # a will be output to YAML, once assigned it cannot be modified -_b = 1 # _b The variable is named with an underscore and will not be output to YAML. It can be modified by multiple assignments -_b = 2 -alice = Person { - name = "Alice" - age = 18 -} -``` - -There are two ways of specifying that variables are immutable: - -- non-underscore top-level variables outside the schema - -```python -a = 1 # immutable exported variable -_b = 2 # mutable non-export variable -``` - -## 48. Is there a type like Go `interface{}`/`any` or Java `Object` in KCL? - -In KCL, we can use the `any` type annotation to define a variable to store any values such as integers, strings and schemas. For example: - -```python -schema Data: - id: int = 1 - -var_list: [any] = [1, "12", Data {}] -``` - -The output YAML is - -```yaml -var_list: - - 1 - - "12" - - id: 1 -``` - -In addition, we can also use the `typeof` function to determine the type of variables during KCL code execution: - -```python -schema Data1: - id: int = 1 - -schema Data2: - name: str = "name" - -data_list: [any] = [Data1 {}, Data2 {}] -data_type_list: [str] = [typeof(data) for data in data_list] -``` - -The output YAML is - -```yaml -data_list: - - id: 1 - - name: name -data_type_list: - - Data1 - - Data2 -``` - -## 49. How to develop a KCL plugin? - -KCL plugins are installed in the plugins subdirectory of KCL (usually installed in the `$HOME/.kcl/plugins` directory), or set through the `$KCL_PLUGINS_ROOT` environment variable. Besides, the `plugins` directory could also be placed at the `pwd` path. For plugin developers, plugins are managed in the [Git repository](https://github.com/kcl-lang/kcl-plugin), and the plugin repository can be cloned to this directory for development. - -KCL has built-in kcl-plugin scaffolding command to assist users to write KCL plug-ins in Python language, so that the corresponding plug-ins can be called in the KCL file to enhance the KCL language itself, such as accessing the network, reading and writing IO, CMDB query and encryption and decryption functions. - -``` -usage: kcl-plugin [-h] {list,init,info,gendoc,test} ... - -positional arguments: - {list,init,info,gendoc,test} - kcl plugin sub commands - list list all plugins - init init a new plugin - info show plugin document - gendoc gen all plugins document - test test plugin - -optional arguments: - -h, --help show this help message and exit -``` - -For example, if you want to develop a plugin named io, you can use the following command to successfully create a new io plugin - -``` -kcl-plugin init io -``` - -Then you can use the following command to get the root path of the plugin and cd to the corresponding io plugin directory for development - -``` -kcl-plugin info -``` - -For example, if you want to develop a function read_file to read a file, you can write python code in `plugin.py` of `$plugin_root/io`: - -```python -# Copyright 2020 The KCL Authors. All rights reserved. - -import pathlib - -INFO = { - 'name': 'io', - 'describe': 'my io plugin description test', - 'long_describe': 'my io plugin long description test', - 'version': '0.0.1', -} - - -def read_file(file: str) -> str: - """Read string from file""" - return pathlib.Path(file).read_text() - -``` - -In addition, you can write the corresponding test function in `plugin_test.py`, or you can directly write the following KCL file for testing: - -```python -import kcl_plugin.io - -text = io.read_file('test.txt') -``` - -You can also use the info command to view information about the io plugin - -``` -kcl-plugin info io -``` - -``` -{ - "name": "io", - "describe": "my io plugin description test", - "long_describe": "my io plugin long description test", - "version": "0.0.1", - "method": { - "read_file": "Read string from file" - } -} -``` - -Finally, the plugin that has written the test can be merged with MR in the `kcl_plugins` repository. - -## 50. How to do basic type conversion in KCL - -You can use the `int()`, `float()` function and `str()` function to convert the basic types between `int`, `float` and `str`. - -``` -_t = 1 - -t_str: str = str(_t) # you will get "t_str: '1'" -t_int: int = int(t_str) # you will get "t_int: 1" -t_float: float = float(t_str) # you will get "t_float: 1.0" -``` - -For more information about type conversion, see [KCL Builtin Types](https://kcl-lang.io/docs/reference/lang/tour#built-in-types) and [KCL Type System](https://kcl-lang.io/docs/reference/lang/tour#type-system). diff --git a/versioned_docs/version-0.5.4/user_docs/support/faq-yaml.md b/versioned_docs/version-0.5.4/user_docs/support/faq-yaml.md deleted file mode 100644 index b13a0f7a..00000000 --- a/versioned_docs/version-0.5.4/user_docs/support/faq-yaml.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -sidebar_position: 3 ---- - -# YAML - -## 1. What is the difference between single and double quote YAML strings? - -- YAML double-quoted strings are the only style that can express arbitrary strings, by using `\` escape characters, such as `\"` to escape double quotes `"`, `\\` to escape backslashes `\`, and a single backslash `\` can be used as a continuation character for double-quoted strings. -- YAML single-quoted strings differ from YAML double-quoted strings in that `\` and `"` can be used freely without escaping, but two single-quotes `''` are used to escape single-quote `'` characters. - -For the following example, the contents of the three string variables are the same. - -```yaml -string1: 'here '' s to "quotes"' -string2: 'here''s to "quotes"' -string3: here's to "quotes" -``` - -> Note: KCL's strategy for outputting YAML strings is to output unquoted strings or double-quoted strings preferentially when single quotes appear in the string content, and output single-quoted strings in other cases to avoid the burden of understanding. - -For more details, please refer to [YAML Spec v1.2](https://yaml.org/spec/1.2.1/) - -## 2. What is the meaning of symbols such as | - + > in YAML? - -When using KCL multi-line strings (triple quote strings), the output YAML often carries some special tokens, such as `|`, `-`, `+` and `>`, etc. These tokens usually are the representation method of YAML multi-line string, such as the following KCL code: - -```python -data = """This is a KCL multi line string (the first line) -This is a KCL multi line string (the second line) -This is a KCL multi line string (the third line) - - -""" -var = 1 -``` - -The output YAML is - -```yaml -data: |+ - This is a KCL multi line string (the first line) - This is a KCL multi line string (the second line) - This is a KCL multi line string (the third line) - - -var: 1 -``` - -- `|` represents **block style**, which is used to represent a multi-line string, where all newlines in the string represent the real newlines. -- `>` represents **folding style**, in which all newlines in the string will be replaced by spaces. -- `+` and `-` are used to control the use of newlines at the end of strings. The default is to keep a single newline at the end of the string. If we want to remove all newlines, we can put a `-` after the style indicator `|` or `>`. If we want to keep the newline at the end, we need to put a `+` after `|` or `>`. - -For more details, please refer to [YAML Multiline String](https://yaml-multiline.info/) and [YAML Spec v1.2](https://yaml.org/spec/1.2.1/) - -## 3. What is the meaning of numbers that appear after symbols | - + > such as |1 and |2 in YAML? - -Numbers represent **explicit indentation indicators** in YAML. For long strings in YAML, YAML usually the first non-blank line determines the indentation level of the string, and when the first non-blank line is preceded by a non-leading character, such as a newline, we must use **explicit indent indicators** to specify the indent level of the content, such as `|1` and `|2` etc. - -For example, for the following KCL code: - -```python -longStringStartWithNewline = """ -This is the second line -This is the third line -""" - -``` - -```yaml -longStringStartWithNewline: |2 - - This is the second line - This is the third line -``` - -- Writing long strings from the first line. - -```python -longString = """This is the second line -This is the third line -""" -``` - -- Writing long strings with line continuation characters. - -```python -longString = """\ -This is the second line -This is the third line -""" -``` - -The YAML output by the above two methods is: - -```yaml -longString: | - This is the second line - This is the third line -``` - -For more details, please refer to [YAML Spec v1.2](https://yaml.org/spec/1.2.1/) diff --git a/versioned_docs/version-0.5.4/user_docs/support/support.md b/versioned_docs/version-0.5.4/user_docs/support/support.md deleted file mode 100644 index fac13ef2..00000000 --- a/versioned_docs/version-0.5.4/user_docs/support/support.md +++ /dev/null @@ -1,3 +0,0 @@ -# FAQ - -KCL frequently asked questions. diff --git a/versioned_docs/version-0.5.5/community/contribute/_category_.json b/versioned_docs/version-0.5.5/community/contribute/_category_.json deleted file mode 100644 index e2dca064..00000000 --- a/versioned_docs/version-0.5.5/community/contribute/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Contribution Guide", - "position": 4 -} diff --git a/versioned_docs/version-0.5.5/community/contribute/contribute-code.md b/versioned_docs/version-0.5.5/community/contribute/contribute-code.md deleted file mode 100644 index f4e9169b..00000000 --- a/versioned_docs/version-0.5.5/community/contribute/contribute-code.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -sidebar_position: 2 ---- - -# How to Contribute Code? - -Welcome to participate in the KCL co construction to improve the code, documentation and testing, and also welcome to provide feedback through Issues. If you want to add KCL language features, please submit through the [KEP](https://github.com/kcl-lang/KEP) process. - -## 1. Misspellings in Code and Comments - -If you only need to modify the typos in the code and comments, you can directly modify and submit the PR to the repository. It is important to keep the code style as consistent as possible. - -## 2. How to Contribute KCL - -See [KCL contribute guide](https://github.com/kcl-lang/kcl/blob/main/docs/dev_guide/1.about_this_guide.md) for more information. - -## 3. How to Contribute VS Code KCL Plugin - -See [VS Code KCL plugin contribute guide](https://github.com/kcl-lang/vscode-kcl/blob/main/docs/CONTRIBUTING.md) for more information. diff --git a/versioned_docs/version-0.5.5/community/contribute/contribute-docs.md b/versioned_docs/version-0.5.5/community/contribute/contribute-docs.md deleted file mode 100644 index 2b400a52..00000000 --- a/versioned_docs/version-0.5.5/community/contribute/contribute-docs.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -sidebar_position: 1 ---- - -# How to Contribute Document? - -This document mainly makes partial modifications to existing documents. If you are submitting blog posts, adding new documents or adjusting the document directory structure, please contact team members first. - -KCL documents are divided into user guides, development documents, internal documents, reference manuals and blog articles. Their differences are as follows: - -- User's Guide: The corresponding usage document allows users to quickly use the KCL tool to complete their work at the minimum cost, without involving too much internal principles and implementation -- Reference: KCL language, tools, IDE and other documents with all features, covering the most extensive but trivial content -- Blog: There are no special restrictions. They can be shared for specific scenarios, technical points or overall development prospects - -When contributing different types of documents, it is better to combine the above positioning to make some appropriate tailoring for different content to give readers the best experience. - -## 1. Basic Specifications - -- In addition to the title, the internal subtitles shall be numbered as much as possible for easy reading -- The document automatically output by the tool needs a link to the source code, and the subtitle can be without number -- Try not to paste large pieces of code (within 30 lines). It is better to provide text explanations and corresponding reference links for the code -- There are diagrams and truths, but overly complex architecture diagrams are not recommended -- Internal link: in the form of [`/docs/user_docs/getting-started/intro`](/docs/user_docs/getting-started/intro) absolute path - -**Punctuation and space** - -- Chinese punctuation is preferred in Chinese documents -- One space is required between Chinese and English -- One space needs to be added between Chinese and numbers -- Chinese uses full width punctuation without adding spaces before and after punctuation -- English content uses half width punctuation, with a space after the punctuation -- You need to leave a space before and after the link, but you do not need to add a space near the beginning of the paragraph and Chinese full width punctuation. - -**Picture and resource file names** - -- The file name and directory name can only use numbers, English letters and underscores`_` And minus sign '-' -- Pictures of the current document are placed in the images directory of the current directory -- Vector pictures can be viewed through [drawio offline version](https://github.com/jgraph/drawio-desktop/releases) (and submit source files at the same time), and export png format pictures at 200% resolution - -## 2. Basic mode of using document content - -Each usage document can be regarded as a relatively complete sharing or blog post (the reference manual is no longer such). Using documents to organize content follows the following pattern: - -1. Overview: What problems do you want to solve and what effects do you want to achieve in this article? You can put a screenshot of the final effect first -2. Dependent environment: what tools need to be installed, and provide relevant links -3. Introduce this article to build a relationship diagram or architecture diagram of resources -4. Give the test method. Try to use community common methods (such as kube, curl command, or browser) to test -5. Summary and Outlook. Briefly review the current operation process and some places that can be expanded (some links can be given) - -## 3. Test and submit PR - -First, clone the document warehouse, and then test the viewing effect locally with the 'npm run start' and 'npm run build' commands to ensure that you can browse normally and then submit PR. diff --git a/versioned_docs/version-0.5.5/community/contribute/contribute.md b/versioned_docs/version-0.5.5/community/contribute/contribute.md deleted file mode 100644 index dd6e2b3f..00000000 --- a/versioned_docs/version-0.5.5/community/contribute/contribute.md +++ /dev/null @@ -1,3 +0,0 @@ -# Contribute Guide - -If it is the first time to participate in the open-source community, you can first check the similar changes in Issue and PR (PullRequest). Then you can fully discuss your own problems with the community or development team classmates, and you can also feedback the problems encountered by creating issues, and then you can provide code patches for related issues. At the beginning, you can start with document improvement and partial code improvement, such as: documentation, Examples, multi-language Binding, etc. At the same time, students who want to participate deeply can contribute to core features such as language functions, language testing, programming frameworks, and various backends. diff --git a/versioned_docs/version-0.5.5/community/contribute/git-guideline.md b/versioned_docs/version-0.5.5/community/contribute/git-guideline.md deleted file mode 100644 index 7d427c01..00000000 --- a/versioned_docs/version-0.5.5/community/contribute/git-guideline.md +++ /dev/null @@ -1,130 +0,0 @@ -# Git Commit Guide - -This document describes the matters needing attention when Git submits changes. If you refuse to accept the contents of this article, the submitted changes will not be accepted. - -## 1. About issue - -Before submitting an issue, please check the closed issue. There may already be an appropriate solution in the closed issue. - -If no suitable solution is found, we provide four templates to use when creating an issue. - -- Bug Report: If a bug is found, you can contact us by creating an issue through the bug report template. -- Enhancement: The developer has enhanced the tool, and can create an issue through the enhancement template to introduce the added content. -- Feature Request: If you want to add some new features or functions to the tool during use, you can create an issue through the Feature Request template to describe the new features. -- Ask a Question: If you have any questions, you can create an issue through the Ask a Question template to contact us. - -After selecting the appropriate template, you only need to fill in the required content on the template. If you find that there is no template or the template content is empty when creating the issue, you can feed back this problem to us through WeChat group, nail group or email. - -## 2. About Git Branch - -To contribute code to KCL, you must have a GitHub account so that you can push the code to your own branch and create pull requests. We recommend reference [Angular Specification]( https://github.com/angular/angular.js/blob/master/DEVELOPERS.md# -Git commit guidelines) name your own branches. - -The recommended format is as follows: - -``` -{type}-{a_short_description} -``` - -The branch name mainly includes two fields, which are separated by "-". Including: - -- `{type}`: the type of the current branch content. -- `{a_short_description}`: A short description of the main content of this branch. - -For example, Alice first transfers the Fork warehouse to his own account, and then creates a branch with the corresponding name 'alice: fix output fmt bug' (Alice's account is before the colon) to fix the output formatting bug. - -## 3. 关于 Git Commit - -We refer to [Commitizen](https://github.com/commitizen/cz-cli) to write a Commit Message. - -``` -Note: If you directly use Commit to generate a Commit Message, please note that -It is a tool for developers to manage commit. It is not related to the project itself, so it is an intermediate product generated by Commiten -(For example, the node_modules file directory) may not be in the project. gitignore file. - -You can git add {filename} select the file to submit and ignore the intermediate product. -Or you can add the following content to the. gitignore file and automatically ignore the intermediate products: -# commitizen -package.json -package-lock.json -node_modules/* -``` - -If you manually write a commit Message, we also recommend [Commiten](https://github.com/commitizen/cz-cli) for the commit message format. - -``` -{type} ( {component_or_file} ) {a_short_description} -{a_longer_description} -BREAKING CHANGE: {breaking_change_description}. -{linked issue} -``` - -It mainly includes 6 fields: - -- `{type}`: the type of the branch corresponding to the current commit. -- `{component_or_file}`: the name of the module or file that the current commit changes. -- `{a_short_description}`: A short description describes the content of the commit. -- `{a_longer_description}`: The detailed description is used to introduce the content in the commit. -- `{breaking_change_description}`: If the commit contains broken compatibility changes, the impact of compatibility changes needs to be introduced. -- `{linked issue}`: the issue associated with the current commit. - -Where `{breaking_change_description}` and `{linked issue}` can be omitted if the commit does not contain compatibility breaking changes and associated issues. - -For example, the commit created by Alice in branch 'alice: fix output fmt bug'. - -``` -fix(kcl-printer): fix an output format bug in kcl-printer - -There is an output format bug in kcl-printer because ..., -So, The calling of method "XXX" is replaced by "HHHH"..., -... - ---If there is no change to break the compatibility and the associated issue, the following contents can be omitted. -BREAKING CHANGE: This change maybe cause ....... - -fix #123 -``` - -## 4. About pull request - -Before submitting a PR, priority may be given to the following issues: - -- Please check the closed PRs first. There may be completed solutions in the closed PRs. -- We suggest that before submitting the change, submit a corresponding issue to describe the problems to be solved in the change, and associate the PR corresponding to the change with the issue. -- After submitting the PR to us, please sign [Contributor License Agreement (CLA)] (# cla). If you refuse to sign, we will not accept the PR. -- Make sure that each change creates a new branch and names the branch according to the specifications mentioned above. -- PR should not exceed two commit at a time. Please compress the extra commit with squash and write a commit message according to the specifications mentioned above. -- We provide [PR template](https://github.com/kcl-lang/.github/blob/main/.github/PULL_REQUEST_TEMPLATE.md). You only need to add the content required in the template. If you find no template or the template content is empty when creating a PR, you can feed back this problem to us through WeChat group, nail group or email. - -We suggest that the PR title be consistent with the branch name and the commit message style: - -``` -{type} ( {component_name_or_file_name} ) :{a_short_description} -``` - -比如,Alice 为分支`fix/alice/fix_output_fmt_bug`创建的PR名称。 - -For example, Alice creates the PR name `fix/alice/fix_output_fmt_bug` for one branch. - -``` -fix(kcl-printer): fix an output format bug in kcl-printer. -``` - -## 5. Supported PR Types - -``` -- feat: -- New features have been added. -- fix: -- Bug is repaired. -- docs: -- The document part has been modified. -- style: -- The modification of code format does not affect the functions of the code, such as deleting redundant spaces, code indentation, etc. -- refactor: -- refactoring code without changing its function. -- perf: -- Performs performance optimization on the code. -- test: -- Add or adjust existing test cases. -- build: -- Adjust the build system or external dependent libraries. -- ci: -- The configuration file or script of the CI has been adjusted. -- choice: -- Adjustments to other parts of the source code and test files. -- reverse: -- Rollback commit. -``` - -## 6. Contributor License Agreement (CLA) - -After the PR is submitted to us for the first time, the CLA check in the PR will fail and prompt to sign the CLA. You can reply "I have read the CLA Document and I hereby sign the CLA" between your accounts in PR to agree to sign the CLA, and then manually restart the failed CLA check action. After PR is successfully merged, it will be locked and cannot be modified. diff --git a/versioned_docs/version-0.5.5/community/intro/_category_.json b/versioned_docs/version-0.5.5/community/intro/_category_.json deleted file mode 100644 index a9646363..00000000 --- a/versioned_docs/version-0.5.5/community/intro/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Community", - "position": 1 -} diff --git a/versioned_docs/version-0.5.5/community/intro/intro.md b/versioned_docs/version-0.5.5/community/intro/intro.md deleted file mode 100644 index 4b1a7f02..00000000 --- a/versioned_docs/version-0.5.5/community/intro/intro.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Community - -Welcome to the KCL open-source community, everyone's participation is the driving force for the healthy growth of all open-source projects! There are many ways to participate in open-source. Everyone can create Issues or fix bugs, improve documentation or modify code by submitting PR (Pull Request), or open new feature discussions by submitting KEP, or share stories about the process of evangelism and use of KCL with surrounding friends. - -See the [community](https://github.com/kcl-lang/community) for ways to join us. diff --git a/versioned_docs/version-0.5.5/community/intro/license.md b/versioned_docs/version-0.5.5/community/intro/license.md deleted file mode 100644 index 4d0097b4..00000000 --- a/versioned_docs/version-0.5.5/community/intro/license.md +++ /dev/null @@ -1,211 +0,0 @@ ---- -sidebar_position: 99 ---- - -# License - -KCL Use [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) License: - -``` - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2023 The KCL Authors. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -``` diff --git a/versioned_docs/version-0.5.5/community/intro/support.md b/versioned_docs/version-0.5.5/community/intro/support.md deleted file mode 100644 index 7ed2e1a8..00000000 --- a/versioned_docs/version-0.5.5/community/intro/support.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Ask for help - -KCL has a developer and user community of many enthusiasts. - -On this page, we list the KCL-related communities you can participate in; see other pages in this section for additional online and offline learning materials. - -Before joining the KCL community, please read the [Contributor Covenant](https://www.contributor-covenant.org/version/2/0/code_of_conduct/) , which is expected to be followed by all community members. - -## Discussions - -- Submit an issue on Github -- Communicate in the Github discussion group -- Get the latest status through official website, Github, Twitter, Slack, Wechat and other accounts. See the [community](https://github.com/kcl-lang/community) for ways to join us. - -## New Features - -Please try to avoid submitting pull requests for new features, we may already have someone working on them, or maybe this feature is already part of our future plans. In conclusion, please contact us before submitting new features! diff --git a/versioned_docs/version-0.5.5/community/release-policy/_category_.json b/versioned_docs/version-0.5.5/community/release-policy/_category_.json deleted file mode 100644 index bc39d651..00000000 --- a/versioned_docs/version-0.5.5/community/release-policy/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Release Policy", - "position": 3 -} diff --git a/versioned_docs/version-0.5.5/community/release-policy/index.md b/versioned_docs/version-0.5.5/community/release-policy/index.md deleted file mode 100644 index c87091d0..00000000 --- a/versioned_docs/version-0.5.5/community/release-policy/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# Release Policy - -The release policy defines the semantics of the release, the release process, etc. In order to maximize the concurrent development process, KCL, etc. adopt independent release strategies. diff --git a/versioned_docs/version-0.5.5/community/release-policy/kcl.md b/versioned_docs/version-0.5.5/community/release-policy/kcl.md deleted file mode 100644 index a24e1509..00000000 --- a/versioned_docs/version-0.5.5/community/release-policy/kcl.md +++ /dev/null @@ -1,39 +0,0 @@ -# KCL Release Policy - -KCL 开发团队采用 [语义化版本](https://semver.org/lang/zh-CN/) 来简化管理。版本格式:主版本号.次版本号.修订号。版本号递增规则如下:主版本号对应不兼容的 API 修改,次版本号对应向下兼容的功能性新增,修订号对应向下兼容的问题修正。总体目标是每一个半月发布一个特性增强的次要版本,根据需要不定期发布其他版本的修订。 - -KCL 项目版本发布策略如下: - -- 主版本号:当进行重大的架构调整或者加入重大的新功能时,需要提升主版本号。对于 KCL 项目来说,目前的主版本号为 0。 -- 次版本号:当添加的功能和特性有较大的变化时,提升次版本号。目前的次版本号为 5,2023 年度会相继发布 0.5, 0.6, 0.7 版本。 -- 修订号:通过修复漏洞或者改进性能来更新程序时,会提升修订号,修订号从 0 开始计数以此加 1。 -- 发布周期:在未达到 v1.0.0 版本之前,计划每隔 3 个月发布一个新的次要版本。在此期间,需要持续收集用户反馈,并进行必要的修复和改进。 -- 发布流程:在发布新版本之前,需要进行严格的测试和审核,确保新版本的质量。封板并测试完成后,会在 Github 上发布新版本的源代码,二进制和镜像,并提供详细的文档和使用指南。 -- 版本支持:我们将对最新的版本提供长期支持,包括漏洞修复和安全更新。对于旧版本,我们将提供有限的支持,仅在必要时进行修复。 - -## 发布流程与规则 - -- 特性开发:main 分支主干开发,分支发布,block 用户使用的问题和严重的 bug, 安全隐患,高优先级解决,尽可能保持在一周内收敛,高于一般的功能研发。 -- 迭代周期:我们的迭代周期通常为 3 个月,即每 3 个月发布一个新的次要版本。 -- 版本规划:发版前两周产出 alpha 版本,前一周产出 beta 版本,alpha 版本仍可进行特性合并,beta 版本只合并错误修复,最终产出正式版本并打 tag 作为长期保存的 release 分支。 -- 发版计划:在每个发布周期开始时制定详细的发版计划(Github Milestone),包括发布日期、版本号、功能列表和测试计划等。需要尽可能地遵守发版计划,确保按时发布新版本。 -- 发布前测试:在发布新版本之前,需要进行全面的测试,包括单元测试、集成测试,模糊测试,压测,用户验收测试等。只有经过测试并无问题后,我们才会发布新版本。 -- 版本回滚:如果在发布后发现了严重的问题,需要立即回滚版本,并尽快修复问题。并通过邮件、社交媒体等渠道及时通知用户,并提供解决方案。 -- 发布文档:需要在发布时提供详细的文档,包括发布说明、更新日志、API 文档和使用指南等,帮助用户了解和使用新版本。在 KCL 中,我们统一在 KCL 网站进行维护。 -- 版本兼容性:在发布新版本时,需要尽可能保持兼容性,以确保用户无需进行过多的修改和适应。KCL 还没有达到 v1,暂时没有兼容性保证。KCL 的目标是尽可能少地进行重大更改,不应轻率地考虑对语言的更改,为了语言自身更好地演进和发展,一般认为更改具有重大好处时才会进行(较好地解决了目标场景的问题或者提升了绝大用户的使用体验)。对于可能引入兼容性问题的功能或变更,提供相应的提示和解决方案,同时会提供逐步升级的指南或提供自动迁移的工具,以帮助用户平滑地迁移到新版本。 - -## 发布组件 - -![](/img/docs/community/release-policy/kcl-components.png) - -每次版本发布时,KCL 相关所有组件保持一个依赖同一个 KCL 核心主要版本,整体采用树形结构组织依赖顺序发布并进行回归测试,直到发布测试完成,尽力避免三角依赖,禁止循环依赖。 - -## 一个 Feature 的生命周期 - -- 设计方案/文档:通过 Issue 回答清楚这个 feature 的动机是什么,它解决什么问题以及目标是什么,用户需求和用户故事是怎样的;这个 feature 做什么,如何做,难度怎样,需要多长时间,依赖项,需要做什么测试等。(Tips: 大的设计尽量拆分成小的设计,通过权衡和广泛的调研找到一个简单且可持续的解决方案,并且具备一定得到可扩展以适应未来的业务或技术变化,通过持续讨论和方案评审确定最终设计)。 -- 编写代码:通过高频小改动进行迭代、持续沟通和协作,提前设计单元测试、集成测试和 benchmark 等测试用例,确保编写代码 100% 测试覆盖,注释完整和逻辑清晰,并通过 Demo 演示持续收集反馈。 -- 文档撰写:在 [KCL 网站](https://kcl-lang.io) 中更新用户文档。 -- 测试和反馈:在发布功能之前,让一些同行/用户通过**随循文档**而不是口述来尝试和测试这些新功能。接收反馈并改进。 -- 发布和公告:撰写 Release Note, PR 文章,场景和新特性解读等以及渠道宣发等。 - -> 注:以上所有信息全是公开的,需要透出给所有社区研发者进行参与、讨论和贡献。 diff --git a/versioned_docs/version-0.5.5/community/release-policy/roadmap.md b/versioned_docs/version-0.5.5/community/release-policy/roadmap.md deleted file mode 100644 index df220576..00000000 --- a/versioned_docs/version-0.5.5/community/release-policy/roadmap.md +++ /dev/null @@ -1,3 +0,0 @@ -# Roadmap - -![](/img/docs/community/release-policy/roadmap.jpg) diff --git a/versioned_docs/version-0.5.5/reference/_advanced-concepts/_category_.json b/versioned_docs/version-0.5.5/reference/_advanced-concepts/_category_.json deleted file mode 100644 index 85a16abb..00000000 --- a/versioned_docs/version-0.5.5/reference/_advanced-concepts/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Advanced-Concepts", - "position": 6 -} diff --git a/versioned_docs/version-0.5.5/reference/_advanced-concepts/build_cache.md b/versioned_docs/version-0.5.5/reference/_advanced-concepts/build_cache.md deleted file mode 100644 index 746e2351..00000000 --- a/versioned_docs/version-0.5.5/reference/_advanced-concepts/build_cache.md +++ /dev/null @@ -1 +0,0 @@ -# Building Cache diff --git a/versioned_docs/version-0.5.5/reference/_category_.json b/versioned_docs/version-0.5.5/reference/_category_.json deleted file mode 100644 index 1b337d5a..00000000 --- a/versioned_docs/version-0.5.5/reference/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Reference", - "position": 5 -} diff --git a/versioned_docs/version-0.5.5/reference/cheatsheets/_category_.json b/versioned_docs/version-0.5.5/reference/cheatsheets/_category_.json deleted file mode 100644 index 80464148..00000000 --- a/versioned_docs/version-0.5.5/reference/cheatsheets/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Cheat Sheet", - "position": 10 -} diff --git a/versioned_docs/version-0.5.5/reference/cheatsheets/index.md b/versioned_docs/version-0.5.5/reference/cheatsheets/index.md deleted file mode 100644 index da4189eb..00000000 --- a/versioned_docs/version-0.5.5/reference/cheatsheets/index.md +++ /dev/null @@ -1,5 +0,0 @@ -# KCL Cheat Sheet - -![](/img/docs/reference/cheatsheets/cheatsheet.png) - -[Download PDF](https://github.com/kcl-lang/kcl-lang.io/blob/main/cheatsheet/cheatsheet.pdf) diff --git a/versioned_docs/version-0.5.5/reference/lang/_category_.json b/versioned_docs/version-0.5.5/reference/lang/_category_.json deleted file mode 100644 index 4c823148..00000000 --- a/versioned_docs/version-0.5.5/reference/lang/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Tutorial", - "position": 1 -} diff --git a/versioned_docs/version-0.5.5/reference/lang/codelab/_category_.json b/versioned_docs/version-0.5.5/reference/lang/codelab/_category_.json deleted file mode 100644 index 2e047bcb..00000000 --- a/versioned_docs/version-0.5.5/reference/lang/codelab/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Code Lab", - "position": 2 -} diff --git a/versioned_docs/version-0.5.5/reference/lang/codelab/collaborative.md b/versioned_docs/version-0.5.5/reference/lang/codelab/collaborative.md deleted file mode 100644 index 84ee8160..00000000 --- a/versioned_docs/version-0.5.5/reference/lang/codelab/collaborative.md +++ /dev/null @@ -1,345 +0,0 @@ ---- -title: "Co-configuration with config operations" -linkTitle: "Co-configuration with config operations" -type: "docs" -weight: 2 -description: Co-configuration with config operations -sidebar_position: 3 ---- - -## 1. Introduction - -KCL is a simple and easy-to-use configuration language, where users can simply write the reusable configuration code. - -In this codelab, we will learn how to write the config in a collaborative way using the KCL config operation features. - -### What We Will Learn - -1. Define schemas and organize project directories. -2. Create multiple environment configurations via the KCL config operation features. -3. Configure compiling parameters and tests. - -## 2. Define Schemas and Organize Project Directories - -### Schema Definitions - -Suppose we want to define a server configuration with certain attributes, we can create a simple config by creating a `server.k`, we can fill in the following code as below which defines a reusable schema of the configuration of a server. - -```python -import units - -type Unit = units.NumberMultiplier - -schema Server: - replicas: int = 1 - image: str - resource: Resource = {} - mainContainer: Main = {} - labels?: {str:str} - annotations?: {str:str} - -schema Main: - name: str = "main" - command?: [str] - args?: [str] - ports?: [Port] - -schema Resource: - cpu?: int = 1 - memory?: Unit = 1024Mi - disk?: Unit = 10Gi - -schema Port: - name?: str - protocol: "HTTP" | "TCP" - port: 80 | 443 - targetPort: int - - check: - targetPort > 1024, "targetPort must be larger than 1024" -``` - -In the code above, we define a schema named `Server`, which represents the configuration type that the user will write, which contains some basic type attributes (e.g., `replicas`, `image`, etc) and some composite type attributes (e.g., `resource`, `main`, etc). In addition to some basic types mentioned in the [schema codelab](./schema.md), we can see two types in the above code `Unit` and `units.NumberMultiplier`. Among them, `units.NumberMultiplier` denotes the KCL number unit type, which means that a natural unit or binary unit can be added after the KCL number, such as `1K` for `1000`, `1Ki` for `1024`. `Unit` is the type alias of `units.NumberMultiplier`, which is used to simplify the writing of type annotations. - -### Project Directories - -In order to complete the collaborative configuration development, we first need a configuration project, which contains the configuration of the test application and the differential configuration of different environments, so we are creating the following project directory: - -``` -. -├── appops -│ └── test_app -│ ├── base -│ │ └── base.k -│ ├── dev -│ │ ├── ci-test -│ │ │ └── stdout.golden.yaml -│ │ ├── kcl.yaml -│ │ └── main.k -│ └── prod -│ ├── ci-test -│ │ └── stdout.golden.yaml -│ ├── kcl.yaml -│ └── main.k -├── kcl.mod -└── pkg - └── sever.k -``` - -The directory of the project mainly contains three parts: - -- `kcl.mod`: The file used to identify the root directory of the KCL project. -- `pkg`: `Server` Schema structure reused by different application configurations. -- `appops`: Server configurations of different applications, currently only one application `test_app` is placed. - - `base`: Application common configurations for all environments. - - `dev`: Application configuration for the development environment. - - `prod`: Application configuration for the production environment. - -The meaning of `base.k`, `main.k`, `kcl.yaml` and `ci-test/stdout.golden.yaml` will be mentioned in subsequent sections. - -## 3. Create multiple environment configurations via the KCL config operation features - -### Create a baseline configuration - -After we have organized the project directory and the basic server configuration model, we can write the configuration of the user application. We can create our own test application folder `test_app` and place it in the application configuration folder `appops`. - -For the configuration of an application, we often divide it into a basic configuration and the differential configuration of multiple environments and merge them. Through the configuration merging feature of KCL, we can easily do this. Assuming that we have two configurations of development environment and production environment, we can create three folders: `base`, `dev` and `prod` to store baseline, development environment and production environment configurations respectively. First, we write the configuration of `base/base.k`: - -```python -import pkg - -server: pkg.Server { - # Set the image with the value "nginx:1.14.2" - image = "nginx:1.14.2" - # Add a label app into labels - labels.app = "test_app" - # Add a mainContainer config, and its ports are [{protocol = "HTTP", port = 80, targetPort = 1100}] - mainContainer.ports = [{ - protocol = "HTTP" - port = 80 - targetPort = 1100 - }] -} -``` - -As in the above code, we use the `import` keyword in `base.k` to import the `Server` schema placed under `pkg` and use it to instantiate a configuration named `server`, in which we set `image` attribute to `"nginx:1.14.2"`, and a label `app` with the value `test_app` is added. In addition, we also added the configuration of the main container `mainContainer` with the value `[{protocol = "HTTP", port = 80, targetPort = 1100}]` for the ports attribute. - -KCL command: - -```bash -kcl appops/test_app/base/base.k -``` - -Output: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2 - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app -``` - -At this point, we have a baseline configuration. - -### Create multiple environment configurations - -Next we configure a differentiated multi-environment configuration. First assume that we want to use a temporary image of our own `nginx:1.14.2-dev` in the development environment, and then use it to override the server configuration in the baseline, we can write the following configuration in `dev/main.k`: - -```python -import pkg - -server: pkg.Server { - # Override the image declared in the base - image = "nginx:1.14.2-dev" -} -``` - -KCL command: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -Output: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app -``` - -It can be seen that the `image` field of the output YAML is overwritten to `nginx:1.14.2-dev`. Suppose we also want to add a label to the `dev` environment with a key of `env` and a value of `dev`, we add the following code to `dev/main.k`: - -```python -import pkg - -server: pkg.Server { - # Override the image declared in the base - image = "nginx:1.14.2-dev" - # Union a new label env into base labels - labels.env = "dev" -} -``` - -KCL command: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app - env: dev -``` - -It can be seen that there are two labels in the `labels` field of the output YAML. - -In addition, we can also use the `+=` operator to add new values to list type attributes, such as the `mainContainer.ports` configuration in the baseline environment, continue to modify the code in `dev/main.k`: - -```python -import pkg - -server: pkg.Server { - # Override the base image. - image = "nginx:1.14.2-dev" - # Union a new label env into base labels. - labels.env = "dev" - # Append a port into base ports. - mainContainer.ports += [{ - protocol = "TCP" - port = 443 - targetPort = 1100 - }] -} -``` - -KCL command: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -Output: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - - protocol: TCP - port: 443 - targetPort: 1100 - labels: - app: test_app - env: dev -``` - -Using the same method, we can build the production configuration, write the code in the `dev/main.k` file, and add a label to it. - -```python -import pkg - -server: pkg.Server { - # Union a new label env into base labels - labels.env = "prod" -} -``` - -KCL command: - -```bash -kcl appops/test_app/base/base.k appops/test_app/prod/main.k -``` - -Output: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2 - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app - env: prod -``` - -## 4. Configure compiling parameters and tests - -In the previous section, we built a multi-environment configuration through code. It can be seen that the KCL command line compilation parameters of different environments are similar, so we can configure these compilation parameters into a file and input them to the KCL command line for invocation. Configure the following code in `dev/kcl.yaml`: - -```yaml -kcl_cli_configs: - files: - - ../base/base.k - - main.k - output: ./ci-test/stdout.golden.yaml -``` - -Then we can compile the configuration in the development environment with the following command: - -```bash -cd appops/test_app/dev && kcl -Y ./kcl.yaml -``` - -In addition, we have configured the `output` field in `dev/kcl.yaml` to output YAML to a file for subsequent configuration distribution or testing. You can verify that the application's configuration is as expected by walking through the `kcl.yaml` builds in each environment and comparing with `./ci-test/stdout.golden.yaml`. - -## 5. The Final Step - -Congratulations! - -We have completed the third lesson about KCL. diff --git a/versioned_docs/version-0.5.5/reference/lang/codelab/index.md b/versioned_docs/version-0.5.5/reference/lang/codelab/index.md deleted file mode 100644 index dbe554a9..00000000 --- a/versioned_docs/version-0.5.5/reference/lang/codelab/index.md +++ /dev/null @@ -1 +0,0 @@ -# Code Lab diff --git a/versioned_docs/version-0.5.5/reference/lang/codelab/schema.md b/versioned_docs/version-0.5.5/reference/lang/codelab/schema.md deleted file mode 100644 index 02f792d4..00000000 --- a/versioned_docs/version-0.5.5/reference/lang/codelab/schema.md +++ /dev/null @@ -1,817 +0,0 @@ ---- -title: "Write complex config using KCL Schema" -linkTitle: "Write complex config using KCL Schema" -type: "docs" -weight: 2 -description: Write complex config using KCL Schema -sidebar_position: 2 ---- - -## 1. Introduction - -KCL is a simple and easy-to-use configuration language, where users can simply write the reusable configuration code. - -In this codelab, we will learn how to write customized config using KCL, such that we can define a schema and write the config in a collaborative way. - -### What We Will Learn - -1. Define a simple schema -2. Set default immutable values to schema fields -3. Create config based on a simple schema -4. Write complex logic in schema -5. Create a new schema via schema combinations -6. Create a config of a deeply nested schema using dict/map -7. Create new schema via schema inheritance -8. Create new schema via multiple mixin schemas -9. Declare validation rules for the schema -10. Config schema output layout -11. Share and reuse schema - -## 2. Write Simple Schema - -Suppose we want to define a workload with certain attributes, we can create a simple config by creating a `my_config.k`, we can fill in the following code as below which defines a reusable schema of the configuration of deploy. - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels: {str:str} -``` - -In the code above, `cpu` and `memory` are defined as int value; `name`, `image` and `service` are string; `command` is a list of string type; `labels` is a dict type, whose key type and value type are both string. - -Besides, each attribute **must** be assigned with a not-None value as a schema instance unless it is modified by a question mark **?** as an optional attribute. - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels?: {str:str} # labels is an optional attribute -``` - -When there is an inheritance relationship: - -- If the attribute is optional in the base schema, it could be optional or required in the sub-schema. -- If the attribute is required in the base schema, it must be required in the sub-schema. - -## 3. Enhance Schema as Needed - -Suppose we need to set default values to service and replica, we can make them as below: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str = "my-service" # defaulting - replica: int = 1 # defaulting - command: [str] - labels?: {str:str} # labels is an optional attribute -``` - -And then we can set the service type annotation as the string literal type to make it immutable: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: "my-service" = "my-service" - replica: int = 1 - command: [str] - labels?: {str:str} -``` - -In the schema, type hint is a `must`, for example we can define cpu as `cpu: int`. - -Specially, we can define a string-interface dict as `{str:}`, and in case we want to define an object or interface, just define as `{:}`. - -## 4. Create Config Based on Simple Schema - -Now we have a simple schema definition, we can use it to define config as: - -```python -nginx = Deployment { - name = "my-nginx" - cpu = 256 - memory = 512 - image = "nginx:1.14.2" - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } -} -``` - -Run with the following KCL command, we should be able to see the generated yaml files as the output as below: - -KCL command: - -``` - kcl my_config.k -``` - -Stdout: - -```yaml -nginx: - name: my-nginx - cpu: 256 - memory: 512 - image: nginx:1.14.2 - service: my-service - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -> Check the manual and specification out for more details about collection data types and block. - -In addition, the **config selector expressions** can be used to init a schema instance, and we can ignore the comma at the end of the line in the config expression. - -```python -nginx = Deployment { - name = "my-nginx" - cpu = 256 - memory = 512 - image = "nginx:1.14.2" - command = ["nginx"] # Ignore the comma at the end of the line - labels.run = "my-nginx" # A dict variable in schema can use selector expressions - labels.env = "pre-prod" # A dict variable in schema can use selector expressions -} -``` - -## 5. Write More Complex Logic in Schema - -Suppose we have some schema logic, we can wrapper it into schema: - -```python -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - image: str - service: "my-service" = "my-service" - replica: int = 1 - command: [str] - labels?: {str:str} - - _cpu = 2048 - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 -``` - -Now, we can define a config by creating a schema instance and pass in priority as an argument to schema: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -Run with kcl, we should see the generated yaml files as output as below: - -KCL command: - -``` -kcl my_config.k -``` - -Stdout: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - image: nginx:1.14.2 - service: my-service - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 6. Create New Schema via Schema Combinations - -Now we want to define a detailed schema with service and volumes, we can do it as follows: - -```python -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - volumes?: [Volume] - image: str - service?: Service - replica: int = 1 - command: [str] - labels?: {str:str} - - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 - -schema Port: - name: str - protocol: str - port: int - targetPort: int - -schema Service: - name: "my-service" = "my-service" - ports: [Port] - -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -In this case, Deployment is composed of Service and a list of Volumes, and Service is composed of a list of Ports. - -## 7. Create Config of Deeply Nested Schema using Dict/Map - -Now we have a new Deployment schema, however, we may notice that it contains multiple layers of nested structures, in fact, this is very common in complex structure definitions, and we often have to write imperative assembly code to generate the final structure. - -With KCL, we can create the config with simple dict declaration, with the capability of full schema initialization and validation. For example, we can simply config nginx by the new Deployment schema as follows: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -Run with KCL, we will see the generated yaml files as below: - -KCL command: - -``` -kcl my_config.k -``` - -Stdout: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -Note that, the dict that we use to define Deployment config must be aligned with the schema definition, otherwise we will get an error. For example, suppose we define a wrong type of service port as below: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = [80] # wrong data type, trying to assign List to int - targetPort = 9376 - }] -} -``` - -Run with KCL, we will see the error message as output as below: - -KCL command: - -```python -kcl my_config.k -``` - -Stderr: - -``` -The type got is inconsistent with the type expected: expect int, got [int(80)] -``` - -## 8. Declare Schema Validation Rules - -Now we have seen a complex schema, in which every field has a type hint to make it less error-prone. But this is not good enough, we want to support more enhanced verifications to our schemas, so that code errors in schemas and configs can be discovered as soon as possible. - -Lots of validation rules, like None type check, range check, value check, length check, regular expression matching, enum check have already been added or in progress. Here is a code sample: - -```python -import regex - -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - volumes?: [Volume] - image: str - service?: Service - replica: int = 1 - command: [str] - labels?: {str:str} - - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 - - check: - multiplyof(cpu, 256), "cpu must be a multiplier of 256" - regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$"), "image name should be like 'nginx:1.14.2'" - 1 <= replica < 100, "replica should be in range (1, 100)" - len(labels) >= 2 if labels, "the length of labels should be large or equal to 2" - "env" in labels, "'env' must be in labels" - len(command) > 0, "the command list should be non-empty" - -schema Port: - name: str - protocol: str - port: int - targetPort: int - - check: - port in [80, 443], "we can only expose 80 and 443 port" - protocol in ["HTTP", "TCP"], "protocol must be either HTTP or TCP" - 1024 < targetPort, "targetPort must be larger than 1024" - -schema Service: - name: "my-service" = "my-service" - ports: [Port] - - check: - len(ports) > 0, "ports list must be non-empty" - -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -Since the attributes defined by the schema are **required** by default, the verification that judges that the variable cannot be None/Undefined can be omitted. - -```python -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -Now we can write the config based on the new schema and expose config errors in time. For example, with the invalid config as below: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1142" # image value is not matching the regex - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -Every field is type-valid, but the image name is invalid. - -Run with KCL, we will see the error message as below: - -KCL command: - -``` -kcl my_config.k -``` - -Stderr: - -``` -Schema check is failed to check condition: regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$"), "image name should be like 'nginx:1.14.2'" -``` - -> The verification capability of KCL covers the verification defined by Openapi so that we can write any API verifications through KCL. - -## 9. Create New Schema via Schema Inheritance - -Now we have a solid Deployment schema definition and we can use it to declare config. - -Usually, schema Deployment will be used in multiple scenarios. We can directly use the schema to declare the configurations in different use cases (see the above section), or we can produce a more specific schema definition through inheritance. - -For example, we can use the Deployment schema as a basis, to define the nginx's base schema, and extend the definition -in each scenario. - -In this case, we define some commonly used attributes. Please note that we mark the name to be immutable with the 'final' keyword to prevent it from being overwritten. - -```python -schema Nginx(Deployment): - """ A base nginx schema """ - name: "my-nginx" = "my-nginx" - image: str = "nginx:1.14.2" - replica: int = 3 - command: [str] = ["nginx"] - -schema NginxProd(Nginx): - """ A prod nginx schema with stable configurations """ - volumes: [Volume] = [{ - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - """ A volume mapped to host path """ - service: Service = { - ports = [{ - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] - } - """ An 80 port to target backend server """ -``` - -Now we have some static configurations for nginx. It is recommended to declare configurations that we think are static there, and put more dynamic configurations as below: - -```python -nginx = Nginx { - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -```python -nginx = NginxProd { - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -Now, we can simply define nginx prod config just with runtime label value "prod" which is not that static. - -In fact, under some complex situation, we can split all configurations into the basic, business, and environment configuration definitions in this way, and achieve collaboration among team members based on this. - -Run with KCL, we will see the generated yaml files as output as below: - -KCL command: - -``` -kcl prod_config.k -``` - -Stdout: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 3 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 10. Create New Schema by Multiple Protocol and Mixin Schemas Inheritance - -Now, we can complete the declaration of the server configuration through the Deployment schema. - -However, usually, the actual situation is more complicated, and the deployment may have a variety of optional variable accessories. - -For example, we want to support a persistent volume claim based on an existing schema, as a reusable Kubernetes schema. In this case, we can just wrapper it with a `mixin` and a `protocol` as follows: - -```python -import k8spkg.api.core.v1 - -protocol PVCProtocol: - pvc?: {str:} - -mixin PersistentVolumeClaimMixin for PVCProtocol: - """ - PersistentVolumeClaim (PVC) sample: - Link: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims - """ - - # Mix in a new attribute `kubernetesPVC` - kubernetesPVC?: v1.PersistentVolumeClaim - - if pvc: - kubernetesPVC = v1.PersistentVolumeClaim { - metadata.name = pvc.name - metadata.labels = pvc.labels - spec = { - accessModes = pvc.accessModes - resources = pvc.resources - storageClassName = pvc.storageClassName - } - } -``` - -With this PersistentVolumeClaimMixin, we define a PVC schema with a clear `user interface`, and use Kubernetes PVC as an implementation. Then, we can define a server schema with Deployment schema, and PVC mixin schema. - -``` -schema Server(Deployment): - mixin [PersistentVolumeClaimMixin] - pvc?: {str:} - """ pvc user interface data defined by PersistentVolumeClaimMixin """ -``` - -In the Server schema, Deployment is the base schema, and PersistentVolumeClaimMixin is an optional add-on whose user interface data is `pvc?: {str:}`. - -Note, the `mixin` is often used to add new attributes to the host schema, or to modify the existing attributes of the host schema. Thus, `mixin` can use the attributes in the host schema. Since the `mixin` is designed to be reusable, we need an additional `protocol` to constrain the attribute names and types in the host schema for the `mixin`. - -Now, if we want a deploy with a PVC, just declare as user interface: - -```python -server = Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] - pvc = { - name = "my_pvc" - accessModes = ["ReadWriteOnce"] - resources.requests.storage = "8Gi" - storageClassName = "slow" - } -} -``` - -Run with kcl, we will see the generated yaml files as output as below: - -KCL command: - -``` -kcl server.k -``` - -Stdout: - -```yaml -server: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod - pvc: - name: my_pvc - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 8Gi - storageClassName: slow ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: my_pvc -spec: - accessModes: - - ReadWriteOnce - storageClassName: slow - resources: - requests: - storage: 8Gi -``` - -If we don't want a persistent volume, just remove the pvc config block. - -## 11. Share and Reuse Schema - -The Server schema could be shared via `import`, we can simply package our code with KCL. - -```python -import pkg - -server = pkg.Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -Another skill we should know about sharing code is, modules under the same package do not need to import each other. - -Suppose we have models in a pkg: - -``` -pkg/ - - deploy.k - - server.k - - pvc.k -``` - -And in `server.k`, we can just use Deployment schema in `deploy.k` and pvc schema in `pvc.k` without import: - -```python -# no import needed -schema Server(Deployment): - mixin [PersistentVolumeClaimMixin] - pvc?: {str:} - """ pvc user interface data defined by PersistentVolumeClaimMixin """ -``` - -And then users must import the pkg to use it as a whole: - -```python -import pkg - -server = pkg.Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [pkg.Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } - service.ports = [pkg.Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -Run kcl command: - -``` -kcl pkg_server.k -``` - -Output: - -```yaml -server: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 12. The Final Step - -Congratulations! - -We have completed the second lesson about KCL, we have used KCL to replace our key-value text file to get better programming support. diff --git a/versioned_docs/version-0.5.5/reference/lang/codelab/simple.md b/versioned_docs/version-0.5.5/reference/lang/codelab/simple.md deleted file mode 100644 index 56be5805..00000000 --- a/versioned_docs/version-0.5.5/reference/lang/codelab/simple.md +++ /dev/null @@ -1,495 +0,0 @@ ---- -title: "Write simple config with KCL" -linkTitle: "Write simple config with KCL" -type: "docs" -weight: 2 -description: Write simple config with KCL -sidebar_position: 1 ---- - -## 1. Introduction - -KCL is a simple and easy-to-use configuration language, where users can simply write the reusable configuration code. - -In this first codelab, we will learn how to write a simple config with KCL. - -Learning this codelab only requires basic programming knowledge, and experience with python will make it even easier. - -### What We Will Learn - -1. Write simple key-value configuration in a programmable way -2. Write simple logic in KCL code -3. Write collections in KCL code -4. Test and debug with KCL code -5. Use built-in support in KCL code -6. Share and reuse KCL code -7. Write config with dynamic input arguments - -## 2. Write Key-Value Pairs - -Generate a simple config by creating a `my_config.k`, we can fill in the following code without strict format which describes the configuration of deploy. - -```python -cpu = 256 -memory = 512 -image = "nginx:1.14.2" -service = "my-service" -``` - -In the code above, cpu and memory are declared as int value, while image and service are string literal. - -Run with KCL, we will see the generated data in yaml format as below: - -KCL command: - -```bash -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -The exported variable is immutable by default so that once it is declared, we can't modify it some where else. - -## 3. Write Simple Logic - -Sometimes we want to write a logic in configuration, then we can use: - -- Mutable and non-exported variable starting with `_` -- If-else statement - -A non-exported variable means it will not appear in the output YAML, and it can be assigned multiple times. - -Here is a sample to show how to adjust the resource with conditions. - -KCL command: - -```python -kcl my_config.k -``` - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -image = "nginx:1.14.2" -service = "my-service" -``` - -Run with KCL, we will see the generated data in yaml format as below: - -```python -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -.. note:: -KCL has rich support of operators and string member functions, please read manual and specification for more details. - -## 4. Write Collections - -We can use collections to represent complex data types. The collections which are already supported are: - -- list -- dict - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -command = ["nginx"] # a list -labels = {run = "my-nginx"} # a dict -image = "nginx:1.14.2" -service = "my-service" -``` - -Run with kcl, we will see the generated data as yaml format as below: - -KCL command: - -```bash -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx -image: nginx:1.14.2 -service: my-service -``` - -> Check manual and specification out for more about collection date type and member functions. - -## 5. Append Items Into Collections - -We can combine logical expressions, comprehensions, slices, unions and other characteristics to dynamically add elements to the collection - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable -_env = "pre-prod" - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -_command = ["nginx"] # a list -_command = _command + ["-f", "file"] # Append items into command using + operator to contact two lists -command = [c.lower() for c in _command] # Take each element in the list to lowercase -_labels = { - run = "my-nginx" - if _env: - env = _env # Append a dict key-value pair when the _env is not None/Undefined or empty using if expressions -} # a dict -labels = _labels -image = "nginx:1.14.2" -service = "my-service" -``` - -Run with kcl, we will see the generated data as yaml format as below: - -```python -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 256 -memory: 512 -command: - - nginx - - -f - - file -labels: - run: my-nginx -image: nginx:1.14.2 -service: my-service -``` - -## 6. Write Assert - -To make code testable and robust, we can verify config data with assertions. - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -command = ["nginx"] # a list -labels = {run = "my-nginx"} # a dict -image = "nginx:1.14.2" -service = "my-service" -assert "env" in labels, "env label is a must" -assert cpu >= 256, "cpu cannot be less than 256" -``` - -Run with KCL, we will see eval failure with an error message as output as below: - -```bash -kcl my_config.k -``` - -Stderr: - -```bash -Assertion failure: env label is a must. -``` - -After adding env:pre-prod pair into labels, we will get the output as: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 7. Use Handy Built-in Support - -What's more, we can use built-in functions to help we debug or simplify coding. - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -_name = "nginx" -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # a list -labels = { - run = "my-{}".format(_name) - env = "pre-prod" -} # a dict -image = "{}:1.14.2".format(_name) # string format -service = "my-service" - -# debugging -print(labels) # debugging by print - -# test -assert len(labels) > 0, "labels can't be empty" # use len() to get list length -assert "env" in labels, "env label is a must" -assert cpu >= 256, "cpu cannot be less than 256" -``` - -This sample shows how we use `format()`, `len()`, `print()` function to help customize the config. - -Run with KCL, we will see the generated data in yaml format as below: - -KCL command: - -```bash -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -run: my-nginx -env: pre-prod -``` - -Note: more built-in functions and modules can be seen in spec/module - -## 8. Reuse Variables in Another Module - -To make our code well-organized, we can simply separate our code to `my_config.k` and `my_config_test.k`. - -Config data defined in `my_config.k`, - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 -_name = "nginx" - -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # a list -labels = { - run = "my-{}".format(_name) - env = "pre-prod" -} # a dict -image = "{}:1.14.2".format(_name) # string format -service = "my-service" -``` - -And test code defined in `my_config_test.k`, in which we can import `my_config.k`: - -```python -import my_config - -# debugging -print(my_config.labels) # debugging by print - -# test -assert len(my_config.labels) > 0, "labels can't be empty" # use len() to get list length -assert "env" in my_config.labels, "env label is a must" -assert my_config.cpu >= 256, "cpu cannot be less than256" -``` - -## 9. Config with Input Arguments - -Sometimes we need to get external input via parameters dynamically from the end user or platform. - -In this case, we can pass in `priority` and `env` on demand: - -- Pass in arguments: `-D priority=1 -D env=pre-prod` -- Get value by `option` keyword in KCL code - -```python -_priority = option("priority") # a non-exported and mutable variable -_env = option("env") # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -_name = "nginx" -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # a list -labels = { - run = "my-{}".format(_name) - env = _env -} # a dict -image = "{}:1.14.2".format(_name) # string format -service = "my-service" -``` - -Run with KCL, we will see the generated data in yaml format as below: - -```bash -kcl my_config.k -D priority=2 -D env=pre-prod -``` - -Stdout: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 10. Simplify Logic Expression using Dict - -When we need to write complex logic, we can use dict to simplify the writing of logic. - -```python -_priority = option("priority") # a non-exported and mutable variable -_env = option("env") # a non-exported and mutable variable -_priorityCpuMap = { - "1" = 256 - "2" = 512 - "3" = 1024 -} -# Using a dict to simplify logic and the default value is 2048 -_cpu = _priorityCpuMap[_priority] or 2048 -_name = "nginx" -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # a list -labels = { - run = "my-{}".format(_name) - env = _env -} # a dict -image = "{}:1.14.2".format(_name) # string format -service = "my-service" -``` - -Run with KCL, we will see the generated data in yaml format as below: - -KCL command: - -```bash -kcl my_config.k -D priority=2 -D env=pre-prod -``` - -Stdout: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 11. The Final Step - -Congratulations! - -We have completed the first lesson about KCL, we have used KCL to replace our key-value text file to get better programming support. - -Please check schema codelab out now to learn how to write an advanced config collaboratively with KCL `schema` mechanism. diff --git a/versioned_docs/version-0.5.5/reference/lang/error/_category_.json b/versioned_docs/version-0.5.5/reference/lang/error/_category_.json deleted file mode 100644 index 95062745..00000000 --- a/versioned_docs/version-0.5.5/reference/lang/error/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Errors and Warnings", - "position": 4 -} diff --git a/versioned_docs/version-0.5.5/reference/lang/error/exception.md b/versioned_docs/version-0.5.5/reference/lang/error/exception.md deleted file mode 100644 index 92c527a6..00000000 --- a/versioned_docs/version-0.5.5/reference/lang/error/exception.md +++ /dev/null @@ -1,1427 +0,0 @@ ---- -title: "KCL Errors and Warnings" -linkTitle: "KCL Errors and Warnings" -type: "docs" -weight: 2 -description: KCL Errors and Warnings ---- - -The articles in this section of the documentation explain the diagnostic error and warning messages that are generated by the KCL. - -**Important:** -**The KCL can report many kinds of errors and warnings. After an error or warning is found, the build tools may make assumptions about code intent and attempt to continue, so that more issues can be reported at the same time. If the tools make the wrong assumption, later errors or warnings may not apply to your project. When you correct issues in your project, always start with the first error or warning that's reported and rebuild often. One fix may make many subsequent errors go away.** - -In the following sections you will find: - -[KCL Syntax Error (E1xxx)](#11-kcl-syntax-error-e1xxx) : The KCL may reports KCL syntax errors when illegal syntax is used in KCL program. - -[KCL Compile Error (E2xxx)](#12-kcl-compile-error-e2xxx): The KCL may reports KCL compile errors when the KCL program conforms to the KCL syntax but does not conform to the KCL semantics. - -[KCL Runtime Error (E3xxx)](#13-kcl-runtime-error-e3xxx): The KCL may report KCL runtime errors when the virtual machine executing a KCL program that passes the compilation. - -[KCL Compile Warning (W2xxx)](#14-kcl-compile-warning-w2xxx): When the compiler compiles KCL programs and finds possible potential errors, such warnings will be reported by KCL. - -## 1.1 KCL Syntax Error (E1xxx) - -This section mainly includes KCL errors: - -| ewcode | KCL exception | messages | -| ------ | ------------------------------------------------------------------- | ----------------------- | -| E1001 | [InvalidSyntaxError](#111-invalidsyntaxerror-e1001) | Invalid syntax | -| E1002 | [KCLTabError](#112-kcltaberror-e1002) | Tab Error | -| E1003 | [KCLIndentationError](#113-kclindentationerrore1003) | Indentation Error | -| E1I37 | [IllegalArgumentSyntaxError](#114-illegalargumentsyntaxerror-e1i37) | Illegal argument syntax | - -### 1.1.1 InvalidSyntaxError (E1001) - -KCL will report `InvalidSyntaxError` when KCL has a syntax error. - -The `ewcode` of `InvalidSyntaxError` is `E1001`. - -For example: - -```python -a, b = 1, 2 # Multiple assign is illegal in KCL syntax -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> /syntax_error/general/multiple_assign/case0/main.k:1:2 - | -1 | a, b = 1, 2 # Multiple assign is illegal in KCL syntax - | ^ expected statement - | -``` - -Possible resolution: - -- Check and fix KCL syntax errors based on the KCL Language Standard - -### 1.1.2 KCLTabError - -KCL will report `KCLTabError` when KCL has a tab and white space syntax error. - -In KCL, it is forbidden to mix tabs and four spaces in one indentation block. And we recommend only using white spaces or tabs for indentation in the entire KCL project, don’t mix them. - -For example: - -```python -schema Person: - name: str # begin with a tab - age: int # begin with four white spaces, - # and four white spaces != tab in the env -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> File /syntax_error/tab/tab_error_0/main.k:6:5 - | -3 | age: int = 1 - | ^ inconsistent use of tabs and spaces in indentation - | -``` - -Possible resolution: - -- Only use a tab or four white spaces in KCL, do not mix them. - -### 1.1.3 KCLIndentationError - -KCL will report `KCLIndentationError` when KCL has an indentation syntax error. - -The KCL syntax includes indentation. A tab or four white spaces in KCL represents an indentation. The other cases will be regarded as syntax errors by KCL. - -For example: - -```python -schema Person: - name: str # a tab or four white spaces is legal. - age: int # three white spaces are illegal - info: str # two white spaces is illegal -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> /syntax_error/indent/indent_error_0/main.k:3:4 - | -3 | age: int # three white spaces are illegal - | ^ unindent 3 does not match any outer indentation level - | -``` - -Possible resolution: - -- Only use a tab or four white spaces in the KCL program for indentation. - -### 1.1.4 IllegalArgumentSyntaxError (E1I37) - -KCL will report `IllegalArgumentSyntaxError` when KCL has an illegal argument in KCL syntax. - -For example: - -```python -# Parameters without default values -# must be in front of parameters with default values. -a = option(type="list", default={"key": "value"}, "key1") -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> /option/type_convert_fail_2/main.k:3:57 - | -3 | a = option(type="list", default={"key": "value"}, "key1") - | ^ positional argument follows keyword argument - | -``` - -Possible resolution: - -```python -func(input_1, ..., input_n, param_with_key_1 = input_with_key_1, ..., param_with_key_n = input_with_key_n) -``` - -## 1.2 KCL Compile Error (E2xxx) - -This section mainly includes KCL errors: - -| ewcode | KCL exception | messages | -| ------ | ---------------------------------------------------------------------- | --------------------------------------------------- | -| E2F04 | [CannotFindModule](#121-cannotfindmodulee2f04) | Cannot find the module | -| E2F05 | [FailedLoadModule](#122-failedloadmodulee2f05) | Failed to load module | -| E2H13 | [UnKnownDecoratorError](#123-unknowndecoratorerrore2h13) | UnKnown decorator | -| E2H14 | [InvalidDecoratorTargetError](#124-invaliddecoratortargeterrore2h14) | Invalid Decorator Target | -| E2C15 | [MixinNamingError](#125-mixinnamingerrore2c15) | Illegal mixin naming | -| E2C16 | [MixinStructureIllegal](#126-mixinstructureillegale2c16) | Illegal mixin structure | -| E2B17 | [CannotAddMembersComplieError](#127-cannotaddmemberscomplieerrore2b17) | Cannot add members to a schema | -| E2B20 | [IndexSignatureError](#128-indexsignatureerrore2b20) | Invalid index signature | -| E2G22 | [TypeComplieError](#129-typecomplieerrore2g22) | The type got is inconsistent with the type expected | -| E2L23 | [CompileError](#1210-compileerrore2l23) | A complie error occurs during compiling | -| E2L25 | [KCLNameError](#1211-kclnameerrore2l25) | Name Error | -| E2L26 | [KCLValueError](#1212-kclvalueerrore2l26) | Value Error | -| E2L27 | [KCLKeyError](#1213-kclkeyerrore2l27) | Key Error | -| E2L28 | [UniqueKeyError](#1214-uniquekeyerrore2l28) | Unique key error | -| E2A29 | [KCLAttributeComplieError](#1215-kclattributecomplieerrore2a29) | Attribute error occurs during compiling | -| E2D32 | [MultiInheritError](#1216-multiinheriterrore2d32) | Multiple inheritance is illegal | -| E2D34 | [IllegalInheritError](#1217-illegalinheriterrore2d34) | Illegal inheritance | -| E2I36 | [IllegalArgumentComplieError](#1218-illegalargumentcomplieerrore2i36) | Illegal argument during compiling | -| E3L41 | [ImmutableCompileError](#1219-immutablecompileerror-e3l41) | Immutable variable is modified | - -### 1.2.1 CannotFindModule(E2F04) - -KCL will report `CannotFindModule` when KCL imports a module that does not exist. - -The `ewcode` of `CannotFindModule` is `E2F04`. - -For example: - -```python -import .some0.pkg1 as some00 # some0 not found in package - -Name1 = some00.Name # some0.pkg1.name -``` - -The KCL program will cause the following error message. - -```shell -error[E2F04]: CannotFindModule - --> import_abs_fail_0/app-main/main.k:1:1 - | -1 | import .some0.pkg1 as some00 # some0 not found in package - | Cannot find the module .some0.pkg1 - | -``` - -Possible resolution: - -- Add the import module file under the import path. - -### 1.2.2 FailedLoadModule(E2F05) - -KCL will report `FailedLoadModule` when an error occurs during loading a KCL external package. - -The `ewcode` of `FailedLoadModule` is `E2F05`. - -Possible resolution: - -- Check whether the module file is readable. -- Check whether the module file is a KCL file. - -### 1.2.3 UnKnownDecoratorError(E2H13) - -KCL will report `UnKnownDecoratorError` when an unknown decorator is used in KCL. - -The `ewcode` of `UnKnownDecoratorError` is `E2H13`. - -For example: - -```python -@err_deprecated # It is an unknown decorator -schema Person: - firstName: str = "John" - lastName: str - name: str - -JohnDoe = Person { - name: "deprecated" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> deprecated/unknown_fail_1/main.k:1:2 - | -1 | @err_deprecated # 这是一个非法的装饰器 - | ^ UnKnown decorator err_deprecated - | -``` - -Possible resolution: - -- Check whether the decorator exists. - -### 1.2.4 InvalidDecoratorTargetError(E2H14) - -KCL will report `InvalidDecoratorTargetError` when the target cannot be the target of the decorator. - -The `ewcode` of `InvalidDecoratorTargetError` is `E2H14`. - -Possible resolution: - -- Check whether the decorator in KCL is illegal. - -### 1.2.5 MixinNamingError(E2C15) - -KCL will report `MixinNamingError` when a mixin name does not end with 'Mixin'. - -The `ewcode` of `MixinNamingError` is `E2C15`. - -For example: - -```python -schema Person: - firstName: str - lastName: str - fullName: str - -schema Fullname: # It is a mixin, but 'Fullname' is not end with 'Mixin - fullName = "{} {}".format(firstName, lastName) - -schema Scholar(Person): - mixin [Fullname] - school: str - -JohnDoe = Scholar { - "firstName": "John", - "lastName": "Doe", - "fullName": "Doe Jon" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2D34]: IllegalInheritError - --> mixin/invalid_name_failure/main.k:10:12 - | -10 | mixin [Fullname] - | ^ illegal schema mixin object type 'Fullname' - | -``` - -Possible resolution: - -- If the schema is a mixin, then the name of the schema should end with Mixin. - -### 1.2.6 MixinStructureIllegal(E2C16) - -KCL will report `MixinStructureIllegal` when the KCL structure is illegal. - -The `ewcode` of `MixinStructureIllegal` is `E2C16`. - -Possible resolution: - -- Check the structure of schema as Mixin. - -### 1.2.7 CannotAddMembersComplieError(E2B17) - -KCL will report `CannotAddMembersComplieError` when members that are not in the schema are used. - -The `ewcode` of `CannotAddMembersComplieError` is `E2B17`. - -For example: - -```python -schema Girl: - gender: str = "female" - -alice = Girl { - "first": "alice", # "first" can not be found in schema Girl - "last": " Green", # "last" can not be found in schema Girl - "age": 10 # "age" can not be found in schema Girl -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:5:5 - | -5 | "first": "alice", - | ^ Cannot add member 'first' to schema 'Girl' - | - -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:6:5 - | -6 | "last": " Green", - | ^ Cannot add member 'last' to schema 'Girl' - | - -error[E2L23]: CompileError - --> /invalid/add_attribute/main.k:7:5 - | -7 | "age": 10 - | ^ Cannot add member 'age' to schema 'Girl' - | -``` - -Possible resolution: - -- Add the members to the schema. -- Remove the using of the members not exists - -### 1.2.8 IndexSignatureError(E2B20) - -The `ewcode` of `IndexSignatureError` is `E2B20`. - -KCL will report `IndexSignatureError` when: - -1. Multiple index signatures in one schema. - -For example: - -```python -schema Data: - [str]: str - [str]: int # Multiple index signatures in one schema. - -data = Data { - name: "test" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError ----> index_signature/fail_1/main.k:3:5 - | -3 | [str]: int - | 5 ^ only one index signature is allowed in the schema - | -``` - -Possible resolution: - -- Remove the extra index signature in the schema. - -2. The name of index signature attributes has the same name that conflicts with other attributes in the schema. - -For example: - -```python -schema Data: - name: str # name - [name: str]: str # the same name with the above attribute - -data = Data { - name: "test" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: IndexSignatureError - --> index_signature/fail_2/main.k:3:5 - | -3 | [name: str]: str # the same name with the above attribute - | ^ index signature attribute name 'name' cannot have the same name as schema attributes - | -``` - -Possible resolution: - -- Remove attributes or index signatures that have conflicts with the same name in the schema, or change their names. - -3. Schema index signature value type has conflicts with the instance of schema. - -For example: - -```python -schema Data: - [str]: int - -data = Data { - name: "test" # Conflict with [str]:int, "test" is a string. -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> index_signature/fail_3/main.k:5:5 - | -5 | name: "test" # Conflict with [str]:int, "test" is a string. - | ^ expected int, got str(test) - | -``` - -Possible resolution: - -- Check that the type of schema index signature is consistent with the attribute type in the schema instance. - -4. Schema index signature has conflicts with schema. - -For example: - -```python -schema Data: - count: int # got int - [str]: str # except str - -data = Data { - count: 1 -} -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: IndexSignatureError - --> index_signature/fail_4/main.k:2:5 - | -2 | count: int - | ^ the type 'int' of schema attribute 'count' does not meet the index signature definition [str]: str - | -``` - -Possible resolution: - -- Change schema for index signature or change index signature for schema. - -### 1.2.9 TypeComplieError(E2G22) - -KCL will report `TypeComplieError` when a type error occurs in compiling type check. - -The `ewcode` of `TypeComplieError` is `E2G22`. - -For example: - -```python -schema Person: - firstName: str - lastName: int - -JohnDoe = Person { - "firstName": "John", - "lastName": "Doe" # Type Error,lastName: int,“Doe” is a string. -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> type/type_fail_0/main.k:7:5 - | -7 | "lastName": "Doe" # Type Error,lastName: int,“Doe” is a string. - | ^ expected int, got str(Doe) - | - - --> type/type_fail_0/main.k:3:5 - | -3 | lastName: int - | ^ variable is defined here, its type is int, but got str(Doe) - | -``` - -Possible resolution: - -- Check that the type of value assigned to a variable is consistent with the type of the variable. - -### 1.2.10 CompileError(E2L23) - -The `ewcode` of `CompileError` is `E2L23`. - -KCL will report `CompileError` when: - -1. unsupport type union. - -For example: - -```python -_data = [1, 2, 3] -_data |= "value" -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> union/fail/fail_1/main.k:2:1 - | -2 | _data |= "value" - | ^ unsupported operand type(s) for |: '[int]' and 'str(value)' - | -``` - -Possible resolution: - -1. unsupported operand type. - -For example: - -```python -a = None -b = 1 + None # Unsupport operand type + for int and None -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> operator/operator_fail_0/main.k:2:5 - | -2 | b = 1 + None # Unsupport operand type + for int and None - | ^ unsupported operand type(s) for +: 'int(1)' and 'NoneType' - | -``` - -Possible resolution: - -- Adjust the operator so that it supports both operand types. -- Adjust the operands so that they conform to the constraints of the operator at the same time. - -1. variable is not defined. - -For example: - -```python -a = 1 -b = "${c + 1}" # 'c' is not defined -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> var_not_define_fail_0/main.k:2:8 - | -2 | b = "${c + 1}" # 'c' is not defined - | ^ name 'c' is not defined - | -``` - -Possible resolution: - -- Define undefined variables. -- Remove the undefined variable from the expression. - -1. invalid assign expression. - -For example: - -```python -# pkg.k -a = 1 - -# main.k -import pkg -pkg.a |= 2 -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> pkg_inplace_modify_1/main.k:3:1 - | -6 | pkg |= 2 - | ^ unsupported operand type(s) for |: 'module 'pkg'' and 'int(2)' - | -``` - -Possible resolution: - -- Check the assignment expression. - -1. invalid string expression. - -For example: - -```python -a = 1 -b = "${b = a + 1}" # Invalid string interpolation expression -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> invalid_format_value_fail_0/main.k:2:5 - | -2 | b = "${b = a + 1}" - | 5 ^ invalid string interpolation expression 'b = a + 1' - | -``` - -Possible resolution: - -- Check the string expression. - -1. invalid loop variable. - -For example: - -```python -data = {"key1": "value1", "key2": "value2"} -dataLoop = [i for i, j, k in data] # the number of loop variables can only be 1 or 2 -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> dict/invalid_loop_var_fail_0/main.k:2:25 - | -2 | dataLoop = [i for i, j, k in data] # the number of loop variables can only be 1 or 2 - | ^ the number of loop variables is 3, which can only be 1 or 2 - | -``` - -### 1.2.11 KCLNameError(E2L25) - -KCL will report `KCLNameError` when a name error occurs in compiling. - -The `ewcode` of `KCLNameError` is `E2L25`. - -### 1.2.12 KCLValueError(E2L26) - -KCL will report `KCLValueError` will be raised when a value error occurs in compiling. - -The `ewcode` of `KCLValueError` is `E2L25`. - -### 1.2.13 KCLKeyError(E2L27) - -KCL will report `KCLKeyError` will be raised when a key error occurs in compiling. - -The `ewcode` of `KCLKeyError` is `E2L25`. - -### 1.2.14 UniqueKeyError(E2L28) - -KCL will report `UniqueKeyError` when duplicate names appear in the KCL code. - -The `ewcode` of `UniqueKeyError` is `E2L28`. - -For example: - -```python -schema Person: - name: str = "kcl" - age: int = 1 - -schema Person: - aa: int - -x0 = Person{} -x1 = Person{age:101} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L28]: UniqueKeyError - --> /schema/same_name/main.k:5:8 - | -5 | schema Person: - | ^ Unique key error name 'Person' - | - - --> /schema/same_name/main.k:1:8 - | -1 | schema Person: - | ^ The variable 'Person' is declared here - | -``` - -Possible resolution: - -- Check if the name with error has been used. - -### 1.2.15 KCLAttributeComplieError(E2A29) - -KCL will report `KCLAttributeComplieError` when KCL has an illegal attribute in the schema. - -The `ewcode` of `KCLAttributeComplieError` is `E2A29`. - -For example: - -```python -# pkg -schema A: - field_A: str - -# main -import pkg as p - -a = p.D + 1 -``` - -The KCL program will cause the following error message. - -```shell -error[E2G22]: TypeError - --> /import/module/no_module_attr_fail_0/main.k:4:5 - | -4 | a = p.D + 1 - | ^ module 'pkg' has no attribute D - | -``` - -Possible resolution: - -- Check for the existence of the schema attribute when using it. - -### 1.2.16 MultiInheritError(E2D32) - -KCL will report `MultiInheritError` when multiple inheritance appears in the schema. - -The `ewcode` of `MultiInheritError` is `E2D32`. - -For example: - -```python -schema Person: - firstName: str - lastName: str - -schema KnowledgeMixin: - firstName: int - subject: str - -schema Scholar(KnowledgeMixin, Person): - school: str -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: InvalidSyntax - --> /schema/inherit/multi_inherit_fail_1/main.k:9:30 - | -9 | schema Scholar(KnowledgeMixin, Person): - | ^ expected one of [")"] got , - | -``` - -Possible resolution: - -- Check the inheritance structure of the program, and multi-inheritance is not supported in KCL. - -### 1.2.17 IllegalInheritError(E2D34) - -KCL will report `IllegalInheritError` when an illegal inheritance occurs in the schema. - -The `ewcode` of `IllegalInheritError` is `E2D34`. - -For example: - -```python -schema FullnameMixin: - fullName = "{} {}".format(firstName, lastName) - -schema Scholar(FullnameMixin): # mixin inheritance is illegal - school: str -``` - -The KCL program will cause the following error message. - -```shell -error[E2D34]: IllegalInheritError - --> /schema/inherit/inherit_mixin_fail/main.k:4:16 - | -4 | schema Scholar(FullnameMixin): - | ^ invalid schema inherit object type, expect schema, got 'FullnameMixin' - | -``` - -Possible resolution: - -- Schema supports single inheritance of schema in KCL. - -### 1.2.18 IllegalArgumentComplieError(E2I36) - -KCL will report `IllegalArgumentComplieError` when the argument of option in KCL is illegal. - -The `ewcode` of `IllegalArgumentComplieError` is `E2I36`. -For example: - -```python -a = option("key") - -# kcl main.k -D key=value= -# key=value= is an illegal expression -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError -Invalid value for top level arguments -``` - -Possible resolution: - -- Check whether the KCL option arguments are legal. - -### 1.2.19 ImmutableCompileError (E3L41) - -KCL will report `ImmutableCompileError` when the value of the immutable variable changes. - -The `ewcode` of `ImmutableCompileError` is `E3L41`. - -For example: - -```python -a = 2147483646 -a += 1 -``` - -The KCL program will cause the following error message. - -```shell -error[E1001]: ImmutableError - --> augment_assign/main.k:2:1 - | -2 | a += 1 - | ^ Immutable variable 'a' is modified during compiling - | - - --> augment_assign/main.k:1:1 - | -1 | a = 2147483646 - | ^ The variable 'a' is declared here firstly - | -note: change the variable name to '_a' to make it mutable -``` - -Possible resolution: - -- Set immutable variables changed to private or remove immutable variables. - -## 1.3 KCL Runtime Error (E3xxx) - -This section mainly includes KCL errors: - -| ewcode | KCL exception | messages | -| ------ | ---------------------------------------------------------------------- | --------------------------------------------------- | -| E3F06 | [RecursiveLoad](#131-recursiveload-e3f06) | Recursively loading module | -| E3K04 | [FloatOverflow](#132-floatoverflow-e3k04) | Float overflow | -| E3K09 | [IntOverflow](#133-intoverflow-e3k09) | Integer overflow | -| E3N11 | [DeprecatedError](#134-deprecatederror-e3n11) | Deprecated error | -| E3A30 | [KCLAttributeRuntimeError](#135-kclattributeruntimeerror-e3a30) | Attribute error occurs at runtime | -| E3G21 | [TypeRuntimeError](#136-typeruntimeerror-e3g21) | The type got is inconsistent with the type expected | -| E3B17 | [SchemaCheckFailure](#137-schemacheckfailure-e3b17) | Schema check is failed to check condition | -| E3B19 | [CannotAddMembersRuntimeError](#138-cannotaddmembersruntimeerrore3b19) | Cannot add members to a schema | -| E3M38 | [EvaluationError](#139-evaluationerrore3m38) | Evaluation failure | -| E3M39 | [InvalidFormatSpec](#1310-invalidformatspec-e3m39) | Invalid format specification | -| E3M40 | [KCLAssertionError](#1311-kclassertionerror-e3m40) | Assertion failure | -| E3M44 | [ImmutableRuntimeError](#1312-immutableruntimeerror-e3m44) | Immutable variable is modified | -| E2D33 | [CycleInheritError](#1313-cycleinheriterror-e2d33) | Cycle Inheritance is illegal | -| E3M42 | [KCLRecursionError](#1314-kclrecursionerror-e3m42) | Recursively reference | - -### 1.3.1 RecursiveLoad (E3F06) - -KCL will report `RecursiveLoad` when a cycle import of external packages occurs in KCL. - -The `ewcode` of `RecursiveLoad` is `E2F06`. - -For example: - -```python -# module.k -import main # module.k imports main.k - -print('module') - -# main.k -import module # main.k imports module.k - -print('main') -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /import/recursive_import_fail/main.k:4 - | -2 | import module # main.k imports module.k - | ^ There is a circular import reference between module main and module - | -``` - -Possible resolution: - -- Check whether there is a circle import in KCL. - -### 1.3.2 FloatOverflow (E3K04) - -KCL will report `FloatOverflow` when a floating-point number overflows in KCL. - -The `ewcode` of `FloatOverflow` is `E3K04`. - -For example: - -```python -uplimit = 3.402823466e+39 -epsilon = 2.220446049250313e-16 -a = uplimit * (1 + epsilon) - -# kcl main.k -r -d -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /range_check_float/overflow/number_0/main.k:3:1 - | -3 | a = uplimit * (1 + epsilon) - | 3.4028234660000003e+39: A 32-bit floating point number overflow - | -``` - -Possible resolution: - -- Check whether the value of the float is the float range supported by KCL. - -### 1.3.3 IntOverflow (E3K09) - -KCL will report `IntOverflow` when an integer number overflows in KCL. - -The `ewcode` of `IntOverflow` is `E3K09`. - -For example: - -```python -_a = 9223372036854775807 -_a += 1 - -# kcl test.k -d -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /range_check_int/augment_assign_fail_1/main.k:2:1 - | -2 | _a += 1 - | 9223372036854775808: A 64 bit integer overflow - | -``` - -Possible resolution: - -- Check whether the value of the integer is the integer range supported by KCL. - -### 1.3.4 DeprecatedError (E3N11) - -KCL will report `DeprecatedError` when a deprecated variable is used and the strict is True. - -The `ewcode` of `DeprecatedError` is `E3N11`. - -For example: - -```python -schema Person: - firstName: str = "John" - lastName: str - @deprecated(version="1.16", reason="use firstName and lastName instead", strict=True) - name: str - -JohnDoe = Person { - name: "deprecated" # name is deprecated and strict is True -} -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /range_check_float/overflow/number_0/main.k:7:1 - | -7 | JohnDoe = Person { - | name was deprecated since version 1.16, use firstName and lastName instead - | -``` - -Possible resolution: - -- When strict is set to True, using deprecated code will cause an error and stop KCL. -- You can set the strict to False which will cause a warning insteads of an error. -- Adjust the code without using deprecated code. - -### 1.3.5 KCLAttributeRuntimeError (E3A30) - -KCL will report `KCLAttributeRuntimeError`, if an error occurs during dynamically accessing schema attributes through variables at runtime. - -The `ewcode` of `KCLAttributeRuntimeError` is `E3A30`. - -For example: - -```python -import math - -a = math.err_func(1) # err_func is not found in math -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /import/module/no_module_attr_fail_2/main.k:3:5 - | -3 | a = math.err_func(1) # err_func is not found in math - | ^ module 'math' has no attribute err_func - | -``` - -Possible resolution: - -- Check whether the attributes of schema are correct. - -### 1.3.6 TypeRuntimeError (E3G21) - -KCL will report `TypeRuntimeError` when an type error occurs in the runtime type check. - -The `ewcode` of `TypeRuntimeError` is `E3G21`. - -For example: - -```python -schema Person: - name: str = "Alice" - -_personA = Person {} -_personA |= {"name" = 123.0} # name: str = "Alice" -personA = _personA -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /fail/fail_4/main.k:2:1 - | -2 | name: str = "Alice" - | expect str, got float - | -``` - -Possible resolution: - -- Stop the wrong type union or adjust to the type union supported by KCL. - -### 1.3.7 SchemaCheckFailure (E3B17) - -KCL will report `SchemaCheckFailure` when the schema check conditions are not met. - -The `ewcode` of `SchemaCheckFailure` is `E3B17`. - -For example: - -```python -schema Person: - lastName: str - age: int - check: - age < 140, "age is too large" - -JohnDoe = Person { - "lastName": "Doe", - "age": 1000 # the check condition: age < 140 -} -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /check_block/check_block_fail_1/main.k:7:11 - | -7 | JohnDoe = Person { - | ^ Instance check failed - | - - --> /check_block/check_block_fail_1/main.k:5:1 - | -5 | age < 140, "age is too large" - | Check failed on the condition - | -``` - -Possible resolution: - -- Check whether the attributes of schema can satisfy the conditions in check. - -### 1.3.8 CannotAddMembersRuntimeError(E3B19) - -KCL will report `CannotAddMembersRuntimeError` when members that are not in the schema are used. - -The `ewcode` of `CannotAddMembersRuntimeError` is `E3B19`. - -For example: - -```python -schema Name: - name: str - -schema Person: - name: Name - -person = Person { - name.err_name: "Alice" # err_name is not found in schema Name -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /nest_var/nest_var_fail_1/main.k:8:5 - | -8 | name.err_name: "Alice" # err_name is not found in schema Name - | ^ Cannot add member 'err_name' to schema 'Name' - | -``` - -Possible resolution: - -- Add a non-existent member to the schema. -- Access members that exist in the schema. - -### 1.3.9 EvaluationError(E3M38) - -KCL will report `EvaluationError` when an illegal evaluation occurs in KCL. - -The `ewcode` of `EvaluationError` is `E3M38`. - -For example: - -```python -_list1 = [1, 2, 3] # _list1 is a variable, and its type can only be known at runtime -_list2 = None # _list1 is a variable, and its type can only be known at runtime - -result2 = _list1 + _list2 # list + NoneType is illegal -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /datatype/list/add_None_fail/main.k:1 - | -4 | result2 = _list1 + _list2 # list + NoneType is illegal - | can only concatenate list (not "NoneType") to list - | -``` - -Possible resolution: - -- Check whether the evaluation of the expression is legal. - -### 1.3.10 InvalidFormatSpec (E3M39) - -KCL will report `InvalidFormatSpec` when an illegal string format appears in KCL. - -The `ewcode` of `InvalidFormatSpec` is `E3M39`. - -For example: - -```python -a = 1 -b = 1 -data = "${a: #js}" + " $$ " # #js is illegal string -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /datatype/str_interpolation/invalid_format_spec_fail_0/main.k:3 - | -3 | data = "${a: #js}" + " $$ " # #js is illegal string - | ^ #js is a invalid format spec - | -``` - -Possible resolution: - -- Adjust illegal String to String supported by KCL standards. - -### 1.3.11 KCLAssertionError (E3M40) - -KCL will report `KCLAssertionError` when assert False occurs in KCL. - -The `ewcode` of `KCLAssertionError` is `E3M40`. - -For example: - -```python -assert False -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /assert/invalid/fail_0/main.k:1 - | -1 | assert False - | - | -``` - -Possible resolution: - -- Check the condition of Assert, and when the Assert condition is False, such an error occurs, removing the Assert statement or changing the condition to True. - -### 1.3.12 ImmutableRuntimeError (E3M44) - -KCL will report `ImmutableRuntimeError` when the value of the immutable variable changes. - -The `ewcode` of `ImmutableRuntimeError` is `E3M44`. - -For example: - -```python -schema Person: - final firstName : str - lastName : str - -schema Scholar(Person): - firstName = "CBA" - -scholar = Scholar { - "firstName": "ABC" # firstName in schema Person is final. -} -``` - -The KCL program will cause the following error message. - -```shell -error[E3M38]: EvaluationError - --> /final/fail_lazy_init_0/main.k:8:1 - | -8 | scholar = Scholar { - | attribute 'lastName' of Scholar is required and can't be None or Undefined - | -``` - -Possible resolution: - -- Check if the final variables have been assigned or other changes affect the values of the final variables. - -### 1.3.13 CycleInheritError (E2D33) - -KCL will report `CycleInheritError` when circle inheritance appeared in the schema. - -The `ewcode` of `CycleInheritError` is `E2D33`. - -For example: - -```python -schema Parent(Son): - parent_field: str - -schema Son(GrandSon): - son_field: str - -schema GrandSon(Parent): - grandson_field: str - -parent = Parent { - parent_field: "" -} -``` - -The KCL program will cause the following error message. - -```shell -error[E2L23]: CompileError - --> /inherit/cycle_inherit_fail_1/main.k:7:8 - | -7 | schema GrandSon(Parent): - | ^ There is a circular reference between schema GrandSon and Parent - | -``` - -Possible resolution: - -- Check schema inheritance relationship to avoid A inheritance B and B inheritance A at the same time. - -### 1.3.14 KCLRecursionError (E3M42) - -KCL will report `KCLRecursionError` when a circle reference appears in the program. - -The `ewcode` of `KCLRecursionError` is `E3M42`. - -For example: - -```python -schema Parent(Son): - parent_field: str - son: Son = Son { # Parent has attribute Son - parent: Parent { - parent_field: "123" - } - } - -schema Son: - son_field: str - parent: Parent = Parent { # Son has attribute Parent - son: Son { - son_field: "123" - } - } - -parent = Parent { - parent_field: "", -} -``` - -The KCL program will cause the following error message. - -```shell -thread 'main' has overflowed its stack -fatal runtime error: stack overflow -``` - -Possible resolution: - -- Check the members in the schema to avoid the problem of circle references. - -## 1.4 KCL Compile Warning (W2xxx) - -This section mainly includes KCL warnings: - -| ewcode | KCL exception | messages | -| ------ | ------------------------------------------------- | ------------------ | -| W2K04 | [FloatUnderflow](#141-floatunderflow-w2k04) | Float underflow | -| W2P10 | [InvalidDocstring](#142-invaliddocstring-w2p10) | Invalid docstring | -| W2N12 | [DeprecatedWarning](#143-deprecatedwarning-w2n12) | Deprecated warning | - -### 1.4.1 FloatUnderflow (W2K04) - -KCL will report `FloatUnderflow` when a floating-point number underflows in KCL. - -The `ewcode` of `FloatUnderflow` is `W2K08`. - -Possible resolution: - -- Check whether the value of the float number is in the range supported by KCL. - -### 1.4.2 InvalidDocstring (W2P10) - -KCL will report `InvalidDocstring` when a string is illegal in KCL doc. - -The `ewcode` of `InvalidDocstring` is `W2P10`. - -Possible resolution: - -- Please write doc according to KCL standards. - -### 1.4.3 DeprecatedWarning (W2N12) - -KCL will report `DeprecatedWarning` when a deprecated variable is used and the strict is False. - -The `ewcode` of `DeprecatedWarning` is `W2N12`. - -Possible resolution: - -- Try not to use deprecated code. If the strict is True, KCL will output the error and stop running. diff --git a/versioned_docs/version-0.5.5/reference/lang/error/index.md b/versioned_docs/version-0.5.5/reference/lang/error/index.md deleted file mode 100644 index 15fbda6f..00000000 --- a/versioned_docs/version-0.5.5/reference/lang/error/index.md +++ /dev/null @@ -1 +0,0 @@ -# Errors and Warnings diff --git a/versioned_docs/version-0.5.5/reference/lang/spec/_category_.json b/versioned_docs/version-0.5.5/reference/lang/spec/_category_.json deleted file mode 100644 index 7b24faae..00000000 --- a/versioned_docs/version-0.5.5/reference/lang/spec/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Spec", - "position": 3 -} diff --git a/versioned_docs/version-0.5.5/reference/lang/spec/codestyle.md b/versioned_docs/version-0.5.5/reference/lang/spec/codestyle.md deleted file mode 100644 index dd40925e..00000000 --- a/versioned_docs/version-0.5.5/reference/lang/spec/codestyle.md +++ /dev/null @@ -1,608 +0,0 @@ ---- -title: "Code Style" -linkTitle: "Code Style" -type: "docs" -weight: 2 -description: Code Style ---- - -## Introduction - -This document gives the KCL code style conventions. Good code style can play a vital role in the development and maintenance of the project. We can learn the KCL code style by referring to the full text of the description and sample codes, and use KCL format and lint tools to help coding. - -## Source File Encoding - -KCL file encoding should always use **UTF-8**. - -## Code Layout - -### Indentation - -Use **4 spaces** per indentation level such as in the schema statement and if statement. - -```python -schema PersonA: - name: str # non-recommended - age: int - -schema PersonB: - name: str # recommended - age: int - -if True: - a = 1 # recommended -elif True: - b = 2 # non-recommended -else: - c = 3 # non-recommended -``` - -The closing brace/bracket/parenthesis on multiline constructs should line up under **first character** of the line that starts the multiline construct, as in: - -```python -# valid and recommended -my_list = [ - 1, 2, 3, - 4, 5, 6, -] -``` - -```python -# invalid -my_list = [ - 1, 2, 3, - 4, 5, 6, - ] -``` - -### Tabs or Spaces - -- Spaces are the preferred indentation method. -- Tabs should be used solely to remain consistent with code that is already indented with tabs. - -KCL disallows mixing the use of tabs and spaces for indentation and an error will be reported during the compile time. - -### Blank Lines - -- Surround top-level schema definitions with one blank line. -- Keep at most one blank line between two statements and remove redundant blank lines. -- Remove extra blank characters at the end of the line -- Remove extra blank characters in a blank line. -- There is no blank line in the header of the file, start writing from the first line. -- Only one blank line will be left at the end of the KCL file. - -```python -# Remove blank lines in the file header -a = 1 # Remove white space at the end of the line -# Keep at most one blank line between two statements - -b = 2 -# Only leave one blank line at the end of the file - -``` - -### Inline Expressions - -Write indentation of KCL `if`, `elif`, `else` and other conditions on different lines. - -```python -if True: print("") # non-recommended - -if True: # recommended - print("") -``` - -### Line Break and Continuation lines - -- For long expressions, use the line continuation symbol `\` and keep the left end of multiple expressions aligned. -- The 4-space rule is optional for continuation lines. - -```python -anotherString = "Too long expression " + \ - "Too long expression " # non-recommended - -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " # recommended -``` - -### When to Use Trailing Commas - -- Always use trailing commas. - -### Maximum Line Length - -- The general recommendation is **80 characters** but not absolute. - -### Symbol Break White Space - -Try to keep the spaces between different symbols, but not too many, usually one is good. - -```python -a = 1 # recommended -b = 1 + 2 # non-recommended -``` - -### Whitespace in Expressions and Statements - -Avoid extraneous whitespace in the following situations: - -- The parentheses `()`, brackets `[]` and braces `{}` in the expression have no spaces inside. - -```python -a = (1 + 2) # recommended -b = ( 1 + 2 ) # non-recommended - -c = [1, 2, 3] # recommended -d = [ 1, 2, 3 ] # non-recommended - -e = {key = "value"} # recommended -f = { key = "value" } # non-recommended -``` - -```python -spam(ham[1], {eggs = 2}) # recommended -spam( ham[ 1 ], { eggs = 2 } ) # non-recommended -``` - -- Between a trailing comma and a following close parenthesis. - -```python -foo = [0,] # recommended -bar = [0, ] # non-recommended -``` - -- Immediately before the open parenthesis that starts the argument list of a function call. - -```python -print(1) # recommended -print (1) # non-recommended -``` - -- Immediately before the open parenthesis that starts indexing or slicing. - -```python -dct = {key = "value"} -lst = [1, 2, 3] - -a = dct['key'] # recommended -b = dct ['key'] # non-recommended - -c = lst[0] # recommended -d = lst [1] # non-recommended -``` - -- More than one space around an assignment `=` (or other) operator to align it with another. - -```python -# recommended: -x = 1 -y = 2 -long_variable = 3 -``` - -```python -# non-recommended: -x = 1 -y = 2 -long_variable = 3 -``` - -- Always surround these binary operators with a single space on either side: assignment (`=`), augmented assignment (`+=`, `-=`, etc.), comparisons (`==`, `<`, `>`, `!=`, `<=`, `>=`, `in`, `not in`, `is`, `is not`), booleans (`and`, `or`, `not`). - -```python -# recommended: -i = i + 1 -submitted += 1 -x = x * 2 - 1 -hypot2 = x * x + y * y -c = (a + b) * (a - b) -``` - -```python -# non-recommended: -i = i+1 -submitted+=1 -x = x*2 - 1 -hypot2 = x*x + y*y -c = (a+b) * (a-b) -``` - -- Break one blank line between different statements e.g., import, schema and expression statements. - -```python -import math -import net - -schema Person: - name: str - -person = Person { - name = "Alice" -} -``` - -- Compound statements (multiple statements on the same line) are generally discouraged - -```python -# recommended: -if foo == 'blah': - do_blah_thing() -do_one() -do_two() -do_three() -``` - -```python -# non-recommended: -if foo == 'blah': do_blah_thing() -do_one(); do_two(); do_three() -``` - -## Naming Conventions - -### Naming Styles - -The following naming styles are commonly distinguished: - -- `b` (single lowercase letter) -- `B` (single uppercase letter) -- `lowercase` -- `lower_case_with_underscores` -- `UPPERCASE` -- `UPPER_CASE_WITH_UNDERSCORES` -- `CapitalizedWords` (capitalize all letters of the acronym in `CapitalizedWords` e.g., `HTTPServer`.) -- `mixedCase` (differs from `CapitalizedWords` by initial lowercase character) -- `Capitalized_Words_With_Underscores` (ugly and non-recommended) - -### Names to Avoid - -Never use the characters 'l' (lowercase letter el), 'O' (uppercase letter oh), or 'I' (uppercase letter eye) as single-character variable names. - -### Package and Module Names - -Package and module names should have short, all-lowercase names. - -### Schema Names - -Schema names should normally use the `CapWords` convention. - -### Constants - -Constants are usually defined on a module level and written in all capital letters with underscores separating words such as `MAX_OVERFLOW` and `TOTAL`. - -## Import - -- Imports should usually be on separate lines. -- Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants. -- Imports should be grouped in the following order and we should put a blank line between each group of imports. - 1. Standard library imports. - 2. Related third party plugin imports. - 3. Local application/library specific imports. -- Use an alias when we import a package name with a relatively long path. -- Leave only one space between the Import keyword and the package name. - -```python -import net # recommended -import math # non-recommended - -import ..pkg.internal_pkg as alias_pkg # recommended -``` - -## Comments - -- Comments should be complete sentences. The first word should be capitalized unless it is an identifier that begins with a lower-case letter (never alter the case of identifiers!). -- Block comments generally consist of one or more paragraphs built out of complete sentences, with each sentence ending in a period. -- Use two spaces after a sentence-ending period in multi-sentence comments, except after the final sentence. - -### Block Comments - -Block comments generally apply to some (or all) code that follows them, and are indented to the same level as that code. Each line of a block comment starts with a `#` and **a single space**(unless it is indented text inside the comment). - -Paragraphs inside a block comment are separated by a line containing a single `#`. - -```python -# This is a block comment -a = 1 -``` - -### Inline Comments - -Use inline comments sparingly. - -An inline comment is a comment on the same line as a statement. Inline comments should be separated by **at least two spaces** from the statement. They should start with a `#` and **a single space**. - -```python -a = 1 # This is an inline comment -``` - -### Documentation Strings - -Write doc strings for all public schema and schema attributes. - -```python -schema Person: - """ - Person schema doc string - """ - - name: str = "Alice" -``` - -## String - -- Single-quoted strings and double-quoted strings are the same in KCL. -- Use double-quoted string with lowercase prefix -- For triple-quoted strings, always use double quote characters to be consistent with the docstring convention. -- When a string contains single or double quote characters, use the other one to avoid backslashes in the string. - -```python -strC = "'123'" # recommended -strD = "\"123\"" # non-recommended -``` - -## Number - -- Use lowercase for the prefix of non-decimal numbers, and use uppercase for the number itself. - -```python -foo = 0xAB # recommended -bar = 0Xab # non-recommended -``` - -## Operators - -### Binary Operators - -- Leave only one space before and after the assignment `=`. -- Leave only one space before and after the binary operator in the expression. - -```python -a = 1 # recommended -b=2 # non-recommended -c= 3 # non-recommended -d =4 # non-recommended - -_value = (1 + 2 * 3) # recommended -_value = (1+2*3) # non-recommended -``` - -### Unary Operators - -- There is only no space after unary operators e.g., `~`, `+` and `-`. - -```python -_value = 1 + -2 * ~3 # recommended -_value = 1+ - 2 * ~ 3 # non-recommended -``` - -- There is no space after `**` and `*` in the dict/list deduction expressions and argument expressions. - -```python -_list = [1, 2, 3] -_list = [*_list, [4, 5 ,6]] # recommended -_list = [* _list, [4, 5 ,6]] # non-recommended - -_dict = {**{k = "v"}, **{k = "v"}} # recommended -_dict = {** {k = "v"}, ** {k = "v"}} # non-recommended -``` - -- Use `is not` operator rather than `not ... is`. - -```python -# recommended: -if foo is not None: - a = 1 -``` - -```python -# non-recommended: -if not foo is None: - a = 1 -``` - -## Dict - -- There is no space before the colon `:` at the instantiation of KCL dict and schema config, and a space after the colon `:`. - -```python -d1 = {labels: {k1 = "v1"}} # recommended -d2 = {labels : {k1 = "v1"}} # non-recommended -d3 = {labels :{k1 = "v1"}} # non-recommended -``` - -- Always surround the override attribute operator `=` and the insert attribute operator `+=` with a single space on either sid. - -```python -d1 = {key = "value"} # recommended -d2 = {key= "value"} # non-recommended -d3 = {key ="value"} # non-recommended -``` - -```python -d1 = {key += [0, 1, 2]} # recommended -d2 = {key+= [0, 1, 2]} # non-recommended -d3 = {key +=[0, 1, 2]} # non-recommended -``` - -- Remove all commas at the end of the line in the KCL multiline dict because the end commas of each line are optional. - -```python -d = { - key1 = "value1" - key2 = "value2" - key3 = "value3" - key4 = "value4" -} -``` - -## List - -- Keep only **one space** after the comma `,` separating elements in the list - -```python -a = [1, 2, 3] # recommended -b = [1,2,3] # non-recommended -``` - -- Keep only **one space** before and after the comprehension expression token `for` and `in` in the dict and list. - -```python -a = [i for i in range(10)] # recommended -b = [i for i in range(10)] # non-recommended -``` - -## Slice - -- Keep the same number of spaces before and after the colon `:` of the list slice. - -```python -l = [1, 2, 3] -a = l[0:2] # recommended -b = l[0 : 2] # non-recommended -c = l[0: 2] # non-recommended - -d = l[0 + 0 : 1 + 1] # recommended -e = l[0 + 0:1 + 1] # non-recommended -``` - -## Schema - -- Leave only one space before and after the schema attribute assignment `=`. -- Always add a doc string to a schema, which is a good programming habit. - -```python -schema Person: - """ - Schema doc string - """ - name: str = "Alice" # recommended - age : int=12 # non-recommended - -person = Person {} -``` - -- Keep **no spaces** around the schema inheritance operator `()` - -```python -schema Base: - name: str - -schema Person(Base): # recommended - age: int - -schema Schema ( Base ): # non-recommended - age: int -``` - -- Keep **only one space** between the brackets and the schema name of the config at schema instantiation. - -```python -schema Base: - name: str - -schema Person(Base): - age: int - -personA = Person{} # non-recommended -personB = Person {} # recommended -``` - -- Keep **only one space** between the **mixin** keyword and the following `[]` operator - -```python -schema NameMixin: - name: str = "name" - -schema Person: - mixin [NameMixin] # non-recommended - age: int - -schema Parent: - mixin [NameMixin] # recommended - age: int -``` - -### Attribute Annotations - -- Annotations for schema attributes should have a single space after the colon `:` and no space before the colon `:`. - -```python -# recommended: -schema Person: - name: str # No space before the colon `:` - age: int = 18 # Spaces around assignment`=` -``` - -```python -# non-recommended: -schema Person: - codeA:int # No space after the colon `:` - codeB : int # Space before the colon `:` - name: str="Alice" # No spaces around assignment`=` -``` - -- There are no spaces around the colon `:` in the dict type annotation. - -```python -schema Person: - labels: {str:str} # recommended - keyValues: {str : str} # non-recommended -``` - -### Arguments - -- There are no spaces around the assignment `=` in the function/schema/decorator keyword arguments (kwargs). - -```python -schema Person[nameVar]: - # Decorator kwargs - @deprecated(strict=False) # recommended - name: str = nameVar - - @deprecated(strict = False) # non-recommended - age: int - -# Schema kwargs -personA = Person(nameVar="Alice") {} # recommended -personB = Person(nameVar = "Bob") {} # non-recommended - -# Function kwargs -print("", end='') # recommended -print("", end = '') # non-recommended -``` - -## Keywords - -- Only one space is usually reserved around the keyword, such as `schema`, `mixin`, `is` and `not`, etc. - -```python -schema NameMixin: - check: - name not None - -schema Person: - """ - Person schema definition - """ - mixin [NameMixin] - - name: str = "Alice" - age: int - -person = Person { - age = 18 -} -``` - -## Function - -- There are no spaces around the function/package select operator `.` -- There are no spaces between the function name and the parentheses `()`. - -```python -import math - -print(math.log(10)) # recommended -print( math . log (10)) # non-recommended -``` diff --git a/versioned_docs/version-0.5.5/reference/lang/spec/datatypes.md b/versioned_docs/version-0.5.5/reference/lang/spec/datatypes.md deleted file mode 100644 index ef7ea71a..00000000 --- a/versioned_docs/version-0.5.5/reference/lang/spec/datatypes.md +++ /dev/null @@ -1,452 +0,0 @@ ---- -title: "Data Types" -linkTitle: "Data Types" -type: "docs" -weight: 2 -description: Data Types ---- - -## Syntax - -### Bool - -Boolean values are the two constant objects `False` and `True`. They are used to represent truth values (although other values can also be considered false or true). The built-in function bool() can be used to convert any value to a Boolean, if the value can be interpreted as a truth value. - -### Int - -Int, or integer, is an arbitrarily sized integer, positive or negative, without decimals, of 64 binary digits precision(-9,223,372,036,854,775,808~9,223,372,036,854,775,807). Int is created by int literals or as the result of built-in functions and operators. Unadorned integer literals (including `hex`, `octal` and `binary` numbers) yield integers. The constructor int() can be used to produce int of a specific type. - -Besides, integer literals may have an `SI` or `IEC` multiplier. - -- `SI`: General integer or fixed-point number form: `P`, `T`, `G`, `M`, `K`, `k`, `m`, `u`, `n`. -- `IEC`: Corresponding power of 2: `Pi`, `Ti`, `Gi`, `Mi`, `Ki`. - -```python -a = 1 # positive integer: 1 -b = -1 # negative integer: -1 -c = 0x10 # hexadecimal literal: 16 -d = 0o10 # octal literal: 8, or the form `010` -e = 0b10 # binary literal: 2 -f = 10Ki # integer literal with IEC multiplier: 10240 -g = 1M # integer literal with SI multiplier: 1000000 -h = int("10") # int constructor: 10 -i = int("10Ki") # int constructor with multiplier: 10240 -``` - -Notes: - -- Report an error if unable to represent an integer value precisely. - -### Float - -Float, floating-point, approximation to real numbers, positive or negative, containing one or more decimals, of 64 bit IEEE 754 floats. The constructor float() can be used to produce int of a specific type. - -```python -a = 1.10 -b = 1.0 -c = -35.59 -d = 32.3+e18 -f = -90. -g = -32.54e100 -h = 70.2-E12 -i = float("112") # float constructor -``` - -Notes: - -- Report an error if unable to represent a floating-point value due to overflow -- Report a warning if unable to represent a floating-point value due to underflow. Round to the nearest representable value if unable to represent a floating-point value due to limits on precision. These requirements apply to the result of any expression except for built-in functions for which an unusual loss of precision must be explicitly documented. - -#### None - -In KCL, `None` can indicate that the value of the object is empty, which is similar to `nil` in Go or `null` in Java, and corresponds to `null` in YAML and JSON. - -```python -a = None -b = [1, 2, None] -c = {"key1" = "value1", "key2" = None} -``` - -Please note that `None` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + None # error -b = int(None) # error -c = not None # True -d = None == None # True -e = None or 1 # 1 -f = str(None) # None -``` - -#### Undefined - -`Undefined` is similar to None, but its semantics is that a variable is not assigned any value and will not be output to YAML or JSON. - -```python -a = Undefined -b = [1, 2, Undefined] -c = {"key1" = "value1", "key2" = Undefined} -``` - -Please note that `Undefined` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + Undefined # error -b = int(Undefined) # error -c = not Undefined # True -d = Undefined == Undefined # True -e = Undefined or 1 # 1 -f = str(Undefined) # Undefined -``` - -### Common Numeric Operations - -Int and Float support the following operations (see built-in proposal for built-in details): - -- `x + y`: sum of x and y. -- `x - y`: difference of x and y. -- `x * y`: product of x and y. -- `x / y`: quotient of x and y. -- `x // y`: floored quotient of x and y. -- `x % y`: remainder of x / y. -- `x ** y`: x to the power y. -- `-x`: x negated. -- `+x`: x unchanged. -- `~x`: x bitwise negation. -- `abs(x)`: absolute value or magnitude of x. -- `int(x)`: x converted to integer. -- `float(x)`: x converted to floating point. - -KCL supports mixed arithmetic: when a binary arithmetic operator has operands of different numeric types, the operand with the "narrower" type is widened to that of the other, where integer is narrower than floating-point. - -### String - -Strings are immutable sequences of Unicode characters. String literals are written in a variety of ways: - -```python -'allows embedded "double" quotes' # Single quotes -"allows embedded 'single' quotes" # Double quotes -'''Three single quotes''', """Three double quotes""" # Triple quoted -``` - -Triple quoted strings may span multiple lines. - -Indexing a string produces strings of length 1, for a non-empty string s, `s[0] == s[0:1]`. - -```python -a = "Hello, World!" -b = a[2:5] # "llo" -c = a[-5:-2] # "orl" -d = a[::-1] # "'!dlroW ,olleH'" -``` - -- `str(x=None) -> str` - -Return a string. If _x_ is not provided, raise a runtime error. - -```python -x = str(3.5) # "3.5" -``` - -#### Members - -Built-in function and members of a string - -- `str#len() -> int` - Return the number of characters in the string. -- `capitalize() -> str` - Return a copy of the string with its first character (if any) capitalized and the rest lowercased. -- `count(sub: str, start: int = 0, end: int = -1) -> int` - Returns the number of (non-overlapping) occurrences of substring sub in string, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `endswith(suffix: str, start: int = 0, end: int = -1) -> bool` - Returns `True` if the string ends with the specified suffix, otherwise return `False`, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `find(sub: str, start: int = 0, end: int = -1) -> int` - Returns the lowest index where substring sub is found, or -1 if no such index exists, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `format(*args, **kwargs) -> str` - Perform string interpolation. Format strings contain replacement fields surrounded by curly braces {}. Anything that is not contained in braces is considered literal text, which is copied unchanged to the output. If you need to include a bracket character in the literal text, it can be escaped by doubling: A replacement field can be either a name, a number or empty. Values are converted to strings using the str function. -- `index(sub: str, start: int = 0, end: int = -1) -> int` - Returns the first index where sub is found, or raises an error if no such index exists, optionally restricting to `[start:end]` start being inclusive and end being exclusive. -- `isalnum() -> bool` - Returns True if all characters in the string are alphanumeric (`[a-zA-Z0-9]`) and there is at least one character, False otherwise. -- `isalpha() -> bool` - Returns True if all characters in the string are alphabetic (`[a-zA-Z]`) and there is at least one character. -- `isdigit() -> bool` - Returns True if all characters in the string are digits (`[0-9]`) and there is at least one character. -- `islower() -> bool` - Returns True if all cased characters in the string are lowercase and there is at least one character. -- `isspace() -> bool` - Returns True if all characters are white space characters and the string contains at least one character. -- `istitle() -> bool` - Returns True if the string is in title case and it contains at least one character. This means that every uppercase character must follow an uncased one (e.g., whitespace) and every lowercase character must follow a cased one (e.g., uppercase or lowercase). -- `isupper() -> bool` - Returns True if all cased characters in the string are uppercase and there is at least one character. -- `join(iterable: list) -> str` - Return a string which is the concatenation of the strings in iterable. A TypeError will be raised if there are any non-string values in iterable. The separator between elements is the string providing this method. Example: - - ```python - >>> "|".join(["a", "b", "c"]) - "a|b|c" - ``` - -- `lower() -> str` - Returns a copy of the string with all the cased characters converted to lowercase. -- `lstrip(chars: str) -> str` - Return a copy of the string with leading characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.lstrip() - 'spacious ' - >>> 'www.example.com'.lstrip('cmowz.') - 'example.com' - ``` - -- `replace(old: str, new: str, count: int) -> str` - Return a copy of the string with all occurrences of substring old replaced by new. If the optional argument count is given, only the first count occurrences are replaced. -- `rfind(sub: str, start: int = 0, end: int = -1) -> int` - Return the highest index in the string where substring sub is found, such that sub is contained within s[start:end]. Optional arguments start and end are interpreted as in slice notation. Return -1 on failure. -- `rindex(sub: str, start: int = 0, end: int = -1) -> int` - Returns the last index where sub is found, or raises an ValueError if no such index exists, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `rsplit(sep: str, maxsplit: int = -1) -> list` - Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done, the rightmost ones. If sep is not specified or None, any whitespace string is a separator. Except for splitting from the right, rsplit() behaves like split() which is described in detail below. -- `rstrip(chars: str) -> str` - Return a copy of the string with trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a suffix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.rstrip() - ' spacious' - >>> 'mississippi'.rstrip('ipz') - 'mississ' - ``` - -- `split(sep: str, maxsplit: int) -> list` - Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done (thus, the list will have at most maxsplit+1 elements). If maxsplit is not specified or -1, then there is no limit on the number of splits (all possible splits are made). - - If sep is given, consecutive delimiters are not grouped together and are deemed to delimit empty strings (for example, `'1,,2'.split(',')` returns `['1', '', '2']`). The sep argument may consist of multiple characters (for example, `'1<>2<>3'.split('<>')` returns `['1', '2', '3']`). Splitting an empty string with a specified separator returns `['']`. - - For example: - - ```python - >>> '1,2,3'.split(',') - ['1', '2', '3'] - >>> '1,2,3'.split(',', maxsplit=1) - ['1', '2,3'] - >>> '1,2,,3,'.split(',') - ['1', '2', '', '3', ''] - ``` - - If sep is not specified or is None, a different splitting algorithm is applied: runs of consecutive whitespace are regarded as a single separator, and the result will contain no empty strings at the start or end if the string has leading or trailing whitespace. Consequently, splitting an empty string or a string consisting of just whitespace with a `None` separator returns `[]`. - - For example: - - ```python - >>> '1 2 3'.split() - ['1', '2', '3'] - >>> '1 2 3'.split(maxsplit=1) - ['1', '2 3'] - >>> ' 1 2 3 '.split() - ['1', '2', '3'] - ``` - -- `splitlines(keepends: str) -> list` - Return a list of the lines in the string, breaking at line boundaries('\n', '\r\n', '\r'). Line breaks are not included in the resulting list unless keepends is given and true. - - This method splits on the following line boundaries. In particular, the boundaries are a superset of universal newlines. - - For example: - - ```python - >>> 'ab c\n\nde fg\rkl\r\n'.splitlines() - ['ab c', '', 'de fg', 'kl'] - >>> 'ab c\n\nde fg\rkl\r\n'.splitlines(keepends=True) - ['ab c\n', '\n', 'de fg\r', 'kl\r\n'] - ``` - - Unlike `split()` when a delimiter string sep is given, this method returns an empty list for the empty string, and a terminal line break does not result in an extra line: - - ```python - >>> "".splitlines() - [] - >>> "One line\n".splitlines() - ['One line'] - ``` - - For comparison, `split('\n')` gives: - - ```python - >>> ''.split('\n') - [''] - >>> 'Two lines\n'.split('\n') - ['Two lines', ''] - ``` - -- `startswith(prefix: str, start: int = 0, end: int = -1) -> bool` - Return `True` if string starts with the prefix, otherwise return False. prefix can also be a list of prefixes to look for. With optional start, test string beginning at that position. With optional end, stop comparing string at that position. -- `strip(chars: str) -> str` - Return a copy of the string with the leading and trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix or suffix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.strip() - 'spacious' - >>> 'www.example.com'.strip('cmowz.') - 'example' - ``` - - The outermost leading and trailing chars argument values are stripped from the string. Characters are removed from the leading end until reaching a string character that is not contained in the set of characters in chars. A similar action takes place on the trailing end. For example: - - ```python - >>> comment_string = '#....... Section 3.2.1 Issue #32 .......' - >>> comment_string.strip('.#! ') - 'Section 3.2.1 Issue #32' - ``` - -- `title() -> str` - Return a titlecased version of the string where words start with an uppercase character and the remaining characters are lowercase. - - For example: - - ```python - >>> 'Hello world'.title() - 'Hello World' - ``` - - The algorithm uses a simple language-independent definition of a word as groups of consecutive letters. The definition works in many contexts but it means that apostrophes in contractions and possessives form word boundaries, which may not be the desired result: - - ```python - >>> "they're bill's friends from the UK".title() - "They'Re Bill'S Friends From The Uk" - ``` - -- `upper() -> str` - Return a copy of the string with all the cased characters 4 converted to uppercase. Note that `s.upper().isupper()` might be `False` if s contains uncased characters or if the Unicode category of the resulting character(s) is not “Lu” (Letter, uppercase), but e.g., “Lt” (Letter, titlecase). -- `removeprefix(prefix: str) -> str` - If the string starts with the prefix string, return string[len(prefix):]. Otherwise, return a copy of the original string. - ```python - >>> "prefix-data".removeprefix("prefix-") - "data" - ``` -- `rermovesuffix(suffix: str) -> str` - If the string ends with the suffix string and that suffix is not empty, return string[:-len(suffix)]. Otherwise, return a copy of the original string. - ```python - >>> "data-suffix".removesuffix("-suffix") - "data" - ``` - -### List - -Lists are immutable sequences, typically used to store collections of homogeneous items (where the precise degree of similarity will vary by application). - -Lists may be constructed in several ways: - -- Using a pair of square brackets to denote the empty list: `[]` -- Using square brackets, separating items with commas: `[a]`, `[a, b, c]` -- Using a list comprehension: `[x for x in iterable]` -- Using the type constructor: list() or list(iterable) - -The constructor builds a list whose items are the same and in the same order as iterable’s items.Iterable may be either a sequence, a container that supports iteration, or an iterator object. If iterable is already a list, a copy is made and returned, similar to `iterable[:]`. For example, `list('abc')` returns `['a', 'b', 'c']` and `list([1, 2, 3])` returns `[1, 2, 3]`. If no argument is given, the constructor creates a new empty list `[]`. - -Lists implement all of the common sequence operations. - -#### Members - -- `len()` - Return the number of items in the list. - -### Common Sequence Operations - -The operations in the following table are supported by List and Dict. - -This table lists the sequence operations sorted in ascending priority. In the table, s and t are sequences of the same type, n, i, j and k are integers and x is an arbitrary object that meets any type and value restrictions imposed by s. - -The `in` and `not in` operations have the same priorities as the comparison operations. The + -(concatenation) and \* (repetition) operations have the same priority as the corresponding numeric operations. - -| Operation | Result | Notes | -| ------------ | -------------------------------------------------- | ----- | -| `x in s` | `True` if an item of s is equal to x, else `False` | #1 | -| `x not in s` | `False` if an item of s is equal to x, else `True` | #1 | -| `s + t` | the concatenation of s and t | #5 | -| `s[i]` | ith item of s, origin 0 | #2 | -| `s[i:j]` | slice of s from i to j | #2 #3 | -| `s[i:j:k]` | slice of s from i to j with step k | #2 #4 | -| `min(s)` | smallest item of s | | -| `max(s)` | largest item of s | | - -Notes: - -- 1. While the in and not in operations are used only for simple containment testing in the - general case, some specialized sequences (str) also use them for subsequence testing: - -```python ->>> "gg" in "eggs" -True -``` - -- 2. If i or j is negative, the index is relative to the end of sequence s: `s.len() + i` or `s.len() + j` is substituted. But note that -0 is still 0. -- 3. The slice of s from i to j is defined as the sequence of items with index k such that `i <= k < j`. If i or j is greater than `s.len()`, use `s.len()`. If i is omitted or None, use 0. If j is omitted or None, use `s.len()`. If i is greater than or equal to j, the slice is empty. -- 4. The slice of s from i to j with step k is defined as the sequence of items with index `x = i + n*k` such that `0 <= n < (j-i)/k`. In other words, the indices are `i`, `i+k`, `i+2*k`, `i+3*k` and so on, stopping when j is reached (but never including j). When k is positive, i and j are reduced to s.len() if they are greater. When k is negative, i and j are reduced to s.len() - - - If they are greater. If i or j are omitted or None, they become “end” values (which end depends on the sign of k). Note, k cannot be zero. If k is None, it is treated like 1. - -- 5. Concatenating immutable sequences always results in a new object. This means that building up a sequence by repeated concatenation will have a quadratic runtime cost in the total sequence length. To get a linear runtime cost, you must switch to one of the alternatives below: - - - if concatenating str objects, you can build a list and use `str.join()` at the end - -- 6. `index` raises `ValueError` when x is not found in s. Not all implementations support passing the additional arguments i and j. These arguments allow efficient searching of subsections of the sequence. Passing the extra arguments is roughly equivalent to using `s[i:j].index(x)`, only without copying any data and with the returned index being relative to the start of the sequence rather than the start of the slice. - -### Dict - -Dict is an immutable mapping object maps hashable values to arbitrary objects. A dictionary’s keys are almost arbitrary values. Values that are not hashable, that is, values containing lists, dictionaries may not be used as keys. Numeric types used for keys obey the normal rules for numeric comparison: if two numbers compare equal (such as 1 and 1.0) then they can be used interchangeably to index the same dictionary entry. (Note however, that since computers store floating-point numbers as approximations it is usually unwise to use them as dictionary keys.) Dict is ordered. The order of the keys is the order of their declaration. - -Dictionaries can be created by placing a comma-separated list of keys: value pairs within braces, for example: `{'jack': 4098, 'sjoerd': 4127}` or `{4098: 'jack', 4127: 'sjoerd'}`, by the dict constructor, or list/dict comprehension. - -- `dict(obj)` - -Return a new dictionary initialized from an optional positional argument and a possibly empty set of keyword arguments.If no positional argument is given, an empty dictionary is created. If a positional argument is given and it is a mapping object, a dictionary is created with the same key-value pairs as the mapping object. Otherwise, the positional argument must be an iterable object. Each item in the iterable must itself be an iterable with exactly two objects. The first object of each item becomes a key in the new dictionary, and the second object the corresponding value. If a key occurs more than once, the last value for that key becomes the corresponding value in the new dictionary. If keyword arguments are given, the keyword arguments and their values are added to the dictionary created from the positional argument. If a key being added is already present, the value from the keyword argument replaces the value from the positional argument. To illustrate, the following examples all return a dictionary equal to `{"one": 1, "two": 2, "three": 3}`: - -```python ->>> a = {'two': 2, 'one': 1, 'three': 3} ->>> b = {'one': 1, 'two': 2, 'three': 3} ->>> c = {'three': 3, 'one': 1, 'two': 2} ->>> a == b == c -True -``` - -Providing keyword arguments as in the first example only works for keys that are valid KCL identifiers. Otherwise, any valid keys can be used. - -In the dict comprehension, key/value pairs yielded by the generator expression is set in the dictionary in the order yielded: the first occurrence of the key determines its insertion order, and the last determines the value associated to it. - -```python ->>> {str(i): 2 * i for i in range(3)} -{"0": 0, "1": 2, "2": 4} - ->>> a = {"one": 1, "two": 2, "three": 3} ->>> b = {k: v for k, v in a if v >= 2} -{two: 2, three: 3} -``` - -#### Operations & Members - -These are the operations that dictionaries the support. - -- `list(d)` - Return a list of all the keys used in the dictionary d. -- `len()` - Return the number of items in the dictionary d. -- `d[key]` - Return the item of d with key. Return Undefined if key is not in the map. -- `key in d` - Return True if d has a key, else False. -- `key not in d` - Equivalent to not key in d. -- `d.key` - Return the item of d with key. Return Undefined if key is not in the map. - -Dictionaries compare equal if and only if they have the same (key, value) pairs(keys' ordering matters). Order comparisons (‘<’, ‘<=’, ‘>=’, ‘>’) raise TypeError. - -```python ->>> d = {"one": 1, "two": 2, "three": 3, "four": 4} ->>> d -{'one': 1, 'two': 2, 'three': 3, 'four': 4} ->>> list(d) -['one', 'two', 'three', 'four'] -``` diff --git a/versioned_docs/version-0.5.5/reference/lang/spec/error.md b/versioned_docs/version-0.5.5/reference/lang/spec/error.md deleted file mode 100644 index 2a58b553..00000000 --- a/versioned_docs/version-0.5.5/reference/lang/spec/error.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: "Errors" -linkTitle: "Errors" -type: "docs" -weight: 2 -description: Errors ---- - -When errors happen, developers should be able to detect the error and abort -execution. Thus, KCL introduce the `assert` syntax. - -In the previous topic of `schema` syntax. Errors can also be raised when a -schema is violated. - -## Syntax - -The syntax of the `assert` statement is the following. - -```bnf -assert_stmt: 'assert' test ['if' test] [',' test] -``` - -In the basic form, an `assert` statement evaluates an expression. If the -expression is evaluated to `False`, the assertion is failed, and an error -should be reported. - -In the extended form, an error message can be provided. The error message is -another expression. It is only evaluated when the expression to be evaluated -is evaluated to `False`. The evaluation result of the error message is printed -when reporting the error. - -The following is an example: - -```python -a = 1 -b = 3 -condition = False -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -# if condition is True, then assert `a == b`, if failed, the message "error message" will be printed. -assert a == b if condition, "error message" -``` - -## The Implementation - -When an error happens, no matter it is caused by the `assert` or the `schema` syntax, -the virtual machine should exit with an exit code greater than `0`. - -The virtual machine may choose to dump the back trace information, and it is strongly recommended to implement it. - -In practice, KCL can dump back trace by default, and an argument can be introduced to disable it. diff --git a/versioned_docs/version-0.5.5/reference/lang/spec/index.md b/versioned_docs/version-0.5.5/reference/lang/spec/index.md deleted file mode 100644 index 88bbaa59..00000000 --- a/versioned_docs/version-0.5.5/reference/lang/spec/index.md +++ /dev/null @@ -1 +0,0 @@ -# KCL Spec diff --git a/versioned_docs/version-0.5.5/reference/lang/spec/kcl-spec.md b/versioned_docs/version-0.5.5/reference/lang/spec/kcl-spec.md deleted file mode 100644 index 63a9d6e7..00000000 --- a/versioned_docs/version-0.5.5/reference/lang/spec/kcl-spec.md +++ /dev/null @@ -1,343 +0,0 @@ ---- -title: "KCL Spec" -linkTitle: "KCL Spec" -type: "docs" -weight: 2 -description: KCL Spec ---- - -## Lexical rules - -### Keywords and reserved words - -The following are the keywords of the KCL: - -```python -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -The following are reserved words for the KCL: - -```python -pass return validate rule flow -def del raise except try -finally while from with yield -global nonlocal struct class final -``` - -### Line comment - -```python -# a comment -``` - -### Operators - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != = -+= -= *= **= /= //= %= -<<= >>= &= ^= -``` - -### Delimiters - -```python -( ) [ ] { } -, : . ; @ -``` - -### Operator precedence - -The following list of operators is ordered from **highest to lowest**: - -| Operator | Description | -| -------------------------------------------------------------------------------- | -------------------------------------------------------- | -| `**` | Exponentiation (highest priority) | -| `+x` `-x` `~x` | Positive, negative, bitwise NOT | -| `*` `/` `%` `//` | Multiplication, division, floor division and remainder | -| `+` `-` | Addition and subtraction | -| `<<` `>>` | Left and right shifts | -| `&` | Bitwise AND | -| `^` | Bitwise XOR | -| \| | Bitwise OR | -| `in`, `not in`, `is`, `is not`, `<`, `<=`, `>`, `>=`, `!=`, `==` | Comparisons, including membership and identity operators | -| `not` | Boolean NOT | -| `and` | Boolean AND | -| `or` | Boolean OR | -| `if – else` | Conditional expression = | -| `=`, `+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `=`, `^=`, `\*\*=`, `//=`, `<<=`, `>>=` | Assign | - -## Grammar - -KCL uses Python's [LarkParser](https://lark-parser.readthedocs.io/en/latest/) tool to describe the grammar, and the specification rules are as follows: - -```bnf -//////////// KCL grammar //////////// -start: (NEWLINE | statement)* - -statement: simple_stmt | compound_stmt -simple_stmt: (assign_stmt | unification_stmt | expr_stmt | assert_stmt | import_stmt | type_alias_stmt) NEWLINE -compound_stmt: if_stmt | schema_stmt | rule_stmt - -//////////// import_stmt //////////// -import_stmt: IMPORT dot_name (AS NAME)? -dot_name: (leading_dots identifier) | identifier -leading_dots: DOT+ - -/////////// assert_stmt //////////// -assert_stmt: ASSERT simple_expr (IF simple_expr)? (COMMA test)? - -//////////// if_stmt //////////// -if_stmt: IF test COLON execution_block (ELIF test COLON execution_block)* (ELSE COLON execution_block)? -execution_block: if_simple_stmt | NEWLINE _INDENT schema_init_stmt+ _DEDENT -if_simple_stmt: (simple_assign_stmt | unification_stmt | expr_stmt | assert_stmt) NEWLINE - -//////////// assign_stmt //////////// -assign_stmt: identifier [COLON type] (ASSIGN identifier)* ASSIGN test - | identifier (COMP_PLUS | COMP_MINUS | COMP_MULTIPLY | COMP_DOUBLE_STAR | COMP_DIVIDE - | COMP_DOUBLE_DIVIDE | COMP_MOD | COMP_AND | COMP_OR | COMP_XOR | COMP_SHIFT_LEFT - | COMP_SHIFT_RIGHT) test - -simple_assign_stmt: identifier ASSIGN test - | identifier (COMP_PLUS | COMP_MINUS | COMP_MULTIPLY | COMP_DOUBLE_STAR | COMP_DIVIDE - | COMP_DOUBLE_DIVIDE | COMP_MOD | COMP_AND | COMP_OR | COMP_XOR | COMP_SHIFT_LEFT - | COMP_SHIFT_RIGHT) test - -//////////// unification_stmt //////////// -unification_stmt: identifier COLON schema_expr - -//////////// schema_stmt //////////// -schema_stmt: [decorators] (SCHEMA|MIXIN|PROTOCOL) NAME [LEFT_BRACKETS [schema_arguments] RIGHT_BRACKETS] [LEFT_PARENTHESES identifier (COMMA identifier)* RIGHT_PARENTHESES] [for_host] COLON NEWLINE [schema_body] -schema_arguments: schema_argument (COMMA schema_argument)* -schema_argument: NAME [COLON type] [ASSIGN test] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt|schema_init_stmt|schema_index_signature)* [check_block] _DEDENT -schema_attribute_stmt: attribute_stmt NEWLINE -attribute_stmt: [decorators] identifier [QUESTION] COLON type [(ASSIGN|COMP_OR) test] -schema_init_stmt: if_simple_stmt | if_stmt -schema_index_signature: LEFT_BRACKETS [NAME COLON] [ELLIPSIS] basic_type RIGHT_BRACKETS COLON type [ASSIGN test] NEWLINE - -//////////// rule_stmt //////////// -rule_stmt: [decorators] RULE NAME [LEFT_BRACKETS [schema_arguments] RIGHT_BRACKETS] [LEFT_PARENTHESES identifier (COMMA identifier)* RIGHT_PARENTHESES] [for_host] COLON NEWLINE [rule_body] -rule_body: _INDENT (string NEWLINE)* check_expr+ _DEDENT - -for_host: FOR identifier - -/////////// decorators //////////// -decorators: (AT decorator_expr NEWLINE)+ -decorator_expr: identifier [call_suffix] - -//////////// type //////////// -type: type_element (OR type_element)* -type_element: schema_type | basic_type | compound_type | literal_type -schema_type: identifier -basic_type: STRING_TYPE | INT_TYPE | FLOAT_TYPE | BOOL_TYPE | ANY_TYPE -compound_type: list_type | dict_type -list_type: LEFT_BRACKETS (type)? RIGHT_BRACKETS -dict_type: LEFT_BRACE (type)? COLON (type)? RIGHT_BRACE -literal_type: string | number | TRUE | FALSE | NONE - -//////////// type alias //////////// -type_alias_stmt: TYPE NAME ASSIGN type - -//////////// check_stmt //////////// -check_block: CHECK COLON NEWLINE _INDENT check_expr+ _DEDENT -check_expr: simple_expr [IF simple_expr] [COMMA primary_expr] NEWLINE - -//////////// mixin_stmt //////////// -mixin_stmt: MIXIN LEFT_BRACKETS [mixins | multiline_mixins] RIGHT_BRACKETS NEWLINE -multiline_mixins: NEWLINE _INDENT mixins NEWLINE _DEDENT -mixins: identifier (COMMA (NEWLINE mixins | identifier))* - - -//////////// expression_stmt //////////// -expr_stmt: testlist_expr -testlist_expr: test (COMMA test)* -test: if_expr | simple_expr -if_expr: simple_expr IF simple_expr ELSE test - -simple_expr: unary_expr | binary_expr | primary_expr - -unary_expr: un_op simple_expr -binary_expr: simple_expr bin_op simple_expr - -bin_op: L_OR | L_AND - | OR | XOR | AND - | SHIFT_LEFT | SHIFT_RIGHT - | PLUS | MINUS | MULTIPLY | DIVIDE | MOD | DOUBLE_DIVIDE - | DOUBLE_STAR - | EQUAL_TO | NOT_EQUAL_TO - | LESS_THAN | GREATER_THAN | LESS_THAN_OR_EQUAL_TO | GREATER_THAN_OR_EQUAL_TO - | IN | L_NOT IN | IS | IS L_NOT | L_NOT | AS -un_op: L_NOT | PLUS | MINUS | NOT - -primary_expr: identifier call_suffix | operand | primary_expr select_suffix | primary_expr call_suffix | primary_expr slice_suffix -operand: identifier | number | string | constant | quant_expr | list_expr | list_comp | config_expr | dict_comp | schema_expr | lambda_expr | LEFT_PARENTHESES test RIGHT_PARENTHESES -select_suffix: [QUESTION] DOT NAME -call_suffix: LEFT_PARENTHESES [arguments [COMMA]] RIGHT_PARENTHESES -slice_suffix: [QUESTION] LEFT_BRACKETS (test | [test] COLON [test] [COLON [test]]) RIGHT_BRACKETS -arguments: argument (COMMA argument)* -argument: test | NAME ASSIGN test | MULTIPLY test | DOUBLE_STAR test - - -//////////// operand //////////// -identifier: NAME (DOT NAME)* -quant_expr: quant_op [ identifier COMMA ] identifier IN quant_target LEFT_BRACE (simple_expr [IF simple_expr] | NEWLINE _INDENT simple_expr [IF simple_expr] NEWLINE _DEDENT)? RIGHT_BRACE -quant_target: string | identifier | list_expr | list_comp | config_expr | dict_comp -quant_op: ALL | ANY | FILTER | MAP -list_expr: LEFT_BRACKETS [list_items | NEWLINE [_INDENT list_items _DEDENT]] RIGHT_BRACKETS -list_items: list_item ((COMMA [NEWLINE] | [NEWLINE]) list_item)* [COMMA] [NEWLINE] -list_item: test | star_expr | if_item -list_comp: LEFT_BRACKETS (list_item comp_clause+ | NEWLINE _INDENT list_item comp_clause+ _DEDENT) RIGHT_BRACKETS -dict_comp: LEFT_BRACE (entry comp_clause+ | NEWLINE _INDENT entry comp_clause+ _DEDENT) RIGHT_BRACE -entry: test (COLON | ASSIGN | COMP_PLUS) test -comp_clause: FOR loop_variables [COMMA] IN simple_expr [NEWLINE] [IF test [NEWLINE]] -if_entry: IF test COLON if_entry_exec_block (ELIF test COLON if_entry_exec_block)* (ELSE COLON if_entry_exec_block)? -if_entry_exec_block: (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry) [NEWLINE] | NEWLINE _INDENT (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry) ((COMMA [NEWLINE] | [NEWLINE]) (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry))* [COMMA] [NEWLINE] _DEDENT -if_item: IF test COLON if_item_exec_block (ELIF test COLON if_item_exec_block)* (ELSE COLON if_item_exec_block)? -if_item_exec_block: list_item [NEWLINE] | NEWLINE _INDENT list_item ((COMMA [NEWLINE] | NEWLINE) list_item)* [COMMA] [NEWLINE] _DEDENT - -star_expr: MULTIPLY test -double_star_expr: DOUBLE_STAR test -loop_variables: primary_expr (COMMA primary_expr)* -schema_expr: identifier (LEFT_PARENTHESES [arguments] RIGHT_PARENTHESES)? config_expr -config_expr: LEFT_BRACE [config_entries | NEWLINE [_INDENT config_entries _DEDENT]] RIGHT_BRACE -config_entries: config_entry ((COMMA [NEWLINE] | [NEWLINE]) config_entry)* [COMMA] [NEWLINE] -config_entry: test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry - -//////////// lambda_expr //////////// -lambda_expr: LAMBDA [schema_arguments] [RIGHT_ARROW type] LEFT_BRACE [expr_stmt | NEWLINE _INDENT schema_init_stmt+ _DEDENT] RIGHT_BRACE - -//////////// misc //////////// -number: DEC_NUMBER [multiplier] | HEX_NUMBER | BIN_NUMBER | OCT_NUMBER | FLOAT_NUMBER -multiplier: SI_N_L | SI_U_L | SI_M_L | SI_K_L | SI_K | SI_M | SI_G | SI_T | SI_P - | SI_K_IEC | SI_M_IEC | SI_G_IEC | SI_T_IEC | SI_P_IEC -string: STRING | LONG_STRING -constant : TRUE | FALSE | NONE | UNDEFINED -// Tokens - -ASSIGN: "=" -COLON: ":" -SEMI_COLON: ";" -COMMA: "," -QUESTION: "?" -ELLIPSIS: "..." -RIGHT_ARROW: "->" -LEFT_PARENTHESES: "(" -RIGHT_PARENTHESES: ")" -LEFT_BRACKETS: "[" -RIGHT_BRACKETS: "]" -LEFT_BRACE: "{" -RIGHT_BRACE: "}" -PLUS: "+" -MINUS: "-" -MULTIPLY: "*" -DIVIDE: "/" -MOD: "%" -DOT: "." -AND: "&" -OR: "|" -XOR: "^" -NOT: "~" -LESS_THAN: "<" -GREATER_THAN: ">" -EQUAL_TO: "==" -NOT_EQUAL_TO: "!=" -GREATER_THAN_OR_EQUAL_TO: ">=" -LESS_THAN_OR_EQUAL_TO: "<=" -DOUBLE_STAR: "**" -DOUBLE_DIVIDE: "//" -SHIFT_LEFT: "<<" -SHIFT_RIGHT: ">>" -AT: "@" - -COMP_PLUS: "+=" -COMP_MINUS: "-=" -COMP_MULTIPLY: "*=" -COMP_DIVIDE: "/=" -COMP_MOD: "%=" -COMP_AND: "&=" -COMP_OR: "|=" -COMP_XOR: "^=" -COMP_DOUBLE_STAR: "**=" -COMP_DOUBLE_DIVIDE: "//=" -COMP_SHIFT_LEFT: "<<=" -COMP_SHIFT_RIGHT: ">>=" - -// Special tokens -IMPORT: "import" -AS: "as" -RULE: "rule" -SCHEMA: "schema" -MIXIN: "mixin" -PROTOCOL: "protocol" -CHECK: "check" -FOR: "for" -ASSERT: "assert" -IF: "if" -ELIF: "elif" -ELSE: "else" -L_OR: "or" -L_AND: "and" -L_NOT: "not" -IN: "in" -IS: "is" -LAMBDA: "lambda" -ALL: "all" -ANY: "any" -FILTER: "filter" -MAP: "map" -TYPE: "type" - -ANY_TYPE: "any" -STRING_TYPE: "str" -INT_TYPE: "int" -FLOAT_TYPE: "float" -BOOL_TYPE: "bool" - -// Constant tokens -TRUE: "True" -FALSE: "False" -NONE: "None" -UNDEFINED: "Undefined" - -// Binary prefix -SI_N_L: "n" -SI_U_L: "u" -SI_M_L: "m" -SI_K_L: "k" -SI_K: "K" -SI_M: "M" -SI_G: "G" -SI_T: "T" -SI_P: "P" -SI_K_IEC: "Ki" -SI_M_IEC: "Mi" -SI_G_IEC: "Gi" -SI_T_IEC: "Ti" -SI_P_IEC: "Pi" -IEC: "i" - -NAME: /\$?[a-zA-Z_]\w*/ -COMMENT: /#[^\n]*/ -NEWLINE: ( /\r?\n[\t ]*/ | COMMENT )+ - -STRING: /r?("(?!"").*?(? **note** -> -> Any character except the ASCII space, tab (`\t`) and formfeed (`\f`) is considered a none-space character. - -- A line ending in a backslash cannot carry a comment (, which will be introduced shortly afterwards). -- A backslash does not continue a comment. -- A backslash does not continue a token except for string literals (i.e., tokens other than string literals cannot be split across physical lines using a backslash). -- A backslash is illegal elsewhere on a line outside a string literal. - -### Implicit Line Joining - -Expressions in parentheses, square brackets or curly braces can be split over more than one physical line without using backslashes. - -- Implicitly continued lines can carry comments. -- The indentation of the continuation lines is not important. -- Blank continuation lines are allowed. -- There is no `NEWLINE` token between implicit continuation lines. -- Implicitly continued lines can also occur within triple-quoted strings (see below); in that case they cannot carry comments. - -### Blank Lines - -### Indentation - -### Comments - -Starting with a `#` character that is not part of a string literal is a comment. A comment ends at the end of the physical line. - -A comment signifies the end of the logical line unless the implicit line joining rules are invoked. - -Comments are ignored by the syntax. - -### Identifiers and Keywords - -Identifiers (also referred to as names) are described by the following lexical definitions. - -Within the ASCII range (from `U+0001` to `U+007F`), the valid characters for identifiers are the uppercase and lowercase letters `A` through `Z`, the underscore `_` and, except for the first character, the digits `0` through `9`. - -Identifiers are unlimited in length. The case is significant. - -### Keywords - -The following identifiers are used as reserved words, or keywords of the language, and cannot be used as ordinary identifiers. They must be spelled exactly as written here: - -``` -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -The following tokens are not used, but they are reserved as possible future keywords: - -``` -pass return validate rule flow -def del raise except try -finally while from with yield -global nonlocal struct class final -``` - -### Literals - -Literals are notations for constant values of some built-in types. - -### String Literals - -String literals are described by the following lexical definitions: - -``` -stringliteral ::= [stringprefix](shortstring | longstring) -stringprefix ::= "r" | "R" -shortstring ::= "'" shortstringitem* "'" | '"' shortstringitem* '"' -longstring ::= "'''" longstringitem* "'''" | '"""' longstringitem* '"""' -shortstringitem ::= shortstringchar | stringescapeseq -longstringitem ::= longstringchar | stringescapeseq -shortstringchar ::= -longstringchar ::= -stringescapeseq ::= "\" -``` - -Multiple adjacent string or bytes literals (delimited by whitespace),possibly using different quoting conventions, are allowed, and their meaning is the same as their concatenation. - -### Numeric Literals - -There are two types of numeric literals: integers and floating-point numbers. - -Integer literals are described by the following lexical definitions: - -``` -integer ::= decinteger | bininteger | octinteger | hexinteger -decinteger ::= nonzerodigit (["_"] digit)* | "0"+ (["_"] "0")* -bininteger ::= "0" ("b" | "B") (["_"] bindigit)+ -octinteger ::= "0" ("o" | "O") (["_"] octdigit)+ -hexinteger ::= "0" ("x" | "X") (["_"] hexdigit)+ -nonzerodigit ::= "1"..."9" -digit ::= "0"..."9" -bindigit ::= "0" | "1" -octdigit ::= "0"..."7" -hexdigit ::= digit | "a"..."f" | "A"..."F" -``` - -Floating-point literals are described by the following lexical definitions: - -``` -floatnumber ::= pointfloat | exponentfloat -pointfloat ::= [digitpart] fraction | digitpart "." -exponentfloat ::= (digitpart | pointfloat) exponent -digitpart ::= digit (["_"] digit)* -fraction ::= "." digitpart -exponent ::= ("e" | "E") ["+" | "-"] digitpart -``` - -## Operators and Delimiters - -### Operators - -The following tokens are operators: - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != @ -``` - -### Delimiters - -The following tokens serve as delimiters in the grammar: - -```python -( ) [ ] { } -, : . ; = += --= *= **= /= //= %= -<<= >>= &= |= ^= -``` - -The period can also occur in floating-point literals. - -The following printing ASCII characters have special meaning as part of other tokens or are otherwise significant to the lexical analyzer: - -``` -' " # \ -``` - -The following printing ASCII characters are not used in KCL. Their occurrence outside string literals and comments is an unconditional error: - -``` -? ` -``` - -## Reference - -Since the lexical conventions of KCL is very similar to that of Python, we use the following document as the reference when writing this chapter. - -- [https://docs.python.org/3/reference/lexical_analysis.html](https://docs.python.org/3/reference/lexical_analysis.html) diff --git a/versioned_docs/version-0.5.5/reference/lang/spec/modules.md b/versioned_docs/version-0.5.5/reference/lang/spec/modules.md deleted file mode 100644 index f8608619..00000000 --- a/versioned_docs/version-0.5.5/reference/lang/spec/modules.md +++ /dev/null @@ -1,621 +0,0 @@ ---- -title: "Modules" -linkTitle: "Modules" -type: "docs" -weight: 2 -description: Modules ---- - -## Modules and the Import System - -KCL code is organized in **modules**. For code in one module to access the code defined in another module, a process called **importing** must be used. - -Importing is undertaken at compile-time in KCL. The advantage is to have static checking enabled. - -A regular KCL module is a file on the file system. It is required to have a `.k` suffix. - -## Packages - -To help manage modules and provide a naming hierarchy, KCL has the concept of packages. In KCL, a package maps to exactly a file system directory, and a regular module maps to a file. - -Files directly under a package are considered parts of the package, instead of individual regular modules. - -Packages can have sub-packages. - -Packages are special modules: - -- All packages in KCL are modules. -- A single-file module can never be a package. - -All modules have a name. - -Sub package names are separated from their parent package name by dots. - -To summary, a regular KCL module is a `.k` file, and a package is a directory on the file system. All `.k` files directly under the directory are included in the package, other files are ignored. If the directory has subdirectories, they become sub-packages as long as there are `.k` files underneath. - -### Intra-Package Name Space Sharing - -Inside a package, all `.k` files are considered parts of the package, instead of regular modules. Code in these files share a single name space and can access names defined in other files, without explicitly granted. - -### Package Initialization - -A package can have the initialization code. The code must exist in only one of the `.k` files under this package. The interpreter guarantees that the initialization code is executed after all definitions. - -## Searching - -The searching begins when an `import` statement is used to import a module. - -### Module Cache - -In KCL, only standard system modules are cached. When a cached module is imported, the cached version is used. In other words, KCL runtime would not create another copy of the standard system module in memory. - -However, other modules are uncached. Importing a module multiple time would create multiple instances of the module. - -### Module Names - -An `import` statement specifies the name of the module to import. The syntax is: - -``` -import [as ] -``` - -The rule to search with the module name is very simple: - -- **Step 1**: Searches the module name from the **standard system modules**, then **plugins modules**. - - See **standard system modules** and **plugins modules** for more details. If matched, the module is imported. Otherwise, continue to **Step 2**. -- **Step 2**. Whether a module name starts with a `.` is checked. If yes, the name is a so-called relative pathname, and we go to **Step 5**. Otherwise, continue to **Step 3**. -- **Step 3**: If the module name does not start with any `.`, then the compiler searches the nearest `root path` directory from this directory to the parent, and find the module according to the name just from the `root path`. If no `root path` is found, find the module according to the name from the folder the `.k` file including this `import` statement exists. - - **root path**: the directory contains a `kcl.mod` file. If matched, the module is imported. Otherwise, continue to **Step 4**. -- **Step 4**: Then the compiler checks if the name is the name of any library module that requires explicit loading. If matched, the library module is imported. Otherwise, continue to **Step 6**. -- **Step 5**. For relative importing, find the module according to the name from the folder the `.k` file including this `import` statement exists. Interpret leading dots using the following rule: -- One dot: Ignore. -- Tow or more dots: Suppose there are `n` leading dots, then the searching starts at `n - 1` levels above this folder. If matched, the module is imported. Otherwise, continue to **Step 6**. -- **Step 6**. Module not found, report an error. - -Do case-sensitive search when the operating system allows. If case-sensitive search is not allowed, search directories before regular files. - -In KCL, the `from <> import <>` is unsupported, and relative import is performed with the `import <>` syntax. - -### Uniqueness of Module - -Each module has a unique location path in its scope, so that a module or package could be located with a unique location path, such as `a.b.c`. - -Searching by location path should be supported by the kcl compiler, which needs to provide corresponding searching features through the command line and api form. - -## Standard System Packages - -KCL supports a few standard system modules. The following is the full list of these standard system modules: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PackageMember
datetimetoday
now
ticks
date
mathceil
exp
expm1
factorial
floor
gcd
isfinite
isinf
isnan
log
log1p
log2
log10
modf
pow
sqrt
regexreplace
match
compile
findall
search
split
unitsn
u
m
k
K
M
G
T
P
Ki
Mi
Gi
Ti
Pi
to_n
to_u
to_m
to_K
to_M
to_G
to_T
to_P
to_Ki
to_Mi
to_Gi
to_Ti
to_Pi
jsonencode
decode
dump_to_file
yamlencode
decode
dump_to_file
netsplit_host_port
join_host_port
fqdn
parse_IP
to_IP4
to_IP16
IP_string
is_IPv4
is_IP
is_loopback_IP
is_multicast_IP
is_interface_local_multicast_IP
is_link_local_multicast_IP
is_link_local_unicast_IP
is_global_unicast_IP
is_unspecified_IP
base64encode
decode
cryptomd5
sha1
sha224
sha256
sha384
sha512
- -- datetime - - ticks() -> float - Return the current time in seconds since the Epoch. Fractions of a second may be present if the system clock provides them. - - date() -> str - return the `%Y-%m-%d %H:%M:%S` format date. - - now() -> str - return the local time. e.g. `'Sat Jun 06 16:26:11 1998'` - - today() -> str - return the `%Y-%m-%d %H:%M:%S.%{ticks}` format date. -- math - - ceil(x) -> int - Return the ceiling of x as an Integral. This is the smallest integer >= x. - - factorial(x) -> int - Return x!. Raise a error if x is negative or non-integral. - - floor(x) -> int - Return the floor of x as an Integral. This is the largest integer <= x. - - gcd(a: int, b: int) -> int - Return the greatest common divisor of x and y - - isfinite(x) -> bool - Return True if x is neither an infinity nor a NaN, and False otherwise. - - isinf(x) -> bool - Return True if x is a positive or negative infinity, and False otherwise. - - isnan(x) -> bool - Return True if x is a NaN (not a number), and False otherwise. - - modf(x) -> Listfloat, float] - Return the fractional and integer parts of x. Both results carry the sign of x and are floats. - - exp(x) -> float - Return e raised to the power of x. - - expm1(x) -> float - Return exp(x)-1. This function avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small x. - - log(x, base=2.71828182845904523536028747135266250) -> float - Return the logarithm of x to the base e. - - log1p(x) -> float - Return the natural logarithm of 1+x (base e). The result is computed in a way which is accurate for x near zero. - - log2(x) -> float - Return the base 2 logarithm of x. - - log10(x) -> float - Return the base 10 logarithm of x. - - pow(x, y) -> float - Return x\*\*y (x to the power of y). - - sqrt(x) -> float - Return the square root of x. -- regex - - replace(string: str, pattern: str, replace: str, count=0) -> str - Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement. - - match(string: str, pattern: str) -> bool - Try to apply the pattern at the start of the string, returning a bool value True if any match was found, or False if no match was found. - - compile(pattern: str) -> bool - Compile a regular expression pattern, returning a bool value denoting whether the pattern is valid. - - findall(string: str, pattern: str) -> List[str] - Return a list of all non-overlapping matches in the string. - - search(string: str, pattern: str) -> bool - Scan through string looking for a match to the pattern, returning a bool value True if any match was found, or False if no match was found. - - split(string: str, pattern: str, maxsplit=0) -> List[str] - Scan through string looking for a match to the pattern, returning a Match object, or None if no match was found. -- units - - Unit constants - - Fixed point: `n`, `u`, `m`, `k`, `K`, `G`, `T` and `P`. - - Power of 2: `Ki`, `Mi`, `Gi`, `Ti` and `Pi`. - - Functions - - to_n(num: int) -> str - Int literal to string with `n` suffix - - to_u(num: int) -> str - Int literal to string with `u` suffix - - to_m(num: int) -> str - Int literal to string with `m` suffix - - to_K(num: int) -> str - Int literal to string with `K` suffix - - to_M(num: int) -> str - Int literal to string with `M` suffix - - to_G(num: int) -> str - Int literal to string with `G` suffix - - to_T(num: int) -> str - Int literal to string with `T` suffix - - to_P(num: int) -> str - Int literal to string with `P` suffix - - to_Ki(num: int) -> str - Int literal to string with `Ki` suffix - - to_Mi(num: int) -> str - Int literal to string with `Mi` suffix - - to_Gi(num: int) -> str - Int literal to string with `Gi` suffix - - to_Ti(num: int) -> str - Int literal to string with `Ti` suffix - - to_Pi(num: int) -> str - Int literal to string with `Pi` suffix -- json - - encode(data: any, sort_keys: bool = False, indent: int = None, ignore_private: bool = False, ignore_none: bool = False) -> str - Serialize a KCL object `data` to a JSON formatted str. - - decode(value: str) -> any - Deserialize `value` (a string instance containing a JSON document) to a KCL object. - - dump_to_file(data: any, filename: str, ignore_private: bool = False, ignore_none: bool = False) -> None - Serialize a KCL object `data` to a JSON formatted str and write it into the file `filename`. -- yaml - - encode(data: any, sort_keys: bool = False, ignore_private: bool = False, ignore_none: bool = False) -> str - Serialize a KCL object `data` to a YAML formatted str. - - decode(value: str) -> any - Deserialize `value` (a string instance containing a YAML document) to a KCL object. - - dump_to_file(data: any, filename: str, ignore_private: bool = False, ignore_none: bool = False) -> None - Serialize a KCL object `data` to a YAML formatted str and write it into the file `filename`. -- net - - split_host_port(ip_end_point: str) -> List[str] - Split the 'host' and 'port' from the ip end point. - - join_host_port(host, port) -> str - Merge the 'host' and 'port'. - - fqdn(name: str = '') -> str - Return Fully Qualified Domain Name (FQDN). - - parse_IP(ip) -> str - Parse 'ip' to a real IP address - - to_IP4(ip) -> str - Get the IP4 form of 'ip'. - - to_IP16(ip) -> int - Get the IP16 form of 'ip'. - - IP_string(ip: str | int) -> str - Get the IP string. - - is_IPv4(ip: str) -> bool - Whether 'ip' is a IPv4 one. - - is_IP(ip: str) -> bool - Whether ip is a valid ip address. - - is_loopback_IP(ip: str) -> bool - Whether 'ip' is a loopback one. - - is_multicast_IP(ip: str) -> bool - Whether 'ip' is a multicast one. - - is_interface_local_multicast_IP(ip: str) -> bool - Whether 'ip' is a interface, local and multicast one. - - is_link_local_multicast_IP(ip: str) -> bool - Whether 'ip' is a link local and multicast one. - - is_link_local_unicast_IP(ip: str) -> bool - Whether 'ip' is a link local and unicast one. - - is_global_unicast_IP(ip: str) -> bool - Whether 'ip' is a global and unicast one. - - is_unspecified_IP(ip: str) -> bool - Whether 'ip' is a unspecified one. -- base64 - - encode(value: str, encoding: str = "utf-8") -> str - Encode the string `value` using the codec registered for encoding. - - decode(value: str, encoding: str = "utf-8") -> str - Decode the string `value` using the codec registered for encoding. -- crypto - - md5(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `MD5` and the codec registered for encoding. - - sha1(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA1` and the codec registered for encoding. - - sha224(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA224` and the codec registered for encoding. - - sha256(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA256` and the codec registered for encoding. - - sha384(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA384` and the codec registered for encoding. - - sha512(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA512` and the codec registered for encoding. -- manifests - - `yaml_stream(values: [any], opts: {str:} = {sort_keys = False, ignore_private = True, ignore_none = False, sep = "---"}`. This function is used to serialize the KCL object list into YAML output with the `---` separator - -### The Built-in System Package - -KCL provides a list of built-in system modules, which are loaded automatically and can be directly used without providing any module name. For example, `print` is a widely used built-in module. - -The following is the full list of these built-in system modules: - -- print() - - The print function. -- multiplyof(a, b) - - Check if the modular result of a and b is 0 -- isunique(inval) - - Check if a list has duplicated elements -- len(inval) - Return the length of a value -- abs(x) - Return the absolute value of the argument. -- all(iterable) - Return True if bool(x) is True for all values x in the iterable. If the iterable is empty, return True. -- any(iterable) - Return True if bool(x) is True for any x in the iterable. If the iterable is empty, return False. -- bin(number) - Return the binary representation of an integer. -- hex(number) - Return the hexadecimal representation of an integer. -- oct(number) - Return the octal representation of an integer. -- ord(c) -> int - Return the Unicode code point for a one-character string. -- sorted(iterable) - Return a new list containing all items from the iterable in ascending order. A custom key function can be supplied to customize the sort order, and the reverse flag can be set to request the result in descending order. -- range(start, end, step=1) - Return the range of a value with start, end and step parameter. -- min(iterable) - With a single iterable argument, return its smallest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the smallest argument. -- max(iterable) - With a single iterable argument, return its biggest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the largest argument. -- sum(iterable, start) - Return the sum of a 'start' value (default: 0) plus an iterable of numbers. When the iterable is empty, return the start value. This function is intended specifically for use with numeric values and may reject non-numeric types. -- pow(x, y, z) - Equivalent to `x**y` (with two arguments) or `x**y % z` (with three arguments). Some types, such as ints, are able to use a more efficient algorithm when invoked using the three argument form. -- round(number, ndigits) - Round a number to a given precision in decimal digits. The return value is an integer if ndigits is omitted or None. Otherwise the return value has the same type as the number. ndigits may be negative. -- typeof(x: any, \*, full_name: bool = False) -> str - Return the type of the value 'x' at runtime. When the 'full_name' is 'True', return the full package type name such as `pkg.schema`. - -### Plugin Modules - -KCL compiler needs to provide the ability to dynamically expand and load plugin modules without modifying the compiler itself. KCL compiler needs to support flexible pluggable module extension mechanism, so that KCL users can use more abundant built-in function capabilities to simplify writing. - -KCL compiler needs to ensure the stability and safety of the expansion mechanism, without affecting the core of the compiler. - -Searching extended plugin module is performed after the standard system module. The standard system module has a higher priority in naming. If it exists a standard or built-in system module with the same name, the extended plugin module will be ignored. - -Importing and using the extended plugin module should be consistent with the standard or built-in system module. - -### Replacing Standard System Packages - -Replacing standard system modules is not allowed. - -## Examples - -We show more module features through an example. - -Suppose we have the following directories and files: - -``` - . - ├── mod1.k - ├── mod2.k - ├── pkg1 - │   ├── def1.k - │   ├── def2.k - │   └── def3init.k - └── pkg2 - ├── file2.k - └── subpkg3 - └── file3.k -``` - -From the structure we can see that `pkg1` and `pkg2` are two packages, `subpkg3` is a subpackage of `pkg2`, and `mod1.k` and `mod2.k` are regular modules. - -### Importing a Standard System Package - -The following statement can import the standard system module `math` - -```python -import math -``` - -This is the only way to import a standard system module. After importing a standard system module, functions, variables and schemas defined in it can be used. For example, the following statement uses the `log10` function -defined in `math` - -```python -a = math.log10(100) # a is 2 after computation. -``` - -### Importing a Regular Module - -In `mod1.k`, we can import `mod2` using one of the following syntaxes. - -```python -import mod2 -``` - -```python -import .mod2 -``` - -The difference is that in the first syntax, the KCL compiler will first try to check if `mod2` matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where `mod1.k` resists in, like what the second statement does. - -Suppose in `mod2.k` there is a definition of a variable:: - -```python -a = 100 -``` - -After importing `mod2`, we can access `a` in `mod1.k` using the following syntax - -```python -b = mod2.a -``` - -### Importing a Package - -In `mod1.k`, we can import `pkg1` using one of the following syntaxes. - -```python -import pkg1 -``` - -```python -import .pkg1 -``` - -The difference is that in the first syntax, the KCL compiler will first try to check if `pkg1` matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where `mod1.k` resists in, like what the second statement does. - -We can use similar statements to import `pkg2`. Note that importing `pkg2` will not import `subpkg3`. - -The name of the package is the name of the imported module. - -Suppose in `file2.k` that is inside `pkg2` there is a definition to variable `foo` - -```python -foo = 100 -``` - -This variable can be used in `mod1.k` after importing `pkg2` like the following - -```python -bar = pkg2.foo -``` - -### Importing a Subpackage - -To import `subpkg3` from `mod1.k`, one of the following statements can be used. - -```python -import pkg2.subpkg3 -``` - -```python -import .pkg2.subpkg3 -``` - -The behaviors of these statements are identical. - -The name of the subpackage is the name of the imported module. - -Suppose in `file3.k` that is inside `subpkg3` there is a definition to variable `foo` - -```python -foo = 100 -``` - -This variable can be used in `mod1.k` after importing `subpkg3` like the following - -```python -bar = subpkg3.foo -``` - -### Relative Importing - -Relative importing is useful when there is code trying to import modules that does not exist recursively inside the current directory. - -For example, the following statements, if written in `file3.k`, can be used to import `pkg2`, `pkg1` and `mod2` respectively. - -```python -import ...pkg2 # Go two levels up then import pkg2 -import ...pkg1 # Go two levels up then import pkg1 -import ...mod2 # Go two levels up then import mod2 -``` - -### Importing from a Root Path - -Suppose we have a `kcl.mod` file in the directory to mark it as a root path, then we have the following files: - -``` - . - |── kcl.mod - ├── mod1.k - ├── mod2.k - ├── pkg1 - │   ├── def1.k - │   ├── def2.k - │   └── def3init.k - └── pkg2 - ├── file2.k - └── subpkg3 - └── file3.k -``` - -In `pkg1` `def1.k`, we can import `pkg2.subpkg3` `file3` using the following syntaxes. - -```python -import pkg2.subpkg3.file3 -``` - -Importing from the root path is very convenient when the code is trying to import modules from a directory needs to look up multiple directories above this directory. At also, it is helpful to organize a large number of files in a root directory. - -### Importing a Module Inside a Package - -Note that `subpkg3` is only implemented with one file `file3.k`. The file can be regarded as a regular module and imported directly. - -In `mod1.k`, the importing statement would be:: - -```python -import pkg2.subpkg3.file3 -``` - -Different from importing `subpkg3`, now the name of the module is `file3`. We can access the variable `foo` defined in this module with the following -statement - -```python -bar = file3.foo -``` - -### Precedence of Importing - -When an import statement specifies a package to import, the virtual machine first looks for a directory named according to the import statement in the file system. - -If such a directory is not found, the virtual machine looks for a single file module. - -For example, when the statement `import a.b.c` appears, the virtual machine first looks for the directory `a/b/c` from the directory of the current file. If `a/b/c` is not found, the virtual machine looks for a file named `a/b/c.k`. If the file is also absent, an error is reported. - -### Package Implemented with Multiple Files - -Package `pkg1` is implemented with multiple KCL files. - -Multiple files can be used to define variables, schemas and functions, and they can access names defined in other files of this package. - -For example, suppose `def1.k` defines a variable `foo`, `def2.k` defines `bar`, and `def3init.k` defines a variable `baz`, when `pkg1` is imported by `mod1.k`, all these variable can be used - -```python -import pkg1 -a = pkg1.foo + pkg1.bar + pkg1.baz -``` - -Inside a module, names defined in a file can be accessed in another file without further importing. For example, suppose `bar` in `def2.k` would invoke `foo` defined in `def1.k`, it can directly use `foo` like the following - -```python -bar = foo + 1 -``` diff --git a/versioned_docs/version-0.5.5/reference/lang/spec/schema.md b/versioned_docs/version-0.5.5/reference/lang/spec/schema.md deleted file mode 100644 index c3d09f65..00000000 --- a/versioned_docs/version-0.5.5/reference/lang/spec/schema.md +++ /dev/null @@ -1,916 +0,0 @@ ---- -title: "Schema" -linkTitle: "Schema" -type: "docs" -weight: 2 -description: Schema ---- - -## Syntax - -### Schema Definition - -A schema is a language element to define a type of configuration data. - -To define a schema, the syntax is the following: - -```bnf -schema_stmt: [decorators] "schema" ["relaxed"] identifier ["[" [arguments] "]"] ["(" operand_name ")"] ":" NEWLINE [schema_body] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt | schema_index_signature | statement)* [check_block] _DEDENT -``` - -Attributes could be defined in a schema, the syntax is the following: - -```bnf -schema_attribute_stmt: [decorators] identifier ["?"] ":" type [(ASSIGN | augassign) test] NEWLINE -``` - -Index signature could be defined in a schema, the syntax is the following: - -```bnf -schema_index_signature: LEFT_BRACKETS [NAME COLON] [ELLIPSIS] basic_type RIGHT_BRACKETS COLON type [ASSIGN test] NEWLINE -``` - -Once defined, an attribute must have a valid type: - -```bnf -type: type_element ("|" type_element)* -type_element: schema_type | basic_type | list_type | dict_type -schema_type: operand_name -basic_type: "str" | "int" | "float" | "bool" -list_type: "[" (type)? "]" -dict_type: "{" (type)? COLON (type)? "}" -``` - -The followings are some basic examples: - -```python -# A person has a first name, a last name and an age. -schema person: - firstName: str - lastName: str - # fullName is generated by firstName and lastName - fullName: str = firstName + ' ' + lastName - # The default value of age is 0 - age: int = 0 - -# An employee IS a person, and has some additional information. -schema employee(person): - bankCard: int - nationality: str - -# A company has a name and many employees. -schema company: - name: str - employees: [employee] -``` - -More complex schema definitions will be elaborated after other concepts are -introduced. - -#### Optional Attribute - -Each attribute **must** be assigned with a not-None value as a schema instance unless it is modified by a question mark as an optional attribute. - -Examples: - -```bnf -schema employee(person): - bankCard?: int # bankCard is an optional attribute - nationality?: str # # nationality is an optional attribute -``` - -When there is an inheritance relationship: - -- If the attribute is optional in the base schema, it could be optional or required in the sub-schema. -- If the attribute is required in the base schema, it must be required in the sub-schema. - -### Configuration Definition - -A configuration is structured data stored in a dict-like structure. In KCL, we have introduced -the configuration definition syntax as a variant of dict definition syntax. - -```bnf -schema_expr: operand_name ("(" [arguments] ")")? dict_expr -``` - -As can be seen, apart from having an identifier as schema type, a configuration definition -is just an ordinary dict definition, and each key in the dict matches an attribute in the schema. - -To simplify configuration, schema attribute key is much easier to define as: - -- schema attribute key can be unquoted. When the attribute key has the same name as a variable, it must be quoted as a normal dict to avoid naming conflict. -- schema attribute key can be defined nested through `select expression`, such as `a.b.c`. - -The comma at the end of each line can be omitted. - -For example, we can define a `person` named `John Doe` using the following statement: - -```python -johnDoe = person { - # In the result, 'lastName' appears later than 'firstName', according the schema - lastName = 'Doe' - firstName = 'John' - # If we don't specify the 'age', the default value 0 is used. - # 'age': 20 -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' - 'age': 0 -} -``` - -Compared to the ordinary dict definition, a configuration definition has the following features: - -- Each attribute defined in the schema (or one of the schemas) could be configured, and config data has higher priority than the default value. -- When an attribute defined in the schema (or one of the schemas) is not configured in the configuration definition statement, and it has a default value, the default value is used. -- Unless the schema (or one of the schemas) is a **relaxed schema**, no more attributes can be defined. -- The quotation marks of dict key can be omitted. -- The comma at the end of each line can be omitted. -- Cases of **inheritance** will be discussed separately. - -For attributes of list, dict and schema types, the config data is added by **union** instead of reassignment. For instance: - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name = { - firstNam = "John" - lastName = "default" - } - -JohnDoe = Person { - name.lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' -} -``` - -#### Attribute Identify - -Each key identifier in the configuration expr identifies an element or a range of elements in a schema. The key identifier may consist of multiple attribute identifiers, and each attribute may be a basic type value, a list, a dict or schema. For example, the key identifier 'a.b.c' identifies the element 'c' in the 'A' schema: - -```python - -schema C: - c: int - -schema B: - b: C - -schema A: - a: B - -A { - a.b.c: 5 -} -``` - -To make the key identifier usage rules as clear as possible, we define the way of identifying with complex data types as follows. - -##### List - -Suppose we have a list attribute a. - -Identify an element in a: - -```python -a[0] # the first element -a[3] # the 4th element -a[-1] # the last element -a[-2] # the penultimate element -``` - -Identify a range of elements in the list: - -```python -a[2:5] # a slice of the third, 4th, and 5th elements -a[:5] # a slice of the first to 5th elements -``` - -#### Attribute Operator - -Once we identified the element(s), we can declare operation on it. It follows the pattern of `identifier op E`. - -#### Union - -Pattern: `identifier : E` - -The value of the expression `E` will be unioned into the element value. - -Examples: - -```python -a = A { - # union {d:4} into the element b.c, suppose c is a schema with an int type attribute d. - b.c : { - d : 4 - } -} -``` - -See 'union' in `expressions` spec for more details. - -#### Override - -Pattern: `identifier = E` - -The value of the expression `E` will override the element value. - -Examples: - -```python -a = A { - # override {c:4} to the element b, suppose b is a schema with an int type attribute c. - b = { - c: 4 - } -} -``` - -Unlike union, the override operation will reassign the element with a brand new value. -For basic type value, `union` and `override` have equivalent effects. - -Note: - -- Especially, we can "delete" its content by overriding the element to `Undefined`, such as `{ a = Undefined }`. - -#### Insert - -Pattern: `identifier += E` -Insert only works for list type `identifier`. - -List `E` will be inserted just after the specified index of the list `identifier`, and the following elements after the index will be automatically shifted. - -Examples: - -```python -a = A { - # insert {c:4} to the end position(just after index=1), suppose b is a list of schema with an int type attribute c. - b += { - c: 4 - } -} -``` - -If no index is specified, the last index will be used. - -The type of 'E' must be compatible with the type of list. See `types` for more details. - -#### Index Signature - -Index signatures can be defined in the KCL schema, and it means that the key-value constraints of the index signature can be used to construct a dict with the schema type, or additional checks can be added to the relaxed schema attributes to enhance the KCL type and semantic checks. - -- Use the form `[{attr_alias}: {key_type}]: {value_type}` to define an index signature in the schema, and `{attr_alias}` can be omitted. - -```python -schema Map: - """ - Map is a relaxed schema with a key of str type and a value of str type - """ - [str]: str # `{attr_alias}` can be omitted. - -data = Map { - key1 = "value1" - key2 = "value2" -} -``` - -- Mandatory all attributes of the schema key and value types - -```python -schema Person: - name: str - age: int # error, conflicts with the index signature definition `[str]: str` - [str]: str # The values of all attributes of the schema can only be strings -``` - -- Mandatory all attribute key and value types are defined in the schema, which is equivalent to restricting all attribute types except the relaxed attributes. - -```python -schema Person: - name: str - age: int - [...str]: str # Except for the `name` and `age` attributes, the key type of all other attributes of the schema must be `str`, and the value type must also be `str`. -``` - -- Define the index signature attribute alias and use it with the check block. - -```python -schema Data: - [dataName: str]: str - check: - dataName in ["Alice", "Bob", "John"] - -data = Data { - Alice = "10" - Bob = "12" - Jonn = "8" # error Jonn not in ["Alice", "Bob", "John"] -} -``` - -```python -import regex - -schema DataMap: - [attr: str]: str - check: - regex.match(attr, r'^[-._a-zA-Z0-9]+$') - -data = DataMap { - key1 = "value1" - "foo.bar" = "value2" # check error -} -``` - -### Schema Context - -The schema definition space can be regarded as a separate function context. - -Init statement could be defined inside the schema, the syntax is the following: - -```bnf -statement: small_stmt NEWLINE | if_stmt -``` - -The following is an example: - -```python -schema Person: - firstName: str = "John" - lastName: str - # fullName is generated by firstName and lastName in a separate init statement - fullName: str = firstName + ' ' + lastName - -JohnDoe = Person { - lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' -} -``` - -If statement, expr statement and assert statement are supported as a schema init -statement. See more in statement spec. - -- The attributes must be defined first, including inherited ones, and then used in the init statement. -- Statements in the schema context will be executed sequentially. -- The value of attributes referenced in the init statement will be evaluated at runtime. - See the **Configuration Definition** section for the assignment rules of non-referenced attributes. For example, `"fullName"` in Person is generated by `"firstName"` and `"lastName"` evaluated at runtime, in which firstName is 'John', and lastName is "Doe". - -The immutability of attributes in the schema context follows the same rules as the immutability of global variables: - -```python -schema Person: - age: int = 1 # Immutable attribute - _name: str = "Alice" # Mutable attribute - - age = 10 # Error - _name = "Bob" # Ok -``` - -#### Arguments - -Schema context can also have arguments. The following is an example. - -```python -schema Person[separator]: - firstName: str = "John" - lastName: str - fullName: str = firstName + separator + lastName - -JohnDoe = Person('_') { - lastName = "Doe" -} -``` - -The example is similar to the previous one, except that the separator character used in -the `"fullName"` member is passed in as an argument. The way to perform a schema generation -when the schema has an initialization function with arguments is demonstrated in the code. - -### Check Block - -Optionally, a check block can be added to a schema definition to allow -additional checking to be performed. - -The syntax is the following: - -```bnf -check_block: "check" ":" NEWLINE _INDENT check_expr+ _DEDENT -check_expr: test (IF test)? [":" primary_expr] NEWLINE -``` - -In terms of grammatical definition, a check block consists of a list of conditional expressions. The following is an example: - -```python -schema employee(person): - bankCard: int - gender: str - - check: - len(str(bankCard)) == 16 - gender in ['male', 'female'], "The gender {} is unsupported".format(gender) -``` - -The ability of KCL check expressions covers the abilities that can be defined by OpenAPI spec and is aligned with the ability of logical expressions. We consider further aligning the syntax with `CEL` spec. -Whether to support `lambda expressions` is still under discussion. - -Summary: - -- A check block consists of one or more logical **expressions**. -- When defining a configuration, the expressions in the check block are evaluated - in any order. If any of the expression is `False`, an error is reported. -- A custom error message can be provided after an expression. - -### Specifying Types - -Optionally, the type of any member of a schema can be specified. As previous examples have shown. - -A member can be of a basic type, such as a string (`str`), a floating-point number (`float`), a fixed-point number (`int`) or a boolean number (`bool`). - -A member can also be of a dictionary generated from another schema. In such a case, the name of the other schema is used as the type name. - -A member can also be a list or an ordinary dict: - -- A list with unspecified type of elements is `[]`. -- A list with elements of type `t` is `[t]`. Here `t` is another type. -- A dict with keys of type `kt` and values of type `vt` is `{kt:vt}`. -- `kt`, `vt` or both of them can be missing, like a list with unspecified type of elements. - -The followings are some more examples: - -- A list of lists of strings: `[[str]]`. -- A dict of keys with the type string and unspecified value types: `{str:}`. - -A member can be a **union type** defined by `|`, such as `a | b`, which means the type of the member could be a or b. - -A union type can include types of `int`, `str`, `float`, `bool`, `list` and `dict` and support type nesting e.g. `{str:str|int}` and `[[int|str]|str|float]`, etc. - -Examples: - -```python -schema x: - p: int | str # p could be defined as a int or string -``` - -### Immutability - -KCL pursues strict immutability of schema attributes. It's generally followed the rules: - -- For the attributes of the basic type, such as string, int and float, it's allowed to be reassigned - through the init statement in **schema context** or by the **configuration definition**. -- For the attributes of list, dict and schema type, it's allowed to be reassigned only by the init statement in **schema context**. The content of it is allowed to be operated in **schema context** or by the **configuration definition**. -- Any other attempt to reassign or modify schema attribute will report an error. - -#### Assign by Value - -When using a schema variable to assign the value to another variable, we can only get a deep copy of its value, not a pointer or reference. That is, modifying the assigned value will not change the assigned schema variable. - -```python -schema Person: - name: str - -person = { - name = "Alice" -} -personCopy = person # 'personCopy' is a deep copy of 'person' and modifying 'personCopy' will not affect 'person' -``` - -### Union Operator - -For list, dict and schema, we can union delta to existing data. For example: - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name = { - firstName = "John" - } - - # union a schema and a dict - name: Name { - lastName = "Doe" - } - -person = Person {} -``` - -The result is a **dict**: - -```python -{ - 'person': { - 'name': { - 'firstName': 'Jhon', - 'lastName': 'Doe' - } - } -} -``` - -### Other Operators - -Except for `assignment` and `union assignment`, it's not support other operators on schema type data. -Report an error if trying to use other operators on schema type data. - -### Deprecated - -The schema attribute can be marked as deprecated once it's considered invalid. - -```python -schema Person: - @deprecated(version="1.1.0", reason="use fullName instead", strict=True) - name: str - ... # Omitted contents - -person = Person { - # report an error on configing a deprecated attribute - name = "name" -} -``` - -- Deprecated attributes cannot be configured under any circumstances. Report an error or warning once the attribute is assigned. -- Define the expired version of the attribute through **version**, and define the reason for the attribute expired through **reason**. -- When strict is true, the attribute assignment will cause an error, otherwise it will report a warning and ignore the attribute assignment. - -### Composition - -The composition is a common way to define complex structures. KCL provides simplified means for the configuration definition of combined structures. - -Assuming we have the following schemas, which is defined by a combination of multiple schemas. - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name - age: int - -schema Group: - name: str - persons: [Person] -``` - -To config a group: - -```python -group = Group { - name = "group" - persons = [{ - name = { - firstName = "John" - lastName = "Doe" - } - age = 24 - }] -} -``` - -- Top-level schema name is required to config a schema. -- The schema of the attributes in the schema can be omitted. - -Multi-level nested schemas will make the configuration verbose. KCL supports defining attributes in the schema through `selector expression`. The selector form is **x.y.z**, see the following example: - -```python -group = Group { - name = "group" - persons = [{ - name.firstName = "John" - name.lastName = "Doe" - age = 24 - }] -} -``` - -- Selector can be used to represent attribute in a schema - -### Inheritance - -Inheritance is an effective means to define a hierarchical structure definition, and KCL supports limited **single inheritance** of the schema. - -```python -schema Person: - firstName: str - lastName: str - -# schema Scholar inherits schema Person -schema Scholar(Person): - fullName: str = firstName + '_' + lastName - subject: str - -JohnDoe = Scholar { - firstName = "John", - lastName = "Doe", - subject = "CS" -} -``` - -The result is a **dict**: - -```python -{ - 'JohnDoe': { - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' - 'subject': 'CS' - } -} -``` - -Each schema can be treated as a separated function context. Statements, including attribute statements and init statements, in the context of schemas will be evaluated from base schema to subschema according to the inheritance order. Each schema context is evaluated only once sequentially. The same goes for expressions in the check block. In the example, firstName and lastName are configured in the context of Person schema, and fullName is formed by splicing firstName and lastName in the context of Scholar schema. - -The default value can be modified in each schema. Value defined in **Configuration Definition** has a higher priority than the default value. Attributes with default values in any schema context ​​will eventually be unioned by configuration data. References to attributes in the schema context statements will use the value with unioned configuration data on evaluating at runtime. For example: - -```python -schema a: - x = 1 - y = x * 2 - -schema b(a): - x = 2 - -v = a { - x = 3 -} - -``` - -The result is a **dict**: - -```python -{ - 'v': { - 'x': 3 - 'y': 6 - } -} -``` - -Notes: - -- Report an error if inheriting more than one base schema. -- The type of the base schema attribute cannot be modified in the subschema. -- Report an error if inheriting a **mixin**. -- Report an error when a circular dependency occurs. - -Limitations: - -Since inheritance will derive some complex demands, we are cautious about these complex demands. There are still some restrictions on inheritance, and it's still under discussion. - -- KCL provides limited and deterministic polymorphism support, more complex and flexible polymorphism support, such as **self**, **super** keywords, are temporarily not included in the schema definition. -- Currently, KCL only supports the polymorphism of the inherited attributes of the schema, and does not support the polymorphism of the expressions in the check block. -- For the case of multiple levels of schema inheritance, the schema arguments can only be passed to the last level of sub-schema. - -### Mixin - -In addition to **composition** and **inheritance**, KCL supports declarative reuse of schema code through the **mixin** mechanism. To use a mixin, we only need to declare the **mixin** in the schema definition. - -The **mixin** syntax is the following: - -```bnf -//////////// mixin_stmt //////////// -mixin_stmt: "mixin" "[" [mixins | multiline_mixins] "]" "\n" -multiline_mixins: "\n" _INDENT mixins "\n" _DEDENT -mixins: operand_name ("," ("\n" mixins | operand_name))* -``` - -Here is a simple example: - -```python -schema Person: - mixin [FullNameMixin] - firstName: str = "default" - lastName: str - -schema FullNameMixin: - fullName: str = "{} {}".format(firstName, lastName) - -JohnDoe = Person { - firstName = "John" - lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'JohnDoe': { - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' - } -} -``` - -Multiple mixins can be added to a single schema, and mixins context will be evaluated after the host schema context at runtime. In the inheritance scenario, the mixin context can be regarded as a part of the host schema context, and the overall evaluation of schema context order is not affected. - -Notes: - -- The name of **mixin** schema must end with 'Mixin', otherwise an error will be reported. -- The attributes referenced in the **mixin** must be defined in the **mixin** itself or host schema, otherwise an error will be reported. - -### Protocol - -In addition to schema, an additional type definition method `protocol` is provided in KCL, and its properties are as follows: - -- In a protocol, only attributes and their types can be defined, complex logic and check expressions cannot be written, and mixins cannot be used. -- A protocol can only inherit or refer to other protocols, but cannot inherit or refer to other schemas. - -We can use **protocol** to add an optional host type to the dynamically inserted **mixin**. - -The **mixin** can define its host type through the `for` keyword, and internally it will query the type corresponding to the attribute from the host type. - -```python -protocol DataProtocol: # A mixin host type - data: str - -mixin DataMixin for DataProtocol: # Using the `for` keyword to define a mixin host type - x: int = data # The type of `data` is `str`, which is from `data` of `DataProtocol` -``` - -In `DataMixin`, the `data` attribute is obtained according to the `DataProtocol` host type as `str` type, and then a type error will occur when the value is assigned to `x` of type `int`: - -```python -protocol DataProtocol: - data: str - -mixin DataMixin for DataProtocol: - x: int = data # Error: expect int, got str - x: str = data # Error: can't change schema field type of 'x' from int to str -``` - -Please note that the host type **protocol** can only be used for **mixin** definitions (the suffix name is `Mixin`), otherwise an error will be reported. - -```python -protocol DataProtocol: - data: str - -schema Data for DataProtocol: # Error: only schema mixin can inherit from protocol - x: str = data -``` - -### Schema Context Evaluation - -The schema definition is composed of attribute statements, configuration data, init statements, mixins, and checks. In a separate schema context, the evaluation top-down order is as follows: - -``` -|------------------------------------------| -| attribute defaulting | -|------------------------------------------| -| configuration union | -|------------------------------------------| -| attribute templating | -|------------------------------------------| -| statements in declaration order | -|------------------------------------------| -| mixins in declaration order | -|------------------------------------------| -| check expressions in any order | -|------------------------------------------| -``` - -In the case of schema inheritance, each schema context is evaluated from the base schema in the order of inheritance, and each context is evaluated only once. -Suppose there are schemas a, b, and c, where c inherits b and b inherits a. Schema contexts will be evaluated in top-down order as: - -``` -|-----------------| -| schema a | -|-----------------| -| schema b | -|-----------------| -| schema c | -|-----------------| -``` - -### Members - -Built-in function and members of schema - -- instances() - Return the list of existing instances of a schema. - -### Irrelevant Order Calculation - -The irrelevant order calculation in the schema indicates the reference relationship between the internal attributes of the schema. For example, when we declare an expression of the form `a = b + 1`, the calculation of the value of `a` depends on the calculation of the value of `b`. When the compiler calculate the value of `a` and the value of `a` depends on the value of `b`, the compiler will choose to first calculate the value of `b`, and then calculate the value of a according to the expression `a = b + 1`, which is slightly different from the calculation method of traditional procedural language the difference. - -Since the calculation of values in the schema is based on dependencies, just like a directed acyclic graph traverses each node in the graph according to the order of topological sorting, the order of declaration of attributes in the schema is not so important, so the feature is called the irrelevant order calculation. - -Please note that there can be no circular references between different schema attribute values. - -We can see this feature through the following examples. - -```python -schema Person: - name?: str - age: int = _age - - _age = 10 - - if name == "Son": - _age = 18 - -schema Son(Person): - name: str = "Son" - -person = Person {} -son = Son {} -``` - -The output is - -```yaml -person: - name: null - age: 10 -son: - name: Son - age: 18 -``` - -Besides, we can achieve KCL polymorphism such as - -```python -schema Person: - name?: str - _age: int = _age - - _age = 10 - if name == "Son": - _age = 18 - elif name == "SonConf": - _age = 24 - -schema Son(Person): - name: str = "Son" - -person = Person() {} -son = Son() { - name = "SonConf" -} -``` - -The output is - -```yaml -person: - name: null - age: 10 -son: - name: SonConf - age: 24 -``` - -More examples: - -```python -schema Fib: - n1: int = n - 1 - n2: int = n1 - 1 - n: int - value: int = _value - - if n <= 2: - _value = 1 - else: - _value = (Fib {n = n1}).value + (Fib {n = n2}).value - -fib8 = (Fib {n = 8}).value -``` - -The output is - -```yaml -fib8: 21 -``` - -As in the above examples, we can see that in the schema, we only need to simply specify the dependency between attributes, and the compiler will automatically calculate the value based on the dependency, which can help us save a lot of boilerplate code and reduce configuration difficulty of writing. diff --git a/versioned_docs/version-0.5.5/reference/lang/spec/statements.md b/versioned_docs/version-0.5.5/reference/lang/spec/statements.md deleted file mode 100644 index b09488b9..00000000 --- a/versioned_docs/version-0.5.5/reference/lang/spec/statements.md +++ /dev/null @@ -1,185 +0,0 @@ ---- -title: "Statements" -linkTitle: "Statements" -type: "docs" -weight: 2 -description: Statements ---- - -## Syntax - -In KCL, statements consist of small statements and compound statements. The syntax is the following: - -```bnf -preamble_statement: preamble_small_stmt | preamble_compound_stmt -preamble_small_stmt: (small_stmt | import_stmt) NEWLINE -preamble_compound_stmt: compound_stmt | schema_stmt -statement: small_stmt NEWLINE | compound_stmt -compound_stmt: if_stmt -small_stmt: assign_stmt | expr_stmt | assert_stmt -``` - -The preamble statement is used to define the module level statements, consist of `statement`, `import_stmt`, and `schema_stmt`. The statement is used to define the block level statements, which are used in the `if` statement and `schema` statement. - -### Small Statements - -A small statement is comprised of a single logical line. Multiple statements in one-line are not allowed. - -#### Assignment Statements - -Generally, assign_stmt is divided into assignment and augmented assignment. The syntax is the following: - -```bnf -assign_stmt: target_primary ("=" target_primary)* "=" test | target_primary augassign test -augassign: "+=" | "-=" | "*=" | "**=" | "/=" | "//=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>=" | "or" | "and" -target_primary: identifier | target_primary DOT identifier -``` - -An assignment statement has the form `lhs = rhs`. It evaluates the expression on the right-hand side then assigns its value (or values) to the variable (or variables) on the left-hand side. - -The **target_primary** on the left-hand side is an `identifier` or an `identifier` followed by select dots. - -Note: When using **target_primary** will cause collisions, use **primary_expr** as an alternative. - -Examples: - -```python -k = 1 -a.b = "a.b" -``` - -To keep it simple, the compound target is not supported as **target_primary**. - -The right value of an assignment statement is a conditional expression, which is discussed separately. - -An augmented assignment, which has the form `lhs op= rhs` updates the variable `lhs` by applying a binary arithmetic operator op (one of +, -, \*, /, //, %, &, |, ^, <<, >>) to the previous value of `lhs` and the value of `rhs`. - -The **target_primary** on the left-hand side is the same as assignment statement. Examples: - -```python -_x -= 1 -_filename += ".k" -``` - -There is no concept of in-place modification in KCL. The `augassign` statement will modify a copy of the **target_primary** and assign the copy to **target_primary**. - -In particular, in KCL, the `|=` symbol represents the **union** operation, which is defined as follows: - -- The behavior of the **union** operation needs to be consistent with the behavior of the **configuration definition**. - -See **expressions** spec for more details of union operator in **Arithmetic Operations**. - -#### Expression Statements - -An expression statement evaluates an expression and discards its result. - -Syntax: - -```bnf -expr_stmt: expression -``` - -An expression statement supported in KCL is function invocation expression, which is discussed in **expression** spec. - -```python -print(k) # print a variable -``` - -#### Import Statements - -Import statements are used to **search** and **load** a module, and define a name or names in the local namespace for the scope where the import statement occurs. - -Syntax: - -```bnf -import_stmt: "import" dot_name ("as" NAME)? -dot_name: [leading_dots] identifier (DOT identifier)* -leading_dots: "."+ -``` - -Examples: - -```python -import math # import a built-in module math -import pkg # import pkg -import pkg.foo # import pkg.foo -import pkg.subpkg # import a subpkg in a pkg -import .pkg2.subpkg3 # import a subpkg in a pkg inside of current pkg -import ...pkg2 # Go two levels up then import pkg2 -``` - -See **module** spec for more details of module spec. - -#### Assert Statements - -Assert statements are a convenient way to insert debugging assertions into KCL code. - -The syntax is the following: - -``` -assert_stmt: ASSERT test ("," test)? -``` - -The conditional expression in assert will be evaluated and get a boolean. Report an error if returning a `False`. - -Examples: - -```python -assert: x > 1 # report an error on x <= 1 -``` - -#### Conditional Statements - -KCL allows using conditional statements to control the instructions to -be executed. They are also called the control-flow statements. - -The only type of control-flow syntax is the well-known `if-elif-else` syntax. - -The syntax of the `if-elif-else` statement is the following. - -```bnf -if_stmt: "if" test ":" suite ("elif" test ":" suite)* (ELSE ":" suite)? -suite: small_stmt | NEWLINE _INDENT statement+ _DEDENT -``` - -An `if` or `elif` statement evaluates a given expression. When the expression -is evaluated to `True`, a list of statements following `:` are executed. - -The following is an example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - print("maybe a is negative") -else: - print("a >= 100") -``` - -`if-elif-else` statements can be nested. For example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - if a < 0: - print("a is negative") - print("No matter a is negative or positive, this message is printed") -else: - print("a >= 100") -``` - -#### Schema Statements - -Schema statements are used to define a type of configuration data. The syntax is the following: - -```bnf -schema_stmt: [decorators] "schema" ["relaxed"] identifier ["[" [arguments] "]"] ["(" operand_name ")"] ":" NEWLINE [schema_body] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt | statement)* [check_block] _DEDENT -``` - -See **schema** spec for more details of schema spec. diff --git a/versioned_docs/version-0.5.5/reference/lang/spec/variables.md b/versioned_docs/version-0.5.5/reference/lang/spec/variables.md deleted file mode 100644 index b3e1c539..00000000 --- a/versioned_docs/version-0.5.5/reference/lang/spec/variables.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: "Variables" -linkTitle: "Variable" -type: "docs" -weight: 2 -description: Variable ---- - -In KCL, variables can be defined using assign statements. For example, the following statement defines a variable `spam` to a string `"ham"`. - -```python -spam = "ham" -``` - -There are two types of variables, which are global variables and list comprehension local variables. - -- A global variable is defined not within any context. -- A comprehension local variable is defined inside a comprehension. - -A variable can be used after definition, until the end of the current scope. - -For a global variable, the scope is the module it is defined in. Note that a module can consists of multiple source files. - -For a list comprehension local variable, the scope is the list comprehension it is defined in. - -More information on modules, list comprehensions and scopes will be discussed in later chapters. - -## Immutability - -Global variables are immutable. In other words, once defined such a variable cannot be redefined (or, i.e., modified). - -The following code is illegal, and KCL will report an error during evaluation. - -```python -spam = "ham" -spam = "eggs" # Error: The immutability rule is violated! -``` - -- A variable starts with the `_` character is mutable. - -```python -_spam -cond = True -if cond: - _spam = "ham" -else: - _spam = "eggs" -``` - -## Variable Exporting - -As shown in the preview chapter, KCL is able to export evaluation results to the standard output according to a target data format. - -The rules are the followings: - -- Living global variables at the end of an evaluation will be dumped out. -- If the name of a variable starts with the `_` character, it will not be dumped out. - -## Uniqueness of Exported Variable Identifier - -Each exported variable identifier must be unique in its package, so that an exported variable could be located uniquely by package location path and variable identifier, such as 'a.b.c:var', in which 'a.b.c' locates a package. - -Two variable identifiers are different if: - -- they are spelled differently -- they are defined in different packages and are not compiled in a single execution - -Identifying an exported variable should be supported by the kcl compiler, which needs to provide corresponding identifying features through the command line and api form. diff --git a/versioned_docs/version-0.5.5/reference/lang/tour.md b/versioned_docs/version-0.5.5/reference/lang/tour.md deleted file mode 100644 index f7acf49c..00000000 --- a/versioned_docs/version-0.5.5/reference/lang/tour.md +++ /dev/null @@ -1,3324 +0,0 @@ ---- -title: "KCL Tour" -sidebar_position: 1 ---- - -This page shows how to use major KCL features, from variables and operators to schemas and libraries, with the assumption that you have already known how to program in another language. KCL is mainly inspired by Python, and knowing Python is very helpful for learning KCL. - -### Important Concepts - -As we learn about the KCL language, keep these facts and concepts in mind: - -- KCL is a configuration and policy language. It provides simplified and self-contained language design and library support for writing configurations and policies. It cannot be used for application development or other purposes supported by General Purpose Language (GPL). -- KCL absorbs classic **OOP** elements and provides simple, developer-friendly and reliable configuration writing practice with **type**, **reusing**, and **union**. -- KCL prefers **immutability** and recommend to add up incremental updates through the **union**. Immutability reduces side effects like unpredictable issues. -- KCL **schema** struct defines strict attributes, static types, and it also supports validation expressions. The **schema** struct is mainly composed of typed attributes, the schema context and the check block. -- KCL **config** is a **json**-like expression, by which we can reuse a full definition of the schema. KCL provides support for definition and configuration by separating schema and config. -- KCL **rule** is a structure for writing rule constraint expressions, which can be used for data verification and policy writing. -- KCL code files are managed as packages(directories) and modules(files). The schema types in the same package are visible to each other; the data cross packages need to be imported through the **import statement**. The package-level variables can be exported, but they are immutable for other packages. -- The KCL syntax definition mainly uses declarative expressions, and only provides a small number of necessary and imperative statements, such as import, if .. else, assert, assignment and schema. -- No main function, each `.k` file could be executed as a separate configuration. -- **Built-in functions** and **plugins** are supported to simplify coding. - -### Keywords - -The following table lists the words that the KCL language treats specially. - -```txt -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -### Identifiers - -In KCL, an identifier is a name, may with selectors, that identifies a value. - -- Identifiers consist of letters, numbers, underscores or the prefix `$`. -- Identifiers cannot be repeated with keywords unless they have a `$` prefix. -- Identifiers must not contain any embedded spaces or symbols. -- Letters and underscores can be used anywhere in the identifier. -- Numbers cannot be placed in the first place of the identifier. -- The `$` character can only be placed in the first position of the identifier. - -Examples: - -```python -x -a -b1 -b_2 -_c -$if -``` - -To simplify the definition of the qualified identifier, such as `pkg.type`, we additionally define `qualified identifier`: - -Examples: - -```python -pkg.a -``` - -The package name in `qualified identifier` must be imported. - -#### Identifier Prefix - -Use the `$` character prefix to define keyword identifiers. - -```python -$if = 1 -$else = "s" -``` - -Please note: whether the non-keyword identifier is prefixed with `$` has the same effect. - -```python -_a = 1 -$_a = 2 # equal to `_a = 2` -``` - -### Variables - -Here’s an example of how to create a variable and initialize it: - -```python -name = "Foo" # Declare a variable named `name` and its value is a string literal "Foo" -``` - -It corresponds to the following YAML output: - -```yaml -name: Foo -``` - -In KCL, we can export variables as config data by defining package-level variables. To make it direct, clear, and maintainable. Exported variables are immutable so that once we declare it, we can't modify it. For example, assume we have a config file named `example.k`, the variable `name` can't be modified after the declaration, just like the standard imperative language. - -```python -name = "Foo" # exported - -... - -name = "Bar" # error: a exported declaration variable can only be set once. -``` - -As a complement, we can define a non-exported variable in module level which is mutable, which won't show up in YAML output: - -```python -_name = "Foo" # _ variables are not output to YAML and are mutable -_name = "Bar" -``` - -Please note that the variable name cannot be one of `True`, `False`, `None`, `Undefined` because of ambiguity. - -```python -False = 1 # Error -True = False # Error -None = Undefined # Error -Undefined = None # Error -``` - -### Built-in Types - -The KCL language has special support for the following types: - -- number -- string -- boolean -- list -- dict - -#### Number - -KCL number comes into two flavors: - -- **Int**: 64 bits signed integer values. Values can be from -9223372036854775808~9223372036854775807. -- **Float**: 64-bit floating-point numbers, as specified by the IEEE 754 standard. We do not recommend using the float type in the configuration, we can use a string instead and parse it during runtime processing. - -Both int and float support basic operators such as `+`, `-`, `/`, and `*`, while complex operations, such as `abs()`, `ceil()`, and `floor()`, are supported through the built-in math library. - -Integers are numbers without a decimal point. Here are some examples of defining integer literals: - -```python -a = 1 -b = -1 -c = 0x10 # hexadecimal literal -d = 0o10 # octal literal -e = 010 # octal literal -f = 0b10 # binary literal -g = int("10") # int constructor -``` - -If a number includes a decimal point, it is a float number. Here are some examples of defining float literals: - -```python -a = 1.10 -b = 1.0 -c = -35.59 -d = 32.3e+18 -f = -90. -h = 70.2E-12 -i = float("112") # float constructor -``` - -Built-in math libraries can be used with numbers: - -```python -import math - -assert abs(-40) == 40 -assert round(70.23456) == 70 -assert min(80, 100, 1000) == 80 -assert max(80, 100, 1000) == 1000 -assert sum([0,1,2]) == 3 -assert math.ceil(100.12) == 101.0 -assert math.floor(100.12) == 100.0 -assert math.pow(100, 2) == 10000.0 -``` - -In addition, please note that the KCL number is 64-bit by default. We can perform a stricter 32-bit range check by adding the `-r` parameter to the KCL command-line tool. - -```bash -kcl main.k -r -d -``` - -Please note that the value range check is only enabled in `debug` mode - -##### Units - -In KCL, we can add a unit suffix to an integer denomination to indicate that it does not affect its true value as follows. - -- General integer or fixed-point number form: `P`, `T`, `G`, `M`, `K`, `k`, `m`, `u`, `n` -- Corresponding power of 2: `Pi`, `Ti`, `Gi`, `Mi`, `Ki` - -```python -# SI -n = 1n # 1e-09 -u = 1u # 1e-06 -m = 1m # 1e-03 -k = 1k # 1000 -K = 1K # 1000 -M = 1M # 1000000 -G = 1G # 1000000000 -T = 1T # 100000000000 -P = 1P # 1000000000000000 -# IEC -Ki = 1Ki # 1024 -Mi = 1Mi # 1024 ** 2 -Gi = 1Gi # 1024 ** 3 -Ti = 1Ti # 1024 ** 4 -Pi = 1Pi # 1024 ** 5 -``` - -Besides, And we can also use the unit constants defined in the `units` module as follows: - -```python -import units - -n = 1 * units.n # 1e-09 -u = 1 * units.u # 1e-06 -m = 1 * units.m # 1e-03 -k = 1 * units.k # 1000 -K = 1 * units.K # 1000 -M = 1 * units.M # 1000000 -G = 1 * units.G # 1000000000 -T = 1 * units.T # 1000000000000 -P = 1 * units.P # 1000000000000000 -# IEC -Ki = 1 * units.Ki # 1024 -Mi = 1 * units.Mi # 1024 ** 2 -Gi = 1 * units.Gi # 1024 ** 3 -Ti = 1 * units.Ti # 1024 ** 4 -Pi = 1 * units.Pi # 1024 ** 5 -``` - -We can also use the methods in the `units` module to convert between integers and unit strings. - -```python -import units -# SI -K = units.to_K(1000) # "1K" -M = units.to_M(1000000) # "1M" -G = units.to_G(1000000000) # "1G" -T = units.to_T(1000000000000) # "1T" -P = units.to_P(1000000000000000) # "1P" -# IEC -Ki = units.to_Ki(1024) # "1Ki" -Mi = units.to_Mi(1024 ** 2) # "1Mi" -Gi = units.to_Gi(1024 ** 3) # "1Gi" -Ti = units.to_Ti(1024 ** 4) # "1Ti" -Pi = units.to_Pi(1024 ** 5) # "1Pi" -``` - -```python -import units -# SI -K = units.to_K(int("1M")) # "1000K" -M = units.to_M(int("1G")) # "1000M" -G = units.to_G(int("1T")) # "1000G" -T = units.to_T(int("1P")) # "1000T" -P = units.to_P(int("10P")) # "10P" -# IEC -Ki = units.to_Ki(int("1Mi")) # "1024Ki" -Mi = units.to_Mi(int("1Gi")) # "1024Mi" -Gi = units.to_Gi(int("1Ti")) # "1024Gi" -Ti = units.to_Ti(int("1Pi")) # "1024Ti" -Pi = units.to_Pi(int("10Pi")) # "10Pi" -``` - -The unit value type is defined in the units module, and the unit value type does not allow any four calculations. - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -x0: NumberMultiplier = 1M # Ok -x1: NumberMultiplier = x0 # Ok -x2 = x0 + x1 # Error: unsupported operand type(s) for +: 'number_multiplier(1M)' and 'number_multiplier(1M)' -``` - -We can use the `int()`, `float()` function and `str()` function to convert the numeric unit type to the normal integer type and string type. - -```python -a: int = int(1Ki) # 1024 -b: float = float(1Ki) # 1024.0 -c: str = str(1Mi) # "1Mi" -``` - -#### String - -The string is an immutable sequence of Unicode characters. We can use either single or double quotes to create a string: - -```python -'allows embedded "double" quotes' # Single quotes -"allows embedded 'single' quotes" # Double quotes -'''Three single quotes''', """Three double quotes""" # Triple quoted -``` - -Triple quoted strings may span multiple lines. - -```python -"""This is a long triple quoted string -may span multiple lines. -""" -``` - -Please note that there is almost no difference in the use of KCL single-quoted and double-quoted strings. The only thing that can be simplified is that we don’t need to escape double quotes in single quoted strings, and we don’t need to escape single quotes in double quoted strings. - -```python -'This is my book named "foo"' # Don’t need to escape double quotes in single quoted strings. -"This is my book named 'foo'" # Don’t need to escape single quotes in double quoted strings. -``` - -We can concatenate strings using the `+` operator: - -```python -x = 'The + operator ' + 'works, as well.' -``` - -We can cast an int or float to a string using the built-in function `str`: - -```python -x = str(3.5) # "3.5" -``` - -A lot of handy built-in functions and members of a string could be used: - -```python -x = "length" -assert len(x) == 6 # True -assert x.capitalize() == "Length" -assert x.count("gt") == 1 -assert x.endswith("th") == True -assert x.find("gth") == 3 -assert "{} {}".format("hello", "world") == 'hello world' -assert x.index("gth") == 3 -assert x.isalnum() == True -assert x.isalpha() == True -assert "123456".isdigit() == True -assert x.islower() == True -assert " ".isspace() == True -assert "This Is Title Example".istitle() == True -assert x.isupper() == False -assert "|".join(["a", "b", "c"]) == "a|b|c" -assert "LENGTH".lower() == "length" -assert ' spacious '.lstrip() == 'spacious ' -assert x.replace("th", "ht") == "lenght" -assert "lengthlength".rfind("le") == 6 -assert "lengthlength".rindex("le") == 6 -assert "length length".rsplit() == ["length", "length"] -assert "length ".rstrip() == "length" -assert "length length".split() == ["length", "length"] -assert 'ab c\n\nde fg\rkl\r\n'.splitlines() == ['ab c', '', 'de fg', 'kl'] -assert "length".startswith('len') == True -assert "***length***".strip('*') == "length" -assert "length length".title() == "Length Length" -assert x.upper() == "LENGTH" -``` - -There are 2 different ways to format a string: to use the `"{}".format()` built-in function, or to specify the variable between the curly braces and use a `$` mark to tell KCL to extract its value. This is called **string interpolation** in KCL. In following example, both `a` and `b` will be assigned to string `"hello world"`. - -Besides, the variable to serialized can be extracted in special data format, such as YAML or JSON. In this case, a `#yaml` or `#json` can be included within the curly braces. - -Specifically, when the dollar sign `$` itself is needed in a **string interpolation**, it needs to be escaped and use `$$` instead. Or in another way, `+` can be used to concat the dollar sign with the **string interpolation** to avoid that escape. In following example, both `c` and `c2` will be assigned to string `$hello world$` - -```python -world = "world" -a = "hello {}".format(world) # "hello world" -b = "hello ${world}" # "hello world" -c = "$$hello ${world}$$" # "$hello world$" -c2 = "$" + "hello ${world}" + "$" # "$hello world$" - -myDict = { - "key1" = "value1" - "key2" = "value2" -} - -d = "here is myDict in json: ${myDict: #json}" -# d: 'here is myDict in json: {"key1": "value1", "key2": "value2"}' - -e = "here is myDict in yaml:\n${myDict: #yaml}" -# e: | -# here is myDict in yaml: -# key1: value1 -# key2: value2 -``` - -Besides, we can see some symbols in the example code output **YAML string** above such as `|`, `>`, `+`, `-`. - -- `|` denotes the **block literal style** that indicates how newlines inside the block should behave. -- `>` denotes the **block folded style** in the block scalar that the newlines will be replaced by spaces. -- `+` and `-` are the **block chomping indicators** that control what should happen with newlines at the end of the string. The default value **clip** puts a single newline at the end of the string. To remove all newlines, **strip** them by putting a `-` after the style indicators `|` or `>`. Both clip and strip ignore how many newlines are actually at the end of the block; to **keep** them all put a `+` after the style indicator. - -For example, a **strip block literal style** yaml string is - -```yaml -example: |- - Several lines of text, - with some "quotes" of various 'types', - and also a blank line: - - plus another line at the end. -``` - -The result is - -```plain -Several lines of text, -with some "quotes" of various 'types', -and also a blank line: - -plus another line at the end. -``` - -See [Yaml Multiline String](https://yaml-multiline.info/) and [YAML Specification v1.2](https://yaml.org/spec/1.2.1/) for more information. - -##### Raw String - -KCL raw string is created by prefixing a string literal with `'r'` or `'R'`. KCL raw string treats backslash (`\`) and string interpolation (`${}`) as a literal character. This is useful when we want to have a string that contains backslash, string interpolation and don’t want them to be treated as an escape character. - -- For backslash (`\`), the KCL code and output YAML are as follows: - -```python -s = "Hi\nHello" -raw_s = r"Hi\nHello" # This is a KCL raw string with the `r` prefix. -``` - -```yaml -s: |- - Hi - Hello -raw_s: Hi\nHello -``` - -- For string interpolation (`${}`), the KCL code and output YAML are as follows: - -```python -worldString = "world" -s = "Hello ${worldString}" -raw_s = r"Hello ${worldString}" # This is a KCL raw string with the `r` prefix. -``` - -```yaml -worldString: world -s: Hello world -raw_s: Hello ${worldString} -``` - -In addition, the most common scenario for raw strings is to be used with regular expressions: - -```python -import regex - -key = "key" -result = regex.match(key, r"[A-Za-z0-9_.-]*") # True -``` - -#### Boolean - -Boolean values are the two constant objects `False` and `True`. - -```python -a = True -b = False -``` - -#### List - -The list is a sequence, typically used to store collections of homogeneous items. Here’s a simple KCL list: - -```python -list = [1, 2, 3] -assert len(list) == 3 # True -assert list[0] == 1 # True -``` - -We can declare a list with list comprehension: - -```python -list = [ _x for _x in range(20) if _x % 2 == 0] -assert list == [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] # True -``` - -We can perform nested list comprehension: - -```python -matrix = [[1, 2], [3,4], [5,6], [7,8]] -transpose = [[row[_i] for row in matrix] for _i in range(2)] -assert transpose == [[1, 3, 5, 7], [2, 4, 6, 8]] # True -``` - -Besides, we can use two variables in the list comprehension, the first variable denotes the list index and the second variable denotes the list item. - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use `_` to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -We can merge list like this: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -joined_list = _list0 + _list1 # [1, 2, 3, 4, 5, 6] -``` - -We can also use the list unpacking operator `*` to merge multiple lists: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -union_list = [*_list0, *_list1] # [1, 2, 3, 4, 5, 6] -``` - -We can use `if expressions` to dynamically add elements to the list element, elements that meet the conditions are added to the list, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = [ - 1 - if a == 1: 2 - if a > 0: 3 - if a < 0: 4 -] # [1, 2, 3] -``` - -```python -a = 1 # 1 -data1 = [ - 1 - if a == 1: - 2 - elif a == 2: - 3 - else: - 3 -] # [1, 2] -data2 = [ - 1 - if a == 1: 2 - elif a == 2: 2 - else: 3 -] # [1, 2] -``` - -Please note that in the above `if expressions`, nested use is not supported. - -We can union two lists like this: - -```python -_list0 = [1, 2, 3] -_list1 = [4, 5, 6] -union_list = _list0 | _list1 # [4, 5, 6] -``` - -We can use the expression `for k in list_var` to traverse a list. - -```python -data = [1, 2, 3] -dataAnother = [val * 2 for val in data] # [2, 4, 6] -``` - -#### Dict - -Dict is a mapping object that maps hashable values to arbitrary objects. Dict is ordered. The order of the keys follows the order of their declaration. - -Here are a couple of simple KCL dict, created using dict literals: - -```python -a = {"one" = 1, "two" = 2, "three" = 3} -b = {'one' = 1, 'two' = 2, 'three' = 3} -assert a == b # True -assert len(a) == 3 # True -``` - -We can ignore the comma `,` at the end of the line for writing dict key-value pairs in multiple lines: - -```python -data = { - "key1" = "value1" # Ignore the comma ',' at the end of line - "key2" = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -We can ignore the key quotation marks when we writing simple literals on the key. - -```python -data = { - key1 = "value1" # Ignore key quotation '"' - key2 = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -In addition, the **config selector expressions** can be used to init a dict instance with nested keys. - -```python -person = { - base.count = 2 - base.value = "value" - labels.key = "value" -} # {"base": {"count": 2, "value": "value"}, "labels": {"key": "value"}} -``` - -The output YAML is - -```yaml -person: - base: - count: 2 - value: value - labels: - key: value -``` - -In KCL, different fields in dict can be referenced, such as the following example. - -```python -config = { - name = "me" - metadata.name = name # Reference `name` with the value `"me"` in `config` directly. -} -``` - -The output YAML is - -```yaml -config: - name: me - metadata: - name: me -``` - -We can declare a dict with dict comprehension: - -```python -x = {str(i): 2 * i for i in range(3)} -assert x == {"0" = 0, "1" = 2, "2" = 4} -``` - -Besides, we can use two variables in the dict comprehension, the first variable denotes the dict key and the second variable denotes the dict value of the key. - -```python -data = {key1 = "value1", key2 = "value2"} -# Single variable loop -dataKeys1 = {k: k for k in data} # {"key1": "key1", "key2": "key2"} -dataValues1 = {k: data[k] for k in data} # {"key1": "value1", "key2": "value2"} -# Double variable loop -dataKeys2 = {k: k for k, v in data} # {"key1": "key1", "key2": "key2"} -dataValues2 = {v: v for k, v in data} # {"value1": "value1", "value2": "value2"} -dataFilter = {k: v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use `_` to ignore loop variables -dataKeys3 = {k: k for k, _ in data} # {"key1": "key1", "key2": "key2"} -dataValues3 = {v: v for _, v in data} # {"value1": "value1", "value2": "value2"} -``` - -We can **merge** dict using the dict unpacking operator `**` like this: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = {**_part1, **_part2} # {"a: "b", "c": "d"} -``` - -In addition, the same effect can be achieved by using the union operator `|`: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = _part1 | _part2 # {"a: "b", "c": "d"} -``` - -We can use `if expressions` to dynamically add elements to the dict element, elements that meet the conditions are added to the dict, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = { - key1 = "value1" - if a == 1: key2 = "value2" - if a > 0: key3 = "value3" - if a < 0: key4 = "value4" -} # {"key1": "value1", "key2": "value2", "key3": "value3"} -``` - -```python -a = 1 # 1 -data1 = { - key1 = "value1" - if a == 1: - key2 = "value2" - elif a > 0: - key3 = "value3" - else: - key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -data2 = { - key1 = "value1" - if a == 1: key2 = "value2" - elif a > 0: key3 = "value3" - else: key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -``` - -We can use the expression `for k in dict_var` to traverse a dict, and we can use the `in` operator to determine whether a dict contains a certain key - -```python -data = {key1 = "value1", key2 = "value2"} -dataAnother = {k: data[k] + "suffix" for k in data} # {"key1": "value1suffix", "key2": "value2suffix"} -containsKey1 = "key1" in data # True -containsKey2 = "key" in data # False -``` - -#### None - -In KCL, `None` can indicate that the value of the object is empty, which is similar to `nil` in Go or `null` in Java, and corresponds to `null` in YAML. - -```python -a = None -b = [1, 2, None] -c = {key1 = value1, key2 = None} -``` - -The output is as follows: - -```yaml -a: null -b: - - 1 - - 2 - - null -c: - key1: value1 - key2: null -``` - -Please note that `None` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + None # error -b = int(None) # error -c = not None # True -d = None == None # True -e = None or 1 # 1 -f = str(None) # None -``` - -#### Undefined - -`Undefined` is similar to `None`, but its semantics is that a variable is not assigned any value and will not be output to YAML - -```python -a = Undefined -b = [1, 2, Undefined] -c = {key1 = "value1", key2 = Undefined} -``` - -The output is as follows: - -```yaml -b: - - 1 - - 2 -c: - key1: value1 -``` - -Please note that `Undefined` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + Undefined # error -b = int(Undefined) # error -c = not Undefined # True -d = Undefined == Undefined # True -e = Undefined or 1 # 1 -f = str(Undefined) # Undefined -``` - -### Operators - -The following character sequences represent operators: - -```txt -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != @ \ -``` - -#### Arithmetic Operators - -KCL supports the common arithmetic operators: - -```python -assert 2 + 3 == 5 -assert 2 - 3 == -1 -assert 2 * 3 == 6 -assert 5 / 2 == 2.5 -assert 5 // 2 == 2 -assert 5 % 2 == 1 -``` - -#### Equality and Relational Operators - -KCL supports the meanings of equality and relational operators: - -```python -assert 2 == 2 -assert 2 != 3 -assert 3 > 2 -assert 2 < 3 -assert 3 >= 3 -assert 2 <= 3 -``` - -#### Logical Operators - -We can invert or combine boolean expressions using the logical operators e.g., `and` and `or`: - -```python -if not done and (col == 0 or col == 3): - # ...Do something... - -``` - -#### Bitwise and Shift Operators - -Here are examples of using bitwise and shift operators: - -```python -value = 0x22 -bitmask = 0x0f - -assert (value & bitmask) == 0x02 -assert (value & ~bitmask) == 0x20 -assert (value | bitmask) == 0x2f -assert (value ^ bitmask) == 0x2d -assert (value << 4) == 0x220 -assert (value >> 4) == 0x02 -``` - -The `|` operator likewise computes bitwise, unions basic types and unions collection and schema data, such as **list**, **dict** and **schema**. - -Computing bitwise examples: - -```python -0x12345678 | 0xFF # 0x123456FF -``` - -Unioning basic types examples: - -```python -schema x: - a: int | str # attribute a could be a int or string -``` - -#### Assignment Operators - -The following tokens serve as delimiters in the grammar: - -```bash - ( ) [ ] { } - , : . ; = -> - += -= *= /= //= %= - &= ^= >>= <<= **= -``` - -The following examples use assignment and argument assignment operators: - -```python -_a = 2 -_a *= 3 -_a += 1 -assert _a == 7 -``` - -#### Identity Operators - -The following keywords serve as identity operators in the grammar: - -```python -is, is not -``` - -The identity operators check whether the right hand side and the left hand side are the very same object. They are usually used to check if some variable is `None/Undefined/True/False`. Here are some examples: - -```python -empty_String = "" -empty_String is not None # True -``` - -#### Membership Operators - -The following keywords serve as membership operators in the grammar: - -```python -in, not in -``` - -- The `in` operator reports whether its first operand is a member of its second operand, which must be a list, dict, schema, or string. -- The `not in` operator is its negation. Both return a Boolean. - -The meaning of membership varies by the type of the second operand: the members of a list are its elements; the members of a dict are its keys; the members of a string are all its substrings. - -```python -1 in [1, 2, 3] # True - -d = {one = 1, two = 2} -"one" in d # True -"three" in d # False -1 in d # False -[] in d # False - -"nasty" in "dynasty" # True -"a" in "banana" # True -"f" not in "way" # True - -d = Data {one = 1, two = 2} # Data is a schema with attributes one and two -"one" in d # True -"three" in d # False -``` - -#### Comprehension - -A comprehension constructs a new list or dictionary value by looping over one or more iterables and evaluating a body expression that produces successive elements of the result. - -We can declare list and dict by comprehension as: - -```python -listVar = [_x for _x in range(20) if _x % 2 == 0] # list comprehension -dictVar = {str(_i): 2 * _i for _i in range(3)} # dict comprehension -``` - -#### Other Operators - -We can: - -- Represents a function call with **()**, like `"{} {}".format("hello", world)` -- Refers to the value at the specified index in the list with **[]** -- Define a type hint with **:** -- Refers to a member field with **.** -- Use the line continuation symbol `\` to write long expressions - -```python -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " -``` - -### Expressions - -#### Conditional Expressions - -A conditional expression has the form `a if cond else b`. It first evaluates the condition `cond`. If it's true, it evaluates `a` and yields its value; otherwise, it yields the value of `b`. - -Examples: - -```python -x = True if enabled else False # If enabled is True, x is True, otherwise x is False -``` - -#### Index Expressions - -An index expression `a[i]` yields the `i` th element of an indexable type such as a string or list. The index `i` must be an `int` value in the range `-n` ≤ `i` < `n`, where `n` is `len(a)`; any other index results in an error. - -A valid negative index `i` behaves like the non-negative index `n+i`, allowing for convenient indexing relative to the end of the sequence. - -```python -val = "abc" -list = ["zero", "one", "two"] -str_0 = val[0] # "a" -str_1 = val[1] # "b" -str_n1 = val[-1] # "c" - -list_0 = list[0] # "zero" -list_1 = list[1] # "one" -list_n1 = list[-1] # "two" -``` - -An index expression `d[key]` may also be applied to a dictionary `d`, to obtain the value associated with the specified key. It returns `Undefined` if the dictionary contains no such key. - -An index expression appearing on the left side of an assignment causes the specified list or dictionary element to be updated: - -```python -d = {key1 = "value1", key2 = "value2"} -key1value = d["key1"] # value1 -key2value = d["key2"] # value2 -``` - -It is a dynamic error to attempt to update an element of an immutable type, such as a list or string, or a frozen value of a mutable type. - -#### Slice Expressions - -A slice expression `a[start:stop:step]` yields a new value containing a sub-sequence of `a`, which must be a string, or list. - -Each of the `start`, `stop`, and `step` operands is optional; if present, each must be an integer. The `step` value defaults to 1. If the step is not specified, the colon preceding it may be omitted too. It is an error to specify a step of zero. - -Conceptually, these operands specify a sequence of values `i` starting at start and successively adding 'step' until `i` reaches or passes `stop`. The result consists of the concatenation of values of `a[i]` for which `i` is valid. - -The effective start and stop indices are computed from the three operands as follows. Let `n` be the length of the sequence. - -```python -val = "abc" -len = len(val) -a = val[1:len] # "bc" (remove first element) -b = val[0:-1] # "ab" (remove last element) -c = val[1:-1] # "b" (remove first and last element) -``` - -```python -"abc"[1:] # "bc" (remove first element) -"abc"[:-1] # "ab" (remove last element) -"abc"[1:-1] # "b" (remove first and last element) -"banana"[1::2] # "aaa" (select alternate elements starting at index 1) -"banana"[4::-2] # "nnb" (select alternate elements in reverse, starting at index 4) -``` - -It's not allowed to define a slice expression as a left value in KCL. Cause list and string are immutable, re-slicing can directly operate to operand to ensure better performance. - -#### Function Invocations - -KCL allows calling built-in functions and functions from built-in and system modules. - -To call a function, the basic way is shown as the following code excerpt: - -```python -import math - -a = math.pow(2, 3) # 2 powers 3 is 8. -b = len([1, 2, 3]) # the length of [1, 2, 3] is 3 -``` - -As you can see, arguments are separated with `,`, and KCL also supports positional arguments and key-value arguments. - -```python -print("hello world", end="") -``` - -Note that: - -- Some functions have parameters with default values. -- Some functions accept variadic arguments. - -When an argument is not supplied for a parameter without a default value, an error will be reported. - -#### Selector Expressions - -A selector expression selects the attribute or method of the value. KCL provides a wealth of ways to identify or filter attributes. - -`x.y` - -- dict: it denotes the value of the key `y` in the dict `x` -- schema: it denotes the attribute value of a schema `x` identified by `y` -- package: it denotes the identifier of a package `x` identified by `y` - -Examples: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -name = person.name # "Alice" -age = person.age # 18 - -myDict = { - key = "value" -} -result = myDict.key # "value" -``` - -`x?.y` - -`x` can be a schema instance or a dict. This is extremely helpful when the value of `x` might be `None` or when the key `y` might not exist in `x`. - -```python -# Example of dict: -data = {key = "value"} -a = data?.key # "value" -b = data?.name # Undefined - -# example of schema instance: -schema Company: - name: str - address: str - -schema Person: - name: str - job?: Company - -alice = Person { - name = "alice" -} - -if alice?.job?.name == "Group": - print("work in Group") -``` - -#### Quantifier Expressions - -Quantifier expressions act on collection: list or dict, generally used to obtain a certain result after processing the collection, mainly in the following four forms: - -- **all** - - Used to detect that all elements in the collection satisfy the given logical expression, and return a boolean value as the result. - - Only when all elements in the collection satisfy the expression true, the `all` expression is true, otherwise it is false. - - If the original collection is empty, return true. - - Supports short-circuiting of logical expressions during expression execution. -- **any** - - Used to detect that at least one element in the collection satisfies the given logical expression, and returns a boolean value as the result. - - When at least one element in the collection satisfies the expression true, the `any` expression is true, otherwise it is false. - - If the original collection is empty, return false. - - Supports short-circuiting of logical expressions during expression execution. -- **map** - - Generate a new **list** by mapping the elements in the original collection. - - The length of the new list is exactly the same as the original collection. -- **filter** - - By logically judging and filtering the elements in the original collection, and returning the filtered sub-collection. - - Only when the element judges the expression to be true, it is added to the sub-collection. - - The type (list, dict and schema) of the new collection is exactly the same as the original collection, and the length range is `[0, len(original-collection)]`. - -**all** and **any** expression sample codes: - -```python -schema Config: - volumes: [{str:}] - services: [{str:}] - - check: - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - }, "invalid cluster ip" - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } -``` - -**map** and **filter** expression sample codes: - -```python -a = map e in [{name = "1", value = 1}, {name = "2", value = 2}] { - {name = e.name, value = int(e.value) ** 2} -} # [{"name": "1", value: 1}, {"name": "2", "value": 4}] - -b = map k, v in {a = "foo", b = "bar"} { v } # ["foo", "bar"] - -c = filter e in [{name = "1", value = 1}, {name = "2", value = 2}] { - int(e.value) > 1 -} # [{"name": "2", "value": 2}] - -d = filter _, v in {a = "foo", b = "bar"} { - v == "foo" -} # {"a": "foo"} -``` - -Please pay attention to distinguish the difference between any expression and any type. When `any` is used in type annotations, it means that the value of the variable is arbitrary, while the any expression means that one of the elements in a set satisfies the condition. - -### Control Flow Statements - -#### If and Else - -KCL supports `if` statements with optional `elif` and `else` statements, as the next sample shows. - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - print("maybe a is negative") -else: - print("a >= 100") -``` - -The `elif` example: - -```python -_result = 0 -if condition == "one": - _result = 1 -elif condition == "two": - _result = 2 -elif condition == "three": - _result = 3 -else: - _result = 4 -``` - -`if-elif-else` statements can be nested. For example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - if a < 0: - print("a is negative") - print("No matter a is negative or positive, this message is printed") -else: - print("a >= 100") -``` - -In addition, for simple `if` statements as follows: - -```python -if success: - _result = "success" -else: - _result = "failed" -``` - -We can have it in one line using the ` if else ` pattern: - -```python -_result = "success" if success else "failed" -``` - -An `if` or `elif` statement evaluates a given expression. When the expression is evaluated to `True`, a list of statements following `:` are executed and when the expression is evaluated to `False` and statements will not be executed. - -Please note that the false name constant `False`, `None`, the zero number `0`, the empty list `[]`, the empty dict `{}` and the empty string `""` are all seen as `False` expressions. - -```python -_emptyStr = "" -_emptyList = [] -_emptyDict = {} -isEmptyStr = False if _emptyStr else True -isEmptyList = False if _emptyList else True -isEmptyDict = False if _emptyDict else True -``` - -The output is - -```yaml -isEmptyStr: true -isEmptyList: true -isEmptyDict: true -``` - -### Assert - -When errors happen, developers should be able to detect the error and abort execution. Thus, KCL introduce the `assert` syntax. The following is an example: - -```python -a = 1 -b = 3 -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -``` - -In addition, we can declare a condition for the assert statement and make an assertion when the condition is met. The usual way of writing is - -```python -a = None -if a: - assert a > 2: -``` - -In KCL, it can also be simplified to the following form using the **if** expression to compose more complex conditional assert logic: - -```python -a = None -assert a > 2 if a -``` - -### Function - -KCL supports using the lambda keyword to define a function. - -```python -func = lambda x: int, y: int -> int { - x + y -} -a = func(1, 1) # 2 -``` - -- The value of the last expression is used as the return value of the function, and the empty function body returns `None`. -- The return value type annotation can be omitted, and the return value type is the type of the last expression value. -- There is no order-independent feature in the function body, all expressions are executed in order. - -```python -_func = lambda x: int, y: int -> int { - x + y -} # Define a function using the lambda expression -_func = lambda x: int, y: int -> int { - x - y -} # Ok -_func = lambda x: int, y: int -> str { - str(x + y) -} # Error (int, int) -> str can't be assigned to (int, int) -> int -``` - -The function type variables cannot participate in any calculations and can only be used in assignment statements and call statements. - -```python -func = lambda x: int, y: int -> int { - x + y -} -x = func + 1 # Error: unsupported operand type(s) for +: 'function' and 'int(1)' -``` - -The lambda function supports the capture of external variables, which can be passed as parameters of other functions. - -```python -a = 1 -func = lambda x: int { - x + a -} -funcOther = lambda f, para: int { - f(para) -} -r0 = funcOther(func, 1) # 2 -r1 = funcOther(lambda x: int { - x + a -}, 1) # 2 -``` - -The output is - -```yaml -a: 1 -r: 2 -``` - -Further, we can define an anonymous function through lambda expression and call it. - -```python -result = (lambda x, y { - z = 2 * x - z + y -})(1, 1) # 3 -``` - -We can also use anonymous functions in the for loop. - -```python -result = [(lambda x, y { - x + y -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 3, 3, 4] -``` - -Note that the functions defined in the KCL are pure functions: - -- The return result of a function depends only on its arguments. -- There are no side effects in the function execution process. - -Therefore, KCL functions cannot modify external variables, but can only reference external variables. For example, the following code will cause an error: - -```python -globalVar = 1 -func = lambda { - x = globalVar # Ok - globalVar = 1 # Error -} -``` - -### Type System - -#### Type Annotation - -Type annotations can be used on top level variables, schema attributes and arguments. - -- An attribute can be of a basic type, such as a string (`str`), a floating-point number (`float`), a fixed-point number (`int`) or a boolean (`bool`). -- An attribute can be a literal type, such as a string literal (`"TCP"` and `"UDP"`), a number literal (`"1"` and `"1.2"`), a boolean literal (`True` and `False`) -- An attribute can also be a list or an ordinary dict: - - A list with unspecified type of elements is `[]`. - - A list with elements of type `t` is `[t]`. Here `t` is another type. - - A dict with keys of type `kt` and values of type `vt` is `{kt:vt}`. - - `kt`, `vt` or both of them can be missing, like a list with unspecified type of elements. -- An attribute can be a **union type** defined by `|`, such as `a | b`, which means the type of the member could be a or b. - - A union type can include any types of `int`, `str`, `float`, `bool`, `list`, `dict`, literal and schema type, and supports type nesting e.g. `{str:str|int}`, `[[int|str]|str|float]` and `2 | 4 | 6`, etc. -- An attribute can also be of a type generated from other schema. In such a case, the name of the other schema (including the package path prefix) is used as the type name. -- An attribute can annotated an any type e.g., `any`. - -Examples: - -- Basic type - -```python -"""Top level variable type annotation""" -a: int = 1 # Declare a variable `a` that has the type `int` and the value `1` -b: str = "s" # Declare a variable `b` that has the type `str` and the value `"s"` -c: float = 1.0 # Declare a variable `c` that has the type `float` and the value `1.0` -d: bool = True # Declare a variable `d` that has the type `bool` and the value `True` -``` - -- List/Dict/Schema Type - -```python -schema Person: - name: str = "Alice" - age: int = 10 - -a: [int] = [1, 2, 3] # Declare a variable `a` that has the list type `[int]` and the value `[1, 2, 3]` -b: {str:str} = {k1 = "v1", k2 = "v2"} # Declare a variable `b` that has the dict type `{str:str}` and the value `{k1 = "v1", k2 = "v2"}` -c: Person = Person {} # Declare a variable `c` that has the schema type `Person` and the value `Person {}` -``` - -- Union Type - -```python -# Basic union types -schema x[argc: int]: # Schema argument type annotation - p: int | str # Schema attribute type annotation -``` - -```python -# Literal union types -schema LiteralType: - # String literal union types, x_01 can be one of "TCP" and "UDP" - x_01: "TCP" | "UDP" - # Number literal union types, x_02 can be one of 2, 4, and 6 - x_02: 2 | 4 | 6 - # Unit union types, x_03 can be one of 1Gi, 2Gi and 4Gi - x_03: 1Gi | 2Gi | 4Gi - -x = LiteralType { - x_01 = "TCP" - x_02 = 2 - x_03 = 1Gi -} -``` - -The compiler throws an error when the value of a property does not conform to the union type definition: - -```python -# Literal union types -schema LiteralType: - # String literal union types, x_01 can be one of "TCP" and "UDP" - x_01: "TCP" | "UDP" - -x = LiteralType { - x_01 = "HTTP" # Error: the type got is inconsistent with the type expected, expect str(TCP)|str(UDP), got str(HTTP) -} -``` - -- Any Type - -```python -# Any type -schema Config: - literalConf: any = 1 - dictConf: {str:any} = {key = "value"} - listConf: [any] = [1, "2", True] - -config = Config {} -``` - -In KCL, changing the type of a variable is not allowed. If the type is not satisfied when reassigning the value, the type error will be raised. - -```python -_a = 1 # The type of `_a` is `int` -_a = "s" # Error: expect int, got str(s) -``` - -The type of a variable can be assigned to its upper bound type, but cannot be assigned to its specialized type. - -`None` and `Undefined` can be assigned to any type: - -- All types can be assigned to `any` type, `None` and `Undefined` can be assigned to `any` type. - -```python -a: int = None -b: str = Undefined -c: any = 1 -d: any = "s" -e: any = None -``` - -- The `int` type can be assigned to the `float` type, and the `float` type cannot be assigned to the `int` type. - -```python -a: float = 1 -b: int = 1.0 # Error: expect int, got float(1.0) -``` - -- The `int` type can be assigned to the `int|str` type, and the `int|str` type cannot be assigned to the `int` type. - -```python -a: int | str = 1 -b: int = 1 if a else "s" # Error: expect int, got int(1)|str(s) -``` - -Note that although the any type is provided in the KCl, it is still a static type, and the types of all variables are immutable during compilation. - -#### Type Inference - -If a variable or constant declaration in the top level or in the schema is not annotated explicitly with a type, the declaration's type is inferred from the initial value. - -- Integer literals are inferred to type `int`. - -```python -a = 1 # The variable `a` has the type `int` -``` - -- Float literals are inferred to type `float`. - -```python -a = 1.0 # The variable `a` has the type `float` -``` - -- String literals are inferred to type `str`. - -```python -a = "s" # The variable `a` has the type `str` -``` - -- Boolean literals are inferred to type `bool` - -```python -a = True # The variable `a` has the type `bool` -b = False # The variable `b` has the type `bool` -``` - -- `None` and `Undefined` are inferred to type `any` - -```python -a = None # The variable `a` has the type `any` -b = Undefined # The variable `b` has the type `any` -``` - -- List literals are inferred based on the elements of the literal, and to be variable-size. - -```python -a = [1, 2, 3] # The variable `a` has the type `[int]` -b = [1, 2, True] # The variable `b` has the list union type `[int|bool]` -c = ["s", 1] # The variable `c` has the list union type `[int|str]` -``` - -Please note that a empty list will be inferred to `[any]` - -```python -a = [] # The variable `a` has the type `[any]` -``` - -- Dict literals are inferred based on the keys and values of the literal, and to be variable-size. - -```python -a = {key = "value"} # The variable `a` has the type `{str:str}` -b = {key = 1} # The variable `b` has the type `{str:int}` -c = {key1 = 1, key2 = "s"} # The variable `c` has the type `{str:int|str}` -``` - -Please note that a empty dict will be inferred to `{any:any}` - -```python -a = {} # The variable `a` has the type `{any:any}` -``` - -- The type of the if conditional expression carrying the runtime value will be statically inferred as a union type of all possible results. - -```python -a: bool = True # The variable `a` has the type `bool` -b = 1 if a else "s" # The variable `b` has the type `int|str` -``` - -When a variable is deduced to a certain type, its type cannot be changed - -```python -_a = 1 -_a = "s" # Error: expect int, got str(1) -``` - -#### Type Alias - -We can use the `type` keyword to declare a type alias for all types in KCL to simplify the writing and use of complex types. - -```python -type Int = int -type String = str -type StringOrInt = String | Int -type IntList = [int] -type StringAnyDict = {str:} -``` - -We can import a type through import and define an alias for it. - -```py -import pkg - -type Data = pkg.Data -``` - -In addition, we can use type aliases and union types to achieve similar enumeration functions. - -```python -# A type alias of string literal union types -type Color = "Red" | "Yellow" | "Blue" - -schema Config: - color: Color = "Red" # The type of color is `"Red" | "Yellow" | "Blue"`, and it has an alias `Color`, whose default value is `"Red"` - -config = Config { - color = "Blue" -} -``` - -The output YAML is - -```yaml -config: - color: Blue -``` - -Please note that the type alias name cannot be one of `any`, `int`, `float`, `bool` and `str` because of ambiguity. - -```python -type any = int | str # Error -type int = str # Error -type float = int # Error -type bool = True # Error -type str = "A" | "B" | "C" # Error -``` - -#### Type Guards - -KCL supports the `typeof` function which can give very basic information about the type of values we have at runtime. In KCL, checking against the value returned by `typeof` is a type guard. KCL expects this to return a certain set of strings: - -Example: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person {} -t3 = typeof(_x1) - -_x2 = pkg.Person {} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# Output -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -In addition, we can use the `as` keyword in conjunction with type guards to complete defensive type conversion programming. - -Only types with partial order can be downcast converted, the use of the as keyword is as follows: - -- Basic types of partial order relations, e.g., `float -> int` -- Partial order relation of union type, e.g., `int | str -> str` and `[int | str] -> [str]` -- Contains the partial order relation of the upper bound of the type, e.g., `any -> int` -- Partial order relationship of structure type, e.g., `base-schema -> sub-schema` - -```python -schema Data1: - id?: int - -schema Data2: - name?: str - -data: Data1 | Data2 = Data1 {} - -if typeof(a) == "Data1": - data1 = data as Data1 # The type of `data1` is `Data1` -elif typeof(a) == "Data2": - data2 = data as Data2 # The type of `data2` is `Data2` -``` - -When a runtime error occurs in the `as` type conversion, a runtime error is thrown. - -```python -a: any = "s" -b: int = a as int # Error: The `str` type cannot be converted to the `int` type -``` - -If we don’t want to throw a runtime error, we can use the type guard for defensive coding with `if` expressions. - -```python -a: any = "s" -b = a as int if typeof(a) == "int" else None # The type of b is `int` -``` - -Note that the `as` conversion of literal type and union type is not supported, because they are not a certain runtime object, only int, float and other objects at runtime, there is no int literal, float literal object, and no union object. - -### Schema - -#### Overview - -A schema is a language element to define a complex configuration. -We can define typed attributes, initialization assignment, and verification rules. In addition, KCL supports schema single inheritance, mixin and protocol to realize the reuse of complex configuration. - -#### Basic - -##### Attribute - -The followings are some basic examples: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 -``` - -In KCL, we can use type annotations to define some attributes in the schema, each attribute can be set with an optional default value (such as the `age` attribute in the above code, its default value is `0`), attributes that are not set default values have an initial value of `Undefined`, which are not output in YAML. - -Note, the immutability of attributes in the schema follows the same rules as the immutability of global variables, only mutable attributes in the schema can be modified in the schema. - -```python -schema Person: - age: int = 1 # Immutable attribute - _name: str = "Alice" # Mutable attribute - - age = 10 # Error - _name = "Bob" # Ok -``` - -###### Optional Attribute - -Each attribute **must** be assigned with a not `None`/`Undefined` value as a schema instance unless it is modified by a question mark as an optional attribute. - -Examples: - -```python -schema Employee: - bankCard: int # bankCard is a required attribute, and it can NOT be None or Undefined - nationality?: str # nationality is an optional attribute, and it can be None or Undefined - -employee = Employee { - bankCard = None # Error, attribute 'bankCard' of Employee is required and can't be None or Undefined - nationality = None # Ok -} -``` - -##### Irrelevant Order Calculation - -The irrelevant order calculation in the schema indicates the reference relationship between the internal attributes of the schema. For example, when we declare an expression of the form `a = b + 1`, the calculation of the value of `a` depends on the calculation of the value of `b`. When the compiler calculate the value of `a` and the value of `a` depends on the value of `b`, the compiler will choose to first calculate the value of `b`, and then calculate the value of a according to the expression `a = b + 1`, which is slightly different from the calculation method of traditional procedural language the difference. - -Since the calculation of values in the schema is based on dependencies, just like a directed acyclic graph traverses each node in the graph according to the order of topological sorting, the order of declaration of attributes in the schema is not so important, so the feature is called the irrelevant order calculation. - -Please note that there can be no circular references between different schema attribute values. - -We can see this feature through the following examples. - -```python -schema Fib: - n1: int = n - 1 # Refers to the attribute `n` declared after `n1` - n2: int = n1 - 1 - n: int - value: int = 1 if n <= 2 else Fib {n = n1}.value + Fib {n = n2}.value - -fib8 = Fib {n = 8}.value -``` - -The output is - -```yaml -fib8: 21 -``` - -We can see that in the schema, we only need to simply specify the dependency between attributes, and the compiler will automatically calculate the value based on the dependency, which can help us save a lot of boilerplate code and reduce configuration difficulty of writing. - -##### Schema Context - -We can define the context of the schema to manage the attributes of the schema, and we can write schema parameters, temporary variables and expressions directly in the schema: - -```python -schema Person[_name: str]: # define a schema argument - name: str = _name # define a schema attribute - age: int = 10 # define a schema attribute with default value - hands: [int] = [i for i in [1, 2, 3]] # define a for statement -``` - -##### Validation - -In addition to using **static typing** (the type annotation) and **immutability** in KCL schema mentioned earlier to ensure code stability, a bunch of validation rules are supported in a simple **check** block (KCL supports almost all authentication capabilities of [OpenAPI](https://www.openapis.org/)): - -```python -import regex - -schema Sample: - foo: str - bar: int - fooList: [str] - - check: - bar > 0 # minimum, also support the exclusive case - bar < 100 # maximum, also support the exclusive case - len(fooList) > 0 # min length, also support exclusive case - len(fooList) < 100 # max length, also support exclusive case - regex.match(foo, "^The.*Foo$") # regex match - isunique(fooList) # unique - bar in range(100) # range - bar in [2, 4, 6, 8] # enum - multiplyof(bar, 2) # multipleOf -``` - -With the schema, all instances will be validated at compile time - -```python -# Ok -goodSample = Sample { - foo = "The Foo" - bar = 2 - fooList = ["foo0", "foo1"] -} - -# Error: validation failure: Check failed on check conditions: bar < 100. -badSample = Sample { - foo = "The Foo" - bar = 123 - fooList = ["foo0", "foo1"] -} -``` - -In addition, we can use **and**, **or**, **if** to compose more complex conditional check logic: - -```python -schema Sample: - bar: int - foo: str - doCheck: bool - - check: - regex.match(foo, "^The.*Foo$") and bar in [2, 4, 6, 8] if doCheck -``` - -In order to ensure that all check rules can play their corresponding roles well, we can test the rationality and correctness of different data combinations by writing KCL test cases, and run all test cases through the kcl test tool. - -##### Documents - -Usually after we write the schema model, we will write documentation comments for the schema, which can be completed by using a three-quoted string as follows: - -```python -schema Server: - """Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - - Attributes - ---------- - workloadType : str, default is Deployment - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - name : str, default is None - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - labels : {str:str}, optional, default is None - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - - Examples - ---------------------- - myCustomApp = AppConfiguration { - name = "componentName" - } - """ - workloadType: str = "Deployment" - name: str - labels?: {str:str} -``` - -##### Config - -Suppose we have the following schema definition: - -```python -schema Person: - firstName: str - lastName: str -``` - -A config could be defined with a JSON-like expression: - -```python -person = Person { - firstName = "firstName" - lastName = "lastName" -} -``` - -At the same time, the schema adheres to strict attribute definitions, -and configuring undefined attributes will trigger a compilation error. - -```python -person = Person { - firstName = "firstName" - lastName = "lastName" - fullName = "fullName" # Error: Cannot add member 'fullName' to schema 'Person', 'fullName' is not defined in schema 'Person' -} -``` - -We can use `if expressions` to dynamically add elements to the schema config, elements that meet the conditions are added to the schema config, and elements that do not meet the conditions are ignored. Besides, the **config selector expressions** can be used to init a schema instance. - -```python -schema Base: - count: int - value: str - -schema Person: - base: Base - labels: {str:str} - name?: str - -env = "prod" - -person1 = Person { - base.count = 2 # Config selector expression - base.value = "value" # A schema variable in schema can use selector expressions - labels.key = "value" # A dict variable in schema can use selector expressions -} - -person2 = Person { - base = { - count = 1 - value = "value" - } - labels.key = "value" - if env == "prod": - labels.env = env - else: - labels.env = "other" -} -``` - -The output YAML is - -```yaml -person1: - base: - count: 2 - value: value - labels: - key: value -person2: - base: - count: 1 - value: value - labels: - key: value - env: prod -``` - -When we instantiate a schema without config parameters, we can generate schema instances in the following three forms: - -```python -schema Data: - id: int = 1 - -data1 = Data {} -data2 = Data() {} -data3 = Data() -``` - -In addition to using a schema type to instantiate a schema, we can also use a schema instance to get a new instance using the config expression. - -```python -schema Config: - id: int - values: [int] - -configOrigin = Config { - id = 1 - values = [0, 1] -} -configNew = configOrigin { - id = 2 - values += [2, 3] -} -``` - -The output is - -```yaml -configOrigin: - id: 1 - values: - - 0 - - 1 -configNew: - id: 2 - values: - - 0 - - 1 - - 2 - - 3 -``` - -In addition, schema attribute default values can be modified by schema config. - -```python -schema Person: - age: int = 1 - name: str = "Alice" - - age = 2 # Error, can't change the default value of the attribute `age` in the schema context - -person = Person { - age = 3 # Ok, can change the default value of the attribute `age` in the schema config -} -``` - -#### Advanced - -##### Protocol & Mixin - -In addition to schema, an additional type definition method `protocol` is provided in KCL, and its properties are as follows: - -- In a protocol, only attributes and their types can be defined, complex logic and check expressions cannot be written, and mixins cannot be used. -- A protocol can only constrain properties that do not start with `_`. -- A protocol can only inherit or refer to other protocols, but cannot inherit or refer to other schemas. - -Besides, we can declare a complex assembly schema with optional **mixin** support and use **protocol** to add an optional host type to the dynamically inserted **mixin**.: - -```python -schema Person: - mixin [FullNameMixin] - - firstName: str # Required - lastName: str # Required - fullName?: str # Optional -``` - -A fullName mixin which generates a fullName as a simple sample: - -```python -protocol PersonProtocol: - firstName: str - lastName: str - fullName?: str - -mixin FullNameMixin for PersonProtocol: - fullName = "{} {}".format(firstName, lastName) -``` - -Then we can get the schema instance by: - -```python -person = Person { - firstName = "John" - lastName = "Doe" -} -``` - -The output is - -```yaml -person: - firstName: John - lastName: Doe - fullName: John Doe -``` - -Please note that the host type **protocol** can only be used for **mixin** definitions (the suffix name is `Mixin`), otherwise an error will be reported. - -```python -protocol DataProtocol: - data: str - -schema Data for DataProtocol: # Error: only schema mixin can inherit from protocol - x: str = data -``` - -##### Index Signature - -Index signatures can be defined in the KCL schema, and it means that the key-value constraints of the index signature can be used to construct a dict with the schema type, or additional checks can be added to the schema attributes to enhance the KCL type and semantic checks. - -- Use the form `[{attr_alias}: {key_type}]: {value_type}` to define an index signature in the schema, and `{attr_alias}` can be omitted. - -```python -schema Map: - """ - Map is a schema with a key of str type and a value of str type - """ - [str]: str # `{attr_alias}` can be omitted. - -data = Map { - key1 = "value1" - key2 = "value2" -} -``` - -- Mandatory all attributes of the schema key and value types - -```python -schema Person: - name: str - age: int # error, conflicts with the index signature definition `[str]: str` - [str]: str # The values of all attributes of the schema can only be strings -``` - -- Mandatory all attribute key and value types are defined in the schema, which is equivalent to restricting all attribute types except the additional attributes. - -```python -schema Person: - name: str - age: int - [...str]: str # Except for the `name` and `age` attributes, the key type of all other attributes of the schema must be `str`, and the value type must also be `str`. -``` - -- Define the index signature attribute alias and use it with the check block. - -```python -schema Data: - [dataName: str]: str - check: - dataName in ["Alice", "Bob", "John"] - -data = Data { - Alice = "10" - Bob = "12" - Jonn = "8" # Error: Jonn not in ["Alice", "Bob", "John"] -} -``` - -```python -import regex - -schema DataMap: - [attr: str]: str - check: - regex.match(attr, r'^[-._a-zA-Z0-9]+$') - -data = DataMap { - key1 = "value1" - "foo.bar" = "value2" # check error -} -``` - -##### Inheritance - -Like some other object-oriented languages, KCL provides fundamental but limited object-oriented support, such as **attribute reuse**, **private and public variables**, and **single inheritance**. Besides, KCL does NOT support multiple inheritances for the schema. - -The following is an example of schema inheritance: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 - -# An employee **is** a person, and has some additional information. -schema Employee(Person): - bankCard: int - nationality?: str - -employee = Employee { - firstName = "Bob" - lastName = "Green" - age = 18 - bankCard = 123456 -} -``` - -The output is - -```yaml -employee: - firstName: Bob - lastName: Green - age: 18 - bankCard: 123456 - nationality: null -``` - -Please note that KCL only allows **single inheritance** on schemas. - -In addition, when the schema has an inheritance relationship, the properties of optional attributes are as follows: - -- If the attribute is optional in the base schema, it could be optional or required in the sub-schema. -- If the attribute is required in the base schema, it must be required in the sub-schema. - -```python -schema Person: - bankCard?: int - nationality: str - -schema Employee(Person): - bankCard: int # Valid, both `bankCard: int` and `bankCard?: int` are allowed - nationality?: str # Error, only `nationality: str` is allowed -``` - -##### Schema Function - -Schema map very nicely onto functions; it can have any number of input and output parameters. For example, the Fibonacci function can be written as follows using the recursive schema config: - -```python -schema Fib[n: int]: - n1 = n - 1 - n2 = n - 2 - if n == 0: - value = 0 - elif n == 1: - value = 1 - else: - value = Fib(n1).value + Fib(n2).value - -fib8 = Fib(8).value # 21 -``` - -##### Decorators - -Just like Python, KCL supports the use of decorators on the schema. KCL Decorators dynamically alter the functionality of a schema without having to directly use sub schema or change the source code of the schema being decorated. And like a function call, the decorator supports passing in additional parameters. - -Built-in decorators of schema - -- `@deprecated` - Mark whether a schema or schema attribute is deprecated. The `@deprecated` decorator supports three parameters: - - **version** - string type, indicating the version information. The default value is empty. - - **reason** - string type, indicating the deprecated reason. The default value is empty. - - **strict** - bool type, indicating whether to report an error or warning. The default value is true. If `strict` is `True` and the error is thrown, the program will be interrupted. If `strict` is `False`, a warning will be output and the program will not be interrupted. - -Examples: - -```python -@deprecated -schema ObsoleteSchema: - attr: str - -schema Person: - name: str = "John" - attrs: ObsoleteSchema = { - attr = "value" - } - -person = Person {} # Error: ObsoleteSchema was deprecated -``` - -```python -schema Person: - firstName: str = "John" - lastName: str - @deprecated(version="1.16", reason="use firstName and lastName instead", strict=True) - name: str - -JohnDoe = Person { # Error: name was deprecated since version 1.16, use firstName and lastName instead - name = "deprecated" -} -``` - -Note that the current version of KCL does not yet support user-defined decorators. - -##### Members - -Built-in functions and members of schema - -- instances() - Return the list of existing instances of a schema. - -```python -schema Person: - name: str - age: int - -alice = Person { - name = "Alice" - age = 18 -} - -bob = Person { - name = "Bob" - age = 10 -} - -aliceAndBob = Person.instances() # Person is a schema type, instances() is its member method -``` - -The output is - -```yaml -alice: - name: Alice - age: 18 -bob: - name: Bob - age: 10 -aliceAndBob: - - name: Alice - age: 18 - - name: Bob - age: 10 -``` - -### Config Operations - -#### Config Unification - -##### | Operators - -In KCL, we can use the union operator `|` to achieve the merging of configurations, the types supported by the union operator are as follows: - -```txt -SchemaInstance | SchemaInstance -SchemaInstance | Dict -Dict | Dict -List | List -``` - -Unioning collection and schema data: - -- Unioning List. Overwrite the list expression on the right side of the operator `|` to the list variable on the left side of the operator one by one according to the **index**. - -```python -_a = [1, 2, 3] -_b = [4, 5, 6, 7] -x = _a | _b # [4, 5, 6, 7] 1 -> 4; 2 -> 5; 3 -> 6; Undefined -> 7 -``` - -Unioning to the specific index or all elements is still under discussion. - -- Unioning Dict. Union the dict expression on the right side of the operator `|` one by one to the dict variable on the left side of the operator according to the **key** - -```python -_a = {key1 = "value1"} -_b = {key1 = "overwrite", key2 = "value2"} -x = _a | _b # {"key1": "overwrite", "key2": "value2"} -``` - -The union of collection and schema is a new one whose attributes are unioning b to a, preserving the order of the attributes of the operands, left before right. - -- Unioning Schema. The union operation for schema is similar to dict. - -Schema union could be done as: - -```python -schema Person: - firstName?: str - lastName?: str - -_a = Person { - firstName = "John" -} -_b = {lastName = "Doe"} -_c = _a | _b # {"firstName": "John", "lastName": "Doe"} -_d = _a | None # {"firstName": "John"} -_e = _a | Undefined # {"firstName": "John"} -_f = None | _a # {"firstName": "John"} -_g = Undefined | _a # {"firstName": "John"} -``` - -Please note that when one of the left and right operands of the union operator is None, the other operand is returned immediately. - -```python -data1 = {key = "value"} | None # {"key": "value"} -data2 = None | [1, 2, 3] # [1, 2, 3] -data3 = None | None # None -``` - -The output is - -```yaml -data1: - key: value -data2: - - 1 - - 2 - - 3 -data3: null -``` - -##### : Operators - -Pattern: `identifier : E` or `identifier : T E` - -The value of the expression `E` with optional type annotation `T` will be unioned into the element value. - -Examples: - -```python -data = { - labels: {key1: "value1"} - # union {key2: "value2"} into the attribute labels. - labels: {key2: "value2"} -} -``` - -Output: - -```yaml -data: - labels: - key1: value1 - key2: value2 -``` - -In addition to using attribute operators on the schema config attributes, variables inside and outside the schema can use attribute operators to perform different operations on the configuration. - -- Using `:` outside the schema - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - data: Data - -# This is one configuration that will be merged. -config: Config { - data.d1 = 1 -} -# This is another configuration that will be merged. -config: Config { - data.d2 = 2 -} -``` - -Its equivalent configuration code can be expressed as - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - data: Data - -config: Config { - data.d1 = 1 - data.d2 = 1 -} -``` - -The output is - -```yaml -config: - data: - d1: 1 - d2: 1 -``` - -- Using `:` inside the schema - -```python -schema Data: - d1?: int - d2?: int - -schema Config: - # This is one configuration that will be merged. - data: Data { - d1 = 1 - } - # This is another configuration that will be merged. - data: Data { - d2 = 1 - } - -config: Config {} -``` - -#### Config Override - -##### = Operators - -Pattern: `identifier = E` or `identifier : T = E` - -The value of the expression `E` with optional type annotation `T` will override the attribute value. - -Examples: - -```python -schema Data: - labels: {str:} = {key1 = "value1"} - -data = Data { - # override {key2: "value2"} into the attribute labels of the schema Data. - labels = {key2 = "value2"} -} -``` - -Output: - -```yaml -data: - labels: - key2: value2 -``` - -Note: - -- Especially, we can "delete" its content by overriding the attribute to `Undefined`, such as `{ a = Undefined }`. - -#### Insert - -##### += Operators - -Pattern: `identifier += E` or `identifier : T += E` - -Insert only works for list type `identifier`. - -`E` will be inserted just after the specified index of the list `identifier`, and the following attributes after the index will be automatically shifted. - -Examples: - -```python -schema Data: - labels: {str:} = {key1 = [0]} - -data = Data { - # insert [1] into the attribute labels.key1 of the schema Data. - labels: {key1 += [1]} -} -``` - -Output: - -```yaml -data: - labels: - key1: - - 0 - - 1 -``` - -If no index is specified, the last index will be used. - -#### Notice - -Please note that the calculations of the `=` and `+=` attribute operators of the same attribute are sequential, and the latter ones have a higher priority. - -```python -x = { - a = 1 # 1 -} | { - a = 2 # 1 -> 2 -} | { - a = 3 # 2 -> 3 -} # The final value of attribute `a` is 3 -``` - -Please note that the `:` attribute operator represents an idempotent merge operation, and an error will be thrown when the values that need to be merged conflict. - -Therefore, when we need a configuration to override or add and delete operations, it is best to use the `=` and `+=` operators - -```python -data0 = {id: 1} | {id: 2} # Error:conflicting values between {'id': 2} and {'id': 1} -data1 = {id: 1} | {id = 2} # Ok, the value of `data` is {"id": 2} -``` - -The check rules for `:` operator for KCL value conflicts are as follows: - -- For `None` and `Undefined` variables, they do not conflict with any value. - -```python -data0 = None | {id: 1} # Ok -``` - -- For `int`, `float`, `str` and `bool` types, when their values are different, they are considered as conflicts. - -```python -data0 = 1 | 1 # Ok -data1 = 1 | "s" # Error -``` - -- For list type - - When their lengths are not equal, they are regarded as conflicts. - - When their lengths are equal, as long as there is a conflict in the value of a child element, it is regarded as a conflict. - -```python -data0 = [1] | [1] # Ok -data1 = [1, 2] | [1] # Error -``` - -- For dict/schema type - - When the values of the same key conflict, they are regarded as conflicts - -```python -data0 = {id: 1} | {id: 1} # Ok -data1 = {id: 1} | {id: 2} # Error -data1 = {id: 1} | {idAnother: 1} # Ok -``` - -### Rule - -In addition to using the check keyword for verification and writing in the schema, KCL also supports the use of the `rule` keyword to define a set of rules for policy verification - -The KCL rule is the same as the schema/mixin/protocol and it is defined by indentation. We need write a rule per line and we can write if filter conditions and verification failure information for each rule. Different conditions are connected with logic `and` (similar to the way of writing in check block). - -```python -rule SomeRule: - age > 0, "rule check failure message" -``` - -We can call a KCL rule like instantiating a schema: - -```python -age = 1 -name = "Alice" - -rule SomeRule: - age > 0, "rule check failure message" - name == "Alice" - -rule1 = SomeRule() # Rule call -rule2 = SomeRule {} # Rule call -``` - -We can use protocol to implement type checking of rule structure: - -```python -# Schema definition -protocol Service: - clusterIp: str - $type: str - -# Schema definition -protocol Volume: - mountPath: [str] - -# Protocol -protocol SomeProtocol: - id: int - env: {str: any} - services: [Service] - volumes: [Volume] - -rule SomeChecker for SomeProtocol: - id > 0, "id must >0" - - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - } - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } - -# Call rule to check with config parameter -SomeChecker { - id = 1 - env = { - MY_ENV = "MY_ENV_VALUE" - } - services = [ - { - type = "ClusterIP" - clusterIP = "NONE" - } - ] - volumes = [ - { - mountPath = "/home/admin" - } - { - mountPath = "/home/myapp" - } - ] -} -``` - -Please note that the combination of `protocol` and `rule` can separate attributes from their constraint definitions. We can define different rules and protocols in different packages and combine them as needed. This is different from check expressions in schema, which can only be combined with schema attributes. - -Besides, the following two ways can be used to achieve the multiplexing of different Rules: - -- Inline Call - -```python -weather = "sunny" -day = "wednesday" - -rule IsSunny: - weather == "sunny" - -rule IsWednesday: - day == "wednesday" - -rule Main: - IsSunny() # Rule inline call - IsWednesday() # Rule inline call - -Main() # Rule call -``` - -- Inherit - -```python -weather = "sunny" -day = "wednesday" - -rule IsSunny: - weather == "sunny" - -rule IsWednesday: - day == "wednesday" - -rule Main(IsSunny, IsWednesday): - id == 1 - -Main() -``` - -We can obtain external data or input from the `option` function and the CLI parameter `-D` for verification: - -- A simple example - -```python -schema Day: - day: str - homework: str - -days: [Day] = option("days") - -rule Main: - filter d in days { - d.day not in ["saturday", "sunday"] and d.homework - } - -Main() -``` - -- A complex example - -```python -data = option("data") -input = option("input") - -rule Allow: - UserIsAdmin() - any grant in UserIsGranted() { - input.action == grant.action and input.type == grant.type - } - -rule UserIsAdmin: - any user in data.user_roles[input.user] { - user == "admin" - } - -rule UserIsGranted: - [ - grant - for role in data.user_roles[input.user] - for grant in data.role_grants[role] - ] - -allow = Allow() or False -``` - -Further, the above KCL rule code can be compiled into a target such as WASM and used at runtime. - -### Module - -KCL config files are organized as **modules**. A single KCL file is considered as a module, and a directory is considered as a package, which is a special module. - -The modules in the same package are visible and cross-package references need to be visible through import. - -Code structure: - -```bash -. -└── root - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -model1.k: - -```python -# schema CatalogItem in model1.k - -schema CatalogItem: - id: int - image: CatalogItemImage # CatalogItemImage is defined in the module of the same package e.g., model2.k in package model - title: str -``` - -service1.k: - -```python -import ..model as model # cross-package references - -schema ImageService: - image: model.CatalogItemImage # CatalogItemImage is imported from another package e.g., model2.k in package model - name: str -``` - -#### Relative Path Import - -We can use the operator `.` to realize the relative path import of KCL entry files. - -main.k: - -```python -import .model1 # Current directory module -import ..service # Parent directory -import ...root # Parent of parent directory - -s = service.ImageService {} -m = root.Schema {} -``` - -#### Absolute Path Import - -The semantics of `import a.b.c.d` is - -1. If `kcl.mod` not exist, regard the current directory as the package root and search the path `a/b/c/d` from the current directory. -2. If the current directory search fails, search from the root path `ROOT_PATH/a/b/c/d`, else raise an import error. - -The definition of the root path `ROOT_PATH` is the directory corresponding to the `kcl.mod` file from the current directory. - -Code structure: - -```bash -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -main.k: - -```python -import service # `root package` and `kcl.mod` are in the same directory -import mixin # `root package` and `kcl.mod` are in the same directory - -myModel = model.CatalogItem {} -``` - -Note that for the KCL entry file `main.k`, it cannot be imported into the folder where it is located, otherwise a recursive import error will occur: - -```python -import model # Error: recursively loading -``` - -### Top-Level Argument - -Assume some field need to be passed in dynamically like user input, we can define a top-level argument in a module: - -```python -bankCard = option("bankCard") # Get bankCard through the option function. -``` - -Then we can use the module as below: - -```bash -kcl employee.k -D bankCard=123 -``` - -Currently, supported types of top-level argument are number, string, bool, list and dict. - -```bash -kcl main.k -D list_key='[1,2,3]' -D dict_key='{"key":"value"}' -``` - -We need to pay attention to the escape of quotation marks `"` and other symbols in the command line - -#### Arguments with Setting Files - -In addition, it also supports inputting a YAML file as top-level arguments. - -```yaml -kcl_options: - - key: key_number - value: 1 - - key: key_dict - value: - innerDictKey: innerDictValue - - key: key_list - value: - - 1 - - 2 - - 3 - - key: bankCard - value: 123 -``` - -```bash -kcl -Y setting.yaml employee.k -``` - -In addition, the setting file also supports configuring command-line compilation parameters as follows: - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - disable_none: true - strict_range_check: true - debug: 1 - verbose: 1 - sort_keys: true - output: ./stdout.golden - overrides: - - app.image=new_image - path_selector: - - config - package_maps: - k8s: /Users/.kcl/kpm/k8s_1.24 -kcl_options: - - key: image - value: docker.io/kcllang/kcl:latest -``` - -KCL CLI -Y parameters also support multi-file configuration, and support separate writing and merging of compilation parameters and option top level arguments parameter configuration. - -```bash -kcl -Y compile_setting.yaml option_setting.yaml -``` - -- `compile_setting.yaml` - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - disable_none: true - strict_range_check: true - debug: 1 - verbose: 1 - output: ./stdout.golden -``` - -- `option_setting.yaml` - -```yaml -kcl_options: - - key: image - value: docker.io/kcllang/kcl:latest -``` - -We can use the following command line to get the meaning of each configuration parameter or see KCL Quick Start - -```bash -kcl --help -``` - -#### Option Functions - -We can use the `option` function in the KCL code to get the top-level arguments. - -```python -value = option(key="key", type='str', default="default_value", required=True, help="Set key value") -``` - -Parameters - -- **key**: The argument key. -- **type**: The argument type to be converted. -- **default**: The argument default value when the key-value argument is not provided -- **required**: Report an error when the key-value argument is not provided and required is True. -- **help**: The help message. - -### Multi-file Compilation - -In addition to the above KCL single file execution, we can compile multiple KCL entry files at the same time using the following command: - -```bash -kcl main_1.k main_2.k ... main_n.k -``` - -main_1.k - -```python -a = 1 -b = 2 -``` - -main_2.k - -```python -c = 3 -d = 4 -``` - -The output is: - -```yaml -a: 1 -b: 2 -c: 3 -d: 4 -``` - -Taking advantage of the **multi-file combination**, we can assemble multiple KCL files without the need to use import management files. Let us see an example of combining **multi-file compilation** and **schema instance**. - -model.k - -```python -schema Model: - name: str - labels?: {str:} - annotations?: {str:} - replicas: int - -_model1 = Model { - name = "model1" - labels.key1 = "value1" - labels.key2 = "value2" - annotations.key = "value" - replicas = 2 -} - -_model2 = Model { - name = "model2" - replicas = 3 -} -``` - -backend.k - -```python -import yaml - -schema Backend: - apiVersion: str = "v1" - kind: str = "Deployment" - metadata: {str:} - spec: {str:} = { - minReadySeconds = 0 - paused = False - progressDeadlineSeconds = 600 - replicas = 1 - revisionHistoryLimit = 10 - selector = {} - } - -_backends = [Backend { - metadata.name = model.name - metadata.labels = model.labels - metadata.annotations = model.annotations - spec.selector.matchLabels: model.labels - spec.replicas = model.replicas -} for model in Model.instances()] # Schema Model is defined in model.k -print("---\n".join([yaml.encode(_b, ignore_private=True) for _b in _backends])) -``` - -The command is - -```bash -kcl model.k backend.k -``` - -The output is - -```yaml -apiVersion: v1 -kind: Deployment -metadata: - name: model1 - labels: - key1: value1 - key2: value2 - annotations: - key: value -spec: - minReadySeconds: 0 - paused: false - progressDeadlineSeconds: 600 - replicas: 2 - revisionHistoryLimit: 10 - selector: - matchLabels: - key1: value1 - key2: value2 ---- -apiVersion: v1 -kind: Deployment -metadata: - name: model2 -spec: - minReadySeconds: 0 - paused: false - progressDeadlineSeconds: 600 - replicas: 3 - revisionHistoryLimit: 10 - selector: {} -``` - -### KCL CLI Path Selector - -We can use KCL CLI `-S|--path-selector` parameter to select one or more values out of a KCL model. - -The path selector looks like this: - -`var.name` - -#### Examples - -Code structure: - -```bash -. -├── kcl.mod -└── main.k - └── pkg - └── model.k -``` - -pkg/model.k: - -```python -schema Person: - name: str - age: int - -var = Person { - name = "Alice" - age = 18 -} -``` - -main.k - -```python -import pkg - -var = pkg.Person { - name = "Bob" - age = 10 -} -``` - -The command is - -```bash -kcl main.k -S var -``` - -The output is - -```yaml -name: Alice -age: 18 -``` - -### KCL CLI Variable Override - -In addition to **Variable Selector**, KCL also allows us to directly modify the values in the configuration model through the KCL CLI `-O|--overrides` parameter. - -The use of **Variable Override** is similar to [**Variable Selector**](#variable-selector), and the parameter contains three parts e.g., `pkg`, `identifier`, `attribute` and `override_value`. - -```bash -kcl main.k -O override_spec -``` - -- `override_spec` represents a unified representation of the configuration model fields and values that need to be modified - -```txt -override_spec: [[pkgpath] ":"] identifier ("=" value | "-") -``` - -- `pkgpath`: Indicates the path of the package whose identifier needs to be modified, usually in the form of `a.b.c`. For the main package, `pkgpath` is expressed as `__main__`, which can be omitted. If omitted, it means the main package. -- `identifier`: Indicates the identifier that needs to modify the configuration, usually in the form of `a.b.c`. -- `value`: Indicates the value of the configuration that needs to be modified, which can be any legal KCL expression, such as number/string literal value, list/dict/schema expression, etc. -- `=`: means to modify the value of identifier. - - When the identifier exists, modify the value of the existing identifier to value. - - When identifier does not exist, add the identifier attribute and set its value to value. -- `-`: means to delete the identifier attribute. - - When the identifier exists, delete it directly. - - When the identifier does not exist, no modification is made to the configuration. - -Note: When `identifier` appears multiple times, modify/delete all `identifier` values - -#### Examples - -##### Override Update Sample - -KCL code: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -``` - -The command is - -```bash -kcl main.k -O :person.name=\"Bob\" -O :person.age=10 -``` - -The output is - -```yaml -person: - name: Bob - age: 10 -``` - -Besides, when we use KCL CLI `-d` argument, the KCL file will be modified to the following content at the same time - -```bash -kcl main.k -O :person.name=\"Bob\" -O :person.age=10 -d -``` - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Bob" - age = 10 -} -``` - -Another more complicated example: - -```python -schema Person: - name: str - age: int - ids?: [int] - -person = Person { - name = "Alice" - age = 10 -} -``` - -The command is - -```bash -kcl main.k -O :person.ids=\[1,2\] -``` - -The output is - -```yaml -person: - name: Alice - age: 10 - ids: - - 1 - - 2 -``` - -##### Override Delete Sample - -KCL code: - -```python -schema Config: - x?: int = 1 - y?: str = "s" - -config = Config { - x = 2 -} -``` - -The command is - -```bash -kcl main.k -O config.x- -``` - -The output is - -```yaml -config: - x: 1 - y: s -``` - -### Summary - -This page summarized the commonly used features in the KCL language. As a new language, KCL will gradually increase the functional features according to the requirements of the configuration scenario. - -For more information, please try further resources: - -- KCL codelabs -- KCL language specification -- KCL OpenAPI specification diff --git a/versioned_docs/version-0.5.5/reference/lang/types/_category_.json b/versioned_docs/version-0.5.5/reference/lang/types/_category_.json deleted file mode 100644 index 8b257445..00000000 --- a/versioned_docs/version-0.5.5/reference/lang/types/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Types", - "position": 4 -} diff --git a/versioned_docs/version-0.5.5/reference/lang/types/types.md b/versioned_docs/version-0.5.5/reference/lang/types/types.md deleted file mode 100644 index ee88c64d..00000000 --- a/versioned_docs/version-0.5.5/reference/lang/types/types.md +++ /dev/null @@ -1,1381 +0,0 @@ -# Type System - -This document describes the type system of KCL, including: - -- Type rules -- Type checking -- Type conversion -- Type inference - -## Type Rules - -### Basic Definition - -#### Assertion - -All free variables of $S$ are defined in $\Gamma$ - -$$ -\Gamma \vdash S -$$ - -$\Gamma$ is a variable's well-formed environment, such as $x_1:T_1$, ..., $x_n:T_n$ - -The assertion of $S$ has three forms: - -**Environment assertion** indicates that $\Gamma$ is a well-formed type. - -$$ -\Gamma \vdash ◇ -$$ - -**Well-formed type assertion**. In the environment $\Gamma$, $nat$ is a type expression. - -$$ -\Gamma \vdash nat -$$ - -**Typing judgment assertion**. In the environment $\Gamma$,$E$ has the type $T$. - -$$ -\Gamma \vdash E: T -$$ - -#### Inference Rules - -Representation - -$$ -\frac{\Gamma \vdash S_1, ..., \Gamma \vdash S_n}{\Gamma \vdash S} -$$ - -In the inference rules, $u$, $v$, and $w$ are used to represent variables, $i$, $j$, $k$ are used to represent integers, $a$ and $b$ are used to represent floating point numbers, $s$ is used to represent strings, $c$ is used to represent literal values of constants (integers, floating point numbers, strings, boolean), $f$ is used to represent functions, $T$, $S$, $U$ are used to represent types. - -## Environment Rules - -Env ⌀ - -$$ -\frac{}{⌀ \vdash ◇ } -$$ - -## Type Definitions - -Type Bool - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash boolean} -$$ - -Type Int - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash integer} -$$ - -Type Float - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash float} -$$ - -Type String - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash string} -$$ - -Type Literal - -$$ -\frac{ c \in \{boolean, integer, float, string\}}{\Gamma \vdash literalof(c)} -$$ - -Type List - -$$ -\frac{\Gamma \vdash T \ T \neq Void}{\Gamma \vdash listof(T) } -$$ - -Type Dict - -$$ -\frac{\Gamma \vdash T_1 \ \Gamma \vdash T_2\ T_1 \neq Void \ \ T_2 \neq Void}{\Gamma \vdash dictof(T_k=T_1, T_v=T_2)} -$$ - -Type Struct - -$$ -\frac{\Gamma \vdash T_{1} \ ... \ \Gamma \vdash T_{n} \ \ T_i \neq Void \ K_1 \neq K_n}{\Gamma \vdash structof(K_1 : T_{1}, ... , K_n : T_{n})} -$$ - -Type Union - -$$ -\frac{\Gamma \vdash T_1 \ ... \ \Gamma \vdash T_n \ \ T_i \neq Void}{\Gamma \vdash unionof(T_1, ..., T_n)} -$$ - -Type None - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash None} -$$ - -Type Undefined - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Undefined} -$$ - -Type Void - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Void} -$$ - -Type Any - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Any} -$$ - -Type Nothing - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Nothing} -$$ - -## Typing Judgment Rules - -### Operand Expr - -Exp Truth - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash true: boolean} -$$ - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash false: boolean} -$$ - -Exp Int - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash int: integer} -$$ - -Exp Flt - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash flt: float} -$$ - -Exp Str - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash str: string} -$$ - -Exp None - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash none: none} -$$ - -Exp Undefined - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash undefined: undefined} -$$ - -Expr ListExp - -$$ -\frac{\Gamma \vdash E_1: T_1 \ E_2: T_2 \ ... \ E_n: T_n}{\Gamma \vdash [E_1, E_2, ..., E_n]: listof \ sup(T_1, T_2, ..., T_n)} -$$ - -Expr ListComp - -$$ -\frac{\Gamma \vdash E_1: T_1 \ \Gamma \vdash v: T \ \Gamma \vdash E_2: listof \ T \ \Gamma \vdash E_3: boolean}{\Gamma \vdash [E_1 \ for \ v \ in \ E_2 \ if \ E_3]: listof(T_1) } -$$ - -Expr DictExp - -$$ -\frac{\Gamma \vdash E_{k1}: T_{k1} \ \Gamma \vdash E_{v1}: T_{v1} \ ... \ \Gamma \vdash E_{kn}: T_{kN} \ \Gamma \vdash E_{vn}: T_{vN}}{\Gamma \vdash \{E_{k1}: E_{v1}, ..., E_{{kn}}: E_{vn}\}: dictof(T_{k}=sup(T_{k1}, T_{k2}, ... T_{kn}), \ T_{v}=sup(T_{v1}, T_{v2}, ..., T_{vn}))} -$$ - -Expr DictComp - -$$ -\frac{\Gamma \vdash E_1: T_{rki} \ \Gamma \vdash E_2: T_{rvi} \ \Gamma \vdash v_1: T_k \ \Gamma \vdash v_2: T_v \ \Gamma \vdash E_3: dictof(T_{k}, \ T_{v}) \ \Gamma \vdash E_4: boolean}{\Gamma \vdash \{E_1:E_2 \ for \ (v_1, v_2) \ in \ E_3 \ if \ E_4\}: dictof(T_{k}=sup(T_{rk1}, T_{rk2}, ..., T_{rkn}), T_{v}=sup(T_{rv1}, T_{rv2}, ..., T_{rvn})) } -$$ - -Expr StructExpr - -$$ -\frac{\Gamma \vdash E_{1}: T_{1} \ ... \ \Gamma \vdash E_{n}: T_{n} \ K_1 \neq K_n}{\Gamma \vdash \{K_{1} = E_{1}, ..., K_{{n}} = E_{n}\}: structof(K_1 : T_{1}, ... , K_n : T_{n})} -$$ - -The literal type is the value type of basic type, the union type is the combination type of types, void, any, nothing are special type references, and there is no direct value expression correspondence. - -### Primary Expr - -Expr Index - -$$ -\frac{\Gamma \vdash E: listof(T) \ \Gamma \vdash Index: integer}{\Gamma \vdash E[Index]: T} -$$ - -Expr Call - -$$ -\frac{\Gamma \vdash E_1: T_1 \rightarrow T_2 \ \Gamma \vdash E_2: T_1}{\Gamma \vdash E_1 \ (E_2): T_2} -$$ - -Expr List Selector - -$$ -\frac{\Gamma \vdash E: listof(T) \ \Gamma \vdash Index: integer}{\Gamma \vdash E.[Index]: T} -$$ - -Expr Dict Selector - -$$ -\frac{\Gamma \vdash E: dictof(T_k = T_1, T_v=T_2) \ \Gamma \vdash S_1: string \ ... \ \Gamma \vdash S_n: string}{\Gamma \vdash E.\{S_1, ..., S_n\}: dictof(T_k = T_1, T_v=T_2)} -$$ - -Expr Struct Selector - -$$ -\frac{\Gamma \vdash E: structof(K_1 : T_{1}, ... , K_n : T_{n}) \ \Gamma \vdash K_i: string}{\Gamma \vdash E.K_i: T_{i}} -$$ - -### Unary Expr - -Expr + - -$$ -\frac{\Gamma \vdash E: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash \ +E: T} -$$ - -Expr - - -$$ -\frac{\Gamma \vdash E: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash \ -E: T} -$$ - -Expr ~ - -$$ -\frac{\Gamma \vdash E: integer}{\Gamma \vdash \ ~E: integer} -$$ - -Expr not - -$$ -\frac{\Gamma \vdash E: boolean}{\Gamma \vdash \ not \ E: boolean} -$$ - -### Binary Expr - -Expr op, op $\in$ {-, /, %, \*\*, //} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash E_1 \ op \ E_2: T} -$$ - -Expr + - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, float, string, listof(T_1)\}}{\Gamma \vdash E_1 \ + \ E_2: T} -$$ - -Expr \* - -$$ -\frac{\Gamma \vdash E_1: T_1 \ \ \ \Gamma \vdash E_2: T_2 \ \ \ \ (T_1==T_2 \in \{integer, float\}) \ or \ (T_1 == interger \ and \ T_2 \ \in \ \{string, listof(T_3)\}) \ or \ (T_2 == interger \ and \ T_1 \ \in \ \{string, listof(T_3)\})} {\Gamma \vdash E_1 \ * \ E_2: T} -$$ - -Expr % - -$$ -\frac{\Gamma \vdash E_1: interger \ \ \ \Gamma \vdash E_2: integer}{\Gamma \vdash E_1 \ \% \ E_2: interger} -$$ - -Expr op, op $\in$ \{or, and\} - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ op \ E_2: boolean} -$$ - -示例 - -Expr and - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ and \ E_2: boolean} -$$ - -Expr op, op $\in$ \{==, !=, <, >, <=, >=\} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T}{\Gamma \vdash E_1 \ op \ E_2: boolean} -$$ - -Expr > - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ > \ E_2: boolean} -$$ - -Expr op, op $\in$ {&, ^, ~, <<, >>} - -$$ -\frac{\Gamma \vdash E_1: integer \ \ \ \Gamma \vdash E_2: integer}{\Gamma \vdash E_1 \ op \ E_2: integer} -$$ - -Expr | - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, listof(T_1), dictof(T_k, T_v), structof(K_1=T_1, ..., K_n=T_n)\}}{\Gamma \vdash E_1 \ | \ E_2: T} -$$ - -Expr op, op $\in$ {in, not in} - -$$ -\frac{\Gamma \vdash E_1: string \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{dictof, structof\}}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: listof(S), T \sqsubseteq S}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -Expr op $\in$ {is, is not} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -### IF Expr - -Expr If - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: T \ \ \ \Gamma \vdash E_3: T}{\Gamma \vdash if \ E_1 \ then \ E_2 \ else \ E_3: T} -$$ - -### Stmt - -Stmt If - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash S_1: Void \ \ \ \Gamma \vdash S_2: Void}{\Gamma \vdash if \ E_1 \ then \ S_1 \ else \ S_2: Void} -$$ - -Stmt Assign - -$$ -\frac{\Gamma \vdash id: T_0 \ \ \ \Gamma \vdash T_1 \ \ \ \Gamma \vdash E: T_2}{\Gamma \vdash id: T_1 \ = \ E : Void} -$$ - -Type Alias - -$$ -\frac{\Gamma \vdash id: T_0 \ \ \ \Gamma \vdash T_1}{\Gamma \vdash type \ id \ = \ T_1 : Void} -$$ - -## Union - -List Union - -$$ -\frac{\Gamma \vdash \ listof(T) \ \ \ \Gamma \vdash \ listof(S)}{\Gamma \vdash \ listof(unionof(T, S))} -$$ - -Dict Union - -$$ -\frac{\Gamma \vdash \ dictof(T_1, T_2) \ \ \ \Gamma \vdash \ dictof(S_1, S_2)}{\Gamma \vdash \ dictof(unionof(T_1, S_1), unionof(T_2, S_2))} -$$ - -Struct Union - -Define two structures: $structof(K_{1}: T_{1}, ..., K_{n}: T_{n}),structof(H_{1}: S_{1}, ..., H_{m}: S_{n})$ - -Define their union types: - -$$ -structof(J_{1}: U_{1}, ..., J_{p}: U_{n}) = structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \bigcup structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) -$$ - -Example - -$$ -structof() \ \bigcup \ structof(H_{1}: T_{1}, ..., H_{m}: T_{n}) = structof(H_{1}: T_{1}, ..., H_{m}: T_{n}) -$$ - -$$ -structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \ \bigcup \ structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) = structof(K_1: T_1) :: (structof(K_{2}: T_{2}, ..., K_{n}: T_{n}) \ \bigcup \ structof(H_{1}: S_{1}, ..., H_{m}: S_{n})) -$$ - -where "::" denotes the operation of adding a dual to a structure, which is defined as follows: - -$$ -structof(K_{1}: T_{1}) :: structof() = structof(K_{1}: T_{1}) -$$ - -$$ -structof(K_{1}: T_{1}) :: structof(K_{1}: T_{1}', ..., K_n: T_{n}) = structof(K_{1}: union\_op(T_{1}, T_{1}'), ..., K_{n}: T_{n}) -$$ - -$$ -structof(K_{1}: T_{1}) :: structof(K_{2}: T_{2}, ..., K_n: T_{n}) = structof(K_{2}: T_2) :: structof(K_{1}: T_1) :: structof(K_{3}: T_3, ..., K_{n}: T_{n}) -$$ - -Based on this, the union of two structures is defined as: - -$$ -\frac{\Gamma \vdash structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \ \Gamma \vdash structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) \ structof(J_{1}: U_{1}, ..., J_{p}: U_{n}) = structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \bigcup structof(H_{1}: S_{1}, ..., H_{m}: S_{n})}{\Gamma \vdash structof(J_{1}: U_{1}, ..., J_{p}: U_{n}))} -$$ - -where $union\_op(T_1, T_2)$ denotes different types of judgment operations for the same $K_i$. - -- When $T_1$ and $T_2$ have the partial order relation. If $T_1 \sqsubseteq T_2$, return $T_2$, otherwise return $T_1$, which is the minimum upper bound -- When $T_1$ and $T_2$ have no partial order relationship, there are three optional processing logic: - - Structure union failed, return a type error. - - Return the type of the latter $T_2$. - - Return the type $unionof (T_1, T_2)$. - -Here, we need to choose the appropriate processing method according to the actual needs. - -Structure inheritance can be regarded as a special union. The overall logic is similar to that of union, but in $union\_op(T_1, T_2)$ for the same $K_i$, the different types of judgment operations are as follows: - -- When $T_1$ and $T_2$ have the partial order relation and $T_1 \sqsubseteq T_2$, return $T_1$, that is, only if $T_1$ is the lower bound of $T_2$, the lower bound of $T_1$ shall prevail. -- Otherwise, a type error is returned. - -Through such inheritance design, we can achieve hierarchical, bottom-up and layer-by-layer contraction of type definition. - -## Operation - -KCL supports operations on structure attributes in the form of $p op E$. That is, for the given structure $A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})$, the path $p$ in the structure is specified with the value of $E$ (such as union, assign, insert, etc.). - -Define the following update operations: - -$$ -\frac{{\Gamma\vdash A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})}  {\Gamma\vdash p \in (K_{1}, ..., K_{n})} \ {\Gamma\vdash e:T}   k \neq k_1, ..., k \neq k_n} -{ A \{p \ op \ e\}:\{K_1:T_1, ..., K_n:T_n\}∪\{p:T\}} -$$ - -That is to say, the operation on the path $p$ is essentially a union of two structures. The rules for the same name attribute type union depend on the situation. For example, the path $p$ is an identifier $p=k_1$ that can be used as a field name $k_1$, and the field name in structure A is also $k_1$, its type is $T_1$, and the type of the expression $e$ is also $T_1$, then - -$$ -\frac{{\Gamma\vdash A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})}  {\Gamma\vdash p = K_{1}} \ {\Gamma\vdash e:T_1}   k \neq k_1, ..., k \neq k_n} -{ A \{p \ op \ e\}:\{K_1:T_1, ..., K_n:T_n\}} -$$ - -Note: - -- The type $T_1$ of the expression $e$ have the same type with the original attribute of the same name $K_1$. It can be relaxed appropriately according to the actual situation, such as the type of $e$ $\sqsubseteq T_1$ is enough. -- For the operation of nested multi-layer structures, the above rules can be used recursively. - -## Type Partial Order - -### Basic Types - -$$ -Type \ T \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ T -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Bool \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Int \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Float \sqsubseteq Type \ Any -$$ - -$$ -Type \ Int \sqsubseteq Type \ Float -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ String \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Literal \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ List \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Dict \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Struct \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ None \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Void \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Any -$$ - -### Literal Type - -$$ -Type \ Literal(Bool) \sqsubseteq Type \ Bool -$$ - -$$ -Type \ Literal(Int) \sqsubseteq Type \ Int -$$ - -$$ -Type \ Literal(Float) \sqsubseteq Type \ Float -$$ - -$$ -Type \ Literal(String) \sqsubseteq Type \ String -$$ - -### Union Type - -$$ -Type \ X \sqsubseteq Type \ Union(X, Y) -$$ - -### Introspect - -$$ -Type \ X \sqsubseteq Type \ X -$$ - -Example - -$$ -Type \ Bool \sqsubseteq Type \ Bool -$$ - -$$ -Type \ Int \sqsubseteq Type \ Int -$$ - -$$ -Type \ Float \sqsubseteq Type \ Float -$$ - -$$ -Type \ String \sqsubseteq Type \ String -$$ - -$$ -Type \ List \sqsubseteq Type \ List -$$ - -$$ -Type \ Dict \sqsubseteq Type \ Dict -$$ - -$$ -Type \ Struct \sqsubseteq Type \ Struct -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Nothing -$$ - -$$ -Type \ Any \sqsubseteq Type \ Any -$$ - -$$ -Type \ Union(Type Int, Type Bool) \sqsubseteq Type \ Union(Type Int, Type Bool) -$$ - -### Transmit - -$$ -Type \ X \sqsubseteq Type \ Z \ if \ Type \ X \sqsubseteq Type \ Y \ and \ Type \ Y \sqsubseteq \ Type \ Z -$$ - -### Contained - -$$ -Type \ List(T_1) \sqsubseteq Type \ List(T_2) \ if \ T_1 \sqsubseteq T_2 -$$ - -$$ -Type \ Dict(T_{k1}, T_{v1}) \sqsubseteq Type \ Dict(T_{k2}, T_{v2}) \ if \ T_{k1} \sqsubseteq T_{k2} \ and \ T_{v1} \sqsubseteq T_{v1} -$$ - -$$ -Type \ Structure(K_1: T_{a1}, K_2: T_{a2}, ..., K_n: T_{an}) \sqsubseteq Type \ Structure(K_1: T_{b1}, K_2: T_{b2}, ..., K_n: T_{bn}) \ if \ T_{a1} \sqsubseteq T_{b1} \ and \ T_{a2} \sqsubseteq T_{b2} \ and \ ... \ and \ T_{an} \sqsubseteq T_{bn} -$$ - -### Inheritance - -$$ -Type \ Struct \ A \sqsubseteq Type \ Struct \ B \ if \ A \ inherits \ B -$$ - -### None - -$$ -Type \ None \sqsubseteq Type \ X, X \notin \{Type \ Nothing, \ Type \ Void\} -$$ - -### Undefined - -$$ -Type \ Undefined \sqsubseteq Type \ X, X \notin \{Type \ Nothing, \ Type \ Void\} -$$ - -## Equality - -- Commutative law - -$$ -Type \ Union(X, Y) == Type \ Union(Y, X) -$$ - -Example - -$$ -Type \ Union(Int, Bool) == Type \ Union(Bool, Int) -$$ - -- Associative law - -$$ -Type \ Union(Union(X, Y), Z) == Type \ Union(X, Union(Y, Z)) -$$ - -Example - -$$ -Type \ Union(Union(Int, String), Bool) == Type \ Union(Int, Union(String, Bool)) -$$ - -- Idempotent - -$$ -Type \ Union(X, X) == Type \ X -$$ - -Example - -$$ -Type \ Union(Int, Int) == Type \ Int -$$ - -Partial order derivation - -$$ -Type \ Union(X, Y) == Type \ Y \ if \ X \sqsubseteq Y -$$ - -Example - -Assume that Struct A inherits Struct B - -$$ -Type \ Union(A, B) == Type \ B -$$ - -Idempotency is a special case of partial order reflexivity - -### List - -$$ -Type \ List(X) == Type \ List(Y) \ if \ X == Y -$$ - -### Dict - -$$ -Type \ Dict(T_k, T_v) == Type \ Dict(S_k, S_v) \ if \ T_k == S_k \ and \ T_v == S_v -$$ - -### Struct - -$$ -Type \ Struct(K_1: T_{1}, K_2: T_{2}, ..., K_n: T_{n}) == Type \ Struct(K_1: S_{1}, K_2: S_{2}, ..., K_n: S_{n}) \ if \ T_{1} == S_{1} \ and \ ... \ and \ T_{n} == S_{n} -$$ - -### Partial Order Checking - -$$ -Type \ X == Type \ Y \ if \ Type \ X \sqsubseteq Type \ Y \ and \ Type \ Y \sqsubseteq \ Type \ X -$$ - -## Basic Methods - -- `sup(t1: T, t2: T) -> T`: Calculate the minimum upper bound of two types `t1` and `t2` according to the type partial order. The union type needs to be created dynamically. -- `typeEqual(t1: T, t2: T) -> bool`: Compare whether the two types `t1` and `t2` are equal. -- `typeToString(t: T) -> string`: Resolve and convert the type to the corresponding string type recursively from top to bottom. - -### Sup Function - -- Type parameters, condition types and other characteristics are not considered temporarily. -- Use an ordered collection to store all types of `UnionType`. -- Use a global map to store all generated union types according to the name of `UnionType`. -- Calculate the inclusion relationship between types according to the partial order relationship. - -```go -// The Sup function returns the minimum supremum of all types in an array of types -func Sup(types: T[]) -> T { - typeOf(types, removeSubTypes=true) -} - -// Build a sup type from types [T1, T2, ... , Tn] -func typeOf(types: T[], removeSubTypes: bool = false) -> T { - assert isNotNullOrEmpty(types) - // 1. Initialize an ordered set to store the type array - typeSet: Set[T] = {} - // 2. Add the type array to the ordered set for sorting by the type id and de-duplication - addTypesToTypeSet(typeSet, types) - // 3. Remove sub types according to partial order relation rules e.g. sub schema types - if removeSubTypes { - removeSubTypes(typeSet) - } - if len(typeSet) == 1 { - // If the typeSet has only one type, return it - return typeSet[0] - } - // 4. Get or set the union type from the global union type map - id := getIdentifierFromTypeSet(typeSet) - unionType := globalUnionTypeMap.get(id) - if !unionType { - unionType = createUnionType(typeSet) // Build a new union type - globalUnionTypeMap.set(id, unionType) - } - return unionType -} - -// Add many types into the type set -func addTypesToTypeSet(typeSet: Set[T], types: T[]) -> void { - for type in types { - addTypeToTypeSet(typeSet, type) - } -} - -// Add one type into the type set -func addTypeToTypeSet(typeSet: Set[T], type: T) -> void { - if isUnion(type) { - return addTypesToTypeSet(typeSet, toUnionOf(type).types) - } - // Ignore the void type check - if !isVoid(type) { - // De-duplication according to the type of id - typeSet.add(type) - } -} - -func removeSubTypes(types: Set[T]) -> void { - for source in types { - for target in types { - if !typeEqual(source, target) { - // If the two types have an inheritance relationship, the base class is retained, or if the two types have a partial order relationship according to the relation table. - if (isPartialOrderRelatedTo(source, target)) { - types.remove(source) - } - } - } - } -} - -// isPartialOrderRelatedTo function Determine whether two types have a partial order relationship `source \sqsubseteq target` -// according to the partial order relationship table and rules -func isPartialOrderRelatedTo(source: T, target: T) -> bool { - assert isNotNullOrEmpty(source) - assert isNotNullOrEmpty(target) - if isNoneOrUndefined(source) and !isNothing(target) and !isVoid(target) { - return true - } - if isAny(target) { - return true - } - if typeEqual(source, target) { - return true - } - if isUnion(target) and source in target.types { - return true - } - // Literal Type - if (isStringLiteral(source) and isString(target)) or \ - (isBooleanLiteral(source) and isBool(target)) or \ - (isIntLiteral(source) and isInt(target)) or \ - (isFloatLiteral(source) and isFloat(target)) { - return true - } - if isInt(source) and isFloat(target) { - return true - } - if isList(source) and isList(target) { - return isPartialOrderRelatedTo(toListOf(source).eleType, toListOf(target).eleType - } - if isDict(source) and isDict(target) { - return isPartialOrderRelatedTo(toDictOf(source).keyType, toDictOf(target).keyType) and isPartialOrderRelatedTo(toDictOf(source).valueType, toDictOf(target).valueType) - } - if isStruct(source) and isStruct(target) { - if isTypeDerivedFrom(source, target) { - return true - } - // Empty Object - if len(target.keys) == 0 { - return true - } - if any([key Not in source.keys for key in target.keys]) { - return false - } - for key, sourceType in (source.keys, source.types) { - targetType = getKeyType(target, key) ? getKeyType(target, key) : anyTypeOf() - if !isPartialOrderRelatedTo(sourceType, targetType) { - return false - } - } - return true - } - return false -} -``` - -## Type Checking - -### Checker - -The type checker traverses the syntax tree from top to bottom through syntax-directed translation, and determines whether the program structure is a well-typed program according to context-sensitive training rules. - -The type checker depends on type rules, and the information of type environment $\Gamma$ is recorded in the symbol table. Use abstract syntax for type expressions, such as `listof (T)`. When the type check fails, a type mismatch error is generated, and the error message is generated according to the syntax context. - -### Basic Methods - -1. `isUpperBound(t1, t2): supUnify(t1, t2) == t2` -2. `supUnify(t1, t2):` - -- For the foundation type, `sup(t1, t2)` is calculated according to the partial order relationship -- For list, dict, Struct, recursively `supUnify` the types of elements -- When there is no partial order relationship, return `Nothing` - -### Checking Logic - -#### Operand Expr - -$D \to id: T$ - -``` -env.addtype(id.entry, T.type) -``` - -$T \to boolean$ - -``` -T.type = boolean -``` - -$T \to integer$ - -``` -T.type = integer -``` - -$T \to float$ - -``` -T.type = float -``` - -$T \to string$ - -``` -T.type = string -``` - -$T \to c, \ c \in \{boolean, integer, float, string\}$ - -``` -T.type = literalof(c) -``` - -$T \to None$ - -``` -T.type = None -``` - -$T \to Undefined$ - -``` -T.type = Undefined -``` - -$T \to \ [T_1]$ - -``` -T.type = listof (T1.type) -``` - -$T \to { \{T_1: T_2\} }$ - -``` -T.type = dictof (T1.type: T2.type) -``` - -$T \to { \{N_1: T_1, N2: T_2, ..., N_n: T_n\} }$ - -``` -T.type = structof (N1: T1.type, N2: T2.type, ..., Nn: Tn.type) -``` - -$E \to id$ - -``` -E.type = env.lookup(id.entry) -``` - -$E \to [E_1, E_2, ..., E_n]$ - -``` -func listExpr(E) { - supe = sup([e.type for e in E]]) - E.type = listof(type) -} -``` - -$E \to [E_1 \ for \ E_2 \ in \ E_3 \ if \ E_4]$ - -``` -func listComp(E) { - if !typeEqual(E4.type, boolean) { - raise type_error - } - if !isUpperBound(listof(Any), E3.type) { - raise type_error(E) - } - if !isUpperBound(E3.type, E2.type) { - raise type_error(E) - } - E.type = listof(E1.type) -} -``` - -$E \to \{E_{k1}: E_{v1}, ..., E_{kn}: E_{vn}\}$ - -``` -func dictExpr(E) { - supk := sup([e.type for e in E.keys()]]) - supv := sup([e.type for e in E.values()]]) - E.type = dictof(supk, supv) -} -``` - -$E \to \{E_1:E_2 \ for \ (E_3, E_4) \ in \ E_5 \ if \ E_6\}$ - -``` -func dictComp(E) { - if !typeEqual(E6.type, boolean) { - raise type_error(E) - } - if !isUpperBound(dictof(Any, Any), E5.type) { - raise type_error(E) - } - if !isUpperBound(E5.type, dictof(E3.type, E4.type)) { - raise type_error(E) - } - E.type = dictof(E1.type, E2.type) -} -``` - -$E \to \{E_{k1}: E_{v1}, ..., E_{kn}: E_{vn}\}$ - -``` -func dictExpr(E) { - supk := sup(Ek1, ..., Ekn) - supv = sup(Ev1, ..., Evn) - E.type = dictof(supk, supv) -} -``` - -$E \to \{N_{1} = E_{1}, ..., N_{{n}} = E_{n}\}$ - -``` -func structExpr(E) { - Struct = structof() - for n, e in E { - Struct.add(n, e.type) - } - E.type = Struct -} -``` - -#### Primary Expr - -$E \to E_1[E_2]$ - -``` -func sliceSuffix(E) { - if !isUpperBound(listof(Any), E.E1.type) { - raise type_error(E) - } - if typeEqual(E.E2.type, integer) { - raise type_error(E) - } - E.type = E.E1.type.eleType -} -``` - -$E \to E_1(E_2)$ - -``` -func callSuffix(E) { - if !typeEqual(E.E1.type, func) { - raise type_error(E) - } - if !isUpperBound(listof(E.E1.arguType), E.E2.type) { - raise type_error(E) - } - E.type = E.E1.returnType -} -``` - -#### Unary Expr - -According to the reasoning rules of each binocular operator, take `+` as an example. - -$E \to + E_1$ - -``` -func Plus(E) { - if !typeEqual(E.E1.type, [integer, float]) { - raise type_error(E) - } - E.type = E.E1.type -} -``` - -#### Binary Expr - -According to the reasoning rules of each binocular operator, take `%` as an example. - -$E \to E_1 \ % \ E_2$ - -``` -func Mod(E) { - if !(typeEqual(E.E1.type, [integer, float]) && typeEqual(E.E2.type, [integer, float])) { - raise type_error(E) - } - E.type = E.E1.type -} -``` - -#### IF Binary Expr - -$E \to if E_1 \ then \ E_2 else \ E_3$ - -``` -func ifExpr(E) { - if !typeEqual(E.type, boolean) { - raise type_error(E) - } - if !typeEqual(E_2.type, E_3.type) { - raise type_error(E) - } - E.type = E_2.type -} -``` - -#### Stmt - -$S \to if \ E \ then \ S_1 \ else \ S_2$ - -``` -func ifStmt(S) { - if !typeEqual(S.E.type, boolean) { - raise type_error(E) - } - if !typeEqual(S.S1.type, S.S2.type) { - raise type_error(E) - } - S.type = S.S1.type -} -``` - -$S \to id: T = E$ - -$S \to id = T E$ - -``` -func assignStmt(S) { - tpe := env.lookup(id.entry) - if tpe != nil && tpe != S.T { - raise type_error(E) - } - if isUpperBound(tpe, E.type) { - raise type_error(E) - } - env.addtype(id.entry, T.type) -} -``` - -## Type Conversion - -### Basic Definition - -Through syntax-directed translation, the value types involved in the operation are automatically converted according to the operator characteristics. - -### Conversion Rules - -$E \to E_1 \ op \ E_2, , op \in \{+, -, *, /, \%, **, //\}$ - -``` -func binOp(E) { - if E.E1.type == integer and E.E2.type == integer { - E.type = integer - } else if E.E1.type == integer and E.E2.type == float { - E.type = float - } else if E.E1.type == float and E.E2.type == integer { - E.type = float - } else if E.E1.type == float and E.E2.type == float { - E.type = float - } -} -``` - -## Type Inference - -### Basic Definition - -- Type rule derivation and type reconstruction in case of incomplete type information -- Derive and reconstruct the data structure types in the program from the bottom up, such as basic type, e.g., list, dict and struct types. - -### Basic Methods - -1. `typeOf(expr, subst)`: The input is the expression and substitution rule set, and the type of expr and the new substitution rule set are returned. -2. `unifier(t1, t2, subst, expr)`: Try substitution with `t1=t2`. If the substitution is successful (no occurrence and no conflict), add `t1=t2` to the subst and return the subst. Otherwise, an error has occurred or there is a conflict. - -### Inferential Logic - -$E \to id = E_1$ - -``` -func assignExpr(E, subst) { - return unifier(E.id.type, E.E_1.type, subst, E) -} -``` - -$unifier(t1, t2, subst, expr) \rightarrow subst$ - -``` -func unifier(t1, t2, subst, expr) { - t1 = applySubstToTypeEquation(t1, subst) - t2 = applySubstToTypeEquation(t2, subst) - - if t1 == t2 { - return subst - } - - if isTypeVar(t1) { - if isNoOccur(t1, t2) { - addTypeEquationToSubst(subst, t1, t2) - return subst - } else { - raise occurrence_violation_error(t1, t2, expr) - } - } - - if isTypeVar(t2) { - if isNoOccur(t2, t1) { - addTypeEquationToSubst(subst, t2, t1) - return subst - } else { - raise occurrence_violation_error(t2, t1, expr) - } - } - - if isList(t1) and isList(t2) { - return unifier(toListOf(t1).eleType, toListOf(t2).eleType, subst, expr) - } - if isDict(t1) and isDict(t2) { - dict1of := toDictOf(t1) - dict2of := toDictOf(t2) - subst = unifier(dict1of.keyType, dict2of.keyType, subst, expr) - subst = unifier(dict1of.valueType, dict2of.valueType, subst, expr) - return subst - } - if isStruct(t1) and isStruct(t2) { - Struct1of := tostructof(t1) - Struct2of := tostructof(t2) - for key, _ in Struct1of { - subst = unifier(t1[key].type, t2[key].type, subst, expr) - } - return subst - } - - raise unification_error(t1, t2, expr) -} - -func applySubstToTypeEquation(t, subst) { - // walks through the type t, replacing each type variable by its binding in the substitution -σ. If a variable is Not bound in the substitution, then it is left unchanged. - if isBasicType(t) { - return t - } - if isList(t) { - return listOf(applySubstToTypeEquation(toListOf(t).eleType, subst)) - } - if isDict(t) { - dictof := toDictOf(t) - kT := applySubstToTypeEquation(dictof.keyType, subst) - vT := applySubstToTypeEquation(dictof.valueType, subst) - return dictOf(kT, vT) - } - if isStruct(t) { - structof := tostructof(t) - s := structof() - for key, type in Struct1of { - kT := applySubstToTypeEquation(type, subst) - s.add(key, kT) - } - return s - } - if hasTypeVar(t) { - for tvar in t.vars { - if tvar in subst { - *tvar = subst[tvar] - } - } - } - return t -} - -func addTypeEquationToSubst(subst, tvar, t) { - // takes the substitution σ and adds the equation tv = t to it - for _, t in subst { - for tvar in t.vars { - tmp := applyOneSubst(tsvar, tvar, t) - *tvar = tmp - } - } - subst.add(tvar, t) -} - -func applyOneSubst(t0, tvar, t1) { - // substituting t1 for every occurrence of tv in t0. - if isBasicType(t0) { - return t0 - } - if isList(t0) { - return listOf(applyOneSubst(toListOf(t).eleType, tvar, t1)) - } - if isDict(t0) { - dictof := toDictOf(t) - kT := applyOneSubst(dictof.keyType, tvar, t1) - vT := applyOneSubst(dictof.valueType, tvar, t1) - return dictOf(kT, vT) - } - if isStruct(t0) { - structof := tostructof(t) - s := structof() - for key, type in Struct1of { - kT := applyOneSubst(type, tvar, t1) - s.add(key, kT) - } - return s - } - if t0 == tvar { - return t1 - } - return t0 -} - -func isNoOccur(tvar, t) { - // No variable bound in the substitution occurs in any of the right-hand sides of the substitution. - if isBasicType(t) { - return true - } - if isList(t) { - return isNoOccur(tvar, toListOf(t).eleType) - } - if isDict(t) { - dictof := toDictOf(t) - return isNoOccur(tvar, dictof.keyType) and isNoOccur(tvar, dictof.valueType) - } - if isStruct(t) { - structof := tostructof(t) - noOccur := true - for _, type in structof { - noOccur = noOccur and isNoOccur(tvar, type) - } - return noOccur - } - return tvar != t -} -``` - -### Example - -#### Normal Inference - -``` -T : { - a = 1 - b = "2" - c = a * 2 - d = { - d0 = [a, c] - } -} - -x: T = { - a = 10 -} -``` - -#### Occurrence Violation Error - -``` -T = { - a = a -} -``` - -#### Type Unification Error - -``` -T : { - a = 1 -} - -T : { - a = "1" -} -``` - -## Reference - -- [https://en.wikipedia.org/wiki/Type_system](https://en.wikipedia.org/wiki/Type_system) -- Pierce, Benjamin C. (2002). Types and Programming Languages. MIT Press. -- [https://www.cs.cornell.edu/courses/cs4110/2010fa/](https://www.cs.cornell.edu/courses/cs4110/2010fa/) -- [https://www.typescriptlang.org/docs/handbook/basic-types.html](https://www.typescriptlang.org/docs/handbook/basic-types.html) -- [https://www.typescriptlang.org/docs/handbook/advanced-types.html](https://www.typescriptlang.org/docs/handbook/advanced-types.html) diff --git a/versioned_docs/version-0.5.5/reference/model/_category_.json b/versioned_docs/version-0.5.5/reference/model/_category_.json deleted file mode 100644 index 398617be..00000000 --- a/versioned_docs/version-0.5.5/reference/model/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "System Package", - "position": 2 -} diff --git a/versioned_docs/version-0.5.5/reference/model/base64.md b/versioned_docs/version-0.5.5/reference/model/base64.md deleted file mode 100644 index 3f6e617b..00000000 --- a/versioned_docs/version-0.5.5/reference/model/base64.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: "base64" -linkTitle: "base64" -type: "docs" -description: base64 system module - base64 encode and decode function -weight: 100 ---- - -## encode - -`encode(value: str, encoding: str = "utf-8") -> str` - -Encode the string `value` using the codec registered for encoding. - -## decode - -`decode(value: str, encoding: str = "utf-8") -> str` - -Decode the string `value` using the codec registered for encoding. diff --git a/versioned_docs/version-0.5.5/reference/model/builtin.md b/versioned_docs/version-0.5.5/reference/model/builtin.md deleted file mode 100644 index 4bb34766..00000000 --- a/versioned_docs/version-0.5.5/reference/model/builtin.md +++ /dev/null @@ -1,386 +0,0 @@ ---- -title: "builtin" -sidebar_position: 1 ---- - -KCL provides a list of built-in functions that are automatically loaded and can be used directly without providing any module name. For example, `print` is a function provided by a widely used built-in module. - -## Type Conversion Functions - -KCL's `bool`, `int`, `float`, `str`, `list`, `dict` and other types have built-in conversion functions of the same name. Among them, `int` can not only be used to truncate floating-point numbers, but also can be used to convert strings to integers (decimal when parsing, other values can also be specified). - -The following are common uses of type-related functions: - -```py -b1 = bool(1) # true -b2 = bool(1.5) # true -b3 = bool("true") # true -b4 = bool("") # false -b5 = bool([]) # false -b6 = bool({}) # false - -i1 = int("11") # 11 -i2 = int("11", base=8) # 9 -i3 = int("11", base=2) # 3 - -f1 = float(1) # 1.0 -f2 = float("1.5") # 1.5 - -s1 = str(1) # 1 - -l1 = list([1, 2, 3]) -``` - -## String Builtin Member Functions - -- [String Spec](/docs/reference/lang/spec/datatypes) - -## print - -`print(*args:any, end:str='\n')` - -The built-in print function, which provides different types of variable parameter printing, adds a newline at the end by default. The following are common usages: - -```python -print("hello KCL") -print() -print(None, end=':') -print(None) -print(True) -print(False) -print(123) -print(123.0) -print('abc ${123}') -print("abc ${456}") -print([1,'a', True]) -print(1,'a', True) -print({}) -print({a: 123}) -``` - -The output is: - -```shell -hello KCL - -None:None -True -False -123 -123.0 -abc 123 -abc 456 -[1, 'a', True] -1 a True -{} -{'a': 123} -``` - -If you do not want the default newline, you can re-specify the ending string with the `end=''` named parameter. - -```python -print("Hello KCL", end='') -``` - -## multiplyof - -`multiplyof(a:int, b:int) -> bool` - -Check whether the integer `a` is an integer multiple of `b`, and return a boolean value: - -```python -print(multiplyof(2, 1)) # True -print(multiplyof(1, 2)) # False -print(multiplyof(0, 1)) # True -print(multiplyof(0, 2)) # True -print(multiplyof(1, 0)) # Error -``` - -`0` is a multiple of any number. But `b` cannot be `0`, otherwise an exception will be thrown. - -## isunique - -`isunique(list: [any]) -> bool` - -Check if there are duplicate elements in an array, and return a boolean value: - -```python -print(isunique([])) # True -print(isunique([1])) # True -print(isunique([1, 2])) # True - -print(isunique([1, 1])) # False -print(isunique([1, 1.0])) # False -print(isunique([1.1, 1.1])) # False - -print(isunique(['abc', "abc"])) # False -print(isunique(['abc', "a${'bc'}"])) # False -``` - -It should be noted that integers and floating-point numbers ignore the type difference and judge whether the values are equal. - -## len - -`len(x: str | [any] | {:}) -> int` - -Return the length of strings, lists, and arrays: - -```python -print(len([])) # 0 -print(len({})) # 0 - -print(len([1])) # 1 -print(len({abc:123})) # 1 - -print("abc") # 3 -``` - -Note: Calculating lengths on `schema` objects is not supported. - -## abs - -`abs(x: number) -> number` - -Calculate the absolute value of `x`. - -## all_true - -`all_true(x:str|[]|{:}) -> bool` - -Judging that all elements of a list or dictionary class are true, the usage is as follows: - -```python -print(all_true([])) # True -print(all_true({})) # True - -print(all_true([True])) # True -print(all_true([1])) # True - -print(all_true([True, False])) # False -print(all_true([True, None])) # False -``` - -Returns true when the list is empty. - -## any_true - -`any_true(x:str|[]|{:}) -> bool` - -Judging that at least one element in the iterable object is true, the usage is as follows: - -```python -print(any_true([])) # False -print(any_true([1])) # True -``` - -## bin - -`bin(x:number) -> str` - -A string that returns the binary representation of an integer, used as follows: - -```python -print(bin(8)) # 0b1000 -``` - -## hex - -`hex(number)` - -A string that returns the hexadecimal representation of an integer, used as follows: - -```python -print(hex(18)) # 0x12 -``` - -## oct - -`oct(number)` - -A string that returns the octal representation of an integer, used as follows: - -```python -print(oct(10)) # 0o12 -``` - -## option - -`option(key:str, type:str='', required=False, default=None, help="") -> any` - -Gets the value of the command line top level argument input. - -## ord - -`ord(c) -> int` - -Get the Unicode code point value of the character, the usage is as follows: - -```python -print(ord('A')) # 65 -print(ord('B')) # 66 -print(ord('C')) # 67 -``` - -## sorted - -`sorted(x: []) -> []` - -Returns the sorted list, used as follows: - -```python -_a = [] -_b = [2, 1] - -_c = sorted(_a) -_d = sorted(_b) - -print(_a) # [] -print(_b) # [2, 1] -print(_c) # [] -print(_d) # [1, 2] -``` - -## range - -`range(start:int, end:int, step=1) -> [int]` - -Generates an iterable list, used as follows: - -```python -print(range(1,5)) # [1, 2, 3, 4] -print(range(1,5, 2)) # [1, 3] -print(range(5, 1, -1)) # [5, 4, 3, 2] -``` - -## min - -`min(x:[number]) -> number` - -Returns the smallest element in the list, used as follows: - -```python -print(min([1,2])) # 1 -print(min([2,1])) # 1 -``` - -## max - -`max(x:[number]) -> number` - -Returns the largest element in the list, used as follows: - -```python -print(max([1,2])) # 2 -print(max([2,1])) # 2 -``` - -## sum - -`sum(x:[number], init_value=0) -> number` - -Returns the sum of all elements in the list, used as follows: - -``` -print(sum([1,2])) # 3 -print(sum([2,1], 1000)) # 1003 -``` - -## pow - -`pow(x: number, y: number, z: number = None) -> number` - -Computes `x**y`, or `(x**y)%z` if `z` is not empty, supports integer and floating point numbers, used as follows: - -```python -print(pow(2,3)) # 8 -print(pow(2, 3, 5)) # 8%5 == 3 - -print(pow(2, 0.5)) # 1.414 -``` - -## round - -`round(number: int|float, ndigits:int|None) -> float | int` - -Returns the rounded approximation of `number`. If `ndigits` is not `None` returns a float with the specified number of decimal places (cannot be negative), otherwise returns an integer structure, used as follows: - -```python -print(round(1)) # 1 -print(round(1.4)) # 1 -print(round(1.5)) # 2 - -print(round(1.5555, 1)) # 1.6 -print(round(1.5555, 2)) # 1.56 - -print(round(1.5555)) # 2 -print(round(1.5555, 0)) # 2.0 -``` - -It should be noted that the difference between `ndigits` being `None` and `0` is that the prefix returns `int` type, the latter returns `float` type. - -## typeof - -`typeof(x: any, full_name: bool = False) -> str` - -Output the type of `x` at runtime. When the `full_name` parameter is set to `True`, the package prefix of the form `pkg.schema` will be returned, used as follows: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person{} -t3 = typeof(_x1) - -_x2 = pkg.Person{} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# Output -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -## zip - -`zip(*args: str|list|dict)` - -It is used to take an iterable object as a parameter, pack the corresponding elements in the object into tuples, and then return a list composed of these tuples, used as follows: - -```py -a = zip([0, 1, 2], [3, 4, 5]) -b = zip([0, 1], [3, 4, 5]) -c = zip([0, 1, 2], [3, 4, 5, 6]) - -# Output -# a: -# - - 0 -# - 3 -# - - 1 -# - 4 -# - - 2 -# - 5 -# b: -# - - 0 -# - 3 -# - - 1 -# - 4 -# c: -# - - 0 -# - 3 -# - - 1 -# - 4 -# - - 2 -``` diff --git a/versioned_docs/version-0.5.5/reference/model/crypto.md b/versioned_docs/version-0.5.5/reference/model/crypto.md deleted file mode 100644 index 7fab7e50..00000000 --- a/versioned_docs/version-0.5.5/reference/model/crypto.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "crypto" -linkTitle: "crypto" -type: "docs" -description: crypto system module -weight: 100 ---- - -## md5 - -`md5(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `MD5` and the codec registered for encoding. - -## sha1 - -`sha1(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA1` and the codec registered for encoding. - -## sha224 - -`sha224(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA224` and the codec registered for encoding. - -## sha256 - -`sha256(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA256` and the codec registered for encoding. - -## sha384 - -`sha384(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA384` and the codec registered for encoding. - -## sha512 - -`sha512(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA512` and the codec registered for encoding. diff --git a/versioned_docs/version-0.5.5/reference/model/datetime.md b/versioned_docs/version-0.5.5/reference/model/datetime.md deleted file mode 100644 index 5b829890..00000000 --- a/versioned_docs/version-0.5.5/reference/model/datetime.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: "datetime" -linkTitle: "datetime" -type: "docs" -description: datetime system module -weight: 100 ---- - -## time - -`ticks() -> float` - -Return the current time in seconds since the Epoch. Fractions of a second may be present if the system clock provides them. - -## date - -`date() -> str` - -Return the `%Y-%m-%d %H:%M:%S` format date. - -## now - -`now() -> str` - -Return the local time. e.g. `'Sat Jun 06 16:26:11 1998'` - -## today - -`today() -> str` - -Return the `%Y-%m-%d %H:%M:%S.%{ticks}` format date. diff --git a/versioned_docs/version-0.5.5/reference/model/index.md b/versioned_docs/version-0.5.5/reference/model/index.md deleted file mode 100644 index 163e8db3..00000000 --- a/versioned_docs/version-0.5.5/reference/model/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# System Package - -KCL provides engineering extensibility through system modules, user modules and plug-in modules. This section describes the basic concepts of system modules. diff --git a/versioned_docs/version-0.5.5/reference/model/json.md b/versioned_docs/version-0.5.5/reference/model/json.md deleted file mode 100644 index 44ec8c73..00000000 --- a/versioned_docs/version-0.5.5/reference/model/json.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: "json" -linkTitle: "json" -type: "docs" -description: json system module -weight: 100 ---- - -## encode - -``` -encode( - data: any, - sort_keys: bool = False, - indent: int = None, - ignore_private: bool = False, - ignore_none: bool = False -) -> str -``` - -Serialize a KCL object `data` to a JSON formatted str. - -## decode - -`decode(value: str) -> any` - -Deserialize `value` (a string instance containing a JSON document) to a KCL object. - -## dump_to_file - -``` -dump_to_file( - data: any, - filename: str, - ignore_private: bool = False, - ignore_none: bool = False -) -> None -``` - -Serialize a KCL object `data` to a JSON formatted str and write it into the file `filename`. diff --git a/versioned_docs/version-0.5.5/reference/model/manifests.md b/versioned_docs/version-0.5.5/reference/model/manifests.md deleted file mode 100644 index ab31ad47..00000000 --- a/versioned_docs/version-0.5.5/reference/model/manifests.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: "manifests" -linkTitle: "manifests" -type: "docs" -description: manifests system module -weight: 100 ---- - -## yaml_stream - -```python -yaml_stream(values: [any], opts: {str:} = { - sort_keys = False - ignore_private = True - ignore_none = False - sep = "---" -}) -``` - -This function is used to serialize the KCL object list into YAML output with the --- separator. It has two parameters: - -- `values` - A list of KCL objects -- `opts` - The YAML serialization options - - `sort_keys`: Whether to sort the serialized results in the dictionary order of attribute names (the default is `False`). - - `ignore_private`: Whether to ignore the attribute output whose name starts with the character `_` (the default value is `True`). - - `ignore_none`: Whether to ignore the attribute with the value of' None '(the default value is `False`). - - `sep`: Set the separator between multiple YAML documents (the default value is `"---"`). - -Here's an example: - -```python -# Use the `import` keyword to import the `manifests` module. -import manifests - -# The schema `Deployment` definition. -schema Deployment: - apiVersion: str = "v1" - kind: str = "Deployment" - metadata: {str:} = { - name = "deploy" - } - spec: {str:} = { - replica = 2 - } - -# The schema `Service` definition. -schema Service: - apiVersion: str = "v1" - kind: str = "Service" - metadata: {str:} = { - name = "svc" - } - spec: {str:} = {} - -# Define two `Deployment` resources. -deployments = [Deployment {}, Deployment {}] -# Define two `Service` resources. -services = [Service {}, Service {}] -# Put them into a KCL list and call the `manifests.yaml_stream` function. -manifests.yaml_stream(deployments + services) -``` - -First, we use the `import` keyword to import the `manifests` module and define two deployment resources and two service resources. When we want to output these four resources in YAML stream format with `---` as the separator, we can put them into a KCL list and use the `manifests.yaml_stream` function pass it to the `values` parameter (if there is no special requirement, the `opts` parameter can generally use the default value). Finally, the YAML output is: - -```yaml -apiVersion: v1 -kind: Deployment -metadata: - name: deploy -spec: - replica: 2 ---- -apiVersion: v1 -kind: Deployment -metadata: - name: deploy -spec: - replica: 2 ---- -apiVersion: v1 -kind: Service -metadata: - name: svc ---- -apiVersion: v1 -kind: Service -metadata: - name: svc -``` diff --git a/versioned_docs/version-0.5.5/reference/model/math.md b/versioned_docs/version-0.5.5/reference/model/math.md deleted file mode 100644 index dae369af..00000000 --- a/versioned_docs/version-0.5.5/reference/model/math.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: "math" -linkTitle: "math" -type: "docs" -description: math system module -weight: 100 ---- - -## ceil - -`ceil(x) -> int` - -Return the ceiling of `x` as an Integral. This is the smallest integer >= x. - -## factorial - -`factorial(x) -> int` - -Return `x!`. Raise a error if `x` is negative or non-integral. - -## floor - -`floor(x) -> int` - -Return the floor of `x` as an Integral. This is the largest integer <= x. - -## gcd - -`gcd(a: int, b: int) -> int` - -Return the greatest common divisor of `x` and `y` - -## isfinite - -`isfinite(x) -> bool` - -Return `True` if `x` is neither an infinity nor a `NaN`, and `False` otherwise. - -## isinf - -`isinf(x) -> bool` - -Return `True` if `x` is a positive or negative infinity, and `False` otherwise. - -## isnan - -`isnan(x) -> bool` - -Return `True` if `x` is a `NaN` (not a number), and `False` otherwise. - -## modf - -`modf(x) -> List[float, float]` - -Return the fractional and integer parts of `x`. Both results carry the sign of `x` and are floats. - -## exp - -`exp(x) -> float` - -Return `e` raised to the power of `x`. - -## expm1 - -`expm1(x) -> float` - -Return `exp(x) - 1`. This function avoids the loss of precision involved in the direct evaluation of `exp(x) - 1` for small `x`. - -## log - -`log(x, base=2.71828182845904523536028747135266250) -> float` - -Return the logarithm of `x` to the base `e`. - -## log1p - -`log1p(x) -> float` - -Return the natural logarithm of `1+x` (base `e`). The result is computed in a way which is accurate for `x` near zero. - -## log2 - -`log2(x) -> float` -Return the base 2 logarithm of `x`. - -## log10 - -`log10(x) -> float` - -Return the base 10 logarithm of `x`. - -## pow - -`pow(x, y) -> float` - -Return `x**y` (`x` to the power of `y`). - -## sqrt - -`sqrt(x) -> float` - -Return the square root of `x`. diff --git a/versioned_docs/version-0.5.5/reference/model/net.md b/versioned_docs/version-0.5.5/reference/model/net.md deleted file mode 100644 index a4e83659..00000000 --- a/versioned_docs/version-0.5.5/reference/model/net.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: "net" -linkTitle: "net" -type: "docs" -description: net system module -weight: 100 ---- - -## split_host_port - -`split_host_port(ip_end_point: str) -> List[str]` - -Split the `host` and `port` from the `ip_end_point`. - -## join_host_port - -`join_host_port(host, port) -> str` - -Merge the `host` and `port`. - -## fqdn - -`fqdn(name: str = '') -> str` - -Return Fully Qualified Domain Name (FQDN). - -## parse_IP - -`parse_IP(ip) -> str` - -Parse `ip` to a real IP address - -## to_IP4 - -`to_IP4(ip) -> str` - -Get the IP4 form of `ip`. - -## to_IP16 - -`to_IP16(ip) -> int` - -Get the IP16 form of `ip`. - -## IP_string - -`IP_string(ip: str | int) -> str` - -Get the IP string. - -## is_IPv4 - -`is_IPv4(ip: str) -> bool` - -Whether `ip` is a IPv4 one. - -## is_IP - -`is_IP(ip: str) -> bool` - -Whether `ip` is a valid ip address. - -## is_loopback_IP - -`is_loopback_IP(ip: str) -> bool` - -Whether `ip` is a loopback one. - -## is_multicast_IP - -`is_multicast_IP(ip: str) -> bool` - -Whether `ip` is a multicast one. - -## is_interface_local_multicast_IP - -`is_interface_local_multicast_IP(ip: str) -> bool` - -Whether `ip` is a interface, local and multicast one. - -## is_link_local_multicast_IP - -`is_link_local_multicast_IP(ip: str) -> bool` - -Whether `ip` is a link local and multicast one. - -## is_link_local_unicast_IP - -`is_link_local_unicast_IP(ip: str) -> bool` - -Whether `ip` is a link local and unicast one. - -## is_global_unicast_IP - -`is_global_unicast_IP(ip: str) -> bool` - -Whether `ip` is a global and unicast one. - -## is_unspecified_IP - -`is_unspecified_IP(ip: str) -> bool` - -Whether `ip` is a unspecified one. diff --git a/versioned_docs/version-0.5.5/reference/model/overview.md b/versioned_docs/version-0.5.5/reference/model/overview.md deleted file mode 100644 index 36365ac1..00000000 --- a/versioned_docs/version-0.5.5/reference/model/overview.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -sidebar_position: 0 ---- - -# Overview - -KCL provides engineering extensibility through built-in modules, system modules and plug-in modules. - -![](/img/docs/reference/lang/model/kcl-module.png) - -The user code does not need to import functions that directly use builtin functions (such as calculating the length of a list with `len`, obtaining the type of value through `typeof`, etc.), and for basic types such as strings, it also provides some built-in methods (such as converting the case of strings, etc.). - -For relatively complex general logic, it is provided through the system modules. For example, by importing the `math` module, we can use related mathematical functions, and we can use the regular expression by importing the `regex` module. For KCL code, it can also be organized into different user modules. - -In addition, Python and Go can be used to develop plug-ins for KCL through the plugin mechanism. For example, there are the app-context plug-in can be used to obtain the context information of the current application to simplify code writing. diff --git a/versioned_docs/version-0.5.5/reference/model/regex.md b/versioned_docs/version-0.5.5/reference/model/regex.md deleted file mode 100644 index adde0630..00000000 --- a/versioned_docs/version-0.5.5/reference/model/regex.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "regex" -linkTitle: "regex" -type: "docs" -description: regex system module -weight: 100 ---- - -## replace - -`replace(string: str, pattern: str, replace: str, count=0) -> str` - -Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement. - -## match - -`match(string: str, pattern: str) -> bool` - -Try to apply the pattern at the start of the string, returning a bool value `True` if any match was found, or `False` if no match was found. - -## compile - -`compile(pattern: str) -> bool` - -Compile a regular expression pattern, returning a bool value denoting whether the pattern is valid. - -## findall - -`findall(string: str, pattern: str) -> List[str]` - -Return a list of all non-overlapping matches in the string. - -## search - -`search(string: str, pattern: str) -> bool` - -Scan through string looking for a match to the pattern, returning a bool value `True` if any match was found, or `False` if no match was found. - -## split - -`split(string: str, pattern: str, maxsplit=0) -> List[str]` - -Return a list composed of words from the string, splitting up to a maximum of `maxsplit` times using `pattern` as the separator. diff --git a/versioned_docs/version-0.5.5/reference/model/units.md b/versioned_docs/version-0.5.5/reference/model/units.md deleted file mode 100644 index 34465a53..00000000 --- a/versioned_docs/version-0.5.5/reference/model/units.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: "units" -linkTitle: "units" -type: "docs" -description: units system module - Unit handlers -weight: 100 ---- - -## Constants - -- Fixed point unit constants: `n`, `u`, `m`, `k`, `K`, `G`, `T` and `P`. -- Power of 2 unit constants: `Ki`, `Mi`, `Gi`, `Ti` and `Pi`. - -## Functions - -- `to_n(num: int) -> str` - Int literal to string with `n` suffix -- `to_u(num: int) -> str` - Int literal to string with `u` suffix -- `to_m(num: int) -> str` - Int literal to string with `m` suffix -- `to_K(num: int) -> str` - Int literal to string with `K` suffix -- `to_M(num: int) -> str` - Int literal to string with `M` suffix -- `to_G(num: int) -> str` - Int literal to string with `G` suffix -- `to_T(num: int) -> str` - Int literal to string with `T` suffix -- `to_P(num: int) -> str` - Int literal to string with `P` suffix -- `to_Ki(num: int) -> str` - Int literal to string with `Ki` suffix -- `to_Mi(num: int) -> str` - Int literal to string with `Mi` suffix -- `to_Gi(num: int) -> str` - Int literal to string with `Gi` suffix -- `to_Ti(num: int) -> str` - Int literal to string with `Ti` suffix -- `to_Pi(num: int) -> str` - Int literal to string with `Pi` suffix diff --git a/versioned_docs/version-0.5.5/reference/model/yaml.md b/versioned_docs/version-0.5.5/reference/model/yaml.md deleted file mode 100644 index 4b952dcf..00000000 --- a/versioned_docs/version-0.5.5/reference/model/yaml.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: "yaml" -linkTitle: "yaml" -type: "docs" -description: yaml encode and decode function -weight: 300 ---- - -## encode - -``` -encode( - data: any, - sort_keys: bool = False, - ignore_private: bool = False, - ignore_none: bool = False -) -> str -``` - -Serialize a KCL object `data` to a YAML formatted str. - -## decode - -`decode(value: str) -> any` - -Deserialize `value` (a string instance containing a YAML document) to a KCL object. - -## dump_to_file - -``` -dump_to_file( - data: any, - filename: str, - ignore_private: bool = False, - ignore_none: bool = False -) -> None -``` - -Serialize a KCL object `data` to a YAML formatted str and write it into the file `filename`. diff --git a/versioned_docs/version-0.5.5/reference/package-management/_category_.json b/versioned_docs/version-0.5.5/reference/package-management/_category_.json deleted file mode 100644 index 7848e437..00000000 --- a/versioned_docs/version-0.5.5/reference/package-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Package Management Tools", - "position": 4 -} diff --git a/versioned_docs/version-0.5.5/reference/package-management/command-reference/1.init.md b/versioned_docs/version-0.5.5/reference/package-management/command-reference/1.init.md deleted file mode 100644 index 6a46976a..00000000 --- a/versioned_docs/version-0.5.5/reference/package-management/command-reference/1.init.md +++ /dev/null @@ -1,45 +0,0 @@ -# kpm init - -Init a kcl package. - -## Usage - -```shell -kpm init [options][package_name] -``` - -## Description - -`kpm init` will initialize a kcl package in the current directory. If the package name is not provided, the name of the current directory will be used. - -If the package name is provided, a subdirectory with the name of the package will be created and the package will be initialized in that directory. - -`kpm init` will create `kcl.mod`, `kcl.mod.lock` and `main.k` under the package directory. - -## Options - -### --help, -h - -Show help for `kpm init` command. - -## Examples - -### Init the current directory into a kcl package - -```shell -# create an empty directory -$ mkdir my_package - -# cd into the directory -$ cd my_package - -# init the current directory into a kcl package -$ kpm init -``` - -### Init a kcl package with a name - -```shell -# init a kcl package with a name 'my_package' -kpm init my_package -``` diff --git a/versioned_docs/version-0.5.5/reference/package-management/command-reference/10.help.md b/versioned_docs/version-0.5.5/reference/package-management/command-reference/10.help.md deleted file mode 100644 index 94c078f5..00000000 --- a/versioned_docs/version-0.5.5/reference/package-management/command-reference/10.help.md +++ /dev/null @@ -1,21 +0,0 @@ -# kpm help - -Print help information for kpm commands. - -## Usage - -```shell -kpm help -``` - -## Description - -`kpm help` will print help information for kpm commands. - -## Examples - -Use `kpm help` to print help information for kpm commands. - -```shell -kpm help -``` diff --git a/versioned_docs/version-0.5.5/reference/package-management/command-reference/2.add.md b/versioned_docs/version-0.5.5/reference/package-management/command-reference/2.add.md deleted file mode 100644 index 1d2517fb..00000000 --- a/versioned_docs/version-0.5.5/reference/package-management/command-reference/2.add.md +++ /dev/null @@ -1,53 +0,0 @@ -# kpm add - -Add a dependency to a kcl package. - -## Usage - -```shell -kpm add [options][package_reference] -``` - -## Description - -`kpm add` will add a dependency to a kcl package. The dependency can be from a git repository, or a kcl registry. - -`package_reference` is a kcl package reference, looks like `package_name:version`. - -## options - -### --git - -Specify the git url of the dependency from a git repository. - -### --tag - -Specify the tag of the dependency from a git repository. - -### --help, -h - -Show help for `kpm add` command. - -## Examples - -### Add a dependency from kcl registry - -Add kcl dependency named `k8s` to the current package.The version of the dependency will be the latest version. - -```shell -kpm add k8s -``` - -Add kcl dependency named 'k8s' with version 'v1.27.2'. - -```shell -kpm add k8s:v1.27.2 -``` - -### Add a dependency from git repository - -Add kcl dependency named `konfig` with version `v0.1.0` from git repository. - -```shell -kpm add --git https://github.com/awesome-kusion/konfig.git --tag v0.1.0 -``` diff --git a/versioned_docs/version-0.5.5/reference/package-management/command-reference/3.pkg.md b/versioned_docs/version-0.5.5/reference/package-management/command-reference/3.pkg.md deleted file mode 100644 index 9b4298a5..00000000 --- a/versioned_docs/version-0.5.5/reference/package-management/command-reference/3.pkg.md +++ /dev/null @@ -1,33 +0,0 @@ -# kpm pkg - -Package a kcl package into `*.tar`. - -## Usage - -```shell -kpm pkg [options] -``` - -## Description - -`kpm pkg` will package a kcl package into `*.tar`. - -Option `--target` is required to specify the tar file path of the package. - -## options - -### --target - -Specify the tar file path of the package. - -### --help, -h - -Show help for `kpm pkm` command. - -## Examples - -### Package a kcl package - -```shell -kpm pkg --target /Users/my_package_tar -``` diff --git a/versioned_docs/version-0.5.5/reference/package-management/command-reference/4.metadata.md b/versioned_docs/version-0.5.5/reference/package-management/command-reference/4.metadata.md deleted file mode 100644 index 3074a8d5..00000000 --- a/versioned_docs/version-0.5.5/reference/package-management/command-reference/4.metadata.md +++ /dev/null @@ -1,41 +0,0 @@ -# kpm metadata - -Print the metadata of a kcl package. - -## Usage - -```shell -kpm metadata [options] -``` - -## Description - -`kpm metadata` will print the metadata of a kcl package. The metadata includes the dependency information of the package. - -`--update` option is used to automatically download the missing dependency packages. - -## options - -### --update - -Automatically download the missing dependency packages. - -### --help, -h - -Show help for `kpm metadata` command. - -## Examples - -### Print the metadata of a kcl package - -Print the metadata of a kcl package. - -```shell -kpm metadata -``` - -Print the metadata of a kcl package and automatically download the missing dependency packages. - -```shell -kpm metadata --update -``` diff --git a/versioned_docs/version-0.5.5/reference/package-management/command-reference/5.run.md b/versioned_docs/version-0.5.5/reference/package-management/command-reference/5.run.md deleted file mode 100644 index b5001185..00000000 --- a/versioned_docs/version-0.5.5/reference/package-management/command-reference/5.run.md +++ /dev/null @@ -1,69 +0,0 @@ -# kpm run - -Compile a kcl package. - -## Usage - -```shell -kpm run [options][package_source] -``` - -## Description - -`kpm run` will compile a kcl package. - -## options - -### --input - -Specify the entry file path of the package. - -### --tag - -Specify the tag of the package specified by oci url `package_source`. - -### --vendor - -`--vendor` will move the dependency packages into the current packages and automatically download the missing dependency packages. - -### --kcl_args - -`--kcl_args` specifies the arguments passed to the kcl compiler. - -### --help, -h - -Show help for `kpm run` command. - -## Examples - -### compile the current kcl package - -Under the kcl package directory, `kpm run` can be used to compile the current kcl package. - -```shell -kpm run -``` - -### compile a kcl package tar file - -`kpm run` can be used to compile a kcl package tar file. - -```shell -kpm run /Users/demo/my_package.tar -``` - -### compile a kcl package from oci url - -`kpm run` can be used to compile a kcl package from oci url. - -```shell -kpm run --tag 0.0.1 oci://localhost:5001/test/my_package -``` - -### compile a kcl package from oci ref - -`kpm run` can be used to compile a kcl package from oci ref. - -```shell -kpm run test/my_package:0.0.1 -``` diff --git a/versioned_docs/version-0.5.5/reference/package-management/command-reference/6.login.md b/versioned_docs/version-0.5.5/reference/package-management/command-reference/6.login.md deleted file mode 100644 index 68ca0f1b..00000000 --- a/versioned_docs/version-0.5.5/reference/package-management/command-reference/6.login.md +++ /dev/null @@ -1,68 +0,0 @@ -# kpm login - -Login to the kpm registry. - -## Usage - -```shell -kpm login [options][kpm_registry] -``` - -## Description - -`kpm login` will login the kpm registry. - -## options - -### --username - -Specify the username of the kpm registry. - -### --password - -Specify the password of the kpm registry. - -### --help, -h - -Show help for `kpm login` command. - -## Examples - -### login to a registry with account and password - -```shell -kpm login -u -p -``` - -The output is - -```shell -Login succeeded -``` - -### login to a registry with account, and enter the password interactively - -```shell -kpm login -u -``` - -The output is - -```shell -Password: -Login succeeded -``` - -### login to a registry, and enter the account and password interactively - -```shell -kpm login -``` - -The output is - -```shell -Username: -Password: -Login succeeded -``` diff --git a/versioned_docs/version-0.5.5/reference/package-management/command-reference/7.logout.md b/versioned_docs/version-0.5.5/reference/package-management/command-reference/7.logout.md deleted file mode 100644 index 6c5d9aec..00000000 --- a/versioned_docs/version-0.5.5/reference/package-management/command-reference/7.logout.md +++ /dev/null @@ -1,27 +0,0 @@ -# kpm logout - -Logout from the kpm registry. - -## Usage - -```shell -kpm logout [options][kpm_registry] -``` - -## Description - -`kpm logout` will logout from the kpm registry. - -## options - -### --help, -h - -Show help for `kpm logout` command. - -## Examples - -### logout from oci registry - -```shell -kpm logout -``` diff --git a/versioned_docs/version-0.5.5/reference/package-management/command-reference/8.push.md b/versioned_docs/version-0.5.5/reference/package-management/command-reference/8.push.md deleted file mode 100644 index a70c5bc1..00000000 --- a/versioned_docs/version-0.5.5/reference/package-management/command-reference/8.push.md +++ /dev/null @@ -1,46 +0,0 @@ -# kpm push - -Push a package to the kpm registry. - -## Usage - -```shell -kpm push [options][kpm_registry] -``` - -## Description - -`kpm push` will push a package to the kpm registry. - -## options - -### --tar_path - -The path to the tar file to push. - -### --help, -h - -Show help for `kpm push` command. - -## Examples - -### push the current package - -You can use `kpm push` under the kcl package root directory to upload a kcl package to an OCI-based registry. - -```shell -# create a new kcl package. -$ kpm init -# enter the kcl package root directory -$ cd -# push it to an oci registry -$ kpm push -``` - -### push a tar to the registry - -You can also use `kpm push` to upload a tar file to an OCI-based registry. - -```shell -kpm push --tar_path -``` diff --git a/versioned_docs/version-0.5.5/reference/package-management/command-reference/9.pull.md b/versioned_docs/version-0.5.5/reference/package-management/command-reference/9.pull.md deleted file mode 100644 index b0126bcf..00000000 --- a/versioned_docs/version-0.5.5/reference/package-management/command-reference/9.pull.md +++ /dev/null @@ -1,42 +0,0 @@ -# kpm pull - -Pull a package from the kpm registry. - -## Usage - -```shell -kpm pull [options][package_source] -``` - -## Description - -`kpm pull` will pull a package from the kpm registry. - -## options - -### --tag - -The tag of the package to pull. - -### --help, -h - -Show help for `kpm push` command. - -## Examples - -### pull the package by package name - -You can use `kpm pull` to download a kcl package from the default OCI registry by kcl package name. -`kpm` will download the kcl package from the default OCI registry specified in the configuration file `kpm.json`. - -```shell -kpm pull : -``` - -### pull the package by oci url - -You can download a kcl package from an OCI-based registry url. - -```shell -kpm pull --tag -``` diff --git a/versioned_docs/version-0.5.5/reference/package-management/command-reference/_category_.json b/versioned_docs/version-0.5.5/reference/package-management/command-reference/_category_.json deleted file mode 100644 index 8c705ed9..00000000 --- a/versioned_docs/version-0.5.5/reference/package-management/command-reference/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Command Reference", - "position": 4 -} diff --git a/versioned_docs/version-0.5.5/reference/package-management/command-reference/index.md b/versioned_docs/version-0.5.5/reference/package-management/command-reference/index.md deleted file mode 100644 index ab6cc90c..00000000 --- a/versioned_docs/version-0.5.5/reference/package-management/command-reference/index.md +++ /dev/null @@ -1,36 +0,0 @@ -# kpm - -The kpm cli - -## Usage - -```shell -kpm [arguments]... -``` - -## Description - -`kpm` is a kcl package manager. It is used to install, remove, and update kcl packages. - -## Options - -### --help, -h - -Show help for kpm command - -### --version, -v - -Print the version of kpm - -## Subcommands - -- [kpm init](./1.init.md) - Init a kcl package -- [kpm add](./2.add.md) - Add a dependency to a kcl package -- [kpm pkg](./3.pkg.md) - Package a kcl package into `\*.tar`` -- [kpm metadata](./4.metadata.md) - Print the metadata of a kcl package -- [kpm run](./5.run.md) - Compile a kcl package into yaml -- [kpm login](./6.login.md) - Login to a kcl registry -- [kpm logout](./7.logout.md) - Logout from a kcl registry -- [kpm push](./8.push.md) - Push a kcl package to a registry -- [kpm pull](./9.pull.md) - Pull a kcl package from a registry -- [kpm help](./10.help.md) - print help for kpm command diff --git a/versioned_docs/version-0.5.5/reference/plugin/_category_.json b/versioned_docs/version-0.5.5/reference/plugin/_category_.json deleted file mode 100644 index e77dfb1c..00000000 --- a/versioned_docs/version-0.5.5/reference/plugin/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Plugin System", - "position": 4 -} diff --git a/versioned_docs/version-0.5.5/reference/plugin/index.md b/versioned_docs/version-0.5.5/reference/plugin/index.md deleted file mode 100644 index df299e93..00000000 --- a/versioned_docs/version-0.5.5/reference/plugin/index.md +++ /dev/null @@ -1 +0,0 @@ -# Plugin System diff --git a/versioned_docs/version-0.5.5/reference/plugin/overview.md b/versioned_docs/version-0.5.5/reference/plugin/overview.md deleted file mode 100644 index f9561ddc..00000000 --- a/versioned_docs/version-0.5.5/reference/plugin/overview.md +++ /dev/null @@ -1,187 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Introduction - -KCL provides plugin support through a plugin agent and auxiliary command line tools, and the KCL plugin framework supports different general-purpose languages to develop plugins. Here we take Python as an example to briefly explain the use of plugins. - -KCL plugin Git repository: [https://github.com/kcl-lang/kcl-plugin](https://github.com/kcl-lang/kcl-plugin) - -## 0. Prerequisites - -Using the KCL Python plugin requires the presence of `Python 3.7+` in your `PATH`. - -## 1. Hello Plugin - -KCL plugins are installed in the `plugins` subdirectory of KCL (usually installed in the `$HOME/.kcl/plugins` directory), or set through the `$KCL_PLUGINS_ROOT` environment variable. Besides, the `plugins` directory could also be placed at the `pwd` path. KCL plugins are managed in the Git repository: [https://github.com/kcl-lang/kcl-plugin](https://github.com/kcl-lang/kcl-plugin), we can clone the repository for development. - -Enter the `kcl-plugin info` command to view the plugin directory (replace `/Users/kcl_user` with the local `$HOME` path): - -```shell -$ kcl-plugin info -# plugin_root: /Users/kcl_user/.kcl/plugins -``` - -View the list of plugins with the `kcl-plugin list` subcommand: - -```shell -$ kcl-plugin list -hello: hello doc - 0.0.1 -``` - -Where `hello` is an example builtin plugin (do not modify the plugin). - -In KCL code, the `hello` plugin can be imported via `import kcl_plugin.hello`. `main.k` code is as follows: - -```python -import kcl_plugin.hello - -name = "kcl" -three = hello.add(1,2) -``` - -The output result is - -```shell -$ python3 -m kclvm main.k -name: kcl -three: 3 -``` - -## 2. `kcl-plugin` Command - -`kcl-plugin` is a plugin helper command line tool, the command line help is as follows: - -```shell -$ kcl-plugin -usage: kcl-plugin [-h] {list,info,init,gendoc,test} ... -positional arguments: - {list,info,init,gendoc,test} - kcl plugin sub commands - list list all plugins - info show plugin document - init init a new plugin - gendoc gen all plugins document - test test plugin -optional arguments: - -h, --help show this help message and exit -``` - -- The `list` subcommand is used to view the list of plugins. -- The `info` subcommand is used to view the plugin directory and information about each plugin. -- The `init` subcommand is used to initialize new plugins. -- The `gendoc` subcommand is used to update the API documentation of all plugins. -- The `test` subcommand is used to test specified plugins. - -## 3. Plugin Information and Documentation - -Enter `kcl-plugin info hello` to view the `hello` plugin information: - -```shell -$ kcl-plugin info hello -{ - "name": "hello", - "describe": "hello doc", - "long_describe": "long describe", - "version": "0.0.1", - "method": { - "add": "add two numbers, and return result", - "foo": "no doc", - "list_append": "no doc", - "say_hello": "no doc", - "tolower": "no doc", - "update_dict": "no doc" - } -} -``` - -The information of the plugin mainly includes the name and version information of the plugin, and the function information provided by the plugin. This information is consistent with the automatically generated `api.md` file in the plugin directory (regenerate the `api.md` file for all plugins via `kcl-plugin gendoc` when the plugin API document changes). - -## 4. Plugin Directory Structure - -The directory structure of the plugin is as follows (replace `/Users/kcl_user` with the local `$HOME` path): - -```shell -$ tree /Users/kcl_user/.kcl/plugins/ -/Users/kcl_user/.kcl/plugins/ -├── _examples -├── _test -└── hello - ├── api.md - ├── plugin.py - └── plugin_test.py -$ -``` - -The `_examples` directory is the sample code of the plugin, the `_test` directory is the KCL test code of the plugin, and the other directories starting with letters are ordinary plugins. The content of the plugin is as follows: - -```shell -$ cat ./hello/plugin.py -# Copyright 2020 The KCL Authors. All rights reserved. -INFO = { - 'name': 'hello', - 'describe': 'hello doc', - 'long_describe': 'long describe', - 'version': '0.0.1', -} -def add(a: int, b: int) -> int: - """add two numbers, and return result""" - return a + b -... -``` - -Where `INFO` specifies the name of the plugin, a brief description, a detailed description and version information. And all the functions whose names start with letters are the functions provided by the plugin, so the `add` function can be called directly in KCL. - -> Note: KCL plugins are implemented in an independent pure Python code file, and plugins cannot directly call each other. - -## 5. Create Plugin - -A plugin can be created with the `kcl-plugin init` command: - -``` -$ kcl-plugin init hi -$ kcl-plugin list -hello: hello doc - 0.0.1 -hi: hi doc - 0.0.1 -``` - -The `kcl-plugin init` command will construct a new plugin from the built-in template, and then we can view the created plugin information with the `kcl-plugin list` command. - -## 6. Remove Plugin - -KCL plugins are located in the `plugins` subdirectory of KCL (usually installed in the `$HOME/.kcl/plugins` directory). -We can query the plugin installation directory with the command `kcl-plugin info`. - -```shell -$ kcl-plugin info -/Users/kcl_user/.kcl/plugins/ -$ tree /Users/kcl_user/.kcl/plugins/ -/Users/kcl_user/.kcl/plugins/ -├── _examples -├── _test -└── hello -- Delete this directory to delete the hello plugin - ├── api.md - ├── plugin.py - └── plugin_test.py -$ -``` - -## 7. Test Plugin - -There is a `plugin_test.py` file in the plugin directory, which is the unit test file of the plugin (based on the `pytest` testing framework). Also placed in the `_test` directory are plugin integration tests for KCL files. The `plugin_test.py` unit test is required, and the KCL integration tests in the `_test` directory can be added as needed. - -Unit tests for plugins can be executed via `kcl-plugin test`: - -```shell -$ kcl-plugin test hello -============================= test session starts ============================== -platform darwin -- Python 3.7.6+, pytest-5.3.5, py-1.9.0, pluggy-0.13.1 -rootdir: /Users/kcl_user -collected 5 items -.kcl/plugins/hello/plugin_test.py ..... [100%] -============================== 5 passed in 0.03s =============================== -$ -``` - -Integration tests can be tested by executing the `python3 -m pytest` command in the `_test` directory. diff --git a/versioned_docs/version-0.5.5/reference/plugin/project_context.md b/versioned_docs/version-0.5.5/reference/plugin/project_context.md deleted file mode 100644 index 0be02e78..00000000 --- a/versioned_docs/version-0.5.5/reference/plugin/project_context.md +++ /dev/null @@ -1,59 +0,0 @@ -# project_context - -project_context extract base info from project.yaml&stack.yaml - -_version: 0.0.1_ - -## `get_project_current_path` - -return the relative path of first file - -Example: - -```py -import kcl_plugin.project_context as ctx - -path = ctx.get_project_current_path() -print(path) -``` - -## `get_project_input_file` - -return compiling file list - -Example: - -```py -import kcl_plugin.project_context as ctx - -input_file = ctx.get_project_input_file() -print(input_file) -``` - -## `get_project_context` - -return the current project context from project.yaml - -Example: - -```py -import kcl_plugin.project_context as ctx - -project = ctx.get_project_context() -# Get project name -print(project?.name) -``` - -## `get_stack_context` - -return the current stack context from stack.yaml - -Example: - -```py -import kcl_plugin.project_context as ctx - -stack = ctx.get_stack_context() -# Get stack name -print(stack?.name) -``` diff --git a/versioned_docs/version-0.5.5/reference/xlang-api/_category_.json b/versioned_docs/version-0.5.5/reference/xlang-api/_category_.json deleted file mode 100644 index c2aafb21..00000000 --- a/versioned_docs/version-0.5.5/reference/xlang-api/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Multi-Language", - "position": 4 -} diff --git a/versioned_docs/version-0.5.5/reference/xlang-api/go-api.md b/versioned_docs/version-0.5.5/reference/xlang-api/go-api.md deleted file mode 100644 index 2a978250..00000000 --- a/versioned_docs/version-0.5.5/reference/xlang-api/go-api.md +++ /dev/null @@ -1,665 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Go API - -```go -import kcl "kcl-lang.io/kcl-go" -``` - -## KCL Go SDK - -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ kcl files │ │ KCL-Go-API │ │ KCLResultList │ -│ ┌───────────┐ │ │ │ │ │ -│ │ 1.k │ │ │ │ │ │ -│ └───────────┘ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ ┌───────────┐ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.Get("a.b.c") │ -│ │ 2.k │ │ │ │ Run(path) │ │ │ └───────────┘ │ └───────────────┘ -│ └───────────┘ │────┐ │ └───────────┘ │ │ │ -│ ┌───────────┐ │ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ │ 3.k │ │ │ │ │ │ │ KCLResult │──┼────────▶│x.Get("k", &v) │ -│ └───────────┘ │ │ │ │ │ └───────────┘ │ └───────────────┘ -│ ┌───────────┐ │ ├───▶│ ┌───────────┐ │──────────▶│ │ -│ │setting.yml│ │ │ │ │RunFiles() │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ └───────────┘ │ │ │ └───────────┘ │ │ │ KCLResult │──┼────────▶│x.JSONString() │ -└─────────────────┘ │ │ │ │ └───────────┘ │ └───────────────┘ - │ │ │ │ │ -┌─────────────────┐ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ Options │ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.YAMLString() │ -│WithOptions │ │ │ │MustRun() │ │ │ └───────────┘ │ └───────────────┘ -│WithOverrides │────┘ │ └───────────┘ │ │ │ -│WithWorkDir │ │ │ │ │ -│WithDisableNone │ │ │ │ │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ -``` - -
Example -

- -```go -{ - const k_code = ` -name = "kcl" -age = 1 - -two = 2 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {} -x1 = Person { - age = 101 -} -` - - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First().YAMLString() - fmt.Println(yaml) - - fmt.Println("----") - - result := kcl.MustRun("./testdata/main.k").First() - fmt.Println(result.JSONString()) - - fmt.Println("----") - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - - fmt.Println("----") - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x1", &person)) -} -``` - -

-
- -## Index - -- [Go API](#go-api) - - [KCL Go SDK](#kcl-go-sdk) - - [Index](#index) - - [Constants](#constants) - - [func FormatCode](#func-formatcode) - - [func FormatPath](#func-formatpath) - - [func InitKclvmPath](#func-initkclvmpath) - - [func InitKclvmRuntime](#func-initkclvmruntime) - - [func LintPath](#func-lintpath) - - [func ListDepFiles](#func-listdepfiles) - - [func ListDownStreamFiles](#func-listdownstreamfiles) - - [func ListUpStreamFiles](#func-listupstreamfiles) - - [func OverrideFile](#func-overridefile) - - [func ValidateCode](#func-validatecode) - - [type KCLResult](#type-kclresult) - - [type KCLResultList](#type-kclresultlist) - - [func MustRun](#func-mustrun) - - [func Run](#func-run) - - [func RunFiles](#func-runfiles) - - [type KclType](#type-kcltype) - - [func GetSchemaType](#func-getschematype) - - [type ListDepFilesOption](#type-listdepfilesoption) - - [type ListDepsOptions](#type-listdepsoptions) - - [type Option](#type-option) - - [func WithCode](#func-withcode) - - [func WithDisableNone](#func-withdisablenone) - - [func WithKFilenames](#func-withkfilenames) - - [func WithOptions](#func-withoptions) - - [func WithOverrides](#func-withoverrides) - - [func WithPrintOverridesAST](#func-withprintoverridesast) - - [func WithSettings](#func-withsettings) - - [func WithSortKeys](#func-withsortkeys) - - [func WithWorkDir](#func-withworkdir) - - [type ValidateOptions](#type-validateoptions) - -## Constants - -KclvmAbiVersion is the current kclvm ABI version. - -```go -const KclvmAbiVersion = scripts.KclvmAbiVersion -``` - -## func [FormatCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L110) - -```go -func FormatCode(code interface{}) ([]byte, error) -``` - -FormatCode returns the formatted code. - -
Example -

- -```go -{ - out, err := kcl.FormatCode(`a = 1+2`) - if err != nil { - log.Fatal(err) - } - fmt.Println(string(out)) - -} -``` - -``` -a = 1 + 2 -``` - -

-
- -## func [FormatPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L122) - -```go -func FormatPath(path string) (changedPaths []string, err error) -``` - -FormatPath formats files from the given path path: if path is \`.\` or empty string, all KCL files in current directory will be formatted, not recursively if path is \`path/file.k\`, the specified KCL file will be formatted if path is \`path/to/dir\`, all KCL files in the specified dir will be formatted, not recursively if path is \`path/to/dir/...\`, all KCL files in the specified dir will be formatted recursively - -the returned changedPaths are the changed file paths \(relative path\) - -
Example -

- -```go -{ - changedPaths, err := kcl.FormatPath("testdata/fmt") - if err != nil { - log.Fatal(err) - } - fmt.Println(changedPaths) -} -``` - -

-
- -## func [InitKclvmPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L54) - -```go -func InitKclvmPath(kclvmRoot string) -``` - -InitKclvmPath init kclvm path. - -## func [InitKclvmRuntime](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L59) - -```go -func InitKclvmRuntime(n int) -``` - -InitKclvmRuntime init kclvm process. - -## func [LintPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L142) - -```go -func LintPath(paths []string) (results []string, err error) -``` - -LintPath lint files from the given path - -
Example -

- -```go -{ - - results, err := kcl.LintPath([]string{"testdata/lint/import.k"}) - if err != nil { - log.Fatal(err) - } - for _, s := range results { - fmt.Println(s) - } - -} -``` - -``` -Module 'a' is reimported multiple times -Module 'a' imported but unused -``` - -

-
- -## func [ListDepFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L127) - -```go -func ListDepFiles(workDir string, opt *ListDepFilesOption) (files []string, err error) -``` - -ListDepFiles return the depend files from the given path - -## func [ListDownStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L137) - -```go -func ListDownStreamFiles(workDir string, opt *ListDepsOptions) ([]string, error) -``` - -ListDownStreamFiles return a list of downstream depend files from the given changed path list. - -## func [ListUpStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L132) - -```go -func ListUpStreamFiles(workDir string, opt *ListDepsOptions) (deps []string, err error) -``` - -ListUpStreamFiles return a list of upstream depend files from the given path list - -## func [OverrideFile](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L154) - -```go -func OverrideFile(file string, specs, importPaths []string) (bool, error) -``` - -OverrideFile rewrites a file with override spec file: string. The File that need to be overridden specs: \[\]string. List of specs that need to be overridden. - -``` -Each spec string satisfies the form: := or :- -When the pkgpath is '__main__', it can be omitted. -``` - -importPaths. List of import statements that need to be added - -## func [ValidateCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L159) - -```go -func ValidateCode(data, code string, opt *ValidateOptions) (ok bool, err error) -``` - -ValidateCode validate data match code - -## type [KCLResult](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L47) - -```go -type KCLResult = kcl.KCLResult -``` - -
Example -

- -```go -{ - const k_code = ` -name = "kcl" -age = 1 - -two = 2 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {name = "kcl-go"} -x1 = Person {age = 101} -` - - result := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First() - - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - -} -``` - -``` -x0.name: kcl-go -x1.age: 101 -``` - -

-
- -
Example ('et_struct) -

- -```go -{ - const k_code = ` -schema Person: - name: str = "kcl" - age: int = 1 - X: int = 2 - -x = { - "a": Person {age = 101} - "b": 123 -} -` - - result := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First() - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x.a", &person)) - fmt.Printf("person: %+v\n", person) - -} -``` - -``` -person: &{Name:kcl Age:101} -person: {Name:kcl Age:101} -``` - -

-
- -## type [KCLResultList](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L48) - -```go -type KCLResultList = kcl.KCLResultList -``` - -### func [MustRun](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L64) - -```go -func MustRun(path string, opts ...Option) *KCLResultList -``` - -MustRun is like Run but panics if return any error. - -
Example -

- -```go -{ - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(`name = "kcl"`)).First().YAMLString() - fmt.Println(yaml) - -} -``` - -``` -name: kcl -``` - -

-
- -
Example (Raw Yaml) -

- -```go -{ - const code = ` -b = 1 -a = 2 -` - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(code)).GetRawYamlResult() - fmt.Println(yaml) - - yaml_sorted := kcl.MustRun("testdata/main.k", kcl.WithCode(code), kcl.WithSortKeys(true)).GetRawYamlResult() - fmt.Println(yaml_sorted) - -} -``` - -``` -b: 1 -a: 2 -a: 2 -b: 1 -``` - -

-
- -
Example (Schema Type) -

- -```go -{ - const code = ` -schema Person: - name: str = "" - -x = Person() -` - json := kcl.MustRun("testdata/main.k", kcl.WithCode(code)).First().JSONString() - fmt.Println(json) - -} -``` - -``` -{ - "x": { - "name": "" - } -} -``` - -

-
- -
Example (Settings) -

- -```go -{ - yaml := kcl.MustRun("./testdata/app0/kcl.yaml").First().YAMLString() - fmt.Println(yaml) -} -``` - -

-
- -### func [Run](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L69) - -```go -func Run(path string, opts ...Option) (*KCLResultList, error) -``` - -Run evaluates the KCL program with path and opts, then returns the object list. - -
Example (Get Field) -

- -```go -{ - - x, err := kcl.Run("./testdata/app0/kcl.yaml") - assert(err == nil, err) - - fmt.Println(x.First().Get("deploy_topology.1.zone")) - -} -``` - -``` -R000A -``` - -

-
- -### func [RunFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L74) - -```go -func RunFiles(paths []string, opts ...Option) (*KCLResultList, error) -``` - -RunFiles evaluates the KCL program with multi file path and opts, then returns the object list. - -
Example -

- -```go -{ - result, _ := kcl.RunFiles([]string{"./testdata/app0/kcl.yaml"}) - fmt.Println(result.First().YAMLString()) -} -``` - -

-
- -## type [KclType](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L50) - -```go -type KclType = kcl.KclType -``` - -### func [GetSchemaType](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L176) - -```go -func GetSchemaType(file, code, schemaName string) ([]*KclType, error) -``` - -GetSchemaType returns schema types from a kcl file or code. - -file: string - -``` -The kcl filename -``` - -code: string - -``` -The kcl code string -``` - -schema_name: string - -``` -The schema name got, when the schema name is empty, all schemas are returned. -``` - -## type [ListDepFilesOption](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L45) - -```go -type ListDepFilesOption = list.Option -``` - -## type [ListDepsOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L44) - -```go -type ListDepsOptions = list.DepOptions -``` - -## type [Option](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L43) - -```go -type Option = kcl.Option -``` - -### func [WithCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L79) - -```go -func WithCode(codes ...string) Option -``` - -WithCode returns a Option which hold a kcl source code list. - -### func [WithDisableNone](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L97) - -```go -func WithDisableNone(disableNone bool) Option -``` - -WithDisableNone returns a Option which hold a disable none switch. - -### func [WithKFilenames](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L82) - -```go -func WithKFilenames(filenames ...string) Option -``` - -WithKFilenames returns a Option which hold a filenames list. - -### func [WithOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L85) - -```go -func WithOptions(key_value_list ...string) Option -``` - -WithOptions returns a Option which hold a key=value pair list for option function. - -
Example -

- -```go -{ - const code = ` -name = option("name") -age = option("age") -` - x, err := kcl.Run("hello.k", kcl.WithCode(code), - kcl.WithOptions("name=kcl", "age=1"), - ) - if err != nil { - log.Fatal(err) - } - - fmt.Println(x.First().YAMLString()) - -} -``` - -``` -age: 1 -name: kcl -``` - -

-
- -### func [WithOverrides](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L88) - -```go -func WithOverrides(override_list ...string) Option -``` - -WithOverrides returns a Option which hold a override list. - -### func [WithPrintOverridesAST](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L100) - -```go -func WithPrintOverridesAST(printOverridesAST bool) Option -``` - -WithPrintOverridesAST returns a Option which hold a printOverridesAST switch. - -### func [WithSettings](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L91) - -```go -func WithSettings(filename string) Option -``` - -WithSettings returns a Option which hold a settings file. - -### func [WithSortKeys](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L105) - -```go -func WithSortKeys(sortKeys bool) Option -``` - -WithSortKeys returns a Option which hold a sortKeys switch. - -### func [WithWorkDir](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L94) - -```go -func WithWorkDir(workDir string) Option -``` - -WithWorkDir returns a Option which hold a work dir. - -## type [ValidateOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L46) - -```go -type ValidateOptions = validate.ValidateOptions -``` diff --git a/versioned_docs/version-0.5.5/reference/xlang-api/index.md b/versioned_docs/version-0.5.5/reference/xlang-api/index.md deleted file mode 100644 index f6f8e076..00000000 --- a/versioned_docs/version-0.5.5/reference/xlang-api/index.md +++ /dev/null @@ -1 +0,0 @@ -# Multi-Language diff --git a/versioned_docs/version-0.5.5/reference/xlang-api/java-api.md b/versioned_docs/version-0.5.5/reference/xlang-api/java-api.md deleted file mode 100644 index 52c8cf34..00000000 --- a/versioned_docs/version-0.5.5/reference/xlang-api/java-api.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Java API - -At present, the KCL Java SDK is still in the early preview version. The KCL team will continue to update and provide more functions in the future. For more information, see [https://github.com/kcl-lang/kcl-java](https://github.com/kcl-lang/kcl-java) diff --git a/versioned_docs/version-0.5.5/reference/xlang-api/overview.md b/versioned_docs/version-0.5.5/reference/xlang-api/overview.md deleted file mode 100644 index e63422d4..00000000 --- a/versioned_docs/version-0.5.5/reference/xlang-api/overview.md +++ /dev/null @@ -1,293 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Introduction - -The KCL language provides general programming language interfaces such as C/Rust/Go/Python/Java, and the related languages are under development. - -## C/Rust API - -The core of KCL is developed in Rust, and the C language API is exported externally for packaging and integration in high-level languages such as Go/Python/Java. - -## Go API - -Go API is a C-API provided by CGO wrapping KCL, while providing deeper customization features to meet the needs of upper-level tools. - -### Abstract Model - -The abstract model of the KCL Go API is as follows: - -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ kcl files │ │ KCL-Go-API │ │ KCLResultList │ -│ ┌───────────┐ │ │ │ │ │ -│ │ 1.k │ │ │ │ │ │ -│ └───────────┘ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ ┌───────────┐ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.Get("a.b.c") │ -│ │ 2.k │ │ │ │ Run(path) │ │ │ └───────────┘ │ └───────────────┘ -│ └───────────┘ │────┐ │ └───────────┘ │ │ │ -│ ┌───────────┐ │ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ │ 3.k │ │ │ │ │ │ │ KCLResult │──┼────────▶│x.Get("k", &v) │ -│ └───────────┘ │ │ │ │ │ └───────────┘ │ └───────────────┘ -│ ┌───────────┐ │ ├───▶│ ┌───────────┐ │──────────▶│ │ -│ │setting.yml│ │ │ │ │RunFiles() │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ └───────────┘ │ │ │ └───────────┘ │ │ │ KCLResult │──┼────────▶│x.JSONString() │ -└─────────────────┘ │ │ │ │ └───────────┘ │ └───────────────┘ - │ │ │ │ │ -┌─────────────────┐ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ Options │ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.YAMLString() │ -│WithOptions │ │ │ │MustRun() │ │ │ └───────────┘ │ └───────────────┘ -│WithOverrides │────┘ │ └───────────┘ │ │ │ -│WithWorkDir │ │ │ │ │ -│WithDisableNone │ │ │ │ │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ -``` - -The input file contains the KCL file and the `setting.yml` configuration file, and `Options` can be used to specify additional parameters and information such as working directory. The "KCL-Go-API" part is the provided KCL execution function. The execution function executes the KCL program according to the input file and additional parameters, and finally outputs the result of `KCLResultList`. `KCLResultList` is a list of `KCLResult`, each `KCLResult` corresponding to a generated configuration file or `map[string]interface{}`. - -### Example - -```go -package main - -import ( - "fmt" - - kcl "kcl-lang.io/kcl-go" -) - - -func main() { - const k_code = ` -name = "kcl" -age = 1 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person{} -x1 = Person{age:101} -` - - result := kcl.MustRun("hello.k", kcl.WithCode(k_code)).First() - fmt.Println(result.YAMLString()) - - fmt.Println("----") - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - - fmt.Println("----") - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x1", &person)) -} -``` - -Output result: - -```yaml -age: 1 -name: kcl -x0: - age: 1 - name: kcl -x1: - age: 101 - name: kcl - ----- -x0.name: kcl -x1.age: 101 ----- -person: &{Name:kcl Age:101} -``` - -## Python API - -Using the Python SDK requires that you have a local Python version higher than 3.7.3 and a local pip package management tool. You can use the following command to install and obtain helpful information. - -```bash -python3 -m pip install kclvm --user && python3 -m kclvm --help -``` - -### Command Line Tool - -Prepare a KCL file named `main.k` - -```python -name = "kcl" -age = 1 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {} -x1 = Person { - age = 101 -} -``` - -Execute the following command and get the output: - -```shell -$ python3 -m kclvm hello.k -name: kcl -age: 1 -x0: - name: kcl - age: 1 -x1: - name: kcl - age: 101 -``` - -### API - -In addition, we can also execute KCL files through Python code. - -Prepare a KCL file named `main.py` - -```python -import kclvm.program.exec as kclvm_exec -import kclvm.vm.planner as planner - -print(planner.plan(kclvm_exec.Run(["hello.k"]).filter_by_path_selector())) -``` - -Execute the following command and get the output: - -```shell -$ python3 main.py -name: kcl -age: 1 -x0: - name: kcl - age: 1 -x1: - name: kcl - age: 101 -``` - -You can see that the same output can be obtained through command line tools and APIs. - -At present, the KCL Python SDK is still in the early preview version. The KCL team will continue to update and provide more functions in the future. For more information, see [https://github.com/kcl-lang/kcl-py](https://github.com/kcl-lang/kcl-py) - -## REST-API - -The C-API provided by KCL does not have a REST-API. The REST-API is defined by Protobuf. - -### Start REST Service - -The RestAPI service can be started in the following way: - -```shell -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -The service can then be requested via the POST protocol: - -```shell -$ curl -X POST http://127.0.0.1:2021/api:protorpc/BuiltinService.Ping --data '{}' -{ - "error": "", - "result": {} -} -``` - -The POST request and the returned JSON data are consistent with the structure defined by Protobuf. - -### `BuiltinService` - -Where the `/api:protorpc/BuiltinService.Ping` path represents the `Ping` method of the `BuiltinService` service. - -The complete `BuiltinService` is defined by Protobuf: - -```protobuf -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} -``` - -The `Ping` method can verify whether the service is normal, and the `ListMethod` method can query the list of all services and functions provided. - -### `KclvmService` - -The `KclvmService` service is a service related to KCL functionality. The usage is the same as the `BuiltinService` service. - -For example, there is the following `Person` structure definition: - -```python -schema Person: - key: str - - check: - "value" in key # 'key' is required and 'key' must contain "value" -``` - -Then we want to use `Person` to verify the following JSON data: - -```json -{ "key": "value" } -``` - -This can be done through the `ValidateCode` method of the `KclvmService` service. Refer to the `ValidateCode_Args` structure of the `ValidateCode` method: - -```protobuf -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} -``` - -Construct the JSON data required by the POST request according to the `ValidateCode_Args` structure, which contains the `Person` definition and the JSON data to be verified: - -```json -{ - "code": "\nschema Person:\n key: str\n\n check:\n \"value\" in key # 'key' is required and 'key' must contain \"value\"\n", - "data": "{\"key\": \"value\"}" -} -``` - -Save this JSON data to the `vet-hello.json` file and verify it with the following command: - -```shell -$ curl -X POST \ - http://127.0.0.1:2021/api:protorpc/KclvmService.ValidateCode \ - -H "accept: application/json" \ - --data @./vet-hello.json -{ - "error": "", - "result": { - "success": true - } -} -``` - -## APIs in other languages - -Coming soon diff --git a/versioned_docs/version-0.5.5/reference/xlang-api/python-api.md b/versioned_docs/version-0.5.5/reference/xlang-api/python-api.md deleted file mode 100644 index e6ce67dc..00000000 --- a/versioned_docs/version-0.5.5/reference/xlang-api/python-api.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Python API - -At present, the KCL Python SDK is still in the early preview version. The KCL team will continue to update and provide more functions in the future. For more information, see [https://github.com/kcl-lang/kcl-py](https://github.com/kcl-lang/kcl-py) diff --git a/versioned_docs/version-0.5.5/tools/Ide/_category_.json b/versioned_docs/version-0.5.5/tools/Ide/_category_.json deleted file mode 100644 index d9bfcdd7..00000000 --- a/versioned_docs/version-0.5.5/tools/Ide/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "IDE", - "position": 2 -} diff --git a/versioned_docs/version-0.5.5/tools/Ide/index.md b/versioned_docs/version-0.5.5/tools/Ide/index.md deleted file mode 100644 index aec7245a..00000000 --- a/versioned_docs/version-0.5.5/tools/Ide/index.md +++ /dev/null @@ -1,6 +0,0 @@ -# IDE - -We have provided two simple kinds of plugins for KCL. You can get more help information at the following link: - -- IntelliJ Plugin: https://github.com/kcl-lang/intellij-kcl -- VSCode Plugin: https://github.com/kcl-lang/vscode-kcl diff --git a/versioned_docs/version-0.5.5/tools/_category_.json b/versioned_docs/version-0.5.5/tools/_category_.json deleted file mode 100644 index 5ecd522f..00000000 --- a/versioned_docs/version-0.5.5/tools/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Tools", - "position": 3 -} diff --git a/versioned_docs/version-0.5.5/tools/cli/_category_.json b/versioned_docs/version-0.5.5/tools/cli/_category_.json deleted file mode 100644 index 887061ef..00000000 --- a/versioned_docs/version-0.5.5/tools/cli/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Command Line Tools", - "position": 1 -} diff --git a/versioned_docs/version-0.5.5/tools/cli/index.md b/versioned_docs/version-0.5.5/tools/cli/index.md deleted file mode 100644 index ef4f69dc..00000000 --- a/versioned_docs/version-0.5.5/tools/cli/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# Command Line Tools - -KCL provides IDE plug-ins, rich language tools and OpenAPI tools. These tools provide a complete set of solutions, including configuration languages, model interfaces, automation tools, and best practices. diff --git a/versioned_docs/version-0.5.5/tools/cli/kcl/_category_.json b/versioned_docs/version-0.5.5/tools/cli/kcl/_category_.json deleted file mode 100644 index 4c605bd0..00000000 --- a/versioned_docs/version-0.5.5/tools/cli/kcl/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KCL Tools", - "position": 2 -} diff --git a/versioned_docs/version-0.5.5/tools/cli/kcl/docgen.md b/versioned_docs/version-0.5.5/tools/cli/kcl/docgen.md deleted file mode 100644 index ca647228..00000000 --- a/versioned_docs/version-0.5.5/tools/cli/kcl/docgen.md +++ /dev/null @@ -1,317 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Docgen - -The KCL Docgen tool supports extracting model documents from KCL source code and supports multiple output formats: JSON, YAML and Markdown. This article introduces the document specification of the KCL language, gives an example of how to use the KCL Docgen tool to extract documents, and shows the process of importing localization documents. - -## 1. Document Specification of KCL - -The documentation of the KCL file mainly contains the following two parts: - -- Current KCL Module document: description of the current KCL file -- All schema documents contained in the KCL file: a description of the current schema, including schema description, schema attribute descriptions, and Examples. The specific format is as follows: - -1. Schema description - -```python -"""This is a brief description of the Schema -""" -``` - -2. Description of each attribute of Schema: including attribute description, attribute type, default value, optional or required - -```python -""" -Attributes ----------- -x : type, default is a, optional. - Description of parameter `x`. -y : type, default is b, required. - Description of parameter `y`. -""" -``` - -`----------` indicates that `Attributes` is a title (the length of the symbol `-` is the same as the length of the title), the attribute name and attribute type are separated by a colon `:`, the description of the attribute is written on another line with indentation. The default value of the attribute is separated by a comma `,` after the attribute type, and it is written in the form of `default is {default value}`. In addition, it is necessary to indicate whether the attribute is optional/required. Write `optional` after the default value for an optional attribute, and write `required` after the default value for a required attribute. - -3. Examples - -```python -""" -Examples --------- -val = Schema { - name = "Alice" - age = 18 -} -""" -``` - -In addition, the KCL docstring syntax should use a subset of the [re-structured text (reST)](https://docutils.sourceforge.io/rst.html) and be rendered using the [Sphinx](https://www.sphinx-doc.org/en/master/). - -## 2. Generating Documentation From KCL - -Use the `kcl-doc generate` command to extract documentation from a user-specified file or directory and output it to the specified directory. - -1. Args - -``` -usage: kcl-doc generate [-h] [--format YAML] [-o OUTPUT] [--r] - [--i18n-locale LOCALE] [--repo-url REPO_URL] - [files [files ...]] - -positional arguments: - files KCL file paths. If there's more than one files to - generate, separate them by space - -optional arguments: - -h, --help show this help message and exit - --format YAML Doc file format, support YAML, JSON and MARKDOWN. - Defaults to MARKDOWN - -o OUTPUT, --output-path OUTPUT - Specify the output directory. Defaults to ./kcl_doc - --r, -R, --recursive Search directory recursively - --i18n-locale LOCALE I18n locale, e.g.: zh, zh_cn, en, en_AS. Defaults to - en - --repo-url REPO_URL The source code repository url. It will be displayed in - the generated doc to link to the source code. -``` - -2. Extract documents from the file(s) and output them to the specified directory - -```text -kcl-doc generate your_config.k your_another_config.k -o your_docs_output_dir -``` - -3. From the specified directory, recursively find the KCL file(s) and extract the documentation - -```text -kcl-doc generate your_config_dir -r -o your_docs_output_dir -``` - -4. When generating documentation, specify the source code repository address. The generated documentation will contain links to source files - -```text -kcl-doc generate your_config.k -o your_docs_output_dir --repo-url https://url/to/source_code -``` - -## 3. Add Documentation for Localized Languages - -As shown before, by default, the documentation extracted by the documentation generation tool is based on the content of the source docstring, and thus the language of the documentation depends on the language in which the docstring was written. If you need to add localized language documentation to the source file, you can follow the steps below: - -1. Initialize the i18n configuration file. This step generates the corresponding i18n configuration file based on the specified KCL file. The file format can be JSON/YAML, and the default is YAML. The output profile name will end in the specified target localization language - -```text -kcl-doc init-i18n your_config.k --format JSON --i18n-locale your_target_locale -``` - -2. Modify the i18n configuration file and update each doc field in your locale language - -3. Generate localized documents from the modified i18n configuration file - -```text -kcl-doc generate your_config_dir --i18n-locale your_target_locale --format Markdown -``` - -Next, a simple example is used to demonstrate the process of adding localized language documents. - -3.1 Prepare the KCL file, such as `server.k`: - - ```python - schema Server: - """Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - - Attributes - ---------- - workloadType : str, default is "Deployment", required - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - name : str, required - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - labels : {str:str}, optional - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - - Examples - ---------------------- - myCustomApp = AppConfiguration { - name = "componentName" - } - """ - - workloadType: str = "Deployment" - name: str - labels?: {str: str} - ``` - -3.2 Get the initialized i18n configuration file from the `server.k`. For example, if you want to add Chinese documents to it, specify the format of the generated configuration file as YAML - - ```text - kcl-doc init-i18n server.k --format YAML --i18n-locale zh_cn - ``` - - This command will create the directory `kcl_doc` under the current directory and generate the i18n configuration file `kcl_doc/i18n_server_zh_cn.yaml`. Its contents are as follows: - - ```yaml - name: server - relative_path: ./server.k - schemas: - - name: Server - doc: | - Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - attributes: - - name: workloadType - doc: | - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - default_value: '"Deployment"' - is_optional: false - - name: name - doc: | - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: false - default_value: '' - - name: labels - doc: | - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - type: - type_str: '{str: str}' - type_category: DICT - dict_type: - key_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - value_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: true - default_value: '' - examples: | - myCustomApp = AppConfiguration { - name = "componentName" - } - doc: '' - source_code_url: '' - ``` - -3.3 Modify all the `doc` fields to the Chinese description. The modified configuration is as follows: - - ```yaml - name: server - relative_path: ./server.k - schemas: - - name: Server - doc: | - Server 模型定义了采用 Kubernetes 最佳实践的持续运行的服务的通用配置接口 - attributes: - - name: workloadType - doc: | - workloadType 属性定义了服务的类型,是服务级别的属性。合法的取值有:Deployment, CafeDeployment. - 另请查看:k8s/core/v1/workload_metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - default_value: '"Deployment"' - is_optional: false - - name: name - doc: | - name 为服务的名称,是服务级别的属性。 - 另请查看:k8s/core/v1/metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: false - default_value: '' - - name: labels - doc: | - labels 为服务的标签,是服务级别的属性。 - 另请查看:k8s/core/v1/metadata.k. - type: - type_str: '{str: str}' - type_category: DICT - dict_type: - key_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - value_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: true - default_value: '' - examples: | - myCustomApp = AppConfiguration { - name = "componentName" - } - doc: '' - source_code_url: '' - ``` - -3.4 Based on the modified i18n configuration, generate documents in localized languages. Execute the following command to output the Chinese document `kcl_doc/doc_server_zh_cn.md`. The commands and the contents of the generated documents are as follows: - -```text -kcl-doc generate server.k --i18n-locale zh_cn --format Markdown -``` - -````markdown -# server - -## Schema Server - -Server 模型定义了采用 Kubernetes 最佳实践的持续运行的服务的通用配置接口 - -### Attributes - -| Name and Description | Type | Default Value | Required | -| -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | ------------- | ------------ | -| **workloadType**
workloadType 属性定义了服务的类型,是服务级别的属性。合法的取值有:Deployment, CafeDeployment.
另请查看:k8s/core/v1/workload_metadata.k. | str | "Deployment" | **required** | -| **name**
name 为服务的名称,是服务级别的属性。
另请查看:k8s/core/v1/metadata.k. | str | Undefined | **required** | -| **labels**
labels 为服务的标签,是服务级别的属性。
另请查看:k8s/core/v1/metadata.k. | {str: str} | Undefined | optional | - -### Examples - -``` -myCustomApp = AppConfiguration { - name = "componentName" -} -``` - - -```` - -## 4. Appendix - -### 1. Concept of reST - -For documents in reST format, paragraphs and indentation are important, new paragraphs are marked with blank lines, and indentation is the indentation indicated in the output. Font styles can be expressed as follows: - -- \*Italic\* -- \*\*Bold\*\* -- \`\`Monospaced\`\` - -Refer to [reST](https://docutils.sourceforge.io/rst.html) for more information. diff --git a/versioned_docs/version-0.5.5/tools/cli/kcl/index.md b/versioned_docs/version-0.5.5/tools/cli/kcl/index.md deleted file mode 100644 index b750f652..00000000 --- a/versioned_docs/version-0.5.5/tools/cli/kcl/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# KCL Language Tools - -KCL not only provides the command `kcl` to compile and execute configuration programs but also provides fmt, lint, test, vet, docgen and other supporting tools. diff --git a/versioned_docs/version-0.5.5/tools/cli/kcl/overview.md b/versioned_docs/version-0.5.5/tools/cli/kcl/overview.md deleted file mode 100644 index b1354b8c..00000000 --- a/versioned_docs/version-0.5.5/tools/cli/kcl/overview.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Overview - -KCL toolchain is a toolset of KCL language, which aims to improve the efficiency of batch migration, writing, compiling and running of KCL. - -| | Name | Description | -| ---------- | ------------------------ | ------------------------------------------------------------------- | -| Main Tools | **kcl** | Provide support for KCL in coding, compiling and running | -| | kcl-test | Coming soon | -| | kcl-lint | Check code style for KCL | -| | kcl-doc | Parses the KCL code and generate documents | -| | kcl-fmt | Format the kcl code | -| | kcl-vet | Validate data files such as JSON and YAML using KCL | -| IDE Plugin | IntelliJ IDEA KCL plugin | Provide assistance for KCL in coding and compiling on IntelliJ IDEA | -| | VS Code KCL plugin | Provide assistance for KCL in coding and compiling on VS Code | - -## KCL Tool - -### Args - -```shell -USAGE: - kcl [OPTIONS] [--] [input]... - -Arguments: - [input]... Specify the input files to run - -Options: - -o, --output - Specify the YAML output file path - -Y, --setting ... - Specify the input setting file - -v, --verbose... - Print test information verbosely - -n, --disable_none - Disable dumping None values - -r, --strict_range_check - Do perform strict numeric range checks - -d, --debug - Run in debug mode (for developers only) - -k, --sort_keys - Sort result keys - -D, --argument ... - Specify the top-level argument - -S, --path_selector ... - Specify the path selector - -O, --overrides ... - Specify the configuration override path and value - --target - Specify the target type - -E, --external ... - Mapping of package name and path where the package is located - -h, --help - Print help -``` diff --git a/versioned_docs/version-0.5.5/tools/cli/kcl/test.md b/versioned_docs/version-0.5.5/tools/cli/kcl/test.md deleted file mode 100644 index 4f99e53d..00000000 --- a/versioned_docs/version-0.5.5/tools/cli/kcl/test.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Test Tool - -Coming soon. diff --git a/versioned_docs/version-0.5.5/tools/cli/kcl/vet.md b/versioned_docs/version-0.5.5/tools/cli/kcl/vet.md deleted file mode 100644 index d2f2220e..00000000 --- a/versioned_docs/version-0.5.5/tools/cli/kcl/vet.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Validation - -## Intro - -The KCL Validation tool supports basic configuration data verification capabilities. You can write a KCL schema to verify the type and value of the input JSON/YAML files. - -## How to use - -There is a JSON format file `data.json`: - -```json -{ - "name": "Alice", - "age": 18, - "message": "This is Alice", - "data": { - "id": 1, - "value": "value1" - }, - "labels": { - "key": "value" - }, - "hc": [1, 2, 3] -} -``` - -Build a validated KCL file `schema.k`: - -```py -schema User: - name: str - age: int - message?: str - data: Data - labels: {str:} - hc: [int] - - check: - age > 10 - -schema Data: - id: int - value: str -``` - -Execute the following command: - -```shell -kcl-vet data.json schema.k -``` - -## Specify the schema for validation - -When multiple schema definitions exist in the KCL file, by default, the KCL Validation tool will use the first schema to check. If you need to specify a schema for verification, you can use the `-d|--schema` parameter - -```shell -kcl-vet data.json schema.k -d User -``` - -## Args - -```shell -$ kcl-vet -h -USAGE: - kcl-vet [OPTIONS] [ARGS] - -ARGS: - Validation data file - KCL file - -OPTIONS: - -d, --schema - Iterate through subdirectories recursively - - --format - Validation data file format, support YAML and JSON, default is JSON - - -h, --help - Print help information - - -n, --attribute_name - The attribute name for the data loading -``` diff --git a/versioned_docs/version-0.5.5/tools/cli/openapi/_category_.json b/versioned_docs/version-0.5.5/tools/cli/openapi/_category_.json deleted file mode 100644 index 58e4c68a..00000000 --- a/versioned_docs/version-0.5.5/tools/cli/openapi/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "OpenAPI Tools", - "position": 3 -} diff --git a/versioned_docs/version-0.5.5/tools/cli/openapi/crd-to-kcl.md b/versioned_docs/version-0.5.5/tools/cli/openapi/crd-to-kcl.md deleted file mode 100644 index aafebcd9..00000000 --- a/versioned_docs/version-0.5.5/tools/cli/openapi/crd-to-kcl.md +++ /dev/null @@ -1,118 +0,0 @@ -# CRD to KCL - -To convert from models defined in the Kubernetes CRD file to KCL schema, we could run the following script: - -```shell -kcl-openapi generate model --crd -f ${your_CRD.yaml} -t ${the_kcl_files_output_dir} --skip-validation -``` - -## Example - -- There is the Kubernetes CRD file that we need to convert: `test_crontab_CRD.yaml`: - -```yaml -# Deprecated in v1.16 in favor of apiextensions.k8s.io/v1 -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - # name must match the spec fields below, and be in the form: . - name: crontabs.stable.example.com -spec: - # group name to use for REST API: /apis// - group: stable.example.com - # list of versions supported by this CustomResourceDefinition - versions: - - name: v1 - # Each version can be enabled/disabled by Served flag. - served: true - # One and only one version must be marked as the storage version. - storage: true - # either Namespaced or Cluster - scope: Namespaced - names: - # plural name to be used in the URL: /apis/// - plural: crontabs - # singular name to be used as an alias on the CLI and for display - singular: crontab - # kind is normally the CamelCased singular type. Your resource manifests use this. - kind: CronTab - # shortNames allow shorter string to match your resource on the CLI - shortNames: - - ct - preserveUnknownFields: false - validation: - openAPIV3Schema: - type: object - properties: - spec: - type: object - properties: - cronSpec: - type: string - image: - type: string - replicas: - type: integer -``` - -- The script will be: - -```shell -kcl-openapi generate model -f test_crontab_CRD.yaml -t ~/ --skip-validation --crd -``` - -- Then we can find the generated file here: `~/models/stable_example_com_v1_cron_tab.k` - -```python -""" -This file was generated by the KCL auto-gen tool. DO NOT EDIT. -Editing this file might prove futile when you re-run the KCL auto-gen generate command. -""" -import kusion_kubernetes.apimachinery.apis - - -schema CronTab: - """stable example com v1 cron tab - - Attributes - ---------- - apiVersion : str, default is "stable.example.com/v1", required - APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - kind : str, default is "CronTab", required - Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - metadata : apis.ObjectMeta, default is Undefined, optional - metadata - spec : StableExampleComV1CronTabSpec, default is Undefined, optional - spec - """ - - - apiVersion: "stable.example.com/v1" = "stable.example.com/v1" - - kind: "CronTab" = "CronTab" - - metadata?: apis.ObjectMeta - - spec?: StableExampleComV1CronTabSpec - - -schema StableExampleComV1CronTabSpec: - """stable example com v1 cron tab spec - - Attributes - ---------- - cronSpec : str, default is Undefined, optional - cron spec - image : str, default is Undefined, optional - image - replicas : int, default is Undefined, optional - replicas - """ - - - cronSpec?: str - - image?: str - - replicas?: int -``` diff --git a/versioned_docs/version-0.5.5/tools/cli/openapi/index.md b/versioned_docs/version-0.5.5/tools/cli/openapi/index.md deleted file mode 100644 index 236d6e36..00000000 --- a/versioned_docs/version-0.5.5/tools/cli/openapi/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# OpenAPI Tools - -The KCL OpenAPI tool can not only convert common models but also support CRD and other models. diff --git a/versioned_docs/version-0.5.5/tools/cli/openapi/openapi-to-kcl.md b/versioned_docs/version-0.5.5/tools/cli/openapi/openapi-to-kcl.md deleted file mode 100644 index bef582ec..00000000 --- a/versioned_docs/version-0.5.5/tools/cli/openapi/openapi-to-kcl.md +++ /dev/null @@ -1,64 +0,0 @@ -# OpenAPI to KCL - -To convert from models defined in the OpenAPI spec file to KCL schema, we could run the following script: - -```shell -kcl-openapi generate model -f ${your_open_api_spec.yaml} -t ${the_kcl_files_output_dir} -``` - -For example: - -- There is the OpenAPI spec file that we need to convert: `test_open_api_spec.yaml` - -```yaml -definitions: - v1.TestInt: - type: object - properties: - name: - type: string - format: int-or-string - required: - - name - x-kcl-type: - import: - package: v1.test_int - alias: test_int - type: TestInt -swagger: "2.0" -info: - title: KCL - version: v0.0.2 -paths: {} -``` - -- The script will be: - -```shell -kcl-openapi generate model -f test_open_api_spec.yaml -t ~/ --skip-validation -``` - -- Then we can find the generated file here: `~/models/v1/test_int.k` - -```python -""" -This is the test_int module in v1 package. -This file was generated by the KCL auto-gen tool. DO NOT EDIT. -Editing this file might prove futile when you re-run the KCL auto-gen generate command. -""" - - -schema TestInt: - """v1 test int - - Attributes - ---------- - name : int | str, default is Undefined, required - name - """ - - - name: int | str - - -``` diff --git a/versioned_docs/version-0.5.5/user_docs/concepts/_category_.json b/versioned_docs/version-0.5.5/user_docs/concepts/_category_.json deleted file mode 100644 index d40bb9de..00000000 --- a/versioned_docs/version-0.5.5/user_docs/concepts/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Concepts", - "position": 5 -} diff --git a/versioned_docs/version-0.5.5/user_docs/concepts/concepts.md b/versioned_docs/version-0.5.5/user_docs/concepts/concepts.md deleted file mode 100644 index 627212ad..00000000 --- a/versioned_docs/version-0.5.5/user_docs/concepts/concepts.md +++ /dev/null @@ -1,3 +0,0 @@ -# Concepts - -Learn more about KCL concepts. diff --git a/versioned_docs/version-0.5.5/user_docs/concepts/package-and-module.md b/versioned_docs/version-0.5.5/user_docs/concepts/package-and-module.md deleted file mode 100644 index a36e45c9..00000000 --- a/versioned_docs/version-0.5.5/user_docs/concepts/package-and-module.md +++ /dev/null @@ -1,156 +0,0 @@ -# Module and Package - -This section mainly describes how to organize files in KCL. - -## Overview - -Within a **module**, KCL organizes files grouped by **package**. A package can be defined within a module or be imported externally (through KCL package manager `kpm`). In the latter case, KCL maintains a copy of the package within the module in a dedicated location. - -## Module - -A KCL module contains a configuration laid out in a directory hierarchy. It contains everything that is needed to deterministically determine the outcome of a KCL configuration. The root of this directory is marked by containing a `kcl.mod` directory. The contents of this directory are mostly managed by the kcl tool such as `kpm`, etc. In that sense, `kcl.mod` is analogous to the `.git` directory marking the root directory of a repo, but where its contents are mostly managed by the git tool. Besides, a KCL module is the largest unit of the file organization, has a fixed location of all KCL files and dependencies. - -> Note: The use of a KCL module e.g., `kcl.mod` is optional, but required if one wants to manage, distribute, share and reuse code with a semantic version. - -### Creating a module - -A module can be created by running the following command within the module root: - -```bash -kpm init [module name] -``` - -The module name is **required** if a package within the module needs to import another package within the module. A module can also be created by setting up the `kcl.mod` file manually. - -## Package - -In KCL, a package is usually composed of a "folder" containing KCL files. This folder can be a real disk physical path, or it can be composed of multiple KCL files (usually main package). Different packages are uniquely located by different package paths (such as `kubernetes.core.v1`) - -Within the same module, different packages can be imported from each other through the import statement of relative or absolute path. During the KCL parsing process, the relative import will be replaced by absolute import and the corresponding KCL code will be found through the package path. - -### Relative Import Path - -We can use the operator `.` to realize the relative path import of KCL entry files. - -main.k: - -```python -import .model1 # Current directory module -import ..service # Parent directory -import ...root # Parent of parent directory - -s = service.ImageService {} -m = root.Schema {} -``` - -### Absolute Import Path - -The semantics of `import a.b.c.d` is - -1. If `kcl.mod` not exist, regard the current directory as the package root and search the path `a/b/c/d` from the current directory. -2. If the current directory search fails, search from the root path `ROOT_PATH/a/b/c/d`, else raise an import error. - -The definition of the root path `ROOT_PATH` is the directory corresponding to the `kcl.mod` file from the current directory. - -Code structure: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -### Builtin Package - -KCL has a collection of builtin packages such as `math`, `regex`, etc. To use a builtin package, import it directly and invoke the functions using its qualified identifier. For instance, - -```python -import regex - -image = "nginx:1.14.2" -is_match = regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$") - -``` - -The output YAML is - -```yaml -image: nginx:1.14.2 -is_match: true -``` - -### Plugin Package - - - -KCL also has a collection of plugin packages such as `hello`, `project_context`, etc. To use a plugin package, import it with a `kcl_plugin.` package path prefix and invoke the functions using its qualified identifier. For instance, - -```python -import kcl_plugin.hello - -result = hello.add(1, 1) -``` - -The output YAML is - -```yaml -result: 2 -``` - -### Main Package - -In KCL, the composition of the main package is usually determined by the compiler parameters. This is because the KCL schema and constraints can be split across files in the package, or even organized across directories, considering the convenience of writing and maintaining the configuration in isolated blocks. - -#### Files belonging to a main package - -It is up to the user to decide which configurations and constraints to use using the KCL command line. For example, - -```bash -kcl file1.k file2.k -``` - -Thus, the main package contains two KCL files named `file1.k` and `file2.k`. - -If KCL is told to load the files for a specific directory, for example: - -```bash -kcl ./path/to/package -``` - -It will only look KCL files with `.k` suffix and ignore files with `_` prefix or `_test.k` into the main package. Besides, if the `./path/to/package` contains `kcl.yaml` files, `kcl.yaml` files be ignored. - -In addition, we can set main package files through configuring the command-line compilation setting file (e.g., `kcl.yaml`) as follows: - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k -``` - -```bash -kcl -Y kcl.yaml -``` - -> Note: If we do not specify any input files for KCL, KCL will find the default `kcl.yaml` from the command line execution path to read the input file. Besides, if we tell KCL both the input files and the compilation setting file, KCL will take input files entered by the user as the final value. - -```bash -# Whether the 'files' field is configured in `kcl.yaml` or not, the final value of input files is ["file1.k", "file2.k"] -kcl -Y kcl.yaml file1.k file2.k -``` - -## The relationship and difference between `kcl.mod` and `kcl.yaml` - -First of all, in KCL, `kcl.mod` and `kcl.yaml` are both optional. The difference is that `kcl.mod` determines the root path of the package path and whether a KCL module has the requirement of distribution and reuse, and `kcl.yaml` determines the KCL file composition of the main package. - -Secondly, for a kcl module for external use only, `kcl.yaml` is optional but `kcl.mod` is required, because it needs to declare the KCL version, module version, dependency and other information. - -Finally, for the KCL IDE plug-in, it needs to know the main package information to form a complete compilation process, so it needs to automatically look up the composition of the main package according to the position of the cursor, because no one can specify this information through the KCL command line. The general query logic is to find whether `kcl.yaml` exists. If it is found, the main package consists of the `files` attribute in `kcl.yaml`, and if not found, the main package consists of the current file. The KCL IDE plug-in is selectively aware of the `kcl.mod` file. When the `kcl.mod` file exists, the IDE plug-in reads the corresponding information of all package paths and their real paths in the external dependencies. diff --git a/versioned_docs/version-0.5.5/user_docs/getting-started/_category_.json b/versioned_docs/version-0.5.5/user_docs/getting-started/_category_.json deleted file mode 100644 index 1bf165d4..00000000 --- a/versioned_docs/version-0.5.5/user_docs/getting-started/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Get Started", - "position": 1 -} diff --git a/versioned_docs/version-0.5.5/user_docs/getting-started/index.md b/versioned_docs/version-0.5.5/user_docs/getting-started/index.md deleted file mode 100644 index c50dbaa6..00000000 --- a/versioned_docs/version-0.5.5/user_docs/getting-started/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# Get Started - -Get started include a quick overview of the KCL programming language. diff --git a/versioned_docs/version-0.5.5/user_docs/getting-started/intro.md b/versioned_docs/version-0.5.5/user_docs/getting-started/intro.md deleted file mode 100644 index c4515840..00000000 --- a/versioned_docs/version-0.5.5/user_docs/getting-started/intro.md +++ /dev/null @@ -1,199 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Introduction - -## What is KCL? - -[KCL](https://github.com/kcl-lang/kcl) is an open-source, constraint-based record and functional language that enhances the writing of complex configurations, including those for cloud-native scenarios. With its advanced programming language technology and practices, KCL is dedicated to promoting better modularity, scalability, and stability for configurations. It enables simpler logic writing and offers ease of automation APIs and integration with homegrown systems. - -## Why Use KCL? - -KCL expects to solve the following problems: - -- Hide infrastructure and platform details by defining more appropriate **API abstractions** to reduce the burden of developers. -- **Mutate** and **validate** existing config files or manifests. -- Manage large-scale configuration data across teams without side effects through configuration language. - - Use **production level high-performance programming language** to **write code** to improve the flexibility of configuration, such as conditional statements, loops, functions, package management and other features to improve the ability of configuration reuse. - - Improve the ability of **configuration semantic verification** at the code level, such as optional/required fields, types, ranges, and other configuration checks. - - Provide the **ability to write, combine and abstract configuration blocks**, such as structure definition, structure inheritance, constraint definition, etc. - -You can use KCL to - -- **Generate** low-level static configuration data like JSON, YAML, etc. -- Reduce boilerplate in configuration data with the **schema modeling**. -- Define transformers and constraints for configuration data and templates and **mutate/validate** them automatically. -- Organize, simplify, unify and manage large configurations scalably without side effects. -- Used as a platform engineering language to deliver modern app with [KusionStack](https://kusionstack.io/). - -In addition to the language itself, KCL also provides many additional tools, such as formatting, testing, document, package management, to help users use, understand and check the configuration or policy they write. We can reduce the cost of configuration writing and sharing through IDE extensions such as VS Code, playground and package manage tools. In addition, through KCL Rust, Go, and Python multilingual SDKs, the configuration can be automatically managed and executed. - -![](/img/docs/user_docs/intro/kcl-overview.png) - -Besides, KCL is a modern high-level domain language, which is a compiled, static and strongly typed language. It provides developers with the ability to write **configuration (config)**, **modeling abstraction (schema)**, **logic (lambda)**, and **policies (rule)** as the core elements through recording and functional language design. - -![](/img/docs/user_docs/intro/kcl-concepts.png) - -KCL tries to provide runtime-independent programmability and does not natively provide system functions such as threads and IO, but supports functions for cloud-native operation scenarios, and tries to provide stable, secure, low-noise, low-side effect, easy-to-automate and easy-to-govern programming support for solving domain problems. - -In summary, KCL has the following characteristics: - -- **Easy-to-use**: Originated from high-level languages ​​such as Python and Golang, incorporating functional language features with low side effects. -- **Well-designed**: Independent Spec-driven syntax, semantics, runtime and system modules design. -- **Quick modeling**: [Schema](https://kcl-lang.github.io/docs/reference/lang/tour#schema)-centric configuration types and modular abstraction. -- **Rich capabilities**: Configuration with type, logic and policy based on [Config](https://kcl-lang.github.io/docs/reference/lang/codelab/simple), [Schema](https://kcl-lang.github.io/docs/reference/lang/tour/#schema), [Lambda](https://kcl-lang.github.io/docs/reference/lang/tour/#function), [Rule](https://kcl-lang.github.io/docs/reference/lang/tour/#rule). -- **Stability**: Configuration stability built on [static type system](https://kcl-lang.github.io/docs/reference/lang/tour/#type-system), [constraints](https://kcl-lang.github.io/docs/reference/lang/tour/#validation), and [rules](https://kcl-lang.github.io/docs/reference/lang/tour#rule). -- **Scalability**: High scalability through [automatic merge mechanism](https://kcl-lang.github.io/docs/reference/lang/tour/#-operators-1) of isolated config blocks. -- **Fast automation**: Gradient automation scheme of [CRUD APIs](https://kcl-lang.github.io/docs/reference/lang/tour/#kcl-cli-variable-override), [multilingual SDKs](https://kcl-lang.github.io/docs/reference/xlang-api/overview), [language plugin](https://kcl-lang.github.io/docs/reference/plugin/overview) -- **High performance**: High compile time and runtime performance using Rust & C and [LLVM](https://llvm.org/), and support compilation to native code and [WASM](https://webassembly.org/). -- **API affinity**: Native support API ecological specifications such as [OpenAPI](https://kcl-lang.github.io/docs/tools/cli/openapi/), Kubernetes CRD, Kubernetes YAML spec. -- **Development friendly**: Friendly development experiences with rich [language tools](https://kcl-lang.github.io/docs/tools/cli/kcl/overview) (Format, Lint, Test, Vet, Doc, etc.) and [IDE extensions](https://kcl-lang.github.io/docs/tools/Ide/). -- **Safety & maintainable**: Domain-oriented, no system-level functions such as native threads and IO, low noise and security risk, easy maintenance and governance. -- **Rich multi-language SDK**: [Go](https://kcl-lang.io/docs/reference/xlang-api/go-api), [Python](https://kcl-lang.io/docs/reference/xlang-api/python-api), [Java](https://kcl-lang.io/docs/reference/xlang-api/java-api) and [REST APIs](https://kcl-lang.io/docs/reference/xlang-api/rest-api) meet different scenarios and application use prelude. -- **Kubernetes Integrations**: External mutation and validation plugins including [Kustomize KCL Plugin](https://github.com/kcl-lang/kustomize-kcl), [Helm KCL Plugin](https://github.com/kcl-lang/helm-kcl), [KPT KCL SDK](https://github.com/kcl-lang/kpt-kcl-sdk), [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) to separate data and logic. -- **Production-ready**: Widely used in production practice of platform engineering and automation at Ant Group. - -Although KCL is not a general language, it has corresponding application scenarios. Developers can write **config**, **schema**, **function** and **rule** through KCL, where config is used to define data, schema is used to describe the model definition of data, rule is used to validate data, and schema and rule can also be combined to use models and constraints that fully describe data, In addition, we can also use the lambda pure function in KCL to organize data code, encapsulate common code, and call it directly when needed. - -The configuration of attributes in KCL usually meets the simple pattern: - -$$ -k = (T) v -$$ - -where $k$ is the attribute name, $v$ is the attributes value, and $T$ is the type annotation. Since KCL has the ability of the type inference, $T$ is usually omitted. - -This is an example of generating kubernetes manifests. - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = name -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -We can use the KCL code to generate a Kubernetes YAML manifest. - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## How to Choose? - -Communities have been making significant efforts to improve their configuration technologies, which can be categorized into three groups: - -- Low-level data format-based tools that utilize external tools for enhancing reuse and validation, specifically for templating, patching, and validation. -- Domain-Specific Languages (DSLs) and Configuration Languages (CLs), which enhance language abilities. -- General Purpose Language (GPL)-based solutions that utilize Cloud-Development Kit (CDK) or framework to define the configuration. - -To simplify, here are some recommended options: - -- YAML/JSON/Kustomize/Helm are recommended if you need to write structured key-value pairs, or use Kubernetes native tools. -- HCL is recommended if you want to use programming language convenience to remove boilerplate with good human readability, or if you are already a Terraform user. -- CUE is recommended if you want to use type system to improve stability and maintain scalable configurations. -- KCL is recommended if you want types and modeling like a modern language, scalable configurations, in-house pure functions and rules, and production-ready performance and automation. - -### vs. YAML/JSON - -YAML/JSON configurations are suitable for small-scale configuration scenarios. However, if you require frequent modifications in large-scale cloud-native configuration scenarios, KCL is more appropriate. The primary difference between the two is the abstraction of configuration data and deployment. - -The advantages of using KCL for configuration are numerous. First, abstracting one layer for static data provides deployment flexibility, allowing various configuration environments, tenants, and runtime to have distinct requirements for static data. Additionally, different organizations may have different specifications and product requirements. By leveraging KCL, administrators can expose the most important and frequently modified configurations to users. - -### vs. Jsonnet/GCL - -GCL is a declarative configuration programming language implemented in Python, providing necessary language capabilities for template abstraction. However, the compiler itself is written in Python, and the language runs with interpretation, leading to poor performance for large template instances, such as the Kubernetes model. - -On the other hand, Jsonnet is a data template language implemented in C++/Go, suitable for application and tool developers. It can generate configuration data and organize, simplify, and manage large configurations without any side effects. - -Both Jsonnet and GCL are excellent at reducing boilerplate, using code to generate configuration, so engineers can write advanced GPL code instead of manually writing error-prone and difficult-to-understand server binary code. Despite reducing some of the complexities of GCL, Jsonnet largely falls into the same category. Both have runtime errors, insufficient type-checking and constraint capacity. - -### vs. HCL - -HCL is a configuration language implemented in Go that is structured and inspired by the syntax of libucl and nginx configurations. It is designed to be both human and machine-friendly, primarily for use in devops tools, server configurations, and resource configurations as a [Terraform language](https://www.terraform.io/language). - -The user interface of HCL is not readily apparent in the Terraform provider Schema definition and can be cumbersome when defining complex object and required/optional fields. Dynamic parameters are constrained by the condition field of the variable, and resource constraints must be defined either by the provider schema or through the use of Sentinel/Rego and other policy languages. The language itself may not be self-contained. - -### vs. CUE - -CUE can be utilized for modeling through structures without the need for inheritance or other features. This can lead to high abstraction as long as there are no conflicts with model definitions. However, since CUE performs all constraint checks at runtime, there may be performance bottlenecks in large-scale modeling scenarios. Despite this, CUE simplifies constraint writing through various syntax options, eliminating the need for generic types and enumerations. Additionally, configuration merging is supported but is completely idempotent, which may not be suitable for complex multi-tenant and multi-environment configuration scenarios. Writing complex loop and constraint scenarios can be challenging and cumbersome for accurately modifying configurations. - -On the other hand, KCL conducts modeling through the schema and achieves high model abstraction through language-level engineering and some object-oriented features, such as single inheritance. KCL is a statically compiled language with low overhead for large-scale modeling scenarios. Additionally, KCL provides a richer declarative constraint syntax, making it easier to write. Compared to CUE, KCL offers more if guard combination constraints, all/any/map/filter, and other collection constraint writing methods, which simplify configuration field combination constraints. - -### vs. Dhall - -Dhall is a functional, programmable configuration language that incorporates JSON, functions, types and imports. If you have experience with languages like Haskell, you may find Dhall familiar. KCL also offers similar functionality for programmability and abstraction, but has made greater advancements in areas such as modeling, constraint checking, automation and package management for sharing models. KCL's syntax and semantics are more aligned with object-oriented languages, making it more approachable than pure functional styles in some cases. - -### vs. Nickel - -Nickel is the cheap configuration language. Its purpose is to automate the generation of static configuration files and it is in essence JSON with functions and types. - -KCL and Nickel both have a similar gradual type system (static + dynamic), merge strategy, function and constraint definition. The difference is that KCL is a Python-like language, while Nickel is a JSON-like language. In addition, KCL provides the schema keyword to distinguish between configuration definitions and configuration data to avoid mixed use. - -### vs. Starlark - -Starlark is the language of Bazel, which is a dialect of Python. It does not have types and recursion is forbidden. - -KCL can also be regarded as a variant of Python to some extent, but it greatly enhances the design related to static typing and configuration extensibility, and is a compiled language, which is essentially different from Starlark. - -### vs. Kustomize - -The key feature of Kustomize is its ability to overlay files at a granular level. However, it faces challenges with multiple overlay chains as a specific attribute value may not be the final value, as it can be overridden by another value elsewhere. Retrieving the inheritance chain of Kustomize files can be less convenient than retrieving the inheritance chain of KCL code, particularly for complex scenarios where careful consideration of the specified configuration file overwrite order is necessary. Additionally, Kustomize does not address issues related to YAML configuration writing, constraint verification, model abstraction, and development, making it more suited for simpler configuration scenarios. - -In contrast, KCL offers fine-grained configuration merge operations for each attribute in the code, with flexible merge strategy settings that are not limited to overall resources. KCL also allows for static analysis of configuration dependencies through import statements. - -### vs. Helm - -The idea behind Helm can be traced back to the package management system used in operating systems. It is a package management tool that relies on templated YAML files to execute and manage resources within packages. - -KCL provides a greater range of capabilities than Helm, making it a viable alternative. Users who have already adopted Helm can still utilize KCL by packaging the stack compilation results in a Helm format or by using the Helm-KCL plugin to programmatically extend existing Helm charts. - -### vs. CDK - -CDK's high-level language integrates well into application projects, effectively becoming part of the client runtime. In contrast, KCL decouples external configurations and policies written using KCL from the client runtime. - -General-purpose languages can often be over-engineered, going beyond the requirements of the problem being solved. These languages can also present various security issues, such as problems with the ability boundary, such as accessing I/O, network, code infinite looping, and other security risks. In specialized fields, such as music, there are special notes used to communicate effectively, which cannot be expressed clearly in general-purpose languages. - -Furthermore, general-purpose languages come in a variety of styles, which can create challenges in terms of unified maintenance, management, and automation. These languages are generally better suited to writing the client runtime, which is a continuation of the server runtime. They are not ideal for writing configurations that are independent of the runtime, as they are compiled into binaries and started from the process, making stability and scalability challenging to control. In contrast, configuration languages are often used to write data combined with simple logic, and they describe the expected final result, which is then consumed by the compiler or engine. - -### vs. OPA/Rego - -While not originally intended as a data definition language, Rego, the language used for Open Policy Agent (OPA), can also address the issue of adding constraints from multiple sources. - -Rego has its roots in logic programming and is based on Datalog, a restricted form of Prolog. In contrast, KCL is based on a static type structure. Typed-feature structures were developed to address the limitations of Prolog in encoding human languages. Using a Datalog variant for a constraint validation task may seem unusual. Datalog excels as a query language, but it can be cumbersome for constraint enforcement, in that values must be queried before applying constraints. - -KCL's approach to constraint validation is more conducive to finding normalized and simplified representations of constraints, making it well-suited for creating structures generated from OpenAPI. diff --git a/versioned_docs/version-0.5.5/user_docs/getting-started/kcl-quick-start.md b/versioned_docs/version-0.5.5/user_docs/getting-started/kcl-quick-start.md deleted file mode 100644 index 2316d9a6..00000000 --- a/versioned_docs/version-0.5.5/user_docs/getting-started/kcl-quick-start.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Quick Start - -KCL is a cloud-native domain configuration and policy language. At the beginning of its design, KCL was inspired by Python3, and at the same time absorbed the conceptual design of declarative and OOP programming paradigms. In this section we will quickly demonstrate the basic features of the KCL language. - -## 1. Hello KCL - -The best way to learn a new language is to write a few small programs, and the same goes for configuring languages. We can write KCL programs just like writing configuration. - -Here is a simple `hello.k`: - -```python -hello = "KCL" -``` - -Set the `hello` attribute to the `"KCL"` string. Then save the code to the `hello.k` file. - -How to execute this program depends on the specific development environment, we first assume that the local macOS or Linux system has installed the `kcl` command (or enter the **Docker** environment test by `docker run --rm -it kcllang/kcl`) and then run the following command: - -```shell -kcl hello.k -``` - -The output is - -```yaml -hello: KCL -``` - -The effect of command line execution is shown as follows: - -![](/img/docs/user_docs/getting-started/hello.gif) - -The output is configuration data in YAML format. Although this program is simple, we can verify the basic usage of the development environment and the `kcl` command line by executing the KCL configuration program to the output. - -## 2. A little more complicated configuration - -In addition to the common key-value pairs, common configuration data also has nested dictionary and list types, and the value basic type includes boolean and numeric types in addition to strings. Here's a slightly more complex `server.k` configuration: - -```python -# This is a KCL document - -title = "KCL Example" - -owner = { - name = "The KCL Authors" - data = "2020-01-02T03:04:05" -} - -database = { - enabled = True - ports = [8000, 8001, 8002] - data = [["delta", "phi"], [3.14]] - temp_targets = {cpu = 79.5, case = 72.0} -} - -servers = [ - {ip = "10.0.0.1", role = "frontend"} - {ip = "10.0.0.2", role = "backend"} -] -``` - -where `#` begins with a line comment. The value of `owner` is a dictionary. The value of the dictionary contains the content in the form of `{}`. The key-value inside the dictionary is similar to the `hello = "KCL"` example. `database` is another dictionary in which the value of the dictionary attribute appears boolean `True`, list `[]` and dictionary `{}`, in which the value of the numeric type also appears in the list and dictionary. The `servers` attribute is a list with dictionaries nested inside the list (dictionaries and lists, as well as the `schema` that will be discussed later, can be nested within each other). - -The YAML output of this configuration is as follows: - -```yaml -$ kcl server.k -title: KCL Example -owner: - name: The KCL Authors - data: '2020-01-02T03:04:05' -database: - enabled: true - ports: - - 8000 - - 8001 - - 8002 - data: - - - delta - - phi - - - 3.14 - temp_targets: - cpu: 79.5 - case: 72.0 -servers: -- ip: 10.0.0.1 - role: frontend -- ip: 10.0.0.2 - role: backend -``` - -## 3. Define the structure of the configuration using KCL schema - -The KCL provides abstract support for attributes with a fixed attribute structure and default value behavior through the `schema` syntax. - -For example, the configuration of `database` in the above example is generally the default value. We can define a structure for the default configuration of the database: - -```python -schema DatabaseConfig: - enabled: bool = True - ports: [int] = [8000, 8001, 8002] - data: [[str|float]] = [["delta", "phi"], [3.14]] - temp_targets: {str: float} = {cpu = 79.5, case = 72.0} -``` - -`enabled` is a boolean type; `ports` is an integer list type; `data` is a list of lists, and the inner list elements are strings or floats; `temp_targets` is a dictionary type, and the attribute value of the dictionary is floating point type. And each attribute of `DatabaseConfig` defines a default value. - -Then pass `database = DatabaseConfig {}` to generate a structure with the same attributes as the default values. We can also modify the default value: - -```python -database = DatabaseConfig { - ports = [2020, 2021] -} -``` - -`schema DatabaseConfig` not only provides default values for attributes, but also adds type information to attributes. Therefore, if we accidentally writes the wrong attribute value type, KCL will give a friendly error prompt, such as the following example where `ports` is wrongly written as a floating point type: - -```python -database = DatabaseConfig { - ports = [1.2, 1.3] -} -``` - -When executed, an error similar to the following will be generated (the displayed file path depends on the local environment): - -```shell -kcl server.k -``` - -The output is - -```shell -error[E2G22]: TypeError - --> /path/to/server.k:8:5 - | -8 | ports = [1.2, 1.3] - | ^ expected [int], got [float(1.2)|float(1.3)] - | - - --> /path/to/server.k:3:5 - | -3 | ports: [int] = [8000, 8001, 8002] - | ^ variable is defined here, its type is [int], but got [float(1.2)|float(1.3)] - | -``` - -Similarly we can encapsulate the attributes of the `servers` section with the following code: - -```python -schema ServerConfig: - ip: str - role: "frontend" | "backend" - -servers = [ - ServerConfig {ip = "10.0.0.1", role = "frontend"} - ServerConfig {ip = "10.0.0.2", role = "backend"} -] -``` - -The attribute `ip` of `ServerConfig` is a string type, and no default value is given. We must manually add the value of the `ip` attribute when generating the `ServerConfig` type attribute, otherwise the KCL will report a missing required attribute error. The `role` attribute is a `"frontend" | "backend"` enumerated string type. - -In addition, `schema` can also combine `check`, `mixin`, optional attributes, inheritance and extension modules to achieve more complex configuration and policy data abstraction, full language details can be found at [here](/docs/reference/lang/tour). diff --git a/versioned_docs/version-0.5.5/user_docs/guides/_category_.json b/versioned_docs/version-0.5.5/user_docs/guides/_category_.json deleted file mode 100644 index 40b1340d..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "User Guide", - "position": 4 -} diff --git a/versioned_docs/version-0.5.5/user_docs/guides/_working-with-terraform/1-overview.md b/versioned_docs/version-0.5.5/user_docs/guides/_working-with-terraform/1-overview.md deleted file mode 100644 index c2ec836d..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/_working-with-terraform/1-overview.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -id: overview -sidebar_label: Overview ---- - -# Overview - -Coming Soon diff --git a/versioned_docs/version-0.5.5/user_docs/guides/_working-with-terraform/2-abstraction.md b/versioned_docs/version-0.5.5/user_docs/guides/_working-with-terraform/2-abstraction.md deleted file mode 100644 index 18a25571..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/_working-with-terraform/2-abstraction.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -id: abstraction -sidebar_label: Abstraction ---- - -# Abstract Your Terraform Modules - -Coming Soon diff --git a/versioned_docs/version-0.5.5/user_docs/guides/_working-with-terraform/3-coverter.md b/versioned_docs/version-0.5.5/user_docs/guides/_working-with-terraform/3-coverter.md deleted file mode 100644 index 1dc975bb..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/_working-with-terraform/3-coverter.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -id: converter -sidebar_label: Converter ---- - -# Convert Your Terraform Provider Schema to KCL Schema - -Coming Soon diff --git a/versioned_docs/version-0.5.5/user_docs/guides/_working-with-terraform/_category_.json b/versioned_docs/version-0.5.5/user_docs/guides/_working-with-terraform/_category_.json deleted file mode 100644 index 3e72e820..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/_working-with-terraform/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Terraform", - "position": 13 -} diff --git a/versioned_docs/version-0.5.5/user_docs/guides/automation.md b/versioned_docs/version-0.5.5/user_docs/guides/automation.md deleted file mode 100644 index 561b3302..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/automation.md +++ /dev/null @@ -1,189 +0,0 @@ ---- -title: "Automation" -sidebar_position: 6 ---- - -## Introduction - -KCL provides many automation related capabilities, mainly including tools and multilingual APIs. Via `package_identifier : key_identifier` mode, KCL supports the indexing of any configured key value, thus completing the addition, deletion, modification and query of any key value. For example, the following figure shows that we can directly execute the following command to modify the image. The code diff before and after modification is also shown in the figure. - -![](/img/blog/2022-09-15-declarative-config-overview/14-kcl-image-update.png) - -In addition, the automation capability of KCL can be realized and integrated into CI/CD. - -![](/img/blog/2022-09-15-declarative-config-overview/15-kcl-automation.png) - -## Use KCL for Automation - -### 0. Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/automation -``` - -We can run the following command to show the config. - -```bash -cat main.k -``` - -The output is - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "app" - replicas = 1 - labels.key = "value" -} -``` - -We can run the command to get the config - -```bash -kcl main.k -``` - -The output is - -```yaml -app: - name: app - replicas: 1 - labels: - app: app - key: value -``` - -### 2. Use KCL CLI for Automation - -KCL allows us to directly modify the values in the configuration model through the KCL CLI `-O|--overrides` parameter. The parameter contains three parts e.g., `pkg`, `identifier`, `attribute` and `override_value`. - -```bash -kcl main.k -O override_spec -``` - -- `override_spec` represents a unified representation of the configuration model fields and values that need to be modified - -```bash -override_spec: [[pkgpath] ":"] identifier ("=" value | "-") -``` - -- `pkgpath`: indicates the package path where the identifier needs to be modified, usually in the form of `a.b.c`. For the main package,`pkgpath` is represented as `__ main__`. When omitted or not written, it indicates the main package -- `identifier` indicates the identifier that needs to modify the configuration, usually in the form of `a.b.c`. -- `value` indicates the value of the configuration that needs to be modified, which can be any legal KCL expression, such as number/string literal value, list/dict/schema expression, etc. -- `=` denotes modifying of the value of the identifier. -- `-` denotes deleting of the identifier. - -#### Override Configuration - -Run the command to update the application name. - -```bash -kcl main.k -O app.name='new_app' -``` - -The output is - -```yaml -app: - name: new_app - replicas: 1 - labels: - app: new_app - key: value -``` - -We can see the `name` attribute of the `app` config is updated to `new_app`. - -Besides, when we use KCL CLI `-d` argument, the KCL file will be modified to the following content at the same time. - -```bash -kcl main.k -O app.name='new_app' -d -``` - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "new_app" - replicas = 1 - labels: {key = "value"} -} -``` - -#### Delete Configuration - -Run the command to delete the `key` attribute of `labels`. - -```bash -kcl main.k -O app.labels.key- -``` - -The output is - -```yaml -app: - name: app - replicas: 1 - labels: - app: app -``` - -### 3. Use KCL API for Automation - -In addition, we can automatically modify the configuration attributes through the [multilingual API](/docs/reference/xlang-api/overview). - -Take the RestAPI as an example. The RestAPI service can be started in the following way: - -```bash -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -The service can then be requested via the POST protocol: - -```bash -curl -X POST http://127.0.0.1:2021/api:protorpc/KclvmService.OverrideFile -H 'content-type: accept/json' -d '{ - "file": "main.k", - "specs": ["app.name=\"nginx\""] -}' -``` - -After the service call is completed, main.k will be modified as follows: - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "nginx" - replicas = 1 - labels: { - "key" = "value" - } -} -``` - -## Summary - -The document introduces the automation capabilities of KCL, including tools and multilingual APIs. It supports indexing of any configured key value, allowing for the addition, deletion, modification, and querying of any key value. It can also be integrated into CI/CD. The document provides an example of using KCL to automate configuration management, including using the KCL CLI to override and delete configurations, and using the KCL API to modify configuration attributes. For more information about KCL automation and Override API, please refer to [here](/docs/reference/lang/tour#kcl-cli-variable-override). diff --git a/versioned_docs/version-0.5.5/user_docs/guides/ci-integration/_3-jenkins-ci.md b/versioned_docs/version-0.5.5/user_docs/guides/ci-integration/_3-jenkins-ci.md deleted file mode 100644 index f85d231f..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/ci-integration/_3-jenkins-ci.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -id: github-ci -sidebar_label: Github CI ---- - -Coming Soon - -## Introduction - -## How to - -## Summary diff --git a/versioned_docs/version-0.5.5/user_docs/guides/ci-integration/_category_.json b/versioned_docs/version-0.5.5/user_docs/guides/ci-integration/_category_.json deleted file mode 100644 index 3145ed7f..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/ci-integration/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "CI Integration", - "position": 12 -} \ No newline at end of file diff --git a/versioned_docs/version-0.5.5/user_docs/guides/configuration.md b/versioned_docs/version-0.5.5/user_docs/guides/configuration.md deleted file mode 100644 index e6060815..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/configuration.md +++ /dev/null @@ -1,129 +0,0 @@ ---- -title: "Configuration" -sidebar_position: 1 ---- - -## Introduction - -Configuration is a vital aspect of software systems that are constantly in flux due to evolving business requirements, infrastructure demands, and other factors. Often, changing these systems' behavior quickly can be challenging, especially when doing so requires a costly and time-consuming reconstruction and redeployment process. In such cases, making changes to the business code may not be sufficient. Fortunately, the configuration provides a low-overhead way to modify system functions. For instance, many developers write JSON or YAML files to configure their systems. - -We can store the static configuration in JSON and YAML files as needed. Moreover, the configuration can also be stored in a high-level language that allows for more flexible configuration. This language can be coded, rendered, and statically configured. KCL is a configuration language that offers such functionality. Developers can write KCL code to generate JSON/YAML and other configurations. - -## Use KCL for Configuration - -KCL's core features are its modeling and constraint capabilities, and its basic functions revolve around these two key elements. Additionally, KCL follows a user-centric configuration concept when designing its basic functions. Configuration code has requirements for configuration data constraints, such as type constraints and required/optional constraints on configuration attributes, range constraints, and immutability constraints. These are also some of the core issues that KCL is committed to resolving. - -Now that we have an understanding of KCL's capabilities, let's explore how to use it to generate configurations. - -### 0. Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. Get the Example - -Firstly, let's get the example. - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/configuration -``` - -We can run the following command to show the config. - -```bash -cat nginx.k -``` - -The output is - -```python -schema Nginx: - """Schema for Nginx configuration files""" - http: Http - -schema Http: - server: Server - -schema Server: - listen: int | str # The attribute `listen` can be int type or a string type. - location?: Location # Optional, but must be non-empty when specified - -schema Location: - root: str - index: str - -nginx = Nginx { - http.server = { - listen = 80 - location = { - root = "/var/www/html" - index = "index.html" - } - } -} -``` - -### 2. Generate YAML using KCL - -Run the following command - -```bash -kcl nginx.k -``` - -We can get the output YAML - -```yaml -nginx: - http: - server: - listen: 80 - location: - root: /var/www/html - index: index.html -``` - -### 3. Configuration with Dynamic Parameters - -Besides, we can dynamically receive external parameters through the KCL builtin function `option`. For example, for the following KCL file (db.k), we can use the KCL command line `-D` flag to receive an external dynamic parameter. - -```python -env: str = option("env") or "dev" # The attribute `env` has a default value "den" -database: str = option("database") -hosts = { - dev = "postgres.dev" - stage = "postgres.stage" - prod = "postgres.prod" -} -dbConfig = { - host = hosts[env] - database = database - port = "2023" - conn = "postgres://${host}:${port}/${database}" -} -``` - -```bash -# Use the `-D` flag to input external parameters. -kcl db.k -D database="foo" -``` - -The output is - -```yaml -env: dev -database: foo -hosts: - dev: postgres.dev - stage: postgres.stage - prod: postgres.prod -dbConfig: - host: postgres.dev - database: foo - port: "2023" - conn: "postgres://postgres.dev:2023/foo" -``` - -## Summary - -By using KCL, we can generate low-level data configurations. For different situations, we set dynamic parameters through the `-D` flag to meet the scene requirements. For more KCL features, please refer to [here](/docs/reference/lang/tour). diff --git a/versioned_docs/version-0.5.5/user_docs/guides/gitops/1-quick-start.md b/versioned_docs/version-0.5.5/user_docs/guides/gitops/1-quick-start.md deleted file mode 100644 index 04570df1..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/gitops/1-quick-start.md +++ /dev/null @@ -1,163 +0,0 @@ ---- -id: gitops-quick-start -sidebar_label: Quick Start ---- - -# Quick Start - -## Introduction - -### What is GitOps - -GitOps is a modern way to do continuous delivery. Its core idea is to have a Git repository which contains environmental and application configurations. An automated process is also needed for sync the config to cluster. - -By changing the files in repository, developers can apply the applications automatically. The benefits of applying GitOps include: - -- Increased productivity. Continuous delivery can speed up the time of deployment. -- Lower the barrier for developer to deploy. By pushing code instead of container configuration, developers can easily deploy Kubernetes without knowing its internal implementation. -- Trace the change records. Managing the cluster with Git makes every change traceable, enhancing the audit trail. -- Recover the cluster with Git's rollback and branch. - -### GitOps with KCL - -Benefits of Using KCL and ArgoCD Together: - -- KCL can help us **simplify complex Kubernetes deployment configuration files**, reduce the error rate of manually writing YAML files, and improve code readability and maintainability. -- ArgoCD can **automate** the deployment of Kubernetes applications, achieve continuous deployment, and provide comprehensive monitoring and control functions. -- By combining KCL and ArgoCD, deployment efficiency can be improved, errors reduced, and management and monitoring of Kubernetes applications strengthened. -- The combination of KCL and ArgoCD can also help us achieve **Infrastructure as Code (IaC)**, simplify application deployment and management, and better implement DevOps principles. - -With GitOps, developer and operation teams can manage application deployment and configuration by modifying KCL code and generating YAML files. The GitOps toolchain will automatically synchronize the changes to the Kubernetes cluster, enabling continuous deployment and ensuring consistency. If there are issues, the GitOps toolchain can be used to quickly rollback. - -## Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -## How to - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/gitops -``` - -We can run the following command to show the config. - -```bash -cat config/main.k -``` - -The output is - -```python -import .app - -config = app.App { - name = "kcl-guestbook-ui" - containers.guestbook = { - image = "gcr.io/heptio-images/ks-guestbook-demo:0.2" - ports = [{containerPort = 80}] - } - service.ports = [{ port = 80 }] - service.type = "LoadBalancer" -} -``` - -In the above code, we defined a configuration using the `App` schema, where we configured an `gcr.io/heptio-images/ks-guestbook-demo:0.2` container and configured it with an `80` service port. - -### 2. Install Kubernetes and GitOps Tool - -#### Setup Kubernetes Cluster and ArgoCD Controllers - -- Install [K3d](https://github.com/k3d-io/k3d) to create a default cluster. - -```bash -k3d cluster create mycluster -``` - -- Install [ArgoCD](https://github.com/argoproj/argo-cd/releases/). - -```bash -kubectl create namespace argocd -kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml -``` - -- Enable ArgoCD KCL Plugin - -Write the patch YAML configuration file and update the ArgoCD configuration: - -```bash -kubectl apply -f ./install/kcl-cmp.yaml -``` - -After completing the first step, ArgoCD will recognize the KCL plugin, but the KCL plugin has not been loaded into the ArgoCD image. To implement configuration drift detection, we have to tune the Deployment of argocd-repo-server. - -```bash -kubectl -n argocd patch deploy/argocd-repo-server -p "$(cat ./install/patch-argocd-repo-server.yaml)" -``` - -Wait for the init container to complete execution (Running). - -```bash -kubectl get pod -n argocd -l app.kubernetes.io/name=argocd-repo-server -``` - -- To access the ArgoCD web UI - -```bash -kubectl port-forward svc/argocd-server -n argocd 8080:443 -``` - -- Open a browser and go to: `https://localhost:8080` - -- The username is "admin" and password get be obtained from the following command: - -```bash -kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d -``` - -#### Setup ArgoCD CLI - -- Install [ArgoCD CLI](https://github.com/argoproj/argo-cd/releases) - -Use "admin" and password to login to ArgoCD - -```bash -argocd login localhost:8080 -``` - -Create ArgoCD Application - -```bash -argocd app create guestbook \ ---repo https://github.com/kcl-lang/kcl-lang.io \ ---path examples/gitops/config \ ---dest-namespace default \ ---dest-server https://kubernetes.default.svc \ ---config-management-plugin kcl-v1.0 -``` - -If you are using a private repository, you need to configure the private repository access with private key credentials before executing the create command. - -Please refer [Private Repositories](https://argo-cd.readthedocs.io/en/stable/user-guide/private-repositories/#ssh-private-key-credential) for more details. - -After successfully creating, you can see the following output: - -```bash -application 'guestbook' created -``` - -Through the ArgoCD UI, you can see that the created applications have not been synchronized yet. Here, you can manually synchronize or set automatic synchronization. - -![](/img/docs/user_docs/guides/gitops/argocd-kcl-app.jpg) - -For more information on synchronization strategies, see [Sync Options](https://argo-cd.readthedocs.io/en/stable/user-guide/sync-options/) - -![](/img/docs/user_docs/guides/gitops/argocd-kcl-app-dashboard.jpg) - -## Summary - -With GitOps, you can easily manage your applications and configuration in your Kubernetes cluster with KCL, ensuring that your applications are always in the desired state. diff --git a/versioned_docs/version-0.5.5/user_docs/guides/gitops/_category_.json b/versioned_docs/version-0.5.5/user_docs/guides/gitops/_category_.json deleted file mode 100644 index 29a73c67..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/gitops/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "GitOps", - "position": 11 -} \ No newline at end of file diff --git a/versioned_docs/version-0.5.5/user_docs/guides/index.md b/versioned_docs/version-0.5.5/user_docs/guides/index.md deleted file mode 100644 index cd3d4522..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/index.md +++ /dev/null @@ -1 +0,0 @@ -# User Guide diff --git a/versioned_docs/version-0.5.5/user_docs/guides/package-management/1-overview.md b/versioned_docs/version-0.5.5/user_docs/guides/package-management/1-overview.md deleted file mode 100644 index cffccc67..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/package-management/1-overview.md +++ /dev/null @@ -1,3 +0,0 @@ -# Overview - -KCL manages packages through the package management tool [kpm](https://github.com/kcl-lang/kpm). diff --git a/versioned_docs/version-0.5.5/user_docs/guides/package-management/2-installation.md b/versioned_docs/version-0.5.5/user_docs/guides/package-management/2-installation.md deleted file mode 100644 index 11d1da5d..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/package-management/2-installation.md +++ /dev/null @@ -1,55 +0,0 @@ -# Installation - -## Install `kpm` - -Before installing and using kpm, ensure that KCL has been installed successfully. - -[How to install KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### Go install - -You can download kpm via go install. - -```shell -go install kcl-lang.io/kpm@latest -``` - -### Download from GITHUB release page - -You can get `kpm` from the [kpm github release](https://github.com/kcl-lang/kpm/releases) and set the `kpm` binary path to the environment variable PATH. - -```shell -# KPM_INSTALLATION_PATH is the path of the `kpm` binary. -export PATH=$KPM_INSTALLATION_PATH:$PATH -``` - -Use the following command to ensure that you install `kpm` successfully. - -```shell -kpm --help -``` - -If you get the following output, you have successfully installed `kpm` and you can proceed to the following steps. - -```shell -NAME: - kpm - kpm is a kcl package manager - -USAGE: - kpm [arguments]... - -COMMANDS: - init initialize new module in current directory - add add new dependency - pkg package a kcl package into tar - metadata output the resolved dependencies of a package - run compile kcl package. - login login to a registry - logout logout from a registry - push push kcl package to OCI registry. - pull pull kcl package from OCI registry. - help, h Shows a list of commands or help for one command - -GLOBAL OPTIONS: - --help, -h show help -``` diff --git a/versioned_docs/version-0.5.5/user_docs/guides/package-management/3-quick-start.md b/versioned_docs/version-0.5.5/user_docs/guides/package-management/3-quick-start.md deleted file mode 100644 index 689e9530..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/package-management/3-quick-start.md +++ /dev/null @@ -1,112 +0,0 @@ -# Quick Start - -## 0. Prerequisite - -- Install [kpm](https://kcl-lang.io/docs/user_docs/guides/package-management/installation) - -## 1. Init an Empty KCL Package - -Create a new kcl package named `my_package`. And after we have created the package `my_package`, we need to go inside the package by `cd my_package` to complete the following operations. - -```shell -kpm init my_package && cd my_package -``` - -![kpm_init](/img/docs/user_docs/guides/package-management/gifs/kpm_init.gif) - -`kpm` will create two kcl package configuration files: `kcl.mod` and `kcl.mod.lock` in the directory where you executed the command. - -```shell -- my_package - |- kcl.mod - |- kcl.mod.lock - |- # You can write your kcl program directly in this directory. -``` - -`kcl.mod.lock` is the file generated by `kpm` to fix the dependency version. Do not modify this file manually. - -`kpm` initializes `kcl.mod` for an empty project as shown below: - -```shell -[package] -name = "my_package" -edition = "0.0.1" -version = "0.0.1" -``` - -## 2. Add a Dependency from OCI Registry - -You can then add a dependency to the current kcl package using the `kpm add` command - -As shown below, taking the example of adding a package dependency named `k8s`, the version of the package is `1.27.2`. - -```shell -kpm add k8s:1.27.2 -``` - -![kpm_add_k8s](/img/docs/user_docs/guides/package-management/gifs/kpm_add_k8s.gif) - -You can see that `kpm` adds the dependency you just added to kcl.mod. - -```shell -[package] -name = "my_package" -edition = "0.0.1" -version = "0.0.1" - -[dependencies] -k8s = "1.27.2" # The dependency 'k8s' with version '1.27.2' -``` - -### Write a kcl program that uses the content in `k8s` - -Create the `main.k` file in the current package. - -```shell -- my_package - |- kcl.mod - |- kcl.mod.lock - |- main.k # Your KCL program. -``` - -And write the following into the `main.k` file. - -```kcl -# Import and use the contents of the external dependency 'k8s'. -import k8s.api.core.v1 as k8core - -k8core.Pod { - metadata.name = "web-app" - spec.containers = [{ - name = "main-container" - image = "nginx" - ports = [{containerPort = 80}] - }] -} - -``` - -## 3. Run the KCL Code - -In the `my_package` directory, you can use `kpm` to compile the `main.k` file you just wrote. - -```shell -kpm run -``` - -The output is - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: web-app -spec: - containers: - - image: nginx - name: main-container - ports: - - containerPort: 80 -``` - -![kpm_run](/img/docs/user_docs/guides/package-management/gifs/kpm_run.gif) diff --git a/versioned_docs/version-0.5.5/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md b/versioned_docs/version-0.5.5/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md deleted file mode 100644 index aa9c119d..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md +++ /dev/null @@ -1,73 +0,0 @@ -# Share Your Package - -[kpm](https://github.com/kcl-lang/kpm) is a tool for managing kcl packages. This article will guide you on how to use kpm to push your kcl package to an OCI Registry for publication. kpm uses [ghcr.io](https://ghcr.io) as the default OCI Registry, and you can change the default OCI Registry by modifying the kpm configuration file. For information on how to modify the kpm configuration file, see [kpm oci registry](https://github.com/kcl-lang/kpm/blob/main/docs/kpm_oci.md#kpm-registry) - -Here is a simple step-by-step guide on how to use kpm to push your kcl package to ghcr.io. - -## Step 1: Install kpm - -First, you need to install kpm on your computer. You can follow the instructions in the [kpm installation documentation](https://kcl-lang.io/docs/user_docs/guides/package-management/installation). - -## Step 2: Create a ghcr.io token - -If you are using the default OCI Registry of kpm, to push a kcl package to ghcr.io, you need to create a token for authentication. You can follow the instruction. - -- [Creating a ghcr.io access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic) - -## Step 3: Log in to ghcr.io - -After installing kpm and creating a ghcr.io token, you need to log in to ghcr.io using kpm. You can do this using the following command: - -```shell -kpm login ghcr.io -u -p -``` - -Where `` is your GitHub username, `` is the token you created in step 2 - -For more information on how to log in to ghcr.io using kpm, see [kpm login](https://kcl-lang.io/docs/reference/package-management/command-reference/login). - -## Step 4: Push your kcl package - -Now, you can use kpm to push your kcl package to ghcr.io. - -### 1. A valid kcl package - -First, you need to make sure that what you are pushing conforms to the specifications of a kcl package, i.e., it must contain valid kcl.mod and kcl.mod.lock files. - -If you don't know how to get a valid kcl.mod and kcl.mod.lock, you can use the `kpm init` command. - -```shell -# Create a new kcl package named my_package -kpm init my_package -``` - -The `kpm init my_package` command will create a new kcl package `my_package` for you and create the `kcl.mod` and `kcl.mod.lock` files for this package. - -If you already have a directory containing kcl files `exist_kcl_package`, you can use the following command to convert it into a kcl package and create valid `kcl.mod` and `kcl.mod.lock` files for it. - -```shell -# In the exist_kcl_package directory -$ pwd -/home/user/exist_kcl_package - -# Run the `kpm init` command to create the `kcl.mod` and `kcl.mod.lock` files -$ kpm init -``` - -For more information on how to use `kpm init`, see [kpm init](https://kcl-lang.io/docs/reference/package-management/command-reference/init). - -### 2. Pushing the KCL Package - -You can use the following command in the root directory of your `kcl` package: - -```shell -# In the root directory of the exist_kcl_package package -$ pwd -/home/user/exist_kcl_package - -# Pushing the KCL Package to Default OCI Registry -$ kpm push -``` - -After completing these steps, you have successfully pushed your KCL Package to the default OCI Registry. -For more information on how to use `kpm push`, see [kpm push](https://kcl-lang.io/docs/reference/package-management/command-reference/push). diff --git a/versioned_docs/version-0.5.5/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md b/versioned_docs/version-0.5.5/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md deleted file mode 100644 index 3fa5aabe..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md +++ /dev/null @@ -1,66 +0,0 @@ -# Share Your Package to docker.io - -[kpm](https://github.com/KusionStack/kpm) is a tool for managing kcl packages. This article will show you how to use kpm to push your kcl packages to docker.io. - -Here is a simple step-by-step guide on how to use kpm to push your kcl package to docker.io. - -## Step 1: Install kpm - -First, you need to install kpm on your computer. You can follow the instructions in the [kpm installation documentation](https://kcl-lang.io/docs/user_docs/guides/package-management/installation). - -## Step 2: Create a docker.io account - -If you want to use `docker.io` as the OCI registry to share your kcl package with others, you need to create a `docker.io` account to support the push of your kcl package. - -## Step 3: Log in to docker.io - -You can use the following command to log in to docker.io. - -```shell -kpm login -u -p docker.io -``` - -Where `` is your `docker.io` username, and `` is your `docker.io` password. - -For more information on how to log in to docker.io using kpm, see [kpm login](https://kcl-lang.io/docs/reference/package-management/command-reference/login). - -## Step 4: Push your kcl package - -Now, you can use kpm to push your kcl package to `docker.io`. - -### 1. A valid kcl package - -First, you need to make sure that what you are pushing conforms to the specifications of a kcl package, i.e., it must contain valid kcl.mod and kcl.mod.lock files. - -If you don't know how to get a valid kcl.mod and kcl.mod.lock, you can use the `kpm init` command. - -Create a new kcl package named `my_package`. - -```shell -kpm init my_package -``` - -The `kpm init my_package` command will create a new kcl package `my_package` for you and create the `kcl.mod` and `kcl.mod.lock` files for this package. - -If you already have a directory containing kcl files `exist_kcl_package`, you can use the following command to convert it into a kcl package and create valid `kcl.mod` and `kcl.mod.lock` files for it. - -Run the `kpm init` command under the `exist_kcl_package` directory. - -```shell -kpm init -``` - -For more information on how to use `kpm init`, see [kpm init](https://kcl-lang.io/docs/reference/package-management/command-reference/init). - -### 2. Pushing the KCL Package - -You can use the following command in the root directory of your `kcl` package: - -Run the `kpm push` command under the `exist_kcl_package` directory. - -```shell -kpm push oci://docker.io//exist_kcl_package -``` - -After completing these steps, you have successfully pushed your KCL Package `exist_kcl_package` to `docker.io`. -For more information on how to use `kpm push`, see [kpm push](https://kcl-lang.io/docs/reference/package-management/command-reference/push). diff --git a/versioned_docs/version-0.5.5/user_docs/guides/package-management/4-how-to/6-push_github_action.md b/versioned_docs/version-0.5.5/user_docs/guides/package-management/4-how-to/6-push_github_action.md deleted file mode 100644 index de88dbcf..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/package-management/4-how-to/6-push_github_action.md +++ /dev/null @@ -1,81 +0,0 @@ -# Push Your KCL Package by GitHub Action - -[kpm](https://github.com/KusionStack/kpm) is a tool for managing kcl packages. This article will guide you how to use kpm in GitHub Action to push your kcl package to OCI registry. - -## Step 1: Install kpm - -At first, you need to install kpm on your computer. You can follow [kpm installation document](https://kcl-lang.io/docs/user_docs/guides/package-management/installation). - -## Step 2: Create a GitHub account - -If you already have a GitHub account, you can skip this step. - -[Sign up for a new GitHub account](https://docs.github.com/en/get-started/signing-up-for-github/signing-up-for-a-new-github-account) - -## Step 3: Create a GitHub repository for your KCL package - -### 1. Prepare a GitHub repository for your KCL package - -You need to prepare a GitHub repository for your KCL package. - -[Create a GitHub repository](https://docs.github.com/en/get-started/quickstart/create-a-repo) - -In this repository, add your KCL program, take the repository https://github.com/awesome-kusion/catalog.git as an example, - -```bash -├── .github -│ └── workflows -│ └── push.yaml # github action workflow -├── LICENSE -├── README.md -├── kcl.mod # kcl.mod to define your kcl package -├── kcl.mod.lock # kcl.mod.lock generated by kpm -└── main.k # Your KCL program -``` - -### 2. Set OCI Registry, account and password for your Github repository - -Take docker.io as an example, you can set secrets `REG`, `REG_ACCOUNT` and `REG_TOKEN` for your repository. The value of `REG` is `docker.io`, the value of `REG_ACCOUNT` is your `docker.io` account, and the value of `REG_TOKEN` is your `docker.io` login password. - -[Add secrets to the repository](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) - -If you use `ghcr.io` as `Registry`, you need to use GitHub token as secrets. - -[Create a GitHub Token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token#personal-access-tokens-classic) - -## Step 4: Add your KCL package to the repository and write github action workflow - -Add github action file `.github/workflows/push.yml` to this repository, the content is as follows: - -```yaml -name: KPM Push Workflow - -on: - push: - branches: - - main - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Set up Go 1.21 - uses: actions/setup-go@v2 - with: - go-version: 1.21 - - - name: Install kpm - run: go install kcl-lang.io/kpm@latest - - - name: Login and Push - env: - KPM_REG: ${{ secrets.REG }} - KPM_REPO: ${{ secrets.REG_ACCOUNT }} - run: kpm login -u ${{ secrets.REG_ACCOUNT }} -p ${{ secrets.REG_TOKEN }} ${{ secrets.REG }} && kpm push - - - name: Run kpm project from oci registry - run: kpm run oci://${{ secrets.REG }}/${{ secrets.REG_ACCOUNT }}/catalog --tag 0.0.1 -``` diff --git a/versioned_docs/version-0.5.5/user_docs/guides/package-management/4-how-to/_category_.json b/versioned_docs/version-0.5.5/user_docs/guides/package-management/4-how-to/_category_.json deleted file mode 100644 index e3409c62..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/package-management/4-how-to/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "How to", - "position": 4 -} diff --git a/versioned_docs/version-0.5.5/user_docs/guides/package-management/_category_.json b/versioned_docs/version-0.5.5/user_docs/guides/package-management/_category_.json deleted file mode 100644 index 1211443e..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/package-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Package Management Tools", - "position": 7 -} diff --git a/versioned_docs/version-0.5.5/user_docs/guides/secret-management/1-vault.md b/versioned_docs/version-0.5.5/user_docs/guides/secret-management/1-vault.md deleted file mode 100644 index 6da58286..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/secret-management/1-vault.md +++ /dev/null @@ -1,142 +0,0 @@ ---- -id: vault -sidebar_label: Vault ---- - -# Vault - -## Introduction - -This guide will show you that KCL solves the secret management problem by integrating [Vault](https://developer.hashicorp.com/vault) and [Vals](https://github.com/helmfile/vals). - -## Prerequisites - -- Install [KCL](/docs/user_docs/getting-started/install) -- Prepare a [Kubernetes Cluster](https://kubernetes.io/) -- Install [Vault](https://developer.hashicorp.com/vault/downloads) -- Install [Vals](https://github.com/helmfile/vals) - -## How to - -### 1. Get the Example - -We put the application source code and infrastructure deployment code in different repos, which can be maintained by different roles to achieve the separation of concerns. - -- Get the application code - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/secret-management/vault -``` - -- Show the config - -```shell -cat main.k -``` - -The output is - -```python -# Secret Management using Vault and Vals - -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" - annotations: { - "secret-store": "vault" - # Valid format: - # "ref+vault://PATH/TO/KV_BACKEND#/KEY" - "foo": "ref+vault://secret/foo#/foo" - "bar": "ref+vault://secret/bar#/bar" - } -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -The main.k file extends the configuration of the Nginx application and customizes annotations. Among them, the value of annotation `foo` and `bar` follow secret reference format (`ref+vault://PATH/TO/KV_BACKEND#/KEY`): - -- `ref+vault`: indicates that this is a secret reference, and the external storage service is `Vault`. -- `PATH/TO/KV_BACKEND`: specifies the path where a secret is stored. -- `KEY`: specifies the key to reading secret. - -The complete format is concatenated using a style similar to URI expressions, which can retrieve a secret stored externally. - -### 2. Pre-store Secrets - -Start the Vault Server - -```shell -vault server -dev -export VAULT_ADDR='http://127.0.0.1:8200' -# Note: Replace with your token -export VAULT_TOKEN=yourtoken -``` - -After Vault is started in development mode and unpacked, secrets are pre-stored, and the path and keys are consistent with `main.k`: - -```shell -vault kv put secret/foo foo=foo -vault kv put secret/bar bar=bar -``` - -### 3. Deploy Configuration - -Using the following command to apply the deployment manifest. - -```shell -kcl main.k | vals eval -f - | kubectl apply -f - -``` - -The expect output is - -```shell -deployment.apps/nginx created -``` - -### 4. Verify Secrets - -Next, verify that the secrets have been retrieved from Vault and replace the values of annotations of Nginx: - -- Verify the `foo` annotation - -```shell -kubectl get deploy nginx -o yaml | grep 'foo:' -``` - -The output is - -```yaml -foo: foo -``` - -- Verify the `bar` annotation - -```shell -kubectl get deploy nginx -o yaml | grep 'bar:' -``` - -The output is - -```yaml -bar: bar -``` - -So far, we have retrieved the secrets hosted in `Vault` and put them into use. - -## Summary - -This guide introduces how KCL solves the secret management by integrating Vault and Vals. By following these steps, we can retrieve the secrets hosted in Vault and utilize them. diff --git a/versioned_docs/version-0.5.5/user_docs/guides/secret-management/_category_.json b/versioned_docs/version-0.5.5/user_docs/guides/secret-management/_category_.json deleted file mode 100644 index c57bb30e..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/secret-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Secret Management", - "position": 13 -} diff --git a/versioned_docs/version-0.5.5/user_docs/guides/validation.md b/versioned_docs/version-0.5.5/user_docs/guides/validation.md deleted file mode 100644 index f589d7fa..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/validation.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: "Validation" -sidebar_position: 2 ---- - -## Introduction - -Validation is the process of verifying that data is accurate, reliable, and meets certain requirements or constraints. This includes checking the data for completeness, consistency, accuracy, and relevance. Data validation is performed to ensure that the data is fit for its intended purpose and that it can be used effectively and efficiently. - -We can use KCL and its vet tools to manually or automatically perform data validation to ensure data consistency. - -## Use KCL for Validation - -In addition to using KCL code to generate configuration formats such as JSON/YAML, KCL also supports format validation of JSON/YAML data. As a configuration language, KCL covers almost all features of [OpenAPI](https://www.openapis.org/). - -In KCL, a structure definition can be used to validate configuration data. At the same time, it supports user-defined constraint rules through the check block, and writes validation expressions in the schema to check and validate the attributes defined by the schema. It is very clear and simple to check whether the input JSON/YAML satisfies the corresponding schema structure definition and constraints. - -### 0. Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. Get the Example - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/validation -``` - -We can run the following command to show the config. - -```bash -cat schema.k -``` - -```python -schema User: - name: str - age: int - message?: str - data: Data - labels: {str:} - hc: [int] - - check: - age > 10, "age must > 10" - -schema Data: - id: int - value: str -``` - -In the schema, we can use the `check` keyword to write the validation rules of every schema attribute. Each line in the check block corresponds to a conditional expression. When the condition is satisfied, the validation is successful. The conditional expression can be followed by `, "check error message"` to indicate the message to be displayed when the check fails. - -To sum up, the validation kinds supported in KCL schema are: - -| Kind | Method | -| ----------------- | ----------------------------------------------------------------------------------------- | -| Range | Using comparison operators such as `<`, `>` | -| Regex | Using methods such as `match` from the `regex` system module | -| Length | Using the `len` built-in function to get the length of a variable of type `list/dict/str` | -| Enum | Using literal union types | -| Optional/Required | Using optional/required attributes of schema | -| Condition | Using the check if conditional expression | - -### 2. Validate the Data - -There is a JSON format file `data.json`: - -```json -{ - "name": "Alice", - "age": 18, - "message": "This is Alice", - "data": { - "id": 1, - "value": "value1" - }, - "labels": { - "key": "value" - }, - "hc": [1, 2, 3] -} -``` - -Execute the following command: - -```bash -kcl-vet data.json schema.k -``` - -## Summary - -KCL is a configuration language that supports data validation through its structure definition and user-defined constraint rules. Validation kinds supported in KCL schema include range, regex, length, enum, optional/required, and condition. To validate data, a schema is defined with validation rules written using the check keyword, and the data is validated using the validation tool or a visualization product built on top of it. - -## Further Information - -The improvement of KCL validation capabilities will gradually focus on the "static" aspect, that is, at compile time, combined with the ability of formal validation, it can directly analyze whether the data meets the constraints, whether the constraints conflict with each other, etc., and can be exposed in real-time through the IDE. - -We also expect that KCL models and constraints can be managed as a package (this package has only KCL files). For example, the Kubernetes models and constraints can be used out of the box. Users can generate configurations or verify existing configurations, and can simply extend the models and constraints users want through KCL inheritance. diff --git a/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md b/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md deleted file mode 100644 index ac20cd12..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: "Adopt From Kubernetes" -sidebar_position: 1 ---- - -## Introduction - -KCL provides many out of the box support for Kubernetes configuration. Through KCL tools, we can integrate Kubernetes Schema and configuration into KCL. This section will introduce how to use KCL to integrate Kubernetes. - -## Prerequisite - -- Install kcl-openapi - -## Quick Start - -### 1. Kubernetes OpenAPI Spec - -Starting from Kubernetes 1.4, the alpha support for the OpenAPI specification (known as Swagger 2.0 before it was donated to the OpenAPI Initiative) was introduced, and the API descriptions follow the [OpenAPI Spec 2.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md). And since Kubernetes 1.5, Kubernetes supports [directly extracting models from source code and then generating the OpenAPI spec file](https://github.com/kubernetes/kube-openapi) to automatically keep the specifications and documents up to date with the operation and models. - -In addition, Kubernetes CRD uses [OpenAPI V3.0 validation](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation) to describe a custom schema (in addition to the built-in attributes apiVersion, Kind, and metadata), that APIServer uses to validate the CR during the resource creation and update phases. - -### 2. KCL OpenAPI Support - -The `kcl-openapi` tool supports extracting and generating KCL schemas from Kubernetes OpenAPI/CRD. the [KCL OpenAPI Spec](/docs/tools/cli/openapi/spec) defines the mapping between the OpenAPI specification and the KCL language features. - -### 3. Migrate From Kubernetes To KCL - -#### 3.1 Write configurations based on the Kusion_Models package - -``We provide an out-of-the-box `kusion_models` package for you to quickly start. It contains a well-designed frontend model called [`Server schema`](https://github.com/KusionStack/konfig/blob/main/base/pkg/kusion_models/kube/frontend/server.k). You can declare the configurations by initializing the `Server schema`. For the description and usage of the schema and its attributes, please refer to the [Server schema documentation](https://kusionstack.io/docs/reference/model/kusion_models/kube/frontend/doc_server).`` - -#### 3.2 Build Your Custom Frontend Models - -The existing KCL Models may not meet your specific business requirements, then you can also design your custom frontend model package. You can design your custom models based on the pre-generated Kubernetes KCL models among all versions. - -##### 3.2.1 Get the k8s package - -The [Kubernetes KCL models](https://github.com/orgs/KusionStack/packages/container/package/k8s) among all versions are pre-generated, you get it by executing `kpm add k8s:` under your project. For detailed information about kpm usage, please refer to [kpm quick start guide](https://github.com/kcl-lang/kpm#quick-start). - -Alternatively, if you may want to generate them yourself, please refer to [Generate KCL Packages from Kubernetes OpenAPI Specs](https://github.com/kcl-lang/kcl-openapi/blob/main/docs/generate_from_k8s_spec.md). - -##### 3.2.2 Design Custom Frontend Models - -Since the Kubernetes built-in models are atomistic and kind of complex to beginners, we recommend taking the native model of Kubernetes as the backend output model and designing a batch of frontend models which could become a more abstract, friendlier and simpler interface to the user. You can refer to the design pattern in the [`Server Schema in the Konfig repo`](https://github.com/KusionStack/konfig/blob/main/base/pkg/kusion_models/kube/frontend/server.k). - -##### 3.2.3 Migrate The Configuration Data - -You can develop your custom scripts to migrate your configuration data automatically. KCL will later provide writing scaffolding and writing guidelines for this script. - -### 4. Migrate From Kubernetes CRD - -If you developed CRDs, you can generate the KCL version of the CRD schemas and declare CRs based on that. - -- Generate KCL Schema from CRD - - ``` - kcl-openapi generate model --crd --skip-validation -f - ``` - -- Define CR based on CRDs in KCL - - You can initialize the CRD schema to define a CR, or further, you can use the generated schema as a backend model and design a frontend interface for users to initialize. The practice is similar to what `KCL Models` does on Kubernetes built-in models. - -## Summary - -This section provides a quick start guide for using KCL with OpenAPI and Custom Resource Definitions (CRD). KCL also supports OpenAPI through the `kcl-openapi tool`, which maps OpenAPI specifications to KCL language features. diff --git a/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md b/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md deleted file mode 100644 index ea65e2f1..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md +++ /dev/null @@ -1,249 +0,0 @@ ---- -title: "Generate Kubernetes Manifests" -sidebar_position: 2 ---- - -## Introduction - -When we manage the Kubernetes resources, we often maintain it by hand, or use Helm and Kustomize tools to maintain our YAML configurations or configuration templates, and then apply the resources to the cluster through kubectl tools. However, as a "YAML engineer", maintaining YAML configuration every day is undoubtedly trivial and boring, and prone to errors. For example as follows: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: ... # Omit -spec: - selector: - matchlabels: - cell: RZ00A - replicas: 2 - template: - metadata: ... # Omit - spec: - tolerations: - - effect: NoSchedules - key: is-over-quota - operator: Equal - value: 'true' - containers: - - name: test-app - image: images.example/app:v1 # Wrong ident - resources: - limits: - cpu: 2 # Wrong type. The type of cpu should be str - memory: 4Gi - # Field missing: ephemeral-storage - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: is-over-quota - operator: In - values: - - 'true' -``` - -- The structured data in YAML is untyped and lacks validation methods, so the validity of all data cannot be checked immediately. -- YAML has poor programming ability. It is easy to write incorrect indents and has no common code organization methods such as logical judgment. It is easy to write a large number of repeated configurations and difficult to maintain. -- The design of Kubernetes is complex, and it is difficult for users to understand all the details, such as the `toleration` and `affinity` fields in the above configuration. If users do not understand the scheduling logic, it may be wrongly omitted or superfluous added. - -Therefore, KCL expects to solve the following problems in Kubernetes YAML resource management: - -- Use **production level high-performance programming language** to **write code** to improve the flexibility of configuration, such as conditional statements, loops, functions, package management and other features to improve the ability of configuration reuse. -- Improve the ability of **configuration semantic verification** at the code level, such as optional/required fields, types, ranges, and other configuration checks. -- Provide **the ability to write, combine and abstract configuration blocks**, such as structure definition, structure inheritance, constraint definition, etc. - -## Prerequisite - -First, you can visit the [KCL Quick Start](/docs/user_docs/getting-started/kcl-quick-start) to download and install KCL according to the instructions, and then prepare a [Kubernetes](https://kubernetes.io/) environment. - -## Quick Start - -### 1. Generate Kubernetes Resource - -We can write the following KCL code and name it `main.k`. KCL is inspired by Python. Its basic syntax is very close to Python, which is easy to learn. The configuration mode is simple, `k [: T] = v`, where `k` denotes the configured attribute name, `v` denotes the configured attribute value and `: T` denotes an optional type annotation. - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -In the above KCL code, we declare the `apiVersion`, `kind`, `metadata`, `spec` and other variables of a Kubernetes `Deployment` resource, and assign the corresponding contents respectively. In particular, we will assign `metadata.labels` fields are reused in `spec.selector.matchLabels` and `spec.template.metadata.labels` field. It can be seen that, compared with YAML, the data structure defined by KCL is more compact, and configuration reuse can be realized by defining local variables. - -We can get a Kubernetes YAML file by executing the following command line - -```bash -kcl main.k -``` - -The output is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -Of course, we can use KCL together with kubectl and other tools. Let's execute the following commands and see the result: - -```shell -kcl main.k | kubectl apply -f - -``` - -The output is - -```shell -deployment.apps/nginx-deployment configured -``` - -It can be seen from the command line that it is completely consistent with the deployment experience of using YAML configuration and kubectl application directly. - -Check the deployment status through kubectl - -```shell -kubectl get deploy -``` - -The output is - -```shell -NAME READY UP-TO-DATE AVAILABLE AGE -nginx-deployment 3/3 3 3 15s -``` - -### 2. Write Code to Manage Kubernetes resources - -When publishing Kubernetes resources, we often encounter scenarios where configuration parameters need to be dynamically specified. For example, different environments need to set different `image` field values to generate resources in different environments. For this scenario, we can dynamically receive external parameters through KCL conditional statements and `option` functions. Based on the above example, we can adjust the configuration parameters according to different environments. For example, for the following code, we wrote a conditional statement and entered a dynamic parameter named `env`. - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" if option("env") == "prod" else "${metadata.name}:latest" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -Use the KCL command line `-D` flag to receive an external dynamic parameter: - -```bash -kcl main.k -D env=prod -``` - -The output is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -The `image=metadata.name+": 1.14.2" if option ("env")=="prod" else metadata.name + ": latest"` in the above code snippet means that when the value of the dynamic parameter `env` is set to `prod`, the value of the image field is `nginx: 1.14.2`; otherwise, it is' nginx: latest'. Therefore, we can set env to different values as required to obtain Kubernetes resources with different contents. - -KCL also supports maintaining the dynamic parameters of the option function in the configuration file, such as writing the `kcl.yaml` file. - -```yaml -kcl_options: - - key: env - value: prod -``` - -The same YAML output can be obtained by using the following command line to simplify the input process of KCL dynamic parameters. - -```bash -kcl main.k -Y kcl.yaml -``` - -The output is: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## Summary - -KCL can be used to generate and manage Kubernetes resources, addressing the limitations of managing YAML configurations, such as a lack of validation methods and poor programming capabilities. It can also dynamically receive external parameters through conditional statements and option functions, allowing configuration parameters to be adjusted according to different environments. In addition, KCL can be used in conjunction with other tools such as kubectl to apply configuration to the cluster. diff --git a/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md b/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md deleted file mode 100644 index 17918b29..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: "Kubectl KCL Plugin" -sidebar_position: 1 ---- - -## Introduction - -[Kubectl](https://kubernetes.io/docs/reference/kubectl/) is a command line tool for communicating with a Kubernetes cluster's control plane, using the Kubernetes API. You can use the `Kubectl-KCL-Plugin` to - -- Edit the YAML configuration in a hook way to separate data and logic for the Kubernetes manifests management. -- For multi-environment and multi-tenant scenarios, you can maintain these configurations gracefully rather than simply copy and paste. -- Validate all KRM resources using the KCL schema. - -## Prerequisites - -- Install [Kubectl](https://github.com/kubernetes/kubectl) -- Install [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=krm-kcl` only to `Deployment` resources in the helm chart. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/kubectl-kcl.git/ -cd ./kubectl-kcl/examples/ -``` - -### 2. Test and Run - -Run the KCL code via the `Kubectl KCL Plugin`. - -```bash -kubectl kcl run -f ./kcl-run.yaml -``` - -The output yaml is - -```yaml -apiVersion: config.kubernetes.io/v1 -kind: ResourceList -items: - - apiVersion: apps/v1 - kind: Deployment - metadata: - annotations: - managed-by: krm-kcl - labels: - app: nginx - name: nginx-deployment - spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - image: "nginx:1.14.2" - name: nginx - ports: - - containerPort: 80 - - apiVersion: v1 - kind: Service - metadata: - name: test - spec: - ports: - - port: 80 - protocol: TCP - targetPort: 9376 - selector: - app: MyApp -functionConfig: - # kcl-fn-config.yaml - apiVersion: krm.kcl.dev/v1alpha1 - kind: KCLRun - metadata: - # EDIT THE SOURCE! - # This should be your KCL code which preloads the `ResourceList` to `option("resource_list") - spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "krm-kcl"}} for resource in option("resource_list").items] -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) diff --git a/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md b/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md deleted file mode 100644 index 01897f37..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: "Helm KCL Plugin" -sidebar_position: 2 ---- - -## Introduction - -[Helm](https://github.com/helm/helm) is a tool for managing Charts. Charts are packages of pre-configured Kubernetes resources. You can use the `Helm-KCL-Plugin` to - -- Edit the helm charts in a hook way to separate data and logic for the Kubernetes manifests management. -- For multi-environment and multi-tenant scenarios, you can maintain these configurations gracefully rather than simply copy and paste. -- Validate all KRM resources using the KCL schema. - -## Prerequisites - -- Install [Helm](https://github.com/helm/helm) -- Install [Helm KCL Plugin](https://github.com/kcl-lang/helm-kcl) - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=helm-kcl-plugin` only to `Deployment` resources in the helm chart. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/helm-kcl.git/ -cd ./helm-kcl/examples/workload-charts-with-kcl -``` - -### 2. Test and Run - -Run the KCL code via the `Helm KCL Plugin`. - -```bash -helm kcl template --file ./kcl-run.yaml -``` - -The output yaml is - -```yaml -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: workload - app.kubernetes.io/version: 0.1.0 - helm.sh/chart: workload-0.1.0 - name: workload -spec: - ports: - - name: www - port: 80 - protocol: TCP - targetPort: 80 - selector: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - type: ClusterIP ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: workload - app.kubernetes.io/version: 0.1.0 - helm.sh/chart: workload-0.1.0 - name: workload - annotations: - managed-by: helm-kcl-plugin -spec: - selector: - matchLabels: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - template: - metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - spec: - containers: - - image: nginx:alpine - name: frontend -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Helm KCL Plugin](https://github.com/kcl-lang/helm-kcl) diff --git a/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md b/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md deleted file mode 100644 index ae0c7a07..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: "Kustomize KCL Plugin" -sidebar_position: 3 ---- - -## Introduction - -[Kustomize](https://github.com/kubernetes-sigs/kustomize) lets you customize raw, template-free YAML files for multiple purposes, leaving the original YAML untouched and usable as is. - -KCL can be used to create functions to mutate and/or validate the YAML Kubernetes Resource Model (KRM) input/output format, and we provide Kustomize KCL functions to simplify the function authoring process. - -## Prerequisites - -- Install [kustomize](https://github.com/kubernetes-sigs/kustomize) -- Install [Docker](https://www.docker.com/) - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=kustomize-kcl` only to Deployment resources. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/kustomize-kcl.git -cd ./kustomize-kcl/examples/set-annotation/ -``` - -### 2. Test and Run - -```bash -kustomize fn run ./local-resource/ --dry-run -``` - -The output YAML is - -```yaml -apiVersion: krm.kcl.dev/v1alpha1 -kind: KCLRun -metadata: - name: set-annotation - annotations: - config.kubernetes.io/function: | - container: - image: docker.io/kcllang/kustomize-kcl:v0.2.0 - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml -# EDIT THE SOURCE! -# This should be your KCL code which preloads the `ResourceList` to `option("resource_list") -spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "kustomize-kcl"}} for resource in option("resource_list").items] ---- -apiVersion: v1 -kind: Service -metadata: - name: test - annotations: - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml -spec: - selector: - app: MyApp - ports: - - protocol: TCP - port: 80 - targetPort: 9376 ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx - annotations: - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml - managed-by: kustomize-kcl -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Kustomize KCL Plugin](https://github.com/kcl-lang/kustomize-kcl) diff --git a/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md b/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md deleted file mode 100644 index 3a029bdd..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: "KPT KCL SDK" -sidebar_position: 4 ---- - -## Introduction - -[kpt](https://github.com/GoogleContainerTools/kpt) is a package-centric toolchain that enables a configuration authoring, automation, and delivery experience, which simplifies managing Kubernetes platforms and KRM-driven infrastructure (e.g., Config Connector, Crossplane) at scale by manipulating declarative Configuration as Data for automating Kubernetes configuration editing including transforming and validating. - -KCL can be used to create functions to transform and/or validate the YAML Kubernetes Resource Model (KRM) input/output format, but we provide KPT KCL SDKs to simplify the function authoring process. - -## Prerequisites - -- Install [kpt](https://github.com/GoogleContainerTools/kpt) -- Install [Docker](https://www.docker.com/) - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=kpt` only to Deployment resources. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/kpt-kcl-sdk.git/ -cd ./kpt-kcl-sdk/get-started/set-annotation -``` - -### 2. Show the KRM - -```bash -kpt pkg tree -``` - -The output is - -```bash -set-annotation -├── [kcl-fn-config.yaml] KCLRun set-annotation -└── data - ├── [resources.yaml] Deployment nginx-deployment - └── [resources.yaml] Service test -``` - -### 3. Show and Update the KCL `FunctionConfig` - -```bash -cat ./kcl-fn-config.yaml -``` - -The output is - -```yaml -# kcl-fn-config.yaml -apiVersion: krm.kcl.dev/v1alpha1 -kind: KCLRun -metadata: # kpt-merge: /set-annotation - name: set-annotation -spec: - # EDIT THE SOURCE! - # This should be your KCL code which preloads the `ResourceList` to `option("resource_list")` - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "kpt"}} for resource in option("resource_list").items] -``` - -### 4. Test and Run - -Run the KCL code via kpt - -```bash -kpt fn eval ./data -i docker.io/kcllang/kpt-kcl:v0.2.0 --fn-config kcl-fn-config.yaml - -# Verify that the annotation is added to the `Deployment` resource and the other resource `Service` -# does not have this annotation. -cat ./data/resources.yaml | grep annotations -A1 -B0 -``` - -The output is - -```bash - annotations: - managed-by: kpt -``` - -It can be seen that we have indeed added the annotation `managed-by=kpt`. - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [KPT KCL SDK](https://github.com/kcl-lang/kpt-kcl-sdk) diff --git a/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md b/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md deleted file mode 100644 index 03d34ec8..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: "Helmfile KCL Plugin" -sidebar_position: 5 ---- - -## Introduction - -[Helmfile](https://github.com/helmfile/helmfile) is a declarative spec for deploying helm charts. It lets you... - -- Keep a directory of chart value files and maintain changes in version control. -- Apply CI/CD to configuration changes. -- Periodically sync to avoid skew in environments. - -KCL can be used to create functions to mutate and/or validate the YAML Kubernetes Resource Model (KRM) input/output format, and we provide Kustomize KCL functions to simplify the function authoring process. - -## Prerequisites - -- Install [helmfile](https://github.com/helmfile/helmfile) -- Prepare a Kubernetes cluster - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=helmfile-kcl` only to Deployment resources. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/helmfile-kcl.git -cd ./helmfile-kcl/examples/hello-world/ -``` - -We can execute the command to show config - -```bash -cat helmfile.yaml -``` - -The output is - -```yaml -repositories: - - name: prometheus-community - url: https://prometheus-community.github.io/helm-charts - -releases: - - name: prom-norbac-ubuntu - namespace: prometheus - chart: prometheus-community/prometheus - set: - - name: rbac.create - value: false - transformers: - # Use KCL Plugin to mutate or validate Kubernetes manifests. - - apiVersion: krm.kcl.dev/v1alpha1 - kind: KCLRun - metadata: - name: "set-annotation" - annotations: - config.kubernetes.io/function: | - container: - image: docker.io/kcllang/kustomize-kcl:v0.2.0 - spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "helmfile-kcl"}} for resource in option("resource_list").items] -``` - -In the above config, we use a `KCLRun` plugin to assign the `transfomer` field. This means that we will add annotations to all deployment resources in the prometheus helm chart. - -### 2. Test and Run - -Firstly, init the helmfile tool. - -```bash -helmfile init -``` - -The output may looks like this: - -```bash -The helm plugin helm-git is not installed, do you need to install it [y/n]: y -Install helm plugin helm-git -Installed plugin: helm-git - -helmfile initialization completed! -... -``` - -Then apply the configuration. - -```bash -helmfile apply -``` - -The output is - -```bash -Adding repo prometheus-community https://prometheus-community.github.io/helm-charts -"prometheus-community" has been added to your repositories - -... -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [KRM KCL Spec](https://github.com/kcl-lang/krm-kcl) diff --git a/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json b/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json deleted file mode 100644 index 6e90c03c..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Mutate or Validate Kubernetes Manifests", - "position": 3 -} diff --git a/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/_category_.json b/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/_category_.json deleted file mode 100644 index 42681f2b..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Kubernetes", - "position": 9 -} diff --git a/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/index.md b/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/index.md deleted file mode 100644 index 8d6340de..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/index.md +++ /dev/null @@ -1 +0,0 @@ -# Kubernetes diff --git a/versioned_docs/version-0.5.5/user_docs/guides/working-with-konfig/1-overview.md b/versioned_docs/version-0.5.5/user_docs/guides/working-with-konfig/1-overview.md deleted file mode 100644 index aca119a1..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/working-with-konfig/1-overview.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -id: overview -sidebar_label: Overview ---- - -# Konfig Overview - -In KCL, it is recommended to uniformly manage all configurations and model libraries in the way of **configuration library**, that is, to store not only KCL definitions of the abstract model itself, but also various types of configurations, such as application operation and maintenance configuration, policy, etc. The configuration is recommended to be hosted in various VCS systems to facilitate configuration rollback and drift check. The best practice code of the configuration repository is Konfig, and the repository is hosted in [Github](https://github.com/KusionStack/konfig)。 - -⚡ The Konfig repository mainly includes: - -- KCL module declaration file (kcl.mod) -- KCL domain model libraries (Kubernetes, Prometheus, etc.) -- Directories of various configurations (application operation and maintenance configuration, etc) -- Configuration build and test scripts (Makefile, Github CI file, etc.) - -The reason for using a unified warehouse to manage all KCL configuration codes is that different code packages have different R&D entities, which will lead to package management and version management problems. When the business configuration code and basic configuration code are stored in a unified warehouse, the version dependency management between codes will be relatively simple. By locating the directory and file of the unique code base, the configuration code can be managed uniformly for easy search, modification and maintenance. - -The following is the architecture of Konfig: - -![](/img/docs/user_docs/guides/konfig/konfig-arch.png) - -Konfig provides users with an out-of-the-box and highly abstract configuration interface. The original simple starting point of the model library is to improve the efficiency and experience of Kubernetes YAML users. We hope to simplify the writing of user-side configuration code by abstracting and encapsulating the model with more complex code into a unified model. Konfig consists of the following parts: - -- **Core model**: - - **Front-end model**: The front-end model is the "user interface", which contains all configurable attributes exposed to users on the platform side. Some repetitive and deducible configurations are omitted, and essential attributes are abstracted and exposed to users. It has user-friendly features, such as `server.k`. - - **Back-end model**: The back-end model is "model implementation", which is the model that makes the properties of the front-end model effective. It mainly contains the rendering logic of the front-end model instance. The back-end model can use KCL to write validation, logic judgment, code fragment reuse and other code to improve the reusability and robustness of the configuration code, and is not sensitive to users, such as `server_backend.k`. -- **Domain model**: It is a model that does not contain any implementation logic and abstraction. It is often generated by tool transformation and does not need to be modified. It corresponds to the real effective YAML attribute one by one. The domain model needs to be further abstracted and is generally not directly used by users. For example, `kusion_kubernetes` is the domain model library of Kubernetes scenarios. - -In addition, the core model simplifies the configuration code of front-end users through two layers of abstraction: the front-end model and the back-end model. The domain model is automatically generated through the KCL OpenAPI. diff --git a/versioned_docs/version-0.5.5/user_docs/guides/working-with-konfig/2-structure.md b/versioned_docs/version-0.5.5/user_docs/guides/working-with-konfig/2-structure.md deleted file mode 100644 index 64e74b1d..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/working-with-konfig/2-structure.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -id: structure -sidebar_label: Structure ---- - -# Konfig Structure - -This article mainly explains the directory and code structure of the Konfig repository. - -## Overview - -```bash -. -├── .github # CI Scripts -├── Makefile # Building and testing scripts -├── README.md # Documents -├── appops # Application configuration. This folder is used to place KCL operation and maintenance configuration of all applications -│ ├── clickhouse-operator -│ ├── code-city -│ ├── guestbook -│ ├── http-echo -│ └── nginx-example -├── base # Models -│ ├── examples # Examples -│ │ ├── monitoring # Monitoring example -│ │ ├── native # Kubernetes resource example -│ │ ├── provider # Basic resource configuration example such as Terraform resource -│ │ └── server # Server example. -│ └── pkg -│ ├── kusion_kubernetes # Kubernetes domain models -│ ├── kusion_models # Core models -│ ├── kusion_prometheus # Prometheus domain models -│ └── kusion_provider # Basic resource models such as Terraform resource -└── kcl.mod # The KCL module declaration file -``` - -## Core Model - -The core model library is generally named `kusion_models`, mainly including front-end model, back-end model, renderer, etc. The directory structure is: - -```bash -├── commons # Common models -├── kube # Cloud-native resource core models -│ ├── backend # Back-end models -│ ├── frontend # Front-end models -│ │ ├── common # Common front-end models -│ │ ├── configmap # ConfigMap -│ │ ├── container # Container -│ │ ├── ingress # Ingress -│ │ ├── resource # Resource -│ │ ├── secret # Secret -│ │ ├── service # Service -│ │ ├── sidecar # Sidecar -│ │ ├── strategy # strategy -│ │ ├── volume # Volume -│ │ └── server.k # The `Server` model -│ ├── metadata # Kubernetes metadata -│ ├── mixins # Mixin -│ ├── render # Front-to-back-end renderers. -│ ├── templates # Data template -│ └── utils -└── metadata # Common metadata -``` - -## Project and Stack - -![](/img/docs/user_docs/concepts/project-stack.png) - -Project and Stack are logical isolation concepts used to organize the Konfig. - -### Project - -Any folder that contains the file `project.yaml` will be regarded as a Project, and the `project.yaml` is used to describe the metadata of this Project like `name` and `tenant`. Projects must have clear business semantics and must belong to a tenant. Users can map an application or an operation scenario to a Project. - -### Stack - -Like Project, any folder that contains the file `stack.yaml` will be regarded as a Stack and `stack.yaml` is used to describe the metadata of this Stack. Stack is a set of `.k` files that represents the smallest operation unit that can be configured and deployed individually. It tends to represent different stages in the CI/CD process, such as dev, gray, prod, etc. - -### Relationship between Project and Stack - -A Project contains one or more Stacks, and a Stack must belong to and can only belong to one Project. Users can interpret the meaning of Project and Stack according to their own needs and flexibly organize the Konfig structure. We provide the following example as a best practice according to our experiences: - -```bash -appops/nginx-example -├── README.md # Project readme -├── base # common configurations for all stacks -│ └── base.k -├── dev # dev stack -│ ├── ci-test # CI test configs -│ │ ├── settings.yaml # test data -│ │ └── stdout.golden.yaml # expected test result -│ ├── kcl.yaml # kcl config -│ ├── main.k -│ └── stack.yaml # Stack metadata -└── project.yaml # Project metadata -``` - -The Project represents an application and Stack represents different environments of this application, such as dev, pre, prod, etc. Common configurations can be stored in a `base` directory under this Project. diff --git a/versioned_docs/version-0.5.5/user_docs/guides/working-with-konfig/3-quick-start.md b/versioned_docs/version-0.5.5/user_docs/guides/working-with-konfig/3-quick-start.md deleted file mode 100644 index 82fa6f36..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/working-with-konfig/3-quick-start.md +++ /dev/null @@ -1,198 +0,0 @@ ---- -id: guide -sidebar_label: Quick Start ---- - -# Introduction - -This guide shows you how to use the KCL language and CLIs to complete the deployment of an application running in Kubernetes. We call the abstraction of application operation and maintenance configuration as `Server`, and its instance as `Application`. It is essentially an operation and maintenance model defined by KCL. - -In actual production, the application online generally needs to update several k8s resources: - -- Namespace -- Deployment -- Service - -This guide requires you to have a basic understanding of Kubernetes. If you are not familiar with the relevant concepts, please refer to the links below: - -- [Learn Kubernetes Basics](https://kubernetes.io/docs/tutorials/kubernetes-basics/) -- [Namespace](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/) -- [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) -- [Service](https://kubernetes.io/docs/concepts/services-networking/service/) - -## Prerequisites - -Before we start, we need to complete the following steps: - -1. Install KCL - See [Download and Install](/docs/user_docs/getting-started/install) for more details. - -2. Clone the [Konfig repo](https://github.com/KusionStack/konfig.git) - -```shell -git clone https://github.com/KusionStack/konfig.git && cd konfig -``` - -## Quick Start - -### 1. Compiling - -The programming language of the project is KCL, not JSON/YAML which Kubernetes recognizes, so it needs to be compiled to get the final output. - -Enter stack dir `appops/nginx-example/dev` and compile: - -```bash -cd appops/nginx-example/dev && kcl -Y kcl.yaml -D __konfig_output_format__=raw -``` - -The output YAML is: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-exampledev - namespace: nginx-example -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - template: - metadata: - labels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - spec: - containers: - - image: nginx:1.7.8 - name: main - ports: - - containerPort: 80 - protocol: TCP - resources: - limits: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi - requests: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi ---- -apiVersion: v1 -kind: Namespace -metadata: - name: nginx-example ---- -apiVersion: v1 -kind: Service -metadata: - name: nginx-example - namespace: nginx-example -spec: - ports: - - nodePort: 30201 - port: 80 - targetPort: 80 - selector: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - type: NodePort -``` - -After compiling, we can see three resources: - -- A `Deployment` with the name `nginx-exampledev` -- A `Namespace` with the name `nginx-example` -- A `Service` with the name `nginx-example` - -The above completes the configuration and takes effect. Later, we can use the command `kubectl apply` to apply and check the actual status of resources. This guide will not elaborate. - -### 2. Modification - -The `image` attribute in the `Server` model is used to declare the application's container image. We can modify the `image` value in `base/main.k` to modify or upgrade the image: - -```diff -14c14 -< image = "nginx:1.7.8" ---- -> image = "nginx:latest" -``` - -Recompile the configuration code to obtain the modified YAML output: - -```shell -kcl -Y kcl.yaml -D __konfig_output_format__=raw -``` - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-exampledev - namespace: nginx-example -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - template: - metadata: - labels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - spec: - containers: - - image: nginx:latest - name: main - ports: - - containerPort: 80 - protocol: TCP - resources: - limits: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi - requests: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi ---- -apiVersion: v1 -kind: Namespace -metadata: - name: nginx-example ---- -apiVersion: v1 -kind: Service -metadata: - name: nginx-example - namespace: nginx-example -spec: - ports: - - nodePort: 30201 - port: 80 - targetPort: 80 - selector: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - type: NodePort -``` - -## Summary - -This document mainly introduces how to use the KCL and Konfig library to deploy a Long Running application running in Kubernetes. diff --git a/versioned_docs/version-0.5.5/user_docs/guides/working-with-konfig/4-best-practice.md b/versioned_docs/version-0.5.5/user_docs/guides/working-with-konfig/4-best-practice.md deleted file mode 100644 index ee0cc576..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/working-with-konfig/4-best-practice.md +++ /dev/null @@ -1,449 +0,0 @@ ---- -id: practice -sidebar_label: Best Practice ---- - -# Best Practice - -This document aims to explain the best practices for integrating new models into the Konfig library and designing, building and writing KCL code models. New models are generally designed and abstracted using the best practice of separating front-end and back-end models. The direct purpose of distinguishing between front-end and back-end models is to separate `"user interface"` and `"model implementation"`, achieving a user-friendly and simple configuration interface as well as automated configuration query and modification interfaces. - -## Workflow - -![](/img/docs/user_docs/guides/konfig/workflow.png) - -1. **Coding**. Use the KCL OpenAPI tool to generate KCL schemas from the Customer Resources Definitions (CRDs) or OpenAPI Swagger models. These schemas define the atomic capabilities of the platform. -1. **Abstraction**. Based on these atomic capabilities, the platform abstracts user-oriented front-end models and provides a set of templates. These front- - end models cannot work independently, and corresponding back-end models are required. These back-end models will eventually obtain an instance of the front-end model at runtime; it parses the input front-end model and converts it into Kubernetes resources. -1. **Configuration**. Developers or SREs describe the requirements of applications based on front-end models. Users can define the base and different environment configurations for different environments e.g., base, development and production and different localities. In most cases, defining configurations only requires declaring key-value pairs. For some complex scenarios, users can define the logic to generate configurations. -1. **Automation**. After defining the user's configuration, all components have been defined and are ready to be automated. The platform can compile, execute, output, modify, query, and perform other automatic works through the KCL CLI or GPL-binding APIs. Users can also deploy the KCL configuration to the Kubernetes cluster with tools. - -## Model Structure - -Just as web applications provide a friendly user interface, and user input is further inferred at the backend of the application to obtain the final data that falls into the database, similarly, using KCL for model design also follows the logic of front-end and back-end separation. In addition, when the downstream required data content changes, we only need to modify the rendering/logic of the user configuration data to the backend model, thereby avoiding large-scale modification of user configurations. - -Taking the sidecar configuration of application services as an example: - -```python -# Config user interface. -user_sidecar_feature_gates: str - -# Downstream config of processing. -sidecars = [ - { - name = "sidecar_name" # Additional template for sidecars parameters, users do not need to configure them. - feature_gates = user_sidecar_feature_gates - } -] -``` - -## Best Practices for Konfig Modeling - -### Use Single Attribute Instead of Configuration Templates - -For some backend models, the configuration attributes that need to be filled in are often large and comprehensive designs, requiring users to actively input more complex configuration templates, and the filling content of this attribute is basically the same for different users. For example, the configuration of logic shown below requires users to fill in a large amount of template data, which has a high mental cost. - -A simple best practice is to abstract such commonly used and complex templates into a simple attribute `overQuota` with the `bool` type in the front-end model, allowing users to do multiple-choice questions instead of filling in blank questions. For example, when the `overQuota` attribute is `True`, the back-end model will render this complex logic. - -- The front-end attribute `overQuota` - -```python -overQuota: bool -``` - -- The back-end YAML output: - -```yaml -spec: - template: - spec: - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: k8s/is-over-quota - operator: In - values: - - "true" -``` - -In addition, different template names can be designed according to specific business scenarios to fill in the blanks, such as designing an attribute template in the code shown below to assist users in template selection instead of directly filling in the template content. The legal template value can be `"success_ratio"` or `"service_cost"`. When the backend model extends more templates, the front-end code does not need to make any modifications, only needs to adapt the corresponding template logic in the backend model. - -```python -schema SLI: - template: str = "success_ratio" -``` - -In addition, it is recommended to avoid using complex structures directly as front-end model attributes to avoid users needing to rely on too many KCL syntax features (such as unpacking, looping, etc.) or writing many temporary variables to complete the instantiation of the structure when using the model. - -### Use Literal Type and Union Type - -In the above section, it was mentioned that a string attribute can be used to represent different template names, and further, a literal type can be used to express the optional content of the template. For example, the following improvements can be made. - -```python -schema SLI: - template: "success_ratio" | "service_cost" = "success_ratio" -``` - -The type of template is a combination of two string types, indicating that the template can only be `"success_ratio"` or `"service_cost"`. When the user fills in the values of other strings, the KCL compiler will report an error. - -In addition to using union types for literal types, KCL also supports union for complex types such as schema types. For the support of this backend **oneof** configuration, KCL has built-in composite structure union types for support. For example, we can define our own SLI front-end types for various scenarios: `CustomSliDataSource`, `PQLSLIDataSource`, and `StackSLIDataSource`. - -```python -schema CustomSLIDataSource: - customPluginUrl: str - -schema PQLSLIDataSource: - total?: str - error?: str - success?: str - cost?: str - count?: str - -schema StackSLIDataSource: - stack: str - groupBy?: str - metric?: str - -# Simplify type definitions using type aliases -type DataSource = CustomSLIDataSource | PQLSLIDataSource | StackSLIDataSource - -schema DataConfiguration: - sources: {str: DataSource} -``` - -The advantage of designing this front-end model is that the compiler can statically check that the type written by the user can only be a certain type. If the back-end model is used directly, it cannot directly obtain the mapping relationship between different types of types and the fields that need to be filled in from the model. - -In addition, the overall design of the front-end model should also consider horizontal scalability, using the union type as much as possible, fully utilizing the advantages of coding, and avoiding unnecessary large amounts of code restructuring and modification when connecting to different backend or backend models. In addition, for the factory pattern commonly used in other GPL languages, union types can also be used instead in KCL. For example, if you want to obtain a constructor of a type based on the content of a string, you can directly use union types for optimization. - -Using the factory pattern in KCL: - -```python -schema DataA: - id?: int = 1 - value?: str = "value" - -schema DataB: - name?: str = "DataB" - -_dataFactory: {str:} = { - DataA = DataA - DataB = DataB -} -dataA = _dataFactory["DataA"]() -dataB = _dataFactory["DataB"]() -``` - -Replacing the factory pattern with the KCL union type. - -```python -schema DataA: - id?: int = 1 - value?: str = "value" - -schema DataB: - name?: str = "DataB" - -# Just use the union type. -dataA: DataA | DataB = DataA() -dataB: DataA | DataB = DataB() -``` - -### Use Dict Instead of List As Much As Possible - -To make it easier to modify configurations on-site or automate queries, it is advisable to define list or array attributes as dictionary types for easy indexing. In many complex configuration scenarios, the index of a list is arbitrary and the order of elements has no impact on the configuration. Using a dictionary type instead of a list type allows for more convenient data querying and modification. For example: - -```python -schema Person: - name: str - age: int - -schema House: - persons: [Person] - -house = House { - persons = [ - Person { - name = "Alice" - age = 18 - } - Person { - name = "Bob" - age = 10 - } - ] -} -``` - -For example, in the above example, if you want to query the age of the person named `"Alice"` from the list of persons in the house, you need to loop through the list to find Alice's age. However, if you define persons as a dictionary like the following code, it not only looks more concise in code, but you can also directly retrieve Alice's age by using house.persons.Alice.age. In addition, the information of the entire configuration is complete and has no redundant information. - -```python -schema Person: - age: int - -schema House: - persons: {str: Person} # Use Dict Instead of List - -house = House { - persons = { - Alice = Person { age = 18 } - Bob = Person { age = 10 } - } -} -``` - -### Write Validation Expressions for Models - -For frontend models, it is often necessary to validate the fields filled in by users. In this case, KCL's check expressions can be used in conjunction with KCL's built-in functions/syntax/system libraries to perform field validation. For frontend model validation, it is recommended to directly write it in the frontend model definition as a prerequisite for validation, in order to avoid unexpected errors that may occur when the errors are passed to the backend model. - -Use all/any expressions and check expressions for validation - -```python -import regex - -schema ConfigMap: - name: str - data: {str:str} - configMounts?: [ConfigMount] - - check: - all k in data { - regex.match(k, r"[A-Za-z0-9_.-]*") - }, "a valid config key must consist of alphanumeric characters, '-', '_' or '.'" - -schema ConfigMount: - containerName: str - mountPath: str - subPath?: str - - check: - ":" not in mountPath, "mount path must not contain ':'" -``` - -### Use Numerical Unit Type - -Numbers with units in KCL have a built-in type of `units.NumberMultiplier`, and any arithmetic operations are not allowed. - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -x0: NumberMultiplier = 1M # Ok -x1: NumberMultiplier = x0 # Ok -x2 = x0 + x1 # Error: unsupported operand type(s) for +: 'number_multiplier(1M)' and 'number_multiplier(1M)' -``` - -We can use the `int()/float()` function and `str()` function to convert the number unit type to integer or string type, and the resulting string retains the units of the original number unit type. - -```python -a: int = int(1Ki) # 1024 -b: str = str(1Mi) # "1Mi" -``` - -The definitions related to Kubernetes Resource in Konfig can be written using numerical unit types - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -schema Resource: - cpu?: NumberMultiplier | int = 1 - memory?: NumberMultiplier = 1024Mi - disk?: NumberMultiplier = 10Gi - epchygontee?: int -``` - -### Automated Modification of Front-end Model Instances - -In KCL, automated modification of front-end model instances can be achieved through the CLI and API. For example, if we want to modify the image content of an application (Konfig Stack Path: apps/nginx example/dev) configuration, we can directly execute the following command to modify the image content. - -```python -kcl -Y kcl.yaml ci-test/settings.yaml -o ci-test/stdout.golden.yaml -d -O :appConfiguration.image=\"test-image-v1\" -``` - -For more documentation related to automation, please refer to the [Automation Documents](/docs/user_docs/guides/automation) section. - -### Use Functions - -```python -# Define a function that adds two numbers and returns the result。 -add = lambda x, y { - x + y -} -# Define a function that subs two numbers and returns the result。 -sub = lambda x, y { - x - y -} -# Call the function, pass in arguments, and obtain the return value. -result = sub(add(2, 3), 2) # The result is 3. -``` - -The output YAML is - -```yaml -result: 3 -``` - -### Use Package and Module - -Create a package called `utils.k`, define a KCL function called `add` in it, and import it into another file for use. - -- `utils.k` - -```python -# utils.k - -# Define a function that adds two numbers and returns the result。 -add = lambda x, y { - x + y -} - -# Define a function that subs two numbers and returns the result。 -sub = lambda x, y { - x - y -} -``` - -- `main.k` - -```python -# main.k -import .utils - -# Call the function, pass in arguments, and obtain the return value. -result = utils.sub(utils.add(2, 3), 2) # The result is 3. -``` - -### Simplify Logical Expressions Using Configuration - -```python -# Complex Logic, `_cpu` is a non-exported and mutable attribute. -_cpu = 256 -_priority = "1" - -if _priority == "1": - _cpu = 256 -elif _priority == "2": - _cpu = 512 -elif _priority == "3": - _cpu = 1024 -else: - _cpu = 2048 - -# Simplify Logic Expression using Config -cpuMap = { - "1" = 256 - "2" = 512 - "3" = 1024 -} -# Get cpu from the cpuMap, when not found, use the default value 2048. -cpu = cpuMap[_priority] or 2048 -``` - -The output is - -```yaml -cpuMap: - "1": 256 - "2": 512 - "3": 1024 -cpu256: 256 -cpu2048: 2048 -``` - -### Separate Logic and Data - -We can use KCL **schema**, **config**, and **lambda** to separate **data** and **logic** as much as possible. - -For example, we can write the following code (main.k). - -```python -schema Student: - """Define a `Student` schema model with documents. - - Attributes - ---------- - name : str, required - The name of the student. - id : int, required. - The id number of the student. - grade : int, required. - The grade of the student. - - Examples - -------- - s = Student { - name = "Alice" - id = 1 - grade = 80 - } - - """ - name: str - id: int - grade: int - - # Define constraints for the `Student` model. - check: - id >= 0 - 0 <= grade <= 100 - -# Student data. -students: [Student] = [ - {name = "Alice", id = 1, grade = 85} - {name = "Bob", id = 2, grade = 70} - {name = "Charlie", id = 3, grade = 90} - {name = "David", id = 4, grade = 80} - {name = "Eve", id = 5, grade = 95} -] - -# Student logic. -query_student_where_name = lambda students: [Student], name: str { - # Query the first student where name is `name` - filter s in students { - s.name == name - }?[0] -} - -alice = query_student_where_name(students, name="Alice") -bob = query_student_where_name(students, name="Bob") -``` - -The output is - -```yaml -students: - - name: Alice - id: 1 - grade: 85 - - name: Bob - id: 2 - grade: 70 - - name: Charlie - id: 3 - grade: 90 - - name: David - id: 4 - grade: 80 - - name: Eve - id: 5 - grade: 95 -alice: - name: Alice - id: 1 - grade: 85 -bob: - name: Bob - id: 2 - grade: 70 -``` - -### Add Comments for Models - -To facilitate user understanding and automatic model documentation generation, it is necessary to write comments for the defined model. The comment content usually includes an explanation of the model, an explanation of model fields, types, default values, usage examples, and more. For detailed KCL schema code commenting guidelines and automatic model documentation generation, please refer to the [KCL Documentation Specification](/docs/tools/cli/kcl/docgen). Additionally, we can use the `kcl-doc generate` command to extract documentation from the user-specified file or directory and output it to the specified directory. - -## Backend Model - -The backend model is an "implementation model," which mainly includes the logical code to map the frontend model to the backend model. After the frontend model is written, we can use the frontend model schema to create frontend model instances, and write the corresponding backend mapping/rendering code to convert these frontend instances into the backend model. By using KCL's multi-file compilation and `Schema.instances()` function, the frontend and backend code can be highly decoupled, so that users only need to focus on frontend configuration without being aware of the complex validation and logical code of the model. diff --git a/versioned_docs/version-0.5.5/user_docs/guides/working-with-konfig/_category_.json b/versioned_docs/version-0.5.5/user_docs/guides/working-with-konfig/_category_.json deleted file mode 100644 index a71426f9..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/working-with-konfig/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Konfig", - "position": 10 -} diff --git a/versioned_docs/version-0.5.5/user_docs/guides/working-with-kusion/_category_.json b/versioned_docs/version-0.5.5/user_docs/guides/working-with-kusion/_category_.json deleted file mode 100644 index 9f914498..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/working-with-kusion/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KusionStack", - "position": 15 -} diff --git a/versioned_docs/version-0.5.5/user_docs/guides/working-with-kusion/index.md b/versioned_docs/version-0.5.5/user_docs/guides/working-with-kusion/index.md deleted file mode 100644 index 2565ad03..00000000 --- a/versioned_docs/version-0.5.5/user_docs/guides/working-with-kusion/index.md +++ /dev/null @@ -1,15 +0,0 @@ -# KusionStack - -**KusionStack is an open-source cloud-native programmable technology stack!** - -KusionStack is a highly flexible programmable technology stack to enable unified application delivery and operation, inspired by the word Fusion, which aims to help enterprises build an application-centric configuration management plane and DevOps ecosystem. - -1. Fusion of hybrid scenarios of **private cloud**, **hybrid cloud**, and **multi-cloud** -2. Fusion of hybrid platform technologies of **cloud-native** and a variety of other platform technologies -3. Fusion of enterprise-level demands of **multi-project**, **multi-team**, **multi-role**, **multi-tenant**, and **multi-environment** - -Based on the concept of Platform as Code, developers can quickly unify the full configuration schemas, constraints, policies and configs across the application life cycle, work with the **hybrid technologies and cloud environment**, go through the **end-to-end workflow** from programming to launching, and truly achieve **write once, deliver anywhere**. - -![](/img/docs/user_docs/intro/kusion-stack-1.png) - -More documents and use cases at [https://kusionstack.io/](https://kusionstack.io/) diff --git a/versioned_docs/version-0.5.5/user_docs/support/_category_.json b/versioned_docs/version-0.5.5/user_docs/support/_category_.json deleted file mode 100644 index 60548d80..00000000 --- a/versioned_docs/version-0.5.5/user_docs/support/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "FAQ", - "position": 6 -} diff --git a/versioned_docs/version-0.5.5/user_docs/support/faq-cli.md b/versioned_docs/version-0.5.5/user_docs/support/faq-cli.md deleted file mode 100644 index ab012a34..00000000 --- a/versioned_docs/version-0.5.5/user_docs/support/faq-cli.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Command Line Tool - -## 1. What is the function of the `settings.yaml` in the application directory of the Konfig? - -The `settings.yaml` in KCL indicates the configuration file of the KCL command line tool. You can put the compiled configuration into it, such as the file to be compiled, the option dynamic parameter that needs to be input(`-d`), whether to ignore the null value(`-n`) and other configurations. - -For example, for the following arguments: - -```shell -kcl main.k -D key=value -n -r -``` - -It can be replaced by the following command line arguments and `settings.yaml` - -```shell -kcl -Y settings.yaml -``` - -settings.yaml - -```yaml -kcl_cli_configs: - files: - - main.k - disable_none: true - strict_range_check: true -kcl_options: - - key: key - value: value -``` - -- `kcl_cli_configs` indicates configurable compilation arguments, `file` indicates the KCL file used for compilation,`disable_none` indicates whether to use `-n`, `strict_range_check` indicates whether to use `-r`. -- `kcl_options` indicates dynamic options that can be configured, `key` indicates option name, `value` indicates option value - -Note: The file name does not need to be `settings.yaml`, but the configuration in it must meet the requirements. - -### 2. How to input dynamic options? How to get dynamic options in code? - -KCL supports multiple ways to input dynamic options - -- `-D`: Use the command line argument `-D` to input dynamic options. It supports basic data types str/int/float/bool and structured data types list/dict - -```shell -kcl main.k -D env-type=TEST -D deploy-topology='[{"cluster":"my-cluster","idc":"my-idc","replicas":2,"workspace":"my-idc","zone":"my-zone"}]' -``` - -- `-Y`: Use the command line argument `-Y` to input dynamic options by configuration file: - -```yaml -kcl_options: - - key: env-type - value: TEST - - key: deploy-topology - value: - - cluster: my-cluster - idc: my-idc - replicas: 2 - workspace: my-workspace - zone: my-zone -``` - -Use the built-in function `option()` to get it: - -```python -env = option("env-type") -deploy_topology = option("deploy-topology") -``` - -Output: - -```yaml -env: TEST -deploy_topology: - - cluster: my-cluster - idc: my-idc - replicas: 2 - workspace: my-workspace - zone: my-zone -``` - -### 3. How to compile multiple files? - -- Input multiple files in the command line: - -```shell -kcl file1.k file2.k file3.k -``` - -- Set multiple files in configuration file and use command line argument `-Y`: - -settings.yaml - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - - file3.k -``` - -```shell -kcl -Y settings.yaml -``` diff --git a/versioned_docs/version-0.5.5/user_docs/support/faq-install.md b/versioned_docs/version-0.5.5/user_docs/support/faq-install.md deleted file mode 100644 index 37100c09..00000000 --- a/versioned_docs/version-0.5.5/user_docs/support/faq-install.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Installation Troubleshooting - -## MacOS prompts that 'kcl' cannot be opened because Apple cannot check if it contains malicious software - -MacOS prompts that 'kcl' cannot be opened because Apple cannot check if it contains malicious software. This issue is due to the Gatekeeper security feature in the macOS system preventing the application from running. To solve this issue, follow these steps: - -Open 'System Preferences' and click 'Security and Privacy'. In the "General" tab, you will see a message: '"kcl" cannot be opened'. Click 'Open still'. Alternatively, you can click 'Open any method' to open your application. (You may need to use administrator privileges to open the application.) - -If you don't want to perform these steps every time you open an application, you can add the application to the whitelist to run without being blocked. To add your application to the whitelist: - -Open the terminal and run the following command: - -```shell -xattr -rd com.apple.quarantine /path/to/kcl -``` - -Where `/path/to/kcl` is the complete path of the kcl application. After running the command, the application will be added to the whitelist and Gatekeeper will no longer prevent it from running. - -## program not found or run linker failed error on Windows/Linux/MacOS - -Please ensure that the following dependencies are in your PATH: - -- `clang` for MacOS -- `gcc` for Linux -- `cl.exe` for Windows, which can be obtained by installing MSVC diff --git a/versioned_docs/version-0.5.5/user_docs/support/faq-kcl.md b/versioned_docs/version-0.5.5/user_docs/support/faq-kcl.md deleted file mode 100644 index 860dd15b..00000000 --- a/versioned_docs/version-0.5.5/user_docs/support/faq-kcl.md +++ /dev/null @@ -1,2341 +0,0 @@ ---- -sidebar_position: 2 ---- - -# KCL - -## 1. How to write a simple key-value pair configuration with KCL - -Create a file named `config.k` - -```python -cpu = 256 -memory = 512 -image = "nginx:1.14.2" -service = "my-service" -``` - -In the above KCL code, `cpu` and `memory` are defined to be declared as integer types, and their values are `256` and `512`, while `image` and `service` are string types, their values are `image` and `service`. - -Use the following command to compile the above KCL file into YAML for output - -``` -kcl config.k -``` - -The output YAML is - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -If we want to output the YAML content to a file such as `config.yaml`, we can add the `-o|--output` CLI argument: - -``` -kcl config.k -o config.yaml -``` - -## 2. What are the basic data types in KCL? - -KCL's current basic data types and values include: - -- Integer type `int` - - Examples: decimal positive integer `1`, decimal negative integer `-1`, hexadecimal integer `0x10`, octal integer `0o10`, binary integer `0b10` -- float type `float` - - Examples: positive float `1.10`, `1.0`, negative float `-35.59`, `-90.`, scientific notation float `32.3e+18`, `70.2E-12` -- boolean type `bool` - - Example: true value `True`, false value `False` -- String type `str` - marked with `'`, `"` - - Example: double quoted string `"string"`, `"""string"""`, single quoted string `'string'`, `'''string'''` -- List type `list` - marked with `[`, `]` - - Example: empty list `[]`, string list `["string1", "string2", "string3"]` -- Dictionary type `dict` - marked with `{`, `}` - - Example: empty dictionary `{}`, dictionary whose keys and values ​​are all strings `{"key1": "value1", "key2": "value2"}` -- Structure type `schema` - defined with the keyword `schema` -- Null value type `None` - used to indicate that the value of a variable is null, corresponding to the `null` value of the output YAML -- Undefined value type `Undefined` - used to indicate that a variable has not been assigned a value, and a variable with a value of `Undefined` will not be output to YAML - -```python -schema Person: - name: str - age: int - -alice = Person { - name = "Alice" - age = 18 -} -bob = Person { - name = "Bob" - age = 10 -} -``` - -> Note: All KCL variables can be assigned the null value `None` and the undefined value `Undefined`. - -## 3. What do some KCL variable names prefixed with `_` underscore mean? What's the difference between without the `_` underscore prefix? In what scenarios are they suitable for use? - -A variable with an underscore prefix in KCL represents a **hidden**, **mutable** variable, **hidden** means a variable with an underscore prefix will not be output to YAML, and **mutable** means that a variable with an underscore prefix can be repeatedly assigned multiple times, and a variable without an underscore prefix is immutable after being assigned. - -```python -name = 'Foo' # Exported and immutable variable -name = 'Bar' # Error: An exported variable can only be assigned a value once -``` - -```python -_name = 'Foo' # Hidden and mutable variable -_name = 'Bar' - -schema Person: - _name: str # hidden and mutable -``` - -## 4. How to add elements to a dict? - -We can use the union operator `|` or the dict unpacking operator `**` to add elements into a dict, and we can use `in` and `not in` operators to determine whether the dict variable contains a certain key. - -```python -_left = {key: {key1 = "value1"}, intKey = 1} # Note: `=` denotes override the value. -_right = {key: {key2 = "value2"}, intKey = 2} -dataUnion = _left | _right # {"key": {"key1": "value1", "key2": "value2"}, "intKey": 2} -dataUnpack = {**_left, **_right} # {"key": {"key1": "value1", "key2": "value2"}, "intKey": 2} -``` - -The output YAML is - -```yaml -dataUnion: - key: - key1: value1 - key2: value2 - intKey: 2 -dataUnpack: - key: - key1: value1 - key2: value2 - intKey: 2 -``` - -It is also possible to add key-value pair to a dict using the `string interpolation` or the string `format` method. - -```python -dictKey1 = "key1" -dictKey2 = "key2" -data = { - "${dictKey1}" = "value1" - "{}".format(dictKey2) = "value2" -} -``` - -The output YAML is - -```yaml -dictKey1: key1 -dictKey2: key2 -data: - key1: value1 - key2: value2 -``` - -## 5. How to modify elements in dict? - -We can use the union operator `|`, or the unpacking operator `**` to modify the elements in the dict - -```python -_data = {key = "value"} # {"key": "value"} -_data = _data | {key = "override_value1"} # {"key": "override_value1"} -_data = {**_data, **{key = "override_value2"}} # {"key": "override_value2"} -``` - -If we want to delete a value with a key of `key` in the dict, we can use the unpacking operator `**{key = Undefined}` or the merge operator `| {key = Undefined}` to overwrite, the value of the key is Undefined after overwriting, and no YAML output will be done. - -## 6. How to add elements to list? - -There are two ways to add elements to a list: - -- Use `+`, `+=` and slice to concatenate list variables to add elements to the list - -```python -_args = ["a", "b", "c"] -_args += ["end"] # Add elements "end" to the end of the list: ["a", "b", "c", "end"] -_args = _args[:2] + ["x"] + _args[2:] # Insert element "x" at list index 2: ["a", "b", "x", "c", "end"] -_args = ["start"] + _args # Add elements "start" to the head of the list: ["start", "a", "b", "x", "c", "end"] -``` - -- Use the `*` unpacking operator to concatenate and merge lists - -```python -_args = ["a", "b", "c"] -_args = [*_args, "end"] # Add elements "end" to the end of the list: ["a", "b", "c", "end"] -_args = ["start", *_args] # Add elements "start" to the head of the list: ["start", "a", "b", "x", "c", "end"] -``` - -> Note: When the consecutive variables are `None/Undefined`, using `+` may cause an error, then we can use the list unpacking operator `*` or use the `or` operator to take the default value of the list to avoid null values judge. - -```python -data1 = [1, 2, 3] -data2 = None -data3 = [*data1, *data2] # Ok: [1, 2, 3] -data4 = data1 + data2 or [] # OK: [1, 2, 3], We can use the `or` operator to take the default value of data2 as [], when data2 is None/Undefined, take the empty list [] for calculation. -data5 = data1 + data2 # Error: can only concatenate list (not "NoneType") to list -``` - -## 7. How to modify/delete elements in list? - -There are two ways to modify the elements in the list: - -- Use slice to directly modify the value at an index of a list - -```python -_index = 1 -_args = ["a", "b", "c"] -_args = _args[:index] + ["x"] + _args[index+1:] # Modify the element of list index 1 to "x": ["a", "x", "c"] -``` - -- Use the list comprehension to modify elements in a list - -```python -_args = ["a", "b", "c"] -_args = ["x" if a == "b" else a for a in _args] # Change the value of "b" in the list to "x": ["a", "x", "c"] -``` - -There are two ways to delete elements in a list: - -- Use the list comprehension to delete elements with the `if` condition expressions. -- Use `filter` expression to filter elements. - -For example, if we want to delete a number greater than 2 in a list `[1, 2, 3, 4, 5]`, we can write as follows: - -```python -originList = [1, 2, 3, 4, 5] -oneWayDeleteListItem = [item for item in originList if item <= 2] -anotherWayDeleteListItem = filter item in originList { - item <= 2 -} -``` - -The output YAML is - -```yaml -originList: - - 1 - - 2 - - 3 - - 4 - - 5 -oneWayDeleteListItem: - - 1 - - 2 -anotherWayDeleteListItem: - - 1 - - 2 -``` - -## 8. How to write a for loop in KCL? How to understand and use list comprehension and dict comprehension? - -KCL currently only supports functional/declarative deductive for loops. We can traverse dict and list variables as follows: - -The specific form of a list comprehension is (where `[]` are used on both sides of the comprehension): - -```txt -[expression for expr in sequence1 - if condition1 - for expr2 in sequence2 - if condition2 - for expr3 in sequence3 ... - if condition3 - for exprN in sequenceN - if conditionN] -``` - -The specific form of dict comprehension is (where `{}` are used on both sides of the comprehension): - -```txt -{expression for expr in sequence1 - if condition1 - for expr2 in sequence2 - if condition2 - for expr3 in sequence3 ... - if condition3 - for exprN in sequenceN - if conditionN} -``` - -The `if` in the above forms represents the filter condition, and the expression `expr` that satisfies the condition will be generated into a new list or dict - -List comprehension example: - -```python -_listData = [1, 2, 3, 4, 5, 6] -_listData = [l * 2 for l in _listData] # All elements in _listData are multiplied by 2: [2, 4, 6, 8, 10, 12] -_listData = [l for l in _listData if l % 4 == 0] # Filter out all elements in _listData that are divisible by 4: [4, 8, 12] -_listData = [l + 100 if l % 8 == 0 else l for l in _listData] # Traverse _listData, when the element in it is divisible by 8, add 100 to the element, otherwise keep it unchanged: [4, 108, 12] -``` - -Note the difference between the two `if`s on lines 3 and 4 in the above code: - -- The first `if` represents the filter condition of the variable `_listData` list comprehension itself, and cannot be followed by `else`. Elements that meet the conditions will be added to the list, and elements that do not meet the conditions will be removed. Besides, the process may change the length of the list. -- The second `if` represents the selection condition of the list iteration variable `l`, which means the `if-else` ternary expression, which must be followed by `else`, regardless of whether the condition is met, the resulting element is still in the list, the length of the list does not change. - -Dict comprehension example: - -```python -_dictData = {key1 = "value1", key2 = "value2"} -_dictData = {k = _dictData[k] for k in _dictData if k == "key1" and _dictData[k] == "value1"} # Filter out the elements whose key is "key1" and value is "value1" in _dictData, {"key1": "value1"} -``` - -Use comprehension to get all keys of dict: - -```python -dictData = {key1 = "value1", key2 = "value2"} -dictDataKeys = [k for k in _dictData] # ["key1", "key2"] -``` - -Use comprehension to sort a dict in ascending order by key: - -```python -dictData = {key3 = "value3", key2 = "value2", key1 = "value1"} # {'key3': 'value3', 'key2': 'value2', 'key1': 'value1'} -dictSortedData = {k = dictData[k] for k in sorted(dictData)} # {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'} -``` - -Multi-level comprehension example: - -```python -array1 = [1, 2, 3] -array2 = [4, 5, 6] -data = [a1 + a2 for a1 in array1 for a2 in array2] # [5, 6, 7, 6, 7, 8, 7, 8, 9] len(data) == len(array1) * len(array2) -``` - -Double variable loop (list comprehension supports index iteration of list and value iteration of dict, which can simplify the code writing of list/dict iteration process): - -- list - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use _ to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -- dict - -```python -data = {key1 = "value1", key2 = "value2"} -# Single variable loop -dataKeys1 = [k for k in data] # ["key1", "key2"] -dataValues1 = [data[k] for k in data] # ["value1", "value2"] -# Double variable loop -dataKeys2 = [k for k, v in data] # ["key1", "key2"] -dataValues2 = [v for k, v in data] # ["value1", "value2"] -dataFilter = {k = v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use _ to ignore loop variables -dataKeys3 = [k for k, _ in data] # ["key1", "key2"] -dataValues3 = [v for _, v in data] # ["value1", "value2"] -``` - -## 9. How to write an if conditional statement? - -KCL supports two ways to write if conditional statements: - -- if-elif-else block statement, where both elif and else blocks can be omitted, and the elif block can be used multiple times - -```python -success = True -_result = "failed" -if success: - _result = "success" -``` - -```python -success = True -if success: - _result = "success" -else: - _result = "failed" -``` - -```python -_result = 0 -if condition == "one": - _result = 1 -elif condition == "two": - _result = 2 -elif condition == "three": - _result = 3 -else: - _result = 4 -``` - -- Conditional expression ` if else `, similar to ` ? : ` ternary expression in C language - -```python -success = True -_result = "success" if success else "failed" -``` - -> Note: When writing an if-elif-else block statement, pay attention to the colon `:` after the if condition and keep the indentation consistent. - -In addition, conditional expressions can also be written directly in a list or dict (the difference is that the value to be written in the if expression written in the structure is not a statement): - -- list - -```python -env = "prod" -data = [ - "env_value" - ":" - if env == "prod": - "prod" # Write values that need to be added to data, not statements - else: - "other_prod" -] # ["env_value", ":", "prod"] -``` - -- dict - -```python -env = "prod" -config = { - if env == "prod": - MY_PROD_ENV = "prod_value" # Write key-value pairs that need to be added to config, not statements - else: - OTHER_ENV = "other_value" -} # {"MY_PROD_ENV": "prod_value"} -``` - -## 10. How to express logical operations such as "and" "or" "not"? - -In KCL, use `and` for "logical and", use `or` for "logical or", use `not` for "not", which is similar to `&&`, `||` and `~` semantic in C language. - -```python -done = True -col == 0 -if done and (col == 0 or col == 3): - ok = 1 -``` - -For "bitwise AND", "bitwise OR" and "bitwise XOR" of integers, we can use `&`, `|` and `^` operators in KCL, which is similar to `&`, `|` and `^` semantic in C language. - -```python -value = 0x22 -bitmask = 0x0f - -assert (value & bitmask) == 0x02 -assert (value & ~bitmask) == 0x20 -assert (value | bitmask) == 0x2f -assert (value ^ bitmask) == 0x2d -``` - -When we need to write a pattern such as `A if A else B`, we can use `A or B` to simplify, such as the following code: - -```python -value = [0] -default = [1] -x0 = value if value else default -x1 = value or default # Use `value or default` instead of `value if value else default` -``` - -## 11. How to judge whether a variable is None/Undefined, and whether a string/dict/list is empty? - -Please note that `False`, `None`, `Undefined`, number `0`, empty list `[]`, empty dictionary `{}` and empty string `""`, `''`, `""""""`, `''''''` in the conditional expression, are all treated as `false` expressions. - -For example, when judging a string variable `strData` is neither `None/Undefined` nor an empty string (string length is greater than 0), we can simply use the following expression: - -```python -strData = "value" -if strData: - isEmptyStr = False -``` - -Empty dictionary and empty list judgment examples: - -```python -_emptyList = [] -_emptyDict = {} -isEmptyList = False if _emptyList else True -isEmptyDict = False if _emptyDict else True -``` - -The output YAML is - -```yaml -isEmptyList: true -isEmptyDict: true -``` - -Or use the boolean function `bool` to judge - -```python -_emptyList = [] -_emptyDict = {} -isEmptyList = bool(_emptyList) -isEmptyDict = bool(_emptyDict) -``` - -## 12. How to concatenate strings, format strings, check string prefixes and suffixes and replace string content? - -- The `+` operator can be used to concatenate two strings in KCL - -```python -data1 = "string1" + "string2" # "string1string2" -data2 = "string1" + " " + "string2" # "string1 string2" -``` - -- There are currently two ways to format strings in KCL: - - `format` method for string variables `"{}".format()` - - Using string interpolation `${}` - -```python -hello = "hello" -a = "{} world".format(hello) -b = "${hello} world" -``` - -Note that if we want to use the `{` character or `}` alone in `"{}".format()`, we need to use `{{` and `}}` to convert `{` and `}` respectively, such as escaping a JSON string as follows: - -```python -data = "value" -jsonData = '{{"key": "{}"}}'.format(data) -``` - -The output YAML is - -```yaml -data: value -jsonData: '{"key": "value"}' -``` - -Note that if we want to use the `$` character alone in the `${}` interpolated string, we need to escape the `$` with `$$` - -```python -world = "world" -a = "hello {}".format(world) # "hello world" -b = "hello ${world}" # "hello world" -c = "$$hello ${world}$$" # "$hello world$" -c2 = "$" + "hello ${world}" + "$" # "$hello world$" -``` - -The output YAML is - -```yaml -world: world -a: hello world -b: hello world -c: $hello world$ -c2: $hello world$ -``` - -- Use the `startswith` and `endswith` methods of strings in KCL to check the prefix and suffix of strings - -```python -data = "length" -isEndsWith = data.endswith("th") # True -isStartsWith = "length".startswith('len') # True -``` - -- Use the replace method of the string or the `regex.replace` function to replace the content of the string in KCL - -```python -import regex -data1 = "length".replace("len", "xxx") # Replace "len", "xxxgth" with "xxx" -data2 = regex.replace("abc123", r"\D", "0") # Replace all non-digits in "abc123" with "0", "000123" -``` - -Among them, `r"\D"` means that we do not need to use `\\` to escape the backslash `\` in `\D`, which is mostly used in regular expression strings. - -Besides, we can use index placeholders or keyword placeholders in string formatting expressions to format multiple strings - -- Index placeholders - -```python -x = '{2} {1} {0}'.format('directions', 'the', 'Read') -y = '{0} {0} {0}'.format('string') -``` - -The output YAML is - -```yaml -x: Read the directions -y: string string string -``` - -- Keyword placeholders - -```python -x = 'a: {a}, b: {b}, c: {c}'.format(a = 1, b = 'Two', c = 12.3) -``` - -The output YAML is - -```yaml -x: "a: 1, b: Two, c: 12.3" -``` - -## 13. What is the difference between using single and double quotes in a string? - -There is little difference between KCL single-quoted and double-quoted strings. The only difference is that we don't need to use `\"` to escape `"` in single-quoted strings, and we don't need to use `\'` to escape `'` in double-quoted strings. - -```python -singleQuotedString = 'This is my book named "foo"' # Don’t need to escape double quotes in single quoted strings. -doubleQuotedString = "This is my book named 'foo'" # Don’t need to escape single quotes in double quoted strings. -``` - -In addition, a long string consisting of three single quotes or three double quotes does not need to be escaped (except for the beginning and end of the string), such as the following example: - -```python -longStrWithQuote0 = """Double quotes in long strings "(not at the beginning and end)""" -longStrWithQuote1 = '''Double quotes in long strings "(not at the beginning and end)''' -longStrWithQuote2 = """Single quotes in long strings '(not at the beginning and end)""" -longStrWithQuote3 = '''Single quotes in long strings '(not at the beginning and end)''' -``` - -The output YAML is - -```yaml -longStrWithQuote0: Double quotes in long strings "(not at the beginning and end) -longStrWithQuote1: Double quotes in long strings "(not at the beginning and end) -longStrWithQuote2: Single quotes in long strings '(not at the beginning and end) -longStrWithQuote3: Single quotes in long strings '(not at the beginning and end) -``` - -## 14. How to write a long multiline string? - -In KCL, we can use a single-quoted string and newline characters `\n` or a triple-quoted string to write a multi-line string, and we can use the continuation character `\` to optimize the form of the KCL string. For example, for the three multi-line string variables in the following code, their values are the same: - -```python -string1 = "The first line\nThe second line\nThe third line\n" -string2 = """The first line -The second line -The third line -""" -string3 = """\ -The first line -The second line -The third line -""" # It is recommended to use the long string writing form of `string3`. -``` - -The output YAML is - -```yaml -string1: | - The first line - The second line - The third line -string2: | - The first line - The second line - The third line -string3: | - The first line - The second line - The third line -``` - -## 15. How to use regular expressions in KCL? - -Regular expressions can be used by importing the regular expression system module `import regex` in KCL, which includes the following functions: - -- **match**: Regular expression matching function, which matches the input string according to the regular expression, and returns a bool type to indicate whether the match is successful. -- **split**: Regular expression split function, which splits the string according to the regular expression, and returns a list of split strings. -- **replace**: Regular expression replacement function, which replaces all substrings in the string that satisfies the regular expression, and returns the replaced string. -- **compile**: Regular expression compilation function, which returns bool type to indicate whether it is a valid regular expression. -- **search**: Regular expression search function, which searches all substrings that satisfy the regular expression, and returns a list of substrings. - -Examples: - -```python -import regex - -regex_source = "Apple,Google,Baidu,Xiaomi" -regex_split = regex.split(regex_source, ",") -regex_replace = regex.replace(regex_source, ",", "|") -regex_compile = regex.compile("$^") -regex_search = regex.search("aaaa", "a") -regex_find_all = regex.findall("aaaa", "a") -regex_result = regex.match("192.168.0.1", "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$") # Determine if it is an IP string -regex_result_false = regex.match("192.168.0,1", "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$") # Determine if it is an IP string -``` - -The output YAML is - -```yaml -regex_source: Apple,Google,Baidu,Xiaomi -regex_split: - - Apple - - Google - - Baidu - - Xiaomi -regex_replace: Apple|Google|Baidu|Xiaomi -regex_compile: true -regex_search: true -regex_find_all: - - a - - a - - a - - a -regex_result: true -regex_result_false: false -``` - -For longer regular expressions, we can also use **r-string** to ignore the escape of `\` symbols to simplify the writing of regular expression strings. - -Examples: - -```python -import regex - -isIp = regex.match("192.168.0.1", r"^(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)$") # Determine if it is an IP string -``` - -```python -import regex - -schema Resource: - cpu: str = "1" - memory: str = "1024Mi" - disk: str = "10Gi" - check: - regex.match(cpu, r"^([+-]?[0-9.]+)([m]*[-+]?[0-9]*)$"), "cpu must match specific regular expression" - regex.match(memory, r"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"), "memory must match specific regular expression" - regex.match(disk, r"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"), "disk must match specific regular expression" -``` - -```python -import regex - -schema Env: - name: str - value?: str - check: - len(name) <= 63, "a valid env name must be no more than 63 characters" - regex.match(name, r"[A-Za-z_][A-Za-z0-9_]*"), "a valid env name must start with alphabetic character or '_', followed by a string of alphanumeric characters or '_'" -``` - -## 16. What is the meaning of schema in KCL? - -Schema is a language element in KCL that defines the type of configuration data. Like struct in C language or class in Java, attributes can be defined in it, and each attribute has a corresponding type. - -## 17. How to use schema? - -In KCL, we can use the `schema` keyword to define a structure in which we can declare the various attributes of the schema. - -```python -# A Person structure with firstName of attribute string type, lastName of string type, age of integer type. -schema Person: - firstName: str - lastName: str - # The default value of the age attribute is 0. - age: int = 0 -``` - -A complex example: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels: {str:str} -``` - -In the above code, `cpu` and `memory` are defined as integer types; `name`, `image` and `service` are string types; `command` is a list of string types; labels are dictionaries type whose key type and value type are both strings. - -## 18. How to add "optional" and "required" constraints to the schema attribute? - -The `?` operator is used in KCL to define an "optional" constraint for a schema, and the schema attribute is "required" by default. - -```python -# A Person structure with firstName of attribute string type, lastName of string type, age of integer type. -schema Person: - firstName?: str # firstName is an optional attribute that can be assigned to None/Undefined - lastName?: str # age is an optional attribute that can be assigned to None/Undefined - age: int = 18 # age is an optional attribute that can be assigned to None/Undefined. -``` - -## 19. How to write validation rules for attributes in schema? - -In the schema definition, we can use the `check` keyword to write the validation rules of the schema attribute. As shown below, each line in the check code block corresponds to a conditional expression. When the condition is satisfied, the validation is successful. The conditional expression can be followed by `, "check error message"` to indicate the information to be displayed when the validation fails. - -```python -import regex - -schema Sample: - foo: str # Required, cannot be None/Undefined, and the type must be str - bar: int # Required, cannot be None/Undefined, and the type must be int - fooList: [int] # Required, cannot be None/Undefined, and the type must be int list - color: "Red" | "Yellow" | "Blue" # Required, literal union type, and must be one of "Red", "Yellow", "Blue". - id?: int # Optional, can be None/Undefined, the type must be int - - check: - 0 <= bar < 100 # bar must be greater than or equal to 0 and less than 100 - 0 < len(fooList) < 100 # fooList cannot be None/Undefined, and the length must be greater than 0 and less than 100 - regex.match(foo, "^The.*Foo$") # regular expression matching - bar in range(100) # bar can only range from 1 to 99 - bar in [2, 4, 6, 8] # bar can only take 2, 4, 6, 8 - bar % 2 == 0 # bar must be a multiple of 2 - all foo in fooList { - foo > 1 - } # All elements in fooList must be greater than 1 - any foo in fooList { - foo > 10 - } # At least one element in fooList must be greater than 10 - abs(id) > 10 if id # check expression with if guard, when id is not empty, the absolute value of id must be greater than 10 -``` - -To sum up, the validation kinds supported in KCL schema are: - -| Kind | Method | -| ----------------- | ----------------------------------------------------------------------------------------- | -| Range | Using comparison operators such as `<`, `>` | -| Regex | Using methods such as `match` from the `regex` system module | -| Length | Using the `len` built-in function to get the length of a variable of type `list/dict/str` | -| Enum | Using literal union types | -| Optional/Required | Using optional/required attributes of schema | -| Condition | Using the check if conditional expression | - -## 20. How to add documentation to schema and its attributes? - -A complete schema document is represented as a triple-quoted string, with the following structure: - -```python -schema Person: - """The schema person definition - - Attributes - ---------- - name : str - The name of the person - age : int - The age of the person - - See Also - -------- - Son: - Sub-schema Son of the schema Person. - - Examples - -------- - person = Person { - name = "Alice" - age = 18 - } - """ - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -``` - -## 21. How to write configuration based on schema? How to reuse the common configuration between multiple configurations? - -In the process of schema instantiation, we can use the unpacking operator `**` to expand the public configuration - -```python -schema Boy: - name: str - age: int - hc: int - -schema Girl: - name: str - age: int - hc: int - -config = { - age = 18 - hc = 10 -} - -boy = Boy { - **config - name = "Bob" -} -girl = Girl { - **config - name = "Alice" -} -``` - -The output YAML is - -```yaml -config: - age: 18 - hc: 10 -boy: - name: Bob - age: 18 - hc: 10 -girl: - name: Alice - age: 18 - hc: 10 -``` - -## 22. How to override the default value of schema attribute when writing configuration based on schema? - -After defining a schema, we can use the schema name to instantiate the corresponding configuration, use the `:` operator to union schema attribute default values, and use `=` to override schema attribute default values. - -```python -schema Meta: - labels: {str:str} = {"key1" = "value1"} - annotations: {str:str} = {"key1" = "value1"} - -meta = Meta { - labels: {"key2": "value2"} - annotations = {"key2" = "value2"} -} -``` - -The output YAML is - -```yaml -meta: - labels: - key1: value1 - key2: value2 - annotations: - key2: value2 -``` - -## 23. How to reuse schema definitions? - -We can declare the schema name that the schema needs to inherit at the definition: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 - -# An employee **is** a person, and has some additional information. -schema Employee(Person): - bankCard: int - nationality: str - -employee = Employee { - firstName = "Bob" - lastName = "Green" - age = 18 - bankCard = 123456 - nationality = "China" -} -``` - -The output YAML is - -```yaml -employee: - firstName: Bob - lastName: Green - age: 18 - bankCard: 123456 - nationality: China -``` - -> Note: KCL only allows schema single inheritance. - -## 24. How to reuse schema logic through composition? - -We can use KCL schema mixin to reuse schema logic. Mixins are generally used for functions such as separation of data in schema internal attributes, and data mapping, which can make KCL code more modular and declarative. - -Note that it is not recommended to define dependencies for mixing attributes between different mixins, which will make the use of mixins complicated. - -Examples: - -```python -schema Person: - mixin [FullNameMixin, UpperMixin] - - firstName: str - lastName: str - fullName: str - upper: str - -schema FullNameMixin: - fullName = "{} {}".format(firstName, lastName) - -schema UpperMixin: - upper = fullName.upper() - -person = Person { - firstName = "John" - lastName = "Doe" -} -``` - -The output YAML is - -```yaml -person: - firstName: John - lastName: Doe - fullName: John Doe - upper: JOHN DOE -``` - -## 25. How to import other KCL files? - -Other KCL files can be imported via the `import` keyword, and KCL configuration files are organized into modules. A single KCL file is considered a module, and a directory is considered a package, as a special module. The `import` keyword supports both relative path import and absolute path import - -For example, for the following directory structure: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ │── service1.k - │ └── service2.k - └── mixin - └── mixin1.k -``` - -For `main.k`, relative path import and absolute path import can be expressed as: - -```python -import service # Absolute path import, the root directory is the path where kcl.mod is located -import mixin # Absolute path import, the root directory is the path where kcl.mod is located - -import .model1 # Relative path import, current directory module -import ..service # Relative path import, parent directory -import ...root # Relative path import, parent directory of parent directory -``` - -> Note that for KCL's entry file `main.k`, it cannot import the folder where it is located, otherwise a circular import error will occur: - -```python -import model # Error: recursively loading -``` - -## 26. When can import be omitted? - -KCL files in the same folder the not in the main package can refer to each other without importing each other. For example, for the following directory structure: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ │── service1.k - │ └── service2.k - └── mixin - └── mixin1.k -``` - -When main.k is used as the KCL command line entry file, the variables in main.k, model1.k and model2.k in the model folder cannot refer to each other and need to be imported through import, but service1.k in the service folder and Variables in service2.k can refer to each other, ignoring import - -service1.k - -```python -schema BaseService: - name: str - namespace: str -``` - -service2.k - -```python -schema Service(BaseService): - id: str -``` - -## 27. There is a line of code that is too long, how to wrap it gracefully with correct syntax? - -In KCL, we can use the continuation character `\` for newlines, and we can also use `\` in strings to indicate continuation. - -An example of a long string concatenation continuation line: - -```python -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " -``` - -An example of a continuation in the comprehension expression: - -```python -data = [1, 2, 3, 4] -dataNew = [ - d + 2 \ - for d in data \ - if d % 2 == 0 -] -``` - -An example of a continuation in the if expression: - -```python -condition = 1 -data1 = 1 \ - if condition \ - else 2 -data2 = 2 \ -if condition \ -else 1 -``` - -An example of a continuation in the long string: - -```python -longString = """\ -The first line\ -The continue second line\ -""" -``` - -Note: Use the line continuation character `\` while maintaining indentation, as follows: - -- Error use case: - -```python -data1 = [ - 1, 2, - 3, 4 \ -] # Error, need to keep the indentation of the closing bracket ] - -data2 = [ - 1, 2, - 3, 4 -] # Error, requires uniform indentation of numbers 1 and 3 -``` - -- Right use case: - -```python -data1 = [ - 1, 2, - 3, 4 -] # OK - -data2 = [ \ - 1, 2, \ - 3, 4 \ -] # OK - -data3 = [ \ - 1, 2, \ - 3, 4 \ -] # OK -``` - -## 28. What do these symbols `**` and `*` mean? - -- `**`, `*` appear outside dict/list to represent power operator and multiplication operator respectively. - -```python -data1 = 2 ** 4 # 16 -data2 = 2 * 3 # 6 -``` - -- `**`, `*` appear inside dict/list to indicate unpacking operator, often used for unpacking and merging of list/dict, similar to unpacking operator in Python - -Unpacking of dict: - -```python -data = {"key1" = "value1"} -dataUnpack = {**data, "key2" = "value2"} # {"key1": "value1", "key2": "value2"} -``` - -Unpacking of list: - -```python -data = [1, 2, 3] -dataUnpack = [*data, 4, 5, 6] # [1, 2, 3, 4, 5, 6] -``` - -## 29. How to get child elements of list/dict/schema - -- For list type, we can use `[]` to get an element in the list - -```python -data = [1, 2, 3] # Define an list of integer types -theFirstItem = data[0] # Get the element with index 0 in the list, that is, the first element 1 -theSecondItem = data[1] # Get the element with index 1 in the list, which is the first element 2 -``` - -> Note: The value of the index cannot exceed the length of the list, otherwise an error will occur, we can use the `len` function to get the length of the list. - -```python -data = [1, 2, 3] -dataLength = len(data) # List length is 3 -item = data[3] # Error: Index out of bounds -``` - -In addition, we can also use the negative index to get the elements in the list in reverse order. - -```python -data = [1, 2, 3] -item1 = data[-1] # Get the element with index -1 in the list, which is the last element 3 -item2 = data[-2] # Get the element with index -2 in the list, which is the second-to-last element 2 -``` - -In summary, the value range of the list index is `[-len, len - 1]` - -When we want to get a part of the sub-elements of the list, we can use the slice expression in `[]`, the specific syntax is `[::]`, Note that the value range of the start and end of the index is `left closed right open [, )`, note that the three parameters can be omitted or not written. - -```python -data = [1, 2, 3, 4, 5] -dataSlice0 = data[1:2] # Get the set of elements in the list whose index starts at 1 and ends at 2 [2] -dataSlice1 = data[1:3] # Get the set of elements in the list whose index starts at 1 and ends at 3 [2, 3] -dataSlice2 = data[1:] # Get the set of elements in the list whose index starts at 1 and ends at the last index [2, 3, 4, 5] -dataSlice3 = data[:3] # Get the set of elements in the list whose index starts at the first index and ends at 3 [1, 2, 3] -dataSlice4 = data[::2] # Get the set of elements in the list whose index starts at the first index and ends at the last index (step size is 2) [1, 3, 5] -dataSlice5 = data[::-1] # Reverse the list, [5, 4, 3, 2, 1] -dataSlice6 = data[2:1] # When the start, stop, step combination of three parameters does not meet the conditions, return an empty list []. -``` - -- For dict/schema types, we can use `[]` and `.` to get child elements in dict/schema. - -```python -data = {key1: "value1", key2: "value2"} -data1 = data["key1"] # "value1" -data2 = data.key1 # "value1" -data3 = data["key2"] # "value2" -data4 = data.key2 # "value2" -``` - -```python -schema Person: - name: str = "Alice" - age: int = 18 - -person = Person {} -name1 = person.name # "Alice" -name2 = person["name"] # "Alice" -age1 = person.age # 18 -age2 = person.age # 18 -``` - -When the key value does not exist in the dict, return the value `Undefined`. - -```python -data = {key1 = "value1", key2 = "value2"} -data1 = data["not_exist_key"] # Undefined -data2 = data.not_exist_key # Undefined -``` - -We can use the `in` keyword to determine whether a key value exists in dict/schema - -```python -data = {key1 = "value1", key2 = "value2"} -exist1 = "key1" in data # True -exist2 = "not_exist_key" in data # False -``` - -When there is `.` in the key value or when we need to get the value corresponding to a key value variable at runtime, we can only use the `[]` method. If there is no special case, use `.`: - -```python -name = "key1" -data = {key1 = "value1", key2 = "value2", "contains.dot" = "value3"} -data1 = data[name] # "value1" -data2 = data["contains.dot"] # "value3" -# Note that this is wrong: data3 = data.contains.dot -``` - -> Note: The above sub-element operators cannot operate on values of non-list/dict/schema collection types, such as integers, nulls, etc. - -```python -data = 1 -data1 = 1[0] # Error -``` - -```python -data = None -data1 = None[0] # Error -``` - -When getting the child elements of the collection type, it is often necessary to make a non-null or length judgment: - -```python -data = [] -item = data[0] if data else None -``` - -We can use the `?` operator to make an if non-null judgment, and return None when the condition is not satisfied. For example, the above code can be simplified to: - -```python -data = [] -item1 = data?[0] # When data is empty, return the empty value None -item2 = data?[0] or 1 # When data is empty, return the empty value None, if we don't want to return None, we can also use the or operator to return other default values e.g., "1" in `data?[0] or 1` -``` - -Use more `?` operators to avoid complicated and cumbersome non-null judgments - -```python -data = {key1.key2.key3 = []} -item = data?.key1?.key2?.key3?[0] -``` - -## 30. How to get the type of a variable in KCL code - -The KCL `typeof` built-in function can return the type (string representation) of a variable immediately for type assertion. - -Examples: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person{} -t3 = typeof(_x1) - -_x2 = pkg.Person{} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# Output -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -## 31. How to solve the conflict between keywords and KCL variable names? - -For identifier names that conflict with keywords, we can add a `$` prefix before the identifier to define a keyword identifier. For example, in the following code, keywords such as `if`, `else` can be used as identifiers with the `$` prefix and we can get the corresponding YAML output - -```python -$if = 1 -$else = "s" - -schema Data: - $filter: str = "filter" - -data = Data {} -``` - -The output YAML is - -```yaml -data: - filter: filter -if: 1 -else: s -``` - -> Note: Prefixing non-keyword identifiers with `$` has the same effect as not adding. - -```python -_a = 1 -$_a = 2 # Equivalent to `_a = 2` -``` - -## 32. Are built-in types of KCL a keyword of KCL? Whether they can be used for the definition of variables - -The built-in types of KCL include `int`, `float`, `bool` and `str`, which are not KCL keywords and can be used to define variables, such as the following code: - -```py -int = 1 -str = 2 -``` - -The output YAML is - -```yaml -int: 1 -str: 2 -``` - -> Note: If there are no special requirements, it is not recommended that the names of variables take these built-in types, because in some languages, they exist as keywords. - -## 33. How to implement enumeration in KCL? - -There are two ways to implement enumeration in KCL - -- Use **literal union types** (recommended) - -```python -schema Person: - name: str - gender: "Male" | "Female" - -person = Person { - name = "Alice" - gender = "Male" # gender can only be "Male" or "Female" -} -``` - -```python -schema Config: - colors: ["Red" | "Yellow" | "Blue"] # colors is an enumerated array - -config = Config { - colors = [ - "Red" - "Blue" - ] -} -``` - -- Use schema check expressions - -```python -schema Person: - name: str - gender: "Male" | "Female" - - check: - gender in ["Male", "Female"] - -person = Person { - name = "Alice" - gender = "Male" # gender can only be "Male" or "Female" -} -``` - -## 34. How to get the length of dict - -In KCL, we can use the `len` built-in function to directly find the length of a dict - -```python -len1 = len({k1: "v1"}) # 1 -len2 = len({k1: "v1", k2: "v2"}) # 2 -varDict = {k1 = 1, k2 = 2, k3 = 3} -len3 = len(varDict) # 3 -``` - -In addition, the `len` function can also be used to get the length of `str` and `list` types - -```python -len1 = len("hello") # 5 -len2 = len([1, 2, 3]) # 3 -``` - -## 35. How to write conditional configuration in KCL - -In KCL, in addition to writing `if-elif-else` conditional expressions in top-level statements, it also supports writing conditional expressions in KCL complex structures (list/dict/schema), and supports conditional configuration writing. - -```python -x = 1 -# Conditional configuration in list -dataList = [ - if x == 1: 1 -] -# Conditional configuration in dict -dataDict = { - if x == 1: key1 = "value1" # Inline form - elif x == 2: - key2 = "value2" # Multi-line form -} - -schema Config: - id?: int - -env = "prod" -# Conditional configuration in schema -dataSchema = Config { - if env == "prod": - id = 1 - elif env == "pre": - id = 2 - elif env == "test": - id = 3 -} -``` - -## 36. Does the == operator in KCL do deep comparisons? - -`==` operator in KCL - -- For primitive types `int`, `float`, `bool`, `str` variables are directly compared to see if their values are equal -- Variables of composite types `list`, `dict`, `schema` will deeply recursively compare their sub-elements for equality - - `list` type deep recursive recursive comparison of the value and length of each index - - `dict`/`schema` types deeply recursively compare the value of each attribute (regardless of the order in which the attributes appear) - -```python -print([1, 2] == [1, 2]) # True -print([[0, 1], 1] == [[0, 1], 1]) # True -print({k1 = 1, k2 = 2} == {k2 = 2, k1 = 1}) # True - -print([1, 2] == [1, 2, 3]) # False -print({k1 = 1, k2 = 2, k3 = 3} == {k2 = 2, k1 = 1}) # False -``` - -## 37. How to modify existing configuration blocks in KCL - -In KCL, there are three **attribute operators** `=`, `+=`, `:`, which can be used to modify existing configuration blocks, and can use **unpacking operator** ` **` etc. "inherit" all attribute fields and values ​​of a configuration block. - -- The `=` attribute operator means overriding, use `=` operator to override/delete the attribute with priority, (if it is overwritten with `Undefined`, it means deletion) -- The `+=` attribute operator means adding, which is generally used to add sub-elements to the attributes of the list type. The operand type following the `+=` attribute operator can only be of the list type. -- The `:` attribute operator means idempotent merge. When the value conflicts, an error is reported, and when there is no conflict, the merge is performed - -### Override attribute operator = - -The most commonly used attribute operator is `=`, which indicates the assignment of an attribute. When the same attribute is used multiple times, it means overwriting. For global variables outside `{}` or attributes within `{}`, it means using value overrides this global variable or attribute - -```python -data = { # define a dictionary type variable data - a = 1 # use = to declare a attribute a in data with a value of 1 - b = 2 # use = to declare a attribute b in data with a value of 1 -} # The final data value is {"a": 1, "b": 1} -``` - -we can also use the override attribute operator at the schema instantiation to achieve the effect of overriding the default value of the schema. Generally, when creating a new schema instance, if there is no special requirement, we can generally use `=` - -```python -schema Person: - name: str = "Alice" # schema Person's name attribute has default value "Alice" - age: int = 18 # schema Person's age attribute has a default value of 18 - -bob = Person { - name = "Bob" # "Bob" -> "Alice", the value of the attribute name "Bob" will override the default value "Alice" of the schema Person name attribute - age = 10 # 10 -> 18, the value of the attribute age of 10 will override the default value of the schema Person age attribute of 18 -} # The final value of bob is {"name": "Bob", age: 10} -``` - -### Insert attribute operator += - -The insert attribute operator means to add the value of an attribute in place, such as adding a new element to a list type attribute - -```python -data = { - args = ["kcl"] # use = to declare an attribute in data with value ["kcl"] args - args += ["-Y", "settings.yaml"] # Add two elements "-Y", "settings.yaml" to attribute args using += operator -} # The final data value is {"args": ["kcl", "-Y", "settings.yaml"]} -``` - -### Merge attribute operators : - -The merge attribute operator means idempotent merging of different configuration block values ​​of an attribute. When the values ​​to be merged conflict, an error is reported. It is mostly used in complex configuration merging scenarios. - -```python -data = { - labels: {key1: "value1"} # define a labels, its type is dict, the value is {"key1": "value1"} - labels: {key2: "value2"} # Use : to combine different configuration values ​​of labels -} # The final data value is {"labels": {"key1": "value1", "key2": "value2"}} -``` - -The merge attribute operator is an idempotent operator, and the writing order of the configuration blocks to be merged does not affect the final result. For example, the two `labels` attributes in the above example can also be written in reverse order. - -```python -data = { # The merged writing order of the same attribute labels does not affect the final result - labels: {key2: "value2"} # define a label whose type is dict and the value is {"key2": "value2"} - labels: {key1: "value1"} # Use : to combine different configuration values ​​of labels -} # The final data value is {"labels": {"key1": "value1", "key2": "value2"}} -``` - -Note: The merge attribute operator will check the merged values ​​for conflicts, and report an error when the configuration values ​​that need to be merged conflict. - -```python -data = { - a: 1 # the value of a is 1 - a: 2 # Error: The value 2 of a cannot be merged with the value 1 of a because the results conflict and the merge is not commutative -} -``` - -```python -data = { - labels: {key: "value"} - labels: {key: "override_value"} # Error: The values ​​"value" and "override_value" of the key attributes of two labels are conflicting and cannot be merged -} -``` - -The coalescing operator is used differently for different types - -- Attributes of different types cannot be merged -- When the attribute is a basic type such as int/float/str/bool, the operator will judge whether the values ​​to be merged are equal, and a merge conflict error will occur if they are not equal - -```python -data = { - a: 1 - a: 1 # Ok - a: 2 # Error -} -``` - -- when the attribute is of type list - - Merge conflict error occurs when two lists that need to be merged are not of equal length - - When the lengths of the two lists to be merged are equal, recursively merge each element in the list according to the index - -```python -data = { - args: ["kcl"] - args: ["-Y", "settings.yaml"] # Error: The lengths of the two args attributes are not the same and cannot be merged - env: [{key1: "value1"}] - env: [{key2: "value2"}] # Ok: The value of the final env attribute is [{"key1": "value1"}, {"key2": "value2"}] -} -``` - -- When the attribute is of type dict/schema, recursively merge each element in dict/schema according to key - -```python -data = { - labels: {key1: "value1"} - labels: {key2: "value2"} - labels: {key3: "value3"} -} # The final data value is {"labels": {"key1": "value1", "key2": "value2", "key3": "value3"}} -``` - -- the result of combining an attribute of any type with None/Undefined is itself - -```python -data = { - args: ["kcl"] - args: None # Ok - args: Undefined #Ok -} # The final data value is {"args": ["kcl"]} -``` - -Support declaration and merging of top-level variables using the `:` attribute (we can still declare a configuration block using `config = Config {}`) - -```python -schema Config: - id: int - value: str - -config: Config { - id: 1 -} -config: Config { - value: "1" -} -""" -Two Config configuration blocks are defined here, and the : operator can be used to merge the two configuration blocks together. The equivalent code for the merge is as follows: -config: Config { - id: 1 - value: "1" -} -""" -``` - -To sum up, the usage scenario of the merge attribute operator `:` is mainly the merge operation of the complex data structure list/dict/schema. In general, if there is no special requirement, the two attribute operators `=` and `+=` are used. Yes, so the best practice for attribute operators is as follows - -- For primitive types, use the `=` operator -- For the list type, the `=` and `+=` operators are generally used. Use `=` to completely override the list attribute, and use `+=` to add elements to the list -- For dict/schema types, the `:` operator is generally used - -In addition, when a configuration already exists, we can use the unpacking operator `**` to get all field values ​​of this configuration and modify the fields with different attribute operators, and get a new configuration - -```python -configBase = { - intKey = 1 # A attribute of type int - floatKey = 1.0 # A attribute of type float - listKey = [0] # A attribute of type list - dictKey = {key1: "value1"} # an attribute of type dict -} -configNew = { - **configBase # Unpack and inline configBase into configNew - intKey = 0 # Use override attribute operator = to override intKey attribute to 1 - floatKey = Undefined # Use override attribute operator = remove floatKey attribute - listKey += [1] # Add an attribute 1 to the end of the listKey attribute using the add attribute operator += - dictKey: {key2: "value2"} # Use the merge attribute operator: extend a key-value pair for the dictKey attribute -} -``` - -The output YAML result is: - -```yaml -configBase: - intKey: 1 - floatKey: 1.0 - listKey: - - 0 - dictKey: - key1: value1 -configNew: - intKey: 0 - listKey: - - 0 - - 1 - dictKey: - key1: value1 - key2: value2 -``` - -Alternatively two configuration blocks can be combined using the `|` operator: - -```python -configBase = { - intKey = 1 # A attribute of type int - floatKey = 1.0 # A attribute of type float - listKey = [0] # A attribute of type list - dictKey = {key1: "value1"} # an attribute of type dict -} -configNew = configBase | { # Use | to merge - intKey = 0 # Use override attribute operator = to override intKey attribute to 1 - floatKey = Undefined # Use override attribute operator = remove floatKey attribute - listKey += [1] # Add an attribute 1 to the end of the listKey attribute using the add attribute operator += - dictKey: {key2: "value2"} # Use the merge attribute operator: extend a key-value pair for the dictKey attribute -} -``` - -The output YAML is - -```yaml -configBase: - intKey: 1 - floatKey: 1.0 - listKey: - - 0 - dictKey: - key1: value1 -configNew: - intKey: 0 - listKey: - - 0 - - 1 - dictKey: - key1: value1 - key2: value2 -``` - -### The solution to the conflicting values on the attribute 'attr' between {value1} and {value2} error in KCL - -When an error like conflicting values on the attribute 'attr' between {value1} and {value2} occurs in KCL, it is usually a problem with the use of the merge attribute operator `:`, indicating that when the `value1` and `value2` configurations are merged, the attribute A conflict error occurred at `attr`. In general, modify the attr attribute of value2 to other attribute operators, use `=` to indicate overwrite, and use `+=` to indicate addition - -For example for the following code: - -```python -data = {k: 1} | {k: 2} # Error: conflicting values on the attribute 'k' between {'k': 1} and {'k': 2} -``` - -We can use the `=` attribute operator to modify it to the following form - -```python -data = {k: 1} | {k = 2} # Ok: the value 2 will override the value 1 through the `=` operator -``` - -## 38. How to traverse multiple elements at the same time in the for comprehension? - -In KCL, we can use for comprehension to traverse multiple elements - -- Example 1: two dimension element loop - -```python -dimension1 = [1, 2, 3] # The length of the dimension1 list is 3 -dimension2 = [1, 2, 3] # The length of the dimension2 list is 3 -matrix = [x + y for x in dimension1 for y in dimension2] # The length of the matrix list is 9 = 3 * 3 -``` - -The output YAML is: - -```yaml -dimension1: - - 1 - - 2 - - 3 -dimension2: - - 1 - - 2 - - 3 -matrix: - - 2 - - 3 - - 4 - - 3 - - 4 - - 5 - - 4 - - 5 - - 6 -``` - -- Example 2: Use for loop and `zip` built-in function to traverse multiple lists one by one by index - -```python -dimension1 = [1, 2, 3] # The length of the dimension1 list is 3 -dimension2 = [1, 2, 3] # The length of the dimension2 list is 3 -dimension3 = [d[0] + d[1] for d in zip(dimension1, dimension2)] # The length of the dimension1 list is 3 -``` - -The output YAML is: - -```yaml -dimension1: - - 1 - - 2 - - 3 -dimension2: - - 1 - - 2 - - 3 -dimension3: - - 2 - - 4 - - 6 -``` - -## 39. How to set default value for option function in KCL - -In KCL, when the value of the option attribute is None/Undefined or empty, we can use the logical `or` to directly specify a default value. - -```python -value = option("key") or "default_value" # When the value of key exists, take the value of option("key"), otherwise take "default_value" -``` - -Or use the default parameter of the option function. - -```python -value = option("key", default="default_value") # When the value of key exists, take the value of option("key"), otherwise take "default_value" -``` - -## 40. How to check that multiple attributes cannot be empty or set values at the same time in schema in KCL? - -In KCL, a single attribute of schema cannot be empty by default, unless we use the attribute optional operator `?`. - -```python -schema Person: - name: str # Required. - age: int # Required. - id?: int # Optional. -``` - -When it is necessary to check that the schema attributes cannot be empty at the same time or only one of them is empty, it needs to be written with the help of schema check expressions. The following takes two attributes `a`, `b` of the schema `Config` as an example to illustrate. - -- `a` and `b` attributes cannot be empty at the same time. - -```python -schema Config: - a?: str - b?: str - - check: - a or b -``` - -- `a` and `b` attributes can only have one or both empty (cannot exist at the same time or not empty) - -```python -schema Config: - a?: str - b?: str - - check: - not a or not b -``` - -## 41. A file is imported in KCL, but the schema defined by other KCL files in the same directory cannot be found. What might be the reason? - -It may be caused to import only this file in this folder. In KCL, import statement supports importing the entire folder, and also supports importing a certain KCL file under a certain folder. For the following directory structure. - -``` -. -├── kcl.mod -├── main.k -└── pkg - ├── pkg1.k - ├── pkg2.k - └── pkg3.k -``` - -There is an entry file main.k in the root directory. You can write the following code in main.k to import the entire pkg folder. At this time, all schema definitions in the pkg folder are visible to each other. - -```python -import pkg -``` - -We can also write the following code to import a single file pkg/pkg1.k. At this time, pkg1.k cannot find other files, namely the schema definitions under pkg2.k/pkg3.k - -```python -import pkg.pkg1 -``` - -## 42. How is indentation handled in KCL? - -In KCL, when a colon `:`, square bracket pair `[]` and curly bracket pair `{}` appear, we generally need to use newline + indentation, and the number of indented spaces for the same indentation level needs to be consistent. The indentation level is generally represented by 4 spaces. - -- colon `:` followed by newline and indent - -```python -"""Indentation in if statements""" -_a = 1 -_b = 1 -if _a >= 1: # colon `:` followed by newline and indent - if _a > 8: - _b = 2 - elif a > 6: - _b = 3 - -"""Indentation in schema statements""" -schema Person: # colon `:` followed by newline and indent - name: str - age: int -``` - -- opening bracket `[` followed by newline and indent - -```python -data = [ # opening bracket `[` followed by newline and indent - 1 - 2 - 3 -] # unindent before closing bracket ] -``` - -```python -data = [ # opening bracket `[` followed by newline and indent - i * 2 for i in range(5) -] # unindent before closing bracket `]` -``` - -- opening bracket `{` followed by newline and indent - -```python -data = { # opening bracket `{` followed by newline and indent - k1 = "v1" - k2 = "v2" -} # unindent before closing brace `}` -``` - -```python -data = { # opening bracket `{` followed by newline and indent - str(i): i * 2 for i in range(5) -} # unindent before closing brace `}` -``` - -## 43. How to write simple tests for KCL code? - -The current version of KCL does not support internal program debugging, we can use the assert statement and the print function to achieve data assertion and viewing. - -```python -a = 1 -print("The value of a is", a) -assert a == 1 -``` - -In addition, we can also use the kcl-test test tool to write KCL internal test cases - -Assuming there is a hello.k file, the code is as follows: - -```python -schema Person: - name: str = "kcl" - age: int = 1 - -hello = Person { - name = "hello kcl" - age = 102 -} -``` - -Construct the hello_test.k test file with the following contents: - -```python -schema TestPerson: - a = Person{} - assert a.name == 'kcl' - -schema TestPerson_age: - a = Person{} - assert a.age == 1 - -schema TestPerson_ok: - a = Person{} - assert a.name == "kcl" - assert a.age == 1 -``` - -Then execute the kcl-test command in the directory: - -``` -$ kcl-test -ok /pkg/to/app [365.154142ms] -$ -``` - -## 44. How to define and use functions in KCL? - -The schema structure acts as a function to a certain extent, and this function has the ability to have multiple input parameters and multiple output parameters. For example, the following code can implement the function of a Fibonacci sequence: - -```python -schema Fib: - n: int - value: int = 1 if n <= 2 else (Fib {n: n - 1}).value + (Fib {n: n - 2}).value - -fib8 = (Fib {n: 8}).value -``` - -The output is - -```yaml -fib8: 21 -``` - -A schema function that merges lists into dictionaries - -```python -schema UnionAll[data, n]: - _?: [] = data - value?: {:} = ((UnionAll(data=data, n=n - 1) {}).value | data[n] if n > 0 else data[0]) if data else {} - -schema MergeList[data]: - """Union all elements in a list returns the merged dictionary - - [{"key1": "value1"}, {"key2": "value2"}, {"key3": "value3"}] -> {"key1": "value1", "key2": "value2", "key3": "value3"} - """ - _?: [] = data - value?: {:} = (UnionAll(data=data, n=len(data) - 1) {}).value if data else {} -``` - -In addition, KCL supports defining a function using the `lambda` keyword: - -```python -func = lambda x: int, y: int -> int { - x + y -} -a = func(1, 1) # 2 -``` - -A lambda function has the following properties: - -- A lambda function takes the value of the last expression as the return value of the function, and an empty function body returns None. -- The return value type annotation can be omitted, the return value type is the type of the last expression value. -- There are no order-independent features in the function body, all expressions are executed in order. - -```python -_func = lambda x: int, y: int -> int { - x + y -} # Define a function using the lambda expression -_func = lambda x: int, y: int -> int { - x - y -} # Ok -_func = lambda x: int, y: int -> str { - str(x + y) -} # Error (int, int) -> str can't be assigned to (int, int) -> int -``` - -A lambda function cannot participate in any computation and can only be used in assignment and call statements. - -```python -func = lambda x: int, y: int -> int { - x + y -} -x = func + 1 # Error: unsupported operand type(s) for +: 'function' and 'int(1)' -``` - -```python -a = 1 -func = lambda x: int { - x + a -} -funcOther = lambda f, para: int { - f(para) -} -r = funcOther(func, 1) # 2 -``` - -The output is - -```python -a: 1 -r: 2 -``` - -We can define an anonymous function and call it directly - -```python -result = (lambda x, y { - z = 2 * x - z + y -})(1, 1) # 3 -``` - -Anonymous functions can be also used in for loops - -```python -result = [(lambda x, y { - x + y -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 3, 3, 4] -``` - -Functions can be defined and used in the KCL schema - -```python -_funcOutOfSchema = lambda x: int, y: int { - x + y -} -schema Data: - _funcInSchema = lambda x: int, y: int { - x + y - } - id0: int = _funcOutOfSchema(1, 1) - id1: int = _funcInSchema(1, 1) - id2: int = (lambda x: int, y: int { - x + y - })(1, 1) -``` - -The output YAML is - -```yaml -data: - id0: 2 - id1: 2 - id2: 2 -``` - -## 45. Why do we get an error when a variable is assigned an enumeration type (a literal union type)? - -In KCL, a attribute defined as a literal union type is only allowed to receive a literal value or a variable of the same literal union type during assignment. For example, the following code is correct: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -data = Data { - color = "Red" # Ok, can be assigned as "Red", "Yellow" and "Blue" -} -``` - -However the following code is wrong: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -_color = "Red" - -data = Data { - color = _color # Error: expect str(Red)|str(Yellow)|str(Blue), got str -} -``` - -This is because there is no type declared for the variable `_color`, it will be deduced by the KCL compiler as a `str` string type, so when a "larger" type `str` is assigned to a "smaller" type `"Red" | "Yellow" | "Blue"` will report an error, one solution is to declare a type for the `_color` variable, the following code is correct: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -_color: "Red" | "Yellow" | "Blue" = "Red" - -data = Data { - color = _color # Ok -} -``` - -Further, we can use type aliases to simplify enumeration (writing of literal union types), such as the following code: - -```python -type Color = "Red" | "Yellow" | "Blue" # Define a type alias, which can be reused in different places, reducing the amount of code writing - -schema Data: - color: Color - -_color: Color = "Red" - -data = Data { - color = _color # Ok -} -``` - -## 46. Procedural for loop - -KCL provides comprehensions and all/any/map/filter expressions for processing a collection element, which meets most needs, and provides a procedural for loop body. Providing a procedural for loop body is not very demanding from the current scenario, so there is no procedural for loop support yet. - -In addition, although KCL does not support procedural for loops, it is possible to "construct" corresponding procedural for loops through for loops and lambda functions. - -```python -result = [(lambda x: int, y: int -> int { - # Write procedural for loop logic in the lambda function. - z = x + y - x * 2 -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 2, 4, 4] -``` - -## 47. Default variables are immutable - -The immutability of KCL variables means that the exported variables starting with non-underscore `_` in the KCL top-level structure cannot be changed after initialization. - -```python -schema Person: - name: str - age: int - -a = 1 # a will be output to YAML, once assigned it cannot be modified -_b = 1 # _b The variable is named with an underscore and will not be output to YAML. It can be modified by multiple assignments -_b = 2 -alice = Person { - name = "Alice" - age = 18 -} -``` - -There are two ways of specifying that variables are immutable: - -- non-underscore top-level variables outside the schema - -```python -a = 1 # immutable exported variable -_b = 2 # mutable non-export variable -``` - -## 48. Is there a type like Go `interface{}`/`any` or Java `Object` in KCL? - -In KCL, we can use the `any` type annotation to define a variable to store any values such as integers, strings and schemas. For example: - -```python -schema Data: - id: int = 1 - -var_list: [any] = [1, "12", Data {}] -``` - -The output YAML is - -```yaml -var_list: - - 1 - - "12" - - id: 1 -``` - -In addition, we can also use the `typeof` function to determine the type of variables during KCL code execution: - -```python -schema Data1: - id: int = 1 - -schema Data2: - name: str = "name" - -data_list: [any] = [Data1 {}, Data2 {}] -data_type_list: [str] = [typeof(data) for data in data_list] -``` - -The output YAML is - -```yaml -data_list: - - id: 1 - - name: name -data_type_list: - - Data1 - - Data2 -``` - -## 49. How to develop a KCL plugin? - -KCL plugins are installed in the plugins subdirectory of KCL (usually installed in the `$HOME/.kcl/plugins` directory), or set through the `$KCL_PLUGINS_ROOT` environment variable. Besides, the `plugins` directory could also be placed at the `pwd` path. For plugin developers, plugins are managed in the [Git repository](https://github.com/kcl-lang/kcl-plugin), and the plugin repository can be cloned to this directory for development. - -KCL has built-in kcl-plugin scaffolding command to assist users to write KCL plug-ins in Python language, so that the corresponding plug-ins can be called in the KCL file to enhance the KCL language itself, such as accessing the network, reading and writing IO, CMDB query and encryption and decryption functions. - -``` -usage: kcl-plugin [-h] {list,init,info,gendoc,test} ... - -positional arguments: - {list,init,info,gendoc,test} - kcl plugin sub commands - list list all plugins - init init a new plugin - info show plugin document - gendoc gen all plugins document - test test plugin - -optional arguments: - -h, --help show this help message and exit -``` - -For example, if you want to develop a plugin named io, you can use the following command to successfully create a new io plugin - -``` -kcl-plugin init io -``` - -Then you can use the following command to get the root path of the plugin and cd to the corresponding io plugin directory for development - -``` -kcl-plugin info -``` - -For example, if you want to develop a function read_file to read a file, you can write python code in `plugin.py` of `$plugin_root/io`: - -```python -# Copyright 2020 The KCL Authors. All rights reserved. - -import pathlib - -INFO = { - 'name': 'io', - 'describe': 'my io plugin description test', - 'long_describe': 'my io plugin long description test', - 'version': '0.0.1', -} - - -def read_file(file: str) -> str: - """Read string from file""" - return pathlib.Path(file).read_text() - -``` - -In addition, you can write the corresponding test function in `plugin_test.py`, or you can directly write the following KCL file for testing: - -```python -import kcl_plugin.io - -text = io.read_file('test.txt') -``` - -You can also use the info command to view information about the io plugin - -``` -kcl-plugin info io -``` - -``` -{ - "name": "io", - "describe": "my io plugin description test", - "long_describe": "my io plugin long description test", - "version": "0.0.1", - "method": { - "read_file": "Read string from file" - } -} -``` - -Finally, the plugin that has written the test can be merged with MR in the `kcl_plugins` repository. - -## 50. How to do basic type conversion in KCL - -You can use the `int()`, `float()` function and `str()` function to convert the basic types between `int`, `float` and `str`. - -``` -_t = 1 - -t_str: str = str(_t) # you will get "t_str: '1'" -t_int: int = int(t_str) # you will get "t_int: 1" -t_float: float = float(t_str) # you will get "t_float: 1.0" -``` - -For more information about type conversion, see [KCL Builtin Types](https://kcl-lang.io/docs/reference/lang/tour#built-in-types) and [KCL Type System](https://kcl-lang.io/docs/reference/lang/tour#type-system). diff --git a/versioned_docs/version-0.5.5/user_docs/support/faq-yaml.md b/versioned_docs/version-0.5.5/user_docs/support/faq-yaml.md deleted file mode 100644 index b13a0f7a..00000000 --- a/versioned_docs/version-0.5.5/user_docs/support/faq-yaml.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -sidebar_position: 3 ---- - -# YAML - -## 1. What is the difference between single and double quote YAML strings? - -- YAML double-quoted strings are the only style that can express arbitrary strings, by using `\` escape characters, such as `\"` to escape double quotes `"`, `\\` to escape backslashes `\`, and a single backslash `\` can be used as a continuation character for double-quoted strings. -- YAML single-quoted strings differ from YAML double-quoted strings in that `\` and `"` can be used freely without escaping, but two single-quotes `''` are used to escape single-quote `'` characters. - -For the following example, the contents of the three string variables are the same. - -```yaml -string1: 'here '' s to "quotes"' -string2: 'here''s to "quotes"' -string3: here's to "quotes" -``` - -> Note: KCL's strategy for outputting YAML strings is to output unquoted strings or double-quoted strings preferentially when single quotes appear in the string content, and output single-quoted strings in other cases to avoid the burden of understanding. - -For more details, please refer to [YAML Spec v1.2](https://yaml.org/spec/1.2.1/) - -## 2. What is the meaning of symbols such as | - + > in YAML? - -When using KCL multi-line strings (triple quote strings), the output YAML often carries some special tokens, such as `|`, `-`, `+` and `>`, etc. These tokens usually are the representation method of YAML multi-line string, such as the following KCL code: - -```python -data = """This is a KCL multi line string (the first line) -This is a KCL multi line string (the second line) -This is a KCL multi line string (the third line) - - -""" -var = 1 -``` - -The output YAML is - -```yaml -data: |+ - This is a KCL multi line string (the first line) - This is a KCL multi line string (the second line) - This is a KCL multi line string (the third line) - - -var: 1 -``` - -- `|` represents **block style**, which is used to represent a multi-line string, where all newlines in the string represent the real newlines. -- `>` represents **folding style**, in which all newlines in the string will be replaced by spaces. -- `+` and `-` are used to control the use of newlines at the end of strings. The default is to keep a single newline at the end of the string. If we want to remove all newlines, we can put a `-` after the style indicator `|` or `>`. If we want to keep the newline at the end, we need to put a `+` after `|` or `>`. - -For more details, please refer to [YAML Multiline String](https://yaml-multiline.info/) and [YAML Spec v1.2](https://yaml.org/spec/1.2.1/) - -## 3. What is the meaning of numbers that appear after symbols | - + > such as |1 and |2 in YAML? - -Numbers represent **explicit indentation indicators** in YAML. For long strings in YAML, YAML usually the first non-blank line determines the indentation level of the string, and when the first non-blank line is preceded by a non-leading character, such as a newline, we must use **explicit indent indicators** to specify the indent level of the content, such as `|1` and `|2` etc. - -For example, for the following KCL code: - -```python -longStringStartWithNewline = """ -This is the second line -This is the third line -""" - -``` - -```yaml -longStringStartWithNewline: |2 - - This is the second line - This is the third line -``` - -- Writing long strings from the first line. - -```python -longString = """This is the second line -This is the third line -""" -``` - -- Writing long strings with line continuation characters. - -```python -longString = """\ -This is the second line -This is the third line -""" -``` - -The YAML output by the above two methods is: - -```yaml -longString: | - This is the second line - This is the third line -``` - -For more details, please refer to [YAML Spec v1.2](https://yaml.org/spec/1.2.1/) diff --git a/versioned_docs/version-0.5.5/user_docs/support/support.md b/versioned_docs/version-0.5.5/user_docs/support/support.md deleted file mode 100644 index fac13ef2..00000000 --- a/versioned_docs/version-0.5.5/user_docs/support/support.md +++ /dev/null @@ -1,3 +0,0 @@ -# FAQ - -KCL frequently asked questions. diff --git a/versioned_docs/version-0.5.6/community/contribute/_category_.json b/versioned_docs/version-0.5.6/community/contribute/_category_.json deleted file mode 100644 index e2dca064..00000000 --- a/versioned_docs/version-0.5.6/community/contribute/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Contribution Guide", - "position": 4 -} diff --git a/versioned_docs/version-0.5.6/community/contribute/contribute-code.md b/versioned_docs/version-0.5.6/community/contribute/contribute-code.md deleted file mode 100644 index f4e9169b..00000000 --- a/versioned_docs/version-0.5.6/community/contribute/contribute-code.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -sidebar_position: 2 ---- - -# How to Contribute Code? - -Welcome to participate in the KCL co construction to improve the code, documentation and testing, and also welcome to provide feedback through Issues. If you want to add KCL language features, please submit through the [KEP](https://github.com/kcl-lang/KEP) process. - -## 1. Misspellings in Code and Comments - -If you only need to modify the typos in the code and comments, you can directly modify and submit the PR to the repository. It is important to keep the code style as consistent as possible. - -## 2. How to Contribute KCL - -See [KCL contribute guide](https://github.com/kcl-lang/kcl/blob/main/docs/dev_guide/1.about_this_guide.md) for more information. - -## 3. How to Contribute VS Code KCL Plugin - -See [VS Code KCL plugin contribute guide](https://github.com/kcl-lang/vscode-kcl/blob/main/docs/CONTRIBUTING.md) for more information. diff --git a/versioned_docs/version-0.5.6/community/contribute/contribute-docs.md b/versioned_docs/version-0.5.6/community/contribute/contribute-docs.md deleted file mode 100644 index 2b400a52..00000000 --- a/versioned_docs/version-0.5.6/community/contribute/contribute-docs.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -sidebar_position: 1 ---- - -# How to Contribute Document? - -This document mainly makes partial modifications to existing documents. If you are submitting blog posts, adding new documents or adjusting the document directory structure, please contact team members first. - -KCL documents are divided into user guides, development documents, internal documents, reference manuals and blog articles. Their differences are as follows: - -- User's Guide: The corresponding usage document allows users to quickly use the KCL tool to complete their work at the minimum cost, without involving too much internal principles and implementation -- Reference: KCL language, tools, IDE and other documents with all features, covering the most extensive but trivial content -- Blog: There are no special restrictions. They can be shared for specific scenarios, technical points or overall development prospects - -When contributing different types of documents, it is better to combine the above positioning to make some appropriate tailoring for different content to give readers the best experience. - -## 1. Basic Specifications - -- In addition to the title, the internal subtitles shall be numbered as much as possible for easy reading -- The document automatically output by the tool needs a link to the source code, and the subtitle can be without number -- Try not to paste large pieces of code (within 30 lines). It is better to provide text explanations and corresponding reference links for the code -- There are diagrams and truths, but overly complex architecture diagrams are not recommended -- Internal link: in the form of [`/docs/user_docs/getting-started/intro`](/docs/user_docs/getting-started/intro) absolute path - -**Punctuation and space** - -- Chinese punctuation is preferred in Chinese documents -- One space is required between Chinese and English -- One space needs to be added between Chinese and numbers -- Chinese uses full width punctuation without adding spaces before and after punctuation -- English content uses half width punctuation, with a space after the punctuation -- You need to leave a space before and after the link, but you do not need to add a space near the beginning of the paragraph and Chinese full width punctuation. - -**Picture and resource file names** - -- The file name and directory name can only use numbers, English letters and underscores`_` And minus sign '-' -- Pictures of the current document are placed in the images directory of the current directory -- Vector pictures can be viewed through [drawio offline version](https://github.com/jgraph/drawio-desktop/releases) (and submit source files at the same time), and export png format pictures at 200% resolution - -## 2. Basic mode of using document content - -Each usage document can be regarded as a relatively complete sharing or blog post (the reference manual is no longer such). Using documents to organize content follows the following pattern: - -1. Overview: What problems do you want to solve and what effects do you want to achieve in this article? You can put a screenshot of the final effect first -2. Dependent environment: what tools need to be installed, and provide relevant links -3. Introduce this article to build a relationship diagram or architecture diagram of resources -4. Give the test method. Try to use community common methods (such as kube, curl command, or browser) to test -5. Summary and Outlook. Briefly review the current operation process and some places that can be expanded (some links can be given) - -## 3. Test and submit PR - -First, clone the document warehouse, and then test the viewing effect locally with the 'npm run start' and 'npm run build' commands to ensure that you can browse normally and then submit PR. diff --git a/versioned_docs/version-0.5.6/community/contribute/contribute.md b/versioned_docs/version-0.5.6/community/contribute/contribute.md deleted file mode 100644 index dd6e2b3f..00000000 --- a/versioned_docs/version-0.5.6/community/contribute/contribute.md +++ /dev/null @@ -1,3 +0,0 @@ -# Contribute Guide - -If it is the first time to participate in the open-source community, you can first check the similar changes in Issue and PR (PullRequest). Then you can fully discuss your own problems with the community or development team classmates, and you can also feedback the problems encountered by creating issues, and then you can provide code patches for related issues. At the beginning, you can start with document improvement and partial code improvement, such as: documentation, Examples, multi-language Binding, etc. At the same time, students who want to participate deeply can contribute to core features such as language functions, language testing, programming frameworks, and various backends. diff --git a/versioned_docs/version-0.5.6/community/contribute/git-guideline.md b/versioned_docs/version-0.5.6/community/contribute/git-guideline.md deleted file mode 100644 index 7d427c01..00000000 --- a/versioned_docs/version-0.5.6/community/contribute/git-guideline.md +++ /dev/null @@ -1,130 +0,0 @@ -# Git Commit Guide - -This document describes the matters needing attention when Git submits changes. If you refuse to accept the contents of this article, the submitted changes will not be accepted. - -## 1. About issue - -Before submitting an issue, please check the closed issue. There may already be an appropriate solution in the closed issue. - -If no suitable solution is found, we provide four templates to use when creating an issue. - -- Bug Report: If a bug is found, you can contact us by creating an issue through the bug report template. -- Enhancement: The developer has enhanced the tool, and can create an issue through the enhancement template to introduce the added content. -- Feature Request: If you want to add some new features or functions to the tool during use, you can create an issue through the Feature Request template to describe the new features. -- Ask a Question: If you have any questions, you can create an issue through the Ask a Question template to contact us. - -After selecting the appropriate template, you only need to fill in the required content on the template. If you find that there is no template or the template content is empty when creating the issue, you can feed back this problem to us through WeChat group, nail group or email. - -## 2. About Git Branch - -To contribute code to KCL, you must have a GitHub account so that you can push the code to your own branch and create pull requests. We recommend reference [Angular Specification]( https://github.com/angular/angular.js/blob/master/DEVELOPERS.md# -Git commit guidelines) name your own branches. - -The recommended format is as follows: - -``` -{type}-{a_short_description} -``` - -The branch name mainly includes two fields, which are separated by "-". Including: - -- `{type}`: the type of the current branch content. -- `{a_short_description}`: A short description of the main content of this branch. - -For example, Alice first transfers the Fork warehouse to his own account, and then creates a branch with the corresponding name 'alice: fix output fmt bug' (Alice's account is before the colon) to fix the output formatting bug. - -## 3. 关于 Git Commit - -We refer to [Commitizen](https://github.com/commitizen/cz-cli) to write a Commit Message. - -``` -Note: If you directly use Commit to generate a Commit Message, please note that -It is a tool for developers to manage commit. It is not related to the project itself, so it is an intermediate product generated by Commiten -(For example, the node_modules file directory) may not be in the project. gitignore file. - -You can git add {filename} select the file to submit and ignore the intermediate product. -Or you can add the following content to the. gitignore file and automatically ignore the intermediate products: -# commitizen -package.json -package-lock.json -node_modules/* -``` - -If you manually write a commit Message, we also recommend [Commiten](https://github.com/commitizen/cz-cli) for the commit message format. - -``` -{type} ( {component_or_file} ) {a_short_description} -{a_longer_description} -BREAKING CHANGE: {breaking_change_description}. -{linked issue} -``` - -It mainly includes 6 fields: - -- `{type}`: the type of the branch corresponding to the current commit. -- `{component_or_file}`: the name of the module or file that the current commit changes. -- `{a_short_description}`: A short description describes the content of the commit. -- `{a_longer_description}`: The detailed description is used to introduce the content in the commit. -- `{breaking_change_description}`: If the commit contains broken compatibility changes, the impact of compatibility changes needs to be introduced. -- `{linked issue}`: the issue associated with the current commit. - -Where `{breaking_change_description}` and `{linked issue}` can be omitted if the commit does not contain compatibility breaking changes and associated issues. - -For example, the commit created by Alice in branch 'alice: fix output fmt bug'. - -``` -fix(kcl-printer): fix an output format bug in kcl-printer - -There is an output format bug in kcl-printer because ..., -So, The calling of method "XXX" is replaced by "HHHH"..., -... - ---If there is no change to break the compatibility and the associated issue, the following contents can be omitted. -BREAKING CHANGE: This change maybe cause ....... - -fix #123 -``` - -## 4. About pull request - -Before submitting a PR, priority may be given to the following issues: - -- Please check the closed PRs first. There may be completed solutions in the closed PRs. -- We suggest that before submitting the change, submit a corresponding issue to describe the problems to be solved in the change, and associate the PR corresponding to the change with the issue. -- After submitting the PR to us, please sign [Contributor License Agreement (CLA)] (# cla). If you refuse to sign, we will not accept the PR. -- Make sure that each change creates a new branch and names the branch according to the specifications mentioned above. -- PR should not exceed two commit at a time. Please compress the extra commit with squash and write a commit message according to the specifications mentioned above. -- We provide [PR template](https://github.com/kcl-lang/.github/blob/main/.github/PULL_REQUEST_TEMPLATE.md). You only need to add the content required in the template. If you find no template or the template content is empty when creating a PR, you can feed back this problem to us through WeChat group, nail group or email. - -We suggest that the PR title be consistent with the branch name and the commit message style: - -``` -{type} ( {component_name_or_file_name} ) :{a_short_description} -``` - -比如,Alice 为分支`fix/alice/fix_output_fmt_bug`创建的PR名称。 - -For example, Alice creates the PR name `fix/alice/fix_output_fmt_bug` for one branch. - -``` -fix(kcl-printer): fix an output format bug in kcl-printer. -``` - -## 5. Supported PR Types - -``` -- feat: -- New features have been added. -- fix: -- Bug is repaired. -- docs: -- The document part has been modified. -- style: -- The modification of code format does not affect the functions of the code, such as deleting redundant spaces, code indentation, etc. -- refactor: -- refactoring code without changing its function. -- perf: -- Performs performance optimization on the code. -- test: -- Add or adjust existing test cases. -- build: -- Adjust the build system or external dependent libraries. -- ci: -- The configuration file or script of the CI has been adjusted. -- choice: -- Adjustments to other parts of the source code and test files. -- reverse: -- Rollback commit. -``` - -## 6. Contributor License Agreement (CLA) - -After the PR is submitted to us for the first time, the CLA check in the PR will fail and prompt to sign the CLA. You can reply "I have read the CLA Document and I hereby sign the CLA" between your accounts in PR to agree to sign the CLA, and then manually restart the failed CLA check action. After PR is successfully merged, it will be locked and cannot be modified. diff --git a/versioned_docs/version-0.5.6/community/intro/_category_.json b/versioned_docs/version-0.5.6/community/intro/_category_.json deleted file mode 100644 index a9646363..00000000 --- a/versioned_docs/version-0.5.6/community/intro/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Community", - "position": 1 -} diff --git a/versioned_docs/version-0.5.6/community/intro/intro.md b/versioned_docs/version-0.5.6/community/intro/intro.md deleted file mode 100644 index 4b1a7f02..00000000 --- a/versioned_docs/version-0.5.6/community/intro/intro.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Community - -Welcome to the KCL open-source community, everyone's participation is the driving force for the healthy growth of all open-source projects! There are many ways to participate in open-source. Everyone can create Issues or fix bugs, improve documentation or modify code by submitting PR (Pull Request), or open new feature discussions by submitting KEP, or share stories about the process of evangelism and use of KCL with surrounding friends. - -See the [community](https://github.com/kcl-lang/community) for ways to join us. diff --git a/versioned_docs/version-0.5.6/community/intro/license.md b/versioned_docs/version-0.5.6/community/intro/license.md deleted file mode 100644 index 4d0097b4..00000000 --- a/versioned_docs/version-0.5.6/community/intro/license.md +++ /dev/null @@ -1,211 +0,0 @@ ---- -sidebar_position: 99 ---- - -# License - -KCL Use [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) License: - -``` - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2023 The KCL Authors. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -``` diff --git a/versioned_docs/version-0.5.6/community/intro/support.md b/versioned_docs/version-0.5.6/community/intro/support.md deleted file mode 100644 index 7ed2e1a8..00000000 --- a/versioned_docs/version-0.5.6/community/intro/support.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Ask for help - -KCL has a developer and user community of many enthusiasts. - -On this page, we list the KCL-related communities you can participate in; see other pages in this section for additional online and offline learning materials. - -Before joining the KCL community, please read the [Contributor Covenant](https://www.contributor-covenant.org/version/2/0/code_of_conduct/) , which is expected to be followed by all community members. - -## Discussions - -- Submit an issue on Github -- Communicate in the Github discussion group -- Get the latest status through official website, Github, Twitter, Slack, Wechat and other accounts. See the [community](https://github.com/kcl-lang/community) for ways to join us. - -## New Features - -Please try to avoid submitting pull requests for new features, we may already have someone working on them, or maybe this feature is already part of our future plans. In conclusion, please contact us before submitting new features! diff --git a/versioned_docs/version-0.5.6/community/release-policy/_category_.json b/versioned_docs/version-0.5.6/community/release-policy/_category_.json deleted file mode 100644 index bc39d651..00000000 --- a/versioned_docs/version-0.5.6/community/release-policy/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Release Policy", - "position": 3 -} diff --git a/versioned_docs/version-0.5.6/community/release-policy/index.md b/versioned_docs/version-0.5.6/community/release-policy/index.md deleted file mode 100644 index c87091d0..00000000 --- a/versioned_docs/version-0.5.6/community/release-policy/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# Release Policy - -The release policy defines the semantics of the release, the release process, etc. In order to maximize the concurrent development process, KCL, etc. adopt independent release strategies. diff --git a/versioned_docs/version-0.5.6/community/release-policy/kcl.md b/versioned_docs/version-0.5.6/community/release-policy/kcl.md deleted file mode 100644 index a24e1509..00000000 --- a/versioned_docs/version-0.5.6/community/release-policy/kcl.md +++ /dev/null @@ -1,39 +0,0 @@ -# KCL Release Policy - -KCL 开发团队采用 [语义化版本](https://semver.org/lang/zh-CN/) 来简化管理。版本格式:主版本号.次版本号.修订号。版本号递增规则如下:主版本号对应不兼容的 API 修改,次版本号对应向下兼容的功能性新增,修订号对应向下兼容的问题修正。总体目标是每一个半月发布一个特性增强的次要版本,根据需要不定期发布其他版本的修订。 - -KCL 项目版本发布策略如下: - -- 主版本号:当进行重大的架构调整或者加入重大的新功能时,需要提升主版本号。对于 KCL 项目来说,目前的主版本号为 0。 -- 次版本号:当添加的功能和特性有较大的变化时,提升次版本号。目前的次版本号为 5,2023 年度会相继发布 0.5, 0.6, 0.7 版本。 -- 修订号:通过修复漏洞或者改进性能来更新程序时,会提升修订号,修订号从 0 开始计数以此加 1。 -- 发布周期:在未达到 v1.0.0 版本之前,计划每隔 3 个月发布一个新的次要版本。在此期间,需要持续收集用户反馈,并进行必要的修复和改进。 -- 发布流程:在发布新版本之前,需要进行严格的测试和审核,确保新版本的质量。封板并测试完成后,会在 Github 上发布新版本的源代码,二进制和镜像,并提供详细的文档和使用指南。 -- 版本支持:我们将对最新的版本提供长期支持,包括漏洞修复和安全更新。对于旧版本,我们将提供有限的支持,仅在必要时进行修复。 - -## 发布流程与规则 - -- 特性开发:main 分支主干开发,分支发布,block 用户使用的问题和严重的 bug, 安全隐患,高优先级解决,尽可能保持在一周内收敛,高于一般的功能研发。 -- 迭代周期:我们的迭代周期通常为 3 个月,即每 3 个月发布一个新的次要版本。 -- 版本规划:发版前两周产出 alpha 版本,前一周产出 beta 版本,alpha 版本仍可进行特性合并,beta 版本只合并错误修复,最终产出正式版本并打 tag 作为长期保存的 release 分支。 -- 发版计划:在每个发布周期开始时制定详细的发版计划(Github Milestone),包括发布日期、版本号、功能列表和测试计划等。需要尽可能地遵守发版计划,确保按时发布新版本。 -- 发布前测试:在发布新版本之前,需要进行全面的测试,包括单元测试、集成测试,模糊测试,压测,用户验收测试等。只有经过测试并无问题后,我们才会发布新版本。 -- 版本回滚:如果在发布后发现了严重的问题,需要立即回滚版本,并尽快修复问题。并通过邮件、社交媒体等渠道及时通知用户,并提供解决方案。 -- 发布文档:需要在发布时提供详细的文档,包括发布说明、更新日志、API 文档和使用指南等,帮助用户了解和使用新版本。在 KCL 中,我们统一在 KCL 网站进行维护。 -- 版本兼容性:在发布新版本时,需要尽可能保持兼容性,以确保用户无需进行过多的修改和适应。KCL 还没有达到 v1,暂时没有兼容性保证。KCL 的目标是尽可能少地进行重大更改,不应轻率地考虑对语言的更改,为了语言自身更好地演进和发展,一般认为更改具有重大好处时才会进行(较好地解决了目标场景的问题或者提升了绝大用户的使用体验)。对于可能引入兼容性问题的功能或变更,提供相应的提示和解决方案,同时会提供逐步升级的指南或提供自动迁移的工具,以帮助用户平滑地迁移到新版本。 - -## 发布组件 - -![](/img/docs/community/release-policy/kcl-components.png) - -每次版本发布时,KCL 相关所有组件保持一个依赖同一个 KCL 核心主要版本,整体采用树形结构组织依赖顺序发布并进行回归测试,直到发布测试完成,尽力避免三角依赖,禁止循环依赖。 - -## 一个 Feature 的生命周期 - -- 设计方案/文档:通过 Issue 回答清楚这个 feature 的动机是什么,它解决什么问题以及目标是什么,用户需求和用户故事是怎样的;这个 feature 做什么,如何做,难度怎样,需要多长时间,依赖项,需要做什么测试等。(Tips: 大的设计尽量拆分成小的设计,通过权衡和广泛的调研找到一个简单且可持续的解决方案,并且具备一定得到可扩展以适应未来的业务或技术变化,通过持续讨论和方案评审确定最终设计)。 -- 编写代码:通过高频小改动进行迭代、持续沟通和协作,提前设计单元测试、集成测试和 benchmark 等测试用例,确保编写代码 100% 测试覆盖,注释完整和逻辑清晰,并通过 Demo 演示持续收集反馈。 -- 文档撰写:在 [KCL 网站](https://kcl-lang.io) 中更新用户文档。 -- 测试和反馈:在发布功能之前,让一些同行/用户通过**随循文档**而不是口述来尝试和测试这些新功能。接收反馈并改进。 -- 发布和公告:撰写 Release Note, PR 文章,场景和新特性解读等以及渠道宣发等。 - -> 注:以上所有信息全是公开的,需要透出给所有社区研发者进行参与、讨论和贡献。 diff --git a/versioned_docs/version-0.5.6/community/release-policy/roadmap.md b/versioned_docs/version-0.5.6/community/release-policy/roadmap.md deleted file mode 100644 index df220576..00000000 --- a/versioned_docs/version-0.5.6/community/release-policy/roadmap.md +++ /dev/null @@ -1,3 +0,0 @@ -# Roadmap - -![](/img/docs/community/release-policy/roadmap.jpg) diff --git a/versioned_docs/version-0.5.6/reference/_advanced-concepts/_category_.json b/versioned_docs/version-0.5.6/reference/_advanced-concepts/_category_.json deleted file mode 100644 index 85a16abb..00000000 --- a/versioned_docs/version-0.5.6/reference/_advanced-concepts/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Advanced-Concepts", - "position": 6 -} diff --git a/versioned_docs/version-0.5.6/reference/_advanced-concepts/build_cache.md b/versioned_docs/version-0.5.6/reference/_advanced-concepts/build_cache.md deleted file mode 100644 index 746e2351..00000000 --- a/versioned_docs/version-0.5.6/reference/_advanced-concepts/build_cache.md +++ /dev/null @@ -1 +0,0 @@ -# Building Cache diff --git a/versioned_docs/version-0.5.6/reference/_category_.json b/versioned_docs/version-0.5.6/reference/_category_.json deleted file mode 100644 index 1b337d5a..00000000 --- a/versioned_docs/version-0.5.6/reference/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Reference", - "position": 5 -} diff --git a/versioned_docs/version-0.5.6/reference/cheatsheets/_category_.json b/versioned_docs/version-0.5.6/reference/cheatsheets/_category_.json deleted file mode 100644 index 80464148..00000000 --- a/versioned_docs/version-0.5.6/reference/cheatsheets/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Cheat Sheet", - "position": 10 -} diff --git a/versioned_docs/version-0.5.6/reference/cheatsheets/index.md b/versioned_docs/version-0.5.6/reference/cheatsheets/index.md deleted file mode 100644 index da4189eb..00000000 --- a/versioned_docs/version-0.5.6/reference/cheatsheets/index.md +++ /dev/null @@ -1,5 +0,0 @@ -# KCL Cheat Sheet - -![](/img/docs/reference/cheatsheets/cheatsheet.png) - -[Download PDF](https://github.com/kcl-lang/kcl-lang.io/blob/main/cheatsheet/cheatsheet.pdf) diff --git a/versioned_docs/version-0.5.6/reference/lang/_category_.json b/versioned_docs/version-0.5.6/reference/lang/_category_.json deleted file mode 100644 index 4c823148..00000000 --- a/versioned_docs/version-0.5.6/reference/lang/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Tutorial", - "position": 1 -} diff --git a/versioned_docs/version-0.5.6/reference/lang/codelab/_category_.json b/versioned_docs/version-0.5.6/reference/lang/codelab/_category_.json deleted file mode 100644 index 2e047bcb..00000000 --- a/versioned_docs/version-0.5.6/reference/lang/codelab/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Code Lab", - "position": 2 -} diff --git a/versioned_docs/version-0.5.6/reference/lang/codelab/collaborative.md b/versioned_docs/version-0.5.6/reference/lang/codelab/collaborative.md deleted file mode 100644 index 84ee8160..00000000 --- a/versioned_docs/version-0.5.6/reference/lang/codelab/collaborative.md +++ /dev/null @@ -1,345 +0,0 @@ ---- -title: "Co-configuration with config operations" -linkTitle: "Co-configuration with config operations" -type: "docs" -weight: 2 -description: Co-configuration with config operations -sidebar_position: 3 ---- - -## 1. Introduction - -KCL is a simple and easy-to-use configuration language, where users can simply write the reusable configuration code. - -In this codelab, we will learn how to write the config in a collaborative way using the KCL config operation features. - -### What We Will Learn - -1. Define schemas and organize project directories. -2. Create multiple environment configurations via the KCL config operation features. -3. Configure compiling parameters and tests. - -## 2. Define Schemas and Organize Project Directories - -### Schema Definitions - -Suppose we want to define a server configuration with certain attributes, we can create a simple config by creating a `server.k`, we can fill in the following code as below which defines a reusable schema of the configuration of a server. - -```python -import units - -type Unit = units.NumberMultiplier - -schema Server: - replicas: int = 1 - image: str - resource: Resource = {} - mainContainer: Main = {} - labels?: {str:str} - annotations?: {str:str} - -schema Main: - name: str = "main" - command?: [str] - args?: [str] - ports?: [Port] - -schema Resource: - cpu?: int = 1 - memory?: Unit = 1024Mi - disk?: Unit = 10Gi - -schema Port: - name?: str - protocol: "HTTP" | "TCP" - port: 80 | 443 - targetPort: int - - check: - targetPort > 1024, "targetPort must be larger than 1024" -``` - -In the code above, we define a schema named `Server`, which represents the configuration type that the user will write, which contains some basic type attributes (e.g., `replicas`, `image`, etc) and some composite type attributes (e.g., `resource`, `main`, etc). In addition to some basic types mentioned in the [schema codelab](./schema.md), we can see two types in the above code `Unit` and `units.NumberMultiplier`. Among them, `units.NumberMultiplier` denotes the KCL number unit type, which means that a natural unit or binary unit can be added after the KCL number, such as `1K` for `1000`, `1Ki` for `1024`. `Unit` is the type alias of `units.NumberMultiplier`, which is used to simplify the writing of type annotations. - -### Project Directories - -In order to complete the collaborative configuration development, we first need a configuration project, which contains the configuration of the test application and the differential configuration of different environments, so we are creating the following project directory: - -``` -. -├── appops -│ └── test_app -│ ├── base -│ │ └── base.k -│ ├── dev -│ │ ├── ci-test -│ │ │ └── stdout.golden.yaml -│ │ ├── kcl.yaml -│ │ └── main.k -│ └── prod -│ ├── ci-test -│ │ └── stdout.golden.yaml -│ ├── kcl.yaml -│ └── main.k -├── kcl.mod -└── pkg - └── sever.k -``` - -The directory of the project mainly contains three parts: - -- `kcl.mod`: The file used to identify the root directory of the KCL project. -- `pkg`: `Server` Schema structure reused by different application configurations. -- `appops`: Server configurations of different applications, currently only one application `test_app` is placed. - - `base`: Application common configurations for all environments. - - `dev`: Application configuration for the development environment. - - `prod`: Application configuration for the production environment. - -The meaning of `base.k`, `main.k`, `kcl.yaml` and `ci-test/stdout.golden.yaml` will be mentioned in subsequent sections. - -## 3. Create multiple environment configurations via the KCL config operation features - -### Create a baseline configuration - -After we have organized the project directory and the basic server configuration model, we can write the configuration of the user application. We can create our own test application folder `test_app` and place it in the application configuration folder `appops`. - -For the configuration of an application, we often divide it into a basic configuration and the differential configuration of multiple environments and merge them. Through the configuration merging feature of KCL, we can easily do this. Assuming that we have two configurations of development environment and production environment, we can create three folders: `base`, `dev` and `prod` to store baseline, development environment and production environment configurations respectively. First, we write the configuration of `base/base.k`: - -```python -import pkg - -server: pkg.Server { - # Set the image with the value "nginx:1.14.2" - image = "nginx:1.14.2" - # Add a label app into labels - labels.app = "test_app" - # Add a mainContainer config, and its ports are [{protocol = "HTTP", port = 80, targetPort = 1100}] - mainContainer.ports = [{ - protocol = "HTTP" - port = 80 - targetPort = 1100 - }] -} -``` - -As in the above code, we use the `import` keyword in `base.k` to import the `Server` schema placed under `pkg` and use it to instantiate a configuration named `server`, in which we set `image` attribute to `"nginx:1.14.2"`, and a label `app` with the value `test_app` is added. In addition, we also added the configuration of the main container `mainContainer` with the value `[{protocol = "HTTP", port = 80, targetPort = 1100}]` for the ports attribute. - -KCL command: - -```bash -kcl appops/test_app/base/base.k -``` - -Output: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2 - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app -``` - -At this point, we have a baseline configuration. - -### Create multiple environment configurations - -Next we configure a differentiated multi-environment configuration. First assume that we want to use a temporary image of our own `nginx:1.14.2-dev` in the development environment, and then use it to override the server configuration in the baseline, we can write the following configuration in `dev/main.k`: - -```python -import pkg - -server: pkg.Server { - # Override the image declared in the base - image = "nginx:1.14.2-dev" -} -``` - -KCL command: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -Output: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app -``` - -It can be seen that the `image` field of the output YAML is overwritten to `nginx:1.14.2-dev`. Suppose we also want to add a label to the `dev` environment with a key of `env` and a value of `dev`, we add the following code to `dev/main.k`: - -```python -import pkg - -server: pkg.Server { - # Override the image declared in the base - image = "nginx:1.14.2-dev" - # Union a new label env into base labels - labels.env = "dev" -} -``` - -KCL command: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app - env: dev -``` - -It can be seen that there are two labels in the `labels` field of the output YAML. - -In addition, we can also use the `+=` operator to add new values to list type attributes, such as the `mainContainer.ports` configuration in the baseline environment, continue to modify the code in `dev/main.k`: - -```python -import pkg - -server: pkg.Server { - # Override the base image. - image = "nginx:1.14.2-dev" - # Union a new label env into base labels. - labels.env = "dev" - # Append a port into base ports. - mainContainer.ports += [{ - protocol = "TCP" - port = 443 - targetPort = 1100 - }] -} -``` - -KCL command: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -Output: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - - protocol: TCP - port: 443 - targetPort: 1100 - labels: - app: test_app - env: dev -``` - -Using the same method, we can build the production configuration, write the code in the `dev/main.k` file, and add a label to it. - -```python -import pkg - -server: pkg.Server { - # Union a new label env into base labels - labels.env = "prod" -} -``` - -KCL command: - -```bash -kcl appops/test_app/base/base.k appops/test_app/prod/main.k -``` - -Output: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2 - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app - env: prod -``` - -## 4. Configure compiling parameters and tests - -In the previous section, we built a multi-environment configuration through code. It can be seen that the KCL command line compilation parameters of different environments are similar, so we can configure these compilation parameters into a file and input them to the KCL command line for invocation. Configure the following code in `dev/kcl.yaml`: - -```yaml -kcl_cli_configs: - files: - - ../base/base.k - - main.k - output: ./ci-test/stdout.golden.yaml -``` - -Then we can compile the configuration in the development environment with the following command: - -```bash -cd appops/test_app/dev && kcl -Y ./kcl.yaml -``` - -In addition, we have configured the `output` field in `dev/kcl.yaml` to output YAML to a file for subsequent configuration distribution or testing. You can verify that the application's configuration is as expected by walking through the `kcl.yaml` builds in each environment and comparing with `./ci-test/stdout.golden.yaml`. - -## 5. The Final Step - -Congratulations! - -We have completed the third lesson about KCL. diff --git a/versioned_docs/version-0.5.6/reference/lang/codelab/index.md b/versioned_docs/version-0.5.6/reference/lang/codelab/index.md deleted file mode 100644 index dbe554a9..00000000 --- a/versioned_docs/version-0.5.6/reference/lang/codelab/index.md +++ /dev/null @@ -1 +0,0 @@ -# Code Lab diff --git a/versioned_docs/version-0.5.6/reference/lang/codelab/schema.md b/versioned_docs/version-0.5.6/reference/lang/codelab/schema.md deleted file mode 100644 index 02f792d4..00000000 --- a/versioned_docs/version-0.5.6/reference/lang/codelab/schema.md +++ /dev/null @@ -1,817 +0,0 @@ ---- -title: "Write complex config using KCL Schema" -linkTitle: "Write complex config using KCL Schema" -type: "docs" -weight: 2 -description: Write complex config using KCL Schema -sidebar_position: 2 ---- - -## 1. Introduction - -KCL is a simple and easy-to-use configuration language, where users can simply write the reusable configuration code. - -In this codelab, we will learn how to write customized config using KCL, such that we can define a schema and write the config in a collaborative way. - -### What We Will Learn - -1. Define a simple schema -2. Set default immutable values to schema fields -3. Create config based on a simple schema -4. Write complex logic in schema -5. Create a new schema via schema combinations -6. Create a config of a deeply nested schema using dict/map -7. Create new schema via schema inheritance -8. Create new schema via multiple mixin schemas -9. Declare validation rules for the schema -10. Config schema output layout -11. Share and reuse schema - -## 2. Write Simple Schema - -Suppose we want to define a workload with certain attributes, we can create a simple config by creating a `my_config.k`, we can fill in the following code as below which defines a reusable schema of the configuration of deploy. - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels: {str:str} -``` - -In the code above, `cpu` and `memory` are defined as int value; `name`, `image` and `service` are string; `command` is a list of string type; `labels` is a dict type, whose key type and value type are both string. - -Besides, each attribute **must** be assigned with a not-None value as a schema instance unless it is modified by a question mark **?** as an optional attribute. - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels?: {str:str} # labels is an optional attribute -``` - -When there is an inheritance relationship: - -- If the attribute is optional in the base schema, it could be optional or required in the sub-schema. -- If the attribute is required in the base schema, it must be required in the sub-schema. - -## 3. Enhance Schema as Needed - -Suppose we need to set default values to service and replica, we can make them as below: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str = "my-service" # defaulting - replica: int = 1 # defaulting - command: [str] - labels?: {str:str} # labels is an optional attribute -``` - -And then we can set the service type annotation as the string literal type to make it immutable: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: "my-service" = "my-service" - replica: int = 1 - command: [str] - labels?: {str:str} -``` - -In the schema, type hint is a `must`, for example we can define cpu as `cpu: int`. - -Specially, we can define a string-interface dict as `{str:}`, and in case we want to define an object or interface, just define as `{:}`. - -## 4. Create Config Based on Simple Schema - -Now we have a simple schema definition, we can use it to define config as: - -```python -nginx = Deployment { - name = "my-nginx" - cpu = 256 - memory = 512 - image = "nginx:1.14.2" - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } -} -``` - -Run with the following KCL command, we should be able to see the generated yaml files as the output as below: - -KCL command: - -``` - kcl my_config.k -``` - -Stdout: - -```yaml -nginx: - name: my-nginx - cpu: 256 - memory: 512 - image: nginx:1.14.2 - service: my-service - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -> Check the manual and specification out for more details about collection data types and block. - -In addition, the **config selector expressions** can be used to init a schema instance, and we can ignore the comma at the end of the line in the config expression. - -```python -nginx = Deployment { - name = "my-nginx" - cpu = 256 - memory = 512 - image = "nginx:1.14.2" - command = ["nginx"] # Ignore the comma at the end of the line - labels.run = "my-nginx" # A dict variable in schema can use selector expressions - labels.env = "pre-prod" # A dict variable in schema can use selector expressions -} -``` - -## 5. Write More Complex Logic in Schema - -Suppose we have some schema logic, we can wrapper it into schema: - -```python -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - image: str - service: "my-service" = "my-service" - replica: int = 1 - command: [str] - labels?: {str:str} - - _cpu = 2048 - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 -``` - -Now, we can define a config by creating a schema instance and pass in priority as an argument to schema: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -Run with kcl, we should see the generated yaml files as output as below: - -KCL command: - -``` -kcl my_config.k -``` - -Stdout: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - image: nginx:1.14.2 - service: my-service - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 6. Create New Schema via Schema Combinations - -Now we want to define a detailed schema with service and volumes, we can do it as follows: - -```python -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - volumes?: [Volume] - image: str - service?: Service - replica: int = 1 - command: [str] - labels?: {str:str} - - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 - -schema Port: - name: str - protocol: str - port: int - targetPort: int - -schema Service: - name: "my-service" = "my-service" - ports: [Port] - -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -In this case, Deployment is composed of Service and a list of Volumes, and Service is composed of a list of Ports. - -## 7. Create Config of Deeply Nested Schema using Dict/Map - -Now we have a new Deployment schema, however, we may notice that it contains multiple layers of nested structures, in fact, this is very common in complex structure definitions, and we often have to write imperative assembly code to generate the final structure. - -With KCL, we can create the config with simple dict declaration, with the capability of full schema initialization and validation. For example, we can simply config nginx by the new Deployment schema as follows: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -Run with KCL, we will see the generated yaml files as below: - -KCL command: - -``` -kcl my_config.k -``` - -Stdout: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -Note that, the dict that we use to define Deployment config must be aligned with the schema definition, otherwise we will get an error. For example, suppose we define a wrong type of service port as below: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = [80] # wrong data type, trying to assign List to int - targetPort = 9376 - }] -} -``` - -Run with KCL, we will see the error message as output as below: - -KCL command: - -```python -kcl my_config.k -``` - -Stderr: - -``` -The type got is inconsistent with the type expected: expect int, got [int(80)] -``` - -## 8. Declare Schema Validation Rules - -Now we have seen a complex schema, in which every field has a type hint to make it less error-prone. But this is not good enough, we want to support more enhanced verifications to our schemas, so that code errors in schemas and configs can be discovered as soon as possible. - -Lots of validation rules, like None type check, range check, value check, length check, regular expression matching, enum check have already been added or in progress. Here is a code sample: - -```python -import regex - -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - volumes?: [Volume] - image: str - service?: Service - replica: int = 1 - command: [str] - labels?: {str:str} - - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 - - check: - multiplyof(cpu, 256), "cpu must be a multiplier of 256" - regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$"), "image name should be like 'nginx:1.14.2'" - 1 <= replica < 100, "replica should be in range (1, 100)" - len(labels) >= 2 if labels, "the length of labels should be large or equal to 2" - "env" in labels, "'env' must be in labels" - len(command) > 0, "the command list should be non-empty" - -schema Port: - name: str - protocol: str - port: int - targetPort: int - - check: - port in [80, 443], "we can only expose 80 and 443 port" - protocol in ["HTTP", "TCP"], "protocol must be either HTTP or TCP" - 1024 < targetPort, "targetPort must be larger than 1024" - -schema Service: - name: "my-service" = "my-service" - ports: [Port] - - check: - len(ports) > 0, "ports list must be non-empty" - -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -Since the attributes defined by the schema are **required** by default, the verification that judges that the variable cannot be None/Undefined can be omitted. - -```python -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -Now we can write the config based on the new schema and expose config errors in time. For example, with the invalid config as below: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1142" # image value is not matching the regex - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -Every field is type-valid, but the image name is invalid. - -Run with KCL, we will see the error message as below: - -KCL command: - -``` -kcl my_config.k -``` - -Stderr: - -``` -Schema check is failed to check condition: regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$"), "image name should be like 'nginx:1.14.2'" -``` - -> The verification capability of KCL covers the verification defined by Openapi so that we can write any API verifications through KCL. - -## 9. Create New Schema via Schema Inheritance - -Now we have a solid Deployment schema definition and we can use it to declare config. - -Usually, schema Deployment will be used in multiple scenarios. We can directly use the schema to declare the configurations in different use cases (see the above section), or we can produce a more specific schema definition through inheritance. - -For example, we can use the Deployment schema as a basis, to define the nginx's base schema, and extend the definition -in each scenario. - -In this case, we define some commonly used attributes. Please note that we mark the name to be immutable with the 'final' keyword to prevent it from being overwritten. - -```python -schema Nginx(Deployment): - """ A base nginx schema """ - name: "my-nginx" = "my-nginx" - image: str = "nginx:1.14.2" - replica: int = 3 - command: [str] = ["nginx"] - -schema NginxProd(Nginx): - """ A prod nginx schema with stable configurations """ - volumes: [Volume] = [{ - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - """ A volume mapped to host path """ - service: Service = { - ports = [{ - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] - } - """ An 80 port to target backend server """ -``` - -Now we have some static configurations for nginx. It is recommended to declare configurations that we think are static there, and put more dynamic configurations as below: - -```python -nginx = Nginx { - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -```python -nginx = NginxProd { - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -Now, we can simply define nginx prod config just with runtime label value "prod" which is not that static. - -In fact, under some complex situation, we can split all configurations into the basic, business, and environment configuration definitions in this way, and achieve collaboration among team members based on this. - -Run with KCL, we will see the generated yaml files as output as below: - -KCL command: - -``` -kcl prod_config.k -``` - -Stdout: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 3 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 10. Create New Schema by Multiple Protocol and Mixin Schemas Inheritance - -Now, we can complete the declaration of the server configuration through the Deployment schema. - -However, usually, the actual situation is more complicated, and the deployment may have a variety of optional variable accessories. - -For example, we want to support a persistent volume claim based on an existing schema, as a reusable Kubernetes schema. In this case, we can just wrapper it with a `mixin` and a `protocol` as follows: - -```python -import k8spkg.api.core.v1 - -protocol PVCProtocol: - pvc?: {str:} - -mixin PersistentVolumeClaimMixin for PVCProtocol: - """ - PersistentVolumeClaim (PVC) sample: - Link: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims - """ - - # Mix in a new attribute `kubernetesPVC` - kubernetesPVC?: v1.PersistentVolumeClaim - - if pvc: - kubernetesPVC = v1.PersistentVolumeClaim { - metadata.name = pvc.name - metadata.labels = pvc.labels - spec = { - accessModes = pvc.accessModes - resources = pvc.resources - storageClassName = pvc.storageClassName - } - } -``` - -With this PersistentVolumeClaimMixin, we define a PVC schema with a clear `user interface`, and use Kubernetes PVC as an implementation. Then, we can define a server schema with Deployment schema, and PVC mixin schema. - -``` -schema Server(Deployment): - mixin [PersistentVolumeClaimMixin] - pvc?: {str:} - """ pvc user interface data defined by PersistentVolumeClaimMixin """ -``` - -In the Server schema, Deployment is the base schema, and PersistentVolumeClaimMixin is an optional add-on whose user interface data is `pvc?: {str:}`. - -Note, the `mixin` is often used to add new attributes to the host schema, or to modify the existing attributes of the host schema. Thus, `mixin` can use the attributes in the host schema. Since the `mixin` is designed to be reusable, we need an additional `protocol` to constrain the attribute names and types in the host schema for the `mixin`. - -Now, if we want a deploy with a PVC, just declare as user interface: - -```python -server = Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] - pvc = { - name = "my_pvc" - accessModes = ["ReadWriteOnce"] - resources.requests.storage = "8Gi" - storageClassName = "slow" - } -} -``` - -Run with kcl, we will see the generated yaml files as output as below: - -KCL command: - -``` -kcl server.k -``` - -Stdout: - -```yaml -server: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod - pvc: - name: my_pvc - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 8Gi - storageClassName: slow ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: my_pvc -spec: - accessModes: - - ReadWriteOnce - storageClassName: slow - resources: - requests: - storage: 8Gi -``` - -If we don't want a persistent volume, just remove the pvc config block. - -## 11. Share and Reuse Schema - -The Server schema could be shared via `import`, we can simply package our code with KCL. - -```python -import pkg - -server = pkg.Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -Another skill we should know about sharing code is, modules under the same package do not need to import each other. - -Suppose we have models in a pkg: - -``` -pkg/ - - deploy.k - - server.k - - pvc.k -``` - -And in `server.k`, we can just use Deployment schema in `deploy.k` and pvc schema in `pvc.k` without import: - -```python -# no import needed -schema Server(Deployment): - mixin [PersistentVolumeClaimMixin] - pvc?: {str:} - """ pvc user interface data defined by PersistentVolumeClaimMixin """ -``` - -And then users must import the pkg to use it as a whole: - -```python -import pkg - -server = pkg.Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [pkg.Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } - service.ports = [pkg.Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -Run kcl command: - -``` -kcl pkg_server.k -``` - -Output: - -```yaml -server: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 12. The Final Step - -Congratulations! - -We have completed the second lesson about KCL, we have used KCL to replace our key-value text file to get better programming support. diff --git a/versioned_docs/version-0.5.6/reference/lang/codelab/simple.md b/versioned_docs/version-0.5.6/reference/lang/codelab/simple.md deleted file mode 100644 index 56be5805..00000000 --- a/versioned_docs/version-0.5.6/reference/lang/codelab/simple.md +++ /dev/null @@ -1,495 +0,0 @@ ---- -title: "Write simple config with KCL" -linkTitle: "Write simple config with KCL" -type: "docs" -weight: 2 -description: Write simple config with KCL -sidebar_position: 1 ---- - -## 1. Introduction - -KCL is a simple and easy-to-use configuration language, where users can simply write the reusable configuration code. - -In this first codelab, we will learn how to write a simple config with KCL. - -Learning this codelab only requires basic programming knowledge, and experience with python will make it even easier. - -### What We Will Learn - -1. Write simple key-value configuration in a programmable way -2. Write simple logic in KCL code -3. Write collections in KCL code -4. Test and debug with KCL code -5. Use built-in support in KCL code -6. Share and reuse KCL code -7. Write config with dynamic input arguments - -## 2. Write Key-Value Pairs - -Generate a simple config by creating a `my_config.k`, we can fill in the following code without strict format which describes the configuration of deploy. - -```python -cpu = 256 -memory = 512 -image = "nginx:1.14.2" -service = "my-service" -``` - -In the code above, cpu and memory are declared as int value, while image and service are string literal. - -Run with KCL, we will see the generated data in yaml format as below: - -KCL command: - -```bash -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -The exported variable is immutable by default so that once it is declared, we can't modify it some where else. - -## 3. Write Simple Logic - -Sometimes we want to write a logic in configuration, then we can use: - -- Mutable and non-exported variable starting with `_` -- If-else statement - -A non-exported variable means it will not appear in the output YAML, and it can be assigned multiple times. - -Here is a sample to show how to adjust the resource with conditions. - -KCL command: - -```python -kcl my_config.k -``` - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -image = "nginx:1.14.2" -service = "my-service" -``` - -Run with KCL, we will see the generated data in yaml format as below: - -```python -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -.. note:: -KCL has rich support of operators and string member functions, please read manual and specification for more details. - -## 4. Write Collections - -We can use collections to represent complex data types. The collections which are already supported are: - -- list -- dict - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -command = ["nginx"] # a list -labels = {run = "my-nginx"} # a dict -image = "nginx:1.14.2" -service = "my-service" -``` - -Run with kcl, we will see the generated data as yaml format as below: - -KCL command: - -```bash -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx -image: nginx:1.14.2 -service: my-service -``` - -> Check manual and specification out for more about collection date type and member functions. - -## 5. Append Items Into Collections - -We can combine logical expressions, comprehensions, slices, unions and other characteristics to dynamically add elements to the collection - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable -_env = "pre-prod" - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -_command = ["nginx"] # a list -_command = _command + ["-f", "file"] # Append items into command using + operator to contact two lists -command = [c.lower() for c in _command] # Take each element in the list to lowercase -_labels = { - run = "my-nginx" - if _env: - env = _env # Append a dict key-value pair when the _env is not None/Undefined or empty using if expressions -} # a dict -labels = _labels -image = "nginx:1.14.2" -service = "my-service" -``` - -Run with kcl, we will see the generated data as yaml format as below: - -```python -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 256 -memory: 512 -command: - - nginx - - -f - - file -labels: - run: my-nginx -image: nginx:1.14.2 -service: my-service -``` - -## 6. Write Assert - -To make code testable and robust, we can verify config data with assertions. - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -command = ["nginx"] # a list -labels = {run = "my-nginx"} # a dict -image = "nginx:1.14.2" -service = "my-service" -assert "env" in labels, "env label is a must" -assert cpu >= 256, "cpu cannot be less than 256" -``` - -Run with KCL, we will see eval failure with an error message as output as below: - -```bash -kcl my_config.k -``` - -Stderr: - -```bash -Assertion failure: env label is a must. -``` - -After adding env:pre-prod pair into labels, we will get the output as: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 7. Use Handy Built-in Support - -What's more, we can use built-in functions to help we debug or simplify coding. - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -_name = "nginx" -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # a list -labels = { - run = "my-{}".format(_name) - env = "pre-prod" -} # a dict -image = "{}:1.14.2".format(_name) # string format -service = "my-service" - -# debugging -print(labels) # debugging by print - -# test -assert len(labels) > 0, "labels can't be empty" # use len() to get list length -assert "env" in labels, "env label is a must" -assert cpu >= 256, "cpu cannot be less than 256" -``` - -This sample shows how we use `format()`, `len()`, `print()` function to help customize the config. - -Run with KCL, we will see the generated data in yaml format as below: - -KCL command: - -```bash -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -run: my-nginx -env: pre-prod -``` - -Note: more built-in functions and modules can be seen in spec/module - -## 8. Reuse Variables in Another Module - -To make our code well-organized, we can simply separate our code to `my_config.k` and `my_config_test.k`. - -Config data defined in `my_config.k`, - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 -_name = "nginx" - -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # a list -labels = { - run = "my-{}".format(_name) - env = "pre-prod" -} # a dict -image = "{}:1.14.2".format(_name) # string format -service = "my-service" -``` - -And test code defined in `my_config_test.k`, in which we can import `my_config.k`: - -```python -import my_config - -# debugging -print(my_config.labels) # debugging by print - -# test -assert len(my_config.labels) > 0, "labels can't be empty" # use len() to get list length -assert "env" in my_config.labels, "env label is a must" -assert my_config.cpu >= 256, "cpu cannot be less than256" -``` - -## 9. Config with Input Arguments - -Sometimes we need to get external input via parameters dynamically from the end user or platform. - -In this case, we can pass in `priority` and `env` on demand: - -- Pass in arguments: `-D priority=1 -D env=pre-prod` -- Get value by `option` keyword in KCL code - -```python -_priority = option("priority") # a non-exported and mutable variable -_env = option("env") # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -_name = "nginx" -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # a list -labels = { - run = "my-{}".format(_name) - env = _env -} # a dict -image = "{}:1.14.2".format(_name) # string format -service = "my-service" -``` - -Run with KCL, we will see the generated data in yaml format as below: - -```bash -kcl my_config.k -D priority=2 -D env=pre-prod -``` - -Stdout: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 10. Simplify Logic Expression using Dict - -When we need to write complex logic, we can use dict to simplify the writing of logic. - -```python -_priority = option("priority") # a non-exported and mutable variable -_env = option("env") # a non-exported and mutable variable -_priorityCpuMap = { - "1" = 256 - "2" = 512 - "3" = 1024 -} -# Using a dict to simplify logic and the default value is 2048 -_cpu = _priorityCpuMap[_priority] or 2048 -_name = "nginx" -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # a list -labels = { - run = "my-{}".format(_name) - env = _env -} # a dict -image = "{}:1.14.2".format(_name) # string format -service = "my-service" -``` - -Run with KCL, we will see the generated data in yaml format as below: - -KCL command: - -```bash -kcl my_config.k -D priority=2 -D env=pre-prod -``` - -Stdout: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 11. The Final Step - -Congratulations! - -We have completed the first lesson about KCL, we have used KCL to replace our key-value text file to get better programming support. - -Please check schema codelab out now to learn how to write an advanced config collaboratively with KCL `schema` mechanism. diff --git a/versioned_docs/version-0.5.6/reference/lang/error/_category_.json b/versioned_docs/version-0.5.6/reference/lang/error/_category_.json deleted file mode 100644 index 95062745..00000000 --- a/versioned_docs/version-0.5.6/reference/lang/error/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Errors and Warnings", - "position": 4 -} diff --git a/versioned_docs/version-0.5.6/reference/lang/error/index.md b/versioned_docs/version-0.5.6/reference/lang/error/index.md deleted file mode 100644 index 15fbda6f..00000000 --- a/versioned_docs/version-0.5.6/reference/lang/error/index.md +++ /dev/null @@ -1 +0,0 @@ -# Errors and Warnings diff --git a/versioned_docs/version-0.5.6/reference/lang/spec/_category_.json b/versioned_docs/version-0.5.6/reference/lang/spec/_category_.json deleted file mode 100644 index 7b24faae..00000000 --- a/versioned_docs/version-0.5.6/reference/lang/spec/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Spec", - "position": 3 -} diff --git a/versioned_docs/version-0.5.6/reference/lang/spec/codestyle.md b/versioned_docs/version-0.5.6/reference/lang/spec/codestyle.md deleted file mode 100644 index dd40925e..00000000 --- a/versioned_docs/version-0.5.6/reference/lang/spec/codestyle.md +++ /dev/null @@ -1,608 +0,0 @@ ---- -title: "Code Style" -linkTitle: "Code Style" -type: "docs" -weight: 2 -description: Code Style ---- - -## Introduction - -This document gives the KCL code style conventions. Good code style can play a vital role in the development and maintenance of the project. We can learn the KCL code style by referring to the full text of the description and sample codes, and use KCL format and lint tools to help coding. - -## Source File Encoding - -KCL file encoding should always use **UTF-8**. - -## Code Layout - -### Indentation - -Use **4 spaces** per indentation level such as in the schema statement and if statement. - -```python -schema PersonA: - name: str # non-recommended - age: int - -schema PersonB: - name: str # recommended - age: int - -if True: - a = 1 # recommended -elif True: - b = 2 # non-recommended -else: - c = 3 # non-recommended -``` - -The closing brace/bracket/parenthesis on multiline constructs should line up under **first character** of the line that starts the multiline construct, as in: - -```python -# valid and recommended -my_list = [ - 1, 2, 3, - 4, 5, 6, -] -``` - -```python -# invalid -my_list = [ - 1, 2, 3, - 4, 5, 6, - ] -``` - -### Tabs or Spaces - -- Spaces are the preferred indentation method. -- Tabs should be used solely to remain consistent with code that is already indented with tabs. - -KCL disallows mixing the use of tabs and spaces for indentation and an error will be reported during the compile time. - -### Blank Lines - -- Surround top-level schema definitions with one blank line. -- Keep at most one blank line between two statements and remove redundant blank lines. -- Remove extra blank characters at the end of the line -- Remove extra blank characters in a blank line. -- There is no blank line in the header of the file, start writing from the first line. -- Only one blank line will be left at the end of the KCL file. - -```python -# Remove blank lines in the file header -a = 1 # Remove white space at the end of the line -# Keep at most one blank line between two statements - -b = 2 -# Only leave one blank line at the end of the file - -``` - -### Inline Expressions - -Write indentation of KCL `if`, `elif`, `else` and other conditions on different lines. - -```python -if True: print("") # non-recommended - -if True: # recommended - print("") -``` - -### Line Break and Continuation lines - -- For long expressions, use the line continuation symbol `\` and keep the left end of multiple expressions aligned. -- The 4-space rule is optional for continuation lines. - -```python -anotherString = "Too long expression " + \ - "Too long expression " # non-recommended - -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " # recommended -``` - -### When to Use Trailing Commas - -- Always use trailing commas. - -### Maximum Line Length - -- The general recommendation is **80 characters** but not absolute. - -### Symbol Break White Space - -Try to keep the spaces between different symbols, but not too many, usually one is good. - -```python -a = 1 # recommended -b = 1 + 2 # non-recommended -``` - -### Whitespace in Expressions and Statements - -Avoid extraneous whitespace in the following situations: - -- The parentheses `()`, brackets `[]` and braces `{}` in the expression have no spaces inside. - -```python -a = (1 + 2) # recommended -b = ( 1 + 2 ) # non-recommended - -c = [1, 2, 3] # recommended -d = [ 1, 2, 3 ] # non-recommended - -e = {key = "value"} # recommended -f = { key = "value" } # non-recommended -``` - -```python -spam(ham[1], {eggs = 2}) # recommended -spam( ham[ 1 ], { eggs = 2 } ) # non-recommended -``` - -- Between a trailing comma and a following close parenthesis. - -```python -foo = [0,] # recommended -bar = [0, ] # non-recommended -``` - -- Immediately before the open parenthesis that starts the argument list of a function call. - -```python -print(1) # recommended -print (1) # non-recommended -``` - -- Immediately before the open parenthesis that starts indexing or slicing. - -```python -dct = {key = "value"} -lst = [1, 2, 3] - -a = dct['key'] # recommended -b = dct ['key'] # non-recommended - -c = lst[0] # recommended -d = lst [1] # non-recommended -``` - -- More than one space around an assignment `=` (or other) operator to align it with another. - -```python -# recommended: -x = 1 -y = 2 -long_variable = 3 -``` - -```python -# non-recommended: -x = 1 -y = 2 -long_variable = 3 -``` - -- Always surround these binary operators with a single space on either side: assignment (`=`), augmented assignment (`+=`, `-=`, etc.), comparisons (`==`, `<`, `>`, `!=`, `<=`, `>=`, `in`, `not in`, `is`, `is not`), booleans (`and`, `or`, `not`). - -```python -# recommended: -i = i + 1 -submitted += 1 -x = x * 2 - 1 -hypot2 = x * x + y * y -c = (a + b) * (a - b) -``` - -```python -# non-recommended: -i = i+1 -submitted+=1 -x = x*2 - 1 -hypot2 = x*x + y*y -c = (a+b) * (a-b) -``` - -- Break one blank line between different statements e.g., import, schema and expression statements. - -```python -import math -import net - -schema Person: - name: str - -person = Person { - name = "Alice" -} -``` - -- Compound statements (multiple statements on the same line) are generally discouraged - -```python -# recommended: -if foo == 'blah': - do_blah_thing() -do_one() -do_two() -do_three() -``` - -```python -# non-recommended: -if foo == 'blah': do_blah_thing() -do_one(); do_two(); do_three() -``` - -## Naming Conventions - -### Naming Styles - -The following naming styles are commonly distinguished: - -- `b` (single lowercase letter) -- `B` (single uppercase letter) -- `lowercase` -- `lower_case_with_underscores` -- `UPPERCASE` -- `UPPER_CASE_WITH_UNDERSCORES` -- `CapitalizedWords` (capitalize all letters of the acronym in `CapitalizedWords` e.g., `HTTPServer`.) -- `mixedCase` (differs from `CapitalizedWords` by initial lowercase character) -- `Capitalized_Words_With_Underscores` (ugly and non-recommended) - -### Names to Avoid - -Never use the characters 'l' (lowercase letter el), 'O' (uppercase letter oh), or 'I' (uppercase letter eye) as single-character variable names. - -### Package and Module Names - -Package and module names should have short, all-lowercase names. - -### Schema Names - -Schema names should normally use the `CapWords` convention. - -### Constants - -Constants are usually defined on a module level and written in all capital letters with underscores separating words such as `MAX_OVERFLOW` and `TOTAL`. - -## Import - -- Imports should usually be on separate lines. -- Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants. -- Imports should be grouped in the following order and we should put a blank line between each group of imports. - 1. Standard library imports. - 2. Related third party plugin imports. - 3. Local application/library specific imports. -- Use an alias when we import a package name with a relatively long path. -- Leave only one space between the Import keyword and the package name. - -```python -import net # recommended -import math # non-recommended - -import ..pkg.internal_pkg as alias_pkg # recommended -``` - -## Comments - -- Comments should be complete sentences. The first word should be capitalized unless it is an identifier that begins with a lower-case letter (never alter the case of identifiers!). -- Block comments generally consist of one or more paragraphs built out of complete sentences, with each sentence ending in a period. -- Use two spaces after a sentence-ending period in multi-sentence comments, except after the final sentence. - -### Block Comments - -Block comments generally apply to some (or all) code that follows them, and are indented to the same level as that code. Each line of a block comment starts with a `#` and **a single space**(unless it is indented text inside the comment). - -Paragraphs inside a block comment are separated by a line containing a single `#`. - -```python -# This is a block comment -a = 1 -``` - -### Inline Comments - -Use inline comments sparingly. - -An inline comment is a comment on the same line as a statement. Inline comments should be separated by **at least two spaces** from the statement. They should start with a `#` and **a single space**. - -```python -a = 1 # This is an inline comment -``` - -### Documentation Strings - -Write doc strings for all public schema and schema attributes. - -```python -schema Person: - """ - Person schema doc string - """ - - name: str = "Alice" -``` - -## String - -- Single-quoted strings and double-quoted strings are the same in KCL. -- Use double-quoted string with lowercase prefix -- For triple-quoted strings, always use double quote characters to be consistent with the docstring convention. -- When a string contains single or double quote characters, use the other one to avoid backslashes in the string. - -```python -strC = "'123'" # recommended -strD = "\"123\"" # non-recommended -``` - -## Number - -- Use lowercase for the prefix of non-decimal numbers, and use uppercase for the number itself. - -```python -foo = 0xAB # recommended -bar = 0Xab # non-recommended -``` - -## Operators - -### Binary Operators - -- Leave only one space before and after the assignment `=`. -- Leave only one space before and after the binary operator in the expression. - -```python -a = 1 # recommended -b=2 # non-recommended -c= 3 # non-recommended -d =4 # non-recommended - -_value = (1 + 2 * 3) # recommended -_value = (1+2*3) # non-recommended -``` - -### Unary Operators - -- There is only no space after unary operators e.g., `~`, `+` and `-`. - -```python -_value = 1 + -2 * ~3 # recommended -_value = 1+ - 2 * ~ 3 # non-recommended -``` - -- There is no space after `**` and `*` in the dict/list deduction expressions and argument expressions. - -```python -_list = [1, 2, 3] -_list = [*_list, [4, 5 ,6]] # recommended -_list = [* _list, [4, 5 ,6]] # non-recommended - -_dict = {**{k = "v"}, **{k = "v"}} # recommended -_dict = {** {k = "v"}, ** {k = "v"}} # non-recommended -``` - -- Use `is not` operator rather than `not ... is`. - -```python -# recommended: -if foo is not None: - a = 1 -``` - -```python -# non-recommended: -if not foo is None: - a = 1 -``` - -## Dict - -- There is no space before the colon `:` at the instantiation of KCL dict and schema config, and a space after the colon `:`. - -```python -d1 = {labels: {k1 = "v1"}} # recommended -d2 = {labels : {k1 = "v1"}} # non-recommended -d3 = {labels :{k1 = "v1"}} # non-recommended -``` - -- Always surround the override attribute operator `=` and the insert attribute operator `+=` with a single space on either sid. - -```python -d1 = {key = "value"} # recommended -d2 = {key= "value"} # non-recommended -d3 = {key ="value"} # non-recommended -``` - -```python -d1 = {key += [0, 1, 2]} # recommended -d2 = {key+= [0, 1, 2]} # non-recommended -d3 = {key +=[0, 1, 2]} # non-recommended -``` - -- Remove all commas at the end of the line in the KCL multiline dict because the end commas of each line are optional. - -```python -d = { - key1 = "value1" - key2 = "value2" - key3 = "value3" - key4 = "value4" -} -``` - -## List - -- Keep only **one space** after the comma `,` separating elements in the list - -```python -a = [1, 2, 3] # recommended -b = [1,2,3] # non-recommended -``` - -- Keep only **one space** before and after the comprehension expression token `for` and `in` in the dict and list. - -```python -a = [i for i in range(10)] # recommended -b = [i for i in range(10)] # non-recommended -``` - -## Slice - -- Keep the same number of spaces before and after the colon `:` of the list slice. - -```python -l = [1, 2, 3] -a = l[0:2] # recommended -b = l[0 : 2] # non-recommended -c = l[0: 2] # non-recommended - -d = l[0 + 0 : 1 + 1] # recommended -e = l[0 + 0:1 + 1] # non-recommended -``` - -## Schema - -- Leave only one space before and after the schema attribute assignment `=`. -- Always add a doc string to a schema, which is a good programming habit. - -```python -schema Person: - """ - Schema doc string - """ - name: str = "Alice" # recommended - age : int=12 # non-recommended - -person = Person {} -``` - -- Keep **no spaces** around the schema inheritance operator `()` - -```python -schema Base: - name: str - -schema Person(Base): # recommended - age: int - -schema Schema ( Base ): # non-recommended - age: int -``` - -- Keep **only one space** between the brackets and the schema name of the config at schema instantiation. - -```python -schema Base: - name: str - -schema Person(Base): - age: int - -personA = Person{} # non-recommended -personB = Person {} # recommended -``` - -- Keep **only one space** between the **mixin** keyword and the following `[]` operator - -```python -schema NameMixin: - name: str = "name" - -schema Person: - mixin [NameMixin] # non-recommended - age: int - -schema Parent: - mixin [NameMixin] # recommended - age: int -``` - -### Attribute Annotations - -- Annotations for schema attributes should have a single space after the colon `:` and no space before the colon `:`. - -```python -# recommended: -schema Person: - name: str # No space before the colon `:` - age: int = 18 # Spaces around assignment`=` -``` - -```python -# non-recommended: -schema Person: - codeA:int # No space after the colon `:` - codeB : int # Space before the colon `:` - name: str="Alice" # No spaces around assignment`=` -``` - -- There are no spaces around the colon `:` in the dict type annotation. - -```python -schema Person: - labels: {str:str} # recommended - keyValues: {str : str} # non-recommended -``` - -### Arguments - -- There are no spaces around the assignment `=` in the function/schema/decorator keyword arguments (kwargs). - -```python -schema Person[nameVar]: - # Decorator kwargs - @deprecated(strict=False) # recommended - name: str = nameVar - - @deprecated(strict = False) # non-recommended - age: int - -# Schema kwargs -personA = Person(nameVar="Alice") {} # recommended -personB = Person(nameVar = "Bob") {} # non-recommended - -# Function kwargs -print("", end='') # recommended -print("", end = '') # non-recommended -``` - -## Keywords - -- Only one space is usually reserved around the keyword, such as `schema`, `mixin`, `is` and `not`, etc. - -```python -schema NameMixin: - check: - name not None - -schema Person: - """ - Person schema definition - """ - mixin [NameMixin] - - name: str = "Alice" - age: int - -person = Person { - age = 18 -} -``` - -## Function - -- There are no spaces around the function/package select operator `.` -- There are no spaces between the function name and the parentheses `()`. - -```python -import math - -print(math.log(10)) # recommended -print( math . log (10)) # non-recommended -``` diff --git a/versioned_docs/version-0.5.6/reference/lang/spec/datatypes.md b/versioned_docs/version-0.5.6/reference/lang/spec/datatypes.md deleted file mode 100644 index ef7ea71a..00000000 --- a/versioned_docs/version-0.5.6/reference/lang/spec/datatypes.md +++ /dev/null @@ -1,452 +0,0 @@ ---- -title: "Data Types" -linkTitle: "Data Types" -type: "docs" -weight: 2 -description: Data Types ---- - -## Syntax - -### Bool - -Boolean values are the two constant objects `False` and `True`. They are used to represent truth values (although other values can also be considered false or true). The built-in function bool() can be used to convert any value to a Boolean, if the value can be interpreted as a truth value. - -### Int - -Int, or integer, is an arbitrarily sized integer, positive or negative, without decimals, of 64 binary digits precision(-9,223,372,036,854,775,808~9,223,372,036,854,775,807). Int is created by int literals or as the result of built-in functions and operators. Unadorned integer literals (including `hex`, `octal` and `binary` numbers) yield integers. The constructor int() can be used to produce int of a specific type. - -Besides, integer literals may have an `SI` or `IEC` multiplier. - -- `SI`: General integer or fixed-point number form: `P`, `T`, `G`, `M`, `K`, `k`, `m`, `u`, `n`. -- `IEC`: Corresponding power of 2: `Pi`, `Ti`, `Gi`, `Mi`, `Ki`. - -```python -a = 1 # positive integer: 1 -b = -1 # negative integer: -1 -c = 0x10 # hexadecimal literal: 16 -d = 0o10 # octal literal: 8, or the form `010` -e = 0b10 # binary literal: 2 -f = 10Ki # integer literal with IEC multiplier: 10240 -g = 1M # integer literal with SI multiplier: 1000000 -h = int("10") # int constructor: 10 -i = int("10Ki") # int constructor with multiplier: 10240 -``` - -Notes: - -- Report an error if unable to represent an integer value precisely. - -### Float - -Float, floating-point, approximation to real numbers, positive or negative, containing one or more decimals, of 64 bit IEEE 754 floats. The constructor float() can be used to produce int of a specific type. - -```python -a = 1.10 -b = 1.0 -c = -35.59 -d = 32.3+e18 -f = -90. -g = -32.54e100 -h = 70.2-E12 -i = float("112") # float constructor -``` - -Notes: - -- Report an error if unable to represent a floating-point value due to overflow -- Report a warning if unable to represent a floating-point value due to underflow. Round to the nearest representable value if unable to represent a floating-point value due to limits on precision. These requirements apply to the result of any expression except for built-in functions for which an unusual loss of precision must be explicitly documented. - -#### None - -In KCL, `None` can indicate that the value of the object is empty, which is similar to `nil` in Go or `null` in Java, and corresponds to `null` in YAML and JSON. - -```python -a = None -b = [1, 2, None] -c = {"key1" = "value1", "key2" = None} -``` - -Please note that `None` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + None # error -b = int(None) # error -c = not None # True -d = None == None # True -e = None or 1 # 1 -f = str(None) # None -``` - -#### Undefined - -`Undefined` is similar to None, but its semantics is that a variable is not assigned any value and will not be output to YAML or JSON. - -```python -a = Undefined -b = [1, 2, Undefined] -c = {"key1" = "value1", "key2" = Undefined} -``` - -Please note that `Undefined` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + Undefined # error -b = int(Undefined) # error -c = not Undefined # True -d = Undefined == Undefined # True -e = Undefined or 1 # 1 -f = str(Undefined) # Undefined -``` - -### Common Numeric Operations - -Int and Float support the following operations (see built-in proposal for built-in details): - -- `x + y`: sum of x and y. -- `x - y`: difference of x and y. -- `x * y`: product of x and y. -- `x / y`: quotient of x and y. -- `x // y`: floored quotient of x and y. -- `x % y`: remainder of x / y. -- `x ** y`: x to the power y. -- `-x`: x negated. -- `+x`: x unchanged. -- `~x`: x bitwise negation. -- `abs(x)`: absolute value or magnitude of x. -- `int(x)`: x converted to integer. -- `float(x)`: x converted to floating point. - -KCL supports mixed arithmetic: when a binary arithmetic operator has operands of different numeric types, the operand with the "narrower" type is widened to that of the other, where integer is narrower than floating-point. - -### String - -Strings are immutable sequences of Unicode characters. String literals are written in a variety of ways: - -```python -'allows embedded "double" quotes' # Single quotes -"allows embedded 'single' quotes" # Double quotes -'''Three single quotes''', """Three double quotes""" # Triple quoted -``` - -Triple quoted strings may span multiple lines. - -Indexing a string produces strings of length 1, for a non-empty string s, `s[0] == s[0:1]`. - -```python -a = "Hello, World!" -b = a[2:5] # "llo" -c = a[-5:-2] # "orl" -d = a[::-1] # "'!dlroW ,olleH'" -``` - -- `str(x=None) -> str` - -Return a string. If _x_ is not provided, raise a runtime error. - -```python -x = str(3.5) # "3.5" -``` - -#### Members - -Built-in function and members of a string - -- `str#len() -> int` - Return the number of characters in the string. -- `capitalize() -> str` - Return a copy of the string with its first character (if any) capitalized and the rest lowercased. -- `count(sub: str, start: int = 0, end: int = -1) -> int` - Returns the number of (non-overlapping) occurrences of substring sub in string, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `endswith(suffix: str, start: int = 0, end: int = -1) -> bool` - Returns `True` if the string ends with the specified suffix, otherwise return `False`, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `find(sub: str, start: int = 0, end: int = -1) -> int` - Returns the lowest index where substring sub is found, or -1 if no such index exists, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `format(*args, **kwargs) -> str` - Perform string interpolation. Format strings contain replacement fields surrounded by curly braces {}. Anything that is not contained in braces is considered literal text, which is copied unchanged to the output. If you need to include a bracket character in the literal text, it can be escaped by doubling: A replacement field can be either a name, a number or empty. Values are converted to strings using the str function. -- `index(sub: str, start: int = 0, end: int = -1) -> int` - Returns the first index where sub is found, or raises an error if no such index exists, optionally restricting to `[start:end]` start being inclusive and end being exclusive. -- `isalnum() -> bool` - Returns True if all characters in the string are alphanumeric (`[a-zA-Z0-9]`) and there is at least one character, False otherwise. -- `isalpha() -> bool` - Returns True if all characters in the string are alphabetic (`[a-zA-Z]`) and there is at least one character. -- `isdigit() -> bool` - Returns True if all characters in the string are digits (`[0-9]`) and there is at least one character. -- `islower() -> bool` - Returns True if all cased characters in the string are lowercase and there is at least one character. -- `isspace() -> bool` - Returns True if all characters are white space characters and the string contains at least one character. -- `istitle() -> bool` - Returns True if the string is in title case and it contains at least one character. This means that every uppercase character must follow an uncased one (e.g., whitespace) and every lowercase character must follow a cased one (e.g., uppercase or lowercase). -- `isupper() -> bool` - Returns True if all cased characters in the string are uppercase and there is at least one character. -- `join(iterable: list) -> str` - Return a string which is the concatenation of the strings in iterable. A TypeError will be raised if there are any non-string values in iterable. The separator between elements is the string providing this method. Example: - - ```python - >>> "|".join(["a", "b", "c"]) - "a|b|c" - ``` - -- `lower() -> str` - Returns a copy of the string with all the cased characters converted to lowercase. -- `lstrip(chars: str) -> str` - Return a copy of the string with leading characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.lstrip() - 'spacious ' - >>> 'www.example.com'.lstrip('cmowz.') - 'example.com' - ``` - -- `replace(old: str, new: str, count: int) -> str` - Return a copy of the string with all occurrences of substring old replaced by new. If the optional argument count is given, only the first count occurrences are replaced. -- `rfind(sub: str, start: int = 0, end: int = -1) -> int` - Return the highest index in the string where substring sub is found, such that sub is contained within s[start:end]. Optional arguments start and end are interpreted as in slice notation. Return -1 on failure. -- `rindex(sub: str, start: int = 0, end: int = -1) -> int` - Returns the last index where sub is found, or raises an ValueError if no such index exists, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `rsplit(sep: str, maxsplit: int = -1) -> list` - Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done, the rightmost ones. If sep is not specified or None, any whitespace string is a separator. Except for splitting from the right, rsplit() behaves like split() which is described in detail below. -- `rstrip(chars: str) -> str` - Return a copy of the string with trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a suffix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.rstrip() - ' spacious' - >>> 'mississippi'.rstrip('ipz') - 'mississ' - ``` - -- `split(sep: str, maxsplit: int) -> list` - Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done (thus, the list will have at most maxsplit+1 elements). If maxsplit is not specified or -1, then there is no limit on the number of splits (all possible splits are made). - - If sep is given, consecutive delimiters are not grouped together and are deemed to delimit empty strings (for example, `'1,,2'.split(',')` returns `['1', '', '2']`). The sep argument may consist of multiple characters (for example, `'1<>2<>3'.split('<>')` returns `['1', '2', '3']`). Splitting an empty string with a specified separator returns `['']`. - - For example: - - ```python - >>> '1,2,3'.split(',') - ['1', '2', '3'] - >>> '1,2,3'.split(',', maxsplit=1) - ['1', '2,3'] - >>> '1,2,,3,'.split(',') - ['1', '2', '', '3', ''] - ``` - - If sep is not specified or is None, a different splitting algorithm is applied: runs of consecutive whitespace are regarded as a single separator, and the result will contain no empty strings at the start or end if the string has leading or trailing whitespace. Consequently, splitting an empty string or a string consisting of just whitespace with a `None` separator returns `[]`. - - For example: - - ```python - >>> '1 2 3'.split() - ['1', '2', '3'] - >>> '1 2 3'.split(maxsplit=1) - ['1', '2 3'] - >>> ' 1 2 3 '.split() - ['1', '2', '3'] - ``` - -- `splitlines(keepends: str) -> list` - Return a list of the lines in the string, breaking at line boundaries('\n', '\r\n', '\r'). Line breaks are not included in the resulting list unless keepends is given and true. - - This method splits on the following line boundaries. In particular, the boundaries are a superset of universal newlines. - - For example: - - ```python - >>> 'ab c\n\nde fg\rkl\r\n'.splitlines() - ['ab c', '', 'de fg', 'kl'] - >>> 'ab c\n\nde fg\rkl\r\n'.splitlines(keepends=True) - ['ab c\n', '\n', 'de fg\r', 'kl\r\n'] - ``` - - Unlike `split()` when a delimiter string sep is given, this method returns an empty list for the empty string, and a terminal line break does not result in an extra line: - - ```python - >>> "".splitlines() - [] - >>> "One line\n".splitlines() - ['One line'] - ``` - - For comparison, `split('\n')` gives: - - ```python - >>> ''.split('\n') - [''] - >>> 'Two lines\n'.split('\n') - ['Two lines', ''] - ``` - -- `startswith(prefix: str, start: int = 0, end: int = -1) -> bool` - Return `True` if string starts with the prefix, otherwise return False. prefix can also be a list of prefixes to look for. With optional start, test string beginning at that position. With optional end, stop comparing string at that position. -- `strip(chars: str) -> str` - Return a copy of the string with the leading and trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix or suffix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.strip() - 'spacious' - >>> 'www.example.com'.strip('cmowz.') - 'example' - ``` - - The outermost leading and trailing chars argument values are stripped from the string. Characters are removed from the leading end until reaching a string character that is not contained in the set of characters in chars. A similar action takes place on the trailing end. For example: - - ```python - >>> comment_string = '#....... Section 3.2.1 Issue #32 .......' - >>> comment_string.strip('.#! ') - 'Section 3.2.1 Issue #32' - ``` - -- `title() -> str` - Return a titlecased version of the string where words start with an uppercase character and the remaining characters are lowercase. - - For example: - - ```python - >>> 'Hello world'.title() - 'Hello World' - ``` - - The algorithm uses a simple language-independent definition of a word as groups of consecutive letters. The definition works in many contexts but it means that apostrophes in contractions and possessives form word boundaries, which may not be the desired result: - - ```python - >>> "they're bill's friends from the UK".title() - "They'Re Bill'S Friends From The Uk" - ``` - -- `upper() -> str` - Return a copy of the string with all the cased characters 4 converted to uppercase. Note that `s.upper().isupper()` might be `False` if s contains uncased characters or if the Unicode category of the resulting character(s) is not “Lu” (Letter, uppercase), but e.g., “Lt” (Letter, titlecase). -- `removeprefix(prefix: str) -> str` - If the string starts with the prefix string, return string[len(prefix):]. Otherwise, return a copy of the original string. - ```python - >>> "prefix-data".removeprefix("prefix-") - "data" - ``` -- `rermovesuffix(suffix: str) -> str` - If the string ends with the suffix string and that suffix is not empty, return string[:-len(suffix)]. Otherwise, return a copy of the original string. - ```python - >>> "data-suffix".removesuffix("-suffix") - "data" - ``` - -### List - -Lists are immutable sequences, typically used to store collections of homogeneous items (where the precise degree of similarity will vary by application). - -Lists may be constructed in several ways: - -- Using a pair of square brackets to denote the empty list: `[]` -- Using square brackets, separating items with commas: `[a]`, `[a, b, c]` -- Using a list comprehension: `[x for x in iterable]` -- Using the type constructor: list() or list(iterable) - -The constructor builds a list whose items are the same and in the same order as iterable’s items.Iterable may be either a sequence, a container that supports iteration, or an iterator object. If iterable is already a list, a copy is made and returned, similar to `iterable[:]`. For example, `list('abc')` returns `['a', 'b', 'c']` and `list([1, 2, 3])` returns `[1, 2, 3]`. If no argument is given, the constructor creates a new empty list `[]`. - -Lists implement all of the common sequence operations. - -#### Members - -- `len()` - Return the number of items in the list. - -### Common Sequence Operations - -The operations in the following table are supported by List and Dict. - -This table lists the sequence operations sorted in ascending priority. In the table, s and t are sequences of the same type, n, i, j and k are integers and x is an arbitrary object that meets any type and value restrictions imposed by s. - -The `in` and `not in` operations have the same priorities as the comparison operations. The + -(concatenation) and \* (repetition) operations have the same priority as the corresponding numeric operations. - -| Operation | Result | Notes | -| ------------ | -------------------------------------------------- | ----- | -| `x in s` | `True` if an item of s is equal to x, else `False` | #1 | -| `x not in s` | `False` if an item of s is equal to x, else `True` | #1 | -| `s + t` | the concatenation of s and t | #5 | -| `s[i]` | ith item of s, origin 0 | #2 | -| `s[i:j]` | slice of s from i to j | #2 #3 | -| `s[i:j:k]` | slice of s from i to j with step k | #2 #4 | -| `min(s)` | smallest item of s | | -| `max(s)` | largest item of s | | - -Notes: - -- 1. While the in and not in operations are used only for simple containment testing in the - general case, some specialized sequences (str) also use them for subsequence testing: - -```python ->>> "gg" in "eggs" -True -``` - -- 2. If i or j is negative, the index is relative to the end of sequence s: `s.len() + i` or `s.len() + j` is substituted. But note that -0 is still 0. -- 3. The slice of s from i to j is defined as the sequence of items with index k such that `i <= k < j`. If i or j is greater than `s.len()`, use `s.len()`. If i is omitted or None, use 0. If j is omitted or None, use `s.len()`. If i is greater than or equal to j, the slice is empty. -- 4. The slice of s from i to j with step k is defined as the sequence of items with index `x = i + n*k` such that `0 <= n < (j-i)/k`. In other words, the indices are `i`, `i+k`, `i+2*k`, `i+3*k` and so on, stopping when j is reached (but never including j). When k is positive, i and j are reduced to s.len() if they are greater. When k is negative, i and j are reduced to s.len() - - - If they are greater. If i or j are omitted or None, they become “end” values (which end depends on the sign of k). Note, k cannot be zero. If k is None, it is treated like 1. - -- 5. Concatenating immutable sequences always results in a new object. This means that building up a sequence by repeated concatenation will have a quadratic runtime cost in the total sequence length. To get a linear runtime cost, you must switch to one of the alternatives below: - - - if concatenating str objects, you can build a list and use `str.join()` at the end - -- 6. `index` raises `ValueError` when x is not found in s. Not all implementations support passing the additional arguments i and j. These arguments allow efficient searching of subsections of the sequence. Passing the extra arguments is roughly equivalent to using `s[i:j].index(x)`, only without copying any data and with the returned index being relative to the start of the sequence rather than the start of the slice. - -### Dict - -Dict is an immutable mapping object maps hashable values to arbitrary objects. A dictionary’s keys are almost arbitrary values. Values that are not hashable, that is, values containing lists, dictionaries may not be used as keys. Numeric types used for keys obey the normal rules for numeric comparison: if two numbers compare equal (such as 1 and 1.0) then they can be used interchangeably to index the same dictionary entry. (Note however, that since computers store floating-point numbers as approximations it is usually unwise to use them as dictionary keys.) Dict is ordered. The order of the keys is the order of their declaration. - -Dictionaries can be created by placing a comma-separated list of keys: value pairs within braces, for example: `{'jack': 4098, 'sjoerd': 4127}` or `{4098: 'jack', 4127: 'sjoerd'}`, by the dict constructor, or list/dict comprehension. - -- `dict(obj)` - -Return a new dictionary initialized from an optional positional argument and a possibly empty set of keyword arguments.If no positional argument is given, an empty dictionary is created. If a positional argument is given and it is a mapping object, a dictionary is created with the same key-value pairs as the mapping object. Otherwise, the positional argument must be an iterable object. Each item in the iterable must itself be an iterable with exactly two objects. The first object of each item becomes a key in the new dictionary, and the second object the corresponding value. If a key occurs more than once, the last value for that key becomes the corresponding value in the new dictionary. If keyword arguments are given, the keyword arguments and their values are added to the dictionary created from the positional argument. If a key being added is already present, the value from the keyword argument replaces the value from the positional argument. To illustrate, the following examples all return a dictionary equal to `{"one": 1, "two": 2, "three": 3}`: - -```python ->>> a = {'two': 2, 'one': 1, 'three': 3} ->>> b = {'one': 1, 'two': 2, 'three': 3} ->>> c = {'three': 3, 'one': 1, 'two': 2} ->>> a == b == c -True -``` - -Providing keyword arguments as in the first example only works for keys that are valid KCL identifiers. Otherwise, any valid keys can be used. - -In the dict comprehension, key/value pairs yielded by the generator expression is set in the dictionary in the order yielded: the first occurrence of the key determines its insertion order, and the last determines the value associated to it. - -```python ->>> {str(i): 2 * i for i in range(3)} -{"0": 0, "1": 2, "2": 4} - ->>> a = {"one": 1, "two": 2, "three": 3} ->>> b = {k: v for k, v in a if v >= 2} -{two: 2, three: 3} -``` - -#### Operations & Members - -These are the operations that dictionaries the support. - -- `list(d)` - Return a list of all the keys used in the dictionary d. -- `len()` - Return the number of items in the dictionary d. -- `d[key]` - Return the item of d with key. Return Undefined if key is not in the map. -- `key in d` - Return True if d has a key, else False. -- `key not in d` - Equivalent to not key in d. -- `d.key` - Return the item of d with key. Return Undefined if key is not in the map. - -Dictionaries compare equal if and only if they have the same (key, value) pairs(keys' ordering matters). Order comparisons (‘<’, ‘<=’, ‘>=’, ‘>’) raise TypeError. - -```python ->>> d = {"one": 1, "two": 2, "three": 3, "four": 4} ->>> d -{'one': 1, 'two': 2, 'three': 3, 'four': 4} ->>> list(d) -['one', 'two', 'three', 'four'] -``` diff --git a/versioned_docs/version-0.5.6/reference/lang/spec/error.md b/versioned_docs/version-0.5.6/reference/lang/spec/error.md deleted file mode 100644 index 2a58b553..00000000 --- a/versioned_docs/version-0.5.6/reference/lang/spec/error.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: "Errors" -linkTitle: "Errors" -type: "docs" -weight: 2 -description: Errors ---- - -When errors happen, developers should be able to detect the error and abort -execution. Thus, KCL introduce the `assert` syntax. - -In the previous topic of `schema` syntax. Errors can also be raised when a -schema is violated. - -## Syntax - -The syntax of the `assert` statement is the following. - -```bnf -assert_stmt: 'assert' test ['if' test] [',' test] -``` - -In the basic form, an `assert` statement evaluates an expression. If the -expression is evaluated to `False`, the assertion is failed, and an error -should be reported. - -In the extended form, an error message can be provided. The error message is -another expression. It is only evaluated when the expression to be evaluated -is evaluated to `False`. The evaluation result of the error message is printed -when reporting the error. - -The following is an example: - -```python -a = 1 -b = 3 -condition = False -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -# if condition is True, then assert `a == b`, if failed, the message "error message" will be printed. -assert a == b if condition, "error message" -``` - -## The Implementation - -When an error happens, no matter it is caused by the `assert` or the `schema` syntax, -the virtual machine should exit with an exit code greater than `0`. - -The virtual machine may choose to dump the back trace information, and it is strongly recommended to implement it. - -In practice, KCL can dump back trace by default, and an argument can be introduced to disable it. diff --git a/versioned_docs/version-0.5.6/reference/lang/spec/index.md b/versioned_docs/version-0.5.6/reference/lang/spec/index.md deleted file mode 100644 index 88bbaa59..00000000 --- a/versioned_docs/version-0.5.6/reference/lang/spec/index.md +++ /dev/null @@ -1 +0,0 @@ -# KCL Spec diff --git a/versioned_docs/version-0.5.6/reference/lang/spec/kcl-spec.md b/versioned_docs/version-0.5.6/reference/lang/spec/kcl-spec.md deleted file mode 100644 index 63a9d6e7..00000000 --- a/versioned_docs/version-0.5.6/reference/lang/spec/kcl-spec.md +++ /dev/null @@ -1,343 +0,0 @@ ---- -title: "KCL Spec" -linkTitle: "KCL Spec" -type: "docs" -weight: 2 -description: KCL Spec ---- - -## Lexical rules - -### Keywords and reserved words - -The following are the keywords of the KCL: - -```python -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -The following are reserved words for the KCL: - -```python -pass return validate rule flow -def del raise except try -finally while from with yield -global nonlocal struct class final -``` - -### Line comment - -```python -# a comment -``` - -### Operators - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != = -+= -= *= **= /= //= %= -<<= >>= &= ^= -``` - -### Delimiters - -```python -( ) [ ] { } -, : . ; @ -``` - -### Operator precedence - -The following list of operators is ordered from **highest to lowest**: - -| Operator | Description | -| -------------------------------------------------------------------------------- | -------------------------------------------------------- | -| `**` | Exponentiation (highest priority) | -| `+x` `-x` `~x` | Positive, negative, bitwise NOT | -| `*` `/` `%` `//` | Multiplication, division, floor division and remainder | -| `+` `-` | Addition and subtraction | -| `<<` `>>` | Left and right shifts | -| `&` | Bitwise AND | -| `^` | Bitwise XOR | -| \| | Bitwise OR | -| `in`, `not in`, `is`, `is not`, `<`, `<=`, `>`, `>=`, `!=`, `==` | Comparisons, including membership and identity operators | -| `not` | Boolean NOT | -| `and` | Boolean AND | -| `or` | Boolean OR | -| `if – else` | Conditional expression = | -| `=`, `+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `=`, `^=`, `\*\*=`, `//=`, `<<=`, `>>=` | Assign | - -## Grammar - -KCL uses Python's [LarkParser](https://lark-parser.readthedocs.io/en/latest/) tool to describe the grammar, and the specification rules are as follows: - -```bnf -//////////// KCL grammar //////////// -start: (NEWLINE | statement)* - -statement: simple_stmt | compound_stmt -simple_stmt: (assign_stmt | unification_stmt | expr_stmt | assert_stmt | import_stmt | type_alias_stmt) NEWLINE -compound_stmt: if_stmt | schema_stmt | rule_stmt - -//////////// import_stmt //////////// -import_stmt: IMPORT dot_name (AS NAME)? -dot_name: (leading_dots identifier) | identifier -leading_dots: DOT+ - -/////////// assert_stmt //////////// -assert_stmt: ASSERT simple_expr (IF simple_expr)? (COMMA test)? - -//////////// if_stmt //////////// -if_stmt: IF test COLON execution_block (ELIF test COLON execution_block)* (ELSE COLON execution_block)? -execution_block: if_simple_stmt | NEWLINE _INDENT schema_init_stmt+ _DEDENT -if_simple_stmt: (simple_assign_stmt | unification_stmt | expr_stmt | assert_stmt) NEWLINE - -//////////// assign_stmt //////////// -assign_stmt: identifier [COLON type] (ASSIGN identifier)* ASSIGN test - | identifier (COMP_PLUS | COMP_MINUS | COMP_MULTIPLY | COMP_DOUBLE_STAR | COMP_DIVIDE - | COMP_DOUBLE_DIVIDE | COMP_MOD | COMP_AND | COMP_OR | COMP_XOR | COMP_SHIFT_LEFT - | COMP_SHIFT_RIGHT) test - -simple_assign_stmt: identifier ASSIGN test - | identifier (COMP_PLUS | COMP_MINUS | COMP_MULTIPLY | COMP_DOUBLE_STAR | COMP_DIVIDE - | COMP_DOUBLE_DIVIDE | COMP_MOD | COMP_AND | COMP_OR | COMP_XOR | COMP_SHIFT_LEFT - | COMP_SHIFT_RIGHT) test - -//////////// unification_stmt //////////// -unification_stmt: identifier COLON schema_expr - -//////////// schema_stmt //////////// -schema_stmt: [decorators] (SCHEMA|MIXIN|PROTOCOL) NAME [LEFT_BRACKETS [schema_arguments] RIGHT_BRACKETS] [LEFT_PARENTHESES identifier (COMMA identifier)* RIGHT_PARENTHESES] [for_host] COLON NEWLINE [schema_body] -schema_arguments: schema_argument (COMMA schema_argument)* -schema_argument: NAME [COLON type] [ASSIGN test] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt|schema_init_stmt|schema_index_signature)* [check_block] _DEDENT -schema_attribute_stmt: attribute_stmt NEWLINE -attribute_stmt: [decorators] identifier [QUESTION] COLON type [(ASSIGN|COMP_OR) test] -schema_init_stmt: if_simple_stmt | if_stmt -schema_index_signature: LEFT_BRACKETS [NAME COLON] [ELLIPSIS] basic_type RIGHT_BRACKETS COLON type [ASSIGN test] NEWLINE - -//////////// rule_stmt //////////// -rule_stmt: [decorators] RULE NAME [LEFT_BRACKETS [schema_arguments] RIGHT_BRACKETS] [LEFT_PARENTHESES identifier (COMMA identifier)* RIGHT_PARENTHESES] [for_host] COLON NEWLINE [rule_body] -rule_body: _INDENT (string NEWLINE)* check_expr+ _DEDENT - -for_host: FOR identifier - -/////////// decorators //////////// -decorators: (AT decorator_expr NEWLINE)+ -decorator_expr: identifier [call_suffix] - -//////////// type //////////// -type: type_element (OR type_element)* -type_element: schema_type | basic_type | compound_type | literal_type -schema_type: identifier -basic_type: STRING_TYPE | INT_TYPE | FLOAT_TYPE | BOOL_TYPE | ANY_TYPE -compound_type: list_type | dict_type -list_type: LEFT_BRACKETS (type)? RIGHT_BRACKETS -dict_type: LEFT_BRACE (type)? COLON (type)? RIGHT_BRACE -literal_type: string | number | TRUE | FALSE | NONE - -//////////// type alias //////////// -type_alias_stmt: TYPE NAME ASSIGN type - -//////////// check_stmt //////////// -check_block: CHECK COLON NEWLINE _INDENT check_expr+ _DEDENT -check_expr: simple_expr [IF simple_expr] [COMMA primary_expr] NEWLINE - -//////////// mixin_stmt //////////// -mixin_stmt: MIXIN LEFT_BRACKETS [mixins | multiline_mixins] RIGHT_BRACKETS NEWLINE -multiline_mixins: NEWLINE _INDENT mixins NEWLINE _DEDENT -mixins: identifier (COMMA (NEWLINE mixins | identifier))* - - -//////////// expression_stmt //////////// -expr_stmt: testlist_expr -testlist_expr: test (COMMA test)* -test: if_expr | simple_expr -if_expr: simple_expr IF simple_expr ELSE test - -simple_expr: unary_expr | binary_expr | primary_expr - -unary_expr: un_op simple_expr -binary_expr: simple_expr bin_op simple_expr - -bin_op: L_OR | L_AND - | OR | XOR | AND - | SHIFT_LEFT | SHIFT_RIGHT - | PLUS | MINUS | MULTIPLY | DIVIDE | MOD | DOUBLE_DIVIDE - | DOUBLE_STAR - | EQUAL_TO | NOT_EQUAL_TO - | LESS_THAN | GREATER_THAN | LESS_THAN_OR_EQUAL_TO | GREATER_THAN_OR_EQUAL_TO - | IN | L_NOT IN | IS | IS L_NOT | L_NOT | AS -un_op: L_NOT | PLUS | MINUS | NOT - -primary_expr: identifier call_suffix | operand | primary_expr select_suffix | primary_expr call_suffix | primary_expr slice_suffix -operand: identifier | number | string | constant | quant_expr | list_expr | list_comp | config_expr | dict_comp | schema_expr | lambda_expr | LEFT_PARENTHESES test RIGHT_PARENTHESES -select_suffix: [QUESTION] DOT NAME -call_suffix: LEFT_PARENTHESES [arguments [COMMA]] RIGHT_PARENTHESES -slice_suffix: [QUESTION] LEFT_BRACKETS (test | [test] COLON [test] [COLON [test]]) RIGHT_BRACKETS -arguments: argument (COMMA argument)* -argument: test | NAME ASSIGN test | MULTIPLY test | DOUBLE_STAR test - - -//////////// operand //////////// -identifier: NAME (DOT NAME)* -quant_expr: quant_op [ identifier COMMA ] identifier IN quant_target LEFT_BRACE (simple_expr [IF simple_expr] | NEWLINE _INDENT simple_expr [IF simple_expr] NEWLINE _DEDENT)? RIGHT_BRACE -quant_target: string | identifier | list_expr | list_comp | config_expr | dict_comp -quant_op: ALL | ANY | FILTER | MAP -list_expr: LEFT_BRACKETS [list_items | NEWLINE [_INDENT list_items _DEDENT]] RIGHT_BRACKETS -list_items: list_item ((COMMA [NEWLINE] | [NEWLINE]) list_item)* [COMMA] [NEWLINE] -list_item: test | star_expr | if_item -list_comp: LEFT_BRACKETS (list_item comp_clause+ | NEWLINE _INDENT list_item comp_clause+ _DEDENT) RIGHT_BRACKETS -dict_comp: LEFT_BRACE (entry comp_clause+ | NEWLINE _INDENT entry comp_clause+ _DEDENT) RIGHT_BRACE -entry: test (COLON | ASSIGN | COMP_PLUS) test -comp_clause: FOR loop_variables [COMMA] IN simple_expr [NEWLINE] [IF test [NEWLINE]] -if_entry: IF test COLON if_entry_exec_block (ELIF test COLON if_entry_exec_block)* (ELSE COLON if_entry_exec_block)? -if_entry_exec_block: (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry) [NEWLINE] | NEWLINE _INDENT (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry) ((COMMA [NEWLINE] | [NEWLINE]) (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry))* [COMMA] [NEWLINE] _DEDENT -if_item: IF test COLON if_item_exec_block (ELIF test COLON if_item_exec_block)* (ELSE COLON if_item_exec_block)? -if_item_exec_block: list_item [NEWLINE] | NEWLINE _INDENT list_item ((COMMA [NEWLINE] | NEWLINE) list_item)* [COMMA] [NEWLINE] _DEDENT - -star_expr: MULTIPLY test -double_star_expr: DOUBLE_STAR test -loop_variables: primary_expr (COMMA primary_expr)* -schema_expr: identifier (LEFT_PARENTHESES [arguments] RIGHT_PARENTHESES)? config_expr -config_expr: LEFT_BRACE [config_entries | NEWLINE [_INDENT config_entries _DEDENT]] RIGHT_BRACE -config_entries: config_entry ((COMMA [NEWLINE] | [NEWLINE]) config_entry)* [COMMA] [NEWLINE] -config_entry: test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry - -//////////// lambda_expr //////////// -lambda_expr: LAMBDA [schema_arguments] [RIGHT_ARROW type] LEFT_BRACE [expr_stmt | NEWLINE _INDENT schema_init_stmt+ _DEDENT] RIGHT_BRACE - -//////////// misc //////////// -number: DEC_NUMBER [multiplier] | HEX_NUMBER | BIN_NUMBER | OCT_NUMBER | FLOAT_NUMBER -multiplier: SI_N_L | SI_U_L | SI_M_L | SI_K_L | SI_K | SI_M | SI_G | SI_T | SI_P - | SI_K_IEC | SI_M_IEC | SI_G_IEC | SI_T_IEC | SI_P_IEC -string: STRING | LONG_STRING -constant : TRUE | FALSE | NONE | UNDEFINED -// Tokens - -ASSIGN: "=" -COLON: ":" -SEMI_COLON: ";" -COMMA: "," -QUESTION: "?" -ELLIPSIS: "..." -RIGHT_ARROW: "->" -LEFT_PARENTHESES: "(" -RIGHT_PARENTHESES: ")" -LEFT_BRACKETS: "[" -RIGHT_BRACKETS: "]" -LEFT_BRACE: "{" -RIGHT_BRACE: "}" -PLUS: "+" -MINUS: "-" -MULTIPLY: "*" -DIVIDE: "/" -MOD: "%" -DOT: "." -AND: "&" -OR: "|" -XOR: "^" -NOT: "~" -LESS_THAN: "<" -GREATER_THAN: ">" -EQUAL_TO: "==" -NOT_EQUAL_TO: "!=" -GREATER_THAN_OR_EQUAL_TO: ">=" -LESS_THAN_OR_EQUAL_TO: "<=" -DOUBLE_STAR: "**" -DOUBLE_DIVIDE: "//" -SHIFT_LEFT: "<<" -SHIFT_RIGHT: ">>" -AT: "@" - -COMP_PLUS: "+=" -COMP_MINUS: "-=" -COMP_MULTIPLY: "*=" -COMP_DIVIDE: "/=" -COMP_MOD: "%=" -COMP_AND: "&=" -COMP_OR: "|=" -COMP_XOR: "^=" -COMP_DOUBLE_STAR: "**=" -COMP_DOUBLE_DIVIDE: "//=" -COMP_SHIFT_LEFT: "<<=" -COMP_SHIFT_RIGHT: ">>=" - -// Special tokens -IMPORT: "import" -AS: "as" -RULE: "rule" -SCHEMA: "schema" -MIXIN: "mixin" -PROTOCOL: "protocol" -CHECK: "check" -FOR: "for" -ASSERT: "assert" -IF: "if" -ELIF: "elif" -ELSE: "else" -L_OR: "or" -L_AND: "and" -L_NOT: "not" -IN: "in" -IS: "is" -LAMBDA: "lambda" -ALL: "all" -ANY: "any" -FILTER: "filter" -MAP: "map" -TYPE: "type" - -ANY_TYPE: "any" -STRING_TYPE: "str" -INT_TYPE: "int" -FLOAT_TYPE: "float" -BOOL_TYPE: "bool" - -// Constant tokens -TRUE: "True" -FALSE: "False" -NONE: "None" -UNDEFINED: "Undefined" - -// Binary prefix -SI_N_L: "n" -SI_U_L: "u" -SI_M_L: "m" -SI_K_L: "k" -SI_K: "K" -SI_M: "M" -SI_G: "G" -SI_T: "T" -SI_P: "P" -SI_K_IEC: "Ki" -SI_M_IEC: "Mi" -SI_G_IEC: "Gi" -SI_T_IEC: "Ti" -SI_P_IEC: "Pi" -IEC: "i" - -NAME: /\$?[a-zA-Z_]\w*/ -COMMENT: /#[^\n]*/ -NEWLINE: ( /\r?\n[\t ]*/ | COMMENT )+ - -STRING: /r?("(?!"").*?(? **note** -> -> Any character except the ASCII space, tab (`\t`) and formfeed (`\f`) is considered a none-space character. - -- A line ending in a backslash cannot carry a comment (, which will be introduced shortly afterwards). -- A backslash does not continue a comment. -- A backslash does not continue a token except for string literals (i.e., tokens other than string literals cannot be split across physical lines using a backslash). -- A backslash is illegal elsewhere on a line outside a string literal. - -### Implicit Line Joining - -Expressions in parentheses, square brackets or curly braces can be split over more than one physical line without using backslashes. - -- Implicitly continued lines can carry comments. -- The indentation of the continuation lines is not important. -- Blank continuation lines are allowed. -- There is no `NEWLINE` token between implicit continuation lines. -- Implicitly continued lines can also occur within triple-quoted strings (see below); in that case they cannot carry comments. - -### Blank Lines - -### Indentation - -### Comments - -Starting with a `#` character that is not part of a string literal is a comment. A comment ends at the end of the physical line. - -A comment signifies the end of the logical line unless the implicit line joining rules are invoked. - -Comments are ignored by the syntax. - -### Identifiers and Keywords - -Identifiers (also referred to as names) are described by the following lexical definitions. - -Within the ASCII range (from `U+0001` to `U+007F`), the valid characters for identifiers are the uppercase and lowercase letters `A` through `Z`, the underscore `_` and, except for the first character, the digits `0` through `9`. - -Identifiers are unlimited in length. The case is significant. - -### Keywords - -The following identifiers are used as reserved words, or keywords of the language, and cannot be used as ordinary identifiers. They must be spelled exactly as written here: - -``` -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -The following tokens are not used, but they are reserved as possible future keywords: - -``` -pass return validate rule flow -def del raise except try -finally while from with yield -global nonlocal struct class final -``` - -### Literals - -Literals are notations for constant values of some built-in types. - -### String Literals - -String literals are described by the following lexical definitions: - -``` -stringliteral ::= [stringprefix](shortstring | longstring) -stringprefix ::= "r" | "R" -shortstring ::= "'" shortstringitem* "'" | '"' shortstringitem* '"' -longstring ::= "'''" longstringitem* "'''" | '"""' longstringitem* '"""' -shortstringitem ::= shortstringchar | stringescapeseq -longstringitem ::= longstringchar | stringescapeseq -shortstringchar ::= -longstringchar ::= -stringescapeseq ::= "\" -``` - -Multiple adjacent string or bytes literals (delimited by whitespace),possibly using different quoting conventions, are allowed, and their meaning is the same as their concatenation. - -### Numeric Literals - -There are two types of numeric literals: integers and floating-point numbers. - -Integer literals are described by the following lexical definitions: - -``` -integer ::= decinteger | bininteger | octinteger | hexinteger -decinteger ::= nonzerodigit (["_"] digit)* | "0"+ (["_"] "0")* -bininteger ::= "0" ("b" | "B") (["_"] bindigit)+ -octinteger ::= "0" ("o" | "O") (["_"] octdigit)+ -hexinteger ::= "0" ("x" | "X") (["_"] hexdigit)+ -nonzerodigit ::= "1"..."9" -digit ::= "0"..."9" -bindigit ::= "0" | "1" -octdigit ::= "0"..."7" -hexdigit ::= digit | "a"..."f" | "A"..."F" -``` - -Floating-point literals are described by the following lexical definitions: - -``` -floatnumber ::= pointfloat | exponentfloat -pointfloat ::= [digitpart] fraction | digitpart "." -exponentfloat ::= (digitpart | pointfloat) exponent -digitpart ::= digit (["_"] digit)* -fraction ::= "." digitpart -exponent ::= ("e" | "E") ["+" | "-"] digitpart -``` - -## Operators and Delimiters - -### Operators - -The following tokens are operators: - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != @ -``` - -### Delimiters - -The following tokens serve as delimiters in the grammar: - -```python -( ) [ ] { } -, : . ; = += --= *= **= /= //= %= -<<= >>= &= |= ^= -``` - -The period can also occur in floating-point literals. - -The following printing ASCII characters have special meaning as part of other tokens or are otherwise significant to the lexical analyzer: - -``` -' " # \ -``` - -The following printing ASCII characters are not used in KCL. Their occurrence outside string literals and comments is an unconditional error: - -``` -? ` -``` - -## Reference - -Since the lexical conventions of KCL is very similar to that of Python, we use the following document as the reference when writing this chapter. - -- [https://docs.python.org/3/reference/lexical_analysis.html](https://docs.python.org/3/reference/lexical_analysis.html) diff --git a/versioned_docs/version-0.5.6/reference/lang/spec/modules.md b/versioned_docs/version-0.5.6/reference/lang/spec/modules.md deleted file mode 100644 index f8608619..00000000 --- a/versioned_docs/version-0.5.6/reference/lang/spec/modules.md +++ /dev/null @@ -1,621 +0,0 @@ ---- -title: "Modules" -linkTitle: "Modules" -type: "docs" -weight: 2 -description: Modules ---- - -## Modules and the Import System - -KCL code is organized in **modules**. For code in one module to access the code defined in another module, a process called **importing** must be used. - -Importing is undertaken at compile-time in KCL. The advantage is to have static checking enabled. - -A regular KCL module is a file on the file system. It is required to have a `.k` suffix. - -## Packages - -To help manage modules and provide a naming hierarchy, KCL has the concept of packages. In KCL, a package maps to exactly a file system directory, and a regular module maps to a file. - -Files directly under a package are considered parts of the package, instead of individual regular modules. - -Packages can have sub-packages. - -Packages are special modules: - -- All packages in KCL are modules. -- A single-file module can never be a package. - -All modules have a name. - -Sub package names are separated from their parent package name by dots. - -To summary, a regular KCL module is a `.k` file, and a package is a directory on the file system. All `.k` files directly under the directory are included in the package, other files are ignored. If the directory has subdirectories, they become sub-packages as long as there are `.k` files underneath. - -### Intra-Package Name Space Sharing - -Inside a package, all `.k` files are considered parts of the package, instead of regular modules. Code in these files share a single name space and can access names defined in other files, without explicitly granted. - -### Package Initialization - -A package can have the initialization code. The code must exist in only one of the `.k` files under this package. The interpreter guarantees that the initialization code is executed after all definitions. - -## Searching - -The searching begins when an `import` statement is used to import a module. - -### Module Cache - -In KCL, only standard system modules are cached. When a cached module is imported, the cached version is used. In other words, KCL runtime would not create another copy of the standard system module in memory. - -However, other modules are uncached. Importing a module multiple time would create multiple instances of the module. - -### Module Names - -An `import` statement specifies the name of the module to import. The syntax is: - -``` -import [as ] -``` - -The rule to search with the module name is very simple: - -- **Step 1**: Searches the module name from the **standard system modules**, then **plugins modules**. - - See **standard system modules** and **plugins modules** for more details. If matched, the module is imported. Otherwise, continue to **Step 2**. -- **Step 2**. Whether a module name starts with a `.` is checked. If yes, the name is a so-called relative pathname, and we go to **Step 5**. Otherwise, continue to **Step 3**. -- **Step 3**: If the module name does not start with any `.`, then the compiler searches the nearest `root path` directory from this directory to the parent, and find the module according to the name just from the `root path`. If no `root path` is found, find the module according to the name from the folder the `.k` file including this `import` statement exists. - - **root path**: the directory contains a `kcl.mod` file. If matched, the module is imported. Otherwise, continue to **Step 4**. -- **Step 4**: Then the compiler checks if the name is the name of any library module that requires explicit loading. If matched, the library module is imported. Otherwise, continue to **Step 6**. -- **Step 5**. For relative importing, find the module according to the name from the folder the `.k` file including this `import` statement exists. Interpret leading dots using the following rule: -- One dot: Ignore. -- Tow or more dots: Suppose there are `n` leading dots, then the searching starts at `n - 1` levels above this folder. If matched, the module is imported. Otherwise, continue to **Step 6**. -- **Step 6**. Module not found, report an error. - -Do case-sensitive search when the operating system allows. If case-sensitive search is not allowed, search directories before regular files. - -In KCL, the `from <> import <>` is unsupported, and relative import is performed with the `import <>` syntax. - -### Uniqueness of Module - -Each module has a unique location path in its scope, so that a module or package could be located with a unique location path, such as `a.b.c`. - -Searching by location path should be supported by the kcl compiler, which needs to provide corresponding searching features through the command line and api form. - -## Standard System Packages - -KCL supports a few standard system modules. The following is the full list of these standard system modules: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PackageMember
datetimetoday
now
ticks
date
mathceil
exp
expm1
factorial
floor
gcd
isfinite
isinf
isnan
log
log1p
log2
log10
modf
pow
sqrt
regexreplace
match
compile
findall
search
split
unitsn
u
m
k
K
M
G
T
P
Ki
Mi
Gi
Ti
Pi
to_n
to_u
to_m
to_K
to_M
to_G
to_T
to_P
to_Ki
to_Mi
to_Gi
to_Ti
to_Pi
jsonencode
decode
dump_to_file
yamlencode
decode
dump_to_file
netsplit_host_port
join_host_port
fqdn
parse_IP
to_IP4
to_IP16
IP_string
is_IPv4
is_IP
is_loopback_IP
is_multicast_IP
is_interface_local_multicast_IP
is_link_local_multicast_IP
is_link_local_unicast_IP
is_global_unicast_IP
is_unspecified_IP
base64encode
decode
cryptomd5
sha1
sha224
sha256
sha384
sha512
- -- datetime - - ticks() -> float - Return the current time in seconds since the Epoch. Fractions of a second may be present if the system clock provides them. - - date() -> str - return the `%Y-%m-%d %H:%M:%S` format date. - - now() -> str - return the local time. e.g. `'Sat Jun 06 16:26:11 1998'` - - today() -> str - return the `%Y-%m-%d %H:%M:%S.%{ticks}` format date. -- math - - ceil(x) -> int - Return the ceiling of x as an Integral. This is the smallest integer >= x. - - factorial(x) -> int - Return x!. Raise a error if x is negative or non-integral. - - floor(x) -> int - Return the floor of x as an Integral. This is the largest integer <= x. - - gcd(a: int, b: int) -> int - Return the greatest common divisor of x and y - - isfinite(x) -> bool - Return True if x is neither an infinity nor a NaN, and False otherwise. - - isinf(x) -> bool - Return True if x is a positive or negative infinity, and False otherwise. - - isnan(x) -> bool - Return True if x is a NaN (not a number), and False otherwise. - - modf(x) -> Listfloat, float] - Return the fractional and integer parts of x. Both results carry the sign of x and are floats. - - exp(x) -> float - Return e raised to the power of x. - - expm1(x) -> float - Return exp(x)-1. This function avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small x. - - log(x, base=2.71828182845904523536028747135266250) -> float - Return the logarithm of x to the base e. - - log1p(x) -> float - Return the natural logarithm of 1+x (base e). The result is computed in a way which is accurate for x near zero. - - log2(x) -> float - Return the base 2 logarithm of x. - - log10(x) -> float - Return the base 10 logarithm of x. - - pow(x, y) -> float - Return x\*\*y (x to the power of y). - - sqrt(x) -> float - Return the square root of x. -- regex - - replace(string: str, pattern: str, replace: str, count=0) -> str - Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement. - - match(string: str, pattern: str) -> bool - Try to apply the pattern at the start of the string, returning a bool value True if any match was found, or False if no match was found. - - compile(pattern: str) -> bool - Compile a regular expression pattern, returning a bool value denoting whether the pattern is valid. - - findall(string: str, pattern: str) -> List[str] - Return a list of all non-overlapping matches in the string. - - search(string: str, pattern: str) -> bool - Scan through string looking for a match to the pattern, returning a bool value True if any match was found, or False if no match was found. - - split(string: str, pattern: str, maxsplit=0) -> List[str] - Scan through string looking for a match to the pattern, returning a Match object, or None if no match was found. -- units - - Unit constants - - Fixed point: `n`, `u`, `m`, `k`, `K`, `G`, `T` and `P`. - - Power of 2: `Ki`, `Mi`, `Gi`, `Ti` and `Pi`. - - Functions - - to_n(num: int) -> str - Int literal to string with `n` suffix - - to_u(num: int) -> str - Int literal to string with `u` suffix - - to_m(num: int) -> str - Int literal to string with `m` suffix - - to_K(num: int) -> str - Int literal to string with `K` suffix - - to_M(num: int) -> str - Int literal to string with `M` suffix - - to_G(num: int) -> str - Int literal to string with `G` suffix - - to_T(num: int) -> str - Int literal to string with `T` suffix - - to_P(num: int) -> str - Int literal to string with `P` suffix - - to_Ki(num: int) -> str - Int literal to string with `Ki` suffix - - to_Mi(num: int) -> str - Int literal to string with `Mi` suffix - - to_Gi(num: int) -> str - Int literal to string with `Gi` suffix - - to_Ti(num: int) -> str - Int literal to string with `Ti` suffix - - to_Pi(num: int) -> str - Int literal to string with `Pi` suffix -- json - - encode(data: any, sort_keys: bool = False, indent: int = None, ignore_private: bool = False, ignore_none: bool = False) -> str - Serialize a KCL object `data` to a JSON formatted str. - - decode(value: str) -> any - Deserialize `value` (a string instance containing a JSON document) to a KCL object. - - dump_to_file(data: any, filename: str, ignore_private: bool = False, ignore_none: bool = False) -> None - Serialize a KCL object `data` to a JSON formatted str and write it into the file `filename`. -- yaml - - encode(data: any, sort_keys: bool = False, ignore_private: bool = False, ignore_none: bool = False) -> str - Serialize a KCL object `data` to a YAML formatted str. - - decode(value: str) -> any - Deserialize `value` (a string instance containing a YAML document) to a KCL object. - - dump_to_file(data: any, filename: str, ignore_private: bool = False, ignore_none: bool = False) -> None - Serialize a KCL object `data` to a YAML formatted str and write it into the file `filename`. -- net - - split_host_port(ip_end_point: str) -> List[str] - Split the 'host' and 'port' from the ip end point. - - join_host_port(host, port) -> str - Merge the 'host' and 'port'. - - fqdn(name: str = '') -> str - Return Fully Qualified Domain Name (FQDN). - - parse_IP(ip) -> str - Parse 'ip' to a real IP address - - to_IP4(ip) -> str - Get the IP4 form of 'ip'. - - to_IP16(ip) -> int - Get the IP16 form of 'ip'. - - IP_string(ip: str | int) -> str - Get the IP string. - - is_IPv4(ip: str) -> bool - Whether 'ip' is a IPv4 one. - - is_IP(ip: str) -> bool - Whether ip is a valid ip address. - - is_loopback_IP(ip: str) -> bool - Whether 'ip' is a loopback one. - - is_multicast_IP(ip: str) -> bool - Whether 'ip' is a multicast one. - - is_interface_local_multicast_IP(ip: str) -> bool - Whether 'ip' is a interface, local and multicast one. - - is_link_local_multicast_IP(ip: str) -> bool - Whether 'ip' is a link local and multicast one. - - is_link_local_unicast_IP(ip: str) -> bool - Whether 'ip' is a link local and unicast one. - - is_global_unicast_IP(ip: str) -> bool - Whether 'ip' is a global and unicast one. - - is_unspecified_IP(ip: str) -> bool - Whether 'ip' is a unspecified one. -- base64 - - encode(value: str, encoding: str = "utf-8") -> str - Encode the string `value` using the codec registered for encoding. - - decode(value: str, encoding: str = "utf-8") -> str - Decode the string `value` using the codec registered for encoding. -- crypto - - md5(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `MD5` and the codec registered for encoding. - - sha1(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA1` and the codec registered for encoding. - - sha224(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA224` and the codec registered for encoding. - - sha256(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA256` and the codec registered for encoding. - - sha384(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA384` and the codec registered for encoding. - - sha512(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA512` and the codec registered for encoding. -- manifests - - `yaml_stream(values: [any], opts: {str:} = {sort_keys = False, ignore_private = True, ignore_none = False, sep = "---"}`. This function is used to serialize the KCL object list into YAML output with the `---` separator - -### The Built-in System Package - -KCL provides a list of built-in system modules, which are loaded automatically and can be directly used without providing any module name. For example, `print` is a widely used built-in module. - -The following is the full list of these built-in system modules: - -- print() - - The print function. -- multiplyof(a, b) - - Check if the modular result of a and b is 0 -- isunique(inval) - - Check if a list has duplicated elements -- len(inval) - Return the length of a value -- abs(x) - Return the absolute value of the argument. -- all(iterable) - Return True if bool(x) is True for all values x in the iterable. If the iterable is empty, return True. -- any(iterable) - Return True if bool(x) is True for any x in the iterable. If the iterable is empty, return False. -- bin(number) - Return the binary representation of an integer. -- hex(number) - Return the hexadecimal representation of an integer. -- oct(number) - Return the octal representation of an integer. -- ord(c) -> int - Return the Unicode code point for a one-character string. -- sorted(iterable) - Return a new list containing all items from the iterable in ascending order. A custom key function can be supplied to customize the sort order, and the reverse flag can be set to request the result in descending order. -- range(start, end, step=1) - Return the range of a value with start, end and step parameter. -- min(iterable) - With a single iterable argument, return its smallest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the smallest argument. -- max(iterable) - With a single iterable argument, return its biggest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the largest argument. -- sum(iterable, start) - Return the sum of a 'start' value (default: 0) plus an iterable of numbers. When the iterable is empty, return the start value. This function is intended specifically for use with numeric values and may reject non-numeric types. -- pow(x, y, z) - Equivalent to `x**y` (with two arguments) or `x**y % z` (with three arguments). Some types, such as ints, are able to use a more efficient algorithm when invoked using the three argument form. -- round(number, ndigits) - Round a number to a given precision in decimal digits. The return value is an integer if ndigits is omitted or None. Otherwise the return value has the same type as the number. ndigits may be negative. -- typeof(x: any, \*, full_name: bool = False) -> str - Return the type of the value 'x' at runtime. When the 'full_name' is 'True', return the full package type name such as `pkg.schema`. - -### Plugin Modules - -KCL compiler needs to provide the ability to dynamically expand and load plugin modules without modifying the compiler itself. KCL compiler needs to support flexible pluggable module extension mechanism, so that KCL users can use more abundant built-in function capabilities to simplify writing. - -KCL compiler needs to ensure the stability and safety of the expansion mechanism, without affecting the core of the compiler. - -Searching extended plugin module is performed after the standard system module. The standard system module has a higher priority in naming. If it exists a standard or built-in system module with the same name, the extended plugin module will be ignored. - -Importing and using the extended plugin module should be consistent with the standard or built-in system module. - -### Replacing Standard System Packages - -Replacing standard system modules is not allowed. - -## Examples - -We show more module features through an example. - -Suppose we have the following directories and files: - -``` - . - ├── mod1.k - ├── mod2.k - ├── pkg1 - │   ├── def1.k - │   ├── def2.k - │   └── def3init.k - └── pkg2 - ├── file2.k - └── subpkg3 - └── file3.k -``` - -From the structure we can see that `pkg1` and `pkg2` are two packages, `subpkg3` is a subpackage of `pkg2`, and `mod1.k` and `mod2.k` are regular modules. - -### Importing a Standard System Package - -The following statement can import the standard system module `math` - -```python -import math -``` - -This is the only way to import a standard system module. After importing a standard system module, functions, variables and schemas defined in it can be used. For example, the following statement uses the `log10` function -defined in `math` - -```python -a = math.log10(100) # a is 2 after computation. -``` - -### Importing a Regular Module - -In `mod1.k`, we can import `mod2` using one of the following syntaxes. - -```python -import mod2 -``` - -```python -import .mod2 -``` - -The difference is that in the first syntax, the KCL compiler will first try to check if `mod2` matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where `mod1.k` resists in, like what the second statement does. - -Suppose in `mod2.k` there is a definition of a variable:: - -```python -a = 100 -``` - -After importing `mod2`, we can access `a` in `mod1.k` using the following syntax - -```python -b = mod2.a -``` - -### Importing a Package - -In `mod1.k`, we can import `pkg1` using one of the following syntaxes. - -```python -import pkg1 -``` - -```python -import .pkg1 -``` - -The difference is that in the first syntax, the KCL compiler will first try to check if `pkg1` matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where `mod1.k` resists in, like what the second statement does. - -We can use similar statements to import `pkg2`. Note that importing `pkg2` will not import `subpkg3`. - -The name of the package is the name of the imported module. - -Suppose in `file2.k` that is inside `pkg2` there is a definition to variable `foo` - -```python -foo = 100 -``` - -This variable can be used in `mod1.k` after importing `pkg2` like the following - -```python -bar = pkg2.foo -``` - -### Importing a Subpackage - -To import `subpkg3` from `mod1.k`, one of the following statements can be used. - -```python -import pkg2.subpkg3 -``` - -```python -import .pkg2.subpkg3 -``` - -The behaviors of these statements are identical. - -The name of the subpackage is the name of the imported module. - -Suppose in `file3.k` that is inside `subpkg3` there is a definition to variable `foo` - -```python -foo = 100 -``` - -This variable can be used in `mod1.k` after importing `subpkg3` like the following - -```python -bar = subpkg3.foo -``` - -### Relative Importing - -Relative importing is useful when there is code trying to import modules that does not exist recursively inside the current directory. - -For example, the following statements, if written in `file3.k`, can be used to import `pkg2`, `pkg1` and `mod2` respectively. - -```python -import ...pkg2 # Go two levels up then import pkg2 -import ...pkg1 # Go two levels up then import pkg1 -import ...mod2 # Go two levels up then import mod2 -``` - -### Importing from a Root Path - -Suppose we have a `kcl.mod` file in the directory to mark it as a root path, then we have the following files: - -``` - . - |── kcl.mod - ├── mod1.k - ├── mod2.k - ├── pkg1 - │   ├── def1.k - │   ├── def2.k - │   └── def3init.k - └── pkg2 - ├── file2.k - └── subpkg3 - └── file3.k -``` - -In `pkg1` `def1.k`, we can import `pkg2.subpkg3` `file3` using the following syntaxes. - -```python -import pkg2.subpkg3.file3 -``` - -Importing from the root path is very convenient when the code is trying to import modules from a directory needs to look up multiple directories above this directory. At also, it is helpful to organize a large number of files in a root directory. - -### Importing a Module Inside a Package - -Note that `subpkg3` is only implemented with one file `file3.k`. The file can be regarded as a regular module and imported directly. - -In `mod1.k`, the importing statement would be:: - -```python -import pkg2.subpkg3.file3 -``` - -Different from importing `subpkg3`, now the name of the module is `file3`. We can access the variable `foo` defined in this module with the following -statement - -```python -bar = file3.foo -``` - -### Precedence of Importing - -When an import statement specifies a package to import, the virtual machine first looks for a directory named according to the import statement in the file system. - -If such a directory is not found, the virtual machine looks for a single file module. - -For example, when the statement `import a.b.c` appears, the virtual machine first looks for the directory `a/b/c` from the directory of the current file. If `a/b/c` is not found, the virtual machine looks for a file named `a/b/c.k`. If the file is also absent, an error is reported. - -### Package Implemented with Multiple Files - -Package `pkg1` is implemented with multiple KCL files. - -Multiple files can be used to define variables, schemas and functions, and they can access names defined in other files of this package. - -For example, suppose `def1.k` defines a variable `foo`, `def2.k` defines `bar`, and `def3init.k` defines a variable `baz`, when `pkg1` is imported by `mod1.k`, all these variable can be used - -```python -import pkg1 -a = pkg1.foo + pkg1.bar + pkg1.baz -``` - -Inside a module, names defined in a file can be accessed in another file without further importing. For example, suppose `bar` in `def2.k` would invoke `foo` defined in `def1.k`, it can directly use `foo` like the following - -```python -bar = foo + 1 -``` diff --git a/versioned_docs/version-0.5.6/reference/lang/spec/schema.md b/versioned_docs/version-0.5.6/reference/lang/spec/schema.md deleted file mode 100644 index c3d09f65..00000000 --- a/versioned_docs/version-0.5.6/reference/lang/spec/schema.md +++ /dev/null @@ -1,916 +0,0 @@ ---- -title: "Schema" -linkTitle: "Schema" -type: "docs" -weight: 2 -description: Schema ---- - -## Syntax - -### Schema Definition - -A schema is a language element to define a type of configuration data. - -To define a schema, the syntax is the following: - -```bnf -schema_stmt: [decorators] "schema" ["relaxed"] identifier ["[" [arguments] "]"] ["(" operand_name ")"] ":" NEWLINE [schema_body] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt | schema_index_signature | statement)* [check_block] _DEDENT -``` - -Attributes could be defined in a schema, the syntax is the following: - -```bnf -schema_attribute_stmt: [decorators] identifier ["?"] ":" type [(ASSIGN | augassign) test] NEWLINE -``` - -Index signature could be defined in a schema, the syntax is the following: - -```bnf -schema_index_signature: LEFT_BRACKETS [NAME COLON] [ELLIPSIS] basic_type RIGHT_BRACKETS COLON type [ASSIGN test] NEWLINE -``` - -Once defined, an attribute must have a valid type: - -```bnf -type: type_element ("|" type_element)* -type_element: schema_type | basic_type | list_type | dict_type -schema_type: operand_name -basic_type: "str" | "int" | "float" | "bool" -list_type: "[" (type)? "]" -dict_type: "{" (type)? COLON (type)? "}" -``` - -The followings are some basic examples: - -```python -# A person has a first name, a last name and an age. -schema person: - firstName: str - lastName: str - # fullName is generated by firstName and lastName - fullName: str = firstName + ' ' + lastName - # The default value of age is 0 - age: int = 0 - -# An employee IS a person, and has some additional information. -schema employee(person): - bankCard: int - nationality: str - -# A company has a name and many employees. -schema company: - name: str - employees: [employee] -``` - -More complex schema definitions will be elaborated after other concepts are -introduced. - -#### Optional Attribute - -Each attribute **must** be assigned with a not-None value as a schema instance unless it is modified by a question mark as an optional attribute. - -Examples: - -```bnf -schema employee(person): - bankCard?: int # bankCard is an optional attribute - nationality?: str # # nationality is an optional attribute -``` - -When there is an inheritance relationship: - -- If the attribute is optional in the base schema, it could be optional or required in the sub-schema. -- If the attribute is required in the base schema, it must be required in the sub-schema. - -### Configuration Definition - -A configuration is structured data stored in a dict-like structure. In KCL, we have introduced -the configuration definition syntax as a variant of dict definition syntax. - -```bnf -schema_expr: operand_name ("(" [arguments] ")")? dict_expr -``` - -As can be seen, apart from having an identifier as schema type, a configuration definition -is just an ordinary dict definition, and each key in the dict matches an attribute in the schema. - -To simplify configuration, schema attribute key is much easier to define as: - -- schema attribute key can be unquoted. When the attribute key has the same name as a variable, it must be quoted as a normal dict to avoid naming conflict. -- schema attribute key can be defined nested through `select expression`, such as `a.b.c`. - -The comma at the end of each line can be omitted. - -For example, we can define a `person` named `John Doe` using the following statement: - -```python -johnDoe = person { - # In the result, 'lastName' appears later than 'firstName', according the schema - lastName = 'Doe' - firstName = 'John' - # If we don't specify the 'age', the default value 0 is used. - # 'age': 20 -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' - 'age': 0 -} -``` - -Compared to the ordinary dict definition, a configuration definition has the following features: - -- Each attribute defined in the schema (or one of the schemas) could be configured, and config data has higher priority than the default value. -- When an attribute defined in the schema (or one of the schemas) is not configured in the configuration definition statement, and it has a default value, the default value is used. -- Unless the schema (or one of the schemas) is a **relaxed schema**, no more attributes can be defined. -- The quotation marks of dict key can be omitted. -- The comma at the end of each line can be omitted. -- Cases of **inheritance** will be discussed separately. - -For attributes of list, dict and schema types, the config data is added by **union** instead of reassignment. For instance: - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name = { - firstNam = "John" - lastName = "default" - } - -JohnDoe = Person { - name.lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' -} -``` - -#### Attribute Identify - -Each key identifier in the configuration expr identifies an element or a range of elements in a schema. The key identifier may consist of multiple attribute identifiers, and each attribute may be a basic type value, a list, a dict or schema. For example, the key identifier 'a.b.c' identifies the element 'c' in the 'A' schema: - -```python - -schema C: - c: int - -schema B: - b: C - -schema A: - a: B - -A { - a.b.c: 5 -} -``` - -To make the key identifier usage rules as clear as possible, we define the way of identifying with complex data types as follows. - -##### List - -Suppose we have a list attribute a. - -Identify an element in a: - -```python -a[0] # the first element -a[3] # the 4th element -a[-1] # the last element -a[-2] # the penultimate element -``` - -Identify a range of elements in the list: - -```python -a[2:5] # a slice of the third, 4th, and 5th elements -a[:5] # a slice of the first to 5th elements -``` - -#### Attribute Operator - -Once we identified the element(s), we can declare operation on it. It follows the pattern of `identifier op E`. - -#### Union - -Pattern: `identifier : E` - -The value of the expression `E` will be unioned into the element value. - -Examples: - -```python -a = A { - # union {d:4} into the element b.c, suppose c is a schema with an int type attribute d. - b.c : { - d : 4 - } -} -``` - -See 'union' in `expressions` spec for more details. - -#### Override - -Pattern: `identifier = E` - -The value of the expression `E` will override the element value. - -Examples: - -```python -a = A { - # override {c:4} to the element b, suppose b is a schema with an int type attribute c. - b = { - c: 4 - } -} -``` - -Unlike union, the override operation will reassign the element with a brand new value. -For basic type value, `union` and `override` have equivalent effects. - -Note: - -- Especially, we can "delete" its content by overriding the element to `Undefined`, such as `{ a = Undefined }`. - -#### Insert - -Pattern: `identifier += E` -Insert only works for list type `identifier`. - -List `E` will be inserted just after the specified index of the list `identifier`, and the following elements after the index will be automatically shifted. - -Examples: - -```python -a = A { - # insert {c:4} to the end position(just after index=1), suppose b is a list of schema with an int type attribute c. - b += { - c: 4 - } -} -``` - -If no index is specified, the last index will be used. - -The type of 'E' must be compatible with the type of list. See `types` for more details. - -#### Index Signature - -Index signatures can be defined in the KCL schema, and it means that the key-value constraints of the index signature can be used to construct a dict with the schema type, or additional checks can be added to the relaxed schema attributes to enhance the KCL type and semantic checks. - -- Use the form `[{attr_alias}: {key_type}]: {value_type}` to define an index signature in the schema, and `{attr_alias}` can be omitted. - -```python -schema Map: - """ - Map is a relaxed schema with a key of str type and a value of str type - """ - [str]: str # `{attr_alias}` can be omitted. - -data = Map { - key1 = "value1" - key2 = "value2" -} -``` - -- Mandatory all attributes of the schema key and value types - -```python -schema Person: - name: str - age: int # error, conflicts with the index signature definition `[str]: str` - [str]: str # The values of all attributes of the schema can only be strings -``` - -- Mandatory all attribute key and value types are defined in the schema, which is equivalent to restricting all attribute types except the relaxed attributes. - -```python -schema Person: - name: str - age: int - [...str]: str # Except for the `name` and `age` attributes, the key type of all other attributes of the schema must be `str`, and the value type must also be `str`. -``` - -- Define the index signature attribute alias and use it with the check block. - -```python -schema Data: - [dataName: str]: str - check: - dataName in ["Alice", "Bob", "John"] - -data = Data { - Alice = "10" - Bob = "12" - Jonn = "8" # error Jonn not in ["Alice", "Bob", "John"] -} -``` - -```python -import regex - -schema DataMap: - [attr: str]: str - check: - regex.match(attr, r'^[-._a-zA-Z0-9]+$') - -data = DataMap { - key1 = "value1" - "foo.bar" = "value2" # check error -} -``` - -### Schema Context - -The schema definition space can be regarded as a separate function context. - -Init statement could be defined inside the schema, the syntax is the following: - -```bnf -statement: small_stmt NEWLINE | if_stmt -``` - -The following is an example: - -```python -schema Person: - firstName: str = "John" - lastName: str - # fullName is generated by firstName and lastName in a separate init statement - fullName: str = firstName + ' ' + lastName - -JohnDoe = Person { - lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' -} -``` - -If statement, expr statement and assert statement are supported as a schema init -statement. See more in statement spec. - -- The attributes must be defined first, including inherited ones, and then used in the init statement. -- Statements in the schema context will be executed sequentially. -- The value of attributes referenced in the init statement will be evaluated at runtime. - See the **Configuration Definition** section for the assignment rules of non-referenced attributes. For example, `"fullName"` in Person is generated by `"firstName"` and `"lastName"` evaluated at runtime, in which firstName is 'John', and lastName is "Doe". - -The immutability of attributes in the schema context follows the same rules as the immutability of global variables: - -```python -schema Person: - age: int = 1 # Immutable attribute - _name: str = "Alice" # Mutable attribute - - age = 10 # Error - _name = "Bob" # Ok -``` - -#### Arguments - -Schema context can also have arguments. The following is an example. - -```python -schema Person[separator]: - firstName: str = "John" - lastName: str - fullName: str = firstName + separator + lastName - -JohnDoe = Person('_') { - lastName = "Doe" -} -``` - -The example is similar to the previous one, except that the separator character used in -the `"fullName"` member is passed in as an argument. The way to perform a schema generation -when the schema has an initialization function with arguments is demonstrated in the code. - -### Check Block - -Optionally, a check block can be added to a schema definition to allow -additional checking to be performed. - -The syntax is the following: - -```bnf -check_block: "check" ":" NEWLINE _INDENT check_expr+ _DEDENT -check_expr: test (IF test)? [":" primary_expr] NEWLINE -``` - -In terms of grammatical definition, a check block consists of a list of conditional expressions. The following is an example: - -```python -schema employee(person): - bankCard: int - gender: str - - check: - len(str(bankCard)) == 16 - gender in ['male', 'female'], "The gender {} is unsupported".format(gender) -``` - -The ability of KCL check expressions covers the abilities that can be defined by OpenAPI spec and is aligned with the ability of logical expressions. We consider further aligning the syntax with `CEL` spec. -Whether to support `lambda expressions` is still under discussion. - -Summary: - -- A check block consists of one or more logical **expressions**. -- When defining a configuration, the expressions in the check block are evaluated - in any order. If any of the expression is `False`, an error is reported. -- A custom error message can be provided after an expression. - -### Specifying Types - -Optionally, the type of any member of a schema can be specified. As previous examples have shown. - -A member can be of a basic type, such as a string (`str`), a floating-point number (`float`), a fixed-point number (`int`) or a boolean number (`bool`). - -A member can also be of a dictionary generated from another schema. In such a case, the name of the other schema is used as the type name. - -A member can also be a list or an ordinary dict: - -- A list with unspecified type of elements is `[]`. -- A list with elements of type `t` is `[t]`. Here `t` is another type. -- A dict with keys of type `kt` and values of type `vt` is `{kt:vt}`. -- `kt`, `vt` or both of them can be missing, like a list with unspecified type of elements. - -The followings are some more examples: - -- A list of lists of strings: `[[str]]`. -- A dict of keys with the type string and unspecified value types: `{str:}`. - -A member can be a **union type** defined by `|`, such as `a | b`, which means the type of the member could be a or b. - -A union type can include types of `int`, `str`, `float`, `bool`, `list` and `dict` and support type nesting e.g. `{str:str|int}` and `[[int|str]|str|float]`, etc. - -Examples: - -```python -schema x: - p: int | str # p could be defined as a int or string -``` - -### Immutability - -KCL pursues strict immutability of schema attributes. It's generally followed the rules: - -- For the attributes of the basic type, such as string, int and float, it's allowed to be reassigned - through the init statement in **schema context** or by the **configuration definition**. -- For the attributes of list, dict and schema type, it's allowed to be reassigned only by the init statement in **schema context**. The content of it is allowed to be operated in **schema context** or by the **configuration definition**. -- Any other attempt to reassign or modify schema attribute will report an error. - -#### Assign by Value - -When using a schema variable to assign the value to another variable, we can only get a deep copy of its value, not a pointer or reference. That is, modifying the assigned value will not change the assigned schema variable. - -```python -schema Person: - name: str - -person = { - name = "Alice" -} -personCopy = person # 'personCopy' is a deep copy of 'person' and modifying 'personCopy' will not affect 'person' -``` - -### Union Operator - -For list, dict and schema, we can union delta to existing data. For example: - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name = { - firstName = "John" - } - - # union a schema and a dict - name: Name { - lastName = "Doe" - } - -person = Person {} -``` - -The result is a **dict**: - -```python -{ - 'person': { - 'name': { - 'firstName': 'Jhon', - 'lastName': 'Doe' - } - } -} -``` - -### Other Operators - -Except for `assignment` and `union assignment`, it's not support other operators on schema type data. -Report an error if trying to use other operators on schema type data. - -### Deprecated - -The schema attribute can be marked as deprecated once it's considered invalid. - -```python -schema Person: - @deprecated(version="1.1.0", reason="use fullName instead", strict=True) - name: str - ... # Omitted contents - -person = Person { - # report an error on configing a deprecated attribute - name = "name" -} -``` - -- Deprecated attributes cannot be configured under any circumstances. Report an error or warning once the attribute is assigned. -- Define the expired version of the attribute through **version**, and define the reason for the attribute expired through **reason**. -- When strict is true, the attribute assignment will cause an error, otherwise it will report a warning and ignore the attribute assignment. - -### Composition - -The composition is a common way to define complex structures. KCL provides simplified means for the configuration definition of combined structures. - -Assuming we have the following schemas, which is defined by a combination of multiple schemas. - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name - age: int - -schema Group: - name: str - persons: [Person] -``` - -To config a group: - -```python -group = Group { - name = "group" - persons = [{ - name = { - firstName = "John" - lastName = "Doe" - } - age = 24 - }] -} -``` - -- Top-level schema name is required to config a schema. -- The schema of the attributes in the schema can be omitted. - -Multi-level nested schemas will make the configuration verbose. KCL supports defining attributes in the schema through `selector expression`. The selector form is **x.y.z**, see the following example: - -```python -group = Group { - name = "group" - persons = [{ - name.firstName = "John" - name.lastName = "Doe" - age = 24 - }] -} -``` - -- Selector can be used to represent attribute in a schema - -### Inheritance - -Inheritance is an effective means to define a hierarchical structure definition, and KCL supports limited **single inheritance** of the schema. - -```python -schema Person: - firstName: str - lastName: str - -# schema Scholar inherits schema Person -schema Scholar(Person): - fullName: str = firstName + '_' + lastName - subject: str - -JohnDoe = Scholar { - firstName = "John", - lastName = "Doe", - subject = "CS" -} -``` - -The result is a **dict**: - -```python -{ - 'JohnDoe': { - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' - 'subject': 'CS' - } -} -``` - -Each schema can be treated as a separated function context. Statements, including attribute statements and init statements, in the context of schemas will be evaluated from base schema to subschema according to the inheritance order. Each schema context is evaluated only once sequentially. The same goes for expressions in the check block. In the example, firstName and lastName are configured in the context of Person schema, and fullName is formed by splicing firstName and lastName in the context of Scholar schema. - -The default value can be modified in each schema. Value defined in **Configuration Definition** has a higher priority than the default value. Attributes with default values in any schema context ​​will eventually be unioned by configuration data. References to attributes in the schema context statements will use the value with unioned configuration data on evaluating at runtime. For example: - -```python -schema a: - x = 1 - y = x * 2 - -schema b(a): - x = 2 - -v = a { - x = 3 -} - -``` - -The result is a **dict**: - -```python -{ - 'v': { - 'x': 3 - 'y': 6 - } -} -``` - -Notes: - -- Report an error if inheriting more than one base schema. -- The type of the base schema attribute cannot be modified in the subschema. -- Report an error if inheriting a **mixin**. -- Report an error when a circular dependency occurs. - -Limitations: - -Since inheritance will derive some complex demands, we are cautious about these complex demands. There are still some restrictions on inheritance, and it's still under discussion. - -- KCL provides limited and deterministic polymorphism support, more complex and flexible polymorphism support, such as **self**, **super** keywords, are temporarily not included in the schema definition. -- Currently, KCL only supports the polymorphism of the inherited attributes of the schema, and does not support the polymorphism of the expressions in the check block. -- For the case of multiple levels of schema inheritance, the schema arguments can only be passed to the last level of sub-schema. - -### Mixin - -In addition to **composition** and **inheritance**, KCL supports declarative reuse of schema code through the **mixin** mechanism. To use a mixin, we only need to declare the **mixin** in the schema definition. - -The **mixin** syntax is the following: - -```bnf -//////////// mixin_stmt //////////// -mixin_stmt: "mixin" "[" [mixins | multiline_mixins] "]" "\n" -multiline_mixins: "\n" _INDENT mixins "\n" _DEDENT -mixins: operand_name ("," ("\n" mixins | operand_name))* -``` - -Here is a simple example: - -```python -schema Person: - mixin [FullNameMixin] - firstName: str = "default" - lastName: str - -schema FullNameMixin: - fullName: str = "{} {}".format(firstName, lastName) - -JohnDoe = Person { - firstName = "John" - lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'JohnDoe': { - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' - } -} -``` - -Multiple mixins can be added to a single schema, and mixins context will be evaluated after the host schema context at runtime. In the inheritance scenario, the mixin context can be regarded as a part of the host schema context, and the overall evaluation of schema context order is not affected. - -Notes: - -- The name of **mixin** schema must end with 'Mixin', otherwise an error will be reported. -- The attributes referenced in the **mixin** must be defined in the **mixin** itself or host schema, otherwise an error will be reported. - -### Protocol - -In addition to schema, an additional type definition method `protocol` is provided in KCL, and its properties are as follows: - -- In a protocol, only attributes and their types can be defined, complex logic and check expressions cannot be written, and mixins cannot be used. -- A protocol can only inherit or refer to other protocols, but cannot inherit or refer to other schemas. - -We can use **protocol** to add an optional host type to the dynamically inserted **mixin**. - -The **mixin** can define its host type through the `for` keyword, and internally it will query the type corresponding to the attribute from the host type. - -```python -protocol DataProtocol: # A mixin host type - data: str - -mixin DataMixin for DataProtocol: # Using the `for` keyword to define a mixin host type - x: int = data # The type of `data` is `str`, which is from `data` of `DataProtocol` -``` - -In `DataMixin`, the `data` attribute is obtained according to the `DataProtocol` host type as `str` type, and then a type error will occur when the value is assigned to `x` of type `int`: - -```python -protocol DataProtocol: - data: str - -mixin DataMixin for DataProtocol: - x: int = data # Error: expect int, got str - x: str = data # Error: can't change schema field type of 'x' from int to str -``` - -Please note that the host type **protocol** can only be used for **mixin** definitions (the suffix name is `Mixin`), otherwise an error will be reported. - -```python -protocol DataProtocol: - data: str - -schema Data for DataProtocol: # Error: only schema mixin can inherit from protocol - x: str = data -``` - -### Schema Context Evaluation - -The schema definition is composed of attribute statements, configuration data, init statements, mixins, and checks. In a separate schema context, the evaluation top-down order is as follows: - -``` -|------------------------------------------| -| attribute defaulting | -|------------------------------------------| -| configuration union | -|------------------------------------------| -| attribute templating | -|------------------------------------------| -| statements in declaration order | -|------------------------------------------| -| mixins in declaration order | -|------------------------------------------| -| check expressions in any order | -|------------------------------------------| -``` - -In the case of schema inheritance, each schema context is evaluated from the base schema in the order of inheritance, and each context is evaluated only once. -Suppose there are schemas a, b, and c, where c inherits b and b inherits a. Schema contexts will be evaluated in top-down order as: - -``` -|-----------------| -| schema a | -|-----------------| -| schema b | -|-----------------| -| schema c | -|-----------------| -``` - -### Members - -Built-in function and members of schema - -- instances() - Return the list of existing instances of a schema. - -### Irrelevant Order Calculation - -The irrelevant order calculation in the schema indicates the reference relationship between the internal attributes of the schema. For example, when we declare an expression of the form `a = b + 1`, the calculation of the value of `a` depends on the calculation of the value of `b`. When the compiler calculate the value of `a` and the value of `a` depends on the value of `b`, the compiler will choose to first calculate the value of `b`, and then calculate the value of a according to the expression `a = b + 1`, which is slightly different from the calculation method of traditional procedural language the difference. - -Since the calculation of values in the schema is based on dependencies, just like a directed acyclic graph traverses each node in the graph according to the order of topological sorting, the order of declaration of attributes in the schema is not so important, so the feature is called the irrelevant order calculation. - -Please note that there can be no circular references between different schema attribute values. - -We can see this feature through the following examples. - -```python -schema Person: - name?: str - age: int = _age - - _age = 10 - - if name == "Son": - _age = 18 - -schema Son(Person): - name: str = "Son" - -person = Person {} -son = Son {} -``` - -The output is - -```yaml -person: - name: null - age: 10 -son: - name: Son - age: 18 -``` - -Besides, we can achieve KCL polymorphism such as - -```python -schema Person: - name?: str - _age: int = _age - - _age = 10 - if name == "Son": - _age = 18 - elif name == "SonConf": - _age = 24 - -schema Son(Person): - name: str = "Son" - -person = Person() {} -son = Son() { - name = "SonConf" -} -``` - -The output is - -```yaml -person: - name: null - age: 10 -son: - name: SonConf - age: 24 -``` - -More examples: - -```python -schema Fib: - n1: int = n - 1 - n2: int = n1 - 1 - n: int - value: int = _value - - if n <= 2: - _value = 1 - else: - _value = (Fib {n = n1}).value + (Fib {n = n2}).value - -fib8 = (Fib {n = 8}).value -``` - -The output is - -```yaml -fib8: 21 -``` - -As in the above examples, we can see that in the schema, we only need to simply specify the dependency between attributes, and the compiler will automatically calculate the value based on the dependency, which can help us save a lot of boilerplate code and reduce configuration difficulty of writing. diff --git a/versioned_docs/version-0.5.6/reference/lang/spec/statements.md b/versioned_docs/version-0.5.6/reference/lang/spec/statements.md deleted file mode 100644 index b09488b9..00000000 --- a/versioned_docs/version-0.5.6/reference/lang/spec/statements.md +++ /dev/null @@ -1,185 +0,0 @@ ---- -title: "Statements" -linkTitle: "Statements" -type: "docs" -weight: 2 -description: Statements ---- - -## Syntax - -In KCL, statements consist of small statements and compound statements. The syntax is the following: - -```bnf -preamble_statement: preamble_small_stmt | preamble_compound_stmt -preamble_small_stmt: (small_stmt | import_stmt) NEWLINE -preamble_compound_stmt: compound_stmt | schema_stmt -statement: small_stmt NEWLINE | compound_stmt -compound_stmt: if_stmt -small_stmt: assign_stmt | expr_stmt | assert_stmt -``` - -The preamble statement is used to define the module level statements, consist of `statement`, `import_stmt`, and `schema_stmt`. The statement is used to define the block level statements, which are used in the `if` statement and `schema` statement. - -### Small Statements - -A small statement is comprised of a single logical line. Multiple statements in one-line are not allowed. - -#### Assignment Statements - -Generally, assign_stmt is divided into assignment and augmented assignment. The syntax is the following: - -```bnf -assign_stmt: target_primary ("=" target_primary)* "=" test | target_primary augassign test -augassign: "+=" | "-=" | "*=" | "**=" | "/=" | "//=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>=" | "or" | "and" -target_primary: identifier | target_primary DOT identifier -``` - -An assignment statement has the form `lhs = rhs`. It evaluates the expression on the right-hand side then assigns its value (or values) to the variable (or variables) on the left-hand side. - -The **target_primary** on the left-hand side is an `identifier` or an `identifier` followed by select dots. - -Note: When using **target_primary** will cause collisions, use **primary_expr** as an alternative. - -Examples: - -```python -k = 1 -a.b = "a.b" -``` - -To keep it simple, the compound target is not supported as **target_primary**. - -The right value of an assignment statement is a conditional expression, which is discussed separately. - -An augmented assignment, which has the form `lhs op= rhs` updates the variable `lhs` by applying a binary arithmetic operator op (one of +, -, \*, /, //, %, &, |, ^, <<, >>) to the previous value of `lhs` and the value of `rhs`. - -The **target_primary** on the left-hand side is the same as assignment statement. Examples: - -```python -_x -= 1 -_filename += ".k" -``` - -There is no concept of in-place modification in KCL. The `augassign` statement will modify a copy of the **target_primary** and assign the copy to **target_primary**. - -In particular, in KCL, the `|=` symbol represents the **union** operation, which is defined as follows: - -- The behavior of the **union** operation needs to be consistent with the behavior of the **configuration definition**. - -See **expressions** spec for more details of union operator in **Arithmetic Operations**. - -#### Expression Statements - -An expression statement evaluates an expression and discards its result. - -Syntax: - -```bnf -expr_stmt: expression -``` - -An expression statement supported in KCL is function invocation expression, which is discussed in **expression** spec. - -```python -print(k) # print a variable -``` - -#### Import Statements - -Import statements are used to **search** and **load** a module, and define a name or names in the local namespace for the scope where the import statement occurs. - -Syntax: - -```bnf -import_stmt: "import" dot_name ("as" NAME)? -dot_name: [leading_dots] identifier (DOT identifier)* -leading_dots: "."+ -``` - -Examples: - -```python -import math # import a built-in module math -import pkg # import pkg -import pkg.foo # import pkg.foo -import pkg.subpkg # import a subpkg in a pkg -import .pkg2.subpkg3 # import a subpkg in a pkg inside of current pkg -import ...pkg2 # Go two levels up then import pkg2 -``` - -See **module** spec for more details of module spec. - -#### Assert Statements - -Assert statements are a convenient way to insert debugging assertions into KCL code. - -The syntax is the following: - -``` -assert_stmt: ASSERT test ("," test)? -``` - -The conditional expression in assert will be evaluated and get a boolean. Report an error if returning a `False`. - -Examples: - -```python -assert: x > 1 # report an error on x <= 1 -``` - -#### Conditional Statements - -KCL allows using conditional statements to control the instructions to -be executed. They are also called the control-flow statements. - -The only type of control-flow syntax is the well-known `if-elif-else` syntax. - -The syntax of the `if-elif-else` statement is the following. - -```bnf -if_stmt: "if" test ":" suite ("elif" test ":" suite)* (ELSE ":" suite)? -suite: small_stmt | NEWLINE _INDENT statement+ _DEDENT -``` - -An `if` or `elif` statement evaluates a given expression. When the expression -is evaluated to `True`, a list of statements following `:` are executed. - -The following is an example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - print("maybe a is negative") -else: - print("a >= 100") -``` - -`if-elif-else` statements can be nested. For example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - if a < 0: - print("a is negative") - print("No matter a is negative or positive, this message is printed") -else: - print("a >= 100") -``` - -#### Schema Statements - -Schema statements are used to define a type of configuration data. The syntax is the following: - -```bnf -schema_stmt: [decorators] "schema" ["relaxed"] identifier ["[" [arguments] "]"] ["(" operand_name ")"] ":" NEWLINE [schema_body] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt | statement)* [check_block] _DEDENT -``` - -See **schema** spec for more details of schema spec. diff --git a/versioned_docs/version-0.5.6/reference/lang/spec/variables.md b/versioned_docs/version-0.5.6/reference/lang/spec/variables.md deleted file mode 100644 index b3e1c539..00000000 --- a/versioned_docs/version-0.5.6/reference/lang/spec/variables.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: "Variables" -linkTitle: "Variable" -type: "docs" -weight: 2 -description: Variable ---- - -In KCL, variables can be defined using assign statements. For example, the following statement defines a variable `spam` to a string `"ham"`. - -```python -spam = "ham" -``` - -There are two types of variables, which are global variables and list comprehension local variables. - -- A global variable is defined not within any context. -- A comprehension local variable is defined inside a comprehension. - -A variable can be used after definition, until the end of the current scope. - -For a global variable, the scope is the module it is defined in. Note that a module can consists of multiple source files. - -For a list comprehension local variable, the scope is the list comprehension it is defined in. - -More information on modules, list comprehensions and scopes will be discussed in later chapters. - -## Immutability - -Global variables are immutable. In other words, once defined such a variable cannot be redefined (or, i.e., modified). - -The following code is illegal, and KCL will report an error during evaluation. - -```python -spam = "ham" -spam = "eggs" # Error: The immutability rule is violated! -``` - -- A variable starts with the `_` character is mutable. - -```python -_spam -cond = True -if cond: - _spam = "ham" -else: - _spam = "eggs" -``` - -## Variable Exporting - -As shown in the preview chapter, KCL is able to export evaluation results to the standard output according to a target data format. - -The rules are the followings: - -- Living global variables at the end of an evaluation will be dumped out. -- If the name of a variable starts with the `_` character, it will not be dumped out. - -## Uniqueness of Exported Variable Identifier - -Each exported variable identifier must be unique in its package, so that an exported variable could be located uniquely by package location path and variable identifier, such as 'a.b.c:var', in which 'a.b.c' locates a package. - -Two variable identifiers are different if: - -- they are spelled differently -- they are defined in different packages and are not compiled in a single execution - -Identifying an exported variable should be supported by the kcl compiler, which needs to provide corresponding identifying features through the command line and api form. diff --git a/versioned_docs/version-0.5.6/reference/lang/types/_category_.json b/versioned_docs/version-0.5.6/reference/lang/types/_category_.json deleted file mode 100644 index 8b257445..00000000 --- a/versioned_docs/version-0.5.6/reference/lang/types/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Types", - "position": 4 -} diff --git a/versioned_docs/version-0.5.6/reference/lang/types/types.md b/versioned_docs/version-0.5.6/reference/lang/types/types.md deleted file mode 100644 index ee88c64d..00000000 --- a/versioned_docs/version-0.5.6/reference/lang/types/types.md +++ /dev/null @@ -1,1381 +0,0 @@ -# Type System - -This document describes the type system of KCL, including: - -- Type rules -- Type checking -- Type conversion -- Type inference - -## Type Rules - -### Basic Definition - -#### Assertion - -All free variables of $S$ are defined in $\Gamma$ - -$$ -\Gamma \vdash S -$$ - -$\Gamma$ is a variable's well-formed environment, such as $x_1:T_1$, ..., $x_n:T_n$ - -The assertion of $S$ has three forms: - -**Environment assertion** indicates that $\Gamma$ is a well-formed type. - -$$ -\Gamma \vdash ◇ -$$ - -**Well-formed type assertion**. In the environment $\Gamma$, $nat$ is a type expression. - -$$ -\Gamma \vdash nat -$$ - -**Typing judgment assertion**. In the environment $\Gamma$,$E$ has the type $T$. - -$$ -\Gamma \vdash E: T -$$ - -#### Inference Rules - -Representation - -$$ -\frac{\Gamma \vdash S_1, ..., \Gamma \vdash S_n}{\Gamma \vdash S} -$$ - -In the inference rules, $u$, $v$, and $w$ are used to represent variables, $i$, $j$, $k$ are used to represent integers, $a$ and $b$ are used to represent floating point numbers, $s$ is used to represent strings, $c$ is used to represent literal values of constants (integers, floating point numbers, strings, boolean), $f$ is used to represent functions, $T$, $S$, $U$ are used to represent types. - -## Environment Rules - -Env ⌀ - -$$ -\frac{}{⌀ \vdash ◇ } -$$ - -## Type Definitions - -Type Bool - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash boolean} -$$ - -Type Int - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash integer} -$$ - -Type Float - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash float} -$$ - -Type String - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash string} -$$ - -Type Literal - -$$ -\frac{ c \in \{boolean, integer, float, string\}}{\Gamma \vdash literalof(c)} -$$ - -Type List - -$$ -\frac{\Gamma \vdash T \ T \neq Void}{\Gamma \vdash listof(T) } -$$ - -Type Dict - -$$ -\frac{\Gamma \vdash T_1 \ \Gamma \vdash T_2\ T_1 \neq Void \ \ T_2 \neq Void}{\Gamma \vdash dictof(T_k=T_1, T_v=T_2)} -$$ - -Type Struct - -$$ -\frac{\Gamma \vdash T_{1} \ ... \ \Gamma \vdash T_{n} \ \ T_i \neq Void \ K_1 \neq K_n}{\Gamma \vdash structof(K_1 : T_{1}, ... , K_n : T_{n})} -$$ - -Type Union - -$$ -\frac{\Gamma \vdash T_1 \ ... \ \Gamma \vdash T_n \ \ T_i \neq Void}{\Gamma \vdash unionof(T_1, ..., T_n)} -$$ - -Type None - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash None} -$$ - -Type Undefined - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Undefined} -$$ - -Type Void - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Void} -$$ - -Type Any - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Any} -$$ - -Type Nothing - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Nothing} -$$ - -## Typing Judgment Rules - -### Operand Expr - -Exp Truth - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash true: boolean} -$$ - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash false: boolean} -$$ - -Exp Int - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash int: integer} -$$ - -Exp Flt - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash flt: float} -$$ - -Exp Str - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash str: string} -$$ - -Exp None - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash none: none} -$$ - -Exp Undefined - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash undefined: undefined} -$$ - -Expr ListExp - -$$ -\frac{\Gamma \vdash E_1: T_1 \ E_2: T_2 \ ... \ E_n: T_n}{\Gamma \vdash [E_1, E_2, ..., E_n]: listof \ sup(T_1, T_2, ..., T_n)} -$$ - -Expr ListComp - -$$ -\frac{\Gamma \vdash E_1: T_1 \ \Gamma \vdash v: T \ \Gamma \vdash E_2: listof \ T \ \Gamma \vdash E_3: boolean}{\Gamma \vdash [E_1 \ for \ v \ in \ E_2 \ if \ E_3]: listof(T_1) } -$$ - -Expr DictExp - -$$ -\frac{\Gamma \vdash E_{k1}: T_{k1} \ \Gamma \vdash E_{v1}: T_{v1} \ ... \ \Gamma \vdash E_{kn}: T_{kN} \ \Gamma \vdash E_{vn}: T_{vN}}{\Gamma \vdash \{E_{k1}: E_{v1}, ..., E_{{kn}}: E_{vn}\}: dictof(T_{k}=sup(T_{k1}, T_{k2}, ... T_{kn}), \ T_{v}=sup(T_{v1}, T_{v2}, ..., T_{vn}))} -$$ - -Expr DictComp - -$$ -\frac{\Gamma \vdash E_1: T_{rki} \ \Gamma \vdash E_2: T_{rvi} \ \Gamma \vdash v_1: T_k \ \Gamma \vdash v_2: T_v \ \Gamma \vdash E_3: dictof(T_{k}, \ T_{v}) \ \Gamma \vdash E_4: boolean}{\Gamma \vdash \{E_1:E_2 \ for \ (v_1, v_2) \ in \ E_3 \ if \ E_4\}: dictof(T_{k}=sup(T_{rk1}, T_{rk2}, ..., T_{rkn}), T_{v}=sup(T_{rv1}, T_{rv2}, ..., T_{rvn})) } -$$ - -Expr StructExpr - -$$ -\frac{\Gamma \vdash E_{1}: T_{1} \ ... \ \Gamma \vdash E_{n}: T_{n} \ K_1 \neq K_n}{\Gamma \vdash \{K_{1} = E_{1}, ..., K_{{n}} = E_{n}\}: structof(K_1 : T_{1}, ... , K_n : T_{n})} -$$ - -The literal type is the value type of basic type, the union type is the combination type of types, void, any, nothing are special type references, and there is no direct value expression correspondence. - -### Primary Expr - -Expr Index - -$$ -\frac{\Gamma \vdash E: listof(T) \ \Gamma \vdash Index: integer}{\Gamma \vdash E[Index]: T} -$$ - -Expr Call - -$$ -\frac{\Gamma \vdash E_1: T_1 \rightarrow T_2 \ \Gamma \vdash E_2: T_1}{\Gamma \vdash E_1 \ (E_2): T_2} -$$ - -Expr List Selector - -$$ -\frac{\Gamma \vdash E: listof(T) \ \Gamma \vdash Index: integer}{\Gamma \vdash E.[Index]: T} -$$ - -Expr Dict Selector - -$$ -\frac{\Gamma \vdash E: dictof(T_k = T_1, T_v=T_2) \ \Gamma \vdash S_1: string \ ... \ \Gamma \vdash S_n: string}{\Gamma \vdash E.\{S_1, ..., S_n\}: dictof(T_k = T_1, T_v=T_2)} -$$ - -Expr Struct Selector - -$$ -\frac{\Gamma \vdash E: structof(K_1 : T_{1}, ... , K_n : T_{n}) \ \Gamma \vdash K_i: string}{\Gamma \vdash E.K_i: T_{i}} -$$ - -### Unary Expr - -Expr + - -$$ -\frac{\Gamma \vdash E: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash \ +E: T} -$$ - -Expr - - -$$ -\frac{\Gamma \vdash E: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash \ -E: T} -$$ - -Expr ~ - -$$ -\frac{\Gamma \vdash E: integer}{\Gamma \vdash \ ~E: integer} -$$ - -Expr not - -$$ -\frac{\Gamma \vdash E: boolean}{\Gamma \vdash \ not \ E: boolean} -$$ - -### Binary Expr - -Expr op, op $\in$ {-, /, %, \*\*, //} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash E_1 \ op \ E_2: T} -$$ - -Expr + - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, float, string, listof(T_1)\}}{\Gamma \vdash E_1 \ + \ E_2: T} -$$ - -Expr \* - -$$ -\frac{\Gamma \vdash E_1: T_1 \ \ \ \Gamma \vdash E_2: T_2 \ \ \ \ (T_1==T_2 \in \{integer, float\}) \ or \ (T_1 == interger \ and \ T_2 \ \in \ \{string, listof(T_3)\}) \ or \ (T_2 == interger \ and \ T_1 \ \in \ \{string, listof(T_3)\})} {\Gamma \vdash E_1 \ * \ E_2: T} -$$ - -Expr % - -$$ -\frac{\Gamma \vdash E_1: interger \ \ \ \Gamma \vdash E_2: integer}{\Gamma \vdash E_1 \ \% \ E_2: interger} -$$ - -Expr op, op $\in$ \{or, and\} - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ op \ E_2: boolean} -$$ - -示例 - -Expr and - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ and \ E_2: boolean} -$$ - -Expr op, op $\in$ \{==, !=, <, >, <=, >=\} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T}{\Gamma \vdash E_1 \ op \ E_2: boolean} -$$ - -Expr > - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ > \ E_2: boolean} -$$ - -Expr op, op $\in$ {&, ^, ~, <<, >>} - -$$ -\frac{\Gamma \vdash E_1: integer \ \ \ \Gamma \vdash E_2: integer}{\Gamma \vdash E_1 \ op \ E_2: integer} -$$ - -Expr | - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, listof(T_1), dictof(T_k, T_v), structof(K_1=T_1, ..., K_n=T_n)\}}{\Gamma \vdash E_1 \ | \ E_2: T} -$$ - -Expr op, op $\in$ {in, not in} - -$$ -\frac{\Gamma \vdash E_1: string \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{dictof, structof\}}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: listof(S), T \sqsubseteq S}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -Expr op $\in$ {is, is not} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -### IF Expr - -Expr If - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: T \ \ \ \Gamma \vdash E_3: T}{\Gamma \vdash if \ E_1 \ then \ E_2 \ else \ E_3: T} -$$ - -### Stmt - -Stmt If - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash S_1: Void \ \ \ \Gamma \vdash S_2: Void}{\Gamma \vdash if \ E_1 \ then \ S_1 \ else \ S_2: Void} -$$ - -Stmt Assign - -$$ -\frac{\Gamma \vdash id: T_0 \ \ \ \Gamma \vdash T_1 \ \ \ \Gamma \vdash E: T_2}{\Gamma \vdash id: T_1 \ = \ E : Void} -$$ - -Type Alias - -$$ -\frac{\Gamma \vdash id: T_0 \ \ \ \Gamma \vdash T_1}{\Gamma \vdash type \ id \ = \ T_1 : Void} -$$ - -## Union - -List Union - -$$ -\frac{\Gamma \vdash \ listof(T) \ \ \ \Gamma \vdash \ listof(S)}{\Gamma \vdash \ listof(unionof(T, S))} -$$ - -Dict Union - -$$ -\frac{\Gamma \vdash \ dictof(T_1, T_2) \ \ \ \Gamma \vdash \ dictof(S_1, S_2)}{\Gamma \vdash \ dictof(unionof(T_1, S_1), unionof(T_2, S_2))} -$$ - -Struct Union - -Define two structures: $structof(K_{1}: T_{1}, ..., K_{n}: T_{n}),structof(H_{1}: S_{1}, ..., H_{m}: S_{n})$ - -Define their union types: - -$$ -structof(J_{1}: U_{1}, ..., J_{p}: U_{n}) = structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \bigcup structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) -$$ - -Example - -$$ -structof() \ \bigcup \ structof(H_{1}: T_{1}, ..., H_{m}: T_{n}) = structof(H_{1}: T_{1}, ..., H_{m}: T_{n}) -$$ - -$$ -structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \ \bigcup \ structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) = structof(K_1: T_1) :: (structof(K_{2}: T_{2}, ..., K_{n}: T_{n}) \ \bigcup \ structof(H_{1}: S_{1}, ..., H_{m}: S_{n})) -$$ - -where "::" denotes the operation of adding a dual to a structure, which is defined as follows: - -$$ -structof(K_{1}: T_{1}) :: structof() = structof(K_{1}: T_{1}) -$$ - -$$ -structof(K_{1}: T_{1}) :: structof(K_{1}: T_{1}', ..., K_n: T_{n}) = structof(K_{1}: union\_op(T_{1}, T_{1}'), ..., K_{n}: T_{n}) -$$ - -$$ -structof(K_{1}: T_{1}) :: structof(K_{2}: T_{2}, ..., K_n: T_{n}) = structof(K_{2}: T_2) :: structof(K_{1}: T_1) :: structof(K_{3}: T_3, ..., K_{n}: T_{n}) -$$ - -Based on this, the union of two structures is defined as: - -$$ -\frac{\Gamma \vdash structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \ \Gamma \vdash structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) \ structof(J_{1}: U_{1}, ..., J_{p}: U_{n}) = structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \bigcup structof(H_{1}: S_{1}, ..., H_{m}: S_{n})}{\Gamma \vdash structof(J_{1}: U_{1}, ..., J_{p}: U_{n}))} -$$ - -where $union\_op(T_1, T_2)$ denotes different types of judgment operations for the same $K_i$. - -- When $T_1$ and $T_2$ have the partial order relation. If $T_1 \sqsubseteq T_2$, return $T_2$, otherwise return $T_1$, which is the minimum upper bound -- When $T_1$ and $T_2$ have no partial order relationship, there are three optional processing logic: - - Structure union failed, return a type error. - - Return the type of the latter $T_2$. - - Return the type $unionof (T_1, T_2)$. - -Here, we need to choose the appropriate processing method according to the actual needs. - -Structure inheritance can be regarded as a special union. The overall logic is similar to that of union, but in $union\_op(T_1, T_2)$ for the same $K_i$, the different types of judgment operations are as follows: - -- When $T_1$ and $T_2$ have the partial order relation and $T_1 \sqsubseteq T_2$, return $T_1$, that is, only if $T_1$ is the lower bound of $T_2$, the lower bound of $T_1$ shall prevail. -- Otherwise, a type error is returned. - -Through such inheritance design, we can achieve hierarchical, bottom-up and layer-by-layer contraction of type definition. - -## Operation - -KCL supports operations on structure attributes in the form of $p op E$. That is, for the given structure $A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})$, the path $p$ in the structure is specified with the value of $E$ (such as union, assign, insert, etc.). - -Define the following update operations: - -$$ -\frac{{\Gamma\vdash A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})}  {\Gamma\vdash p \in (K_{1}, ..., K_{n})} \ {\Gamma\vdash e:T}   k \neq k_1, ..., k \neq k_n} -{ A \{p \ op \ e\}:\{K_1:T_1, ..., K_n:T_n\}∪\{p:T\}} -$$ - -That is to say, the operation on the path $p$ is essentially a union of two structures. The rules for the same name attribute type union depend on the situation. For example, the path $p$ is an identifier $p=k_1$ that can be used as a field name $k_1$, and the field name in structure A is also $k_1$, its type is $T_1$, and the type of the expression $e$ is also $T_1$, then - -$$ -\frac{{\Gamma\vdash A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})}  {\Gamma\vdash p = K_{1}} \ {\Gamma\vdash e:T_1}   k \neq k_1, ..., k \neq k_n} -{ A \{p \ op \ e\}:\{K_1:T_1, ..., K_n:T_n\}} -$$ - -Note: - -- The type $T_1$ of the expression $e$ have the same type with the original attribute of the same name $K_1$. It can be relaxed appropriately according to the actual situation, such as the type of $e$ $\sqsubseteq T_1$ is enough. -- For the operation of nested multi-layer structures, the above rules can be used recursively. - -## Type Partial Order - -### Basic Types - -$$ -Type \ T \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ T -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Bool \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Int \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Float \sqsubseteq Type \ Any -$$ - -$$ -Type \ Int \sqsubseteq Type \ Float -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ String \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Literal \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ List \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Dict \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Struct \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ None \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Void \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Any -$$ - -### Literal Type - -$$ -Type \ Literal(Bool) \sqsubseteq Type \ Bool -$$ - -$$ -Type \ Literal(Int) \sqsubseteq Type \ Int -$$ - -$$ -Type \ Literal(Float) \sqsubseteq Type \ Float -$$ - -$$ -Type \ Literal(String) \sqsubseteq Type \ String -$$ - -### Union Type - -$$ -Type \ X \sqsubseteq Type \ Union(X, Y) -$$ - -### Introspect - -$$ -Type \ X \sqsubseteq Type \ X -$$ - -Example - -$$ -Type \ Bool \sqsubseteq Type \ Bool -$$ - -$$ -Type \ Int \sqsubseteq Type \ Int -$$ - -$$ -Type \ Float \sqsubseteq Type \ Float -$$ - -$$ -Type \ String \sqsubseteq Type \ String -$$ - -$$ -Type \ List \sqsubseteq Type \ List -$$ - -$$ -Type \ Dict \sqsubseteq Type \ Dict -$$ - -$$ -Type \ Struct \sqsubseteq Type \ Struct -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Nothing -$$ - -$$ -Type \ Any \sqsubseteq Type \ Any -$$ - -$$ -Type \ Union(Type Int, Type Bool) \sqsubseteq Type \ Union(Type Int, Type Bool) -$$ - -### Transmit - -$$ -Type \ X \sqsubseteq Type \ Z \ if \ Type \ X \sqsubseteq Type \ Y \ and \ Type \ Y \sqsubseteq \ Type \ Z -$$ - -### Contained - -$$ -Type \ List(T_1) \sqsubseteq Type \ List(T_2) \ if \ T_1 \sqsubseteq T_2 -$$ - -$$ -Type \ Dict(T_{k1}, T_{v1}) \sqsubseteq Type \ Dict(T_{k2}, T_{v2}) \ if \ T_{k1} \sqsubseteq T_{k2} \ and \ T_{v1} \sqsubseteq T_{v1} -$$ - -$$ -Type \ Structure(K_1: T_{a1}, K_2: T_{a2}, ..., K_n: T_{an}) \sqsubseteq Type \ Structure(K_1: T_{b1}, K_2: T_{b2}, ..., K_n: T_{bn}) \ if \ T_{a1} \sqsubseteq T_{b1} \ and \ T_{a2} \sqsubseteq T_{b2} \ and \ ... \ and \ T_{an} \sqsubseteq T_{bn} -$$ - -### Inheritance - -$$ -Type \ Struct \ A \sqsubseteq Type \ Struct \ B \ if \ A \ inherits \ B -$$ - -### None - -$$ -Type \ None \sqsubseteq Type \ X, X \notin \{Type \ Nothing, \ Type \ Void\} -$$ - -### Undefined - -$$ -Type \ Undefined \sqsubseteq Type \ X, X \notin \{Type \ Nothing, \ Type \ Void\} -$$ - -## Equality - -- Commutative law - -$$ -Type \ Union(X, Y) == Type \ Union(Y, X) -$$ - -Example - -$$ -Type \ Union(Int, Bool) == Type \ Union(Bool, Int) -$$ - -- Associative law - -$$ -Type \ Union(Union(X, Y), Z) == Type \ Union(X, Union(Y, Z)) -$$ - -Example - -$$ -Type \ Union(Union(Int, String), Bool) == Type \ Union(Int, Union(String, Bool)) -$$ - -- Idempotent - -$$ -Type \ Union(X, X) == Type \ X -$$ - -Example - -$$ -Type \ Union(Int, Int) == Type \ Int -$$ - -Partial order derivation - -$$ -Type \ Union(X, Y) == Type \ Y \ if \ X \sqsubseteq Y -$$ - -Example - -Assume that Struct A inherits Struct B - -$$ -Type \ Union(A, B) == Type \ B -$$ - -Idempotency is a special case of partial order reflexivity - -### List - -$$ -Type \ List(X) == Type \ List(Y) \ if \ X == Y -$$ - -### Dict - -$$ -Type \ Dict(T_k, T_v) == Type \ Dict(S_k, S_v) \ if \ T_k == S_k \ and \ T_v == S_v -$$ - -### Struct - -$$ -Type \ Struct(K_1: T_{1}, K_2: T_{2}, ..., K_n: T_{n}) == Type \ Struct(K_1: S_{1}, K_2: S_{2}, ..., K_n: S_{n}) \ if \ T_{1} == S_{1} \ and \ ... \ and \ T_{n} == S_{n} -$$ - -### Partial Order Checking - -$$ -Type \ X == Type \ Y \ if \ Type \ X \sqsubseteq Type \ Y \ and \ Type \ Y \sqsubseteq \ Type \ X -$$ - -## Basic Methods - -- `sup(t1: T, t2: T) -> T`: Calculate the minimum upper bound of two types `t1` and `t2` according to the type partial order. The union type needs to be created dynamically. -- `typeEqual(t1: T, t2: T) -> bool`: Compare whether the two types `t1` and `t2` are equal. -- `typeToString(t: T) -> string`: Resolve and convert the type to the corresponding string type recursively from top to bottom. - -### Sup Function - -- Type parameters, condition types and other characteristics are not considered temporarily. -- Use an ordered collection to store all types of `UnionType`. -- Use a global map to store all generated union types according to the name of `UnionType`. -- Calculate the inclusion relationship between types according to the partial order relationship. - -```go -// The Sup function returns the minimum supremum of all types in an array of types -func Sup(types: T[]) -> T { - typeOf(types, removeSubTypes=true) -} - -// Build a sup type from types [T1, T2, ... , Tn] -func typeOf(types: T[], removeSubTypes: bool = false) -> T { - assert isNotNullOrEmpty(types) - // 1. Initialize an ordered set to store the type array - typeSet: Set[T] = {} - // 2. Add the type array to the ordered set for sorting by the type id and de-duplication - addTypesToTypeSet(typeSet, types) - // 3. Remove sub types according to partial order relation rules e.g. sub schema types - if removeSubTypes { - removeSubTypes(typeSet) - } - if len(typeSet) == 1 { - // If the typeSet has only one type, return it - return typeSet[0] - } - // 4. Get or set the union type from the global union type map - id := getIdentifierFromTypeSet(typeSet) - unionType := globalUnionTypeMap.get(id) - if !unionType { - unionType = createUnionType(typeSet) // Build a new union type - globalUnionTypeMap.set(id, unionType) - } - return unionType -} - -// Add many types into the type set -func addTypesToTypeSet(typeSet: Set[T], types: T[]) -> void { - for type in types { - addTypeToTypeSet(typeSet, type) - } -} - -// Add one type into the type set -func addTypeToTypeSet(typeSet: Set[T], type: T) -> void { - if isUnion(type) { - return addTypesToTypeSet(typeSet, toUnionOf(type).types) - } - // Ignore the void type check - if !isVoid(type) { - // De-duplication according to the type of id - typeSet.add(type) - } -} - -func removeSubTypes(types: Set[T]) -> void { - for source in types { - for target in types { - if !typeEqual(source, target) { - // If the two types have an inheritance relationship, the base class is retained, or if the two types have a partial order relationship according to the relation table. - if (isPartialOrderRelatedTo(source, target)) { - types.remove(source) - } - } - } - } -} - -// isPartialOrderRelatedTo function Determine whether two types have a partial order relationship `source \sqsubseteq target` -// according to the partial order relationship table and rules -func isPartialOrderRelatedTo(source: T, target: T) -> bool { - assert isNotNullOrEmpty(source) - assert isNotNullOrEmpty(target) - if isNoneOrUndefined(source) and !isNothing(target) and !isVoid(target) { - return true - } - if isAny(target) { - return true - } - if typeEqual(source, target) { - return true - } - if isUnion(target) and source in target.types { - return true - } - // Literal Type - if (isStringLiteral(source) and isString(target)) or \ - (isBooleanLiteral(source) and isBool(target)) or \ - (isIntLiteral(source) and isInt(target)) or \ - (isFloatLiteral(source) and isFloat(target)) { - return true - } - if isInt(source) and isFloat(target) { - return true - } - if isList(source) and isList(target) { - return isPartialOrderRelatedTo(toListOf(source).eleType, toListOf(target).eleType - } - if isDict(source) and isDict(target) { - return isPartialOrderRelatedTo(toDictOf(source).keyType, toDictOf(target).keyType) and isPartialOrderRelatedTo(toDictOf(source).valueType, toDictOf(target).valueType) - } - if isStruct(source) and isStruct(target) { - if isTypeDerivedFrom(source, target) { - return true - } - // Empty Object - if len(target.keys) == 0 { - return true - } - if any([key Not in source.keys for key in target.keys]) { - return false - } - for key, sourceType in (source.keys, source.types) { - targetType = getKeyType(target, key) ? getKeyType(target, key) : anyTypeOf() - if !isPartialOrderRelatedTo(sourceType, targetType) { - return false - } - } - return true - } - return false -} -``` - -## Type Checking - -### Checker - -The type checker traverses the syntax tree from top to bottom through syntax-directed translation, and determines whether the program structure is a well-typed program according to context-sensitive training rules. - -The type checker depends on type rules, and the information of type environment $\Gamma$ is recorded in the symbol table. Use abstract syntax for type expressions, such as `listof (T)`. When the type check fails, a type mismatch error is generated, and the error message is generated according to the syntax context. - -### Basic Methods - -1. `isUpperBound(t1, t2): supUnify(t1, t2) == t2` -2. `supUnify(t1, t2):` - -- For the foundation type, `sup(t1, t2)` is calculated according to the partial order relationship -- For list, dict, Struct, recursively `supUnify` the types of elements -- When there is no partial order relationship, return `Nothing` - -### Checking Logic - -#### Operand Expr - -$D \to id: T$ - -``` -env.addtype(id.entry, T.type) -``` - -$T \to boolean$ - -``` -T.type = boolean -``` - -$T \to integer$ - -``` -T.type = integer -``` - -$T \to float$ - -``` -T.type = float -``` - -$T \to string$ - -``` -T.type = string -``` - -$T \to c, \ c \in \{boolean, integer, float, string\}$ - -``` -T.type = literalof(c) -``` - -$T \to None$ - -``` -T.type = None -``` - -$T \to Undefined$ - -``` -T.type = Undefined -``` - -$T \to \ [T_1]$ - -``` -T.type = listof (T1.type) -``` - -$T \to { \{T_1: T_2\} }$ - -``` -T.type = dictof (T1.type: T2.type) -``` - -$T \to { \{N_1: T_1, N2: T_2, ..., N_n: T_n\} }$ - -``` -T.type = structof (N1: T1.type, N2: T2.type, ..., Nn: Tn.type) -``` - -$E \to id$ - -``` -E.type = env.lookup(id.entry) -``` - -$E \to [E_1, E_2, ..., E_n]$ - -``` -func listExpr(E) { - supe = sup([e.type for e in E]]) - E.type = listof(type) -} -``` - -$E \to [E_1 \ for \ E_2 \ in \ E_3 \ if \ E_4]$ - -``` -func listComp(E) { - if !typeEqual(E4.type, boolean) { - raise type_error - } - if !isUpperBound(listof(Any), E3.type) { - raise type_error(E) - } - if !isUpperBound(E3.type, E2.type) { - raise type_error(E) - } - E.type = listof(E1.type) -} -``` - -$E \to \{E_{k1}: E_{v1}, ..., E_{kn}: E_{vn}\}$ - -``` -func dictExpr(E) { - supk := sup([e.type for e in E.keys()]]) - supv := sup([e.type for e in E.values()]]) - E.type = dictof(supk, supv) -} -``` - -$E \to \{E_1:E_2 \ for \ (E_3, E_4) \ in \ E_5 \ if \ E_6\}$ - -``` -func dictComp(E) { - if !typeEqual(E6.type, boolean) { - raise type_error(E) - } - if !isUpperBound(dictof(Any, Any), E5.type) { - raise type_error(E) - } - if !isUpperBound(E5.type, dictof(E3.type, E4.type)) { - raise type_error(E) - } - E.type = dictof(E1.type, E2.type) -} -``` - -$E \to \{E_{k1}: E_{v1}, ..., E_{kn}: E_{vn}\}$ - -``` -func dictExpr(E) { - supk := sup(Ek1, ..., Ekn) - supv = sup(Ev1, ..., Evn) - E.type = dictof(supk, supv) -} -``` - -$E \to \{N_{1} = E_{1}, ..., N_{{n}} = E_{n}\}$ - -``` -func structExpr(E) { - Struct = structof() - for n, e in E { - Struct.add(n, e.type) - } - E.type = Struct -} -``` - -#### Primary Expr - -$E \to E_1[E_2]$ - -``` -func sliceSuffix(E) { - if !isUpperBound(listof(Any), E.E1.type) { - raise type_error(E) - } - if typeEqual(E.E2.type, integer) { - raise type_error(E) - } - E.type = E.E1.type.eleType -} -``` - -$E \to E_1(E_2)$ - -``` -func callSuffix(E) { - if !typeEqual(E.E1.type, func) { - raise type_error(E) - } - if !isUpperBound(listof(E.E1.arguType), E.E2.type) { - raise type_error(E) - } - E.type = E.E1.returnType -} -``` - -#### Unary Expr - -According to the reasoning rules of each binocular operator, take `+` as an example. - -$E \to + E_1$ - -``` -func Plus(E) { - if !typeEqual(E.E1.type, [integer, float]) { - raise type_error(E) - } - E.type = E.E1.type -} -``` - -#### Binary Expr - -According to the reasoning rules of each binocular operator, take `%` as an example. - -$E \to E_1 \ % \ E_2$ - -``` -func Mod(E) { - if !(typeEqual(E.E1.type, [integer, float]) && typeEqual(E.E2.type, [integer, float])) { - raise type_error(E) - } - E.type = E.E1.type -} -``` - -#### IF Binary Expr - -$E \to if E_1 \ then \ E_2 else \ E_3$ - -``` -func ifExpr(E) { - if !typeEqual(E.type, boolean) { - raise type_error(E) - } - if !typeEqual(E_2.type, E_3.type) { - raise type_error(E) - } - E.type = E_2.type -} -``` - -#### Stmt - -$S \to if \ E \ then \ S_1 \ else \ S_2$ - -``` -func ifStmt(S) { - if !typeEqual(S.E.type, boolean) { - raise type_error(E) - } - if !typeEqual(S.S1.type, S.S2.type) { - raise type_error(E) - } - S.type = S.S1.type -} -``` - -$S \to id: T = E$ - -$S \to id = T E$ - -``` -func assignStmt(S) { - tpe := env.lookup(id.entry) - if tpe != nil && tpe != S.T { - raise type_error(E) - } - if isUpperBound(tpe, E.type) { - raise type_error(E) - } - env.addtype(id.entry, T.type) -} -``` - -## Type Conversion - -### Basic Definition - -Through syntax-directed translation, the value types involved in the operation are automatically converted according to the operator characteristics. - -### Conversion Rules - -$E \to E_1 \ op \ E_2, , op \in \{+, -, *, /, \%, **, //\}$ - -``` -func binOp(E) { - if E.E1.type == integer and E.E2.type == integer { - E.type = integer - } else if E.E1.type == integer and E.E2.type == float { - E.type = float - } else if E.E1.type == float and E.E2.type == integer { - E.type = float - } else if E.E1.type == float and E.E2.type == float { - E.type = float - } -} -``` - -## Type Inference - -### Basic Definition - -- Type rule derivation and type reconstruction in case of incomplete type information -- Derive and reconstruct the data structure types in the program from the bottom up, such as basic type, e.g., list, dict and struct types. - -### Basic Methods - -1. `typeOf(expr, subst)`: The input is the expression and substitution rule set, and the type of expr and the new substitution rule set are returned. -2. `unifier(t1, t2, subst, expr)`: Try substitution with `t1=t2`. If the substitution is successful (no occurrence and no conflict), add `t1=t2` to the subst and return the subst. Otherwise, an error has occurred or there is a conflict. - -### Inferential Logic - -$E \to id = E_1$ - -``` -func assignExpr(E, subst) { - return unifier(E.id.type, E.E_1.type, subst, E) -} -``` - -$unifier(t1, t2, subst, expr) \rightarrow subst$ - -``` -func unifier(t1, t2, subst, expr) { - t1 = applySubstToTypeEquation(t1, subst) - t2 = applySubstToTypeEquation(t2, subst) - - if t1 == t2 { - return subst - } - - if isTypeVar(t1) { - if isNoOccur(t1, t2) { - addTypeEquationToSubst(subst, t1, t2) - return subst - } else { - raise occurrence_violation_error(t1, t2, expr) - } - } - - if isTypeVar(t2) { - if isNoOccur(t2, t1) { - addTypeEquationToSubst(subst, t2, t1) - return subst - } else { - raise occurrence_violation_error(t2, t1, expr) - } - } - - if isList(t1) and isList(t2) { - return unifier(toListOf(t1).eleType, toListOf(t2).eleType, subst, expr) - } - if isDict(t1) and isDict(t2) { - dict1of := toDictOf(t1) - dict2of := toDictOf(t2) - subst = unifier(dict1of.keyType, dict2of.keyType, subst, expr) - subst = unifier(dict1of.valueType, dict2of.valueType, subst, expr) - return subst - } - if isStruct(t1) and isStruct(t2) { - Struct1of := tostructof(t1) - Struct2of := tostructof(t2) - for key, _ in Struct1of { - subst = unifier(t1[key].type, t2[key].type, subst, expr) - } - return subst - } - - raise unification_error(t1, t2, expr) -} - -func applySubstToTypeEquation(t, subst) { - // walks through the type t, replacing each type variable by its binding in the substitution -σ. If a variable is Not bound in the substitution, then it is left unchanged. - if isBasicType(t) { - return t - } - if isList(t) { - return listOf(applySubstToTypeEquation(toListOf(t).eleType, subst)) - } - if isDict(t) { - dictof := toDictOf(t) - kT := applySubstToTypeEquation(dictof.keyType, subst) - vT := applySubstToTypeEquation(dictof.valueType, subst) - return dictOf(kT, vT) - } - if isStruct(t) { - structof := tostructof(t) - s := structof() - for key, type in Struct1of { - kT := applySubstToTypeEquation(type, subst) - s.add(key, kT) - } - return s - } - if hasTypeVar(t) { - for tvar in t.vars { - if tvar in subst { - *tvar = subst[tvar] - } - } - } - return t -} - -func addTypeEquationToSubst(subst, tvar, t) { - // takes the substitution σ and adds the equation tv = t to it - for _, t in subst { - for tvar in t.vars { - tmp := applyOneSubst(tsvar, tvar, t) - *tvar = tmp - } - } - subst.add(tvar, t) -} - -func applyOneSubst(t0, tvar, t1) { - // substituting t1 for every occurrence of tv in t0. - if isBasicType(t0) { - return t0 - } - if isList(t0) { - return listOf(applyOneSubst(toListOf(t).eleType, tvar, t1)) - } - if isDict(t0) { - dictof := toDictOf(t) - kT := applyOneSubst(dictof.keyType, tvar, t1) - vT := applyOneSubst(dictof.valueType, tvar, t1) - return dictOf(kT, vT) - } - if isStruct(t0) { - structof := tostructof(t) - s := structof() - for key, type in Struct1of { - kT := applyOneSubst(type, tvar, t1) - s.add(key, kT) - } - return s - } - if t0 == tvar { - return t1 - } - return t0 -} - -func isNoOccur(tvar, t) { - // No variable bound in the substitution occurs in any of the right-hand sides of the substitution. - if isBasicType(t) { - return true - } - if isList(t) { - return isNoOccur(tvar, toListOf(t).eleType) - } - if isDict(t) { - dictof := toDictOf(t) - return isNoOccur(tvar, dictof.keyType) and isNoOccur(tvar, dictof.valueType) - } - if isStruct(t) { - structof := tostructof(t) - noOccur := true - for _, type in structof { - noOccur = noOccur and isNoOccur(tvar, type) - } - return noOccur - } - return tvar != t -} -``` - -### Example - -#### Normal Inference - -``` -T : { - a = 1 - b = "2" - c = a * 2 - d = { - d0 = [a, c] - } -} - -x: T = { - a = 10 -} -``` - -#### Occurrence Violation Error - -``` -T = { - a = a -} -``` - -#### Type Unification Error - -``` -T : { - a = 1 -} - -T : { - a = "1" -} -``` - -## Reference - -- [https://en.wikipedia.org/wiki/Type_system](https://en.wikipedia.org/wiki/Type_system) -- Pierce, Benjamin C. (2002). Types and Programming Languages. MIT Press. -- [https://www.cs.cornell.edu/courses/cs4110/2010fa/](https://www.cs.cornell.edu/courses/cs4110/2010fa/) -- [https://www.typescriptlang.org/docs/handbook/basic-types.html](https://www.typescriptlang.org/docs/handbook/basic-types.html) -- [https://www.typescriptlang.org/docs/handbook/advanced-types.html](https://www.typescriptlang.org/docs/handbook/advanced-types.html) diff --git a/versioned_docs/version-0.5.6/reference/model/_category_.json b/versioned_docs/version-0.5.6/reference/model/_category_.json deleted file mode 100644 index 398617be..00000000 --- a/versioned_docs/version-0.5.6/reference/model/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "System Package", - "position": 2 -} diff --git a/versioned_docs/version-0.5.6/reference/model/base64.md b/versioned_docs/version-0.5.6/reference/model/base64.md deleted file mode 100644 index 3f6e617b..00000000 --- a/versioned_docs/version-0.5.6/reference/model/base64.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: "base64" -linkTitle: "base64" -type: "docs" -description: base64 system module - base64 encode and decode function -weight: 100 ---- - -## encode - -`encode(value: str, encoding: str = "utf-8") -> str` - -Encode the string `value` using the codec registered for encoding. - -## decode - -`decode(value: str, encoding: str = "utf-8") -> str` - -Decode the string `value` using the codec registered for encoding. diff --git a/versioned_docs/version-0.5.6/reference/model/builtin.md b/versioned_docs/version-0.5.6/reference/model/builtin.md deleted file mode 100644 index 4bb34766..00000000 --- a/versioned_docs/version-0.5.6/reference/model/builtin.md +++ /dev/null @@ -1,386 +0,0 @@ ---- -title: "builtin" -sidebar_position: 1 ---- - -KCL provides a list of built-in functions that are automatically loaded and can be used directly without providing any module name. For example, `print` is a function provided by a widely used built-in module. - -## Type Conversion Functions - -KCL's `bool`, `int`, `float`, `str`, `list`, `dict` and other types have built-in conversion functions of the same name. Among them, `int` can not only be used to truncate floating-point numbers, but also can be used to convert strings to integers (decimal when parsing, other values can also be specified). - -The following are common uses of type-related functions: - -```py -b1 = bool(1) # true -b2 = bool(1.5) # true -b3 = bool("true") # true -b4 = bool("") # false -b5 = bool([]) # false -b6 = bool({}) # false - -i1 = int("11") # 11 -i2 = int("11", base=8) # 9 -i3 = int("11", base=2) # 3 - -f1 = float(1) # 1.0 -f2 = float("1.5") # 1.5 - -s1 = str(1) # 1 - -l1 = list([1, 2, 3]) -``` - -## String Builtin Member Functions - -- [String Spec](/docs/reference/lang/spec/datatypes) - -## print - -`print(*args:any, end:str='\n')` - -The built-in print function, which provides different types of variable parameter printing, adds a newline at the end by default. The following are common usages: - -```python -print("hello KCL") -print() -print(None, end=':') -print(None) -print(True) -print(False) -print(123) -print(123.0) -print('abc ${123}') -print("abc ${456}") -print([1,'a', True]) -print(1,'a', True) -print({}) -print({a: 123}) -``` - -The output is: - -```shell -hello KCL - -None:None -True -False -123 -123.0 -abc 123 -abc 456 -[1, 'a', True] -1 a True -{} -{'a': 123} -``` - -If you do not want the default newline, you can re-specify the ending string with the `end=''` named parameter. - -```python -print("Hello KCL", end='') -``` - -## multiplyof - -`multiplyof(a:int, b:int) -> bool` - -Check whether the integer `a` is an integer multiple of `b`, and return a boolean value: - -```python -print(multiplyof(2, 1)) # True -print(multiplyof(1, 2)) # False -print(multiplyof(0, 1)) # True -print(multiplyof(0, 2)) # True -print(multiplyof(1, 0)) # Error -``` - -`0` is a multiple of any number. But `b` cannot be `0`, otherwise an exception will be thrown. - -## isunique - -`isunique(list: [any]) -> bool` - -Check if there are duplicate elements in an array, and return a boolean value: - -```python -print(isunique([])) # True -print(isunique([1])) # True -print(isunique([1, 2])) # True - -print(isunique([1, 1])) # False -print(isunique([1, 1.0])) # False -print(isunique([1.1, 1.1])) # False - -print(isunique(['abc', "abc"])) # False -print(isunique(['abc', "a${'bc'}"])) # False -``` - -It should be noted that integers and floating-point numbers ignore the type difference and judge whether the values are equal. - -## len - -`len(x: str | [any] | {:}) -> int` - -Return the length of strings, lists, and arrays: - -```python -print(len([])) # 0 -print(len({})) # 0 - -print(len([1])) # 1 -print(len({abc:123})) # 1 - -print("abc") # 3 -``` - -Note: Calculating lengths on `schema` objects is not supported. - -## abs - -`abs(x: number) -> number` - -Calculate the absolute value of `x`. - -## all_true - -`all_true(x:str|[]|{:}) -> bool` - -Judging that all elements of a list or dictionary class are true, the usage is as follows: - -```python -print(all_true([])) # True -print(all_true({})) # True - -print(all_true([True])) # True -print(all_true([1])) # True - -print(all_true([True, False])) # False -print(all_true([True, None])) # False -``` - -Returns true when the list is empty. - -## any_true - -`any_true(x:str|[]|{:}) -> bool` - -Judging that at least one element in the iterable object is true, the usage is as follows: - -```python -print(any_true([])) # False -print(any_true([1])) # True -``` - -## bin - -`bin(x:number) -> str` - -A string that returns the binary representation of an integer, used as follows: - -```python -print(bin(8)) # 0b1000 -``` - -## hex - -`hex(number)` - -A string that returns the hexadecimal representation of an integer, used as follows: - -```python -print(hex(18)) # 0x12 -``` - -## oct - -`oct(number)` - -A string that returns the octal representation of an integer, used as follows: - -```python -print(oct(10)) # 0o12 -``` - -## option - -`option(key:str, type:str='', required=False, default=None, help="") -> any` - -Gets the value of the command line top level argument input. - -## ord - -`ord(c) -> int` - -Get the Unicode code point value of the character, the usage is as follows: - -```python -print(ord('A')) # 65 -print(ord('B')) # 66 -print(ord('C')) # 67 -``` - -## sorted - -`sorted(x: []) -> []` - -Returns the sorted list, used as follows: - -```python -_a = [] -_b = [2, 1] - -_c = sorted(_a) -_d = sorted(_b) - -print(_a) # [] -print(_b) # [2, 1] -print(_c) # [] -print(_d) # [1, 2] -``` - -## range - -`range(start:int, end:int, step=1) -> [int]` - -Generates an iterable list, used as follows: - -```python -print(range(1,5)) # [1, 2, 3, 4] -print(range(1,5, 2)) # [1, 3] -print(range(5, 1, -1)) # [5, 4, 3, 2] -``` - -## min - -`min(x:[number]) -> number` - -Returns the smallest element in the list, used as follows: - -```python -print(min([1,2])) # 1 -print(min([2,1])) # 1 -``` - -## max - -`max(x:[number]) -> number` - -Returns the largest element in the list, used as follows: - -```python -print(max([1,2])) # 2 -print(max([2,1])) # 2 -``` - -## sum - -`sum(x:[number], init_value=0) -> number` - -Returns the sum of all elements in the list, used as follows: - -``` -print(sum([1,2])) # 3 -print(sum([2,1], 1000)) # 1003 -``` - -## pow - -`pow(x: number, y: number, z: number = None) -> number` - -Computes `x**y`, or `(x**y)%z` if `z` is not empty, supports integer and floating point numbers, used as follows: - -```python -print(pow(2,3)) # 8 -print(pow(2, 3, 5)) # 8%5 == 3 - -print(pow(2, 0.5)) # 1.414 -``` - -## round - -`round(number: int|float, ndigits:int|None) -> float | int` - -Returns the rounded approximation of `number`. If `ndigits` is not `None` returns a float with the specified number of decimal places (cannot be negative), otherwise returns an integer structure, used as follows: - -```python -print(round(1)) # 1 -print(round(1.4)) # 1 -print(round(1.5)) # 2 - -print(round(1.5555, 1)) # 1.6 -print(round(1.5555, 2)) # 1.56 - -print(round(1.5555)) # 2 -print(round(1.5555, 0)) # 2.0 -``` - -It should be noted that the difference between `ndigits` being `None` and `0` is that the prefix returns `int` type, the latter returns `float` type. - -## typeof - -`typeof(x: any, full_name: bool = False) -> str` - -Output the type of `x` at runtime. When the `full_name` parameter is set to `True`, the package prefix of the form `pkg.schema` will be returned, used as follows: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person{} -t3 = typeof(_x1) - -_x2 = pkg.Person{} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# Output -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -## zip - -`zip(*args: str|list|dict)` - -It is used to take an iterable object as a parameter, pack the corresponding elements in the object into tuples, and then return a list composed of these tuples, used as follows: - -```py -a = zip([0, 1, 2], [3, 4, 5]) -b = zip([0, 1], [3, 4, 5]) -c = zip([0, 1, 2], [3, 4, 5, 6]) - -# Output -# a: -# - - 0 -# - 3 -# - - 1 -# - 4 -# - - 2 -# - 5 -# b: -# - - 0 -# - 3 -# - - 1 -# - 4 -# c: -# - - 0 -# - 3 -# - - 1 -# - 4 -# - - 2 -``` diff --git a/versioned_docs/version-0.5.6/reference/model/crypto.md b/versioned_docs/version-0.5.6/reference/model/crypto.md deleted file mode 100644 index 7fab7e50..00000000 --- a/versioned_docs/version-0.5.6/reference/model/crypto.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "crypto" -linkTitle: "crypto" -type: "docs" -description: crypto system module -weight: 100 ---- - -## md5 - -`md5(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `MD5` and the codec registered for encoding. - -## sha1 - -`sha1(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA1` and the codec registered for encoding. - -## sha224 - -`sha224(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA224` and the codec registered for encoding. - -## sha256 - -`sha256(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA256` and the codec registered for encoding. - -## sha384 - -`sha384(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA384` and the codec registered for encoding. - -## sha512 - -`sha512(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA512` and the codec registered for encoding. diff --git a/versioned_docs/version-0.5.6/reference/model/index.md b/versioned_docs/version-0.5.6/reference/model/index.md deleted file mode 100644 index 163e8db3..00000000 --- a/versioned_docs/version-0.5.6/reference/model/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# System Package - -KCL provides engineering extensibility through system modules, user modules and plug-in modules. This section describes the basic concepts of system modules. diff --git a/versioned_docs/version-0.5.6/reference/model/manifests.md b/versioned_docs/version-0.5.6/reference/model/manifests.md deleted file mode 100644 index ab31ad47..00000000 --- a/versioned_docs/version-0.5.6/reference/model/manifests.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: "manifests" -linkTitle: "manifests" -type: "docs" -description: manifests system module -weight: 100 ---- - -## yaml_stream - -```python -yaml_stream(values: [any], opts: {str:} = { - sort_keys = False - ignore_private = True - ignore_none = False - sep = "---" -}) -``` - -This function is used to serialize the KCL object list into YAML output with the --- separator. It has two parameters: - -- `values` - A list of KCL objects -- `opts` - The YAML serialization options - - `sort_keys`: Whether to sort the serialized results in the dictionary order of attribute names (the default is `False`). - - `ignore_private`: Whether to ignore the attribute output whose name starts with the character `_` (the default value is `True`). - - `ignore_none`: Whether to ignore the attribute with the value of' None '(the default value is `False`). - - `sep`: Set the separator between multiple YAML documents (the default value is `"---"`). - -Here's an example: - -```python -# Use the `import` keyword to import the `manifests` module. -import manifests - -# The schema `Deployment` definition. -schema Deployment: - apiVersion: str = "v1" - kind: str = "Deployment" - metadata: {str:} = { - name = "deploy" - } - spec: {str:} = { - replica = 2 - } - -# The schema `Service` definition. -schema Service: - apiVersion: str = "v1" - kind: str = "Service" - metadata: {str:} = { - name = "svc" - } - spec: {str:} = {} - -# Define two `Deployment` resources. -deployments = [Deployment {}, Deployment {}] -# Define two `Service` resources. -services = [Service {}, Service {}] -# Put them into a KCL list and call the `manifests.yaml_stream` function. -manifests.yaml_stream(deployments + services) -``` - -First, we use the `import` keyword to import the `manifests` module and define two deployment resources and two service resources. When we want to output these four resources in YAML stream format with `---` as the separator, we can put them into a KCL list and use the `manifests.yaml_stream` function pass it to the `values` parameter (if there is no special requirement, the `opts` parameter can generally use the default value). Finally, the YAML output is: - -```yaml -apiVersion: v1 -kind: Deployment -metadata: - name: deploy -spec: - replica: 2 ---- -apiVersion: v1 -kind: Deployment -metadata: - name: deploy -spec: - replica: 2 ---- -apiVersion: v1 -kind: Service -metadata: - name: svc ---- -apiVersion: v1 -kind: Service -metadata: - name: svc -``` diff --git a/versioned_docs/version-0.5.6/reference/model/net.md b/versioned_docs/version-0.5.6/reference/model/net.md deleted file mode 100644 index a4e83659..00000000 --- a/versioned_docs/version-0.5.6/reference/model/net.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: "net" -linkTitle: "net" -type: "docs" -description: net system module -weight: 100 ---- - -## split_host_port - -`split_host_port(ip_end_point: str) -> List[str]` - -Split the `host` and `port` from the `ip_end_point`. - -## join_host_port - -`join_host_port(host, port) -> str` - -Merge the `host` and `port`. - -## fqdn - -`fqdn(name: str = '') -> str` - -Return Fully Qualified Domain Name (FQDN). - -## parse_IP - -`parse_IP(ip) -> str` - -Parse `ip` to a real IP address - -## to_IP4 - -`to_IP4(ip) -> str` - -Get the IP4 form of `ip`. - -## to_IP16 - -`to_IP16(ip) -> int` - -Get the IP16 form of `ip`. - -## IP_string - -`IP_string(ip: str | int) -> str` - -Get the IP string. - -## is_IPv4 - -`is_IPv4(ip: str) -> bool` - -Whether `ip` is a IPv4 one. - -## is_IP - -`is_IP(ip: str) -> bool` - -Whether `ip` is a valid ip address. - -## is_loopback_IP - -`is_loopback_IP(ip: str) -> bool` - -Whether `ip` is a loopback one. - -## is_multicast_IP - -`is_multicast_IP(ip: str) -> bool` - -Whether `ip` is a multicast one. - -## is_interface_local_multicast_IP - -`is_interface_local_multicast_IP(ip: str) -> bool` - -Whether `ip` is a interface, local and multicast one. - -## is_link_local_multicast_IP - -`is_link_local_multicast_IP(ip: str) -> bool` - -Whether `ip` is a link local and multicast one. - -## is_link_local_unicast_IP - -`is_link_local_unicast_IP(ip: str) -> bool` - -Whether `ip` is a link local and unicast one. - -## is_global_unicast_IP - -`is_global_unicast_IP(ip: str) -> bool` - -Whether `ip` is a global and unicast one. - -## is_unspecified_IP - -`is_unspecified_IP(ip: str) -> bool` - -Whether `ip` is a unspecified one. diff --git a/versioned_docs/version-0.5.6/reference/model/overview.md b/versioned_docs/version-0.5.6/reference/model/overview.md deleted file mode 100644 index 36365ac1..00000000 --- a/versioned_docs/version-0.5.6/reference/model/overview.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -sidebar_position: 0 ---- - -# Overview - -KCL provides engineering extensibility through built-in modules, system modules and plug-in modules. - -![](/img/docs/reference/lang/model/kcl-module.png) - -The user code does not need to import functions that directly use builtin functions (such as calculating the length of a list with `len`, obtaining the type of value through `typeof`, etc.), and for basic types such as strings, it also provides some built-in methods (such as converting the case of strings, etc.). - -For relatively complex general logic, it is provided through the system modules. For example, by importing the `math` module, we can use related mathematical functions, and we can use the regular expression by importing the `regex` module. For KCL code, it can also be organized into different user modules. - -In addition, Python and Go can be used to develop plug-ins for KCL through the plugin mechanism. For example, there are the app-context plug-in can be used to obtain the context information of the current application to simplify code writing. diff --git a/versioned_docs/version-0.5.6/reference/model/regex.md b/versioned_docs/version-0.5.6/reference/model/regex.md deleted file mode 100644 index adde0630..00000000 --- a/versioned_docs/version-0.5.6/reference/model/regex.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "regex" -linkTitle: "regex" -type: "docs" -description: regex system module -weight: 100 ---- - -## replace - -`replace(string: str, pattern: str, replace: str, count=0) -> str` - -Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement. - -## match - -`match(string: str, pattern: str) -> bool` - -Try to apply the pattern at the start of the string, returning a bool value `True` if any match was found, or `False` if no match was found. - -## compile - -`compile(pattern: str) -> bool` - -Compile a regular expression pattern, returning a bool value denoting whether the pattern is valid. - -## findall - -`findall(string: str, pattern: str) -> List[str]` - -Return a list of all non-overlapping matches in the string. - -## search - -`search(string: str, pattern: str) -> bool` - -Scan through string looking for a match to the pattern, returning a bool value `True` if any match was found, or `False` if no match was found. - -## split - -`split(string: str, pattern: str, maxsplit=0) -> List[str]` - -Return a list composed of words from the string, splitting up to a maximum of `maxsplit` times using `pattern` as the separator. diff --git a/versioned_docs/version-0.5.6/reference/model/units.md b/versioned_docs/version-0.5.6/reference/model/units.md deleted file mode 100644 index 34465a53..00000000 --- a/versioned_docs/version-0.5.6/reference/model/units.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: "units" -linkTitle: "units" -type: "docs" -description: units system module - Unit handlers -weight: 100 ---- - -## Constants - -- Fixed point unit constants: `n`, `u`, `m`, `k`, `K`, `G`, `T` and `P`. -- Power of 2 unit constants: `Ki`, `Mi`, `Gi`, `Ti` and `Pi`. - -## Functions - -- `to_n(num: int) -> str` - Int literal to string with `n` suffix -- `to_u(num: int) -> str` - Int literal to string with `u` suffix -- `to_m(num: int) -> str` - Int literal to string with `m` suffix -- `to_K(num: int) -> str` - Int literal to string with `K` suffix -- `to_M(num: int) -> str` - Int literal to string with `M` suffix -- `to_G(num: int) -> str` - Int literal to string with `G` suffix -- `to_T(num: int) -> str` - Int literal to string with `T` suffix -- `to_P(num: int) -> str` - Int literal to string with `P` suffix -- `to_Ki(num: int) -> str` - Int literal to string with `Ki` suffix -- `to_Mi(num: int) -> str` - Int literal to string with `Mi` suffix -- `to_Gi(num: int) -> str` - Int literal to string with `Gi` suffix -- `to_Ti(num: int) -> str` - Int literal to string with `Ti` suffix -- `to_Pi(num: int) -> str` - Int literal to string with `Pi` suffix diff --git a/versioned_docs/version-0.5.6/reference/model/yaml.md b/versioned_docs/version-0.5.6/reference/model/yaml.md deleted file mode 100644 index 4b952dcf..00000000 --- a/versioned_docs/version-0.5.6/reference/model/yaml.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: "yaml" -linkTitle: "yaml" -type: "docs" -description: yaml encode and decode function -weight: 300 ---- - -## encode - -``` -encode( - data: any, - sort_keys: bool = False, - ignore_private: bool = False, - ignore_none: bool = False -) -> str -``` - -Serialize a KCL object `data` to a YAML formatted str. - -## decode - -`decode(value: str) -> any` - -Deserialize `value` (a string instance containing a YAML document) to a KCL object. - -## dump_to_file - -``` -dump_to_file( - data: any, - filename: str, - ignore_private: bool = False, - ignore_none: bool = False -) -> None -``` - -Serialize a KCL object `data` to a YAML formatted str and write it into the file `filename`. diff --git a/versioned_docs/version-0.5.6/reference/package-management/_category_.json b/versioned_docs/version-0.5.6/reference/package-management/_category_.json deleted file mode 100644 index 7848e437..00000000 --- a/versioned_docs/version-0.5.6/reference/package-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Package Management Tools", - "position": 4 -} diff --git a/versioned_docs/version-0.5.6/reference/package-management/command-reference/1.init.md b/versioned_docs/version-0.5.6/reference/package-management/command-reference/1.init.md deleted file mode 100644 index 6a46976a..00000000 --- a/versioned_docs/version-0.5.6/reference/package-management/command-reference/1.init.md +++ /dev/null @@ -1,45 +0,0 @@ -# kpm init - -Init a kcl package. - -## Usage - -```shell -kpm init [options][package_name] -``` - -## Description - -`kpm init` will initialize a kcl package in the current directory. If the package name is not provided, the name of the current directory will be used. - -If the package name is provided, a subdirectory with the name of the package will be created and the package will be initialized in that directory. - -`kpm init` will create `kcl.mod`, `kcl.mod.lock` and `main.k` under the package directory. - -## Options - -### --help, -h - -Show help for `kpm init` command. - -## Examples - -### Init the current directory into a kcl package - -```shell -# create an empty directory -$ mkdir my_package - -# cd into the directory -$ cd my_package - -# init the current directory into a kcl package -$ kpm init -``` - -### Init a kcl package with a name - -```shell -# init a kcl package with a name 'my_package' -kpm init my_package -``` diff --git a/versioned_docs/version-0.5.6/reference/package-management/command-reference/10.help.md b/versioned_docs/version-0.5.6/reference/package-management/command-reference/10.help.md deleted file mode 100644 index 94c078f5..00000000 --- a/versioned_docs/version-0.5.6/reference/package-management/command-reference/10.help.md +++ /dev/null @@ -1,21 +0,0 @@ -# kpm help - -Print help information for kpm commands. - -## Usage - -```shell -kpm help -``` - -## Description - -`kpm help` will print help information for kpm commands. - -## Examples - -Use `kpm help` to print help information for kpm commands. - -```shell -kpm help -``` diff --git a/versioned_docs/version-0.5.6/reference/package-management/command-reference/2.add.md b/versioned_docs/version-0.5.6/reference/package-management/command-reference/2.add.md deleted file mode 100644 index 1d2517fb..00000000 --- a/versioned_docs/version-0.5.6/reference/package-management/command-reference/2.add.md +++ /dev/null @@ -1,53 +0,0 @@ -# kpm add - -Add a dependency to a kcl package. - -## Usage - -```shell -kpm add [options][package_reference] -``` - -## Description - -`kpm add` will add a dependency to a kcl package. The dependency can be from a git repository, or a kcl registry. - -`package_reference` is a kcl package reference, looks like `package_name:version`. - -## options - -### --git - -Specify the git url of the dependency from a git repository. - -### --tag - -Specify the tag of the dependency from a git repository. - -### --help, -h - -Show help for `kpm add` command. - -## Examples - -### Add a dependency from kcl registry - -Add kcl dependency named `k8s` to the current package.The version of the dependency will be the latest version. - -```shell -kpm add k8s -``` - -Add kcl dependency named 'k8s' with version 'v1.27.2'. - -```shell -kpm add k8s:v1.27.2 -``` - -### Add a dependency from git repository - -Add kcl dependency named `konfig` with version `v0.1.0` from git repository. - -```shell -kpm add --git https://github.com/awesome-kusion/konfig.git --tag v0.1.0 -``` diff --git a/versioned_docs/version-0.5.6/reference/package-management/command-reference/3.pkg.md b/versioned_docs/version-0.5.6/reference/package-management/command-reference/3.pkg.md deleted file mode 100644 index 9b4298a5..00000000 --- a/versioned_docs/version-0.5.6/reference/package-management/command-reference/3.pkg.md +++ /dev/null @@ -1,33 +0,0 @@ -# kpm pkg - -Package a kcl package into `*.tar`. - -## Usage - -```shell -kpm pkg [options] -``` - -## Description - -`kpm pkg` will package a kcl package into `*.tar`. - -Option `--target` is required to specify the tar file path of the package. - -## options - -### --target - -Specify the tar file path of the package. - -### --help, -h - -Show help for `kpm pkm` command. - -## Examples - -### Package a kcl package - -```shell -kpm pkg --target /Users/my_package_tar -``` diff --git a/versioned_docs/version-0.5.6/reference/package-management/command-reference/4.metadata.md b/versioned_docs/version-0.5.6/reference/package-management/command-reference/4.metadata.md deleted file mode 100644 index 3074a8d5..00000000 --- a/versioned_docs/version-0.5.6/reference/package-management/command-reference/4.metadata.md +++ /dev/null @@ -1,41 +0,0 @@ -# kpm metadata - -Print the metadata of a kcl package. - -## Usage - -```shell -kpm metadata [options] -``` - -## Description - -`kpm metadata` will print the metadata of a kcl package. The metadata includes the dependency information of the package. - -`--update` option is used to automatically download the missing dependency packages. - -## options - -### --update - -Automatically download the missing dependency packages. - -### --help, -h - -Show help for `kpm metadata` command. - -## Examples - -### Print the metadata of a kcl package - -Print the metadata of a kcl package. - -```shell -kpm metadata -``` - -Print the metadata of a kcl package and automatically download the missing dependency packages. - -```shell -kpm metadata --update -``` diff --git a/versioned_docs/version-0.5.6/reference/package-management/command-reference/5.run.md b/versioned_docs/version-0.5.6/reference/package-management/command-reference/5.run.md deleted file mode 100644 index b5001185..00000000 --- a/versioned_docs/version-0.5.6/reference/package-management/command-reference/5.run.md +++ /dev/null @@ -1,69 +0,0 @@ -# kpm run - -Compile a kcl package. - -## Usage - -```shell -kpm run [options][package_source] -``` - -## Description - -`kpm run` will compile a kcl package. - -## options - -### --input - -Specify the entry file path of the package. - -### --tag - -Specify the tag of the package specified by oci url `package_source`. - -### --vendor - -`--vendor` will move the dependency packages into the current packages and automatically download the missing dependency packages. - -### --kcl_args - -`--kcl_args` specifies the arguments passed to the kcl compiler. - -### --help, -h - -Show help for `kpm run` command. - -## Examples - -### compile the current kcl package - -Under the kcl package directory, `kpm run` can be used to compile the current kcl package. - -```shell -kpm run -``` - -### compile a kcl package tar file - -`kpm run` can be used to compile a kcl package tar file. - -```shell -kpm run /Users/demo/my_package.tar -``` - -### compile a kcl package from oci url - -`kpm run` can be used to compile a kcl package from oci url. - -```shell -kpm run --tag 0.0.1 oci://localhost:5001/test/my_package -``` - -### compile a kcl package from oci ref - -`kpm run` can be used to compile a kcl package from oci ref. - -```shell -kpm run test/my_package:0.0.1 -``` diff --git a/versioned_docs/version-0.5.6/reference/package-management/command-reference/6.login.md b/versioned_docs/version-0.5.6/reference/package-management/command-reference/6.login.md deleted file mode 100644 index 68ca0f1b..00000000 --- a/versioned_docs/version-0.5.6/reference/package-management/command-reference/6.login.md +++ /dev/null @@ -1,68 +0,0 @@ -# kpm login - -Login to the kpm registry. - -## Usage - -```shell -kpm login [options][kpm_registry] -``` - -## Description - -`kpm login` will login the kpm registry. - -## options - -### --username - -Specify the username of the kpm registry. - -### --password - -Specify the password of the kpm registry. - -### --help, -h - -Show help for `kpm login` command. - -## Examples - -### login to a registry with account and password - -```shell -kpm login -u -p -``` - -The output is - -```shell -Login succeeded -``` - -### login to a registry with account, and enter the password interactively - -```shell -kpm login -u -``` - -The output is - -```shell -Password: -Login succeeded -``` - -### login to a registry, and enter the account and password interactively - -```shell -kpm login -``` - -The output is - -```shell -Username: -Password: -Login succeeded -``` diff --git a/versioned_docs/version-0.5.6/reference/package-management/command-reference/7.logout.md b/versioned_docs/version-0.5.6/reference/package-management/command-reference/7.logout.md deleted file mode 100644 index 6c5d9aec..00000000 --- a/versioned_docs/version-0.5.6/reference/package-management/command-reference/7.logout.md +++ /dev/null @@ -1,27 +0,0 @@ -# kpm logout - -Logout from the kpm registry. - -## Usage - -```shell -kpm logout [options][kpm_registry] -``` - -## Description - -`kpm logout` will logout from the kpm registry. - -## options - -### --help, -h - -Show help for `kpm logout` command. - -## Examples - -### logout from oci registry - -```shell -kpm logout -``` diff --git a/versioned_docs/version-0.5.6/reference/package-management/command-reference/8.push.md b/versioned_docs/version-0.5.6/reference/package-management/command-reference/8.push.md deleted file mode 100644 index a70c5bc1..00000000 --- a/versioned_docs/version-0.5.6/reference/package-management/command-reference/8.push.md +++ /dev/null @@ -1,46 +0,0 @@ -# kpm push - -Push a package to the kpm registry. - -## Usage - -```shell -kpm push [options][kpm_registry] -``` - -## Description - -`kpm push` will push a package to the kpm registry. - -## options - -### --tar_path - -The path to the tar file to push. - -### --help, -h - -Show help for `kpm push` command. - -## Examples - -### push the current package - -You can use `kpm push` under the kcl package root directory to upload a kcl package to an OCI-based registry. - -```shell -# create a new kcl package. -$ kpm init -# enter the kcl package root directory -$ cd -# push it to an oci registry -$ kpm push -``` - -### push a tar to the registry - -You can also use `kpm push` to upload a tar file to an OCI-based registry. - -```shell -kpm push --tar_path -``` diff --git a/versioned_docs/version-0.5.6/reference/package-management/command-reference/9.pull.md b/versioned_docs/version-0.5.6/reference/package-management/command-reference/9.pull.md deleted file mode 100644 index b0126bcf..00000000 --- a/versioned_docs/version-0.5.6/reference/package-management/command-reference/9.pull.md +++ /dev/null @@ -1,42 +0,0 @@ -# kpm pull - -Pull a package from the kpm registry. - -## Usage - -```shell -kpm pull [options][package_source] -``` - -## Description - -`kpm pull` will pull a package from the kpm registry. - -## options - -### --tag - -The tag of the package to pull. - -### --help, -h - -Show help for `kpm push` command. - -## Examples - -### pull the package by package name - -You can use `kpm pull` to download a kcl package from the default OCI registry by kcl package name. -`kpm` will download the kcl package from the default OCI registry specified in the configuration file `kpm.json`. - -```shell -kpm pull : -``` - -### pull the package by oci url - -You can download a kcl package from an OCI-based registry url. - -```shell -kpm pull --tag -``` diff --git a/versioned_docs/version-0.5.6/reference/package-management/command-reference/_category_.json b/versioned_docs/version-0.5.6/reference/package-management/command-reference/_category_.json deleted file mode 100644 index 8c705ed9..00000000 --- a/versioned_docs/version-0.5.6/reference/package-management/command-reference/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Command Reference", - "position": 4 -} diff --git a/versioned_docs/version-0.5.6/reference/package-management/command-reference/index.md b/versioned_docs/version-0.5.6/reference/package-management/command-reference/index.md deleted file mode 100644 index ab6cc90c..00000000 --- a/versioned_docs/version-0.5.6/reference/package-management/command-reference/index.md +++ /dev/null @@ -1,36 +0,0 @@ -# kpm - -The kpm cli - -## Usage - -```shell -kpm [arguments]... -``` - -## Description - -`kpm` is a kcl package manager. It is used to install, remove, and update kcl packages. - -## Options - -### --help, -h - -Show help for kpm command - -### --version, -v - -Print the version of kpm - -## Subcommands - -- [kpm init](./1.init.md) - Init a kcl package -- [kpm add](./2.add.md) - Add a dependency to a kcl package -- [kpm pkg](./3.pkg.md) - Package a kcl package into `\*.tar`` -- [kpm metadata](./4.metadata.md) - Print the metadata of a kcl package -- [kpm run](./5.run.md) - Compile a kcl package into yaml -- [kpm login](./6.login.md) - Login to a kcl registry -- [kpm logout](./7.logout.md) - Logout from a kcl registry -- [kpm push](./8.push.md) - Push a kcl package to a registry -- [kpm pull](./9.pull.md) - Pull a kcl package from a registry -- [kpm help](./10.help.md) - print help for kpm command diff --git a/versioned_docs/version-0.5.6/reference/plugin/_category_.json b/versioned_docs/version-0.5.6/reference/plugin/_category_.json deleted file mode 100644 index e77dfb1c..00000000 --- a/versioned_docs/version-0.5.6/reference/plugin/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Plugin System", - "position": 4 -} diff --git a/versioned_docs/version-0.5.6/reference/plugin/index.md b/versioned_docs/version-0.5.6/reference/plugin/index.md deleted file mode 100644 index df299e93..00000000 --- a/versioned_docs/version-0.5.6/reference/plugin/index.md +++ /dev/null @@ -1 +0,0 @@ -# Plugin System diff --git a/versioned_docs/version-0.5.6/reference/plugin/overview.md b/versioned_docs/version-0.5.6/reference/plugin/overview.md deleted file mode 100644 index f9561ddc..00000000 --- a/versioned_docs/version-0.5.6/reference/plugin/overview.md +++ /dev/null @@ -1,187 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Introduction - -KCL provides plugin support through a plugin agent and auxiliary command line tools, and the KCL plugin framework supports different general-purpose languages to develop plugins. Here we take Python as an example to briefly explain the use of plugins. - -KCL plugin Git repository: [https://github.com/kcl-lang/kcl-plugin](https://github.com/kcl-lang/kcl-plugin) - -## 0. Prerequisites - -Using the KCL Python plugin requires the presence of `Python 3.7+` in your `PATH`. - -## 1. Hello Plugin - -KCL plugins are installed in the `plugins` subdirectory of KCL (usually installed in the `$HOME/.kcl/plugins` directory), or set through the `$KCL_PLUGINS_ROOT` environment variable. Besides, the `plugins` directory could also be placed at the `pwd` path. KCL plugins are managed in the Git repository: [https://github.com/kcl-lang/kcl-plugin](https://github.com/kcl-lang/kcl-plugin), we can clone the repository for development. - -Enter the `kcl-plugin info` command to view the plugin directory (replace `/Users/kcl_user` with the local `$HOME` path): - -```shell -$ kcl-plugin info -# plugin_root: /Users/kcl_user/.kcl/plugins -``` - -View the list of plugins with the `kcl-plugin list` subcommand: - -```shell -$ kcl-plugin list -hello: hello doc - 0.0.1 -``` - -Where `hello` is an example builtin plugin (do not modify the plugin). - -In KCL code, the `hello` plugin can be imported via `import kcl_plugin.hello`. `main.k` code is as follows: - -```python -import kcl_plugin.hello - -name = "kcl" -three = hello.add(1,2) -``` - -The output result is - -```shell -$ python3 -m kclvm main.k -name: kcl -three: 3 -``` - -## 2. `kcl-plugin` Command - -`kcl-plugin` is a plugin helper command line tool, the command line help is as follows: - -```shell -$ kcl-plugin -usage: kcl-plugin [-h] {list,info,init,gendoc,test} ... -positional arguments: - {list,info,init,gendoc,test} - kcl plugin sub commands - list list all plugins - info show plugin document - init init a new plugin - gendoc gen all plugins document - test test plugin -optional arguments: - -h, --help show this help message and exit -``` - -- The `list` subcommand is used to view the list of plugins. -- The `info` subcommand is used to view the plugin directory and information about each plugin. -- The `init` subcommand is used to initialize new plugins. -- The `gendoc` subcommand is used to update the API documentation of all plugins. -- The `test` subcommand is used to test specified plugins. - -## 3. Plugin Information and Documentation - -Enter `kcl-plugin info hello` to view the `hello` plugin information: - -```shell -$ kcl-plugin info hello -{ - "name": "hello", - "describe": "hello doc", - "long_describe": "long describe", - "version": "0.0.1", - "method": { - "add": "add two numbers, and return result", - "foo": "no doc", - "list_append": "no doc", - "say_hello": "no doc", - "tolower": "no doc", - "update_dict": "no doc" - } -} -``` - -The information of the plugin mainly includes the name and version information of the plugin, and the function information provided by the plugin. This information is consistent with the automatically generated `api.md` file in the plugin directory (regenerate the `api.md` file for all plugins via `kcl-plugin gendoc` when the plugin API document changes). - -## 4. Plugin Directory Structure - -The directory structure of the plugin is as follows (replace `/Users/kcl_user` with the local `$HOME` path): - -```shell -$ tree /Users/kcl_user/.kcl/plugins/ -/Users/kcl_user/.kcl/plugins/ -├── _examples -├── _test -└── hello - ├── api.md - ├── plugin.py - └── plugin_test.py -$ -``` - -The `_examples` directory is the sample code of the plugin, the `_test` directory is the KCL test code of the plugin, and the other directories starting with letters are ordinary plugins. The content of the plugin is as follows: - -```shell -$ cat ./hello/plugin.py -# Copyright 2020 The KCL Authors. All rights reserved. -INFO = { - 'name': 'hello', - 'describe': 'hello doc', - 'long_describe': 'long describe', - 'version': '0.0.1', -} -def add(a: int, b: int) -> int: - """add two numbers, and return result""" - return a + b -... -``` - -Where `INFO` specifies the name of the plugin, a brief description, a detailed description and version information. And all the functions whose names start with letters are the functions provided by the plugin, so the `add` function can be called directly in KCL. - -> Note: KCL plugins are implemented in an independent pure Python code file, and plugins cannot directly call each other. - -## 5. Create Plugin - -A plugin can be created with the `kcl-plugin init` command: - -``` -$ kcl-plugin init hi -$ kcl-plugin list -hello: hello doc - 0.0.1 -hi: hi doc - 0.0.1 -``` - -The `kcl-plugin init` command will construct a new plugin from the built-in template, and then we can view the created plugin information with the `kcl-plugin list` command. - -## 6. Remove Plugin - -KCL plugins are located in the `plugins` subdirectory of KCL (usually installed in the `$HOME/.kcl/plugins` directory). -We can query the plugin installation directory with the command `kcl-plugin info`. - -```shell -$ kcl-plugin info -/Users/kcl_user/.kcl/plugins/ -$ tree /Users/kcl_user/.kcl/plugins/ -/Users/kcl_user/.kcl/plugins/ -├── _examples -├── _test -└── hello -- Delete this directory to delete the hello plugin - ├── api.md - ├── plugin.py - └── plugin_test.py -$ -``` - -## 7. Test Plugin - -There is a `plugin_test.py` file in the plugin directory, which is the unit test file of the plugin (based on the `pytest` testing framework). Also placed in the `_test` directory are plugin integration tests for KCL files. The `plugin_test.py` unit test is required, and the KCL integration tests in the `_test` directory can be added as needed. - -Unit tests for plugins can be executed via `kcl-plugin test`: - -```shell -$ kcl-plugin test hello -============================= test session starts ============================== -platform darwin -- Python 3.7.6+, pytest-5.3.5, py-1.9.0, pluggy-0.13.1 -rootdir: /Users/kcl_user -collected 5 items -.kcl/plugins/hello/plugin_test.py ..... [100%] -============================== 5 passed in 0.03s =============================== -$ -``` - -Integration tests can be tested by executing the `python3 -m pytest` command in the `_test` directory. diff --git a/versioned_docs/version-0.5.6/reference/plugin/project_context.md b/versioned_docs/version-0.5.6/reference/plugin/project_context.md deleted file mode 100644 index 0be02e78..00000000 --- a/versioned_docs/version-0.5.6/reference/plugin/project_context.md +++ /dev/null @@ -1,59 +0,0 @@ -# project_context - -project_context extract base info from project.yaml&stack.yaml - -_version: 0.0.1_ - -## `get_project_current_path` - -return the relative path of first file - -Example: - -```py -import kcl_plugin.project_context as ctx - -path = ctx.get_project_current_path() -print(path) -``` - -## `get_project_input_file` - -return compiling file list - -Example: - -```py -import kcl_plugin.project_context as ctx - -input_file = ctx.get_project_input_file() -print(input_file) -``` - -## `get_project_context` - -return the current project context from project.yaml - -Example: - -```py -import kcl_plugin.project_context as ctx - -project = ctx.get_project_context() -# Get project name -print(project?.name) -``` - -## `get_stack_context` - -return the current stack context from stack.yaml - -Example: - -```py -import kcl_plugin.project_context as ctx - -stack = ctx.get_stack_context() -# Get stack name -print(stack?.name) -``` diff --git a/versioned_docs/version-0.5.6/reference/xlang-api/_category_.json b/versioned_docs/version-0.5.6/reference/xlang-api/_category_.json deleted file mode 100644 index c2aafb21..00000000 --- a/versioned_docs/version-0.5.6/reference/xlang-api/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Multi-Language", - "position": 4 -} diff --git a/versioned_docs/version-0.5.6/reference/xlang-api/go-api.md b/versioned_docs/version-0.5.6/reference/xlang-api/go-api.md deleted file mode 100644 index 2a978250..00000000 --- a/versioned_docs/version-0.5.6/reference/xlang-api/go-api.md +++ /dev/null @@ -1,665 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Go API - -```go -import kcl "kcl-lang.io/kcl-go" -``` - -## KCL Go SDK - -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ kcl files │ │ KCL-Go-API │ │ KCLResultList │ -│ ┌───────────┐ │ │ │ │ │ -│ │ 1.k │ │ │ │ │ │ -│ └───────────┘ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ ┌───────────┐ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.Get("a.b.c") │ -│ │ 2.k │ │ │ │ Run(path) │ │ │ └───────────┘ │ └───────────────┘ -│ └───────────┘ │────┐ │ └───────────┘ │ │ │ -│ ┌───────────┐ │ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ │ 3.k │ │ │ │ │ │ │ KCLResult │──┼────────▶│x.Get("k", &v) │ -│ └───────────┘ │ │ │ │ │ └───────────┘ │ └───────────────┘ -│ ┌───────────┐ │ ├───▶│ ┌───────────┐ │──────────▶│ │ -│ │setting.yml│ │ │ │ │RunFiles() │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ └───────────┘ │ │ │ └───────────┘ │ │ │ KCLResult │──┼────────▶│x.JSONString() │ -└─────────────────┘ │ │ │ │ └───────────┘ │ └───────────────┘ - │ │ │ │ │ -┌─────────────────┐ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ Options │ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.YAMLString() │ -│WithOptions │ │ │ │MustRun() │ │ │ └───────────┘ │ └───────────────┘ -│WithOverrides │────┘ │ └───────────┘ │ │ │ -│WithWorkDir │ │ │ │ │ -│WithDisableNone │ │ │ │ │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ -``` - -
Example -

- -```go -{ - const k_code = ` -name = "kcl" -age = 1 - -two = 2 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {} -x1 = Person { - age = 101 -} -` - - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First().YAMLString() - fmt.Println(yaml) - - fmt.Println("----") - - result := kcl.MustRun("./testdata/main.k").First() - fmt.Println(result.JSONString()) - - fmt.Println("----") - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - - fmt.Println("----") - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x1", &person)) -} -``` - -

-
- -## Index - -- [Go API](#go-api) - - [KCL Go SDK](#kcl-go-sdk) - - [Index](#index) - - [Constants](#constants) - - [func FormatCode](#func-formatcode) - - [func FormatPath](#func-formatpath) - - [func InitKclvmPath](#func-initkclvmpath) - - [func InitKclvmRuntime](#func-initkclvmruntime) - - [func LintPath](#func-lintpath) - - [func ListDepFiles](#func-listdepfiles) - - [func ListDownStreamFiles](#func-listdownstreamfiles) - - [func ListUpStreamFiles](#func-listupstreamfiles) - - [func OverrideFile](#func-overridefile) - - [func ValidateCode](#func-validatecode) - - [type KCLResult](#type-kclresult) - - [type KCLResultList](#type-kclresultlist) - - [func MustRun](#func-mustrun) - - [func Run](#func-run) - - [func RunFiles](#func-runfiles) - - [type KclType](#type-kcltype) - - [func GetSchemaType](#func-getschematype) - - [type ListDepFilesOption](#type-listdepfilesoption) - - [type ListDepsOptions](#type-listdepsoptions) - - [type Option](#type-option) - - [func WithCode](#func-withcode) - - [func WithDisableNone](#func-withdisablenone) - - [func WithKFilenames](#func-withkfilenames) - - [func WithOptions](#func-withoptions) - - [func WithOverrides](#func-withoverrides) - - [func WithPrintOverridesAST](#func-withprintoverridesast) - - [func WithSettings](#func-withsettings) - - [func WithSortKeys](#func-withsortkeys) - - [func WithWorkDir](#func-withworkdir) - - [type ValidateOptions](#type-validateoptions) - -## Constants - -KclvmAbiVersion is the current kclvm ABI version. - -```go -const KclvmAbiVersion = scripts.KclvmAbiVersion -``` - -## func [FormatCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L110) - -```go -func FormatCode(code interface{}) ([]byte, error) -``` - -FormatCode returns the formatted code. - -
Example -

- -```go -{ - out, err := kcl.FormatCode(`a = 1+2`) - if err != nil { - log.Fatal(err) - } - fmt.Println(string(out)) - -} -``` - -``` -a = 1 + 2 -``` - -

-
- -## func [FormatPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L122) - -```go -func FormatPath(path string) (changedPaths []string, err error) -``` - -FormatPath formats files from the given path path: if path is \`.\` or empty string, all KCL files in current directory will be formatted, not recursively if path is \`path/file.k\`, the specified KCL file will be formatted if path is \`path/to/dir\`, all KCL files in the specified dir will be formatted, not recursively if path is \`path/to/dir/...\`, all KCL files in the specified dir will be formatted recursively - -the returned changedPaths are the changed file paths \(relative path\) - -
Example -

- -```go -{ - changedPaths, err := kcl.FormatPath("testdata/fmt") - if err != nil { - log.Fatal(err) - } - fmt.Println(changedPaths) -} -``` - -

-
- -## func [InitKclvmPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L54) - -```go -func InitKclvmPath(kclvmRoot string) -``` - -InitKclvmPath init kclvm path. - -## func [InitKclvmRuntime](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L59) - -```go -func InitKclvmRuntime(n int) -``` - -InitKclvmRuntime init kclvm process. - -## func [LintPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L142) - -```go -func LintPath(paths []string) (results []string, err error) -``` - -LintPath lint files from the given path - -
Example -

- -```go -{ - - results, err := kcl.LintPath([]string{"testdata/lint/import.k"}) - if err != nil { - log.Fatal(err) - } - for _, s := range results { - fmt.Println(s) - } - -} -``` - -``` -Module 'a' is reimported multiple times -Module 'a' imported but unused -``` - -

-
- -## func [ListDepFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L127) - -```go -func ListDepFiles(workDir string, opt *ListDepFilesOption) (files []string, err error) -``` - -ListDepFiles return the depend files from the given path - -## func [ListDownStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L137) - -```go -func ListDownStreamFiles(workDir string, opt *ListDepsOptions) ([]string, error) -``` - -ListDownStreamFiles return a list of downstream depend files from the given changed path list. - -## func [ListUpStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L132) - -```go -func ListUpStreamFiles(workDir string, opt *ListDepsOptions) (deps []string, err error) -``` - -ListUpStreamFiles return a list of upstream depend files from the given path list - -## func [OverrideFile](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L154) - -```go -func OverrideFile(file string, specs, importPaths []string) (bool, error) -``` - -OverrideFile rewrites a file with override spec file: string. The File that need to be overridden specs: \[\]string. List of specs that need to be overridden. - -``` -Each spec string satisfies the form: := or :- -When the pkgpath is '__main__', it can be omitted. -``` - -importPaths. List of import statements that need to be added - -## func [ValidateCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L159) - -```go -func ValidateCode(data, code string, opt *ValidateOptions) (ok bool, err error) -``` - -ValidateCode validate data match code - -## type [KCLResult](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L47) - -```go -type KCLResult = kcl.KCLResult -``` - -
Example -

- -```go -{ - const k_code = ` -name = "kcl" -age = 1 - -two = 2 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {name = "kcl-go"} -x1 = Person {age = 101} -` - - result := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First() - - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - -} -``` - -``` -x0.name: kcl-go -x1.age: 101 -``` - -

-
- -
Example ('et_struct) -

- -```go -{ - const k_code = ` -schema Person: - name: str = "kcl" - age: int = 1 - X: int = 2 - -x = { - "a": Person {age = 101} - "b": 123 -} -` - - result := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First() - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x.a", &person)) - fmt.Printf("person: %+v\n", person) - -} -``` - -``` -person: &{Name:kcl Age:101} -person: {Name:kcl Age:101} -``` - -

-
- -## type [KCLResultList](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L48) - -```go -type KCLResultList = kcl.KCLResultList -``` - -### func [MustRun](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L64) - -```go -func MustRun(path string, opts ...Option) *KCLResultList -``` - -MustRun is like Run but panics if return any error. - -
Example -

- -```go -{ - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(`name = "kcl"`)).First().YAMLString() - fmt.Println(yaml) - -} -``` - -``` -name: kcl -``` - -

-
- -
Example (Raw Yaml) -

- -```go -{ - const code = ` -b = 1 -a = 2 -` - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(code)).GetRawYamlResult() - fmt.Println(yaml) - - yaml_sorted := kcl.MustRun("testdata/main.k", kcl.WithCode(code), kcl.WithSortKeys(true)).GetRawYamlResult() - fmt.Println(yaml_sorted) - -} -``` - -``` -b: 1 -a: 2 -a: 2 -b: 1 -``` - -

-
- -
Example (Schema Type) -

- -```go -{ - const code = ` -schema Person: - name: str = "" - -x = Person() -` - json := kcl.MustRun("testdata/main.k", kcl.WithCode(code)).First().JSONString() - fmt.Println(json) - -} -``` - -``` -{ - "x": { - "name": "" - } -} -``` - -

-
- -
Example (Settings) -

- -```go -{ - yaml := kcl.MustRun("./testdata/app0/kcl.yaml").First().YAMLString() - fmt.Println(yaml) -} -``` - -

-
- -### func [Run](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L69) - -```go -func Run(path string, opts ...Option) (*KCLResultList, error) -``` - -Run evaluates the KCL program with path and opts, then returns the object list. - -
Example (Get Field) -

- -```go -{ - - x, err := kcl.Run("./testdata/app0/kcl.yaml") - assert(err == nil, err) - - fmt.Println(x.First().Get("deploy_topology.1.zone")) - -} -``` - -``` -R000A -``` - -

-
- -### func [RunFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L74) - -```go -func RunFiles(paths []string, opts ...Option) (*KCLResultList, error) -``` - -RunFiles evaluates the KCL program with multi file path and opts, then returns the object list. - -
Example -

- -```go -{ - result, _ := kcl.RunFiles([]string{"./testdata/app0/kcl.yaml"}) - fmt.Println(result.First().YAMLString()) -} -``` - -

-
- -## type [KclType](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L50) - -```go -type KclType = kcl.KclType -``` - -### func [GetSchemaType](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L176) - -```go -func GetSchemaType(file, code, schemaName string) ([]*KclType, error) -``` - -GetSchemaType returns schema types from a kcl file or code. - -file: string - -``` -The kcl filename -``` - -code: string - -``` -The kcl code string -``` - -schema_name: string - -``` -The schema name got, when the schema name is empty, all schemas are returned. -``` - -## type [ListDepFilesOption](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L45) - -```go -type ListDepFilesOption = list.Option -``` - -## type [ListDepsOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L44) - -```go -type ListDepsOptions = list.DepOptions -``` - -## type [Option](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L43) - -```go -type Option = kcl.Option -``` - -### func [WithCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L79) - -```go -func WithCode(codes ...string) Option -``` - -WithCode returns a Option which hold a kcl source code list. - -### func [WithDisableNone](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L97) - -```go -func WithDisableNone(disableNone bool) Option -``` - -WithDisableNone returns a Option which hold a disable none switch. - -### func [WithKFilenames](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L82) - -```go -func WithKFilenames(filenames ...string) Option -``` - -WithKFilenames returns a Option which hold a filenames list. - -### func [WithOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L85) - -```go -func WithOptions(key_value_list ...string) Option -``` - -WithOptions returns a Option which hold a key=value pair list for option function. - -
Example -

- -```go -{ - const code = ` -name = option("name") -age = option("age") -` - x, err := kcl.Run("hello.k", kcl.WithCode(code), - kcl.WithOptions("name=kcl", "age=1"), - ) - if err != nil { - log.Fatal(err) - } - - fmt.Println(x.First().YAMLString()) - -} -``` - -``` -age: 1 -name: kcl -``` - -

-
- -### func [WithOverrides](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L88) - -```go -func WithOverrides(override_list ...string) Option -``` - -WithOverrides returns a Option which hold a override list. - -### func [WithPrintOverridesAST](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L100) - -```go -func WithPrintOverridesAST(printOverridesAST bool) Option -``` - -WithPrintOverridesAST returns a Option which hold a printOverridesAST switch. - -### func [WithSettings](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L91) - -```go -func WithSettings(filename string) Option -``` - -WithSettings returns a Option which hold a settings file. - -### func [WithSortKeys](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L105) - -```go -func WithSortKeys(sortKeys bool) Option -``` - -WithSortKeys returns a Option which hold a sortKeys switch. - -### func [WithWorkDir](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L94) - -```go -func WithWorkDir(workDir string) Option -``` - -WithWorkDir returns a Option which hold a work dir. - -## type [ValidateOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L46) - -```go -type ValidateOptions = validate.ValidateOptions -``` diff --git a/versioned_docs/version-0.5.6/reference/xlang-api/index.md b/versioned_docs/version-0.5.6/reference/xlang-api/index.md deleted file mode 100644 index f6f8e076..00000000 --- a/versioned_docs/version-0.5.6/reference/xlang-api/index.md +++ /dev/null @@ -1 +0,0 @@ -# Multi-Language diff --git a/versioned_docs/version-0.5.6/reference/xlang-api/java-api.md b/versioned_docs/version-0.5.6/reference/xlang-api/java-api.md deleted file mode 100644 index 52c8cf34..00000000 --- a/versioned_docs/version-0.5.6/reference/xlang-api/java-api.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Java API - -At present, the KCL Java SDK is still in the early preview version. The KCL team will continue to update and provide more functions in the future. For more information, see [https://github.com/kcl-lang/kcl-java](https://github.com/kcl-lang/kcl-java) diff --git a/versioned_docs/version-0.5.6/reference/xlang-api/overview.md b/versioned_docs/version-0.5.6/reference/xlang-api/overview.md deleted file mode 100644 index e63422d4..00000000 --- a/versioned_docs/version-0.5.6/reference/xlang-api/overview.md +++ /dev/null @@ -1,293 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Introduction - -The KCL language provides general programming language interfaces such as C/Rust/Go/Python/Java, and the related languages are under development. - -## C/Rust API - -The core of KCL is developed in Rust, and the C language API is exported externally for packaging and integration in high-level languages such as Go/Python/Java. - -## Go API - -Go API is a C-API provided by CGO wrapping KCL, while providing deeper customization features to meet the needs of upper-level tools. - -### Abstract Model - -The abstract model of the KCL Go API is as follows: - -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ kcl files │ │ KCL-Go-API │ │ KCLResultList │ -│ ┌───────────┐ │ │ │ │ │ -│ │ 1.k │ │ │ │ │ │ -│ └───────────┘ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ ┌───────────┐ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.Get("a.b.c") │ -│ │ 2.k │ │ │ │ Run(path) │ │ │ └───────────┘ │ └───────────────┘ -│ └───────────┘ │────┐ │ └───────────┘ │ │ │ -│ ┌───────────┐ │ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ │ 3.k │ │ │ │ │ │ │ KCLResult │──┼────────▶│x.Get("k", &v) │ -│ └───────────┘ │ │ │ │ │ └───────────┘ │ └───────────────┘ -│ ┌───────────┐ │ ├───▶│ ┌───────────┐ │──────────▶│ │ -│ │setting.yml│ │ │ │ │RunFiles() │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ └───────────┘ │ │ │ └───────────┘ │ │ │ KCLResult │──┼────────▶│x.JSONString() │ -└─────────────────┘ │ │ │ │ └───────────┘ │ └───────────────┘ - │ │ │ │ │ -┌─────────────────┐ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ Options │ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.YAMLString() │ -│WithOptions │ │ │ │MustRun() │ │ │ └───────────┘ │ └───────────────┘ -│WithOverrides │────┘ │ └───────────┘ │ │ │ -│WithWorkDir │ │ │ │ │ -│WithDisableNone │ │ │ │ │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ -``` - -The input file contains the KCL file and the `setting.yml` configuration file, and `Options` can be used to specify additional parameters and information such as working directory. The "KCL-Go-API" part is the provided KCL execution function. The execution function executes the KCL program according to the input file and additional parameters, and finally outputs the result of `KCLResultList`. `KCLResultList` is a list of `KCLResult`, each `KCLResult` corresponding to a generated configuration file or `map[string]interface{}`. - -### Example - -```go -package main - -import ( - "fmt" - - kcl "kcl-lang.io/kcl-go" -) - - -func main() { - const k_code = ` -name = "kcl" -age = 1 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person{} -x1 = Person{age:101} -` - - result := kcl.MustRun("hello.k", kcl.WithCode(k_code)).First() - fmt.Println(result.YAMLString()) - - fmt.Println("----") - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - - fmt.Println("----") - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x1", &person)) -} -``` - -Output result: - -```yaml -age: 1 -name: kcl -x0: - age: 1 - name: kcl -x1: - age: 101 - name: kcl - ----- -x0.name: kcl -x1.age: 101 ----- -person: &{Name:kcl Age:101} -``` - -## Python API - -Using the Python SDK requires that you have a local Python version higher than 3.7.3 and a local pip package management tool. You can use the following command to install and obtain helpful information. - -```bash -python3 -m pip install kclvm --user && python3 -m kclvm --help -``` - -### Command Line Tool - -Prepare a KCL file named `main.k` - -```python -name = "kcl" -age = 1 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {} -x1 = Person { - age = 101 -} -``` - -Execute the following command and get the output: - -```shell -$ python3 -m kclvm hello.k -name: kcl -age: 1 -x0: - name: kcl - age: 1 -x1: - name: kcl - age: 101 -``` - -### API - -In addition, we can also execute KCL files through Python code. - -Prepare a KCL file named `main.py` - -```python -import kclvm.program.exec as kclvm_exec -import kclvm.vm.planner as planner - -print(planner.plan(kclvm_exec.Run(["hello.k"]).filter_by_path_selector())) -``` - -Execute the following command and get the output: - -```shell -$ python3 main.py -name: kcl -age: 1 -x0: - name: kcl - age: 1 -x1: - name: kcl - age: 101 -``` - -You can see that the same output can be obtained through command line tools and APIs. - -At present, the KCL Python SDK is still in the early preview version. The KCL team will continue to update and provide more functions in the future. For more information, see [https://github.com/kcl-lang/kcl-py](https://github.com/kcl-lang/kcl-py) - -## REST-API - -The C-API provided by KCL does not have a REST-API. The REST-API is defined by Protobuf. - -### Start REST Service - -The RestAPI service can be started in the following way: - -```shell -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -The service can then be requested via the POST protocol: - -```shell -$ curl -X POST http://127.0.0.1:2021/api:protorpc/BuiltinService.Ping --data '{}' -{ - "error": "", - "result": {} -} -``` - -The POST request and the returned JSON data are consistent with the structure defined by Protobuf. - -### `BuiltinService` - -Where the `/api:protorpc/BuiltinService.Ping` path represents the `Ping` method of the `BuiltinService` service. - -The complete `BuiltinService` is defined by Protobuf: - -```protobuf -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} -``` - -The `Ping` method can verify whether the service is normal, and the `ListMethod` method can query the list of all services and functions provided. - -### `KclvmService` - -The `KclvmService` service is a service related to KCL functionality. The usage is the same as the `BuiltinService` service. - -For example, there is the following `Person` structure definition: - -```python -schema Person: - key: str - - check: - "value" in key # 'key' is required and 'key' must contain "value" -``` - -Then we want to use `Person` to verify the following JSON data: - -```json -{ "key": "value" } -``` - -This can be done through the `ValidateCode` method of the `KclvmService` service. Refer to the `ValidateCode_Args` structure of the `ValidateCode` method: - -```protobuf -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} -``` - -Construct the JSON data required by the POST request according to the `ValidateCode_Args` structure, which contains the `Person` definition and the JSON data to be verified: - -```json -{ - "code": "\nschema Person:\n key: str\n\n check:\n \"value\" in key # 'key' is required and 'key' must contain \"value\"\n", - "data": "{\"key\": \"value\"}" -} -``` - -Save this JSON data to the `vet-hello.json` file and verify it with the following command: - -```shell -$ curl -X POST \ - http://127.0.0.1:2021/api:protorpc/KclvmService.ValidateCode \ - -H "accept: application/json" \ - --data @./vet-hello.json -{ - "error": "", - "result": { - "success": true - } -} -``` - -## APIs in other languages - -Coming soon diff --git a/versioned_docs/version-0.5.6/reference/xlang-api/python-api.md b/versioned_docs/version-0.5.6/reference/xlang-api/python-api.md deleted file mode 100644 index e6ce67dc..00000000 --- a/versioned_docs/version-0.5.6/reference/xlang-api/python-api.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Python API - -At present, the KCL Python SDK is still in the early preview version. The KCL team will continue to update and provide more functions in the future. For more information, see [https://github.com/kcl-lang/kcl-py](https://github.com/kcl-lang/kcl-py) diff --git a/versioned_docs/version-0.5.6/tools/Ide/_category_.json b/versioned_docs/version-0.5.6/tools/Ide/_category_.json deleted file mode 100644 index d9bfcdd7..00000000 --- a/versioned_docs/version-0.5.6/tools/Ide/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "IDE", - "position": 2 -} diff --git a/versioned_docs/version-0.5.6/tools/Ide/index.md b/versioned_docs/version-0.5.6/tools/Ide/index.md deleted file mode 100644 index aec7245a..00000000 --- a/versioned_docs/version-0.5.6/tools/Ide/index.md +++ /dev/null @@ -1,6 +0,0 @@ -# IDE - -We have provided two simple kinds of plugins for KCL. You can get more help information at the following link: - -- IntelliJ Plugin: https://github.com/kcl-lang/intellij-kcl -- VSCode Plugin: https://github.com/kcl-lang/vscode-kcl diff --git a/versioned_docs/version-0.5.6/tools/Ide/vs-code.md b/versioned_docs/version-0.5.6/tools/Ide/vs-code.md deleted file mode 100644 index 454e6ff3..00000000 --- a/versioned_docs/version-0.5.6/tools/Ide/vs-code.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Visual Studio Code - -## Quick Start - -- **Step 1.** [Install KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) on your system. Please check that `kcl` and `kcl-language-server` are installed and have been added to your PATH: - - ```bash - which kcl - which kcl-language-server - ``` - -- **Step 2.** Install the [KCL extension](https://marketplace.visualstudio.com/items?itemName=kcl.kcl-vscode-extension) for Visual Studio Code. This extension requires the VS Code 1.50+. -- **Step 3.** Reopen VS Code and create a KCL file and begin your KCL tour! - -## Features - -This extension provides some coding assistance, including the following features: - -- **Syntax Highlight:** - ![Highlight](/img/docs/tools/Ide/vs-code/Highlight.png) -- **Goto Definition:** Goto definition of schema, variable, schema attribute, and import pkg. - ![Goto Definition](/img/docs/tools/Ide/vs-code/GotoDef.gif) -- **Completion:** Keywords completions and dot(`.`) completion. - ![Completion](/img/docs/tools/Ide/vs-code/Completion.gif) -- **Outline:** Main definition(schema def) and variables in KCL file. - ![Outline](/img/docs/tools/Ide/vs-code/Outline.gif) -- **Hover:** Identifier information (type and schema documentation). - ![Hover](/img/docs/tools/Ide/vs-code/Hover.gif) -- **Diagnostics:** Warnings and errors in KCL file. - - > Tips: You can enhance the effect of diagnostics by installing another plugin: [Error Lens](https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens). - - ![Diagnostics](/img/docs/tools/Ide/vs-code/Diagnostics.gif) - -Other useful features such as refactoring and testing are in development. - -## Dependencies - -We recommend that you use the latest version of KCL, but the minimum required version for this extension is 0.4.6. If you are using an earlier version, the extension may not work properly. - -## Known Issues - -See [here](https://github.com/kcl-lang/kcl/issues/524). - -## Ask for help - -If the extension isn't working as you expect, please contact us with [community](https://kcl-lang.io/docs/community/intro/support) for help. - -## Contributing - -We are working actively on improving the KCL development on VS Code. All kinds of contributions are welcomed. You can refer to our [contribution guide](https://kcl-lang.io/docs/community/contribute). It introduces how to build and run the extension locally, and describes the process of sending a contribution. - -## License - -Apache License 2.0 diff --git a/versioned_docs/version-0.5.6/tools/_category_.json b/versioned_docs/version-0.5.6/tools/_category_.json deleted file mode 100644 index 5ecd522f..00000000 --- a/versioned_docs/version-0.5.6/tools/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Tools", - "position": 3 -} diff --git a/versioned_docs/version-0.5.6/tools/cli/_category_.json b/versioned_docs/version-0.5.6/tools/cli/_category_.json deleted file mode 100644 index 887061ef..00000000 --- a/versioned_docs/version-0.5.6/tools/cli/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Command Line Tools", - "position": 1 -} diff --git a/versioned_docs/version-0.5.6/tools/cli/index.md b/versioned_docs/version-0.5.6/tools/cli/index.md deleted file mode 100644 index ef4f69dc..00000000 --- a/versioned_docs/version-0.5.6/tools/cli/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# Command Line Tools - -KCL provides IDE plug-ins, rich language tools and OpenAPI tools. These tools provide a complete set of solutions, including configuration languages, model interfaces, automation tools, and best practices. diff --git a/versioned_docs/version-0.5.6/tools/cli/kcl/_category_.json b/versioned_docs/version-0.5.6/tools/cli/kcl/_category_.json deleted file mode 100644 index 4c605bd0..00000000 --- a/versioned_docs/version-0.5.6/tools/cli/kcl/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KCL Tools", - "position": 2 -} diff --git a/versioned_docs/version-0.5.6/tools/cli/kcl/docgen.md b/versioned_docs/version-0.5.6/tools/cli/kcl/docgen.md deleted file mode 100644 index ca647228..00000000 --- a/versioned_docs/version-0.5.6/tools/cli/kcl/docgen.md +++ /dev/null @@ -1,317 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Docgen - -The KCL Docgen tool supports extracting model documents from KCL source code and supports multiple output formats: JSON, YAML and Markdown. This article introduces the document specification of the KCL language, gives an example of how to use the KCL Docgen tool to extract documents, and shows the process of importing localization documents. - -## 1. Document Specification of KCL - -The documentation of the KCL file mainly contains the following two parts: - -- Current KCL Module document: description of the current KCL file -- All schema documents contained in the KCL file: a description of the current schema, including schema description, schema attribute descriptions, and Examples. The specific format is as follows: - -1. Schema description - -```python -"""This is a brief description of the Schema -""" -``` - -2. Description of each attribute of Schema: including attribute description, attribute type, default value, optional or required - -```python -""" -Attributes ----------- -x : type, default is a, optional. - Description of parameter `x`. -y : type, default is b, required. - Description of parameter `y`. -""" -``` - -`----------` indicates that `Attributes` is a title (the length of the symbol `-` is the same as the length of the title), the attribute name and attribute type are separated by a colon `:`, the description of the attribute is written on another line with indentation. The default value of the attribute is separated by a comma `,` after the attribute type, and it is written in the form of `default is {default value}`. In addition, it is necessary to indicate whether the attribute is optional/required. Write `optional` after the default value for an optional attribute, and write `required` after the default value for a required attribute. - -3. Examples - -```python -""" -Examples --------- -val = Schema { - name = "Alice" - age = 18 -} -""" -``` - -In addition, the KCL docstring syntax should use a subset of the [re-structured text (reST)](https://docutils.sourceforge.io/rst.html) and be rendered using the [Sphinx](https://www.sphinx-doc.org/en/master/). - -## 2. Generating Documentation From KCL - -Use the `kcl-doc generate` command to extract documentation from a user-specified file or directory and output it to the specified directory. - -1. Args - -``` -usage: kcl-doc generate [-h] [--format YAML] [-o OUTPUT] [--r] - [--i18n-locale LOCALE] [--repo-url REPO_URL] - [files [files ...]] - -positional arguments: - files KCL file paths. If there's more than one files to - generate, separate them by space - -optional arguments: - -h, --help show this help message and exit - --format YAML Doc file format, support YAML, JSON and MARKDOWN. - Defaults to MARKDOWN - -o OUTPUT, --output-path OUTPUT - Specify the output directory. Defaults to ./kcl_doc - --r, -R, --recursive Search directory recursively - --i18n-locale LOCALE I18n locale, e.g.: zh, zh_cn, en, en_AS. Defaults to - en - --repo-url REPO_URL The source code repository url. It will be displayed in - the generated doc to link to the source code. -``` - -2. Extract documents from the file(s) and output them to the specified directory - -```text -kcl-doc generate your_config.k your_another_config.k -o your_docs_output_dir -``` - -3. From the specified directory, recursively find the KCL file(s) and extract the documentation - -```text -kcl-doc generate your_config_dir -r -o your_docs_output_dir -``` - -4. When generating documentation, specify the source code repository address. The generated documentation will contain links to source files - -```text -kcl-doc generate your_config.k -o your_docs_output_dir --repo-url https://url/to/source_code -``` - -## 3. Add Documentation for Localized Languages - -As shown before, by default, the documentation extracted by the documentation generation tool is based on the content of the source docstring, and thus the language of the documentation depends on the language in which the docstring was written. If you need to add localized language documentation to the source file, you can follow the steps below: - -1. Initialize the i18n configuration file. This step generates the corresponding i18n configuration file based on the specified KCL file. The file format can be JSON/YAML, and the default is YAML. The output profile name will end in the specified target localization language - -```text -kcl-doc init-i18n your_config.k --format JSON --i18n-locale your_target_locale -``` - -2. Modify the i18n configuration file and update each doc field in your locale language - -3. Generate localized documents from the modified i18n configuration file - -```text -kcl-doc generate your_config_dir --i18n-locale your_target_locale --format Markdown -``` - -Next, a simple example is used to demonstrate the process of adding localized language documents. - -3.1 Prepare the KCL file, such as `server.k`: - - ```python - schema Server: - """Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - - Attributes - ---------- - workloadType : str, default is "Deployment", required - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - name : str, required - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - labels : {str:str}, optional - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - - Examples - ---------------------- - myCustomApp = AppConfiguration { - name = "componentName" - } - """ - - workloadType: str = "Deployment" - name: str - labels?: {str: str} - ``` - -3.2 Get the initialized i18n configuration file from the `server.k`. For example, if you want to add Chinese documents to it, specify the format of the generated configuration file as YAML - - ```text - kcl-doc init-i18n server.k --format YAML --i18n-locale zh_cn - ``` - - This command will create the directory `kcl_doc` under the current directory and generate the i18n configuration file `kcl_doc/i18n_server_zh_cn.yaml`. Its contents are as follows: - - ```yaml - name: server - relative_path: ./server.k - schemas: - - name: Server - doc: | - Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - attributes: - - name: workloadType - doc: | - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - default_value: '"Deployment"' - is_optional: false - - name: name - doc: | - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: false - default_value: '' - - name: labels - doc: | - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - type: - type_str: '{str: str}' - type_category: DICT - dict_type: - key_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - value_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: true - default_value: '' - examples: | - myCustomApp = AppConfiguration { - name = "componentName" - } - doc: '' - source_code_url: '' - ``` - -3.3 Modify all the `doc` fields to the Chinese description. The modified configuration is as follows: - - ```yaml - name: server - relative_path: ./server.k - schemas: - - name: Server - doc: | - Server 模型定义了采用 Kubernetes 最佳实践的持续运行的服务的通用配置接口 - attributes: - - name: workloadType - doc: | - workloadType 属性定义了服务的类型,是服务级别的属性。合法的取值有:Deployment, CafeDeployment. - 另请查看:k8s/core/v1/workload_metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - default_value: '"Deployment"' - is_optional: false - - name: name - doc: | - name 为服务的名称,是服务级别的属性。 - 另请查看:k8s/core/v1/metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: false - default_value: '' - - name: labels - doc: | - labels 为服务的标签,是服务级别的属性。 - 另请查看:k8s/core/v1/metadata.k. - type: - type_str: '{str: str}' - type_category: DICT - dict_type: - key_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - value_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: true - default_value: '' - examples: | - myCustomApp = AppConfiguration { - name = "componentName" - } - doc: '' - source_code_url: '' - ``` - -3.4 Based on the modified i18n configuration, generate documents in localized languages. Execute the following command to output the Chinese document `kcl_doc/doc_server_zh_cn.md`. The commands and the contents of the generated documents are as follows: - -```text -kcl-doc generate server.k --i18n-locale zh_cn --format Markdown -``` - -````markdown -# server - -## Schema Server - -Server 模型定义了采用 Kubernetes 最佳实践的持续运行的服务的通用配置接口 - -### Attributes - -| Name and Description | Type | Default Value | Required | -| -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | ------------- | ------------ | -| **workloadType**
workloadType 属性定义了服务的类型,是服务级别的属性。合法的取值有:Deployment, CafeDeployment.
另请查看:k8s/core/v1/workload_metadata.k. | str | "Deployment" | **required** | -| **name**
name 为服务的名称,是服务级别的属性。
另请查看:k8s/core/v1/metadata.k. | str | Undefined | **required** | -| **labels**
labels 为服务的标签,是服务级别的属性。
另请查看:k8s/core/v1/metadata.k. | {str: str} | Undefined | optional | - -### Examples - -``` -myCustomApp = AppConfiguration { - name = "componentName" -} -``` - - -```` - -## 4. Appendix - -### 1. Concept of reST - -For documents in reST format, paragraphs and indentation are important, new paragraphs are marked with blank lines, and indentation is the indentation indicated in the output. Font styles can be expressed as follows: - -- \*Italic\* -- \*\*Bold\*\* -- \`\`Monospaced\`\` - -Refer to [reST](https://docutils.sourceforge.io/rst.html) for more information. diff --git a/versioned_docs/version-0.5.6/tools/cli/kcl/index.md b/versioned_docs/version-0.5.6/tools/cli/kcl/index.md deleted file mode 100644 index b750f652..00000000 --- a/versioned_docs/version-0.5.6/tools/cli/kcl/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# KCL Language Tools - -KCL not only provides the command `kcl` to compile and execute configuration programs but also provides fmt, lint, test, vet, docgen and other supporting tools. diff --git a/versioned_docs/version-0.5.6/tools/cli/kcl/overview.md b/versioned_docs/version-0.5.6/tools/cli/kcl/overview.md deleted file mode 100644 index b1354b8c..00000000 --- a/versioned_docs/version-0.5.6/tools/cli/kcl/overview.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Overview - -KCL toolchain is a toolset of KCL language, which aims to improve the efficiency of batch migration, writing, compiling and running of KCL. - -| | Name | Description | -| ---------- | ------------------------ | ------------------------------------------------------------------- | -| Main Tools | **kcl** | Provide support for KCL in coding, compiling and running | -| | kcl-test | Coming soon | -| | kcl-lint | Check code style for KCL | -| | kcl-doc | Parses the KCL code and generate documents | -| | kcl-fmt | Format the kcl code | -| | kcl-vet | Validate data files such as JSON and YAML using KCL | -| IDE Plugin | IntelliJ IDEA KCL plugin | Provide assistance for KCL in coding and compiling on IntelliJ IDEA | -| | VS Code KCL plugin | Provide assistance for KCL in coding and compiling on VS Code | - -## KCL Tool - -### Args - -```shell -USAGE: - kcl [OPTIONS] [--] [input]... - -Arguments: - [input]... Specify the input files to run - -Options: - -o, --output - Specify the YAML output file path - -Y, --setting ... - Specify the input setting file - -v, --verbose... - Print test information verbosely - -n, --disable_none - Disable dumping None values - -r, --strict_range_check - Do perform strict numeric range checks - -d, --debug - Run in debug mode (for developers only) - -k, --sort_keys - Sort result keys - -D, --argument ... - Specify the top-level argument - -S, --path_selector ... - Specify the path selector - -O, --overrides ... - Specify the configuration override path and value - --target - Specify the target type - -E, --external ... - Mapping of package name and path where the package is located - -h, --help - Print help -``` diff --git a/versioned_docs/version-0.5.6/tools/cli/kcl/test.md b/versioned_docs/version-0.5.6/tools/cli/kcl/test.md deleted file mode 100644 index 4f99e53d..00000000 --- a/versioned_docs/version-0.5.6/tools/cli/kcl/test.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Test Tool - -Coming soon. diff --git a/versioned_docs/version-0.5.6/tools/cli/kcl/vet.md b/versioned_docs/version-0.5.6/tools/cli/kcl/vet.md deleted file mode 100644 index d2f2220e..00000000 --- a/versioned_docs/version-0.5.6/tools/cli/kcl/vet.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Validation - -## Intro - -The KCL Validation tool supports basic configuration data verification capabilities. You can write a KCL schema to verify the type and value of the input JSON/YAML files. - -## How to use - -There is a JSON format file `data.json`: - -```json -{ - "name": "Alice", - "age": 18, - "message": "This is Alice", - "data": { - "id": 1, - "value": "value1" - }, - "labels": { - "key": "value" - }, - "hc": [1, 2, 3] -} -``` - -Build a validated KCL file `schema.k`: - -```py -schema User: - name: str - age: int - message?: str - data: Data - labels: {str:} - hc: [int] - - check: - age > 10 - -schema Data: - id: int - value: str -``` - -Execute the following command: - -```shell -kcl-vet data.json schema.k -``` - -## Specify the schema for validation - -When multiple schema definitions exist in the KCL file, by default, the KCL Validation tool will use the first schema to check. If you need to specify a schema for verification, you can use the `-d|--schema` parameter - -```shell -kcl-vet data.json schema.k -d User -``` - -## Args - -```shell -$ kcl-vet -h -USAGE: - kcl-vet [OPTIONS] [ARGS] - -ARGS: - Validation data file - KCL file - -OPTIONS: - -d, --schema - Iterate through subdirectories recursively - - --format - Validation data file format, support YAML and JSON, default is JSON - - -h, --help - Print help information - - -n, --attribute_name - The attribute name for the data loading -``` diff --git a/versioned_docs/version-0.5.6/tools/cli/openapi/_category_.json b/versioned_docs/version-0.5.6/tools/cli/openapi/_category_.json deleted file mode 100644 index 58e4c68a..00000000 --- a/versioned_docs/version-0.5.6/tools/cli/openapi/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "OpenAPI Tools", - "position": 3 -} diff --git a/versioned_docs/version-0.5.6/tools/cli/openapi/crd-to-kcl.md b/versioned_docs/version-0.5.6/tools/cli/openapi/crd-to-kcl.md deleted file mode 100644 index aafebcd9..00000000 --- a/versioned_docs/version-0.5.6/tools/cli/openapi/crd-to-kcl.md +++ /dev/null @@ -1,118 +0,0 @@ -# CRD to KCL - -To convert from models defined in the Kubernetes CRD file to KCL schema, we could run the following script: - -```shell -kcl-openapi generate model --crd -f ${your_CRD.yaml} -t ${the_kcl_files_output_dir} --skip-validation -``` - -## Example - -- There is the Kubernetes CRD file that we need to convert: `test_crontab_CRD.yaml`: - -```yaml -# Deprecated in v1.16 in favor of apiextensions.k8s.io/v1 -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - # name must match the spec fields below, and be in the form: . - name: crontabs.stable.example.com -spec: - # group name to use for REST API: /apis// - group: stable.example.com - # list of versions supported by this CustomResourceDefinition - versions: - - name: v1 - # Each version can be enabled/disabled by Served flag. - served: true - # One and only one version must be marked as the storage version. - storage: true - # either Namespaced or Cluster - scope: Namespaced - names: - # plural name to be used in the URL: /apis/// - plural: crontabs - # singular name to be used as an alias on the CLI and for display - singular: crontab - # kind is normally the CamelCased singular type. Your resource manifests use this. - kind: CronTab - # shortNames allow shorter string to match your resource on the CLI - shortNames: - - ct - preserveUnknownFields: false - validation: - openAPIV3Schema: - type: object - properties: - spec: - type: object - properties: - cronSpec: - type: string - image: - type: string - replicas: - type: integer -``` - -- The script will be: - -```shell -kcl-openapi generate model -f test_crontab_CRD.yaml -t ~/ --skip-validation --crd -``` - -- Then we can find the generated file here: `~/models/stable_example_com_v1_cron_tab.k` - -```python -""" -This file was generated by the KCL auto-gen tool. DO NOT EDIT. -Editing this file might prove futile when you re-run the KCL auto-gen generate command. -""" -import kusion_kubernetes.apimachinery.apis - - -schema CronTab: - """stable example com v1 cron tab - - Attributes - ---------- - apiVersion : str, default is "stable.example.com/v1", required - APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - kind : str, default is "CronTab", required - Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - metadata : apis.ObjectMeta, default is Undefined, optional - metadata - spec : StableExampleComV1CronTabSpec, default is Undefined, optional - spec - """ - - - apiVersion: "stable.example.com/v1" = "stable.example.com/v1" - - kind: "CronTab" = "CronTab" - - metadata?: apis.ObjectMeta - - spec?: StableExampleComV1CronTabSpec - - -schema StableExampleComV1CronTabSpec: - """stable example com v1 cron tab spec - - Attributes - ---------- - cronSpec : str, default is Undefined, optional - cron spec - image : str, default is Undefined, optional - image - replicas : int, default is Undefined, optional - replicas - """ - - - cronSpec?: str - - image?: str - - replicas?: int -``` diff --git a/versioned_docs/version-0.5.6/tools/cli/openapi/index.md b/versioned_docs/version-0.5.6/tools/cli/openapi/index.md deleted file mode 100644 index 236d6e36..00000000 --- a/versioned_docs/version-0.5.6/tools/cli/openapi/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# OpenAPI Tools - -The KCL OpenAPI tool can not only convert common models but also support CRD and other models. diff --git a/versioned_docs/version-0.5.6/tools/cli/openapi/openapi-to-kcl.md b/versioned_docs/version-0.5.6/tools/cli/openapi/openapi-to-kcl.md deleted file mode 100644 index bef582ec..00000000 --- a/versioned_docs/version-0.5.6/tools/cli/openapi/openapi-to-kcl.md +++ /dev/null @@ -1,64 +0,0 @@ -# OpenAPI to KCL - -To convert from models defined in the OpenAPI spec file to KCL schema, we could run the following script: - -```shell -kcl-openapi generate model -f ${your_open_api_spec.yaml} -t ${the_kcl_files_output_dir} -``` - -For example: - -- There is the OpenAPI spec file that we need to convert: `test_open_api_spec.yaml` - -```yaml -definitions: - v1.TestInt: - type: object - properties: - name: - type: string - format: int-or-string - required: - - name - x-kcl-type: - import: - package: v1.test_int - alias: test_int - type: TestInt -swagger: "2.0" -info: - title: KCL - version: v0.0.2 -paths: {} -``` - -- The script will be: - -```shell -kcl-openapi generate model -f test_open_api_spec.yaml -t ~/ --skip-validation -``` - -- Then we can find the generated file here: `~/models/v1/test_int.k` - -```python -""" -This is the test_int module in v1 package. -This file was generated by the KCL auto-gen tool. DO NOT EDIT. -Editing this file might prove futile when you re-run the KCL auto-gen generate command. -""" - - -schema TestInt: - """v1 test int - - Attributes - ---------- - name : int | str, default is Undefined, required - name - """ - - - name: int | str - - -``` diff --git a/versioned_docs/version-0.5.6/user_docs/concepts/_category_.json b/versioned_docs/version-0.5.6/user_docs/concepts/_category_.json deleted file mode 100644 index d40bb9de..00000000 --- a/versioned_docs/version-0.5.6/user_docs/concepts/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Concepts", - "position": 5 -} diff --git a/versioned_docs/version-0.5.6/user_docs/concepts/concepts.md b/versioned_docs/version-0.5.6/user_docs/concepts/concepts.md deleted file mode 100644 index 627212ad..00000000 --- a/versioned_docs/version-0.5.6/user_docs/concepts/concepts.md +++ /dev/null @@ -1,3 +0,0 @@ -# Concepts - -Learn more about KCL concepts. diff --git a/versioned_docs/version-0.5.6/user_docs/concepts/package-and-module.md b/versioned_docs/version-0.5.6/user_docs/concepts/package-and-module.md deleted file mode 100644 index a36e45c9..00000000 --- a/versioned_docs/version-0.5.6/user_docs/concepts/package-and-module.md +++ /dev/null @@ -1,156 +0,0 @@ -# Module and Package - -This section mainly describes how to organize files in KCL. - -## Overview - -Within a **module**, KCL organizes files grouped by **package**. A package can be defined within a module or be imported externally (through KCL package manager `kpm`). In the latter case, KCL maintains a copy of the package within the module in a dedicated location. - -## Module - -A KCL module contains a configuration laid out in a directory hierarchy. It contains everything that is needed to deterministically determine the outcome of a KCL configuration. The root of this directory is marked by containing a `kcl.mod` directory. The contents of this directory are mostly managed by the kcl tool such as `kpm`, etc. In that sense, `kcl.mod` is analogous to the `.git` directory marking the root directory of a repo, but where its contents are mostly managed by the git tool. Besides, a KCL module is the largest unit of the file organization, has a fixed location of all KCL files and dependencies. - -> Note: The use of a KCL module e.g., `kcl.mod` is optional, but required if one wants to manage, distribute, share and reuse code with a semantic version. - -### Creating a module - -A module can be created by running the following command within the module root: - -```bash -kpm init [module name] -``` - -The module name is **required** if a package within the module needs to import another package within the module. A module can also be created by setting up the `kcl.mod` file manually. - -## Package - -In KCL, a package is usually composed of a "folder" containing KCL files. This folder can be a real disk physical path, or it can be composed of multiple KCL files (usually main package). Different packages are uniquely located by different package paths (such as `kubernetes.core.v1`) - -Within the same module, different packages can be imported from each other through the import statement of relative or absolute path. During the KCL parsing process, the relative import will be replaced by absolute import and the corresponding KCL code will be found through the package path. - -### Relative Import Path - -We can use the operator `.` to realize the relative path import of KCL entry files. - -main.k: - -```python -import .model1 # Current directory module -import ..service # Parent directory -import ...root # Parent of parent directory - -s = service.ImageService {} -m = root.Schema {} -``` - -### Absolute Import Path - -The semantics of `import a.b.c.d` is - -1. If `kcl.mod` not exist, regard the current directory as the package root and search the path `a/b/c/d` from the current directory. -2. If the current directory search fails, search from the root path `ROOT_PATH/a/b/c/d`, else raise an import error. - -The definition of the root path `ROOT_PATH` is the directory corresponding to the `kcl.mod` file from the current directory. - -Code structure: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -### Builtin Package - -KCL has a collection of builtin packages such as `math`, `regex`, etc. To use a builtin package, import it directly and invoke the functions using its qualified identifier. For instance, - -```python -import regex - -image = "nginx:1.14.2" -is_match = regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$") - -``` - -The output YAML is - -```yaml -image: nginx:1.14.2 -is_match: true -``` - -### Plugin Package - - - -KCL also has a collection of plugin packages such as `hello`, `project_context`, etc. To use a plugin package, import it with a `kcl_plugin.` package path prefix and invoke the functions using its qualified identifier. For instance, - -```python -import kcl_plugin.hello - -result = hello.add(1, 1) -``` - -The output YAML is - -```yaml -result: 2 -``` - -### Main Package - -In KCL, the composition of the main package is usually determined by the compiler parameters. This is because the KCL schema and constraints can be split across files in the package, or even organized across directories, considering the convenience of writing and maintaining the configuration in isolated blocks. - -#### Files belonging to a main package - -It is up to the user to decide which configurations and constraints to use using the KCL command line. For example, - -```bash -kcl file1.k file2.k -``` - -Thus, the main package contains two KCL files named `file1.k` and `file2.k`. - -If KCL is told to load the files for a specific directory, for example: - -```bash -kcl ./path/to/package -``` - -It will only look KCL files with `.k` suffix and ignore files with `_` prefix or `_test.k` into the main package. Besides, if the `./path/to/package` contains `kcl.yaml` files, `kcl.yaml` files be ignored. - -In addition, we can set main package files through configuring the command-line compilation setting file (e.g., `kcl.yaml`) as follows: - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k -``` - -```bash -kcl -Y kcl.yaml -``` - -> Note: If we do not specify any input files for KCL, KCL will find the default `kcl.yaml` from the command line execution path to read the input file. Besides, if we tell KCL both the input files and the compilation setting file, KCL will take input files entered by the user as the final value. - -```bash -# Whether the 'files' field is configured in `kcl.yaml` or not, the final value of input files is ["file1.k", "file2.k"] -kcl -Y kcl.yaml file1.k file2.k -``` - -## The relationship and difference between `kcl.mod` and `kcl.yaml` - -First of all, in KCL, `kcl.mod` and `kcl.yaml` are both optional. The difference is that `kcl.mod` determines the root path of the package path and whether a KCL module has the requirement of distribution and reuse, and `kcl.yaml` determines the KCL file composition of the main package. - -Secondly, for a kcl module for external use only, `kcl.yaml` is optional but `kcl.mod` is required, because it needs to declare the KCL version, module version, dependency and other information. - -Finally, for the KCL IDE plug-in, it needs to know the main package information to form a complete compilation process, so it needs to automatically look up the composition of the main package according to the position of the cursor, because no one can specify this information through the KCL command line. The general query logic is to find whether `kcl.yaml` exists. If it is found, the main package consists of the `files` attribute in `kcl.yaml`, and if not found, the main package consists of the current file. The KCL IDE plug-in is selectively aware of the `kcl.mod` file. When the `kcl.mod` file exists, the IDE plug-in reads the corresponding information of all package paths and their real paths in the external dependencies. diff --git a/versioned_docs/version-0.5.6/user_docs/getting-started/_category_.json b/versioned_docs/version-0.5.6/user_docs/getting-started/_category_.json deleted file mode 100644 index 1bf165d4..00000000 --- a/versioned_docs/version-0.5.6/user_docs/getting-started/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Get Started", - "position": 1 -} diff --git a/versioned_docs/version-0.5.6/user_docs/getting-started/index.md b/versioned_docs/version-0.5.6/user_docs/getting-started/index.md deleted file mode 100644 index c50dbaa6..00000000 --- a/versioned_docs/version-0.5.6/user_docs/getting-started/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# Get Started - -Get started include a quick overview of the KCL programming language. diff --git a/versioned_docs/version-0.5.6/user_docs/getting-started/install.md b/versioned_docs/version-0.5.6/user_docs/getting-started/install.md deleted file mode 100644 index 9cb5975a..00000000 --- a/versioned_docs/version-0.5.6/user_docs/getting-started/install.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Installation - -## 1. Install KCL - -### From the Binary Releases - -Each release of KCL includes various OSes and architectures. These binary versions can be manually downloaded and installed from [Github](https://github.com/kcl-lang/kcl/releases/) or [Gitee](https://gitee.com/kusionstack/kcl/releases) and add `{install-location}/kclvm/bin` to the environment PATH. - -> ⚠️ If you cannot successfully access Github, you can also access Gitee to obtain binaries for installation. - -#### MacOS & Linux - -```bash -export PATH=$PATH:{install-location}/kclvm/bin -``` - -#### Windows - -```powershell -$env:PATH += ";{install-location}\kclvm\bin;" -``` - -### Using script to install the latest release - -#### MacOS - -Install or upgrade the latest darwin KCL to /usr/local/kclvm/bin - -```bash -curl -fsSL https://kcl-lang.io/script/install.sh | /bin/bash -``` - -#### Linux - -Install or upgrade the latest linux KCL to /usr/local/kclvm/bin - -```bash -wget -q https://kcl-lang.io/script/install.sh -O - | /bin/bash -``` - -#### Windows - -Install or upgrade the latest windows KCL to $Env:SystemDrive\kclvm\bin and add this directory to User PATH environment variable. - -```bash -powershell -Command "iwr -useb https://kcl-lang.io/script/install.ps1 | iex" -``` - -### Homebrew (MacOS) - -- Install - -```bash -brew install kcl-lang/tap/kcl -``` - -- Upgrade - -```bash -brew upgrade kcl-lang/tap/kcl -``` - -- Uninstall - -```bash -brew uninstall kcl-lang/tap/kcl -``` - -### Scoop (Windows) - -Install [Scoop](https://scoop.sh/) first, then add this bucket and install `kcl` by running: - -```bash -scoop bucket add kcl-lang https://github.com/kcl-lang/scoop-bucket.git -scoop install kcl-lang/kcl -``` - -### From Go - -Install `kcl` through the `Go` command (`Go` requires 1.18+). - -```bash -go install kcl-lang.io/kcl-go/cmds/kcl-go@main -``` - -Add an alias for the kcl command (optional). - -```bash -alias kcl='kcl-go run' -``` - -> Note: `kcl-go` does not rely on the installation of `kcl`, but if `kcl` exists in PATH, it will be used by `kcl-go` first. - -### From Docker - -- Command - -```bash -docker run --rm -it kcllang/kcl -``` - -- Update image - -```bash -docker pull kcllang/kcl -``` - -### Note - -We can execute the following command to ensure that KCL has been installed correctly. - -```bash -kcl -V -``` - -The output may looks like this: - -```bash -Version: {kcl version} -Platform: {your platform} -GitCommit: {git commit} -``` - -For all the above operating systems and installation methods, if you want to use [KCL Python Plugin](/docs/reference/plugin/overview), you need to ensure that Python 3.7+ is installed and add the python3 command to your PATH environment variable. - -## 2. Install KCL IDE Extension - -### VS Code - -The KCL Extension extension provides some coding assistance, e.g., highlight, goto definition, completion, hover, outline, and diagnostics. You can go [here](/docs/tools/Ide/vs-code) for more information about the installation. - -![Completion](/img/docs/tools/Ide/vs-code/Completion.gif) - -### NeoVim - -See [here](https://github.com/kcl-lang/kcl.nvim) to config the KCL language server and enable it. - -![kcl.nvim](/img/docs/tools/Ide/neovim/overview.png) - -### IntelliJ IDEA - -Download the distribution from [here](https://github.com/kcl-lang/intellij-kcl/releases) and in IntelliJ IDEA, click Preference -> plugins -> install Plugin from Disk... -> select kcl-idea-plugin zip -> restart IDE. This plugin requires the IntelliJ IDEA 2020.2+ - -![intellij](/img/docs/tools/Ide/intellij/overview.png) diff --git a/versioned_docs/version-0.5.6/user_docs/getting-started/intro.md b/versioned_docs/version-0.5.6/user_docs/getting-started/intro.md deleted file mode 100644 index c4515840..00000000 --- a/versioned_docs/version-0.5.6/user_docs/getting-started/intro.md +++ /dev/null @@ -1,199 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Introduction - -## What is KCL? - -[KCL](https://github.com/kcl-lang/kcl) is an open-source, constraint-based record and functional language that enhances the writing of complex configurations, including those for cloud-native scenarios. With its advanced programming language technology and practices, KCL is dedicated to promoting better modularity, scalability, and stability for configurations. It enables simpler logic writing and offers ease of automation APIs and integration with homegrown systems. - -## Why Use KCL? - -KCL expects to solve the following problems: - -- Hide infrastructure and platform details by defining more appropriate **API abstractions** to reduce the burden of developers. -- **Mutate** and **validate** existing config files or manifests. -- Manage large-scale configuration data across teams without side effects through configuration language. - - Use **production level high-performance programming language** to **write code** to improve the flexibility of configuration, such as conditional statements, loops, functions, package management and other features to improve the ability of configuration reuse. - - Improve the ability of **configuration semantic verification** at the code level, such as optional/required fields, types, ranges, and other configuration checks. - - Provide the **ability to write, combine and abstract configuration blocks**, such as structure definition, structure inheritance, constraint definition, etc. - -You can use KCL to - -- **Generate** low-level static configuration data like JSON, YAML, etc. -- Reduce boilerplate in configuration data with the **schema modeling**. -- Define transformers and constraints for configuration data and templates and **mutate/validate** them automatically. -- Organize, simplify, unify and manage large configurations scalably without side effects. -- Used as a platform engineering language to deliver modern app with [KusionStack](https://kusionstack.io/). - -In addition to the language itself, KCL also provides many additional tools, such as formatting, testing, document, package management, to help users use, understand and check the configuration or policy they write. We can reduce the cost of configuration writing and sharing through IDE extensions such as VS Code, playground and package manage tools. In addition, through KCL Rust, Go, and Python multilingual SDKs, the configuration can be automatically managed and executed. - -![](/img/docs/user_docs/intro/kcl-overview.png) - -Besides, KCL is a modern high-level domain language, which is a compiled, static and strongly typed language. It provides developers with the ability to write **configuration (config)**, **modeling abstraction (schema)**, **logic (lambda)**, and **policies (rule)** as the core elements through recording and functional language design. - -![](/img/docs/user_docs/intro/kcl-concepts.png) - -KCL tries to provide runtime-independent programmability and does not natively provide system functions such as threads and IO, but supports functions for cloud-native operation scenarios, and tries to provide stable, secure, low-noise, low-side effect, easy-to-automate and easy-to-govern programming support for solving domain problems. - -In summary, KCL has the following characteristics: - -- **Easy-to-use**: Originated from high-level languages ​​such as Python and Golang, incorporating functional language features with low side effects. -- **Well-designed**: Independent Spec-driven syntax, semantics, runtime and system modules design. -- **Quick modeling**: [Schema](https://kcl-lang.github.io/docs/reference/lang/tour#schema)-centric configuration types and modular abstraction. -- **Rich capabilities**: Configuration with type, logic and policy based on [Config](https://kcl-lang.github.io/docs/reference/lang/codelab/simple), [Schema](https://kcl-lang.github.io/docs/reference/lang/tour/#schema), [Lambda](https://kcl-lang.github.io/docs/reference/lang/tour/#function), [Rule](https://kcl-lang.github.io/docs/reference/lang/tour/#rule). -- **Stability**: Configuration stability built on [static type system](https://kcl-lang.github.io/docs/reference/lang/tour/#type-system), [constraints](https://kcl-lang.github.io/docs/reference/lang/tour/#validation), and [rules](https://kcl-lang.github.io/docs/reference/lang/tour#rule). -- **Scalability**: High scalability through [automatic merge mechanism](https://kcl-lang.github.io/docs/reference/lang/tour/#-operators-1) of isolated config blocks. -- **Fast automation**: Gradient automation scheme of [CRUD APIs](https://kcl-lang.github.io/docs/reference/lang/tour/#kcl-cli-variable-override), [multilingual SDKs](https://kcl-lang.github.io/docs/reference/xlang-api/overview), [language plugin](https://kcl-lang.github.io/docs/reference/plugin/overview) -- **High performance**: High compile time and runtime performance using Rust & C and [LLVM](https://llvm.org/), and support compilation to native code and [WASM](https://webassembly.org/). -- **API affinity**: Native support API ecological specifications such as [OpenAPI](https://kcl-lang.github.io/docs/tools/cli/openapi/), Kubernetes CRD, Kubernetes YAML spec. -- **Development friendly**: Friendly development experiences with rich [language tools](https://kcl-lang.github.io/docs/tools/cli/kcl/overview) (Format, Lint, Test, Vet, Doc, etc.) and [IDE extensions](https://kcl-lang.github.io/docs/tools/Ide/). -- **Safety & maintainable**: Domain-oriented, no system-level functions such as native threads and IO, low noise and security risk, easy maintenance and governance. -- **Rich multi-language SDK**: [Go](https://kcl-lang.io/docs/reference/xlang-api/go-api), [Python](https://kcl-lang.io/docs/reference/xlang-api/python-api), [Java](https://kcl-lang.io/docs/reference/xlang-api/java-api) and [REST APIs](https://kcl-lang.io/docs/reference/xlang-api/rest-api) meet different scenarios and application use prelude. -- **Kubernetes Integrations**: External mutation and validation plugins including [Kustomize KCL Plugin](https://github.com/kcl-lang/kustomize-kcl), [Helm KCL Plugin](https://github.com/kcl-lang/helm-kcl), [KPT KCL SDK](https://github.com/kcl-lang/kpt-kcl-sdk), [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) to separate data and logic. -- **Production-ready**: Widely used in production practice of platform engineering and automation at Ant Group. - -Although KCL is not a general language, it has corresponding application scenarios. Developers can write **config**, **schema**, **function** and **rule** through KCL, where config is used to define data, schema is used to describe the model definition of data, rule is used to validate data, and schema and rule can also be combined to use models and constraints that fully describe data, In addition, we can also use the lambda pure function in KCL to organize data code, encapsulate common code, and call it directly when needed. - -The configuration of attributes in KCL usually meets the simple pattern: - -$$ -k = (T) v -$$ - -where $k$ is the attribute name, $v$ is the attributes value, and $T$ is the type annotation. Since KCL has the ability of the type inference, $T$ is usually omitted. - -This is an example of generating kubernetes manifests. - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = name -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -We can use the KCL code to generate a Kubernetes YAML manifest. - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## How to Choose? - -Communities have been making significant efforts to improve their configuration technologies, which can be categorized into three groups: - -- Low-level data format-based tools that utilize external tools for enhancing reuse and validation, specifically for templating, patching, and validation. -- Domain-Specific Languages (DSLs) and Configuration Languages (CLs), which enhance language abilities. -- General Purpose Language (GPL)-based solutions that utilize Cloud-Development Kit (CDK) or framework to define the configuration. - -To simplify, here are some recommended options: - -- YAML/JSON/Kustomize/Helm are recommended if you need to write structured key-value pairs, or use Kubernetes native tools. -- HCL is recommended if you want to use programming language convenience to remove boilerplate with good human readability, or if you are already a Terraform user. -- CUE is recommended if you want to use type system to improve stability and maintain scalable configurations. -- KCL is recommended if you want types and modeling like a modern language, scalable configurations, in-house pure functions and rules, and production-ready performance and automation. - -### vs. YAML/JSON - -YAML/JSON configurations are suitable for small-scale configuration scenarios. However, if you require frequent modifications in large-scale cloud-native configuration scenarios, KCL is more appropriate. The primary difference between the two is the abstraction of configuration data and deployment. - -The advantages of using KCL for configuration are numerous. First, abstracting one layer for static data provides deployment flexibility, allowing various configuration environments, tenants, and runtime to have distinct requirements for static data. Additionally, different organizations may have different specifications and product requirements. By leveraging KCL, administrators can expose the most important and frequently modified configurations to users. - -### vs. Jsonnet/GCL - -GCL is a declarative configuration programming language implemented in Python, providing necessary language capabilities for template abstraction. However, the compiler itself is written in Python, and the language runs with interpretation, leading to poor performance for large template instances, such as the Kubernetes model. - -On the other hand, Jsonnet is a data template language implemented in C++/Go, suitable for application and tool developers. It can generate configuration data and organize, simplify, and manage large configurations without any side effects. - -Both Jsonnet and GCL are excellent at reducing boilerplate, using code to generate configuration, so engineers can write advanced GPL code instead of manually writing error-prone and difficult-to-understand server binary code. Despite reducing some of the complexities of GCL, Jsonnet largely falls into the same category. Both have runtime errors, insufficient type-checking and constraint capacity. - -### vs. HCL - -HCL is a configuration language implemented in Go that is structured and inspired by the syntax of libucl and nginx configurations. It is designed to be both human and machine-friendly, primarily for use in devops tools, server configurations, and resource configurations as a [Terraform language](https://www.terraform.io/language). - -The user interface of HCL is not readily apparent in the Terraform provider Schema definition and can be cumbersome when defining complex object and required/optional fields. Dynamic parameters are constrained by the condition field of the variable, and resource constraints must be defined either by the provider schema or through the use of Sentinel/Rego and other policy languages. The language itself may not be self-contained. - -### vs. CUE - -CUE can be utilized for modeling through structures without the need for inheritance or other features. This can lead to high abstraction as long as there are no conflicts with model definitions. However, since CUE performs all constraint checks at runtime, there may be performance bottlenecks in large-scale modeling scenarios. Despite this, CUE simplifies constraint writing through various syntax options, eliminating the need for generic types and enumerations. Additionally, configuration merging is supported but is completely idempotent, which may not be suitable for complex multi-tenant and multi-environment configuration scenarios. Writing complex loop and constraint scenarios can be challenging and cumbersome for accurately modifying configurations. - -On the other hand, KCL conducts modeling through the schema and achieves high model abstraction through language-level engineering and some object-oriented features, such as single inheritance. KCL is a statically compiled language with low overhead for large-scale modeling scenarios. Additionally, KCL provides a richer declarative constraint syntax, making it easier to write. Compared to CUE, KCL offers more if guard combination constraints, all/any/map/filter, and other collection constraint writing methods, which simplify configuration field combination constraints. - -### vs. Dhall - -Dhall is a functional, programmable configuration language that incorporates JSON, functions, types and imports. If you have experience with languages like Haskell, you may find Dhall familiar. KCL also offers similar functionality for programmability and abstraction, but has made greater advancements in areas such as modeling, constraint checking, automation and package management for sharing models. KCL's syntax and semantics are more aligned with object-oriented languages, making it more approachable than pure functional styles in some cases. - -### vs. Nickel - -Nickel is the cheap configuration language. Its purpose is to automate the generation of static configuration files and it is in essence JSON with functions and types. - -KCL and Nickel both have a similar gradual type system (static + dynamic), merge strategy, function and constraint definition. The difference is that KCL is a Python-like language, while Nickel is a JSON-like language. In addition, KCL provides the schema keyword to distinguish between configuration definitions and configuration data to avoid mixed use. - -### vs. Starlark - -Starlark is the language of Bazel, which is a dialect of Python. It does not have types and recursion is forbidden. - -KCL can also be regarded as a variant of Python to some extent, but it greatly enhances the design related to static typing and configuration extensibility, and is a compiled language, which is essentially different from Starlark. - -### vs. Kustomize - -The key feature of Kustomize is its ability to overlay files at a granular level. However, it faces challenges with multiple overlay chains as a specific attribute value may not be the final value, as it can be overridden by another value elsewhere. Retrieving the inheritance chain of Kustomize files can be less convenient than retrieving the inheritance chain of KCL code, particularly for complex scenarios where careful consideration of the specified configuration file overwrite order is necessary. Additionally, Kustomize does not address issues related to YAML configuration writing, constraint verification, model abstraction, and development, making it more suited for simpler configuration scenarios. - -In contrast, KCL offers fine-grained configuration merge operations for each attribute in the code, with flexible merge strategy settings that are not limited to overall resources. KCL also allows for static analysis of configuration dependencies through import statements. - -### vs. Helm - -The idea behind Helm can be traced back to the package management system used in operating systems. It is a package management tool that relies on templated YAML files to execute and manage resources within packages. - -KCL provides a greater range of capabilities than Helm, making it a viable alternative. Users who have already adopted Helm can still utilize KCL by packaging the stack compilation results in a Helm format or by using the Helm-KCL plugin to programmatically extend existing Helm charts. - -### vs. CDK - -CDK's high-level language integrates well into application projects, effectively becoming part of the client runtime. In contrast, KCL decouples external configurations and policies written using KCL from the client runtime. - -General-purpose languages can often be over-engineered, going beyond the requirements of the problem being solved. These languages can also present various security issues, such as problems with the ability boundary, such as accessing I/O, network, code infinite looping, and other security risks. In specialized fields, such as music, there are special notes used to communicate effectively, which cannot be expressed clearly in general-purpose languages. - -Furthermore, general-purpose languages come in a variety of styles, which can create challenges in terms of unified maintenance, management, and automation. These languages are generally better suited to writing the client runtime, which is a continuation of the server runtime. They are not ideal for writing configurations that are independent of the runtime, as they are compiled into binaries and started from the process, making stability and scalability challenging to control. In contrast, configuration languages are often used to write data combined with simple logic, and they describe the expected final result, which is then consumed by the compiler or engine. - -### vs. OPA/Rego - -While not originally intended as a data definition language, Rego, the language used for Open Policy Agent (OPA), can also address the issue of adding constraints from multiple sources. - -Rego has its roots in logic programming and is based on Datalog, a restricted form of Prolog. In contrast, KCL is based on a static type structure. Typed-feature structures were developed to address the limitations of Prolog in encoding human languages. Using a Datalog variant for a constraint validation task may seem unusual. Datalog excels as a query language, but it can be cumbersome for constraint enforcement, in that values must be queried before applying constraints. - -KCL's approach to constraint validation is more conducive to finding normalized and simplified representations of constraints, making it well-suited for creating structures generated from OpenAPI. diff --git a/versioned_docs/version-0.5.6/user_docs/getting-started/kcl-quick-start.md b/versioned_docs/version-0.5.6/user_docs/getting-started/kcl-quick-start.md deleted file mode 100644 index 2316d9a6..00000000 --- a/versioned_docs/version-0.5.6/user_docs/getting-started/kcl-quick-start.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Quick Start - -KCL is a cloud-native domain configuration and policy language. At the beginning of its design, KCL was inspired by Python3, and at the same time absorbed the conceptual design of declarative and OOP programming paradigms. In this section we will quickly demonstrate the basic features of the KCL language. - -## 1. Hello KCL - -The best way to learn a new language is to write a few small programs, and the same goes for configuring languages. We can write KCL programs just like writing configuration. - -Here is a simple `hello.k`: - -```python -hello = "KCL" -``` - -Set the `hello` attribute to the `"KCL"` string. Then save the code to the `hello.k` file. - -How to execute this program depends on the specific development environment, we first assume that the local macOS or Linux system has installed the `kcl` command (or enter the **Docker** environment test by `docker run --rm -it kcllang/kcl`) and then run the following command: - -```shell -kcl hello.k -``` - -The output is - -```yaml -hello: KCL -``` - -The effect of command line execution is shown as follows: - -![](/img/docs/user_docs/getting-started/hello.gif) - -The output is configuration data in YAML format. Although this program is simple, we can verify the basic usage of the development environment and the `kcl` command line by executing the KCL configuration program to the output. - -## 2. A little more complicated configuration - -In addition to the common key-value pairs, common configuration data also has nested dictionary and list types, and the value basic type includes boolean and numeric types in addition to strings. Here's a slightly more complex `server.k` configuration: - -```python -# This is a KCL document - -title = "KCL Example" - -owner = { - name = "The KCL Authors" - data = "2020-01-02T03:04:05" -} - -database = { - enabled = True - ports = [8000, 8001, 8002] - data = [["delta", "phi"], [3.14]] - temp_targets = {cpu = 79.5, case = 72.0} -} - -servers = [ - {ip = "10.0.0.1", role = "frontend"} - {ip = "10.0.0.2", role = "backend"} -] -``` - -where `#` begins with a line comment. The value of `owner` is a dictionary. The value of the dictionary contains the content in the form of `{}`. The key-value inside the dictionary is similar to the `hello = "KCL"` example. `database` is another dictionary in which the value of the dictionary attribute appears boolean `True`, list `[]` and dictionary `{}`, in which the value of the numeric type also appears in the list and dictionary. The `servers` attribute is a list with dictionaries nested inside the list (dictionaries and lists, as well as the `schema` that will be discussed later, can be nested within each other). - -The YAML output of this configuration is as follows: - -```yaml -$ kcl server.k -title: KCL Example -owner: - name: The KCL Authors - data: '2020-01-02T03:04:05' -database: - enabled: true - ports: - - 8000 - - 8001 - - 8002 - data: - - - delta - - phi - - - 3.14 - temp_targets: - cpu: 79.5 - case: 72.0 -servers: -- ip: 10.0.0.1 - role: frontend -- ip: 10.0.0.2 - role: backend -``` - -## 3. Define the structure of the configuration using KCL schema - -The KCL provides abstract support for attributes with a fixed attribute structure and default value behavior through the `schema` syntax. - -For example, the configuration of `database` in the above example is generally the default value. We can define a structure for the default configuration of the database: - -```python -schema DatabaseConfig: - enabled: bool = True - ports: [int] = [8000, 8001, 8002] - data: [[str|float]] = [["delta", "phi"], [3.14]] - temp_targets: {str: float} = {cpu = 79.5, case = 72.0} -``` - -`enabled` is a boolean type; `ports` is an integer list type; `data` is a list of lists, and the inner list elements are strings or floats; `temp_targets` is a dictionary type, and the attribute value of the dictionary is floating point type. And each attribute of `DatabaseConfig` defines a default value. - -Then pass `database = DatabaseConfig {}` to generate a structure with the same attributes as the default values. We can also modify the default value: - -```python -database = DatabaseConfig { - ports = [2020, 2021] -} -``` - -`schema DatabaseConfig` not only provides default values for attributes, but also adds type information to attributes. Therefore, if we accidentally writes the wrong attribute value type, KCL will give a friendly error prompt, such as the following example where `ports` is wrongly written as a floating point type: - -```python -database = DatabaseConfig { - ports = [1.2, 1.3] -} -``` - -When executed, an error similar to the following will be generated (the displayed file path depends on the local environment): - -```shell -kcl server.k -``` - -The output is - -```shell -error[E2G22]: TypeError - --> /path/to/server.k:8:5 - | -8 | ports = [1.2, 1.3] - | ^ expected [int], got [float(1.2)|float(1.3)] - | - - --> /path/to/server.k:3:5 - | -3 | ports: [int] = [8000, 8001, 8002] - | ^ variable is defined here, its type is [int], but got [float(1.2)|float(1.3)] - | -``` - -Similarly we can encapsulate the attributes of the `servers` section with the following code: - -```python -schema ServerConfig: - ip: str - role: "frontend" | "backend" - -servers = [ - ServerConfig {ip = "10.0.0.1", role = "frontend"} - ServerConfig {ip = "10.0.0.2", role = "backend"} -] -``` - -The attribute `ip` of `ServerConfig` is a string type, and no default value is given. We must manually add the value of the `ip` attribute when generating the `ServerConfig` type attribute, otherwise the KCL will report a missing required attribute error. The `role` attribute is a `"frontend" | "backend"` enumerated string type. - -In addition, `schema` can also combine `check`, `mixin`, optional attributes, inheritance and extension modules to achieve more complex configuration and policy data abstraction, full language details can be found at [here](/docs/reference/lang/tour). diff --git a/versioned_docs/version-0.5.6/user_docs/guides/_category_.json b/versioned_docs/version-0.5.6/user_docs/guides/_category_.json deleted file mode 100644 index 40b1340d..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "User Guide", - "position": 4 -} diff --git a/versioned_docs/version-0.5.6/user_docs/guides/_working-with-terraform/1-overview.md b/versioned_docs/version-0.5.6/user_docs/guides/_working-with-terraform/1-overview.md deleted file mode 100644 index c2ec836d..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/_working-with-terraform/1-overview.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -id: overview -sidebar_label: Overview ---- - -# Overview - -Coming Soon diff --git a/versioned_docs/version-0.5.6/user_docs/guides/_working-with-terraform/2-abstraction.md b/versioned_docs/version-0.5.6/user_docs/guides/_working-with-terraform/2-abstraction.md deleted file mode 100644 index 18a25571..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/_working-with-terraform/2-abstraction.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -id: abstraction -sidebar_label: Abstraction ---- - -# Abstract Your Terraform Modules - -Coming Soon diff --git a/versioned_docs/version-0.5.6/user_docs/guides/_working-with-terraform/3-coverter.md b/versioned_docs/version-0.5.6/user_docs/guides/_working-with-terraform/3-coverter.md deleted file mode 100644 index 1dc975bb..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/_working-with-terraform/3-coverter.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -id: converter -sidebar_label: Converter ---- - -# Convert Your Terraform Provider Schema to KCL Schema - -Coming Soon diff --git a/versioned_docs/version-0.5.6/user_docs/guides/_working-with-terraform/_category_.json b/versioned_docs/version-0.5.6/user_docs/guides/_working-with-terraform/_category_.json deleted file mode 100644 index 3e72e820..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/_working-with-terraform/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Terraform", - "position": 13 -} diff --git a/versioned_docs/version-0.5.6/user_docs/guides/abstraction.md b/versioned_docs/version-0.5.6/user_docs/guides/abstraction.md deleted file mode 100644 index cec40e2c..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/abstraction.md +++ /dev/null @@ -1,151 +0,0 @@ ---- -title: "Abstraction" -sidebar_position: 3 ---- - -## Introduction - -Abstraction refers to a simplified representation of an entity, typically used in computing. It allows for the concealment of specific details while presenting the most relevant information to the programmer. Each abstraction is tailored to suit a specific need, and can greatly enhance the usability of a given entity. In the context of KCL, abstraction can make code easier to understand and maintain, while also simplifying the user interface. - -It should be noted that code abstraction is not meant to reduce code size, but rather to improve maintainability and extendability. During the process of abstracting code, factors such as reusability, readability, and scalability should be taken into consideration, and the code should be optimized as needed. - -The values of the good abstraction - -1. Provides distinct focal points for better comprehension for specific identities, roles, and scenarios. -2. Shields lower-level details to avoid potential errors. -3. Enhances user-friendliness and automation with better portability and good APIs. - -KCL may not assess the rationality of a user's abstraction, but it offers technical solutions to facilitate the process. - -## Use KCL for Abstraction - -**Now, let's begin to abstract Docker Compose and Kubernetes models into an application config.** - -Application centric development allows developers to focus on their workload's architecture rather than the tech stack in the target environment, infrastructure or platform. We define our application once with the `App` schema and then use the KCL CLI to translate it to multiple platforms, such as `Docker Compose` or `Kubernetes` with different versions. - -`Docker Compose` is a tool for defining and running multi-container Docker applications. With Docker Compose, you can define your application's services, networks, and volumes in a single file, and then use it to start and stop your application as a single unit. Docker Compose simplifies the process of running complex, multi-container applications by handling the details of networking, storage, and other infrastructure concerns. - -`Kubernetes manifests` are YAML files that define Kubernetes objects such as Pods, Deployments, and Services. Manifests provide a declarative way to define the desired state of your application, including the number of replicas, the image to use, and the network configuration. Kubernetes uses the manifests to create and manage the resources needed to deploy and run your application. - -Here are some references to learn more about Docker Compose and Kubernetes manifests: - -- [Docker Compose documentation](https://docs.docker.com/compose/) -- [Kubernetes manifest documentation](https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/) - -The application model aims to reduce developer toil and cognitive load by only having to define a single KCL file that works across multiple platforms, and it is designed to be applied to multiple environments to reduce the amount of configuration. Now, let's learn how to do this. - -### 0. Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/abstraction -``` - -We can run the following command to show the config. - -```bash -cat main.k -``` - -The output is - -```python -import .app - -app.App { - name = "app" - containers.nginx = { - image = "nginx" - ports = [{containerPort = 80}] - } - service.ports = [{ port = 80 }] -} -``` - -In the above code, we defined a configuration using the `App` schema, where we configured an `nginx` container and configured it with an `80` service port. - -Besides, KCL allows developers to define the resources required for their applications in a declarative manner and is tied to a platform such as Docker Compose or Kubernetes manifests and allows to generate a platform-specific configuration file such as `docker-compose.yaml` or a Kubernetes `manifests.yaml` file. Next, let's generate the corresponding configuration. - -### 2. Transform the Application Config into Docker Compose Config - -If we want to transform the application config into the docker compose config, we can run the command simply: - -```shell -kcl main.k docker_compose_render.k -``` - -The output is - -```yaml -services: - app: - image: nginx - ports: - - published: 80 - target: 80 - protocol: TCP -``` - -### 3. Transform the Application Config into Kubernetes Deployment and Service Manifests - -If we want to transform the application config into the Kubernetes manifests, we can run the command simply: - -```shell -kcl main.k kubernetes_render.k -``` - -The output is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: app - labels: - app: app -spec: - replicas: 1 - selector: - matchLabels: - app: app - template: - metadata: - labels: - app: app - spec: - containers: - - name: nginx - image: nginx - ports: - - protocol: TCP - containerPort: 80 ---- -apiVersion: v1 -kind: Service -metadata: - name: app - labels: - app: app -spec: - selector: - app: app - ports: - - port: 80 - protocol: TCP -``` - -Look, it's so simple. If you want to learn more information about the application model, you can refer to [here](https://github.com/kcl-lang/kcl-lang.io/tree/main/examples/abstraction). - -## Summary - -Through the use of KCL, we are able to separate the abstraction and implementation details of a model, allowing for the abstract model to be mapped to various infrastructures or platforms. This is achieved through flexible switching between different implementations and the combination of compilation, which shields configuration differences and ultimately reduces the cognitive burden. - -## Further Information - -In addition to manually maintaining the configuration, we can also use KCL APIs to integrate **automatic configuration changes** into our applications. For specific instructions, please refer to [here](/docs/user_docs/guides/automation). diff --git a/versioned_docs/version-0.5.6/user_docs/guides/automation.md b/versioned_docs/version-0.5.6/user_docs/guides/automation.md deleted file mode 100644 index 561b3302..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/automation.md +++ /dev/null @@ -1,189 +0,0 @@ ---- -title: "Automation" -sidebar_position: 6 ---- - -## Introduction - -KCL provides many automation related capabilities, mainly including tools and multilingual APIs. Via `package_identifier : key_identifier` mode, KCL supports the indexing of any configured key value, thus completing the addition, deletion, modification and query of any key value. For example, the following figure shows that we can directly execute the following command to modify the image. The code diff before and after modification is also shown in the figure. - -![](/img/blog/2022-09-15-declarative-config-overview/14-kcl-image-update.png) - -In addition, the automation capability of KCL can be realized and integrated into CI/CD. - -![](/img/blog/2022-09-15-declarative-config-overview/15-kcl-automation.png) - -## Use KCL for Automation - -### 0. Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/automation -``` - -We can run the following command to show the config. - -```bash -cat main.k -``` - -The output is - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "app" - replicas = 1 - labels.key = "value" -} -``` - -We can run the command to get the config - -```bash -kcl main.k -``` - -The output is - -```yaml -app: - name: app - replicas: 1 - labels: - app: app - key: value -``` - -### 2. Use KCL CLI for Automation - -KCL allows us to directly modify the values in the configuration model through the KCL CLI `-O|--overrides` parameter. The parameter contains three parts e.g., `pkg`, `identifier`, `attribute` and `override_value`. - -```bash -kcl main.k -O override_spec -``` - -- `override_spec` represents a unified representation of the configuration model fields and values that need to be modified - -```bash -override_spec: [[pkgpath] ":"] identifier ("=" value | "-") -``` - -- `pkgpath`: indicates the package path where the identifier needs to be modified, usually in the form of `a.b.c`. For the main package,`pkgpath` is represented as `__ main__`. When omitted or not written, it indicates the main package -- `identifier` indicates the identifier that needs to modify the configuration, usually in the form of `a.b.c`. -- `value` indicates the value of the configuration that needs to be modified, which can be any legal KCL expression, such as number/string literal value, list/dict/schema expression, etc. -- `=` denotes modifying of the value of the identifier. -- `-` denotes deleting of the identifier. - -#### Override Configuration - -Run the command to update the application name. - -```bash -kcl main.k -O app.name='new_app' -``` - -The output is - -```yaml -app: - name: new_app - replicas: 1 - labels: - app: new_app - key: value -``` - -We can see the `name` attribute of the `app` config is updated to `new_app`. - -Besides, when we use KCL CLI `-d` argument, the KCL file will be modified to the following content at the same time. - -```bash -kcl main.k -O app.name='new_app' -d -``` - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "new_app" - replicas = 1 - labels: {key = "value"} -} -``` - -#### Delete Configuration - -Run the command to delete the `key` attribute of `labels`. - -```bash -kcl main.k -O app.labels.key- -``` - -The output is - -```yaml -app: - name: app - replicas: 1 - labels: - app: app -``` - -### 3. Use KCL API for Automation - -In addition, we can automatically modify the configuration attributes through the [multilingual API](/docs/reference/xlang-api/overview). - -Take the RestAPI as an example. The RestAPI service can be started in the following way: - -```bash -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -The service can then be requested via the POST protocol: - -```bash -curl -X POST http://127.0.0.1:2021/api:protorpc/KclvmService.OverrideFile -H 'content-type: accept/json' -d '{ - "file": "main.k", - "specs": ["app.name=\"nginx\""] -}' -``` - -After the service call is completed, main.k will be modified as follows: - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "nginx" - replicas = 1 - labels: { - "key" = "value" - } -} -``` - -## Summary - -The document introduces the automation capabilities of KCL, including tools and multilingual APIs. It supports indexing of any configured key value, allowing for the addition, deletion, modification, and querying of any key value. It can also be integrated into CI/CD. The document provides an example of using KCL to automate configuration management, including using the KCL CLI to override and delete configurations, and using the KCL API to modify configuration attributes. For more information about KCL automation and Override API, please refer to [here](/docs/reference/lang/tour#kcl-cli-variable-override). diff --git a/versioned_docs/version-0.5.6/user_docs/guides/ci-integration/1-github-actions.md b/versioned_docs/version-0.5.6/user_docs/guides/ci-integration/1-github-actions.md deleted file mode 100644 index c4a09c6e..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/ci-integration/1-github-actions.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -id: github-actions -sidebar_label: Github Actions ---- - -# Github Actions Integration - -## Introduction - -In the GitOps section, we have introduced how to integrate KCL with GitOps. In this section, we will continue to provide sample solutions for KCL and CI integrations. We hope to implement the end-to-end application development process by using containers, Continuous Integration (CI) for generation, and GitOps for Continuous Deployment (CD). In this scheme, we use a **Flask application** and **Github Actions** as examples. - -> Note: You can use any containerized application and different CI systems such as **Gitlab CI**, **Jenkins CI**, etc. in this solution. - -The overall workflow is as follows: - -- Develop application code and submit it to the GitHub repository to trigger CI. -- GitHub Actions generate container images from application code and push them to the `docker.io` container registry. -- GitHub Actions automatically synchronizes and updates the KCL manifest deployment file based on the version of the container image in the docker.io container registry. - -## Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -## How to - -### 1. Get the Example - -We put the application source code and infrastructure deployment code in different repos, which can be maintained by different roles to achieve the separation of concerns. - -- Get the application code - -```shell -git clone https://github.com/kcl-lang/flask-demo.git/ -cd flask-demo -``` - -This is a web application written in Python. We can use the `Dockerfile` in the application directory to generate a container image of this application, and also use Github CI to automatically build a image named `flask_demo`, the CI configuration is as follows - -```yaml -# This is a basic workflow to help you get started with Actions - -name: CI - -# Controls when the workflow will run -on: - # Triggers the workflow on push or pull request events but only for the main branch - push: - branches: [main] - pull_request: - branches: [main] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "build" - build: - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - - - name: Docker Login - uses: docker/login-action@v1.10.0 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - logout: true - - # Runs a set of commands using the runners shell - - name: build image - run: | - make image - docker tag flask_demo:latest ${{ secrets.DOCKER_USERNAME }}/flask_demo:${{ github.sha }} - docker push ${{ secrets.DOCKER_USERNAME }}/flask_demo:${{ github.sha }} - - # Trigger KCL manifest - - name: Trigger CI - uses: InformaticsMatters/trigger-ci-action@1.0.1 - with: - ci-owner: kcl-lang - ci-repository: flask-demo-kcl-manifests - ci-ref: refs/heads/main - ci-user: kcl-bot - ci-user-token: ${{ secrets.DEPLOY_ACCESS_TOKEN }} - ci-name: CI - ci-inputs: >- - image=${{ secrets.DOCKER_USERNAME }}/flask_demo - sha-tag=${{ github.sha }} -``` - -We need the workflow in the source code repository to automatically trigger the workflow in the deployment manifest repository. At this point, we need to create a `secrets.DEPLOY_ACCESS_TOKEN` with Github CI operation permissions and **Docker Hub** image push account information `secrets.DOCKER_USERNAME` and `secrets.DOCKER_PASSWORD` can be configured in the `Secrets and variables` settings of the Github, as shown in the following figure - -![](/img/docs/user_docs/guides/ci-integration/github-secrets.png) - -### 2. Commit the Application Code - -After submitting in the `flask-demo` repository, Github will automatically build a container image and push it to the Docker hub. It will also then trigger the Action of the `flask-demo-kcl-manifest` repository and modify the image value in the deployment manifest repository through [KCL Automation API](/docs/user_docs/guides/automation). Now let's create a submission in the `flask-demo` repository, and we can see that the code submission triggers the Github CI process for the application repository. - -![](/img/docs/user_docs/guides/ci-integration/app-ci.png) - -### 3. Configuration Automatic Update - -After the Github CI process in the application repository is completed, an automatic update configuration CI will be triggered in the repository where the KCL configuration is stored and submitted to the main branch of the `flask-demo-kcl-manifests` repository. The commit information is as follows - -![](/img/docs/user_docs/guides/ci-integration/image-auto-update.png) - -- We can obtain the deployment manifest source code for compilation and validation - -```shell -git clone https://github.com/kcl-lang/flask-demo-kcl-manifests.git/ -cd flask-demo-kcl-manifests -git checkout main && git pull && kcl -``` - -The output YAML is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - replicas: 1 - selector: - matchLabels: - app: flask_demo - template: - metadata: - labels: - app: flask_demo - spec: - containers: - - name: flask_demo - image: "kcllang/flask_demo:6428cff4309afc8c1c40ad180bb9cfd82546be3e" - ports: - - protocol: TCP - containerPort: 5000 ---- -apiVersion: v1 -kind: Service -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - type: NodePort - selector: - app: flask_demo - ports: - - port: 5000 - protocol: TCP - targetPort: 5000 -``` - -From the above configuration, it can be seen that the image of the resource is indeed automatically updated to the newly constructed image value. In addition, we can also use the **Argo CD KCL plugin** to automatically synchronize data from the Git repository and deploy the application to the Kubernetes cluster. - -## Summary - -By integrating KCL and Github CI, we can integrate the container build and delivery workflow by automatically updating the image values in the configuration, in order to achieve end-to-end application development process and improve R&D deployment efficiency. diff --git a/versioned_docs/version-0.5.6/user_docs/guides/ci-integration/2-gitlab-ci.md b/versioned_docs/version-0.5.6/user_docs/guides/ci-integration/2-gitlab-ci.md deleted file mode 100644 index 124e9bd9..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/ci-integration/2-gitlab-ci.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -id: gitlab-ci -sidebar_label: Gitlab CI ---- - -# Gitlab CI Integration - -## Introduction - -In the GitOps section, we have introduced how to integrate KCL with GitOps. In this section, we will continue to provide sample solutions for KCL and CI integrations. We hope to implement the end-to-end application development process by using containers, Continuous Integration (CI) for generation, and GitOps for Continuous Deployment (CD). In this scheme, we use a **Flask application** and **Gitlab CI** as examples. - -> Note: You can use any containerized application and different CI systems such as **Github Actions**, **Jenkins CI**, etc. in this solution. - -The overall workflow is as follows: - -- Develop application code and submit it to the Gitlab repository to trigger CI. -- Gitlab generate container images from application code and push them to the `docker.io` container registry. -- Gitlab CI automatically synchronizes and updates the KCL manifest deployment file based on the version of the container image in the docker.io container registry. - -## Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -## How to - -We put the application source code and infrastructure deployment code in different repos, which can be maintained by different roles to achieve the separation of concerns. - -### 1. Get the Example - -- Get the application code - -```shell -git clone https://gitlab.com/kcl-lang/flask-demo.git/ -cd flask-demo -``` - -This is a web application written in Python. We can use the `Dockerfile` in the application directory to generate a container image of this application, and also use Gitlab CI to automatically build a image named `flask_demo`, the CI configuration is as follows - -```yaml -stages: - - publish - - deploy - -publish: - stage: publish - image: - name: cnych/kaniko-executor:v0.22.0 - entrypoint: [""] - script: - - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json - - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile ./Dockerfile --destination $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA - only: - - main - -deploy: - stage: deploy - image: cnych/kustomize:v1.0 - before_script: - - git remote set-url origin https://gitlab.com/kcl-lang/flask-demo - - git config --global user.email "gitlab@git.local" - - git config --global user.name "GitLab CI/CD" - # Install KCL - - wget -q https://kcl-lang.io/script/install.sh -O - | /bin/bash - script: - - git checkout -B main - - cd deployment - # Image auto update - - /usr/local/kclvm/bin/kcl -d -O config.containers.flask_demo.image="$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" - - git commit -am '[skip ci] image update to $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA' - - git push origin main - only: - - main -``` - -We need the workflow in the source code repository to automatically trigger the workflow in the deployment manifest repository. At this point, we need to config `Settings -> CI/CD -> Variables` including `CI_REGISTRY`, `CI_REGISTRY_IMAGE`, `CI_REGISTRY_USER`, `CI_REGISTRY_PASSWORD`, `CI_USERNAME` and `CI_PASSWORD` and update application code to trigger automation build and deploy. - -![](/img/docs/user_docs/guides/ci-integration/gitlab-ci-variables.jpg) - -### 2. Commit the Application Code - -After submitting in the `flask-demo` repository, Gitlab will automatically build a container image and push it to the Docker hub. It will also then trigger the Action of the `flask-demo-kcl-manifest` repository and modify the image value in the deployment manifest repository through [KCL Automation API](/docs/user_docs/guides/automation). Now let's create a submission in the `flask-demo` repository, and we can see that the code submission triggers the Gitlab CI process for the application repository `Build -> Pipelines` page. - -### 3. Configuration Automatic Update - -After the Gitlab CI process in the application repository is completed, an automatic update configuration CI will be triggered in the repository where the KCL configuration is stored and submitted to the main branch of the `flask-demo` repository. - -- We can obtain the deployment manifest source code for compilation and validation - -```shell -git checkout main && git pull && cd deploy && kcl -``` - -The output YAML is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - replicas: 1 - selector: - matchLabels: - app: flask_demo - template: - metadata: - labels: - app: flask_demo - spec: - containers: - - name: flask_demo - image: "kcllang/flask_demo:6428cff4309afc8c1c40ad180bb9cfd82546be3e" - ports: - - protocol: TCP - containerPort: 5000 ---- -apiVersion: v1 -kind: Service -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - type: NodePort - selector: - app: flask_demo - ports: - - port: 5000 - protocol: TCP - targetPort: 5000 -``` - -From the above configuration, it can be seen that the image of the resource is indeed automatically updated to the newly constructed image value. In addition, we can also use the **Argo CD KCL plugin** to automatically synchronize data from the Git repository and deploy the application to the Kubernetes cluster. - -## Summary - -By integrating KCL and Gitlab CI, we can integrate the container build and delivery workflow by automatically updating the image values in the configuration, in order to achieve end-to-end application development process and improve R&D deployment efficiency. diff --git a/versioned_docs/version-0.5.6/user_docs/guides/ci-integration/_3-jenkins-ci.md b/versioned_docs/version-0.5.6/user_docs/guides/ci-integration/_3-jenkins-ci.md deleted file mode 100644 index f85d231f..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/ci-integration/_3-jenkins-ci.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -id: github-ci -sidebar_label: Github CI ---- - -Coming Soon - -## Introduction - -## How to - -## Summary diff --git a/versioned_docs/version-0.5.6/user_docs/guides/ci-integration/_category_.json b/versioned_docs/version-0.5.6/user_docs/guides/ci-integration/_category_.json deleted file mode 100644 index 3145ed7f..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/ci-integration/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "CI Integration", - "position": 12 -} \ No newline at end of file diff --git a/versioned_docs/version-0.5.6/user_docs/guides/configuration.md b/versioned_docs/version-0.5.6/user_docs/guides/configuration.md deleted file mode 100644 index e6060815..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/configuration.md +++ /dev/null @@ -1,129 +0,0 @@ ---- -title: "Configuration" -sidebar_position: 1 ---- - -## Introduction - -Configuration is a vital aspect of software systems that are constantly in flux due to evolving business requirements, infrastructure demands, and other factors. Often, changing these systems' behavior quickly can be challenging, especially when doing so requires a costly and time-consuming reconstruction and redeployment process. In such cases, making changes to the business code may not be sufficient. Fortunately, the configuration provides a low-overhead way to modify system functions. For instance, many developers write JSON or YAML files to configure their systems. - -We can store the static configuration in JSON and YAML files as needed. Moreover, the configuration can also be stored in a high-level language that allows for more flexible configuration. This language can be coded, rendered, and statically configured. KCL is a configuration language that offers such functionality. Developers can write KCL code to generate JSON/YAML and other configurations. - -## Use KCL for Configuration - -KCL's core features are its modeling and constraint capabilities, and its basic functions revolve around these two key elements. Additionally, KCL follows a user-centric configuration concept when designing its basic functions. Configuration code has requirements for configuration data constraints, such as type constraints and required/optional constraints on configuration attributes, range constraints, and immutability constraints. These are also some of the core issues that KCL is committed to resolving. - -Now that we have an understanding of KCL's capabilities, let's explore how to use it to generate configurations. - -### 0. Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. Get the Example - -Firstly, let's get the example. - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/configuration -``` - -We can run the following command to show the config. - -```bash -cat nginx.k -``` - -The output is - -```python -schema Nginx: - """Schema for Nginx configuration files""" - http: Http - -schema Http: - server: Server - -schema Server: - listen: int | str # The attribute `listen` can be int type or a string type. - location?: Location # Optional, but must be non-empty when specified - -schema Location: - root: str - index: str - -nginx = Nginx { - http.server = { - listen = 80 - location = { - root = "/var/www/html" - index = "index.html" - } - } -} -``` - -### 2. Generate YAML using KCL - -Run the following command - -```bash -kcl nginx.k -``` - -We can get the output YAML - -```yaml -nginx: - http: - server: - listen: 80 - location: - root: /var/www/html - index: index.html -``` - -### 3. Configuration with Dynamic Parameters - -Besides, we can dynamically receive external parameters through the KCL builtin function `option`. For example, for the following KCL file (db.k), we can use the KCL command line `-D` flag to receive an external dynamic parameter. - -```python -env: str = option("env") or "dev" # The attribute `env` has a default value "den" -database: str = option("database") -hosts = { - dev = "postgres.dev" - stage = "postgres.stage" - prod = "postgres.prod" -} -dbConfig = { - host = hosts[env] - database = database - port = "2023" - conn = "postgres://${host}:${port}/${database}" -} -``` - -```bash -# Use the `-D` flag to input external parameters. -kcl db.k -D database="foo" -``` - -The output is - -```yaml -env: dev -database: foo -hosts: - dev: postgres.dev - stage: postgres.stage - prod: postgres.prod -dbConfig: - host: postgres.dev - database: foo - port: "2023" - conn: "postgres://postgres.dev:2023/foo" -``` - -## Summary - -By using KCL, we can generate low-level data configurations. For different situations, we set dynamic parameters through the `-D` flag to meet the scene requirements. For more KCL features, please refer to [here](/docs/reference/lang/tour). diff --git a/versioned_docs/version-0.5.6/user_docs/guides/data-integration.md b/versioned_docs/version-0.5.6/user_docs/guides/data-integration.md deleted file mode 100644 index c05b2e7b..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/data-integration.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: "Data Integration" -sidebar_position: 4 ---- - -## Introduction - -In KCL, we can not only compile and output the configuration code written by KCL into YAML format data, but also directly embed JSON/YAML and other data into the KCL language. - -## Use KCL for Data Integration - -### 0. Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/data-integration -``` - -### 2. YAML Integration - -We can run the following command to show the YAML integration config. - -```bash -cat yaml.k -``` - -```python -import yaml - -schema Server: - ports: [int] - -server: Server = yaml.decode("""\ -ports: -- 80 -- 8080 -""") -server_yaml = yaml.encode({ - ports = [80, 8080] -}) -``` - -In the above code, we use the built-in `yaml` module of KCL and its `yaml.decode` function directly integrates YAML data, and uses the `Server` schema to directly verify the integrated YAML data. In addition, we can use `yaml.encode` to serialize YAML data. We can obtain the configuration output through the following command: - -```shell -kcl yaml.k -``` - -The output is - -```yaml -server: - ports: - - 80 - - 8080 -server_yaml: | - ports: - - 80 - - 8080 -``` - -### 3. JSON Integration - -Similarly, for JSON data, we can use `json.encode` and `json.decode` function performs data integration in the same way. - -We can run the following command to show the JSON integration config. - -```bash -cat json.k -``` - -```python -import json - -schema Server: - ports: [int] - -server: Server = json.decode('{"ports": [80, 8080]}') -server_json = json.encode({ - ports = [80, 8080] -}) -``` - -The output of the execution command is: - -```shell -kcl json.k -``` - -```yaml -server: - ports: - - 80 - - 8080 -server_json: '{"ports": [80, 8080]}' -``` - -## Summary - -This document introduces how to perform data integration in KCL, using the built-in yaml and json modules to directly integrate YAML and JSON data into the KCL language, and verify and serialize it using the corresponding decoding and encoding functions. diff --git a/versioned_docs/version-0.5.6/user_docs/guides/gitops/1-quick-start.md b/versioned_docs/version-0.5.6/user_docs/guides/gitops/1-quick-start.md deleted file mode 100644 index 04570df1..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/gitops/1-quick-start.md +++ /dev/null @@ -1,163 +0,0 @@ ---- -id: gitops-quick-start -sidebar_label: Quick Start ---- - -# Quick Start - -## Introduction - -### What is GitOps - -GitOps is a modern way to do continuous delivery. Its core idea is to have a Git repository which contains environmental and application configurations. An automated process is also needed for sync the config to cluster. - -By changing the files in repository, developers can apply the applications automatically. The benefits of applying GitOps include: - -- Increased productivity. Continuous delivery can speed up the time of deployment. -- Lower the barrier for developer to deploy. By pushing code instead of container configuration, developers can easily deploy Kubernetes without knowing its internal implementation. -- Trace the change records. Managing the cluster with Git makes every change traceable, enhancing the audit trail. -- Recover the cluster with Git's rollback and branch. - -### GitOps with KCL - -Benefits of Using KCL and ArgoCD Together: - -- KCL can help us **simplify complex Kubernetes deployment configuration files**, reduce the error rate of manually writing YAML files, and improve code readability and maintainability. -- ArgoCD can **automate** the deployment of Kubernetes applications, achieve continuous deployment, and provide comprehensive monitoring and control functions. -- By combining KCL and ArgoCD, deployment efficiency can be improved, errors reduced, and management and monitoring of Kubernetes applications strengthened. -- The combination of KCL and ArgoCD can also help us achieve **Infrastructure as Code (IaC)**, simplify application deployment and management, and better implement DevOps principles. - -With GitOps, developer and operation teams can manage application deployment and configuration by modifying KCL code and generating YAML files. The GitOps toolchain will automatically synchronize the changes to the Kubernetes cluster, enabling continuous deployment and ensuring consistency. If there are issues, the GitOps toolchain can be used to quickly rollback. - -## Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -## How to - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/gitops -``` - -We can run the following command to show the config. - -```bash -cat config/main.k -``` - -The output is - -```python -import .app - -config = app.App { - name = "kcl-guestbook-ui" - containers.guestbook = { - image = "gcr.io/heptio-images/ks-guestbook-demo:0.2" - ports = [{containerPort = 80}] - } - service.ports = [{ port = 80 }] - service.type = "LoadBalancer" -} -``` - -In the above code, we defined a configuration using the `App` schema, where we configured an `gcr.io/heptio-images/ks-guestbook-demo:0.2` container and configured it with an `80` service port. - -### 2. Install Kubernetes and GitOps Tool - -#### Setup Kubernetes Cluster and ArgoCD Controllers - -- Install [K3d](https://github.com/k3d-io/k3d) to create a default cluster. - -```bash -k3d cluster create mycluster -``` - -- Install [ArgoCD](https://github.com/argoproj/argo-cd/releases/). - -```bash -kubectl create namespace argocd -kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml -``` - -- Enable ArgoCD KCL Plugin - -Write the patch YAML configuration file and update the ArgoCD configuration: - -```bash -kubectl apply -f ./install/kcl-cmp.yaml -``` - -After completing the first step, ArgoCD will recognize the KCL plugin, but the KCL plugin has not been loaded into the ArgoCD image. To implement configuration drift detection, we have to tune the Deployment of argocd-repo-server. - -```bash -kubectl -n argocd patch deploy/argocd-repo-server -p "$(cat ./install/patch-argocd-repo-server.yaml)" -``` - -Wait for the init container to complete execution (Running). - -```bash -kubectl get pod -n argocd -l app.kubernetes.io/name=argocd-repo-server -``` - -- To access the ArgoCD web UI - -```bash -kubectl port-forward svc/argocd-server -n argocd 8080:443 -``` - -- Open a browser and go to: `https://localhost:8080` - -- The username is "admin" and password get be obtained from the following command: - -```bash -kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d -``` - -#### Setup ArgoCD CLI - -- Install [ArgoCD CLI](https://github.com/argoproj/argo-cd/releases) - -Use "admin" and password to login to ArgoCD - -```bash -argocd login localhost:8080 -``` - -Create ArgoCD Application - -```bash -argocd app create guestbook \ ---repo https://github.com/kcl-lang/kcl-lang.io \ ---path examples/gitops/config \ ---dest-namespace default \ ---dest-server https://kubernetes.default.svc \ ---config-management-plugin kcl-v1.0 -``` - -If you are using a private repository, you need to configure the private repository access with private key credentials before executing the create command. - -Please refer [Private Repositories](https://argo-cd.readthedocs.io/en/stable/user-guide/private-repositories/#ssh-private-key-credential) for more details. - -After successfully creating, you can see the following output: - -```bash -application 'guestbook' created -``` - -Through the ArgoCD UI, you can see that the created applications have not been synchronized yet. Here, you can manually synchronize or set automatic synchronization. - -![](/img/docs/user_docs/guides/gitops/argocd-kcl-app.jpg) - -For more information on synchronization strategies, see [Sync Options](https://argo-cd.readthedocs.io/en/stable/user-guide/sync-options/) - -![](/img/docs/user_docs/guides/gitops/argocd-kcl-app-dashboard.jpg) - -## Summary - -With GitOps, you can easily manage your applications and configuration in your Kubernetes cluster with KCL, ensuring that your applications are always in the desired state. diff --git a/versioned_docs/version-0.5.6/user_docs/guides/gitops/_category_.json b/versioned_docs/version-0.5.6/user_docs/guides/gitops/_category_.json deleted file mode 100644 index 29a73c67..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/gitops/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "GitOps", - "position": 11 -} \ No newline at end of file diff --git a/versioned_docs/version-0.5.6/user_docs/guides/index.md b/versioned_docs/version-0.5.6/user_docs/guides/index.md deleted file mode 100644 index cd3d4522..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/index.md +++ /dev/null @@ -1 +0,0 @@ -# User Guide diff --git a/versioned_docs/version-0.5.6/user_docs/guides/package-management/1-overview.md b/versioned_docs/version-0.5.6/user_docs/guides/package-management/1-overview.md deleted file mode 100644 index cffccc67..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/package-management/1-overview.md +++ /dev/null @@ -1,3 +0,0 @@ -# Overview - -KCL manages packages through the package management tool [kpm](https://github.com/kcl-lang/kpm). diff --git a/versioned_docs/version-0.5.6/user_docs/guides/package-management/2-installation.md b/versioned_docs/version-0.5.6/user_docs/guides/package-management/2-installation.md deleted file mode 100644 index 11d1da5d..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/package-management/2-installation.md +++ /dev/null @@ -1,55 +0,0 @@ -# Installation - -## Install `kpm` - -Before installing and using kpm, ensure that KCL has been installed successfully. - -[How to install KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### Go install - -You can download kpm via go install. - -```shell -go install kcl-lang.io/kpm@latest -``` - -### Download from GITHUB release page - -You can get `kpm` from the [kpm github release](https://github.com/kcl-lang/kpm/releases) and set the `kpm` binary path to the environment variable PATH. - -```shell -# KPM_INSTALLATION_PATH is the path of the `kpm` binary. -export PATH=$KPM_INSTALLATION_PATH:$PATH -``` - -Use the following command to ensure that you install `kpm` successfully. - -```shell -kpm --help -``` - -If you get the following output, you have successfully installed `kpm` and you can proceed to the following steps. - -```shell -NAME: - kpm - kpm is a kcl package manager - -USAGE: - kpm [arguments]... - -COMMANDS: - init initialize new module in current directory - add add new dependency - pkg package a kcl package into tar - metadata output the resolved dependencies of a package - run compile kcl package. - login login to a registry - logout logout from a registry - push push kcl package to OCI registry. - pull pull kcl package from OCI registry. - help, h Shows a list of commands or help for one command - -GLOBAL OPTIONS: - --help, -h show help -``` diff --git a/versioned_docs/version-0.5.6/user_docs/guides/package-management/3-quick-start.md b/versioned_docs/version-0.5.6/user_docs/guides/package-management/3-quick-start.md deleted file mode 100644 index 689e9530..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/package-management/3-quick-start.md +++ /dev/null @@ -1,112 +0,0 @@ -# Quick Start - -## 0. Prerequisite - -- Install [kpm](https://kcl-lang.io/docs/user_docs/guides/package-management/installation) - -## 1. Init an Empty KCL Package - -Create a new kcl package named `my_package`. And after we have created the package `my_package`, we need to go inside the package by `cd my_package` to complete the following operations. - -```shell -kpm init my_package && cd my_package -``` - -![kpm_init](/img/docs/user_docs/guides/package-management/gifs/kpm_init.gif) - -`kpm` will create two kcl package configuration files: `kcl.mod` and `kcl.mod.lock` in the directory where you executed the command. - -```shell -- my_package - |- kcl.mod - |- kcl.mod.lock - |- # You can write your kcl program directly in this directory. -``` - -`kcl.mod.lock` is the file generated by `kpm` to fix the dependency version. Do not modify this file manually. - -`kpm` initializes `kcl.mod` for an empty project as shown below: - -```shell -[package] -name = "my_package" -edition = "0.0.1" -version = "0.0.1" -``` - -## 2. Add a Dependency from OCI Registry - -You can then add a dependency to the current kcl package using the `kpm add` command - -As shown below, taking the example of adding a package dependency named `k8s`, the version of the package is `1.27.2`. - -```shell -kpm add k8s:1.27.2 -``` - -![kpm_add_k8s](/img/docs/user_docs/guides/package-management/gifs/kpm_add_k8s.gif) - -You can see that `kpm` adds the dependency you just added to kcl.mod. - -```shell -[package] -name = "my_package" -edition = "0.0.1" -version = "0.0.1" - -[dependencies] -k8s = "1.27.2" # The dependency 'k8s' with version '1.27.2' -``` - -### Write a kcl program that uses the content in `k8s` - -Create the `main.k` file in the current package. - -```shell -- my_package - |- kcl.mod - |- kcl.mod.lock - |- main.k # Your KCL program. -``` - -And write the following into the `main.k` file. - -```kcl -# Import and use the contents of the external dependency 'k8s'. -import k8s.api.core.v1 as k8core - -k8core.Pod { - metadata.name = "web-app" - spec.containers = [{ - name = "main-container" - image = "nginx" - ports = [{containerPort = 80}] - }] -} - -``` - -## 3. Run the KCL Code - -In the `my_package` directory, you can use `kpm` to compile the `main.k` file you just wrote. - -```shell -kpm run -``` - -The output is - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: web-app -spec: - containers: - - image: nginx - name: main-container - ports: - - containerPort: 80 -``` - -![kpm_run](/img/docs/user_docs/guides/package-management/gifs/kpm_run.gif) diff --git a/versioned_docs/version-0.5.6/user_docs/guides/package-management/_category_.json b/versioned_docs/version-0.5.6/user_docs/guides/package-management/_category_.json deleted file mode 100644 index 1211443e..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/package-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Package Management Tools", - "position": 7 -} diff --git a/versioned_docs/version-0.5.6/user_docs/guides/schema-definition.md b/versioned_docs/version-0.5.6/user_docs/guides/schema-definition.md deleted file mode 100644 index ecb118ac..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/schema-definition.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -title: "Schema Definition" -sidebar_position: 3 ---- - -## Introduction - -The core scenario of KCL is write configurations and constraints. and a core feature of KCL is **modeling**. The keyword `schema` in KCL can be used to define structures and constraints, such as attribute types, default values, range check, and various other constraints. In addition, structures defined with KCL schema can be used in turn to verify implementation, validate input (JSON, YAML and other structured data) or generate code (multilingual structures, OpenAPI, and so on). - -## Use KCL for Defining Structures and Constraints - -### 0. Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/definition -``` - -We can run the following command to show the config. - -```bash -cat main.k -``` - -The output is - -```python -import .app_module # A relative path import - -app: app_module.App { - domainType = "Standard" - containerPort = 80 - volumes = [ - { - mountPath = "/tmp" - } - ] - services = [ - { - clusterIP = "None" - $type = "ClusterIP" - } - ] -} -``` - -We put the `app` model into a separate `app_module.k`, then we can use the `import` keyword in `main.k` for modular management, such as the following file structure - -``` -. -├── app_module.k -└── main.k -``` - -The content of `app_module.k` is - -```python -schema App: - domainType: "Standard" | "Customized" | "Global" - containerPort: int - volumes: [Volume] - services: [Service] - - check: - 1 <= containerPort <= 65535 - -schema Service: - clusterIP: str - $type: str - - check: - clusterIP == "None" if $type == "ClusterIP" - -schema Volume: - container: str = "*" # The default value of `container` is "*" - mountPath: str - - check: - mountPath not in ["/", "/boot", "/home", "dev", "/etc", "/root"] -``` - -In the above file, we use the `schema` keyword to define three models `App`, `Service` and `Volume`. The `App` model has four attributes `domainType`, `containerPort`, `volumes` and `services`, where - -- The type of `domainType` is a string literal union type, similar to an "enumeration", which means that the value of `domainType` can only take one of `"Standard"`, `"Customized"` and `"Global"`. -- The type of `containerPort` is an integer (`int`). In addition, we use the `check` keyword to define its value range from 1 to 65535. -- The type of `services` is `Service` schema list type, and we use `?` to mark it as an optional attribute. -- The type of `volumes` is a `Volume` schema list type, and we use `?` to mark it as an optional attribute. - -We can get the YAML output of the `app` instance by using the following command line - -```shell -kcl main.k -``` - -The output is - -```yaml -app: - domainType: Standard - containerPort: 80 - volumes: - - container: "*" - mountPath: /tmp - services: - - clusterIP: None - type: ClusterIP -``` - -### 2. Output Configuration - -We can still get the YAML output of the `app` instance by using the following command line - -```shell -kcl main.k -``` - -The output is - -```yaml -app: - domainType: Standard - containerPort: 80 - volumes: - - container: "*" - mountPath: /tmp - services: - - clusterIP: None - type: ClusterIP -``` - -## Summary - -KCL is a language for defining configurations and constraints, with a core feature of modeling using the schema keyword. This allows for the definition of structures with attributes, default values, range checks, and other constraints. Structures defined using KCL schema can be used to validate data, or generate code. The example demonstrates how to define models using schema, import them for modular management, and output the YAML configuration of an instance of the defined structure using the kcl command. diff --git a/versioned_docs/version-0.5.6/user_docs/guides/secret-management/1-vault.md b/versioned_docs/version-0.5.6/user_docs/guides/secret-management/1-vault.md deleted file mode 100644 index 6da58286..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/secret-management/1-vault.md +++ /dev/null @@ -1,142 +0,0 @@ ---- -id: vault -sidebar_label: Vault ---- - -# Vault - -## Introduction - -This guide will show you that KCL solves the secret management problem by integrating [Vault](https://developer.hashicorp.com/vault) and [Vals](https://github.com/helmfile/vals). - -## Prerequisites - -- Install [KCL](/docs/user_docs/getting-started/install) -- Prepare a [Kubernetes Cluster](https://kubernetes.io/) -- Install [Vault](https://developer.hashicorp.com/vault/downloads) -- Install [Vals](https://github.com/helmfile/vals) - -## How to - -### 1. Get the Example - -We put the application source code and infrastructure deployment code in different repos, which can be maintained by different roles to achieve the separation of concerns. - -- Get the application code - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/secret-management/vault -``` - -- Show the config - -```shell -cat main.k -``` - -The output is - -```python -# Secret Management using Vault and Vals - -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" - annotations: { - "secret-store": "vault" - # Valid format: - # "ref+vault://PATH/TO/KV_BACKEND#/KEY" - "foo": "ref+vault://secret/foo#/foo" - "bar": "ref+vault://secret/bar#/bar" - } -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -The main.k file extends the configuration of the Nginx application and customizes annotations. Among them, the value of annotation `foo` and `bar` follow secret reference format (`ref+vault://PATH/TO/KV_BACKEND#/KEY`): - -- `ref+vault`: indicates that this is a secret reference, and the external storage service is `Vault`. -- `PATH/TO/KV_BACKEND`: specifies the path where a secret is stored. -- `KEY`: specifies the key to reading secret. - -The complete format is concatenated using a style similar to URI expressions, which can retrieve a secret stored externally. - -### 2. Pre-store Secrets - -Start the Vault Server - -```shell -vault server -dev -export VAULT_ADDR='http://127.0.0.1:8200' -# Note: Replace with your token -export VAULT_TOKEN=yourtoken -``` - -After Vault is started in development mode and unpacked, secrets are pre-stored, and the path and keys are consistent with `main.k`: - -```shell -vault kv put secret/foo foo=foo -vault kv put secret/bar bar=bar -``` - -### 3. Deploy Configuration - -Using the following command to apply the deployment manifest. - -```shell -kcl main.k | vals eval -f - | kubectl apply -f - -``` - -The expect output is - -```shell -deployment.apps/nginx created -``` - -### 4. Verify Secrets - -Next, verify that the secrets have been retrieved from Vault and replace the values of annotations of Nginx: - -- Verify the `foo` annotation - -```shell -kubectl get deploy nginx -o yaml | grep 'foo:' -``` - -The output is - -```yaml -foo: foo -``` - -- Verify the `bar` annotation - -```shell -kubectl get deploy nginx -o yaml | grep 'bar:' -``` - -The output is - -```yaml -bar: bar -``` - -So far, we have retrieved the secrets hosted in `Vault` and put them into use. - -## Summary - -This guide introduces how KCL solves the secret management by integrating Vault and Vals. By following these steps, we can retrieve the secrets hosted in Vault and utilize them. diff --git a/versioned_docs/version-0.5.6/user_docs/guides/secret-management/_category_.json b/versioned_docs/version-0.5.6/user_docs/guides/secret-management/_category_.json deleted file mode 100644 index c57bb30e..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/secret-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Secret Management", - "position": 13 -} diff --git a/versioned_docs/version-0.5.6/user_docs/guides/validation.md b/versioned_docs/version-0.5.6/user_docs/guides/validation.md deleted file mode 100644 index f589d7fa..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/validation.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: "Validation" -sidebar_position: 2 ---- - -## Introduction - -Validation is the process of verifying that data is accurate, reliable, and meets certain requirements or constraints. This includes checking the data for completeness, consistency, accuracy, and relevance. Data validation is performed to ensure that the data is fit for its intended purpose and that it can be used effectively and efficiently. - -We can use KCL and its vet tools to manually or automatically perform data validation to ensure data consistency. - -## Use KCL for Validation - -In addition to using KCL code to generate configuration formats such as JSON/YAML, KCL also supports format validation of JSON/YAML data. As a configuration language, KCL covers almost all features of [OpenAPI](https://www.openapis.org/). - -In KCL, a structure definition can be used to validate configuration data. At the same time, it supports user-defined constraint rules through the check block, and writes validation expressions in the schema to check and validate the attributes defined by the schema. It is very clear and simple to check whether the input JSON/YAML satisfies the corresponding schema structure definition and constraints. - -### 0. Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. Get the Example - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/validation -``` - -We can run the following command to show the config. - -```bash -cat schema.k -``` - -```python -schema User: - name: str - age: int - message?: str - data: Data - labels: {str:} - hc: [int] - - check: - age > 10, "age must > 10" - -schema Data: - id: int - value: str -``` - -In the schema, we can use the `check` keyword to write the validation rules of every schema attribute. Each line in the check block corresponds to a conditional expression. When the condition is satisfied, the validation is successful. The conditional expression can be followed by `, "check error message"` to indicate the message to be displayed when the check fails. - -To sum up, the validation kinds supported in KCL schema are: - -| Kind | Method | -| ----------------- | ----------------------------------------------------------------------------------------- | -| Range | Using comparison operators such as `<`, `>` | -| Regex | Using methods such as `match` from the `regex` system module | -| Length | Using the `len` built-in function to get the length of a variable of type `list/dict/str` | -| Enum | Using literal union types | -| Optional/Required | Using optional/required attributes of schema | -| Condition | Using the check if conditional expression | - -### 2. Validate the Data - -There is a JSON format file `data.json`: - -```json -{ - "name": "Alice", - "age": 18, - "message": "This is Alice", - "data": { - "id": 1, - "value": "value1" - }, - "labels": { - "key": "value" - }, - "hc": [1, 2, 3] -} -``` - -Execute the following command: - -```bash -kcl-vet data.json schema.k -``` - -## Summary - -KCL is a configuration language that supports data validation through its structure definition and user-defined constraint rules. Validation kinds supported in KCL schema include range, regex, length, enum, optional/required, and condition. To validate data, a schema is defined with validation rules written using the check keyword, and the data is validated using the validation tool or a visualization product built on top of it. - -## Further Information - -The improvement of KCL validation capabilities will gradually focus on the "static" aspect, that is, at compile time, combined with the ability of formal validation, it can directly analyze whether the data meets the constraints, whether the constraints conflict with each other, etc., and can be exposed in real-time through the IDE. - -We also expect that KCL models and constraints can be managed as a package (this package has only KCL files). For example, the Kubernetes models and constraints can be used out of the box. Users can generate configurations or verify existing configurations, and can simply extend the models and constraints users want through KCL inheritance. diff --git a/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md b/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md deleted file mode 100644 index ac20cd12..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: "Adopt From Kubernetes" -sidebar_position: 1 ---- - -## Introduction - -KCL provides many out of the box support for Kubernetes configuration. Through KCL tools, we can integrate Kubernetes Schema and configuration into KCL. This section will introduce how to use KCL to integrate Kubernetes. - -## Prerequisite - -- Install kcl-openapi - -## Quick Start - -### 1. Kubernetes OpenAPI Spec - -Starting from Kubernetes 1.4, the alpha support for the OpenAPI specification (known as Swagger 2.0 before it was donated to the OpenAPI Initiative) was introduced, and the API descriptions follow the [OpenAPI Spec 2.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md). And since Kubernetes 1.5, Kubernetes supports [directly extracting models from source code and then generating the OpenAPI spec file](https://github.com/kubernetes/kube-openapi) to automatically keep the specifications and documents up to date with the operation and models. - -In addition, Kubernetes CRD uses [OpenAPI V3.0 validation](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation) to describe a custom schema (in addition to the built-in attributes apiVersion, Kind, and metadata), that APIServer uses to validate the CR during the resource creation and update phases. - -### 2. KCL OpenAPI Support - -The `kcl-openapi` tool supports extracting and generating KCL schemas from Kubernetes OpenAPI/CRD. the [KCL OpenAPI Spec](/docs/tools/cli/openapi/spec) defines the mapping between the OpenAPI specification and the KCL language features. - -### 3. Migrate From Kubernetes To KCL - -#### 3.1 Write configurations based on the Kusion_Models package - -``We provide an out-of-the-box `kusion_models` package for you to quickly start. It contains a well-designed frontend model called [`Server schema`](https://github.com/KusionStack/konfig/blob/main/base/pkg/kusion_models/kube/frontend/server.k). You can declare the configurations by initializing the `Server schema`. For the description and usage of the schema and its attributes, please refer to the [Server schema documentation](https://kusionstack.io/docs/reference/model/kusion_models/kube/frontend/doc_server).`` - -#### 3.2 Build Your Custom Frontend Models - -The existing KCL Models may not meet your specific business requirements, then you can also design your custom frontend model package. You can design your custom models based on the pre-generated Kubernetes KCL models among all versions. - -##### 3.2.1 Get the k8s package - -The [Kubernetes KCL models](https://github.com/orgs/KusionStack/packages/container/package/k8s) among all versions are pre-generated, you get it by executing `kpm add k8s:` under your project. For detailed information about kpm usage, please refer to [kpm quick start guide](https://github.com/kcl-lang/kpm#quick-start). - -Alternatively, if you may want to generate them yourself, please refer to [Generate KCL Packages from Kubernetes OpenAPI Specs](https://github.com/kcl-lang/kcl-openapi/blob/main/docs/generate_from_k8s_spec.md). - -##### 3.2.2 Design Custom Frontend Models - -Since the Kubernetes built-in models are atomistic and kind of complex to beginners, we recommend taking the native model of Kubernetes as the backend output model and designing a batch of frontend models which could become a more abstract, friendlier and simpler interface to the user. You can refer to the design pattern in the [`Server Schema in the Konfig repo`](https://github.com/KusionStack/konfig/blob/main/base/pkg/kusion_models/kube/frontend/server.k). - -##### 3.2.3 Migrate The Configuration Data - -You can develop your custom scripts to migrate your configuration data automatically. KCL will later provide writing scaffolding and writing guidelines for this script. - -### 4. Migrate From Kubernetes CRD - -If you developed CRDs, you can generate the KCL version of the CRD schemas and declare CRs based on that. - -- Generate KCL Schema from CRD - - ``` - kcl-openapi generate model --crd --skip-validation -f - ``` - -- Define CR based on CRDs in KCL - - You can initialize the CRD schema to define a CR, or further, you can use the generated schema as a backend model and design a frontend interface for users to initialize. The practice is similar to what `KCL Models` does on Kubernetes built-in models. - -## Summary - -This section provides a quick start guide for using KCL with OpenAPI and Custom Resource Definitions (CRD). KCL also supports OpenAPI through the `kcl-openapi tool`, which maps OpenAPI specifications to KCL language features. diff --git a/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md b/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md deleted file mode 100644 index ea65e2f1..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md +++ /dev/null @@ -1,249 +0,0 @@ ---- -title: "Generate Kubernetes Manifests" -sidebar_position: 2 ---- - -## Introduction - -When we manage the Kubernetes resources, we often maintain it by hand, or use Helm and Kustomize tools to maintain our YAML configurations or configuration templates, and then apply the resources to the cluster through kubectl tools. However, as a "YAML engineer", maintaining YAML configuration every day is undoubtedly trivial and boring, and prone to errors. For example as follows: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: ... # Omit -spec: - selector: - matchlabels: - cell: RZ00A - replicas: 2 - template: - metadata: ... # Omit - spec: - tolerations: - - effect: NoSchedules - key: is-over-quota - operator: Equal - value: 'true' - containers: - - name: test-app - image: images.example/app:v1 # Wrong ident - resources: - limits: - cpu: 2 # Wrong type. The type of cpu should be str - memory: 4Gi - # Field missing: ephemeral-storage - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: is-over-quota - operator: In - values: - - 'true' -``` - -- The structured data in YAML is untyped and lacks validation methods, so the validity of all data cannot be checked immediately. -- YAML has poor programming ability. It is easy to write incorrect indents and has no common code organization methods such as logical judgment. It is easy to write a large number of repeated configurations and difficult to maintain. -- The design of Kubernetes is complex, and it is difficult for users to understand all the details, such as the `toleration` and `affinity` fields in the above configuration. If users do not understand the scheduling logic, it may be wrongly omitted or superfluous added. - -Therefore, KCL expects to solve the following problems in Kubernetes YAML resource management: - -- Use **production level high-performance programming language** to **write code** to improve the flexibility of configuration, such as conditional statements, loops, functions, package management and other features to improve the ability of configuration reuse. -- Improve the ability of **configuration semantic verification** at the code level, such as optional/required fields, types, ranges, and other configuration checks. -- Provide **the ability to write, combine and abstract configuration blocks**, such as structure definition, structure inheritance, constraint definition, etc. - -## Prerequisite - -First, you can visit the [KCL Quick Start](/docs/user_docs/getting-started/kcl-quick-start) to download and install KCL according to the instructions, and then prepare a [Kubernetes](https://kubernetes.io/) environment. - -## Quick Start - -### 1. Generate Kubernetes Resource - -We can write the following KCL code and name it `main.k`. KCL is inspired by Python. Its basic syntax is very close to Python, which is easy to learn. The configuration mode is simple, `k [: T] = v`, where `k` denotes the configured attribute name, `v` denotes the configured attribute value and `: T` denotes an optional type annotation. - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -In the above KCL code, we declare the `apiVersion`, `kind`, `metadata`, `spec` and other variables of a Kubernetes `Deployment` resource, and assign the corresponding contents respectively. In particular, we will assign `metadata.labels` fields are reused in `spec.selector.matchLabels` and `spec.template.metadata.labels` field. It can be seen that, compared with YAML, the data structure defined by KCL is more compact, and configuration reuse can be realized by defining local variables. - -We can get a Kubernetes YAML file by executing the following command line - -```bash -kcl main.k -``` - -The output is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -Of course, we can use KCL together with kubectl and other tools. Let's execute the following commands and see the result: - -```shell -kcl main.k | kubectl apply -f - -``` - -The output is - -```shell -deployment.apps/nginx-deployment configured -``` - -It can be seen from the command line that it is completely consistent with the deployment experience of using YAML configuration and kubectl application directly. - -Check the deployment status through kubectl - -```shell -kubectl get deploy -``` - -The output is - -```shell -NAME READY UP-TO-DATE AVAILABLE AGE -nginx-deployment 3/3 3 3 15s -``` - -### 2. Write Code to Manage Kubernetes resources - -When publishing Kubernetes resources, we often encounter scenarios where configuration parameters need to be dynamically specified. For example, different environments need to set different `image` field values to generate resources in different environments. For this scenario, we can dynamically receive external parameters through KCL conditional statements and `option` functions. Based on the above example, we can adjust the configuration parameters according to different environments. For example, for the following code, we wrote a conditional statement and entered a dynamic parameter named `env`. - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" if option("env") == "prod" else "${metadata.name}:latest" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -Use the KCL command line `-D` flag to receive an external dynamic parameter: - -```bash -kcl main.k -D env=prod -``` - -The output is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -The `image=metadata.name+": 1.14.2" if option ("env")=="prod" else metadata.name + ": latest"` in the above code snippet means that when the value of the dynamic parameter `env` is set to `prod`, the value of the image field is `nginx: 1.14.2`; otherwise, it is' nginx: latest'. Therefore, we can set env to different values as required to obtain Kubernetes resources with different contents. - -KCL also supports maintaining the dynamic parameters of the option function in the configuration file, such as writing the `kcl.yaml` file. - -```yaml -kcl_options: - - key: env - value: prod -``` - -The same YAML output can be obtained by using the following command line to simplify the input process of KCL dynamic parameters. - -```bash -kcl main.k -Y kcl.yaml -``` - -The output is: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## Summary - -KCL can be used to generate and manage Kubernetes resources, addressing the limitations of managing YAML configurations, such as a lack of validation methods and poor programming capabilities. It can also dynamically receive external parameters through conditional statements and option functions, allowing configuration parameters to be adjusted according to different environments. In addition, KCL can be used in conjunction with other tools such as kubectl to apply configuration to the cluster. diff --git a/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md b/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md deleted file mode 100644 index 17918b29..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: "Kubectl KCL Plugin" -sidebar_position: 1 ---- - -## Introduction - -[Kubectl](https://kubernetes.io/docs/reference/kubectl/) is a command line tool for communicating with a Kubernetes cluster's control plane, using the Kubernetes API. You can use the `Kubectl-KCL-Plugin` to - -- Edit the YAML configuration in a hook way to separate data and logic for the Kubernetes manifests management. -- For multi-environment and multi-tenant scenarios, you can maintain these configurations gracefully rather than simply copy and paste. -- Validate all KRM resources using the KCL schema. - -## Prerequisites - -- Install [Kubectl](https://github.com/kubernetes/kubectl) -- Install [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=krm-kcl` only to `Deployment` resources in the helm chart. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/kubectl-kcl.git/ -cd ./kubectl-kcl/examples/ -``` - -### 2. Test and Run - -Run the KCL code via the `Kubectl KCL Plugin`. - -```bash -kubectl kcl run -f ./kcl-run.yaml -``` - -The output yaml is - -```yaml -apiVersion: config.kubernetes.io/v1 -kind: ResourceList -items: - - apiVersion: apps/v1 - kind: Deployment - metadata: - annotations: - managed-by: krm-kcl - labels: - app: nginx - name: nginx-deployment - spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - image: "nginx:1.14.2" - name: nginx - ports: - - containerPort: 80 - - apiVersion: v1 - kind: Service - metadata: - name: test - spec: - ports: - - port: 80 - protocol: TCP - targetPort: 9376 - selector: - app: MyApp -functionConfig: - # kcl-fn-config.yaml - apiVersion: krm.kcl.dev/v1alpha1 - kind: KCLRun - metadata: - # EDIT THE SOURCE! - # This should be your KCL code which preloads the `ResourceList` to `option("resource_list") - spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "krm-kcl"}} for resource in option("resource_list").items] -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) diff --git a/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md b/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md deleted file mode 100644 index 01897f37..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: "Helm KCL Plugin" -sidebar_position: 2 ---- - -## Introduction - -[Helm](https://github.com/helm/helm) is a tool for managing Charts. Charts are packages of pre-configured Kubernetes resources. You can use the `Helm-KCL-Plugin` to - -- Edit the helm charts in a hook way to separate data and logic for the Kubernetes manifests management. -- For multi-environment and multi-tenant scenarios, you can maintain these configurations gracefully rather than simply copy and paste. -- Validate all KRM resources using the KCL schema. - -## Prerequisites - -- Install [Helm](https://github.com/helm/helm) -- Install [Helm KCL Plugin](https://github.com/kcl-lang/helm-kcl) - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=helm-kcl-plugin` only to `Deployment` resources in the helm chart. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/helm-kcl.git/ -cd ./helm-kcl/examples/workload-charts-with-kcl -``` - -### 2. Test and Run - -Run the KCL code via the `Helm KCL Plugin`. - -```bash -helm kcl template --file ./kcl-run.yaml -``` - -The output yaml is - -```yaml -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: workload - app.kubernetes.io/version: 0.1.0 - helm.sh/chart: workload-0.1.0 - name: workload -spec: - ports: - - name: www - port: 80 - protocol: TCP - targetPort: 80 - selector: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - type: ClusterIP ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: workload - app.kubernetes.io/version: 0.1.0 - helm.sh/chart: workload-0.1.0 - name: workload - annotations: - managed-by: helm-kcl-plugin -spec: - selector: - matchLabels: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - template: - metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - spec: - containers: - - image: nginx:alpine - name: frontend -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Helm KCL Plugin](https://github.com/kcl-lang/helm-kcl) diff --git a/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md b/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md deleted file mode 100644 index ae0c7a07..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: "Kustomize KCL Plugin" -sidebar_position: 3 ---- - -## Introduction - -[Kustomize](https://github.com/kubernetes-sigs/kustomize) lets you customize raw, template-free YAML files for multiple purposes, leaving the original YAML untouched and usable as is. - -KCL can be used to create functions to mutate and/or validate the YAML Kubernetes Resource Model (KRM) input/output format, and we provide Kustomize KCL functions to simplify the function authoring process. - -## Prerequisites - -- Install [kustomize](https://github.com/kubernetes-sigs/kustomize) -- Install [Docker](https://www.docker.com/) - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=kustomize-kcl` only to Deployment resources. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/kustomize-kcl.git -cd ./kustomize-kcl/examples/set-annotation/ -``` - -### 2. Test and Run - -```bash -kustomize fn run ./local-resource/ --dry-run -``` - -The output YAML is - -```yaml -apiVersion: krm.kcl.dev/v1alpha1 -kind: KCLRun -metadata: - name: set-annotation - annotations: - config.kubernetes.io/function: | - container: - image: docker.io/kcllang/kustomize-kcl:v0.2.0 - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml -# EDIT THE SOURCE! -# This should be your KCL code which preloads the `ResourceList` to `option("resource_list") -spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "kustomize-kcl"}} for resource in option("resource_list").items] ---- -apiVersion: v1 -kind: Service -metadata: - name: test - annotations: - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml -spec: - selector: - app: MyApp - ports: - - protocol: TCP - port: 80 - targetPort: 9376 ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx - annotations: - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml - managed-by: kustomize-kcl -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Kustomize KCL Plugin](https://github.com/kcl-lang/kustomize-kcl) diff --git a/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md b/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md deleted file mode 100644 index 3a029bdd..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: "KPT KCL SDK" -sidebar_position: 4 ---- - -## Introduction - -[kpt](https://github.com/GoogleContainerTools/kpt) is a package-centric toolchain that enables a configuration authoring, automation, and delivery experience, which simplifies managing Kubernetes platforms and KRM-driven infrastructure (e.g., Config Connector, Crossplane) at scale by manipulating declarative Configuration as Data for automating Kubernetes configuration editing including transforming and validating. - -KCL can be used to create functions to transform and/or validate the YAML Kubernetes Resource Model (KRM) input/output format, but we provide KPT KCL SDKs to simplify the function authoring process. - -## Prerequisites - -- Install [kpt](https://github.com/GoogleContainerTools/kpt) -- Install [Docker](https://www.docker.com/) - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=kpt` only to Deployment resources. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/kpt-kcl-sdk.git/ -cd ./kpt-kcl-sdk/get-started/set-annotation -``` - -### 2. Show the KRM - -```bash -kpt pkg tree -``` - -The output is - -```bash -set-annotation -├── [kcl-fn-config.yaml] KCLRun set-annotation -└── data - ├── [resources.yaml] Deployment nginx-deployment - └── [resources.yaml] Service test -``` - -### 3. Show and Update the KCL `FunctionConfig` - -```bash -cat ./kcl-fn-config.yaml -``` - -The output is - -```yaml -# kcl-fn-config.yaml -apiVersion: krm.kcl.dev/v1alpha1 -kind: KCLRun -metadata: # kpt-merge: /set-annotation - name: set-annotation -spec: - # EDIT THE SOURCE! - # This should be your KCL code which preloads the `ResourceList` to `option("resource_list")` - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "kpt"}} for resource in option("resource_list").items] -``` - -### 4. Test and Run - -Run the KCL code via kpt - -```bash -kpt fn eval ./data -i docker.io/kcllang/kpt-kcl:v0.2.0 --fn-config kcl-fn-config.yaml - -# Verify that the annotation is added to the `Deployment` resource and the other resource `Service` -# does not have this annotation. -cat ./data/resources.yaml | grep annotations -A1 -B0 -``` - -The output is - -```bash - annotations: - managed-by: kpt -``` - -It can be seen that we have indeed added the annotation `managed-by=kpt`. - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [KPT KCL SDK](https://github.com/kcl-lang/kpt-kcl-sdk) diff --git a/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md b/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md deleted file mode 100644 index 03d34ec8..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: "Helmfile KCL Plugin" -sidebar_position: 5 ---- - -## Introduction - -[Helmfile](https://github.com/helmfile/helmfile) is a declarative spec for deploying helm charts. It lets you... - -- Keep a directory of chart value files and maintain changes in version control. -- Apply CI/CD to configuration changes. -- Periodically sync to avoid skew in environments. - -KCL can be used to create functions to mutate and/or validate the YAML Kubernetes Resource Model (KRM) input/output format, and we provide Kustomize KCL functions to simplify the function authoring process. - -## Prerequisites - -- Install [helmfile](https://github.com/helmfile/helmfile) -- Prepare a Kubernetes cluster - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=helmfile-kcl` only to Deployment resources. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/helmfile-kcl.git -cd ./helmfile-kcl/examples/hello-world/ -``` - -We can execute the command to show config - -```bash -cat helmfile.yaml -``` - -The output is - -```yaml -repositories: - - name: prometheus-community - url: https://prometheus-community.github.io/helm-charts - -releases: - - name: prom-norbac-ubuntu - namespace: prometheus - chart: prometheus-community/prometheus - set: - - name: rbac.create - value: false - transformers: - # Use KCL Plugin to mutate or validate Kubernetes manifests. - - apiVersion: krm.kcl.dev/v1alpha1 - kind: KCLRun - metadata: - name: "set-annotation" - annotations: - config.kubernetes.io/function: | - container: - image: docker.io/kcllang/kustomize-kcl:v0.2.0 - spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "helmfile-kcl"}} for resource in option("resource_list").items] -``` - -In the above config, we use a `KCLRun` plugin to assign the `transfomer` field. This means that we will add annotations to all deployment resources in the prometheus helm chart. - -### 2. Test and Run - -Firstly, init the helmfile tool. - -```bash -helmfile init -``` - -The output may looks like this: - -```bash -The helm plugin helm-git is not installed, do you need to install it [y/n]: y -Install helm plugin helm-git -Installed plugin: helm-git - -helmfile initialization completed! -... -``` - -Then apply the configuration. - -```bash -helmfile apply -``` - -The output is - -```bash -Adding repo prometheus-community https://prometheus-community.github.io/helm-charts -"prometheus-community" has been added to your repositories - -... -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [KRM KCL Spec](https://github.com/kcl-lang/krm-kcl) diff --git a/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json b/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json deleted file mode 100644 index 6e90c03c..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Mutate or Validate Kubernetes Manifests", - "position": 3 -} diff --git a/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/_category_.json b/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/_category_.json deleted file mode 100644 index 42681f2b..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Kubernetes", - "position": 9 -} diff --git a/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/index.md b/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/index.md deleted file mode 100644 index 8d6340de..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/index.md +++ /dev/null @@ -1 +0,0 @@ -# Kubernetes diff --git a/versioned_docs/version-0.5.6/user_docs/guides/working-with-konfig/1-overview.md b/versioned_docs/version-0.5.6/user_docs/guides/working-with-konfig/1-overview.md deleted file mode 100644 index aca119a1..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/working-with-konfig/1-overview.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -id: overview -sidebar_label: Overview ---- - -# Konfig Overview - -In KCL, it is recommended to uniformly manage all configurations and model libraries in the way of **configuration library**, that is, to store not only KCL definitions of the abstract model itself, but also various types of configurations, such as application operation and maintenance configuration, policy, etc. The configuration is recommended to be hosted in various VCS systems to facilitate configuration rollback and drift check. The best practice code of the configuration repository is Konfig, and the repository is hosted in [Github](https://github.com/KusionStack/konfig)。 - -⚡ The Konfig repository mainly includes: - -- KCL module declaration file (kcl.mod) -- KCL domain model libraries (Kubernetes, Prometheus, etc.) -- Directories of various configurations (application operation and maintenance configuration, etc) -- Configuration build and test scripts (Makefile, Github CI file, etc.) - -The reason for using a unified warehouse to manage all KCL configuration codes is that different code packages have different R&D entities, which will lead to package management and version management problems. When the business configuration code and basic configuration code are stored in a unified warehouse, the version dependency management between codes will be relatively simple. By locating the directory and file of the unique code base, the configuration code can be managed uniformly for easy search, modification and maintenance. - -The following is the architecture of Konfig: - -![](/img/docs/user_docs/guides/konfig/konfig-arch.png) - -Konfig provides users with an out-of-the-box and highly abstract configuration interface. The original simple starting point of the model library is to improve the efficiency and experience of Kubernetes YAML users. We hope to simplify the writing of user-side configuration code by abstracting and encapsulating the model with more complex code into a unified model. Konfig consists of the following parts: - -- **Core model**: - - **Front-end model**: The front-end model is the "user interface", which contains all configurable attributes exposed to users on the platform side. Some repetitive and deducible configurations are omitted, and essential attributes are abstracted and exposed to users. It has user-friendly features, such as `server.k`. - - **Back-end model**: The back-end model is "model implementation", which is the model that makes the properties of the front-end model effective. It mainly contains the rendering logic of the front-end model instance. The back-end model can use KCL to write validation, logic judgment, code fragment reuse and other code to improve the reusability and robustness of the configuration code, and is not sensitive to users, such as `server_backend.k`. -- **Domain model**: It is a model that does not contain any implementation logic and abstraction. It is often generated by tool transformation and does not need to be modified. It corresponds to the real effective YAML attribute one by one. The domain model needs to be further abstracted and is generally not directly used by users. For example, `kusion_kubernetes` is the domain model library of Kubernetes scenarios. - -In addition, the core model simplifies the configuration code of front-end users through two layers of abstraction: the front-end model and the back-end model. The domain model is automatically generated through the KCL OpenAPI. diff --git a/versioned_docs/version-0.5.6/user_docs/guides/working-with-konfig/2-structure.md b/versioned_docs/version-0.5.6/user_docs/guides/working-with-konfig/2-structure.md deleted file mode 100644 index 64e74b1d..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/working-with-konfig/2-structure.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -id: structure -sidebar_label: Structure ---- - -# Konfig Structure - -This article mainly explains the directory and code structure of the Konfig repository. - -## Overview - -```bash -. -├── .github # CI Scripts -├── Makefile # Building and testing scripts -├── README.md # Documents -├── appops # Application configuration. This folder is used to place KCL operation and maintenance configuration of all applications -│ ├── clickhouse-operator -│ ├── code-city -│ ├── guestbook -│ ├── http-echo -│ └── nginx-example -├── base # Models -│ ├── examples # Examples -│ │ ├── monitoring # Monitoring example -│ │ ├── native # Kubernetes resource example -│ │ ├── provider # Basic resource configuration example such as Terraform resource -│ │ └── server # Server example. -│ └── pkg -│ ├── kusion_kubernetes # Kubernetes domain models -│ ├── kusion_models # Core models -│ ├── kusion_prometheus # Prometheus domain models -│ └── kusion_provider # Basic resource models such as Terraform resource -└── kcl.mod # The KCL module declaration file -``` - -## Core Model - -The core model library is generally named `kusion_models`, mainly including front-end model, back-end model, renderer, etc. The directory structure is: - -```bash -├── commons # Common models -├── kube # Cloud-native resource core models -│ ├── backend # Back-end models -│ ├── frontend # Front-end models -│ │ ├── common # Common front-end models -│ │ ├── configmap # ConfigMap -│ │ ├── container # Container -│ │ ├── ingress # Ingress -│ │ ├── resource # Resource -│ │ ├── secret # Secret -│ │ ├── service # Service -│ │ ├── sidecar # Sidecar -│ │ ├── strategy # strategy -│ │ ├── volume # Volume -│ │ └── server.k # The `Server` model -│ ├── metadata # Kubernetes metadata -│ ├── mixins # Mixin -│ ├── render # Front-to-back-end renderers. -│ ├── templates # Data template -│ └── utils -└── metadata # Common metadata -``` - -## Project and Stack - -![](/img/docs/user_docs/concepts/project-stack.png) - -Project and Stack are logical isolation concepts used to organize the Konfig. - -### Project - -Any folder that contains the file `project.yaml` will be regarded as a Project, and the `project.yaml` is used to describe the metadata of this Project like `name` and `tenant`. Projects must have clear business semantics and must belong to a tenant. Users can map an application or an operation scenario to a Project. - -### Stack - -Like Project, any folder that contains the file `stack.yaml` will be regarded as a Stack and `stack.yaml` is used to describe the metadata of this Stack. Stack is a set of `.k` files that represents the smallest operation unit that can be configured and deployed individually. It tends to represent different stages in the CI/CD process, such as dev, gray, prod, etc. - -### Relationship between Project and Stack - -A Project contains one or more Stacks, and a Stack must belong to and can only belong to one Project. Users can interpret the meaning of Project and Stack according to their own needs and flexibly organize the Konfig structure. We provide the following example as a best practice according to our experiences: - -```bash -appops/nginx-example -├── README.md # Project readme -├── base # common configurations for all stacks -│ └── base.k -├── dev # dev stack -│ ├── ci-test # CI test configs -│ │ ├── settings.yaml # test data -│ │ └── stdout.golden.yaml # expected test result -│ ├── kcl.yaml # kcl config -│ ├── main.k -│ └── stack.yaml # Stack metadata -└── project.yaml # Project metadata -``` - -The Project represents an application and Stack represents different environments of this application, such as dev, pre, prod, etc. Common configurations can be stored in a `base` directory under this Project. diff --git a/versioned_docs/version-0.5.6/user_docs/guides/working-with-konfig/3-quick-start.md b/versioned_docs/version-0.5.6/user_docs/guides/working-with-konfig/3-quick-start.md deleted file mode 100644 index 82fa6f36..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/working-with-konfig/3-quick-start.md +++ /dev/null @@ -1,198 +0,0 @@ ---- -id: guide -sidebar_label: Quick Start ---- - -# Introduction - -This guide shows you how to use the KCL language and CLIs to complete the deployment of an application running in Kubernetes. We call the abstraction of application operation and maintenance configuration as `Server`, and its instance as `Application`. It is essentially an operation and maintenance model defined by KCL. - -In actual production, the application online generally needs to update several k8s resources: - -- Namespace -- Deployment -- Service - -This guide requires you to have a basic understanding of Kubernetes. If you are not familiar with the relevant concepts, please refer to the links below: - -- [Learn Kubernetes Basics](https://kubernetes.io/docs/tutorials/kubernetes-basics/) -- [Namespace](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/) -- [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) -- [Service](https://kubernetes.io/docs/concepts/services-networking/service/) - -## Prerequisites - -Before we start, we need to complete the following steps: - -1. Install KCL - See [Download and Install](/docs/user_docs/getting-started/install) for more details. - -2. Clone the [Konfig repo](https://github.com/KusionStack/konfig.git) - -```shell -git clone https://github.com/KusionStack/konfig.git && cd konfig -``` - -## Quick Start - -### 1. Compiling - -The programming language of the project is KCL, not JSON/YAML which Kubernetes recognizes, so it needs to be compiled to get the final output. - -Enter stack dir `appops/nginx-example/dev` and compile: - -```bash -cd appops/nginx-example/dev && kcl -Y kcl.yaml -D __konfig_output_format__=raw -``` - -The output YAML is: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-exampledev - namespace: nginx-example -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - template: - metadata: - labels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - spec: - containers: - - image: nginx:1.7.8 - name: main - ports: - - containerPort: 80 - protocol: TCP - resources: - limits: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi - requests: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi ---- -apiVersion: v1 -kind: Namespace -metadata: - name: nginx-example ---- -apiVersion: v1 -kind: Service -metadata: - name: nginx-example - namespace: nginx-example -spec: - ports: - - nodePort: 30201 - port: 80 - targetPort: 80 - selector: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - type: NodePort -``` - -After compiling, we can see three resources: - -- A `Deployment` with the name `nginx-exampledev` -- A `Namespace` with the name `nginx-example` -- A `Service` with the name `nginx-example` - -The above completes the configuration and takes effect. Later, we can use the command `kubectl apply` to apply and check the actual status of resources. This guide will not elaborate. - -### 2. Modification - -The `image` attribute in the `Server` model is used to declare the application's container image. We can modify the `image` value in `base/main.k` to modify or upgrade the image: - -```diff -14c14 -< image = "nginx:1.7.8" ---- -> image = "nginx:latest" -``` - -Recompile the configuration code to obtain the modified YAML output: - -```shell -kcl -Y kcl.yaml -D __konfig_output_format__=raw -``` - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-exampledev - namespace: nginx-example -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - template: - metadata: - labels: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - spec: - containers: - - image: nginx:latest - name: main - ports: - - containerPort: 80 - protocol: TCP - resources: - limits: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi - requests: - cpu: 100m - memory: 100Mi - ephemeral-storage: 1Gi ---- -apiVersion: v1 -kind: Namespace -metadata: - name: nginx-example ---- -apiVersion: v1 -kind: Service -metadata: - name: nginx-example - namespace: nginx-example -spec: - ports: - - nodePort: 30201 - port: 80 - targetPort: 80 - selector: - app.kubernetes.io/name: nginx-example - app.kubernetes.io/env: dev - app.kubernetes.io/instance: nginx-example-dev - app.kubernetes.io/component: nginx-exampledev - type: NodePort -``` - -## Summary - -This document mainly introduces how to use the KCL and Konfig library to deploy a Long Running application running in Kubernetes. diff --git a/versioned_docs/version-0.5.6/user_docs/guides/working-with-konfig/4-best-practice.md b/versioned_docs/version-0.5.6/user_docs/guides/working-with-konfig/4-best-practice.md deleted file mode 100644 index ee0cc576..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/working-with-konfig/4-best-practice.md +++ /dev/null @@ -1,449 +0,0 @@ ---- -id: practice -sidebar_label: Best Practice ---- - -# Best Practice - -This document aims to explain the best practices for integrating new models into the Konfig library and designing, building and writing KCL code models. New models are generally designed and abstracted using the best practice of separating front-end and back-end models. The direct purpose of distinguishing between front-end and back-end models is to separate `"user interface"` and `"model implementation"`, achieving a user-friendly and simple configuration interface as well as automated configuration query and modification interfaces. - -## Workflow - -![](/img/docs/user_docs/guides/konfig/workflow.png) - -1. **Coding**. Use the KCL OpenAPI tool to generate KCL schemas from the Customer Resources Definitions (CRDs) or OpenAPI Swagger models. These schemas define the atomic capabilities of the platform. -1. **Abstraction**. Based on these atomic capabilities, the platform abstracts user-oriented front-end models and provides a set of templates. These front- - end models cannot work independently, and corresponding back-end models are required. These back-end models will eventually obtain an instance of the front-end model at runtime; it parses the input front-end model and converts it into Kubernetes resources. -1. **Configuration**. Developers or SREs describe the requirements of applications based on front-end models. Users can define the base and different environment configurations for different environments e.g., base, development and production and different localities. In most cases, defining configurations only requires declaring key-value pairs. For some complex scenarios, users can define the logic to generate configurations. -1. **Automation**. After defining the user's configuration, all components have been defined and are ready to be automated. The platform can compile, execute, output, modify, query, and perform other automatic works through the KCL CLI or GPL-binding APIs. Users can also deploy the KCL configuration to the Kubernetes cluster with tools. - -## Model Structure - -Just as web applications provide a friendly user interface, and user input is further inferred at the backend of the application to obtain the final data that falls into the database, similarly, using KCL for model design also follows the logic of front-end and back-end separation. In addition, when the downstream required data content changes, we only need to modify the rendering/logic of the user configuration data to the backend model, thereby avoiding large-scale modification of user configurations. - -Taking the sidecar configuration of application services as an example: - -```python -# Config user interface. -user_sidecar_feature_gates: str - -# Downstream config of processing. -sidecars = [ - { - name = "sidecar_name" # Additional template for sidecars parameters, users do not need to configure them. - feature_gates = user_sidecar_feature_gates - } -] -``` - -## Best Practices for Konfig Modeling - -### Use Single Attribute Instead of Configuration Templates - -For some backend models, the configuration attributes that need to be filled in are often large and comprehensive designs, requiring users to actively input more complex configuration templates, and the filling content of this attribute is basically the same for different users. For example, the configuration of logic shown below requires users to fill in a large amount of template data, which has a high mental cost. - -A simple best practice is to abstract such commonly used and complex templates into a simple attribute `overQuota` with the `bool` type in the front-end model, allowing users to do multiple-choice questions instead of filling in blank questions. For example, when the `overQuota` attribute is `True`, the back-end model will render this complex logic. - -- The front-end attribute `overQuota` - -```python -overQuota: bool -``` - -- The back-end YAML output: - -```yaml -spec: - template: - spec: - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: k8s/is-over-quota - operator: In - values: - - "true" -``` - -In addition, different template names can be designed according to specific business scenarios to fill in the blanks, such as designing an attribute template in the code shown below to assist users in template selection instead of directly filling in the template content. The legal template value can be `"success_ratio"` or `"service_cost"`. When the backend model extends more templates, the front-end code does not need to make any modifications, only needs to adapt the corresponding template logic in the backend model. - -```python -schema SLI: - template: str = "success_ratio" -``` - -In addition, it is recommended to avoid using complex structures directly as front-end model attributes to avoid users needing to rely on too many KCL syntax features (such as unpacking, looping, etc.) or writing many temporary variables to complete the instantiation of the structure when using the model. - -### Use Literal Type and Union Type - -In the above section, it was mentioned that a string attribute can be used to represent different template names, and further, a literal type can be used to express the optional content of the template. For example, the following improvements can be made. - -```python -schema SLI: - template: "success_ratio" | "service_cost" = "success_ratio" -``` - -The type of template is a combination of two string types, indicating that the template can only be `"success_ratio"` or `"service_cost"`. When the user fills in the values of other strings, the KCL compiler will report an error. - -In addition to using union types for literal types, KCL also supports union for complex types such as schema types. For the support of this backend **oneof** configuration, KCL has built-in composite structure union types for support. For example, we can define our own SLI front-end types for various scenarios: `CustomSliDataSource`, `PQLSLIDataSource`, and `StackSLIDataSource`. - -```python -schema CustomSLIDataSource: - customPluginUrl: str - -schema PQLSLIDataSource: - total?: str - error?: str - success?: str - cost?: str - count?: str - -schema StackSLIDataSource: - stack: str - groupBy?: str - metric?: str - -# Simplify type definitions using type aliases -type DataSource = CustomSLIDataSource | PQLSLIDataSource | StackSLIDataSource - -schema DataConfiguration: - sources: {str: DataSource} -``` - -The advantage of designing this front-end model is that the compiler can statically check that the type written by the user can only be a certain type. If the back-end model is used directly, it cannot directly obtain the mapping relationship between different types of types and the fields that need to be filled in from the model. - -In addition, the overall design of the front-end model should also consider horizontal scalability, using the union type as much as possible, fully utilizing the advantages of coding, and avoiding unnecessary large amounts of code restructuring and modification when connecting to different backend or backend models. In addition, for the factory pattern commonly used in other GPL languages, union types can also be used instead in KCL. For example, if you want to obtain a constructor of a type based on the content of a string, you can directly use union types for optimization. - -Using the factory pattern in KCL: - -```python -schema DataA: - id?: int = 1 - value?: str = "value" - -schema DataB: - name?: str = "DataB" - -_dataFactory: {str:} = { - DataA = DataA - DataB = DataB -} -dataA = _dataFactory["DataA"]() -dataB = _dataFactory["DataB"]() -``` - -Replacing the factory pattern with the KCL union type. - -```python -schema DataA: - id?: int = 1 - value?: str = "value" - -schema DataB: - name?: str = "DataB" - -# Just use the union type. -dataA: DataA | DataB = DataA() -dataB: DataA | DataB = DataB() -``` - -### Use Dict Instead of List As Much As Possible - -To make it easier to modify configurations on-site or automate queries, it is advisable to define list or array attributes as dictionary types for easy indexing. In many complex configuration scenarios, the index of a list is arbitrary and the order of elements has no impact on the configuration. Using a dictionary type instead of a list type allows for more convenient data querying and modification. For example: - -```python -schema Person: - name: str - age: int - -schema House: - persons: [Person] - -house = House { - persons = [ - Person { - name = "Alice" - age = 18 - } - Person { - name = "Bob" - age = 10 - } - ] -} -``` - -For example, in the above example, if you want to query the age of the person named `"Alice"` from the list of persons in the house, you need to loop through the list to find Alice's age. However, if you define persons as a dictionary like the following code, it not only looks more concise in code, but you can also directly retrieve Alice's age by using house.persons.Alice.age. In addition, the information of the entire configuration is complete and has no redundant information. - -```python -schema Person: - age: int - -schema House: - persons: {str: Person} # Use Dict Instead of List - -house = House { - persons = { - Alice = Person { age = 18 } - Bob = Person { age = 10 } - } -} -``` - -### Write Validation Expressions for Models - -For frontend models, it is often necessary to validate the fields filled in by users. In this case, KCL's check expressions can be used in conjunction with KCL's built-in functions/syntax/system libraries to perform field validation. For frontend model validation, it is recommended to directly write it in the frontend model definition as a prerequisite for validation, in order to avoid unexpected errors that may occur when the errors are passed to the backend model. - -Use all/any expressions and check expressions for validation - -```python -import regex - -schema ConfigMap: - name: str - data: {str:str} - configMounts?: [ConfigMount] - - check: - all k in data { - regex.match(k, r"[A-Za-z0-9_.-]*") - }, "a valid config key must consist of alphanumeric characters, '-', '_' or '.'" - -schema ConfigMount: - containerName: str - mountPath: str - subPath?: str - - check: - ":" not in mountPath, "mount path must not contain ':'" -``` - -### Use Numerical Unit Type - -Numbers with units in KCL have a built-in type of `units.NumberMultiplier`, and any arithmetic operations are not allowed. - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -x0: NumberMultiplier = 1M # Ok -x1: NumberMultiplier = x0 # Ok -x2 = x0 + x1 # Error: unsupported operand type(s) for +: 'number_multiplier(1M)' and 'number_multiplier(1M)' -``` - -We can use the `int()/float()` function and `str()` function to convert the number unit type to integer or string type, and the resulting string retains the units of the original number unit type. - -```python -a: int = int(1Ki) # 1024 -b: str = str(1Mi) # "1Mi" -``` - -The definitions related to Kubernetes Resource in Konfig can be written using numerical unit types - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -schema Resource: - cpu?: NumberMultiplier | int = 1 - memory?: NumberMultiplier = 1024Mi - disk?: NumberMultiplier = 10Gi - epchygontee?: int -``` - -### Automated Modification of Front-end Model Instances - -In KCL, automated modification of front-end model instances can be achieved through the CLI and API. For example, if we want to modify the image content of an application (Konfig Stack Path: apps/nginx example/dev) configuration, we can directly execute the following command to modify the image content. - -```python -kcl -Y kcl.yaml ci-test/settings.yaml -o ci-test/stdout.golden.yaml -d -O :appConfiguration.image=\"test-image-v1\" -``` - -For more documentation related to automation, please refer to the [Automation Documents](/docs/user_docs/guides/automation) section. - -### Use Functions - -```python -# Define a function that adds two numbers and returns the result。 -add = lambda x, y { - x + y -} -# Define a function that subs two numbers and returns the result。 -sub = lambda x, y { - x - y -} -# Call the function, pass in arguments, and obtain the return value. -result = sub(add(2, 3), 2) # The result is 3. -``` - -The output YAML is - -```yaml -result: 3 -``` - -### Use Package and Module - -Create a package called `utils.k`, define a KCL function called `add` in it, and import it into another file for use. - -- `utils.k` - -```python -# utils.k - -# Define a function that adds two numbers and returns the result。 -add = lambda x, y { - x + y -} - -# Define a function that subs two numbers and returns the result。 -sub = lambda x, y { - x - y -} -``` - -- `main.k` - -```python -# main.k -import .utils - -# Call the function, pass in arguments, and obtain the return value. -result = utils.sub(utils.add(2, 3), 2) # The result is 3. -``` - -### Simplify Logical Expressions Using Configuration - -```python -# Complex Logic, `_cpu` is a non-exported and mutable attribute. -_cpu = 256 -_priority = "1" - -if _priority == "1": - _cpu = 256 -elif _priority == "2": - _cpu = 512 -elif _priority == "3": - _cpu = 1024 -else: - _cpu = 2048 - -# Simplify Logic Expression using Config -cpuMap = { - "1" = 256 - "2" = 512 - "3" = 1024 -} -# Get cpu from the cpuMap, when not found, use the default value 2048. -cpu = cpuMap[_priority] or 2048 -``` - -The output is - -```yaml -cpuMap: - "1": 256 - "2": 512 - "3": 1024 -cpu256: 256 -cpu2048: 2048 -``` - -### Separate Logic and Data - -We can use KCL **schema**, **config**, and **lambda** to separate **data** and **logic** as much as possible. - -For example, we can write the following code (main.k). - -```python -schema Student: - """Define a `Student` schema model with documents. - - Attributes - ---------- - name : str, required - The name of the student. - id : int, required. - The id number of the student. - grade : int, required. - The grade of the student. - - Examples - -------- - s = Student { - name = "Alice" - id = 1 - grade = 80 - } - - """ - name: str - id: int - grade: int - - # Define constraints for the `Student` model. - check: - id >= 0 - 0 <= grade <= 100 - -# Student data. -students: [Student] = [ - {name = "Alice", id = 1, grade = 85} - {name = "Bob", id = 2, grade = 70} - {name = "Charlie", id = 3, grade = 90} - {name = "David", id = 4, grade = 80} - {name = "Eve", id = 5, grade = 95} -] - -# Student logic. -query_student_where_name = lambda students: [Student], name: str { - # Query the first student where name is `name` - filter s in students { - s.name == name - }?[0] -} - -alice = query_student_where_name(students, name="Alice") -bob = query_student_where_name(students, name="Bob") -``` - -The output is - -```yaml -students: - - name: Alice - id: 1 - grade: 85 - - name: Bob - id: 2 - grade: 70 - - name: Charlie - id: 3 - grade: 90 - - name: David - id: 4 - grade: 80 - - name: Eve - id: 5 - grade: 95 -alice: - name: Alice - id: 1 - grade: 85 -bob: - name: Bob - id: 2 - grade: 70 -``` - -### Add Comments for Models - -To facilitate user understanding and automatic model documentation generation, it is necessary to write comments for the defined model. The comment content usually includes an explanation of the model, an explanation of model fields, types, default values, usage examples, and more. For detailed KCL schema code commenting guidelines and automatic model documentation generation, please refer to the [KCL Documentation Specification](/docs/tools/cli/kcl/docgen). Additionally, we can use the `kcl-doc generate` command to extract documentation from the user-specified file or directory and output it to the specified directory. - -## Backend Model - -The backend model is an "implementation model," which mainly includes the logical code to map the frontend model to the backend model. After the frontend model is written, we can use the frontend model schema to create frontend model instances, and write the corresponding backend mapping/rendering code to convert these frontend instances into the backend model. By using KCL's multi-file compilation and `Schema.instances()` function, the frontend and backend code can be highly decoupled, so that users only need to focus on frontend configuration without being aware of the complex validation and logical code of the model. diff --git a/versioned_docs/version-0.5.6/user_docs/guides/working-with-konfig/_category_.json b/versioned_docs/version-0.5.6/user_docs/guides/working-with-konfig/_category_.json deleted file mode 100644 index a71426f9..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/working-with-konfig/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Konfig", - "position": 10 -} diff --git a/versioned_docs/version-0.5.6/user_docs/guides/working-with-kusion/_category_.json b/versioned_docs/version-0.5.6/user_docs/guides/working-with-kusion/_category_.json deleted file mode 100644 index 9f914498..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/working-with-kusion/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KusionStack", - "position": 15 -} diff --git a/versioned_docs/version-0.5.6/user_docs/guides/working-with-kusion/index.md b/versioned_docs/version-0.5.6/user_docs/guides/working-with-kusion/index.md deleted file mode 100644 index 2565ad03..00000000 --- a/versioned_docs/version-0.5.6/user_docs/guides/working-with-kusion/index.md +++ /dev/null @@ -1,15 +0,0 @@ -# KusionStack - -**KusionStack is an open-source cloud-native programmable technology stack!** - -KusionStack is a highly flexible programmable technology stack to enable unified application delivery and operation, inspired by the word Fusion, which aims to help enterprises build an application-centric configuration management plane and DevOps ecosystem. - -1. Fusion of hybrid scenarios of **private cloud**, **hybrid cloud**, and **multi-cloud** -2. Fusion of hybrid platform technologies of **cloud-native** and a variety of other platform technologies -3. Fusion of enterprise-level demands of **multi-project**, **multi-team**, **multi-role**, **multi-tenant**, and **multi-environment** - -Based on the concept of Platform as Code, developers can quickly unify the full configuration schemas, constraints, policies and configs across the application life cycle, work with the **hybrid technologies and cloud environment**, go through the **end-to-end workflow** from programming to launching, and truly achieve **write once, deliver anywhere**. - -![](/img/docs/user_docs/intro/kusion-stack-1.png) - -More documents and use cases at [https://kusionstack.io/](https://kusionstack.io/) diff --git a/versioned_docs/version-0.5.6/user_docs/support/_category_.json b/versioned_docs/version-0.5.6/user_docs/support/_category_.json deleted file mode 100644 index 60548d80..00000000 --- a/versioned_docs/version-0.5.6/user_docs/support/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "FAQ", - "position": 6 -} diff --git a/versioned_docs/version-0.5.6/user_docs/support/faq-cli.md b/versioned_docs/version-0.5.6/user_docs/support/faq-cli.md deleted file mode 100644 index ab012a34..00000000 --- a/versioned_docs/version-0.5.6/user_docs/support/faq-cli.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Command Line Tool - -## 1. What is the function of the `settings.yaml` in the application directory of the Konfig? - -The `settings.yaml` in KCL indicates the configuration file of the KCL command line tool. You can put the compiled configuration into it, such as the file to be compiled, the option dynamic parameter that needs to be input(`-d`), whether to ignore the null value(`-n`) and other configurations. - -For example, for the following arguments: - -```shell -kcl main.k -D key=value -n -r -``` - -It can be replaced by the following command line arguments and `settings.yaml` - -```shell -kcl -Y settings.yaml -``` - -settings.yaml - -```yaml -kcl_cli_configs: - files: - - main.k - disable_none: true - strict_range_check: true -kcl_options: - - key: key - value: value -``` - -- `kcl_cli_configs` indicates configurable compilation arguments, `file` indicates the KCL file used for compilation,`disable_none` indicates whether to use `-n`, `strict_range_check` indicates whether to use `-r`. -- `kcl_options` indicates dynamic options that can be configured, `key` indicates option name, `value` indicates option value - -Note: The file name does not need to be `settings.yaml`, but the configuration in it must meet the requirements. - -### 2. How to input dynamic options? How to get dynamic options in code? - -KCL supports multiple ways to input dynamic options - -- `-D`: Use the command line argument `-D` to input dynamic options. It supports basic data types str/int/float/bool and structured data types list/dict - -```shell -kcl main.k -D env-type=TEST -D deploy-topology='[{"cluster":"my-cluster","idc":"my-idc","replicas":2,"workspace":"my-idc","zone":"my-zone"}]' -``` - -- `-Y`: Use the command line argument `-Y` to input dynamic options by configuration file: - -```yaml -kcl_options: - - key: env-type - value: TEST - - key: deploy-topology - value: - - cluster: my-cluster - idc: my-idc - replicas: 2 - workspace: my-workspace - zone: my-zone -``` - -Use the built-in function `option()` to get it: - -```python -env = option("env-type") -deploy_topology = option("deploy-topology") -``` - -Output: - -```yaml -env: TEST -deploy_topology: - - cluster: my-cluster - idc: my-idc - replicas: 2 - workspace: my-workspace - zone: my-zone -``` - -### 3. How to compile multiple files? - -- Input multiple files in the command line: - -```shell -kcl file1.k file2.k file3.k -``` - -- Set multiple files in configuration file and use command line argument `-Y`: - -settings.yaml - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - - file3.k -``` - -```shell -kcl -Y settings.yaml -``` diff --git a/versioned_docs/version-0.5.6/user_docs/support/faq-install.md b/versioned_docs/version-0.5.6/user_docs/support/faq-install.md deleted file mode 100644 index 37100c09..00000000 --- a/versioned_docs/version-0.5.6/user_docs/support/faq-install.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Installation Troubleshooting - -## MacOS prompts that 'kcl' cannot be opened because Apple cannot check if it contains malicious software - -MacOS prompts that 'kcl' cannot be opened because Apple cannot check if it contains malicious software. This issue is due to the Gatekeeper security feature in the macOS system preventing the application from running. To solve this issue, follow these steps: - -Open 'System Preferences' and click 'Security and Privacy'. In the "General" tab, you will see a message: '"kcl" cannot be opened'. Click 'Open still'. Alternatively, you can click 'Open any method' to open your application. (You may need to use administrator privileges to open the application.) - -If you don't want to perform these steps every time you open an application, you can add the application to the whitelist to run without being blocked. To add your application to the whitelist: - -Open the terminal and run the following command: - -```shell -xattr -rd com.apple.quarantine /path/to/kcl -``` - -Where `/path/to/kcl` is the complete path of the kcl application. After running the command, the application will be added to the whitelist and Gatekeeper will no longer prevent it from running. - -## program not found or run linker failed error on Windows/Linux/MacOS - -Please ensure that the following dependencies are in your PATH: - -- `clang` for MacOS -- `gcc` for Linux -- `cl.exe` for Windows, which can be obtained by installing MSVC diff --git a/versioned_docs/version-0.5.6/user_docs/support/faq-kcl.md b/versioned_docs/version-0.5.6/user_docs/support/faq-kcl.md deleted file mode 100644 index 860dd15b..00000000 --- a/versioned_docs/version-0.5.6/user_docs/support/faq-kcl.md +++ /dev/null @@ -1,2341 +0,0 @@ ---- -sidebar_position: 2 ---- - -# KCL - -## 1. How to write a simple key-value pair configuration with KCL - -Create a file named `config.k` - -```python -cpu = 256 -memory = 512 -image = "nginx:1.14.2" -service = "my-service" -``` - -In the above KCL code, `cpu` and `memory` are defined to be declared as integer types, and their values are `256` and `512`, while `image` and `service` are string types, their values are `image` and `service`. - -Use the following command to compile the above KCL file into YAML for output - -``` -kcl config.k -``` - -The output YAML is - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -If we want to output the YAML content to a file such as `config.yaml`, we can add the `-o|--output` CLI argument: - -``` -kcl config.k -o config.yaml -``` - -## 2. What are the basic data types in KCL? - -KCL's current basic data types and values include: - -- Integer type `int` - - Examples: decimal positive integer `1`, decimal negative integer `-1`, hexadecimal integer `0x10`, octal integer `0o10`, binary integer `0b10` -- float type `float` - - Examples: positive float `1.10`, `1.0`, negative float `-35.59`, `-90.`, scientific notation float `32.3e+18`, `70.2E-12` -- boolean type `bool` - - Example: true value `True`, false value `False` -- String type `str` - marked with `'`, `"` - - Example: double quoted string `"string"`, `"""string"""`, single quoted string `'string'`, `'''string'''` -- List type `list` - marked with `[`, `]` - - Example: empty list `[]`, string list `["string1", "string2", "string3"]` -- Dictionary type `dict` - marked with `{`, `}` - - Example: empty dictionary `{}`, dictionary whose keys and values ​​are all strings `{"key1": "value1", "key2": "value2"}` -- Structure type `schema` - defined with the keyword `schema` -- Null value type `None` - used to indicate that the value of a variable is null, corresponding to the `null` value of the output YAML -- Undefined value type `Undefined` - used to indicate that a variable has not been assigned a value, and a variable with a value of `Undefined` will not be output to YAML - -```python -schema Person: - name: str - age: int - -alice = Person { - name = "Alice" - age = 18 -} -bob = Person { - name = "Bob" - age = 10 -} -``` - -> Note: All KCL variables can be assigned the null value `None` and the undefined value `Undefined`. - -## 3. What do some KCL variable names prefixed with `_` underscore mean? What's the difference between without the `_` underscore prefix? In what scenarios are they suitable for use? - -A variable with an underscore prefix in KCL represents a **hidden**, **mutable** variable, **hidden** means a variable with an underscore prefix will not be output to YAML, and **mutable** means that a variable with an underscore prefix can be repeatedly assigned multiple times, and a variable without an underscore prefix is immutable after being assigned. - -```python -name = 'Foo' # Exported and immutable variable -name = 'Bar' # Error: An exported variable can only be assigned a value once -``` - -```python -_name = 'Foo' # Hidden and mutable variable -_name = 'Bar' - -schema Person: - _name: str # hidden and mutable -``` - -## 4. How to add elements to a dict? - -We can use the union operator `|` or the dict unpacking operator `**` to add elements into a dict, and we can use `in` and `not in` operators to determine whether the dict variable contains a certain key. - -```python -_left = {key: {key1 = "value1"}, intKey = 1} # Note: `=` denotes override the value. -_right = {key: {key2 = "value2"}, intKey = 2} -dataUnion = _left | _right # {"key": {"key1": "value1", "key2": "value2"}, "intKey": 2} -dataUnpack = {**_left, **_right} # {"key": {"key1": "value1", "key2": "value2"}, "intKey": 2} -``` - -The output YAML is - -```yaml -dataUnion: - key: - key1: value1 - key2: value2 - intKey: 2 -dataUnpack: - key: - key1: value1 - key2: value2 - intKey: 2 -``` - -It is also possible to add key-value pair to a dict using the `string interpolation` or the string `format` method. - -```python -dictKey1 = "key1" -dictKey2 = "key2" -data = { - "${dictKey1}" = "value1" - "{}".format(dictKey2) = "value2" -} -``` - -The output YAML is - -```yaml -dictKey1: key1 -dictKey2: key2 -data: - key1: value1 - key2: value2 -``` - -## 5. How to modify elements in dict? - -We can use the union operator `|`, or the unpacking operator `**` to modify the elements in the dict - -```python -_data = {key = "value"} # {"key": "value"} -_data = _data | {key = "override_value1"} # {"key": "override_value1"} -_data = {**_data, **{key = "override_value2"}} # {"key": "override_value2"} -``` - -If we want to delete a value with a key of `key` in the dict, we can use the unpacking operator `**{key = Undefined}` or the merge operator `| {key = Undefined}` to overwrite, the value of the key is Undefined after overwriting, and no YAML output will be done. - -## 6. How to add elements to list? - -There are two ways to add elements to a list: - -- Use `+`, `+=` and slice to concatenate list variables to add elements to the list - -```python -_args = ["a", "b", "c"] -_args += ["end"] # Add elements "end" to the end of the list: ["a", "b", "c", "end"] -_args = _args[:2] + ["x"] + _args[2:] # Insert element "x" at list index 2: ["a", "b", "x", "c", "end"] -_args = ["start"] + _args # Add elements "start" to the head of the list: ["start", "a", "b", "x", "c", "end"] -``` - -- Use the `*` unpacking operator to concatenate and merge lists - -```python -_args = ["a", "b", "c"] -_args = [*_args, "end"] # Add elements "end" to the end of the list: ["a", "b", "c", "end"] -_args = ["start", *_args] # Add elements "start" to the head of the list: ["start", "a", "b", "x", "c", "end"] -``` - -> Note: When the consecutive variables are `None/Undefined`, using `+` may cause an error, then we can use the list unpacking operator `*` or use the `or` operator to take the default value of the list to avoid null values judge. - -```python -data1 = [1, 2, 3] -data2 = None -data3 = [*data1, *data2] # Ok: [1, 2, 3] -data4 = data1 + data2 or [] # OK: [1, 2, 3], We can use the `or` operator to take the default value of data2 as [], when data2 is None/Undefined, take the empty list [] for calculation. -data5 = data1 + data2 # Error: can only concatenate list (not "NoneType") to list -``` - -## 7. How to modify/delete elements in list? - -There are two ways to modify the elements in the list: - -- Use slice to directly modify the value at an index of a list - -```python -_index = 1 -_args = ["a", "b", "c"] -_args = _args[:index] + ["x"] + _args[index+1:] # Modify the element of list index 1 to "x": ["a", "x", "c"] -``` - -- Use the list comprehension to modify elements in a list - -```python -_args = ["a", "b", "c"] -_args = ["x" if a == "b" else a for a in _args] # Change the value of "b" in the list to "x": ["a", "x", "c"] -``` - -There are two ways to delete elements in a list: - -- Use the list comprehension to delete elements with the `if` condition expressions. -- Use `filter` expression to filter elements. - -For example, if we want to delete a number greater than 2 in a list `[1, 2, 3, 4, 5]`, we can write as follows: - -```python -originList = [1, 2, 3, 4, 5] -oneWayDeleteListItem = [item for item in originList if item <= 2] -anotherWayDeleteListItem = filter item in originList { - item <= 2 -} -``` - -The output YAML is - -```yaml -originList: - - 1 - - 2 - - 3 - - 4 - - 5 -oneWayDeleteListItem: - - 1 - - 2 -anotherWayDeleteListItem: - - 1 - - 2 -``` - -## 8. How to write a for loop in KCL? How to understand and use list comprehension and dict comprehension? - -KCL currently only supports functional/declarative deductive for loops. We can traverse dict and list variables as follows: - -The specific form of a list comprehension is (where `[]` are used on both sides of the comprehension): - -```txt -[expression for expr in sequence1 - if condition1 - for expr2 in sequence2 - if condition2 - for expr3 in sequence3 ... - if condition3 - for exprN in sequenceN - if conditionN] -``` - -The specific form of dict comprehension is (where `{}` are used on both sides of the comprehension): - -```txt -{expression for expr in sequence1 - if condition1 - for expr2 in sequence2 - if condition2 - for expr3 in sequence3 ... - if condition3 - for exprN in sequenceN - if conditionN} -``` - -The `if` in the above forms represents the filter condition, and the expression `expr` that satisfies the condition will be generated into a new list or dict - -List comprehension example: - -```python -_listData = [1, 2, 3, 4, 5, 6] -_listData = [l * 2 for l in _listData] # All elements in _listData are multiplied by 2: [2, 4, 6, 8, 10, 12] -_listData = [l for l in _listData if l % 4 == 0] # Filter out all elements in _listData that are divisible by 4: [4, 8, 12] -_listData = [l + 100 if l % 8 == 0 else l for l in _listData] # Traverse _listData, when the element in it is divisible by 8, add 100 to the element, otherwise keep it unchanged: [4, 108, 12] -``` - -Note the difference between the two `if`s on lines 3 and 4 in the above code: - -- The first `if` represents the filter condition of the variable `_listData` list comprehension itself, and cannot be followed by `else`. Elements that meet the conditions will be added to the list, and elements that do not meet the conditions will be removed. Besides, the process may change the length of the list. -- The second `if` represents the selection condition of the list iteration variable `l`, which means the `if-else` ternary expression, which must be followed by `else`, regardless of whether the condition is met, the resulting element is still in the list, the length of the list does not change. - -Dict comprehension example: - -```python -_dictData = {key1 = "value1", key2 = "value2"} -_dictData = {k = _dictData[k] for k in _dictData if k == "key1" and _dictData[k] == "value1"} # Filter out the elements whose key is "key1" and value is "value1" in _dictData, {"key1": "value1"} -``` - -Use comprehension to get all keys of dict: - -```python -dictData = {key1 = "value1", key2 = "value2"} -dictDataKeys = [k for k in _dictData] # ["key1", "key2"] -``` - -Use comprehension to sort a dict in ascending order by key: - -```python -dictData = {key3 = "value3", key2 = "value2", key1 = "value1"} # {'key3': 'value3', 'key2': 'value2', 'key1': 'value1'} -dictSortedData = {k = dictData[k] for k in sorted(dictData)} # {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'} -``` - -Multi-level comprehension example: - -```python -array1 = [1, 2, 3] -array2 = [4, 5, 6] -data = [a1 + a2 for a1 in array1 for a2 in array2] # [5, 6, 7, 6, 7, 8, 7, 8, 9] len(data) == len(array1) * len(array2) -``` - -Double variable loop (list comprehension supports index iteration of list and value iteration of dict, which can simplify the code writing of list/dict iteration process): - -- list - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use _ to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -- dict - -```python -data = {key1 = "value1", key2 = "value2"} -# Single variable loop -dataKeys1 = [k for k in data] # ["key1", "key2"] -dataValues1 = [data[k] for k in data] # ["value1", "value2"] -# Double variable loop -dataKeys2 = [k for k, v in data] # ["key1", "key2"] -dataValues2 = [v for k, v in data] # ["value1", "value2"] -dataFilter = {k = v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use _ to ignore loop variables -dataKeys3 = [k for k, _ in data] # ["key1", "key2"] -dataValues3 = [v for _, v in data] # ["value1", "value2"] -``` - -## 9. How to write an if conditional statement? - -KCL supports two ways to write if conditional statements: - -- if-elif-else block statement, where both elif and else blocks can be omitted, and the elif block can be used multiple times - -```python -success = True -_result = "failed" -if success: - _result = "success" -``` - -```python -success = True -if success: - _result = "success" -else: - _result = "failed" -``` - -```python -_result = 0 -if condition == "one": - _result = 1 -elif condition == "two": - _result = 2 -elif condition == "three": - _result = 3 -else: - _result = 4 -``` - -- Conditional expression ` if else `, similar to ` ? : ` ternary expression in C language - -```python -success = True -_result = "success" if success else "failed" -``` - -> Note: When writing an if-elif-else block statement, pay attention to the colon `:` after the if condition and keep the indentation consistent. - -In addition, conditional expressions can also be written directly in a list or dict (the difference is that the value to be written in the if expression written in the structure is not a statement): - -- list - -```python -env = "prod" -data = [ - "env_value" - ":" - if env == "prod": - "prod" # Write values that need to be added to data, not statements - else: - "other_prod" -] # ["env_value", ":", "prod"] -``` - -- dict - -```python -env = "prod" -config = { - if env == "prod": - MY_PROD_ENV = "prod_value" # Write key-value pairs that need to be added to config, not statements - else: - OTHER_ENV = "other_value" -} # {"MY_PROD_ENV": "prod_value"} -``` - -## 10. How to express logical operations such as "and" "or" "not"? - -In KCL, use `and` for "logical and", use `or` for "logical or", use `not` for "not", which is similar to `&&`, `||` and `~` semantic in C language. - -```python -done = True -col == 0 -if done and (col == 0 or col == 3): - ok = 1 -``` - -For "bitwise AND", "bitwise OR" and "bitwise XOR" of integers, we can use `&`, `|` and `^` operators in KCL, which is similar to `&`, `|` and `^` semantic in C language. - -```python -value = 0x22 -bitmask = 0x0f - -assert (value & bitmask) == 0x02 -assert (value & ~bitmask) == 0x20 -assert (value | bitmask) == 0x2f -assert (value ^ bitmask) == 0x2d -``` - -When we need to write a pattern such as `A if A else B`, we can use `A or B` to simplify, such as the following code: - -```python -value = [0] -default = [1] -x0 = value if value else default -x1 = value or default # Use `value or default` instead of `value if value else default` -``` - -## 11. How to judge whether a variable is None/Undefined, and whether a string/dict/list is empty? - -Please note that `False`, `None`, `Undefined`, number `0`, empty list `[]`, empty dictionary `{}` and empty string `""`, `''`, `""""""`, `''''''` in the conditional expression, are all treated as `false` expressions. - -For example, when judging a string variable `strData` is neither `None/Undefined` nor an empty string (string length is greater than 0), we can simply use the following expression: - -```python -strData = "value" -if strData: - isEmptyStr = False -``` - -Empty dictionary and empty list judgment examples: - -```python -_emptyList = [] -_emptyDict = {} -isEmptyList = False if _emptyList else True -isEmptyDict = False if _emptyDict else True -``` - -The output YAML is - -```yaml -isEmptyList: true -isEmptyDict: true -``` - -Or use the boolean function `bool` to judge - -```python -_emptyList = [] -_emptyDict = {} -isEmptyList = bool(_emptyList) -isEmptyDict = bool(_emptyDict) -``` - -## 12. How to concatenate strings, format strings, check string prefixes and suffixes and replace string content? - -- The `+` operator can be used to concatenate two strings in KCL - -```python -data1 = "string1" + "string2" # "string1string2" -data2 = "string1" + " " + "string2" # "string1 string2" -``` - -- There are currently two ways to format strings in KCL: - - `format` method for string variables `"{}".format()` - - Using string interpolation `${}` - -```python -hello = "hello" -a = "{} world".format(hello) -b = "${hello} world" -``` - -Note that if we want to use the `{` character or `}` alone in `"{}".format()`, we need to use `{{` and `}}` to convert `{` and `}` respectively, such as escaping a JSON string as follows: - -```python -data = "value" -jsonData = '{{"key": "{}"}}'.format(data) -``` - -The output YAML is - -```yaml -data: value -jsonData: '{"key": "value"}' -``` - -Note that if we want to use the `$` character alone in the `${}` interpolated string, we need to escape the `$` with `$$` - -```python -world = "world" -a = "hello {}".format(world) # "hello world" -b = "hello ${world}" # "hello world" -c = "$$hello ${world}$$" # "$hello world$" -c2 = "$" + "hello ${world}" + "$" # "$hello world$" -``` - -The output YAML is - -```yaml -world: world -a: hello world -b: hello world -c: $hello world$ -c2: $hello world$ -``` - -- Use the `startswith` and `endswith` methods of strings in KCL to check the prefix and suffix of strings - -```python -data = "length" -isEndsWith = data.endswith("th") # True -isStartsWith = "length".startswith('len') # True -``` - -- Use the replace method of the string or the `regex.replace` function to replace the content of the string in KCL - -```python -import regex -data1 = "length".replace("len", "xxx") # Replace "len", "xxxgth" with "xxx" -data2 = regex.replace("abc123", r"\D", "0") # Replace all non-digits in "abc123" with "0", "000123" -``` - -Among them, `r"\D"` means that we do not need to use `\\` to escape the backslash `\` in `\D`, which is mostly used in regular expression strings. - -Besides, we can use index placeholders or keyword placeholders in string formatting expressions to format multiple strings - -- Index placeholders - -```python -x = '{2} {1} {0}'.format('directions', 'the', 'Read') -y = '{0} {0} {0}'.format('string') -``` - -The output YAML is - -```yaml -x: Read the directions -y: string string string -``` - -- Keyword placeholders - -```python -x = 'a: {a}, b: {b}, c: {c}'.format(a = 1, b = 'Two', c = 12.3) -``` - -The output YAML is - -```yaml -x: "a: 1, b: Two, c: 12.3" -``` - -## 13. What is the difference between using single and double quotes in a string? - -There is little difference between KCL single-quoted and double-quoted strings. The only difference is that we don't need to use `\"` to escape `"` in single-quoted strings, and we don't need to use `\'` to escape `'` in double-quoted strings. - -```python -singleQuotedString = 'This is my book named "foo"' # Don’t need to escape double quotes in single quoted strings. -doubleQuotedString = "This is my book named 'foo'" # Don’t need to escape single quotes in double quoted strings. -``` - -In addition, a long string consisting of three single quotes or three double quotes does not need to be escaped (except for the beginning and end of the string), such as the following example: - -```python -longStrWithQuote0 = """Double quotes in long strings "(not at the beginning and end)""" -longStrWithQuote1 = '''Double quotes in long strings "(not at the beginning and end)''' -longStrWithQuote2 = """Single quotes in long strings '(not at the beginning and end)""" -longStrWithQuote3 = '''Single quotes in long strings '(not at the beginning and end)''' -``` - -The output YAML is - -```yaml -longStrWithQuote0: Double quotes in long strings "(not at the beginning and end) -longStrWithQuote1: Double quotes in long strings "(not at the beginning and end) -longStrWithQuote2: Single quotes in long strings '(not at the beginning and end) -longStrWithQuote3: Single quotes in long strings '(not at the beginning and end) -``` - -## 14. How to write a long multiline string? - -In KCL, we can use a single-quoted string and newline characters `\n` or a triple-quoted string to write a multi-line string, and we can use the continuation character `\` to optimize the form of the KCL string. For example, for the three multi-line string variables in the following code, their values are the same: - -```python -string1 = "The first line\nThe second line\nThe third line\n" -string2 = """The first line -The second line -The third line -""" -string3 = """\ -The first line -The second line -The third line -""" # It is recommended to use the long string writing form of `string3`. -``` - -The output YAML is - -```yaml -string1: | - The first line - The second line - The third line -string2: | - The first line - The second line - The third line -string3: | - The first line - The second line - The third line -``` - -## 15. How to use regular expressions in KCL? - -Regular expressions can be used by importing the regular expression system module `import regex` in KCL, which includes the following functions: - -- **match**: Regular expression matching function, which matches the input string according to the regular expression, and returns a bool type to indicate whether the match is successful. -- **split**: Regular expression split function, which splits the string according to the regular expression, and returns a list of split strings. -- **replace**: Regular expression replacement function, which replaces all substrings in the string that satisfies the regular expression, and returns the replaced string. -- **compile**: Regular expression compilation function, which returns bool type to indicate whether it is a valid regular expression. -- **search**: Regular expression search function, which searches all substrings that satisfy the regular expression, and returns a list of substrings. - -Examples: - -```python -import regex - -regex_source = "Apple,Google,Baidu,Xiaomi" -regex_split = regex.split(regex_source, ",") -regex_replace = regex.replace(regex_source, ",", "|") -regex_compile = regex.compile("$^") -regex_search = regex.search("aaaa", "a") -regex_find_all = regex.findall("aaaa", "a") -regex_result = regex.match("192.168.0.1", "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$") # Determine if it is an IP string -regex_result_false = regex.match("192.168.0,1", "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$") # Determine if it is an IP string -``` - -The output YAML is - -```yaml -regex_source: Apple,Google,Baidu,Xiaomi -regex_split: - - Apple - - Google - - Baidu - - Xiaomi -regex_replace: Apple|Google|Baidu|Xiaomi -regex_compile: true -regex_search: true -regex_find_all: - - a - - a - - a - - a -regex_result: true -regex_result_false: false -``` - -For longer regular expressions, we can also use **r-string** to ignore the escape of `\` symbols to simplify the writing of regular expression strings. - -Examples: - -```python -import regex - -isIp = regex.match("192.168.0.1", r"^(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)."+r"(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)$") # Determine if it is an IP string -``` - -```python -import regex - -schema Resource: - cpu: str = "1" - memory: str = "1024Mi" - disk: str = "10Gi" - check: - regex.match(cpu, r"^([+-]?[0-9.]+)([m]*[-+]?[0-9]*)$"), "cpu must match specific regular expression" - regex.match(memory, r"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"), "memory must match specific regular expression" - regex.match(disk, r"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"), "disk must match specific regular expression" -``` - -```python -import regex - -schema Env: - name: str - value?: str - check: - len(name) <= 63, "a valid env name must be no more than 63 characters" - regex.match(name, r"[A-Za-z_][A-Za-z0-9_]*"), "a valid env name must start with alphabetic character or '_', followed by a string of alphanumeric characters or '_'" -``` - -## 16. What is the meaning of schema in KCL? - -Schema is a language element in KCL that defines the type of configuration data. Like struct in C language or class in Java, attributes can be defined in it, and each attribute has a corresponding type. - -## 17. How to use schema? - -In KCL, we can use the `schema` keyword to define a structure in which we can declare the various attributes of the schema. - -```python -# A Person structure with firstName of attribute string type, lastName of string type, age of integer type. -schema Person: - firstName: str - lastName: str - # The default value of the age attribute is 0. - age: int = 0 -``` - -A complex example: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels: {str:str} -``` - -In the above code, `cpu` and `memory` are defined as integer types; `name`, `image` and `service` are string types; `command` is a list of string types; labels are dictionaries type whose key type and value type are both strings. - -## 18. How to add "optional" and "required" constraints to the schema attribute? - -The `?` operator is used in KCL to define an "optional" constraint for a schema, and the schema attribute is "required" by default. - -```python -# A Person structure with firstName of attribute string type, lastName of string type, age of integer type. -schema Person: - firstName?: str # firstName is an optional attribute that can be assigned to None/Undefined - lastName?: str # age is an optional attribute that can be assigned to None/Undefined - age: int = 18 # age is an optional attribute that can be assigned to None/Undefined. -``` - -## 19. How to write validation rules for attributes in schema? - -In the schema definition, we can use the `check` keyword to write the validation rules of the schema attribute. As shown below, each line in the check code block corresponds to a conditional expression. When the condition is satisfied, the validation is successful. The conditional expression can be followed by `, "check error message"` to indicate the information to be displayed when the validation fails. - -```python -import regex - -schema Sample: - foo: str # Required, cannot be None/Undefined, and the type must be str - bar: int # Required, cannot be None/Undefined, and the type must be int - fooList: [int] # Required, cannot be None/Undefined, and the type must be int list - color: "Red" | "Yellow" | "Blue" # Required, literal union type, and must be one of "Red", "Yellow", "Blue". - id?: int # Optional, can be None/Undefined, the type must be int - - check: - 0 <= bar < 100 # bar must be greater than or equal to 0 and less than 100 - 0 < len(fooList) < 100 # fooList cannot be None/Undefined, and the length must be greater than 0 and less than 100 - regex.match(foo, "^The.*Foo$") # regular expression matching - bar in range(100) # bar can only range from 1 to 99 - bar in [2, 4, 6, 8] # bar can only take 2, 4, 6, 8 - bar % 2 == 0 # bar must be a multiple of 2 - all foo in fooList { - foo > 1 - } # All elements in fooList must be greater than 1 - any foo in fooList { - foo > 10 - } # At least one element in fooList must be greater than 10 - abs(id) > 10 if id # check expression with if guard, when id is not empty, the absolute value of id must be greater than 10 -``` - -To sum up, the validation kinds supported in KCL schema are: - -| Kind | Method | -| ----------------- | ----------------------------------------------------------------------------------------- | -| Range | Using comparison operators such as `<`, `>` | -| Regex | Using methods such as `match` from the `regex` system module | -| Length | Using the `len` built-in function to get the length of a variable of type `list/dict/str` | -| Enum | Using literal union types | -| Optional/Required | Using optional/required attributes of schema | -| Condition | Using the check if conditional expression | - -## 20. How to add documentation to schema and its attributes? - -A complete schema document is represented as a triple-quoted string, with the following structure: - -```python -schema Person: - """The schema person definition - - Attributes - ---------- - name : str - The name of the person - age : int - The age of the person - - See Also - -------- - Son: - Sub-schema Son of the schema Person. - - Examples - -------- - person = Person { - name = "Alice" - age = 18 - } - """ - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -``` - -## 21. How to write configuration based on schema? How to reuse the common configuration between multiple configurations? - -In the process of schema instantiation, we can use the unpacking operator `**` to expand the public configuration - -```python -schema Boy: - name: str - age: int - hc: int - -schema Girl: - name: str - age: int - hc: int - -config = { - age = 18 - hc = 10 -} - -boy = Boy { - **config - name = "Bob" -} -girl = Girl { - **config - name = "Alice" -} -``` - -The output YAML is - -```yaml -config: - age: 18 - hc: 10 -boy: - name: Bob - age: 18 - hc: 10 -girl: - name: Alice - age: 18 - hc: 10 -``` - -## 22. How to override the default value of schema attribute when writing configuration based on schema? - -After defining a schema, we can use the schema name to instantiate the corresponding configuration, use the `:` operator to union schema attribute default values, and use `=` to override schema attribute default values. - -```python -schema Meta: - labels: {str:str} = {"key1" = "value1"} - annotations: {str:str} = {"key1" = "value1"} - -meta = Meta { - labels: {"key2": "value2"} - annotations = {"key2" = "value2"} -} -``` - -The output YAML is - -```yaml -meta: - labels: - key1: value1 - key2: value2 - annotations: - key2: value2 -``` - -## 23. How to reuse schema definitions? - -We can declare the schema name that the schema needs to inherit at the definition: - -```python -# A person has a first name, a last name and an age. -schema Person: - firstName: str - lastName: str - # The default value of age is 0 - age: int = 0 - -# An employee **is** a person, and has some additional information. -schema Employee(Person): - bankCard: int - nationality: str - -employee = Employee { - firstName = "Bob" - lastName = "Green" - age = 18 - bankCard = 123456 - nationality = "China" -} -``` - -The output YAML is - -```yaml -employee: - firstName: Bob - lastName: Green - age: 18 - bankCard: 123456 - nationality: China -``` - -> Note: KCL only allows schema single inheritance. - -## 24. How to reuse schema logic through composition? - -We can use KCL schema mixin to reuse schema logic. Mixins are generally used for functions such as separation of data in schema internal attributes, and data mapping, which can make KCL code more modular and declarative. - -Note that it is not recommended to define dependencies for mixing attributes between different mixins, which will make the use of mixins complicated. - -Examples: - -```python -schema Person: - mixin [FullNameMixin, UpperMixin] - - firstName: str - lastName: str - fullName: str - upper: str - -schema FullNameMixin: - fullName = "{} {}".format(firstName, lastName) - -schema UpperMixin: - upper = fullName.upper() - -person = Person { - firstName = "John" - lastName = "Doe" -} -``` - -The output YAML is - -```yaml -person: - firstName: John - lastName: Doe - fullName: John Doe - upper: JOHN DOE -``` - -## 25. How to import other KCL files? - -Other KCL files can be imported via the `import` keyword, and KCL configuration files are organized into modules. A single KCL file is considered a module, and a directory is considered a package, as a special module. The `import` keyword supports both relative path import and absolute path import - -For example, for the following directory structure: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ │── service1.k - │ └── service2.k - └── mixin - └── mixin1.k -``` - -For `main.k`, relative path import and absolute path import can be expressed as: - -```python -import service # Absolute path import, the root directory is the path where kcl.mod is located -import mixin # Absolute path import, the root directory is the path where kcl.mod is located - -import .model1 # Relative path import, current directory module -import ..service # Relative path import, parent directory -import ...root # Relative path import, parent directory of parent directory -``` - -> Note that for KCL's entry file `main.k`, it cannot import the folder where it is located, otherwise a circular import error will occur: - -```python -import model # Error: recursively loading -``` - -## 26. When can import be omitted? - -KCL files in the same folder the not in the main package can refer to each other without importing each other. For example, for the following directory structure: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ │── service1.k - │ └── service2.k - └── mixin - └── mixin1.k -``` - -When main.k is used as the KCL command line entry file, the variables in main.k, model1.k and model2.k in the model folder cannot refer to each other and need to be imported through import, but service1.k in the service folder and Variables in service2.k can refer to each other, ignoring import - -service1.k - -```python -schema BaseService: - name: str - namespace: str -``` - -service2.k - -```python -schema Service(BaseService): - id: str -``` - -## 27. There is a line of code that is too long, how to wrap it gracefully with correct syntax? - -In KCL, we can use the continuation character `\` for newlines, and we can also use `\` in strings to indicate continuation. - -An example of a long string concatenation continuation line: - -```python -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " -``` - -An example of a continuation in the comprehension expression: - -```python -data = [1, 2, 3, 4] -dataNew = [ - d + 2 \ - for d in data \ - if d % 2 == 0 -] -``` - -An example of a continuation in the if expression: - -```python -condition = 1 -data1 = 1 \ - if condition \ - else 2 -data2 = 2 \ -if condition \ -else 1 -``` - -An example of a continuation in the long string: - -```python -longString = """\ -The first line\ -The continue second line\ -""" -``` - -Note: Use the line continuation character `\` while maintaining indentation, as follows: - -- Error use case: - -```python -data1 = [ - 1, 2, - 3, 4 \ -] # Error, need to keep the indentation of the closing bracket ] - -data2 = [ - 1, 2, - 3, 4 -] # Error, requires uniform indentation of numbers 1 and 3 -``` - -- Right use case: - -```python -data1 = [ - 1, 2, - 3, 4 -] # OK - -data2 = [ \ - 1, 2, \ - 3, 4 \ -] # OK - -data3 = [ \ - 1, 2, \ - 3, 4 \ -] # OK -``` - -## 28. What do these symbols `**` and `*` mean? - -- `**`, `*` appear outside dict/list to represent power operator and multiplication operator respectively. - -```python -data1 = 2 ** 4 # 16 -data2 = 2 * 3 # 6 -``` - -- `**`, `*` appear inside dict/list to indicate unpacking operator, often used for unpacking and merging of list/dict, similar to unpacking operator in Python - -Unpacking of dict: - -```python -data = {"key1" = "value1"} -dataUnpack = {**data, "key2" = "value2"} # {"key1": "value1", "key2": "value2"} -``` - -Unpacking of list: - -```python -data = [1, 2, 3] -dataUnpack = [*data, 4, 5, 6] # [1, 2, 3, 4, 5, 6] -``` - -## 29. How to get child elements of list/dict/schema - -- For list type, we can use `[]` to get an element in the list - -```python -data = [1, 2, 3] # Define an list of integer types -theFirstItem = data[0] # Get the element with index 0 in the list, that is, the first element 1 -theSecondItem = data[1] # Get the element with index 1 in the list, which is the first element 2 -``` - -> Note: The value of the index cannot exceed the length of the list, otherwise an error will occur, we can use the `len` function to get the length of the list. - -```python -data = [1, 2, 3] -dataLength = len(data) # List length is 3 -item = data[3] # Error: Index out of bounds -``` - -In addition, we can also use the negative index to get the elements in the list in reverse order. - -```python -data = [1, 2, 3] -item1 = data[-1] # Get the element with index -1 in the list, which is the last element 3 -item2 = data[-2] # Get the element with index -2 in the list, which is the second-to-last element 2 -``` - -In summary, the value range of the list index is `[-len, len - 1]` - -When we want to get a part of the sub-elements of the list, we can use the slice expression in `[]`, the specific syntax is `[::]`, Note that the value range of the start and end of the index is `left closed right open [, )`, note that the three parameters can be omitted or not written. - -```python -data = [1, 2, 3, 4, 5] -dataSlice0 = data[1:2] # Get the set of elements in the list whose index starts at 1 and ends at 2 [2] -dataSlice1 = data[1:3] # Get the set of elements in the list whose index starts at 1 and ends at 3 [2, 3] -dataSlice2 = data[1:] # Get the set of elements in the list whose index starts at 1 and ends at the last index [2, 3, 4, 5] -dataSlice3 = data[:3] # Get the set of elements in the list whose index starts at the first index and ends at 3 [1, 2, 3] -dataSlice4 = data[::2] # Get the set of elements in the list whose index starts at the first index and ends at the last index (step size is 2) [1, 3, 5] -dataSlice5 = data[::-1] # Reverse the list, [5, 4, 3, 2, 1] -dataSlice6 = data[2:1] # When the start, stop, step combination of three parameters does not meet the conditions, return an empty list []. -``` - -- For dict/schema types, we can use `[]` and `.` to get child elements in dict/schema. - -```python -data = {key1: "value1", key2: "value2"} -data1 = data["key1"] # "value1" -data2 = data.key1 # "value1" -data3 = data["key2"] # "value2" -data4 = data.key2 # "value2" -``` - -```python -schema Person: - name: str = "Alice" - age: int = 18 - -person = Person {} -name1 = person.name # "Alice" -name2 = person["name"] # "Alice" -age1 = person.age # 18 -age2 = person.age # 18 -``` - -When the key value does not exist in the dict, return the value `Undefined`. - -```python -data = {key1 = "value1", key2 = "value2"} -data1 = data["not_exist_key"] # Undefined -data2 = data.not_exist_key # Undefined -``` - -We can use the `in` keyword to determine whether a key value exists in dict/schema - -```python -data = {key1 = "value1", key2 = "value2"} -exist1 = "key1" in data # True -exist2 = "not_exist_key" in data # False -``` - -When there is `.` in the key value or when we need to get the value corresponding to a key value variable at runtime, we can only use the `[]` method. If there is no special case, use `.`: - -```python -name = "key1" -data = {key1 = "value1", key2 = "value2", "contains.dot" = "value3"} -data1 = data[name] # "value1" -data2 = data["contains.dot"] # "value3" -# Note that this is wrong: data3 = data.contains.dot -``` - -> Note: The above sub-element operators cannot operate on values of non-list/dict/schema collection types, such as integers, nulls, etc. - -```python -data = 1 -data1 = 1[0] # Error -``` - -```python -data = None -data1 = None[0] # Error -``` - -When getting the child elements of the collection type, it is often necessary to make a non-null or length judgment: - -```python -data = [] -item = data[0] if data else None -``` - -We can use the `?` operator to make an if non-null judgment, and return None when the condition is not satisfied. For example, the above code can be simplified to: - -```python -data = [] -item1 = data?[0] # When data is empty, return the empty value None -item2 = data?[0] or 1 # When data is empty, return the empty value None, if we don't want to return None, we can also use the or operator to return other default values e.g., "1" in `data?[0] or 1` -``` - -Use more `?` operators to avoid complicated and cumbersome non-null judgments - -```python -data = {key1.key2.key3 = []} -item = data?.key1?.key2?.key3?[0] -``` - -## 30. How to get the type of a variable in KCL code - -The KCL `typeof` built-in function can return the type (string representation) of a variable immediately for type assertion. - -Examples: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person{} -t3 = typeof(_x1) - -_x2 = pkg.Person{} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# Output -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -## 31. How to solve the conflict between keywords and KCL variable names? - -For identifier names that conflict with keywords, we can add a `$` prefix before the identifier to define a keyword identifier. For example, in the following code, keywords such as `if`, `else` can be used as identifiers with the `$` prefix and we can get the corresponding YAML output - -```python -$if = 1 -$else = "s" - -schema Data: - $filter: str = "filter" - -data = Data {} -``` - -The output YAML is - -```yaml -data: - filter: filter -if: 1 -else: s -``` - -> Note: Prefixing non-keyword identifiers with `$` has the same effect as not adding. - -```python -_a = 1 -$_a = 2 # Equivalent to `_a = 2` -``` - -## 32. Are built-in types of KCL a keyword of KCL? Whether they can be used for the definition of variables - -The built-in types of KCL include `int`, `float`, `bool` and `str`, which are not KCL keywords and can be used to define variables, such as the following code: - -```py -int = 1 -str = 2 -``` - -The output YAML is - -```yaml -int: 1 -str: 2 -``` - -> Note: If there are no special requirements, it is not recommended that the names of variables take these built-in types, because in some languages, they exist as keywords. - -## 33. How to implement enumeration in KCL? - -There are two ways to implement enumeration in KCL - -- Use **literal union types** (recommended) - -```python -schema Person: - name: str - gender: "Male" | "Female" - -person = Person { - name = "Alice" - gender = "Male" # gender can only be "Male" or "Female" -} -``` - -```python -schema Config: - colors: ["Red" | "Yellow" | "Blue"] # colors is an enumerated array - -config = Config { - colors = [ - "Red" - "Blue" - ] -} -``` - -- Use schema check expressions - -```python -schema Person: - name: str - gender: "Male" | "Female" - - check: - gender in ["Male", "Female"] - -person = Person { - name = "Alice" - gender = "Male" # gender can only be "Male" or "Female" -} -``` - -## 34. How to get the length of dict - -In KCL, we can use the `len` built-in function to directly find the length of a dict - -```python -len1 = len({k1: "v1"}) # 1 -len2 = len({k1: "v1", k2: "v2"}) # 2 -varDict = {k1 = 1, k2 = 2, k3 = 3} -len3 = len(varDict) # 3 -``` - -In addition, the `len` function can also be used to get the length of `str` and `list` types - -```python -len1 = len("hello") # 5 -len2 = len([1, 2, 3]) # 3 -``` - -## 35. How to write conditional configuration in KCL - -In KCL, in addition to writing `if-elif-else` conditional expressions in top-level statements, it also supports writing conditional expressions in KCL complex structures (list/dict/schema), and supports conditional configuration writing. - -```python -x = 1 -# Conditional configuration in list -dataList = [ - if x == 1: 1 -] -# Conditional configuration in dict -dataDict = { - if x == 1: key1 = "value1" # Inline form - elif x == 2: - key2 = "value2" # Multi-line form -} - -schema Config: - id?: int - -env = "prod" -# Conditional configuration in schema -dataSchema = Config { - if env == "prod": - id = 1 - elif env == "pre": - id = 2 - elif env == "test": - id = 3 -} -``` - -## 36. Does the == operator in KCL do deep comparisons? - -`==` operator in KCL - -- For primitive types `int`, `float`, `bool`, `str` variables are directly compared to see if their values are equal -- Variables of composite types `list`, `dict`, `schema` will deeply recursively compare their sub-elements for equality - - `list` type deep recursive recursive comparison of the value and length of each index - - `dict`/`schema` types deeply recursively compare the value of each attribute (regardless of the order in which the attributes appear) - -```python -print([1, 2] == [1, 2]) # True -print([[0, 1], 1] == [[0, 1], 1]) # True -print({k1 = 1, k2 = 2} == {k2 = 2, k1 = 1}) # True - -print([1, 2] == [1, 2, 3]) # False -print({k1 = 1, k2 = 2, k3 = 3} == {k2 = 2, k1 = 1}) # False -``` - -## 37. How to modify existing configuration blocks in KCL - -In KCL, there are three **attribute operators** `=`, `+=`, `:`, which can be used to modify existing configuration blocks, and can use **unpacking operator** ` **` etc. "inherit" all attribute fields and values ​​of a configuration block. - -- The `=` attribute operator means overriding, use `=` operator to override/delete the attribute with priority, (if it is overwritten with `Undefined`, it means deletion) -- The `+=` attribute operator means adding, which is generally used to add sub-elements to the attributes of the list type. The operand type following the `+=` attribute operator can only be of the list type. -- The `:` attribute operator means idempotent merge. When the value conflicts, an error is reported, and when there is no conflict, the merge is performed - -### Override attribute operator = - -The most commonly used attribute operator is `=`, which indicates the assignment of an attribute. When the same attribute is used multiple times, it means overwriting. For global variables outside `{}` or attributes within `{}`, it means using value overrides this global variable or attribute - -```python -data = { # define a dictionary type variable data - a = 1 # use = to declare a attribute a in data with a value of 1 - b = 2 # use = to declare a attribute b in data with a value of 1 -} # The final data value is {"a": 1, "b": 1} -``` - -we can also use the override attribute operator at the schema instantiation to achieve the effect of overriding the default value of the schema. Generally, when creating a new schema instance, if there is no special requirement, we can generally use `=` - -```python -schema Person: - name: str = "Alice" # schema Person's name attribute has default value "Alice" - age: int = 18 # schema Person's age attribute has a default value of 18 - -bob = Person { - name = "Bob" # "Bob" -> "Alice", the value of the attribute name "Bob" will override the default value "Alice" of the schema Person name attribute - age = 10 # 10 -> 18, the value of the attribute age of 10 will override the default value of the schema Person age attribute of 18 -} # The final value of bob is {"name": "Bob", age: 10} -``` - -### Insert attribute operator += - -The insert attribute operator means to add the value of an attribute in place, such as adding a new element to a list type attribute - -```python -data = { - args = ["kcl"] # use = to declare an attribute in data with value ["kcl"] args - args += ["-Y", "settings.yaml"] # Add two elements "-Y", "settings.yaml" to attribute args using += operator -} # The final data value is {"args": ["kcl", "-Y", "settings.yaml"]} -``` - -### Merge attribute operators : - -The merge attribute operator means idempotent merging of different configuration block values ​​of an attribute. When the values ​​to be merged conflict, an error is reported. It is mostly used in complex configuration merging scenarios. - -```python -data = { - labels: {key1: "value1"} # define a labels, its type is dict, the value is {"key1": "value1"} - labels: {key2: "value2"} # Use : to combine different configuration values ​​of labels -} # The final data value is {"labels": {"key1": "value1", "key2": "value2"}} -``` - -The merge attribute operator is an idempotent operator, and the writing order of the configuration blocks to be merged does not affect the final result. For example, the two `labels` attributes in the above example can also be written in reverse order. - -```python -data = { # The merged writing order of the same attribute labels does not affect the final result - labels: {key2: "value2"} # define a label whose type is dict and the value is {"key2": "value2"} - labels: {key1: "value1"} # Use : to combine different configuration values ​​of labels -} # The final data value is {"labels": {"key1": "value1", "key2": "value2"}} -``` - -Note: The merge attribute operator will check the merged values ​​for conflicts, and report an error when the configuration values ​​that need to be merged conflict. - -```python -data = { - a: 1 # the value of a is 1 - a: 2 # Error: The value 2 of a cannot be merged with the value 1 of a because the results conflict and the merge is not commutative -} -``` - -```python -data = { - labels: {key: "value"} - labels: {key: "override_value"} # Error: The values ​​"value" and "override_value" of the key attributes of two labels are conflicting and cannot be merged -} -``` - -The coalescing operator is used differently for different types - -- Attributes of different types cannot be merged -- When the attribute is a basic type such as int/float/str/bool, the operator will judge whether the values ​​to be merged are equal, and a merge conflict error will occur if they are not equal - -```python -data = { - a: 1 - a: 1 # Ok - a: 2 # Error -} -``` - -- when the attribute is of type list - - Merge conflict error occurs when two lists that need to be merged are not of equal length - - When the lengths of the two lists to be merged are equal, recursively merge each element in the list according to the index - -```python -data = { - args: ["kcl"] - args: ["-Y", "settings.yaml"] # Error: The lengths of the two args attributes are not the same and cannot be merged - env: [{key1: "value1"}] - env: [{key2: "value2"}] # Ok: The value of the final env attribute is [{"key1": "value1"}, {"key2": "value2"}] -} -``` - -- When the attribute is of type dict/schema, recursively merge each element in dict/schema according to key - -```python -data = { - labels: {key1: "value1"} - labels: {key2: "value2"} - labels: {key3: "value3"} -} # The final data value is {"labels": {"key1": "value1", "key2": "value2", "key3": "value3"}} -``` - -- the result of combining an attribute of any type with None/Undefined is itself - -```python -data = { - args: ["kcl"] - args: None # Ok - args: Undefined #Ok -} # The final data value is {"args": ["kcl"]} -``` - -Support declaration and merging of top-level variables using the `:` attribute (we can still declare a configuration block using `config = Config {}`) - -```python -schema Config: - id: int - value: str - -config: Config { - id: 1 -} -config: Config { - value: "1" -} -""" -Two Config configuration blocks are defined here, and the : operator can be used to merge the two configuration blocks together. The equivalent code for the merge is as follows: -config: Config { - id: 1 - value: "1" -} -""" -``` - -To sum up, the usage scenario of the merge attribute operator `:` is mainly the merge operation of the complex data structure list/dict/schema. In general, if there is no special requirement, the two attribute operators `=` and `+=` are used. Yes, so the best practice for attribute operators is as follows - -- For primitive types, use the `=` operator -- For the list type, the `=` and `+=` operators are generally used. Use `=` to completely override the list attribute, and use `+=` to add elements to the list -- For dict/schema types, the `:` operator is generally used - -In addition, when a configuration already exists, we can use the unpacking operator `**` to get all field values ​​of this configuration and modify the fields with different attribute operators, and get a new configuration - -```python -configBase = { - intKey = 1 # A attribute of type int - floatKey = 1.0 # A attribute of type float - listKey = [0] # A attribute of type list - dictKey = {key1: "value1"} # an attribute of type dict -} -configNew = { - **configBase # Unpack and inline configBase into configNew - intKey = 0 # Use override attribute operator = to override intKey attribute to 1 - floatKey = Undefined # Use override attribute operator = remove floatKey attribute - listKey += [1] # Add an attribute 1 to the end of the listKey attribute using the add attribute operator += - dictKey: {key2: "value2"} # Use the merge attribute operator: extend a key-value pair for the dictKey attribute -} -``` - -The output YAML result is: - -```yaml -configBase: - intKey: 1 - floatKey: 1.0 - listKey: - - 0 - dictKey: - key1: value1 -configNew: - intKey: 0 - listKey: - - 0 - - 1 - dictKey: - key1: value1 - key2: value2 -``` - -Alternatively two configuration blocks can be combined using the `|` operator: - -```python -configBase = { - intKey = 1 # A attribute of type int - floatKey = 1.0 # A attribute of type float - listKey = [0] # A attribute of type list - dictKey = {key1: "value1"} # an attribute of type dict -} -configNew = configBase | { # Use | to merge - intKey = 0 # Use override attribute operator = to override intKey attribute to 1 - floatKey = Undefined # Use override attribute operator = remove floatKey attribute - listKey += [1] # Add an attribute 1 to the end of the listKey attribute using the add attribute operator += - dictKey: {key2: "value2"} # Use the merge attribute operator: extend a key-value pair for the dictKey attribute -} -``` - -The output YAML is - -```yaml -configBase: - intKey: 1 - floatKey: 1.0 - listKey: - - 0 - dictKey: - key1: value1 -configNew: - intKey: 0 - listKey: - - 0 - - 1 - dictKey: - key1: value1 - key2: value2 -``` - -### The solution to the conflicting values on the attribute 'attr' between {value1} and {value2} error in KCL - -When an error like conflicting values on the attribute 'attr' between {value1} and {value2} occurs in KCL, it is usually a problem with the use of the merge attribute operator `:`, indicating that when the `value1` and `value2` configurations are merged, the attribute A conflict error occurred at `attr`. In general, modify the attr attribute of value2 to other attribute operators, use `=` to indicate overwrite, and use `+=` to indicate addition - -For example for the following code: - -```python -data = {k: 1} | {k: 2} # Error: conflicting values on the attribute 'k' between {'k': 1} and {'k': 2} -``` - -We can use the `=` attribute operator to modify it to the following form - -```python -data = {k: 1} | {k = 2} # Ok: the value 2 will override the value 1 through the `=` operator -``` - -## 38. How to traverse multiple elements at the same time in the for comprehension? - -In KCL, we can use for comprehension to traverse multiple elements - -- Example 1: two dimension element loop - -```python -dimension1 = [1, 2, 3] # The length of the dimension1 list is 3 -dimension2 = [1, 2, 3] # The length of the dimension2 list is 3 -matrix = [x + y for x in dimension1 for y in dimension2] # The length of the matrix list is 9 = 3 * 3 -``` - -The output YAML is: - -```yaml -dimension1: - - 1 - - 2 - - 3 -dimension2: - - 1 - - 2 - - 3 -matrix: - - 2 - - 3 - - 4 - - 3 - - 4 - - 5 - - 4 - - 5 - - 6 -``` - -- Example 2: Use for loop and `zip` built-in function to traverse multiple lists one by one by index - -```python -dimension1 = [1, 2, 3] # The length of the dimension1 list is 3 -dimension2 = [1, 2, 3] # The length of the dimension2 list is 3 -dimension3 = [d[0] + d[1] for d in zip(dimension1, dimension2)] # The length of the dimension1 list is 3 -``` - -The output YAML is: - -```yaml -dimension1: - - 1 - - 2 - - 3 -dimension2: - - 1 - - 2 - - 3 -dimension3: - - 2 - - 4 - - 6 -``` - -## 39. How to set default value for option function in KCL - -In KCL, when the value of the option attribute is None/Undefined or empty, we can use the logical `or` to directly specify a default value. - -```python -value = option("key") or "default_value" # When the value of key exists, take the value of option("key"), otherwise take "default_value" -``` - -Or use the default parameter of the option function. - -```python -value = option("key", default="default_value") # When the value of key exists, take the value of option("key"), otherwise take "default_value" -``` - -## 40. How to check that multiple attributes cannot be empty or set values at the same time in schema in KCL? - -In KCL, a single attribute of schema cannot be empty by default, unless we use the attribute optional operator `?`. - -```python -schema Person: - name: str # Required. - age: int # Required. - id?: int # Optional. -``` - -When it is necessary to check that the schema attributes cannot be empty at the same time or only one of them is empty, it needs to be written with the help of schema check expressions. The following takes two attributes `a`, `b` of the schema `Config` as an example to illustrate. - -- `a` and `b` attributes cannot be empty at the same time. - -```python -schema Config: - a?: str - b?: str - - check: - a or b -``` - -- `a` and `b` attributes can only have one or both empty (cannot exist at the same time or not empty) - -```python -schema Config: - a?: str - b?: str - - check: - not a or not b -``` - -## 41. A file is imported in KCL, but the schema defined by other KCL files in the same directory cannot be found. What might be the reason? - -It may be caused to import only this file in this folder. In KCL, import statement supports importing the entire folder, and also supports importing a certain KCL file under a certain folder. For the following directory structure. - -``` -. -├── kcl.mod -├── main.k -└── pkg - ├── pkg1.k - ├── pkg2.k - └── pkg3.k -``` - -There is an entry file main.k in the root directory. You can write the following code in main.k to import the entire pkg folder. At this time, all schema definitions in the pkg folder are visible to each other. - -```python -import pkg -``` - -We can also write the following code to import a single file pkg/pkg1.k. At this time, pkg1.k cannot find other files, namely the schema definitions under pkg2.k/pkg3.k - -```python -import pkg.pkg1 -``` - -## 42. How is indentation handled in KCL? - -In KCL, when a colon `:`, square bracket pair `[]` and curly bracket pair `{}` appear, we generally need to use newline + indentation, and the number of indented spaces for the same indentation level needs to be consistent. The indentation level is generally represented by 4 spaces. - -- colon `:` followed by newline and indent - -```python -"""Indentation in if statements""" -_a = 1 -_b = 1 -if _a >= 1: # colon `:` followed by newline and indent - if _a > 8: - _b = 2 - elif a > 6: - _b = 3 - -"""Indentation in schema statements""" -schema Person: # colon `:` followed by newline and indent - name: str - age: int -``` - -- opening bracket `[` followed by newline and indent - -```python -data = [ # opening bracket `[` followed by newline and indent - 1 - 2 - 3 -] # unindent before closing bracket ] -``` - -```python -data = [ # opening bracket `[` followed by newline and indent - i * 2 for i in range(5) -] # unindent before closing bracket `]` -``` - -- opening bracket `{` followed by newline and indent - -```python -data = { # opening bracket `{` followed by newline and indent - k1 = "v1" - k2 = "v2" -} # unindent before closing brace `}` -``` - -```python -data = { # opening bracket `{` followed by newline and indent - str(i): i * 2 for i in range(5) -} # unindent before closing brace `}` -``` - -## 43. How to write simple tests for KCL code? - -The current version of KCL does not support internal program debugging, we can use the assert statement and the print function to achieve data assertion and viewing. - -```python -a = 1 -print("The value of a is", a) -assert a == 1 -``` - -In addition, we can also use the kcl-test test tool to write KCL internal test cases - -Assuming there is a hello.k file, the code is as follows: - -```python -schema Person: - name: str = "kcl" - age: int = 1 - -hello = Person { - name = "hello kcl" - age = 102 -} -``` - -Construct the hello_test.k test file with the following contents: - -```python -schema TestPerson: - a = Person{} - assert a.name == 'kcl' - -schema TestPerson_age: - a = Person{} - assert a.age == 1 - -schema TestPerson_ok: - a = Person{} - assert a.name == "kcl" - assert a.age == 1 -``` - -Then execute the kcl-test command in the directory: - -``` -$ kcl-test -ok /pkg/to/app [365.154142ms] -$ -``` - -## 44. How to define and use functions in KCL? - -The schema structure acts as a function to a certain extent, and this function has the ability to have multiple input parameters and multiple output parameters. For example, the following code can implement the function of a Fibonacci sequence: - -```python -schema Fib: - n: int - value: int = 1 if n <= 2 else (Fib {n: n - 1}).value + (Fib {n: n - 2}).value - -fib8 = (Fib {n: 8}).value -``` - -The output is - -```yaml -fib8: 21 -``` - -A schema function that merges lists into dictionaries - -```python -schema UnionAll[data, n]: - _?: [] = data - value?: {:} = ((UnionAll(data=data, n=n - 1) {}).value | data[n] if n > 0 else data[0]) if data else {} - -schema MergeList[data]: - """Union all elements in a list returns the merged dictionary - - [{"key1": "value1"}, {"key2": "value2"}, {"key3": "value3"}] -> {"key1": "value1", "key2": "value2", "key3": "value3"} - """ - _?: [] = data - value?: {:} = (UnionAll(data=data, n=len(data) - 1) {}).value if data else {} -``` - -In addition, KCL supports defining a function using the `lambda` keyword: - -```python -func = lambda x: int, y: int -> int { - x + y -} -a = func(1, 1) # 2 -``` - -A lambda function has the following properties: - -- A lambda function takes the value of the last expression as the return value of the function, and an empty function body returns None. -- The return value type annotation can be omitted, the return value type is the type of the last expression value. -- There are no order-independent features in the function body, all expressions are executed in order. - -```python -_func = lambda x: int, y: int -> int { - x + y -} # Define a function using the lambda expression -_func = lambda x: int, y: int -> int { - x - y -} # Ok -_func = lambda x: int, y: int -> str { - str(x + y) -} # Error (int, int) -> str can't be assigned to (int, int) -> int -``` - -A lambda function cannot participate in any computation and can only be used in assignment and call statements. - -```python -func = lambda x: int, y: int -> int { - x + y -} -x = func + 1 # Error: unsupported operand type(s) for +: 'function' and 'int(1)' -``` - -```python -a = 1 -func = lambda x: int { - x + a -} -funcOther = lambda f, para: int { - f(para) -} -r = funcOther(func, 1) # 2 -``` - -The output is - -```python -a: 1 -r: 2 -``` - -We can define an anonymous function and call it directly - -```python -result = (lambda x, y { - z = 2 * x - z + y -})(1, 1) # 3 -``` - -Anonymous functions can be also used in for loops - -```python -result = [(lambda x, y { - x + y -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 3, 3, 4] -``` - -Functions can be defined and used in the KCL schema - -```python -_funcOutOfSchema = lambda x: int, y: int { - x + y -} -schema Data: - _funcInSchema = lambda x: int, y: int { - x + y - } - id0: int = _funcOutOfSchema(1, 1) - id1: int = _funcInSchema(1, 1) - id2: int = (lambda x: int, y: int { - x + y - })(1, 1) -``` - -The output YAML is - -```yaml -data: - id0: 2 - id1: 2 - id2: 2 -``` - -## 45. Why do we get an error when a variable is assigned an enumeration type (a literal union type)? - -In KCL, a attribute defined as a literal union type is only allowed to receive a literal value or a variable of the same literal union type during assignment. For example, the following code is correct: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -data = Data { - color = "Red" # Ok, can be assigned as "Red", "Yellow" and "Blue" -} -``` - -However the following code is wrong: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -_color = "Red" - -data = Data { - color = _color # Error: expect str(Red)|str(Yellow)|str(Blue), got str -} -``` - -This is because there is no type declared for the variable `_color`, it will be deduced by the KCL compiler as a `str` string type, so when a "larger" type `str` is assigned to a "smaller" type `"Red" | "Yellow" | "Blue"` will report an error, one solution is to declare a type for the `_color` variable, the following code is correct: - -```python -schema Data: - color: "Red" | "Yellow" | "Blue" - -_color: "Red" | "Yellow" | "Blue" = "Red" - -data = Data { - color = _color # Ok -} -``` - -Further, we can use type aliases to simplify enumeration (writing of literal union types), such as the following code: - -```python -type Color = "Red" | "Yellow" | "Blue" # Define a type alias, which can be reused in different places, reducing the amount of code writing - -schema Data: - color: Color - -_color: Color = "Red" - -data = Data { - color = _color # Ok -} -``` - -## 46. Procedural for loop - -KCL provides comprehensions and all/any/map/filter expressions for processing a collection element, which meets most needs, and provides a procedural for loop body. Providing a procedural for loop body is not very demanding from the current scenario, so there is no procedural for loop support yet. - -In addition, although KCL does not support procedural for loops, it is possible to "construct" corresponding procedural for loops through for loops and lambda functions. - -```python -result = [(lambda x: int, y: int -> int { - # Write procedural for loop logic in the lambda function. - z = x + y - x * 2 -})(x, y) for x in [1, 2] for y in [1, 2]] # [2, 2, 4, 4] -``` - -## 47. Default variables are immutable - -The immutability of KCL variables means that the exported variables starting with non-underscore `_` in the KCL top-level structure cannot be changed after initialization. - -```python -schema Person: - name: str - age: int - -a = 1 # a will be output to YAML, once assigned it cannot be modified -_b = 1 # _b The variable is named with an underscore and will not be output to YAML. It can be modified by multiple assignments -_b = 2 -alice = Person { - name = "Alice" - age = 18 -} -``` - -There are two ways of specifying that variables are immutable: - -- non-underscore top-level variables outside the schema - -```python -a = 1 # immutable exported variable -_b = 2 # mutable non-export variable -``` - -## 48. Is there a type like Go `interface{}`/`any` or Java `Object` in KCL? - -In KCL, we can use the `any` type annotation to define a variable to store any values such as integers, strings and schemas. For example: - -```python -schema Data: - id: int = 1 - -var_list: [any] = [1, "12", Data {}] -``` - -The output YAML is - -```yaml -var_list: - - 1 - - "12" - - id: 1 -``` - -In addition, we can also use the `typeof` function to determine the type of variables during KCL code execution: - -```python -schema Data1: - id: int = 1 - -schema Data2: - name: str = "name" - -data_list: [any] = [Data1 {}, Data2 {}] -data_type_list: [str] = [typeof(data) for data in data_list] -``` - -The output YAML is - -```yaml -data_list: - - id: 1 - - name: name -data_type_list: - - Data1 - - Data2 -``` - -## 49. How to develop a KCL plugin? - -KCL plugins are installed in the plugins subdirectory of KCL (usually installed in the `$HOME/.kcl/plugins` directory), or set through the `$KCL_PLUGINS_ROOT` environment variable. Besides, the `plugins` directory could also be placed at the `pwd` path. For plugin developers, plugins are managed in the [Git repository](https://github.com/kcl-lang/kcl-plugin), and the plugin repository can be cloned to this directory for development. - -KCL has built-in kcl-plugin scaffolding command to assist users to write KCL plug-ins in Python language, so that the corresponding plug-ins can be called in the KCL file to enhance the KCL language itself, such as accessing the network, reading and writing IO, CMDB query and encryption and decryption functions. - -``` -usage: kcl-plugin [-h] {list,init,info,gendoc,test} ... - -positional arguments: - {list,init,info,gendoc,test} - kcl plugin sub commands - list list all plugins - init init a new plugin - info show plugin document - gendoc gen all plugins document - test test plugin - -optional arguments: - -h, --help show this help message and exit -``` - -For example, if you want to develop a plugin named io, you can use the following command to successfully create a new io plugin - -``` -kcl-plugin init io -``` - -Then you can use the following command to get the root path of the plugin and cd to the corresponding io plugin directory for development - -``` -kcl-plugin info -``` - -For example, if you want to develop a function read_file to read a file, you can write python code in `plugin.py` of `$plugin_root/io`: - -```python -# Copyright 2020 The KCL Authors. All rights reserved. - -import pathlib - -INFO = { - 'name': 'io', - 'describe': 'my io plugin description test', - 'long_describe': 'my io plugin long description test', - 'version': '0.0.1', -} - - -def read_file(file: str) -> str: - """Read string from file""" - return pathlib.Path(file).read_text() - -``` - -In addition, you can write the corresponding test function in `plugin_test.py`, or you can directly write the following KCL file for testing: - -```python -import kcl_plugin.io - -text = io.read_file('test.txt') -``` - -You can also use the info command to view information about the io plugin - -``` -kcl-plugin info io -``` - -``` -{ - "name": "io", - "describe": "my io plugin description test", - "long_describe": "my io plugin long description test", - "version": "0.0.1", - "method": { - "read_file": "Read string from file" - } -} -``` - -Finally, the plugin that has written the test can be merged with MR in the `kcl_plugins` repository. - -## 50. How to do basic type conversion in KCL - -You can use the `int()`, `float()` function and `str()` function to convert the basic types between `int`, `float` and `str`. - -``` -_t = 1 - -t_str: str = str(_t) # you will get "t_str: '1'" -t_int: int = int(t_str) # you will get "t_int: 1" -t_float: float = float(t_str) # you will get "t_float: 1.0" -``` - -For more information about type conversion, see [KCL Builtin Types](https://kcl-lang.io/docs/reference/lang/tour#built-in-types) and [KCL Type System](https://kcl-lang.io/docs/reference/lang/tour#type-system). diff --git a/versioned_docs/version-0.5.6/user_docs/support/faq-yaml.md b/versioned_docs/version-0.5.6/user_docs/support/faq-yaml.md deleted file mode 100644 index b13a0f7a..00000000 --- a/versioned_docs/version-0.5.6/user_docs/support/faq-yaml.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -sidebar_position: 3 ---- - -# YAML - -## 1. What is the difference between single and double quote YAML strings? - -- YAML double-quoted strings are the only style that can express arbitrary strings, by using `\` escape characters, such as `\"` to escape double quotes `"`, `\\` to escape backslashes `\`, and a single backslash `\` can be used as a continuation character for double-quoted strings. -- YAML single-quoted strings differ from YAML double-quoted strings in that `\` and `"` can be used freely without escaping, but two single-quotes `''` are used to escape single-quote `'` characters. - -For the following example, the contents of the three string variables are the same. - -```yaml -string1: 'here '' s to "quotes"' -string2: 'here''s to "quotes"' -string3: here's to "quotes" -``` - -> Note: KCL's strategy for outputting YAML strings is to output unquoted strings or double-quoted strings preferentially when single quotes appear in the string content, and output single-quoted strings in other cases to avoid the burden of understanding. - -For more details, please refer to [YAML Spec v1.2](https://yaml.org/spec/1.2.1/) - -## 2. What is the meaning of symbols such as | - + > in YAML? - -When using KCL multi-line strings (triple quote strings), the output YAML often carries some special tokens, such as `|`, `-`, `+` and `>`, etc. These tokens usually are the representation method of YAML multi-line string, such as the following KCL code: - -```python -data = """This is a KCL multi line string (the first line) -This is a KCL multi line string (the second line) -This is a KCL multi line string (the third line) - - -""" -var = 1 -``` - -The output YAML is - -```yaml -data: |+ - This is a KCL multi line string (the first line) - This is a KCL multi line string (the second line) - This is a KCL multi line string (the third line) - - -var: 1 -``` - -- `|` represents **block style**, which is used to represent a multi-line string, where all newlines in the string represent the real newlines. -- `>` represents **folding style**, in which all newlines in the string will be replaced by spaces. -- `+` and `-` are used to control the use of newlines at the end of strings. The default is to keep a single newline at the end of the string. If we want to remove all newlines, we can put a `-` after the style indicator `|` or `>`. If we want to keep the newline at the end, we need to put a `+` after `|` or `>`. - -For more details, please refer to [YAML Multiline String](https://yaml-multiline.info/) and [YAML Spec v1.2](https://yaml.org/spec/1.2.1/) - -## 3. What is the meaning of numbers that appear after symbols | - + > such as |1 and |2 in YAML? - -Numbers represent **explicit indentation indicators** in YAML. For long strings in YAML, YAML usually the first non-blank line determines the indentation level of the string, and when the first non-blank line is preceded by a non-leading character, such as a newline, we must use **explicit indent indicators** to specify the indent level of the content, such as `|1` and `|2` etc. - -For example, for the following KCL code: - -```python -longStringStartWithNewline = """ -This is the second line -This is the third line -""" - -``` - -```yaml -longStringStartWithNewline: |2 - - This is the second line - This is the third line -``` - -- Writing long strings from the first line. - -```python -longString = """This is the second line -This is the third line -""" -``` - -- Writing long strings with line continuation characters. - -```python -longString = """\ -This is the second line -This is the third line -""" -``` - -The YAML output by the above two methods is: - -```yaml -longString: | - This is the second line - This is the third line -``` - -For more details, please refer to [YAML Spec v1.2](https://yaml.org/spec/1.2.1/) diff --git a/versioned_docs/version-0.5.6/user_docs/support/support.md b/versioned_docs/version-0.5.6/user_docs/support/support.md deleted file mode 100644 index fac13ef2..00000000 --- a/versioned_docs/version-0.5.6/user_docs/support/support.md +++ /dev/null @@ -1,3 +0,0 @@ -# FAQ - -KCL frequently asked questions. diff --git a/versioned_docs/version-0.5.0/community/contribute/_category_.json b/versioned_docs/version-0.5/community/contribute/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/community/contribute/_category_.json rename to versioned_docs/version-0.5/community/contribute/_category_.json diff --git a/versioned_docs/version-0.5.0/community/contribute/contribute-code.md b/versioned_docs/version-0.5/community/contribute/contribute-code.md similarity index 100% rename from versioned_docs/version-0.5.0/community/contribute/contribute-code.md rename to versioned_docs/version-0.5/community/contribute/contribute-code.md diff --git a/versioned_docs/version-0.5.0/community/contribute/contribute-docs.md b/versioned_docs/version-0.5/community/contribute/contribute-docs.md similarity index 100% rename from versioned_docs/version-0.5.0/community/contribute/contribute-docs.md rename to versioned_docs/version-0.5/community/contribute/contribute-docs.md diff --git a/versioned_docs/version-0.5.0/community/contribute/contribute.md b/versioned_docs/version-0.5/community/contribute/contribute.md similarity index 100% rename from versioned_docs/version-0.5.0/community/contribute/contribute.md rename to versioned_docs/version-0.5/community/contribute/contribute.md diff --git a/versioned_docs/version-0.5.0/community/contribute/git-guideline.md b/versioned_docs/version-0.5/community/contribute/git-guideline.md similarity index 100% rename from versioned_docs/version-0.5.0/community/contribute/git-guideline.md rename to versioned_docs/version-0.5/community/contribute/git-guideline.md diff --git a/versioned_docs/version-0.5.0/community/intro/_category_.json b/versioned_docs/version-0.5/community/intro/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/community/intro/_category_.json rename to versioned_docs/version-0.5/community/intro/_category_.json diff --git a/versioned_docs/version-0.5.0/community/intro/intro.md b/versioned_docs/version-0.5/community/intro/intro.md similarity index 100% rename from versioned_docs/version-0.5.0/community/intro/intro.md rename to versioned_docs/version-0.5/community/intro/intro.md diff --git a/versioned_docs/version-0.5.0/community/intro/license.md b/versioned_docs/version-0.5/community/intro/license.md similarity index 100% rename from versioned_docs/version-0.5.0/community/intro/license.md rename to versioned_docs/version-0.5/community/intro/license.md diff --git a/versioned_docs/version-0.5.0/community/intro/support.md b/versioned_docs/version-0.5/community/intro/support.md similarity index 100% rename from versioned_docs/version-0.5.0/community/intro/support.md rename to versioned_docs/version-0.5/community/intro/support.md diff --git a/versioned_docs/version-0.5.0/community/release-policy/_category_.json b/versioned_docs/version-0.5/community/release-policy/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/community/release-policy/_category_.json rename to versioned_docs/version-0.5/community/release-policy/_category_.json diff --git a/versioned_docs/version-0.5.0/community/release-policy/index.md b/versioned_docs/version-0.5/community/release-policy/index.md similarity index 100% rename from versioned_docs/version-0.5.0/community/release-policy/index.md rename to versioned_docs/version-0.5/community/release-policy/index.md diff --git a/versioned_docs/version-0.5.0/community/release-policy/kcl.md b/versioned_docs/version-0.5/community/release-policy/kcl.md similarity index 100% rename from versioned_docs/version-0.5.0/community/release-policy/kcl.md rename to versioned_docs/version-0.5/community/release-policy/kcl.md diff --git a/versioned_docs/version-0.5.0/community/release-policy/roadmap.md b/versioned_docs/version-0.5/community/release-policy/roadmap.md similarity index 100% rename from versioned_docs/version-0.5.0/community/release-policy/roadmap.md rename to versioned_docs/version-0.5/community/release-policy/roadmap.md diff --git a/versioned_docs/version-0.5.0/reference/_advanced-concepts/_category_.json b/versioned_docs/version-0.5/reference/_advanced-concepts/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/reference/_advanced-concepts/_category_.json rename to versioned_docs/version-0.5/reference/_advanced-concepts/_category_.json diff --git a/versioned_docs/version-0.5.0/reference/_advanced-concepts/build_cache.md b/versioned_docs/version-0.5/reference/_advanced-concepts/build_cache.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/_advanced-concepts/build_cache.md rename to versioned_docs/version-0.5/reference/_advanced-concepts/build_cache.md diff --git a/versioned_docs/version-0.5.0/reference/_category_.json b/versioned_docs/version-0.5/reference/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/reference/_category_.json rename to versioned_docs/version-0.5/reference/_category_.json diff --git a/versioned_docs/version-0.5.0/reference/cheatsheets/_category_.json b/versioned_docs/version-0.5/reference/cheatsheets/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/reference/cheatsheets/_category_.json rename to versioned_docs/version-0.5/reference/cheatsheets/_category_.json diff --git a/versioned_docs/version-0.5.0/reference/cheatsheets/index.md b/versioned_docs/version-0.5/reference/cheatsheets/index.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/cheatsheets/index.md rename to versioned_docs/version-0.5/reference/cheatsheets/index.md diff --git a/versioned_docs/version-0.5.0/reference/lang/_category_.json b/versioned_docs/version-0.5/reference/lang/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/reference/lang/_category_.json rename to versioned_docs/version-0.5/reference/lang/_category_.json diff --git a/versioned_docs/version-0.5.0/reference/lang/codelab/_category_.json b/versioned_docs/version-0.5/reference/lang/codelab/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/reference/lang/codelab/_category_.json rename to versioned_docs/version-0.5/reference/lang/codelab/_category_.json diff --git a/versioned_docs/version-0.5.0/reference/lang/codelab/collaborative.md b/versioned_docs/version-0.5/reference/lang/codelab/collaborative.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/lang/codelab/collaborative.md rename to versioned_docs/version-0.5/reference/lang/codelab/collaborative.md diff --git a/versioned_docs/version-0.5.0/reference/lang/codelab/index.md b/versioned_docs/version-0.5/reference/lang/codelab/index.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/lang/codelab/index.md rename to versioned_docs/version-0.5/reference/lang/codelab/index.md diff --git a/versioned_docs/version-0.5.0/reference/lang/codelab/schema.md b/versioned_docs/version-0.5/reference/lang/codelab/schema.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/lang/codelab/schema.md rename to versioned_docs/version-0.5/reference/lang/codelab/schema.md diff --git a/versioned_docs/version-0.5.0/reference/lang/codelab/simple.md b/versioned_docs/version-0.5/reference/lang/codelab/simple.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/lang/codelab/simple.md rename to versioned_docs/version-0.5/reference/lang/codelab/simple.md diff --git a/versioned_docs/version-0.5.0/reference/lang/error/_category_.json b/versioned_docs/version-0.5/reference/lang/error/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/reference/lang/error/_category_.json rename to versioned_docs/version-0.5/reference/lang/error/_category_.json diff --git a/versioned_docs/version-0.5.6/reference/lang/error/exception.md b/versioned_docs/version-0.5/reference/lang/error/exception.md similarity index 100% rename from versioned_docs/version-0.5.6/reference/lang/error/exception.md rename to versioned_docs/version-0.5/reference/lang/error/exception.md diff --git a/versioned_docs/version-0.5.0/reference/lang/error/index.md b/versioned_docs/version-0.5/reference/lang/error/index.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/lang/error/index.md rename to versioned_docs/version-0.5/reference/lang/error/index.md diff --git a/versioned_docs/version-0.5.0/reference/lang/spec/_category_.json b/versioned_docs/version-0.5/reference/lang/spec/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/reference/lang/spec/_category_.json rename to versioned_docs/version-0.5/reference/lang/spec/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/spec/codestyle.md b/versioned_docs/version-0.5/reference/lang/spec/codestyle.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/spec/codestyle.md rename to versioned_docs/version-0.5/reference/lang/spec/codestyle.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/datatypes.md b/versioned_docs/version-0.5/reference/lang/spec/datatypes.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/datatypes.md rename to versioned_docs/version-0.5/reference/lang/spec/datatypes.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/spec/error.md b/versioned_docs/version-0.5/reference/lang/spec/error.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/spec/error.md rename to versioned_docs/version-0.5/reference/lang/spec/error.md diff --git a/versioned_docs/version-0.5.5/reference/lang/spec/expressions.md b/versioned_docs/version-0.5/reference/lang/spec/expressions.md similarity index 100% rename from versioned_docs/version-0.5.5/reference/lang/spec/expressions.md rename to versioned_docs/version-0.5/reference/lang/spec/expressions.md diff --git a/versioned_docs/version-0.5.0/reference/lang/spec/index.md b/versioned_docs/version-0.5/reference/lang/spec/index.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/lang/spec/index.md rename to versioned_docs/version-0.5/reference/lang/spec/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/spec/kcl-spec.md b/versioned_docs/version-0.5/reference/lang/spec/kcl-spec.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/spec/kcl-spec.md rename to versioned_docs/version-0.5/reference/lang/spec/kcl-spec.md diff --git a/versioned_docs/version-0.5.0/reference/lang/spec/lexical.md b/versioned_docs/version-0.5/reference/lang/spec/lexical.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/lang/spec/lexical.md rename to versioned_docs/version-0.5/reference/lang/spec/lexical.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/spec/modules.md b/versioned_docs/version-0.5/reference/lang/spec/modules.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/spec/modules.md rename to versioned_docs/version-0.5/reference/lang/spec/modules.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/spec/schema.md b/versioned_docs/version-0.5/reference/lang/spec/schema.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/spec/schema.md rename to versioned_docs/version-0.5/reference/lang/spec/schema.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/spec/statements.md b/versioned_docs/version-0.5/reference/lang/spec/statements.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/lang/spec/statements.md rename to versioned_docs/version-0.5/reference/lang/spec/statements.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/variables.md b/versioned_docs/version-0.5/reference/lang/spec/variables.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/variables.md rename to versioned_docs/version-0.5/reference/lang/spec/variables.md diff --git a/versioned_docs/version-0.5.6/reference/lang/tour.md b/versioned_docs/version-0.5/reference/lang/tour.md similarity index 100% rename from versioned_docs/version-0.5.6/reference/lang/tour.md rename to versioned_docs/version-0.5/reference/lang/tour.md diff --git a/versioned_docs/version-0.5.0/reference/lang/types/_category_.json b/versioned_docs/version-0.5/reference/lang/types/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/reference/lang/types/_category_.json rename to versioned_docs/version-0.5/reference/lang/types/_category_.json diff --git a/versioned_docs/version-0.5.0/reference/lang/types/types.md b/versioned_docs/version-0.5/reference/lang/types/types.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/lang/types/types.md rename to versioned_docs/version-0.5/reference/lang/types/types.md diff --git a/versioned_docs/version-0.5.0/reference/model/_category_.json b/versioned_docs/version-0.5/reference/model/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/reference/model/_category_.json rename to versioned_docs/version-0.5/reference/model/_category_.json diff --git a/versioned_docs/version-0.5.0/reference/model/base64.md b/versioned_docs/version-0.5/reference/model/base64.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/model/base64.md rename to versioned_docs/version-0.5/reference/model/base64.md diff --git a/versioned_docs/version-0.5.0/reference/model/builtin.md b/versioned_docs/version-0.5/reference/model/builtin.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/model/builtin.md rename to versioned_docs/version-0.5/reference/model/builtin.md diff --git a/versioned_docs/version-0.5.0/reference/model/crypto.md b/versioned_docs/version-0.5/reference/model/crypto.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/model/crypto.md rename to versioned_docs/version-0.5/reference/model/crypto.md diff --git a/versioned_docs/version-0.5.6/reference/model/datetime.md b/versioned_docs/version-0.5/reference/model/datetime.md similarity index 100% rename from versioned_docs/version-0.5.6/reference/model/datetime.md rename to versioned_docs/version-0.5/reference/model/datetime.md diff --git a/versioned_docs/version-0.5.0/reference/model/index.md b/versioned_docs/version-0.5/reference/model/index.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/model/index.md rename to versioned_docs/version-0.5/reference/model/index.md diff --git a/versioned_docs/version-0.5.6/reference/model/json.md b/versioned_docs/version-0.5/reference/model/json.md similarity index 100% rename from versioned_docs/version-0.5.6/reference/model/json.md rename to versioned_docs/version-0.5/reference/model/json.md diff --git a/versioned_docs/version-0.5.0/reference/model/manifests.md b/versioned_docs/version-0.5/reference/model/manifests.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/model/manifests.md rename to versioned_docs/version-0.5/reference/model/manifests.md diff --git a/versioned_docs/version-0.5.6/reference/model/math.md b/versioned_docs/version-0.5/reference/model/math.md similarity index 100% rename from versioned_docs/version-0.5.6/reference/model/math.md rename to versioned_docs/version-0.5/reference/model/math.md diff --git a/versioned_docs/version-0.5.0/reference/model/net.md b/versioned_docs/version-0.5/reference/model/net.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/model/net.md rename to versioned_docs/version-0.5/reference/model/net.md diff --git a/versioned_docs/version-0.5.0/reference/model/overview.md b/versioned_docs/version-0.5/reference/model/overview.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/model/overview.md rename to versioned_docs/version-0.5/reference/model/overview.md diff --git a/versioned_docs/version-0.5.0/reference/model/regex.md b/versioned_docs/version-0.5/reference/model/regex.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/model/regex.md rename to versioned_docs/version-0.5/reference/model/regex.md diff --git a/versioned_docs/version-0.5.0/reference/model/units.md b/versioned_docs/version-0.5/reference/model/units.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/model/units.md rename to versioned_docs/version-0.5/reference/model/units.md diff --git a/versioned_docs/version-0.5.0/reference/model/yaml.md b/versioned_docs/version-0.5/reference/model/yaml.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/model/yaml.md rename to versioned_docs/version-0.5/reference/model/yaml.md diff --git a/versioned_docs/version-0.5.0/reference/package-management/_category_.json b/versioned_docs/version-0.5/reference/package-management/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/reference/package-management/_category_.json rename to versioned_docs/version-0.5/reference/package-management/_category_.json diff --git a/versioned_docs/version-0.5.0/reference/package-management/command-reference/1.init.md b/versioned_docs/version-0.5/reference/package-management/command-reference/1.init.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/package-management/command-reference/1.init.md rename to versioned_docs/version-0.5/reference/package-management/command-reference/1.init.md diff --git a/versioned_docs/version-0.5.0/reference/package-management/command-reference/10.help.md b/versioned_docs/version-0.5/reference/package-management/command-reference/10.help.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/package-management/command-reference/10.help.md rename to versioned_docs/version-0.5/reference/package-management/command-reference/10.help.md diff --git a/versioned_docs/version-0.5.0/reference/package-management/command-reference/2.add.md b/versioned_docs/version-0.5/reference/package-management/command-reference/2.add.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/package-management/command-reference/2.add.md rename to versioned_docs/version-0.5/reference/package-management/command-reference/2.add.md diff --git a/versioned_docs/version-0.5.0/reference/package-management/command-reference/3.pkg.md b/versioned_docs/version-0.5/reference/package-management/command-reference/3.pkg.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/package-management/command-reference/3.pkg.md rename to versioned_docs/version-0.5/reference/package-management/command-reference/3.pkg.md diff --git a/versioned_docs/version-0.5.0/reference/package-management/command-reference/4.metadata.md b/versioned_docs/version-0.5/reference/package-management/command-reference/4.metadata.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/package-management/command-reference/4.metadata.md rename to versioned_docs/version-0.5/reference/package-management/command-reference/4.metadata.md diff --git a/versioned_docs/version-0.5.0/reference/package-management/command-reference/5.run.md b/versioned_docs/version-0.5/reference/package-management/command-reference/5.run.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/package-management/command-reference/5.run.md rename to versioned_docs/version-0.5/reference/package-management/command-reference/5.run.md diff --git a/versioned_docs/version-0.5.0/reference/package-management/command-reference/6.login.md b/versioned_docs/version-0.5/reference/package-management/command-reference/6.login.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/package-management/command-reference/6.login.md rename to versioned_docs/version-0.5/reference/package-management/command-reference/6.login.md diff --git a/versioned_docs/version-0.5.0/reference/package-management/command-reference/7.logout.md b/versioned_docs/version-0.5/reference/package-management/command-reference/7.logout.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/package-management/command-reference/7.logout.md rename to versioned_docs/version-0.5/reference/package-management/command-reference/7.logout.md diff --git a/versioned_docs/version-0.5.0/reference/package-management/command-reference/8.push.md b/versioned_docs/version-0.5/reference/package-management/command-reference/8.push.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/package-management/command-reference/8.push.md rename to versioned_docs/version-0.5/reference/package-management/command-reference/8.push.md diff --git a/versioned_docs/version-0.5.0/reference/package-management/command-reference/9.pull.md b/versioned_docs/version-0.5/reference/package-management/command-reference/9.pull.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/package-management/command-reference/9.pull.md rename to versioned_docs/version-0.5/reference/package-management/command-reference/9.pull.md diff --git a/versioned_docs/version-0.5.0/reference/package-management/command-reference/_category_.json b/versioned_docs/version-0.5/reference/package-management/command-reference/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/reference/package-management/command-reference/_category_.json rename to versioned_docs/version-0.5/reference/package-management/command-reference/_category_.json diff --git a/versioned_docs/version-0.5.0/reference/package-management/command-reference/index.md b/versioned_docs/version-0.5/reference/package-management/command-reference/index.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/package-management/command-reference/index.md rename to versioned_docs/version-0.5/reference/package-management/command-reference/index.md diff --git a/versioned_docs/version-0.5.0/reference/plugin/_category_.json b/versioned_docs/version-0.5/reference/plugin/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/reference/plugin/_category_.json rename to versioned_docs/version-0.5/reference/plugin/_category_.json diff --git a/versioned_docs/version-0.5.0/reference/plugin/index.md b/versioned_docs/version-0.5/reference/plugin/index.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/plugin/index.md rename to versioned_docs/version-0.5/reference/plugin/index.md diff --git a/versioned_docs/version-0.5.0/reference/plugin/overview.md b/versioned_docs/version-0.5/reference/plugin/overview.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/plugin/overview.md rename to versioned_docs/version-0.5/reference/plugin/overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/plugin/project_context.md b/versioned_docs/version-0.5/reference/plugin/project_context.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/plugin/project_context.md rename to versioned_docs/version-0.5/reference/plugin/project_context.md diff --git a/versioned_docs/version-0.5.0/reference/xlang-api/_category_.json b/versioned_docs/version-0.5/reference/xlang-api/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/reference/xlang-api/_category_.json rename to versioned_docs/version-0.5/reference/xlang-api/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/xlang-api/go-api.md b/versioned_docs/version-0.5/reference/xlang-api/go-api.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.2/reference/xlang-api/go-api.md rename to versioned_docs/version-0.5/reference/xlang-api/go-api.md diff --git a/versioned_docs/version-0.5.0/reference/xlang-api/index.md b/versioned_docs/version-0.5/reference/xlang-api/index.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/xlang-api/index.md rename to versioned_docs/version-0.5/reference/xlang-api/index.md diff --git a/versioned_docs/version-0.5.0/reference/xlang-api/java-api.md b/versioned_docs/version-0.5/reference/xlang-api/java-api.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/xlang-api/java-api.md rename to versioned_docs/version-0.5/reference/xlang-api/java-api.md diff --git a/versioned_docs/version-0.5.0/reference/xlang-api/overview.md b/versioned_docs/version-0.5/reference/xlang-api/overview.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/xlang-api/overview.md rename to versioned_docs/version-0.5/reference/xlang-api/overview.md diff --git a/versioned_docs/version-0.5.0/reference/xlang-api/python-api.md b/versioned_docs/version-0.5/reference/xlang-api/python-api.md similarity index 100% rename from versioned_docs/version-0.5.0/reference/xlang-api/python-api.md rename to versioned_docs/version-0.5/reference/xlang-api/python-api.md diff --git a/versioned_docs/version-0.5.5/reference/xlang-api/rest-api.md b/versioned_docs/version-0.5/reference/xlang-api/rest-api.md similarity index 100% rename from versioned_docs/version-0.5.5/reference/xlang-api/rest-api.md rename to versioned_docs/version-0.5/reference/xlang-api/rest-api.md diff --git a/versioned_docs/version-0.5.0/tools/Ide/_category_.json b/versioned_docs/version-0.5/tools/Ide/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/tools/Ide/_category_.json rename to versioned_docs/version-0.5/tools/Ide/_category_.json diff --git a/versioned_docs/version-0.5.0/tools/Ide/index.md b/versioned_docs/version-0.5/tools/Ide/index.md similarity index 100% rename from versioned_docs/version-0.5.0/tools/Ide/index.md rename to versioned_docs/version-0.5/tools/Ide/index.md diff --git a/versioned_docs/version-0.5.5/tools/Ide/intellij.md b/versioned_docs/version-0.5/tools/Ide/intellij.md similarity index 100% rename from versioned_docs/version-0.5.5/tools/Ide/intellij.md rename to versioned_docs/version-0.5/tools/Ide/intellij.md diff --git a/versioned_docs/version-0.5.5/tools/Ide/neovim.md b/versioned_docs/version-0.5/tools/Ide/neovim.md similarity index 100% rename from versioned_docs/version-0.5.5/tools/Ide/neovim.md rename to versioned_docs/version-0.5/tools/Ide/neovim.md diff --git a/versioned_docs/version-0.5.5/tools/Ide/vs-code.md b/versioned_docs/version-0.5/tools/Ide/vs-code.md similarity index 100% rename from versioned_docs/version-0.5.5/tools/Ide/vs-code.md rename to versioned_docs/version-0.5/tools/Ide/vs-code.md diff --git a/versioned_docs/version-0.5.0/tools/_category_.json b/versioned_docs/version-0.5/tools/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/tools/_category_.json rename to versioned_docs/version-0.5/tools/_category_.json diff --git a/versioned_docs/version-0.5.0/tools/cli/_category_.json b/versioned_docs/version-0.5/tools/cli/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/tools/cli/_category_.json rename to versioned_docs/version-0.5/tools/cli/_category_.json diff --git a/versioned_docs/version-0.5.0/tools/cli/index.md b/versioned_docs/version-0.5/tools/cli/index.md similarity index 100% rename from versioned_docs/version-0.5.0/tools/cli/index.md rename to versioned_docs/version-0.5/tools/cli/index.md diff --git a/versioned_docs/version-0.5.0/tools/cli/kcl/_category_.json b/versioned_docs/version-0.5/tools/cli/kcl/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/tools/cli/kcl/_category_.json rename to versioned_docs/version-0.5/tools/cli/kcl/_category_.json diff --git a/versioned_docs/version-0.5.0/tools/cli/kcl/docgen.md b/versioned_docs/version-0.5/tools/cli/kcl/docgen.md similarity index 100% rename from versioned_docs/version-0.5.0/tools/cli/kcl/docgen.md rename to versioned_docs/version-0.5/tools/cli/kcl/docgen.md diff --git a/versioned_docs/version-0.5.5/tools/cli/kcl/fmt.md b/versioned_docs/version-0.5/tools/cli/kcl/fmt.md similarity index 100% rename from versioned_docs/version-0.5.5/tools/cli/kcl/fmt.md rename to versioned_docs/version-0.5/tools/cli/kcl/fmt.md diff --git a/versioned_docs/version-0.5.0/tools/cli/kcl/index.md b/versioned_docs/version-0.5/tools/cli/kcl/index.md similarity index 100% rename from versioned_docs/version-0.5.0/tools/cli/kcl/index.md rename to versioned_docs/version-0.5/tools/cli/kcl/index.md diff --git a/versioned_docs/version-0.5.5/tools/cli/kcl/lint.md b/versioned_docs/version-0.5/tools/cli/kcl/lint.md similarity index 100% rename from versioned_docs/version-0.5.5/tools/cli/kcl/lint.md rename to versioned_docs/version-0.5/tools/cli/kcl/lint.md diff --git a/versioned_docs/version-0.5.1/tools/cli/kcl/overview.md b/versioned_docs/version-0.5/tools/cli/kcl/overview.md similarity index 100% rename from versioned_docs/version-0.5.1/tools/cli/kcl/overview.md rename to versioned_docs/version-0.5/tools/cli/kcl/overview.md diff --git a/versioned_docs/version-0.5.0/tools/cli/kcl/test.md b/versioned_docs/version-0.5/tools/cli/kcl/test.md similarity index 100% rename from versioned_docs/version-0.5.0/tools/cli/kcl/test.md rename to versioned_docs/version-0.5/tools/cli/kcl/test.md diff --git a/versioned_docs/version-0.5.0/tools/cli/kcl/vet.md b/versioned_docs/version-0.5/tools/cli/kcl/vet.md similarity index 100% rename from versioned_docs/version-0.5.0/tools/cli/kcl/vet.md rename to versioned_docs/version-0.5/tools/cli/kcl/vet.md diff --git a/versioned_docs/version-0.5.0/tools/cli/openapi/_category_.json b/versioned_docs/version-0.5/tools/cli/openapi/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/tools/cli/openapi/_category_.json rename to versioned_docs/version-0.5/tools/cli/openapi/_category_.json diff --git a/versioned_docs/version-0.5.0/tools/cli/openapi/crd-to-kcl.md b/versioned_docs/version-0.5/tools/cli/openapi/crd-to-kcl.md similarity index 100% rename from versioned_docs/version-0.5.0/tools/cli/openapi/crd-to-kcl.md rename to versioned_docs/version-0.5/tools/cli/openapi/crd-to-kcl.md diff --git a/versioned_docs/version-0.5.0/tools/cli/openapi/index.md b/versioned_docs/version-0.5/tools/cli/openapi/index.md similarity index 100% rename from versioned_docs/version-0.5.0/tools/cli/openapi/index.md rename to versioned_docs/version-0.5/tools/cli/openapi/index.md diff --git a/versioned_docs/version-0.5.0/tools/cli/openapi/openapi-to-kcl.md b/versioned_docs/version-0.5/tools/cli/openapi/openapi-to-kcl.md similarity index 100% rename from versioned_docs/version-0.5.0/tools/cli/openapi/openapi-to-kcl.md rename to versioned_docs/version-0.5/tools/cli/openapi/openapi-to-kcl.md diff --git a/versioned_docs/version-0.5.5/tools/cli/openapi/quick-start.md b/versioned_docs/version-0.5/tools/cli/openapi/quick-start.md similarity index 100% rename from versioned_docs/version-0.5.5/tools/cli/openapi/quick-start.md rename to versioned_docs/version-0.5/tools/cli/openapi/quick-start.md diff --git a/versioned_docs/version-0.5.5/tools/cli/openapi/spec.md b/versioned_docs/version-0.5/tools/cli/openapi/spec.md similarity index 100% rename from versioned_docs/version-0.5.5/tools/cli/openapi/spec.md rename to versioned_docs/version-0.5/tools/cli/openapi/spec.md diff --git a/versioned_docs/version-0.5.0/user_docs/concepts/_category_.json b/versioned_docs/version-0.5/user_docs/concepts/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/concepts/_category_.json rename to versioned_docs/version-0.5/user_docs/concepts/_category_.json diff --git a/versioned_docs/version-0.5.0/user_docs/concepts/concepts.md b/versioned_docs/version-0.5/user_docs/concepts/concepts.md similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/concepts/concepts.md rename to versioned_docs/version-0.5/user_docs/concepts/concepts.md diff --git a/versioned_docs/version-0.5.0/user_docs/concepts/package-and-module.md b/versioned_docs/version-0.5/user_docs/concepts/package-and-module.md similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/concepts/package-and-module.md rename to versioned_docs/version-0.5/user_docs/concepts/package-and-module.md diff --git a/versioned_docs/version-0.5.4/user_docs/concepts/type-and-definition.md b/versioned_docs/version-0.5/user_docs/concepts/type-and-definition.md similarity index 100% rename from versioned_docs/version-0.5.4/user_docs/concepts/type-and-definition.md rename to versioned_docs/version-0.5/user_docs/concepts/type-and-definition.md diff --git a/versioned_docs/version-0.5.0/user_docs/getting-started/_category_.json b/versioned_docs/version-0.5/user_docs/getting-started/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/getting-started/_category_.json rename to versioned_docs/version-0.5/user_docs/getting-started/_category_.json diff --git a/versioned_docs/version-0.5.0/user_docs/getting-started/index.md b/versioned_docs/version-0.5/user_docs/getting-started/index.md similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/getting-started/index.md rename to versioned_docs/version-0.5/user_docs/getting-started/index.md diff --git a/versioned_docs/version-0.5.5/user_docs/getting-started/install.md b/versioned_docs/version-0.5/user_docs/getting-started/install.md similarity index 100% rename from versioned_docs/version-0.5.5/user_docs/getting-started/install.md rename to versioned_docs/version-0.5/user_docs/getting-started/install.md diff --git a/versioned_docs/version-0.5.0/user_docs/getting-started/intro.md b/versioned_docs/version-0.5/user_docs/getting-started/intro.md similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/getting-started/intro.md rename to versioned_docs/version-0.5/user_docs/getting-started/intro.md diff --git a/versioned_docs/version-0.5.0/user_docs/getting-started/kcl-quick-start.md b/versioned_docs/version-0.5/user_docs/getting-started/kcl-quick-start.md similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/getting-started/kcl-quick-start.md rename to versioned_docs/version-0.5/user_docs/getting-started/kcl-quick-start.md diff --git a/versioned_docs/version-0.5.0/user_docs/guides/_category_.json b/versioned_docs/version-0.5/user_docs/guides/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/guides/_category_.json rename to versioned_docs/version-0.5/user_docs/guides/_category_.json diff --git a/versioned_docs/version-0.5.0/user_docs/guides/_working-with-terraform/1-overview.md b/versioned_docs/version-0.5/user_docs/guides/_working-with-terraform/1-overview.md similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/guides/_working-with-terraform/1-overview.md rename to versioned_docs/version-0.5/user_docs/guides/_working-with-terraform/1-overview.md diff --git a/versioned_docs/version-0.5.0/user_docs/guides/_working-with-terraform/2-abstraction.md b/versioned_docs/version-0.5/user_docs/guides/_working-with-terraform/2-abstraction.md similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/guides/_working-with-terraform/2-abstraction.md rename to versioned_docs/version-0.5/user_docs/guides/_working-with-terraform/2-abstraction.md diff --git a/versioned_docs/version-0.5.0/user_docs/guides/_working-with-terraform/3-coverter.md b/versioned_docs/version-0.5/user_docs/guides/_working-with-terraform/3-coverter.md similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/guides/_working-with-terraform/3-coverter.md rename to versioned_docs/version-0.5/user_docs/guides/_working-with-terraform/3-coverter.md diff --git a/versioned_docs/version-0.5.0/user_docs/guides/_working-with-terraform/_category_.json b/versioned_docs/version-0.5/user_docs/guides/_working-with-terraform/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/guides/_working-with-terraform/_category_.json rename to versioned_docs/version-0.5/user_docs/guides/_working-with-terraform/_category_.json diff --git a/versioned_docs/version-0.5.2/user_docs/guides/abstraction.md b/versioned_docs/version-0.5/user_docs/guides/abstraction.md similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/guides/abstraction.md rename to versioned_docs/version-0.5/user_docs/guides/abstraction.md diff --git a/versioned_docs/version-0.5.2/user_docs/guides/automation.md b/versioned_docs/version-0.5/user_docs/guides/automation.md similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/guides/automation.md rename to versioned_docs/version-0.5/user_docs/guides/automation.md diff --git a/versioned_docs/version-0.5.2/user_docs/guides/ci-integration/1-github-actions.md b/versioned_docs/version-0.5/user_docs/guides/ci-integration/1-github-actions.md similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/guides/ci-integration/1-github-actions.md rename to versioned_docs/version-0.5/user_docs/guides/ci-integration/1-github-actions.md diff --git a/versioned_docs/version-0.5.2/user_docs/guides/ci-integration/2-gitlab-ci.md b/versioned_docs/version-0.5/user_docs/guides/ci-integration/2-gitlab-ci.md similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/guides/ci-integration/2-gitlab-ci.md rename to versioned_docs/version-0.5/user_docs/guides/ci-integration/2-gitlab-ci.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/ci-integration/_3-jenkins-ci.md b/versioned_docs/version-0.5/user_docs/guides/ci-integration/_3-jenkins-ci.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/ci-integration/_3-jenkins-ci.md rename to versioned_docs/version-0.5/user_docs/guides/ci-integration/_3-jenkins-ci.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/ci-integration/_category_.json b/versioned_docs/version-0.5/user_docs/guides/ci-integration/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/ci-integration/_category_.json rename to versioned_docs/version-0.5/user_docs/guides/ci-integration/_category_.json diff --git a/versioned_docs/version-0.5.2/user_docs/guides/configuration.md b/versioned_docs/version-0.5/user_docs/guides/configuration.md similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/guides/configuration.md rename to versioned_docs/version-0.5/user_docs/guides/configuration.md diff --git a/versioned_docs/version-0.5.2/user_docs/guides/data-integration.md b/versioned_docs/version-0.5/user_docs/guides/data-integration.md similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/guides/data-integration.md rename to versioned_docs/version-0.5/user_docs/guides/data-integration.md diff --git a/versioned_docs/version-0.5.2/user_docs/guides/gitops/1-quick-start.md b/versioned_docs/version-0.5/user_docs/guides/gitops/1-quick-start.md similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/guides/gitops/1-quick-start.md rename to versioned_docs/version-0.5/user_docs/guides/gitops/1-quick-start.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/gitops/_category_.json b/versioned_docs/version-0.5/user_docs/guides/gitops/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/gitops/_category_.json rename to versioned_docs/version-0.5/user_docs/guides/gitops/_category_.json diff --git a/versioned_docs/version-0.5.0/user_docs/guides/index.md b/versioned_docs/version-0.5/user_docs/guides/index.md similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/guides/index.md rename to versioned_docs/version-0.5/user_docs/guides/index.md diff --git a/versioned_docs/version-0.5.0/user_docs/guides/package-management/1-overview.md b/versioned_docs/version-0.5/user_docs/guides/package-management/1-overview.md similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/guides/package-management/1-overview.md rename to versioned_docs/version-0.5/user_docs/guides/package-management/1-overview.md diff --git a/versioned_docs/version-0.5.2/user_docs/guides/package-management/2-installation.md b/versioned_docs/version-0.5/user_docs/guides/package-management/2-installation.md similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/guides/package-management/2-installation.md rename to versioned_docs/version-0.5/user_docs/guides/package-management/2-installation.md diff --git a/versioned_docs/version-0.5.2/user_docs/guides/package-management/3-quick-start.md b/versioned_docs/version-0.5/user_docs/guides/package-management/3-quick-start.md similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/guides/package-management/3-quick-start.md rename to versioned_docs/version-0.5/user_docs/guides/package-management/3-quick-start.md diff --git a/versioned_docs/version-0.5.0/user_docs/guides/package-management/_category_.json b/versioned_docs/version-0.5/user_docs/guides/package-management/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/guides/package-management/_category_.json rename to versioned_docs/version-0.5/user_docs/guides/package-management/_category_.json diff --git a/versioned_docs/version-0.5.6/user_docs/guides/package-management/how-to/4-share_your_pkg.md b/versioned_docs/version-0.5/user_docs/guides/package-management/how-to/4-share_your_pkg.md similarity index 100% rename from versioned_docs/version-0.5.6/user_docs/guides/package-management/how-to/4-share_your_pkg.md rename to versioned_docs/version-0.5/user_docs/guides/package-management/how-to/4-share_your_pkg.md diff --git a/versioned_docs/version-0.5.6/user_docs/guides/package-management/how-to/5-share_your_pkg_docker.md b/versioned_docs/version-0.5/user_docs/guides/package-management/how-to/5-share_your_pkg_docker.md similarity index 100% rename from versioned_docs/version-0.5.6/user_docs/guides/package-management/how-to/5-share_your_pkg_docker.md rename to versioned_docs/version-0.5/user_docs/guides/package-management/how-to/5-share_your_pkg_docker.md diff --git a/versioned_docs/version-0.5.6/user_docs/guides/package-management/how-to/6-push_github_action.md b/versioned_docs/version-0.5/user_docs/guides/package-management/how-to/6-push_github_action.md similarity index 100% rename from versioned_docs/version-0.5.6/user_docs/guides/package-management/how-to/6-push_github_action.md rename to versioned_docs/version-0.5/user_docs/guides/package-management/how-to/6-push_github_action.md diff --git a/versioned_docs/version-0.5.6/user_docs/guides/package-management/how-to/_category_.json b/versioned_docs/version-0.5/user_docs/guides/package-management/how-to/_category_.json similarity index 100% rename from versioned_docs/version-0.5.6/user_docs/guides/package-management/how-to/_category_.json rename to versioned_docs/version-0.5/user_docs/guides/package-management/how-to/_category_.json diff --git a/versioned_docs/version-0.5.2/user_docs/guides/schema-definition.md b/versioned_docs/version-0.5/user_docs/guides/schema-definition.md similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/guides/schema-definition.md rename to versioned_docs/version-0.5/user_docs/guides/schema-definition.md diff --git a/versioned_docs/version-0.5.1/user_docs/guides/secret-management/1-vault.md b/versioned_docs/version-0.5/user_docs/guides/secret-management/1-vault.md similarity index 100% rename from versioned_docs/version-0.5.1/user_docs/guides/secret-management/1-vault.md rename to versioned_docs/version-0.5/user_docs/guides/secret-management/1-vault.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/secret-management/_category_.json b/versioned_docs/version-0.5/user_docs/guides/secret-management/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/secret-management/_category_.json rename to versioned_docs/version-0.5/user_docs/guides/secret-management/_category_.json diff --git a/versioned_docs/version-0.5.2/user_docs/guides/validation.md b/versioned_docs/version-0.5/user_docs/guides/validation.md similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/guides/validation.md rename to versioned_docs/version-0.5/user_docs/guides/validation.md diff --git a/versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md b/versioned_docs/version-0.5/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md rename to versioned_docs/version-0.5/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md diff --git a/versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md b/versioned_docs/version-0.5/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md rename to versioned_docs/version-0.5/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md diff --git a/versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md b/versioned_docs/version-0.5/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md rename to versioned_docs/version-0.5/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md diff --git a/versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md b/versioned_docs/version-0.5/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md rename to versioned_docs/version-0.5/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md diff --git a/versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md b/versioned_docs/version-0.5/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md rename to versioned_docs/version-0.5/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md diff --git a/versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md b/versioned_docs/version-0.5/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md rename to versioned_docs/version-0.5/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md diff --git a/versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md b/versioned_docs/version-0.5/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md rename to versioned_docs/version-0.5/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md diff --git a/versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/6-kcl-operator.md b/versioned_docs/version-0.5/user_docs/guides/working-with-k8s/3-mutate-manifests/6-kcl-operator.md similarity index 100% rename from versioned_docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/6-kcl-operator.md rename to versioned_docs/version-0.5/user_docs/guides/working-with-k8s/3-mutate-manifests/6-kcl-operator.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json b/versioned_docs/version-0.5/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json rename to versioned_docs/version-0.5/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/_category_.json b/versioned_docs/version-0.5/user_docs/guides/working-with-k8s/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/_category_.json rename to versioned_docs/version-0.5/user_docs/guides/working-with-k8s/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/index.md b/versioned_docs/version-0.5/user_docs/guides/working-with-k8s/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-k8s/index.md rename to versioned_docs/version-0.5/user_docs/guides/working-with-k8s/index.md diff --git a/versioned_docs/version-0.5.0/user_docs/guides/working-with-konfig/1-overview.md b/versioned_docs/version-0.5/user_docs/guides/working-with-konfig/1-overview.md similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/guides/working-with-konfig/1-overview.md rename to versioned_docs/version-0.5/user_docs/guides/working-with-konfig/1-overview.md diff --git a/versioned_docs/version-0.5.0/user_docs/guides/working-with-konfig/2-structure.md b/versioned_docs/version-0.5/user_docs/guides/working-with-konfig/2-structure.md similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/guides/working-with-konfig/2-structure.md rename to versioned_docs/version-0.5/user_docs/guides/working-with-konfig/2-structure.md diff --git a/versioned_docs/version-0.5.0/user_docs/guides/working-with-konfig/3-quick-start.md b/versioned_docs/version-0.5/user_docs/guides/working-with-konfig/3-quick-start.md similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/guides/working-with-konfig/3-quick-start.md rename to versioned_docs/version-0.5/user_docs/guides/working-with-konfig/3-quick-start.md diff --git a/versioned_docs/version-0.5.0/user_docs/guides/working-with-konfig/4-best-practice.md b/versioned_docs/version-0.5/user_docs/guides/working-with-konfig/4-best-practice.md similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/guides/working-with-konfig/4-best-practice.md rename to versioned_docs/version-0.5/user_docs/guides/working-with-konfig/4-best-practice.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-konfig/_category_.json b/versioned_docs/version-0.5/user_docs/guides/working-with-konfig/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/user_docs/guides/working-with-konfig/_category_.json rename to versioned_docs/version-0.5/user_docs/guides/working-with-konfig/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-kusion/_category_.json b/versioned_docs/version-0.5/user_docs/guides/working-with-kusion/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-kusion/_category_.json rename to versioned_docs/version-0.5/user_docs/guides/working-with-kusion/_category_.json diff --git a/versioned_docs/version-0.5.0/user_docs/guides/working-with-kusion/index.md b/versioned_docs/version-0.5/user_docs/guides/working-with-kusion/index.md similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/guides/working-with-kusion/index.md rename to versioned_docs/version-0.5/user_docs/guides/working-with-kusion/index.md diff --git a/versioned_docs/version-0.5.0/user_docs/support/_category_.json b/versioned_docs/version-0.5/user_docs/support/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/support/_category_.json rename to versioned_docs/version-0.5/user_docs/support/_category_.json diff --git a/versioned_docs/version-0.5.0/user_docs/support/faq-cli.md b/versioned_docs/version-0.5/user_docs/support/faq-cli.md similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/support/faq-cli.md rename to versioned_docs/version-0.5/user_docs/support/faq-cli.md diff --git a/versioned_docs/version-0.5.0/user_docs/support/faq-install.md b/versioned_docs/version-0.5/user_docs/support/faq-install.md similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/support/faq-install.md rename to versioned_docs/version-0.5/user_docs/support/faq-install.md diff --git a/versioned_docs/version-0.5.0/user_docs/support/faq-kcl.md b/versioned_docs/version-0.5/user_docs/support/faq-kcl.md similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/support/faq-kcl.md rename to versioned_docs/version-0.5/user_docs/support/faq-kcl.md diff --git a/versioned_docs/version-0.5.0/user_docs/support/faq-yaml.md b/versioned_docs/version-0.5/user_docs/support/faq-yaml.md similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/support/faq-yaml.md rename to versioned_docs/version-0.5/user_docs/support/faq-yaml.md diff --git a/versioned_docs/version-0.5.0/user_docs/support/support.md b/versioned_docs/version-0.5/user_docs/support/support.md similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/support/support.md rename to versioned_docs/version-0.5/user_docs/support/support.md diff --git a/versioned_docs/version-0.6.0/community/contribute/_category_.json b/versioned_docs/version-0.6.0/community/contribute/_category_.json deleted file mode 100644 index e2dca064..00000000 --- a/versioned_docs/version-0.6.0/community/contribute/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Contribution Guide", - "position": 4 -} diff --git a/versioned_docs/version-0.6.0/community/contribute/contribute-code.md b/versioned_docs/version-0.6.0/community/contribute/contribute-code.md deleted file mode 100644 index f4e9169b..00000000 --- a/versioned_docs/version-0.6.0/community/contribute/contribute-code.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -sidebar_position: 2 ---- - -# How to Contribute Code? - -Welcome to participate in the KCL co construction to improve the code, documentation and testing, and also welcome to provide feedback through Issues. If you want to add KCL language features, please submit through the [KEP](https://github.com/kcl-lang/KEP) process. - -## 1. Misspellings in Code and Comments - -If you only need to modify the typos in the code and comments, you can directly modify and submit the PR to the repository. It is important to keep the code style as consistent as possible. - -## 2. How to Contribute KCL - -See [KCL contribute guide](https://github.com/kcl-lang/kcl/blob/main/docs/dev_guide/1.about_this_guide.md) for more information. - -## 3. How to Contribute VS Code KCL Plugin - -See [VS Code KCL plugin contribute guide](https://github.com/kcl-lang/vscode-kcl/blob/main/docs/CONTRIBUTING.md) for more information. diff --git a/versioned_docs/version-0.6.0/community/contribute/contribute-docs.md b/versioned_docs/version-0.6.0/community/contribute/contribute-docs.md deleted file mode 100644 index 2b400a52..00000000 --- a/versioned_docs/version-0.6.0/community/contribute/contribute-docs.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -sidebar_position: 1 ---- - -# How to Contribute Document? - -This document mainly makes partial modifications to existing documents. If you are submitting blog posts, adding new documents or adjusting the document directory structure, please contact team members first. - -KCL documents are divided into user guides, development documents, internal documents, reference manuals and blog articles. Their differences are as follows: - -- User's Guide: The corresponding usage document allows users to quickly use the KCL tool to complete their work at the minimum cost, without involving too much internal principles and implementation -- Reference: KCL language, tools, IDE and other documents with all features, covering the most extensive but trivial content -- Blog: There are no special restrictions. They can be shared for specific scenarios, technical points or overall development prospects - -When contributing different types of documents, it is better to combine the above positioning to make some appropriate tailoring for different content to give readers the best experience. - -## 1. Basic Specifications - -- In addition to the title, the internal subtitles shall be numbered as much as possible for easy reading -- The document automatically output by the tool needs a link to the source code, and the subtitle can be without number -- Try not to paste large pieces of code (within 30 lines). It is better to provide text explanations and corresponding reference links for the code -- There are diagrams and truths, but overly complex architecture diagrams are not recommended -- Internal link: in the form of [`/docs/user_docs/getting-started/intro`](/docs/user_docs/getting-started/intro) absolute path - -**Punctuation and space** - -- Chinese punctuation is preferred in Chinese documents -- One space is required between Chinese and English -- One space needs to be added between Chinese and numbers -- Chinese uses full width punctuation without adding spaces before and after punctuation -- English content uses half width punctuation, with a space after the punctuation -- You need to leave a space before and after the link, but you do not need to add a space near the beginning of the paragraph and Chinese full width punctuation. - -**Picture and resource file names** - -- The file name and directory name can only use numbers, English letters and underscores`_` And minus sign '-' -- Pictures of the current document are placed in the images directory of the current directory -- Vector pictures can be viewed through [drawio offline version](https://github.com/jgraph/drawio-desktop/releases) (and submit source files at the same time), and export png format pictures at 200% resolution - -## 2. Basic mode of using document content - -Each usage document can be regarded as a relatively complete sharing or blog post (the reference manual is no longer such). Using documents to organize content follows the following pattern: - -1. Overview: What problems do you want to solve and what effects do you want to achieve in this article? You can put a screenshot of the final effect first -2. Dependent environment: what tools need to be installed, and provide relevant links -3. Introduce this article to build a relationship diagram or architecture diagram of resources -4. Give the test method. Try to use community common methods (such as kube, curl command, or browser) to test -5. Summary and Outlook. Briefly review the current operation process and some places that can be expanded (some links can be given) - -## 3. Test and submit PR - -First, clone the document warehouse, and then test the viewing effect locally with the 'npm run start' and 'npm run build' commands to ensure that you can browse normally and then submit PR. diff --git a/versioned_docs/version-0.6.0/community/contribute/contribute.md b/versioned_docs/version-0.6.0/community/contribute/contribute.md deleted file mode 100644 index dd6e2b3f..00000000 --- a/versioned_docs/version-0.6.0/community/contribute/contribute.md +++ /dev/null @@ -1,3 +0,0 @@ -# Contribute Guide - -If it is the first time to participate in the open-source community, you can first check the similar changes in Issue and PR (PullRequest). Then you can fully discuss your own problems with the community or development team classmates, and you can also feedback the problems encountered by creating issues, and then you can provide code patches for related issues. At the beginning, you can start with document improvement and partial code improvement, such as: documentation, Examples, multi-language Binding, etc. At the same time, students who want to participate deeply can contribute to core features such as language functions, language testing, programming frameworks, and various backends. diff --git a/versioned_docs/version-0.6.0/community/contribute/git-guideline.md b/versioned_docs/version-0.6.0/community/contribute/git-guideline.md deleted file mode 100644 index 7d427c01..00000000 --- a/versioned_docs/version-0.6.0/community/contribute/git-guideline.md +++ /dev/null @@ -1,130 +0,0 @@ -# Git Commit Guide - -This document describes the matters needing attention when Git submits changes. If you refuse to accept the contents of this article, the submitted changes will not be accepted. - -## 1. About issue - -Before submitting an issue, please check the closed issue. There may already be an appropriate solution in the closed issue. - -If no suitable solution is found, we provide four templates to use when creating an issue. - -- Bug Report: If a bug is found, you can contact us by creating an issue through the bug report template. -- Enhancement: The developer has enhanced the tool, and can create an issue through the enhancement template to introduce the added content. -- Feature Request: If you want to add some new features or functions to the tool during use, you can create an issue through the Feature Request template to describe the new features. -- Ask a Question: If you have any questions, you can create an issue through the Ask a Question template to contact us. - -After selecting the appropriate template, you only need to fill in the required content on the template. If you find that there is no template or the template content is empty when creating the issue, you can feed back this problem to us through WeChat group, nail group or email. - -## 2. About Git Branch - -To contribute code to KCL, you must have a GitHub account so that you can push the code to your own branch and create pull requests. We recommend reference [Angular Specification]( https://github.com/angular/angular.js/blob/master/DEVELOPERS.md# -Git commit guidelines) name your own branches. - -The recommended format is as follows: - -``` -{type}-{a_short_description} -``` - -The branch name mainly includes two fields, which are separated by "-". Including: - -- `{type}`: the type of the current branch content. -- `{a_short_description}`: A short description of the main content of this branch. - -For example, Alice first transfers the Fork warehouse to his own account, and then creates a branch with the corresponding name 'alice: fix output fmt bug' (Alice's account is before the colon) to fix the output formatting bug. - -## 3. 关于 Git Commit - -We refer to [Commitizen](https://github.com/commitizen/cz-cli) to write a Commit Message. - -``` -Note: If you directly use Commit to generate a Commit Message, please note that -It is a tool for developers to manage commit. It is not related to the project itself, so it is an intermediate product generated by Commiten -(For example, the node_modules file directory) may not be in the project. gitignore file. - -You can git add {filename} select the file to submit and ignore the intermediate product. -Or you can add the following content to the. gitignore file and automatically ignore the intermediate products: -# commitizen -package.json -package-lock.json -node_modules/* -``` - -If you manually write a commit Message, we also recommend [Commiten](https://github.com/commitizen/cz-cli) for the commit message format. - -``` -{type} ( {component_or_file} ) {a_short_description} -{a_longer_description} -BREAKING CHANGE: {breaking_change_description}. -{linked issue} -``` - -It mainly includes 6 fields: - -- `{type}`: the type of the branch corresponding to the current commit. -- `{component_or_file}`: the name of the module or file that the current commit changes. -- `{a_short_description}`: A short description describes the content of the commit. -- `{a_longer_description}`: The detailed description is used to introduce the content in the commit. -- `{breaking_change_description}`: If the commit contains broken compatibility changes, the impact of compatibility changes needs to be introduced. -- `{linked issue}`: the issue associated with the current commit. - -Where `{breaking_change_description}` and `{linked issue}` can be omitted if the commit does not contain compatibility breaking changes and associated issues. - -For example, the commit created by Alice in branch 'alice: fix output fmt bug'. - -``` -fix(kcl-printer): fix an output format bug in kcl-printer - -There is an output format bug in kcl-printer because ..., -So, The calling of method "XXX" is replaced by "HHHH"..., -... - ---If there is no change to break the compatibility and the associated issue, the following contents can be omitted. -BREAKING CHANGE: This change maybe cause ....... - -fix #123 -``` - -## 4. About pull request - -Before submitting a PR, priority may be given to the following issues: - -- Please check the closed PRs first. There may be completed solutions in the closed PRs. -- We suggest that before submitting the change, submit a corresponding issue to describe the problems to be solved in the change, and associate the PR corresponding to the change with the issue. -- After submitting the PR to us, please sign [Contributor License Agreement (CLA)] (# cla). If you refuse to sign, we will not accept the PR. -- Make sure that each change creates a new branch and names the branch according to the specifications mentioned above. -- PR should not exceed two commit at a time. Please compress the extra commit with squash and write a commit message according to the specifications mentioned above. -- We provide [PR template](https://github.com/kcl-lang/.github/blob/main/.github/PULL_REQUEST_TEMPLATE.md). You only need to add the content required in the template. If you find no template or the template content is empty when creating a PR, you can feed back this problem to us through WeChat group, nail group or email. - -We suggest that the PR title be consistent with the branch name and the commit message style: - -``` -{type} ( {component_name_or_file_name} ) :{a_short_description} -``` - -比如,Alice 为分支`fix/alice/fix_output_fmt_bug`创建的PR名称。 - -For example, Alice creates the PR name `fix/alice/fix_output_fmt_bug` for one branch. - -``` -fix(kcl-printer): fix an output format bug in kcl-printer. -``` - -## 5. Supported PR Types - -``` -- feat: -- New features have been added. -- fix: -- Bug is repaired. -- docs: -- The document part has been modified. -- style: -- The modification of code format does not affect the functions of the code, such as deleting redundant spaces, code indentation, etc. -- refactor: -- refactoring code without changing its function. -- perf: -- Performs performance optimization on the code. -- test: -- Add or adjust existing test cases. -- build: -- Adjust the build system or external dependent libraries. -- ci: -- The configuration file or script of the CI has been adjusted. -- choice: -- Adjustments to other parts of the source code and test files. -- reverse: -- Rollback commit. -``` - -## 6. Contributor License Agreement (CLA) - -After the PR is submitted to us for the first time, the CLA check in the PR will fail and prompt to sign the CLA. You can reply "I have read the CLA Document and I hereby sign the CLA" between your accounts in PR to agree to sign the CLA, and then manually restart the failed CLA check action. After PR is successfully merged, it will be locked and cannot be modified. diff --git a/versioned_docs/version-0.6.0/community/intro/_category_.json b/versioned_docs/version-0.6.0/community/intro/_category_.json deleted file mode 100644 index a9646363..00000000 --- a/versioned_docs/version-0.6.0/community/intro/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Community", - "position": 1 -} diff --git a/versioned_docs/version-0.6.0/community/intro/intro.md b/versioned_docs/version-0.6.0/community/intro/intro.md deleted file mode 100644 index 4b1a7f02..00000000 --- a/versioned_docs/version-0.6.0/community/intro/intro.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Community - -Welcome to the KCL open-source community, everyone's participation is the driving force for the healthy growth of all open-source projects! There are many ways to participate in open-source. Everyone can create Issues or fix bugs, improve documentation or modify code by submitting PR (Pull Request), or open new feature discussions by submitting KEP, or share stories about the process of evangelism and use of KCL with surrounding friends. - -See the [community](https://github.com/kcl-lang/community) for ways to join us. diff --git a/versioned_docs/version-0.6.0/community/intro/license.md b/versioned_docs/version-0.6.0/community/intro/license.md deleted file mode 100644 index 4d0097b4..00000000 --- a/versioned_docs/version-0.6.0/community/intro/license.md +++ /dev/null @@ -1,211 +0,0 @@ ---- -sidebar_position: 99 ---- - -# License - -KCL Use [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) License: - -``` - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2023 The KCL Authors. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -``` diff --git a/versioned_docs/version-0.6.0/community/intro/support.md b/versioned_docs/version-0.6.0/community/intro/support.md deleted file mode 100644 index 7ed2e1a8..00000000 --- a/versioned_docs/version-0.6.0/community/intro/support.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Ask for help - -KCL has a developer and user community of many enthusiasts. - -On this page, we list the KCL-related communities you can participate in; see other pages in this section for additional online and offline learning materials. - -Before joining the KCL community, please read the [Contributor Covenant](https://www.contributor-covenant.org/version/2/0/code_of_conduct/) , which is expected to be followed by all community members. - -## Discussions - -- Submit an issue on Github -- Communicate in the Github discussion group -- Get the latest status through official website, Github, Twitter, Slack, Wechat and other accounts. See the [community](https://github.com/kcl-lang/community) for ways to join us. - -## New Features - -Please try to avoid submitting pull requests for new features, we may already have someone working on them, or maybe this feature is already part of our future plans. In conclusion, please contact us before submitting new features! diff --git a/versioned_docs/version-0.6.0/community/release-policy/_category_.json b/versioned_docs/version-0.6.0/community/release-policy/_category_.json deleted file mode 100644 index bc39d651..00000000 --- a/versioned_docs/version-0.6.0/community/release-policy/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Release Policy", - "position": 3 -} diff --git a/versioned_docs/version-0.6.0/community/release-policy/index.md b/versioned_docs/version-0.6.0/community/release-policy/index.md deleted file mode 100644 index c87091d0..00000000 --- a/versioned_docs/version-0.6.0/community/release-policy/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# Release Policy - -The release policy defines the semantics of the release, the release process, etc. In order to maximize the concurrent development process, KCL, etc. adopt independent release strategies. diff --git a/versioned_docs/version-0.6.0/community/release-policy/kcl.md b/versioned_docs/version-0.6.0/community/release-policy/kcl.md deleted file mode 100644 index a24e1509..00000000 --- a/versioned_docs/version-0.6.0/community/release-policy/kcl.md +++ /dev/null @@ -1,39 +0,0 @@ -# KCL Release Policy - -KCL 开发团队采用 [语义化版本](https://semver.org/lang/zh-CN/) 来简化管理。版本格式:主版本号.次版本号.修订号。版本号递增规则如下:主版本号对应不兼容的 API 修改,次版本号对应向下兼容的功能性新增,修订号对应向下兼容的问题修正。总体目标是每一个半月发布一个特性增强的次要版本,根据需要不定期发布其他版本的修订。 - -KCL 项目版本发布策略如下: - -- 主版本号:当进行重大的架构调整或者加入重大的新功能时,需要提升主版本号。对于 KCL 项目来说,目前的主版本号为 0。 -- 次版本号:当添加的功能和特性有较大的变化时,提升次版本号。目前的次版本号为 5,2023 年度会相继发布 0.5, 0.6, 0.7 版本。 -- 修订号:通过修复漏洞或者改进性能来更新程序时,会提升修订号,修订号从 0 开始计数以此加 1。 -- 发布周期:在未达到 v1.0.0 版本之前,计划每隔 3 个月发布一个新的次要版本。在此期间,需要持续收集用户反馈,并进行必要的修复和改进。 -- 发布流程:在发布新版本之前,需要进行严格的测试和审核,确保新版本的质量。封板并测试完成后,会在 Github 上发布新版本的源代码,二进制和镜像,并提供详细的文档和使用指南。 -- 版本支持:我们将对最新的版本提供长期支持,包括漏洞修复和安全更新。对于旧版本,我们将提供有限的支持,仅在必要时进行修复。 - -## 发布流程与规则 - -- 特性开发:main 分支主干开发,分支发布,block 用户使用的问题和严重的 bug, 安全隐患,高优先级解决,尽可能保持在一周内收敛,高于一般的功能研发。 -- 迭代周期:我们的迭代周期通常为 3 个月,即每 3 个月发布一个新的次要版本。 -- 版本规划:发版前两周产出 alpha 版本,前一周产出 beta 版本,alpha 版本仍可进行特性合并,beta 版本只合并错误修复,最终产出正式版本并打 tag 作为长期保存的 release 分支。 -- 发版计划:在每个发布周期开始时制定详细的发版计划(Github Milestone),包括发布日期、版本号、功能列表和测试计划等。需要尽可能地遵守发版计划,确保按时发布新版本。 -- 发布前测试:在发布新版本之前,需要进行全面的测试,包括单元测试、集成测试,模糊测试,压测,用户验收测试等。只有经过测试并无问题后,我们才会发布新版本。 -- 版本回滚:如果在发布后发现了严重的问题,需要立即回滚版本,并尽快修复问题。并通过邮件、社交媒体等渠道及时通知用户,并提供解决方案。 -- 发布文档:需要在发布时提供详细的文档,包括发布说明、更新日志、API 文档和使用指南等,帮助用户了解和使用新版本。在 KCL 中,我们统一在 KCL 网站进行维护。 -- 版本兼容性:在发布新版本时,需要尽可能保持兼容性,以确保用户无需进行过多的修改和适应。KCL 还没有达到 v1,暂时没有兼容性保证。KCL 的目标是尽可能少地进行重大更改,不应轻率地考虑对语言的更改,为了语言自身更好地演进和发展,一般认为更改具有重大好处时才会进行(较好地解决了目标场景的问题或者提升了绝大用户的使用体验)。对于可能引入兼容性问题的功能或变更,提供相应的提示和解决方案,同时会提供逐步升级的指南或提供自动迁移的工具,以帮助用户平滑地迁移到新版本。 - -## 发布组件 - -![](/img/docs/community/release-policy/kcl-components.png) - -每次版本发布时,KCL 相关所有组件保持一个依赖同一个 KCL 核心主要版本,整体采用树形结构组织依赖顺序发布并进行回归测试,直到发布测试完成,尽力避免三角依赖,禁止循环依赖。 - -## 一个 Feature 的生命周期 - -- 设计方案/文档:通过 Issue 回答清楚这个 feature 的动机是什么,它解决什么问题以及目标是什么,用户需求和用户故事是怎样的;这个 feature 做什么,如何做,难度怎样,需要多长时间,依赖项,需要做什么测试等。(Tips: 大的设计尽量拆分成小的设计,通过权衡和广泛的调研找到一个简单且可持续的解决方案,并且具备一定得到可扩展以适应未来的业务或技术变化,通过持续讨论和方案评审确定最终设计)。 -- 编写代码:通过高频小改动进行迭代、持续沟通和协作,提前设计单元测试、集成测试和 benchmark 等测试用例,确保编写代码 100% 测试覆盖,注释完整和逻辑清晰,并通过 Demo 演示持续收集反馈。 -- 文档撰写:在 [KCL 网站](https://kcl-lang.io) 中更新用户文档。 -- 测试和反馈:在发布功能之前,让一些同行/用户通过**随循文档**而不是口述来尝试和测试这些新功能。接收反馈并改进。 -- 发布和公告:撰写 Release Note, PR 文章,场景和新特性解读等以及渠道宣发等。 - -> 注:以上所有信息全是公开的,需要透出给所有社区研发者进行参与、讨论和贡献。 diff --git a/versioned_docs/version-0.6.0/community/release-policy/roadmap.md b/versioned_docs/version-0.6.0/community/release-policy/roadmap.md deleted file mode 100644 index df220576..00000000 --- a/versioned_docs/version-0.6.0/community/release-policy/roadmap.md +++ /dev/null @@ -1,3 +0,0 @@ -# Roadmap - -![](/img/docs/community/release-policy/roadmap.jpg) diff --git a/versioned_docs/version-0.6.0/reference/_advanced-concepts/_category_.json b/versioned_docs/version-0.6.0/reference/_advanced-concepts/_category_.json deleted file mode 100644 index 85a16abb..00000000 --- a/versioned_docs/version-0.6.0/reference/_advanced-concepts/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Advanced-Concepts", - "position": 6 -} diff --git a/versioned_docs/version-0.6.0/reference/_advanced-concepts/build_cache.md b/versioned_docs/version-0.6.0/reference/_advanced-concepts/build_cache.md deleted file mode 100644 index 746e2351..00000000 --- a/versioned_docs/version-0.6.0/reference/_advanced-concepts/build_cache.md +++ /dev/null @@ -1 +0,0 @@ -# Building Cache diff --git a/versioned_docs/version-0.6.0/reference/_category_.json b/versioned_docs/version-0.6.0/reference/_category_.json deleted file mode 100644 index 1b337d5a..00000000 --- a/versioned_docs/version-0.6.0/reference/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Reference", - "position": 5 -} diff --git a/versioned_docs/version-0.6.0/reference/cheatsheets/_category_.json b/versioned_docs/version-0.6.0/reference/cheatsheets/_category_.json deleted file mode 100644 index 80464148..00000000 --- a/versioned_docs/version-0.6.0/reference/cheatsheets/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Cheat Sheet", - "position": 10 -} diff --git a/versioned_docs/version-0.6.0/reference/cheatsheets/index.md b/versioned_docs/version-0.6.0/reference/cheatsheets/index.md deleted file mode 100644 index da4189eb..00000000 --- a/versioned_docs/version-0.6.0/reference/cheatsheets/index.md +++ /dev/null @@ -1,5 +0,0 @@ -# KCL Cheat Sheet - -![](/img/docs/reference/cheatsheets/cheatsheet.png) - -[Download PDF](https://github.com/kcl-lang/kcl-lang.io/blob/main/cheatsheet/cheatsheet.pdf) diff --git a/versioned_docs/version-0.6.0/reference/lang/_category_.json b/versioned_docs/version-0.6.0/reference/lang/_category_.json deleted file mode 100644 index 4c823148..00000000 --- a/versioned_docs/version-0.6.0/reference/lang/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Tutorial", - "position": 1 -} diff --git a/versioned_docs/version-0.6.0/reference/lang/codelab/_category_.json b/versioned_docs/version-0.6.0/reference/lang/codelab/_category_.json deleted file mode 100644 index 2e047bcb..00000000 --- a/versioned_docs/version-0.6.0/reference/lang/codelab/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Code Lab", - "position": 2 -} diff --git a/versioned_docs/version-0.6.0/reference/lang/codelab/collaborative.md b/versioned_docs/version-0.6.0/reference/lang/codelab/collaborative.md deleted file mode 100644 index 84ee8160..00000000 --- a/versioned_docs/version-0.6.0/reference/lang/codelab/collaborative.md +++ /dev/null @@ -1,345 +0,0 @@ ---- -title: "Co-configuration with config operations" -linkTitle: "Co-configuration with config operations" -type: "docs" -weight: 2 -description: Co-configuration with config operations -sidebar_position: 3 ---- - -## 1. Introduction - -KCL is a simple and easy-to-use configuration language, where users can simply write the reusable configuration code. - -In this codelab, we will learn how to write the config in a collaborative way using the KCL config operation features. - -### What We Will Learn - -1. Define schemas and organize project directories. -2. Create multiple environment configurations via the KCL config operation features. -3. Configure compiling parameters and tests. - -## 2. Define Schemas and Organize Project Directories - -### Schema Definitions - -Suppose we want to define a server configuration with certain attributes, we can create a simple config by creating a `server.k`, we can fill in the following code as below which defines a reusable schema of the configuration of a server. - -```python -import units - -type Unit = units.NumberMultiplier - -schema Server: - replicas: int = 1 - image: str - resource: Resource = {} - mainContainer: Main = {} - labels?: {str:str} - annotations?: {str:str} - -schema Main: - name: str = "main" - command?: [str] - args?: [str] - ports?: [Port] - -schema Resource: - cpu?: int = 1 - memory?: Unit = 1024Mi - disk?: Unit = 10Gi - -schema Port: - name?: str - protocol: "HTTP" | "TCP" - port: 80 | 443 - targetPort: int - - check: - targetPort > 1024, "targetPort must be larger than 1024" -``` - -In the code above, we define a schema named `Server`, which represents the configuration type that the user will write, which contains some basic type attributes (e.g., `replicas`, `image`, etc) and some composite type attributes (e.g., `resource`, `main`, etc). In addition to some basic types mentioned in the [schema codelab](./schema.md), we can see two types in the above code `Unit` and `units.NumberMultiplier`. Among them, `units.NumberMultiplier` denotes the KCL number unit type, which means that a natural unit or binary unit can be added after the KCL number, such as `1K` for `1000`, `1Ki` for `1024`. `Unit` is the type alias of `units.NumberMultiplier`, which is used to simplify the writing of type annotations. - -### Project Directories - -In order to complete the collaborative configuration development, we first need a configuration project, which contains the configuration of the test application and the differential configuration of different environments, so we are creating the following project directory: - -``` -. -├── appops -│ └── test_app -│ ├── base -│ │ └── base.k -│ ├── dev -│ │ ├── ci-test -│ │ │ └── stdout.golden.yaml -│ │ ├── kcl.yaml -│ │ └── main.k -│ └── prod -│ ├── ci-test -│ │ └── stdout.golden.yaml -│ ├── kcl.yaml -│ └── main.k -├── kcl.mod -└── pkg - └── sever.k -``` - -The directory of the project mainly contains three parts: - -- `kcl.mod`: The file used to identify the root directory of the KCL project. -- `pkg`: `Server` Schema structure reused by different application configurations. -- `appops`: Server configurations of different applications, currently only one application `test_app` is placed. - - `base`: Application common configurations for all environments. - - `dev`: Application configuration for the development environment. - - `prod`: Application configuration for the production environment. - -The meaning of `base.k`, `main.k`, `kcl.yaml` and `ci-test/stdout.golden.yaml` will be mentioned in subsequent sections. - -## 3. Create multiple environment configurations via the KCL config operation features - -### Create a baseline configuration - -After we have organized the project directory and the basic server configuration model, we can write the configuration of the user application. We can create our own test application folder `test_app` and place it in the application configuration folder `appops`. - -For the configuration of an application, we often divide it into a basic configuration and the differential configuration of multiple environments and merge them. Through the configuration merging feature of KCL, we can easily do this. Assuming that we have two configurations of development environment and production environment, we can create three folders: `base`, `dev` and `prod` to store baseline, development environment and production environment configurations respectively. First, we write the configuration of `base/base.k`: - -```python -import pkg - -server: pkg.Server { - # Set the image with the value "nginx:1.14.2" - image = "nginx:1.14.2" - # Add a label app into labels - labels.app = "test_app" - # Add a mainContainer config, and its ports are [{protocol = "HTTP", port = 80, targetPort = 1100}] - mainContainer.ports = [{ - protocol = "HTTP" - port = 80 - targetPort = 1100 - }] -} -``` - -As in the above code, we use the `import` keyword in `base.k` to import the `Server` schema placed under `pkg` and use it to instantiate a configuration named `server`, in which we set `image` attribute to `"nginx:1.14.2"`, and a label `app` with the value `test_app` is added. In addition, we also added the configuration of the main container `mainContainer` with the value `[{protocol = "HTTP", port = 80, targetPort = 1100}]` for the ports attribute. - -KCL command: - -```bash -kcl appops/test_app/base/base.k -``` - -Output: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2 - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app -``` - -At this point, we have a baseline configuration. - -### Create multiple environment configurations - -Next we configure a differentiated multi-environment configuration. First assume that we want to use a temporary image of our own `nginx:1.14.2-dev` in the development environment, and then use it to override the server configuration in the baseline, we can write the following configuration in `dev/main.k`: - -```python -import pkg - -server: pkg.Server { - # Override the image declared in the base - image = "nginx:1.14.2-dev" -} -``` - -KCL command: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -Output: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app -``` - -It can be seen that the `image` field of the output YAML is overwritten to `nginx:1.14.2-dev`. Suppose we also want to add a label to the `dev` environment with a key of `env` and a value of `dev`, we add the following code to `dev/main.k`: - -```python -import pkg - -server: pkg.Server { - # Override the image declared in the base - image = "nginx:1.14.2-dev" - # Union a new label env into base labels - labels.env = "dev" -} -``` - -KCL command: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app - env: dev -``` - -It can be seen that there are two labels in the `labels` field of the output YAML. - -In addition, we can also use the `+=` operator to add new values to list type attributes, such as the `mainContainer.ports` configuration in the baseline environment, continue to modify the code in `dev/main.k`: - -```python -import pkg - -server: pkg.Server { - # Override the base image. - image = "nginx:1.14.2-dev" - # Union a new label env into base labels. - labels.env = "dev" - # Append a port into base ports. - mainContainer.ports += [{ - protocol = "TCP" - port = 443 - targetPort = 1100 - }] -} -``` - -KCL command: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -Output: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - - protocol: TCP - port: 443 - targetPort: 1100 - labels: - app: test_app - env: dev -``` - -Using the same method, we can build the production configuration, write the code in the `dev/main.k` file, and add a label to it. - -```python -import pkg - -server: pkg.Server { - # Union a new label env into base labels - labels.env = "prod" -} -``` - -KCL command: - -```bash -kcl appops/test_app/base/base.k appops/test_app/prod/main.k -``` - -Output: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2 - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app - env: prod -``` - -## 4. Configure compiling parameters and tests - -In the previous section, we built a multi-environment configuration through code. It can be seen that the KCL command line compilation parameters of different environments are similar, so we can configure these compilation parameters into a file and input them to the KCL command line for invocation. Configure the following code in `dev/kcl.yaml`: - -```yaml -kcl_cli_configs: - files: - - ../base/base.k - - main.k - output: ./ci-test/stdout.golden.yaml -``` - -Then we can compile the configuration in the development environment with the following command: - -```bash -cd appops/test_app/dev && kcl -Y ./kcl.yaml -``` - -In addition, we have configured the `output` field in `dev/kcl.yaml` to output YAML to a file for subsequent configuration distribution or testing. You can verify that the application's configuration is as expected by walking through the `kcl.yaml` builds in each environment and comparing with `./ci-test/stdout.golden.yaml`. - -## 5. The Final Step - -Congratulations! - -We have completed the third lesson about KCL. diff --git a/versioned_docs/version-0.6.0/reference/lang/codelab/index.md b/versioned_docs/version-0.6.0/reference/lang/codelab/index.md deleted file mode 100644 index dbe554a9..00000000 --- a/versioned_docs/version-0.6.0/reference/lang/codelab/index.md +++ /dev/null @@ -1 +0,0 @@ -# Code Lab diff --git a/versioned_docs/version-0.6.0/reference/lang/codelab/schema.md b/versioned_docs/version-0.6.0/reference/lang/codelab/schema.md deleted file mode 100644 index 02f792d4..00000000 --- a/versioned_docs/version-0.6.0/reference/lang/codelab/schema.md +++ /dev/null @@ -1,817 +0,0 @@ ---- -title: "Write complex config using KCL Schema" -linkTitle: "Write complex config using KCL Schema" -type: "docs" -weight: 2 -description: Write complex config using KCL Schema -sidebar_position: 2 ---- - -## 1. Introduction - -KCL is a simple and easy-to-use configuration language, where users can simply write the reusable configuration code. - -In this codelab, we will learn how to write customized config using KCL, such that we can define a schema and write the config in a collaborative way. - -### What We Will Learn - -1. Define a simple schema -2. Set default immutable values to schema fields -3. Create config based on a simple schema -4. Write complex logic in schema -5. Create a new schema via schema combinations -6. Create a config of a deeply nested schema using dict/map -7. Create new schema via schema inheritance -8. Create new schema via multiple mixin schemas -9. Declare validation rules for the schema -10. Config schema output layout -11. Share and reuse schema - -## 2. Write Simple Schema - -Suppose we want to define a workload with certain attributes, we can create a simple config by creating a `my_config.k`, we can fill in the following code as below which defines a reusable schema of the configuration of deploy. - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels: {str:str} -``` - -In the code above, `cpu` and `memory` are defined as int value; `name`, `image` and `service` are string; `command` is a list of string type; `labels` is a dict type, whose key type and value type are both string. - -Besides, each attribute **must** be assigned with a not-None value as a schema instance unless it is modified by a question mark **?** as an optional attribute. - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels?: {str:str} # labels is an optional attribute -``` - -When there is an inheritance relationship: - -- If the attribute is optional in the base schema, it could be optional or required in the sub-schema. -- If the attribute is required in the base schema, it must be required in the sub-schema. - -## 3. Enhance Schema as Needed - -Suppose we need to set default values to service and replica, we can make them as below: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str = "my-service" # defaulting - replica: int = 1 # defaulting - command: [str] - labels?: {str:str} # labels is an optional attribute -``` - -And then we can set the service type annotation as the string literal type to make it immutable: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: "my-service" = "my-service" - replica: int = 1 - command: [str] - labels?: {str:str} -``` - -In the schema, type hint is a `must`, for example we can define cpu as `cpu: int`. - -Specially, we can define a string-interface dict as `{str:}`, and in case we want to define an object or interface, just define as `{:}`. - -## 4. Create Config Based on Simple Schema - -Now we have a simple schema definition, we can use it to define config as: - -```python -nginx = Deployment { - name = "my-nginx" - cpu = 256 - memory = 512 - image = "nginx:1.14.2" - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } -} -``` - -Run with the following KCL command, we should be able to see the generated yaml files as the output as below: - -KCL command: - -``` - kcl my_config.k -``` - -Stdout: - -```yaml -nginx: - name: my-nginx - cpu: 256 - memory: 512 - image: nginx:1.14.2 - service: my-service - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -> Check the manual and specification out for more details about collection data types and block. - -In addition, the **config selector expressions** can be used to init a schema instance, and we can ignore the comma at the end of the line in the config expression. - -```python -nginx = Deployment { - name = "my-nginx" - cpu = 256 - memory = 512 - image = "nginx:1.14.2" - command = ["nginx"] # Ignore the comma at the end of the line - labels.run = "my-nginx" # A dict variable in schema can use selector expressions - labels.env = "pre-prod" # A dict variable in schema can use selector expressions -} -``` - -## 5. Write More Complex Logic in Schema - -Suppose we have some schema logic, we can wrapper it into schema: - -```python -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - image: str - service: "my-service" = "my-service" - replica: int = 1 - command: [str] - labels?: {str:str} - - _cpu = 2048 - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 -``` - -Now, we can define a config by creating a schema instance and pass in priority as an argument to schema: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -Run with kcl, we should see the generated yaml files as output as below: - -KCL command: - -``` -kcl my_config.k -``` - -Stdout: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - image: nginx:1.14.2 - service: my-service - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 6. Create New Schema via Schema Combinations - -Now we want to define a detailed schema with service and volumes, we can do it as follows: - -```python -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - volumes?: [Volume] - image: str - service?: Service - replica: int = 1 - command: [str] - labels?: {str:str} - - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 - -schema Port: - name: str - protocol: str - port: int - targetPort: int - -schema Service: - name: "my-service" = "my-service" - ports: [Port] - -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -In this case, Deployment is composed of Service and a list of Volumes, and Service is composed of a list of Ports. - -## 7. Create Config of Deeply Nested Schema using Dict/Map - -Now we have a new Deployment schema, however, we may notice that it contains multiple layers of nested structures, in fact, this is very common in complex structure definitions, and we often have to write imperative assembly code to generate the final structure. - -With KCL, we can create the config with simple dict declaration, with the capability of full schema initialization and validation. For example, we can simply config nginx by the new Deployment schema as follows: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -Run with KCL, we will see the generated yaml files as below: - -KCL command: - -``` -kcl my_config.k -``` - -Stdout: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -Note that, the dict that we use to define Deployment config must be aligned with the schema definition, otherwise we will get an error. For example, suppose we define a wrong type of service port as below: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = [80] # wrong data type, trying to assign List to int - targetPort = 9376 - }] -} -``` - -Run with KCL, we will see the error message as output as below: - -KCL command: - -```python -kcl my_config.k -``` - -Stderr: - -``` -The type got is inconsistent with the type expected: expect int, got [int(80)] -``` - -## 8. Declare Schema Validation Rules - -Now we have seen a complex schema, in which every field has a type hint to make it less error-prone. But this is not good enough, we want to support more enhanced verifications to our schemas, so that code errors in schemas and configs can be discovered as soon as possible. - -Lots of validation rules, like None type check, range check, value check, length check, regular expression matching, enum check have already been added or in progress. Here is a code sample: - -```python -import regex - -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - volumes?: [Volume] - image: str - service?: Service - replica: int = 1 - command: [str] - labels?: {str:str} - - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 - - check: - multiplyof(cpu, 256), "cpu must be a multiplier of 256" - regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$"), "image name should be like 'nginx:1.14.2'" - 1 <= replica < 100, "replica should be in range (1, 100)" - len(labels) >= 2 if labels, "the length of labels should be large or equal to 2" - "env" in labels, "'env' must be in labels" - len(command) > 0, "the command list should be non-empty" - -schema Port: - name: str - protocol: str - port: int - targetPort: int - - check: - port in [80, 443], "we can only expose 80 and 443 port" - protocol in ["HTTP", "TCP"], "protocol must be either HTTP or TCP" - 1024 < targetPort, "targetPort must be larger than 1024" - -schema Service: - name: "my-service" = "my-service" - ports: [Port] - - check: - len(ports) > 0, "ports list must be non-empty" - -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -Since the attributes defined by the schema are **required** by default, the verification that judges that the variable cannot be None/Undefined can be omitted. - -```python -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -Now we can write the config based on the new schema and expose config errors in time. For example, with the invalid config as below: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1142" # image value is not matching the regex - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -Every field is type-valid, but the image name is invalid. - -Run with KCL, we will see the error message as below: - -KCL command: - -``` -kcl my_config.k -``` - -Stderr: - -``` -Schema check is failed to check condition: regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$"), "image name should be like 'nginx:1.14.2'" -``` - -> The verification capability of KCL covers the verification defined by Openapi so that we can write any API verifications through KCL. - -## 9. Create New Schema via Schema Inheritance - -Now we have a solid Deployment schema definition and we can use it to declare config. - -Usually, schema Deployment will be used in multiple scenarios. We can directly use the schema to declare the configurations in different use cases (see the above section), or we can produce a more specific schema definition through inheritance. - -For example, we can use the Deployment schema as a basis, to define the nginx's base schema, and extend the definition -in each scenario. - -In this case, we define some commonly used attributes. Please note that we mark the name to be immutable with the 'final' keyword to prevent it from being overwritten. - -```python -schema Nginx(Deployment): - """ A base nginx schema """ - name: "my-nginx" = "my-nginx" - image: str = "nginx:1.14.2" - replica: int = 3 - command: [str] = ["nginx"] - -schema NginxProd(Nginx): - """ A prod nginx schema with stable configurations """ - volumes: [Volume] = [{ - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - """ A volume mapped to host path """ - service: Service = { - ports = [{ - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] - } - """ An 80 port to target backend server """ -``` - -Now we have some static configurations for nginx. It is recommended to declare configurations that we think are static there, and put more dynamic configurations as below: - -```python -nginx = Nginx { - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -```python -nginx = NginxProd { - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -Now, we can simply define nginx prod config just with runtime label value "prod" which is not that static. - -In fact, under some complex situation, we can split all configurations into the basic, business, and environment configuration definitions in this way, and achieve collaboration among team members based on this. - -Run with KCL, we will see the generated yaml files as output as below: - -KCL command: - -``` -kcl prod_config.k -``` - -Stdout: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 3 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 10. Create New Schema by Multiple Protocol and Mixin Schemas Inheritance - -Now, we can complete the declaration of the server configuration through the Deployment schema. - -However, usually, the actual situation is more complicated, and the deployment may have a variety of optional variable accessories. - -For example, we want to support a persistent volume claim based on an existing schema, as a reusable Kubernetes schema. In this case, we can just wrapper it with a `mixin` and a `protocol` as follows: - -```python -import k8spkg.api.core.v1 - -protocol PVCProtocol: - pvc?: {str:} - -mixin PersistentVolumeClaimMixin for PVCProtocol: - """ - PersistentVolumeClaim (PVC) sample: - Link: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims - """ - - # Mix in a new attribute `kubernetesPVC` - kubernetesPVC?: v1.PersistentVolumeClaim - - if pvc: - kubernetesPVC = v1.PersistentVolumeClaim { - metadata.name = pvc.name - metadata.labels = pvc.labels - spec = { - accessModes = pvc.accessModes - resources = pvc.resources - storageClassName = pvc.storageClassName - } - } -``` - -With this PersistentVolumeClaimMixin, we define a PVC schema with a clear `user interface`, and use Kubernetes PVC as an implementation. Then, we can define a server schema with Deployment schema, and PVC mixin schema. - -``` -schema Server(Deployment): - mixin [PersistentVolumeClaimMixin] - pvc?: {str:} - """ pvc user interface data defined by PersistentVolumeClaimMixin """ -``` - -In the Server schema, Deployment is the base schema, and PersistentVolumeClaimMixin is an optional add-on whose user interface data is `pvc?: {str:}`. - -Note, the `mixin` is often used to add new attributes to the host schema, or to modify the existing attributes of the host schema. Thus, `mixin` can use the attributes in the host schema. Since the `mixin` is designed to be reusable, we need an additional `protocol` to constrain the attribute names and types in the host schema for the `mixin`. - -Now, if we want a deploy with a PVC, just declare as user interface: - -```python -server = Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] - pvc = { - name = "my_pvc" - accessModes = ["ReadWriteOnce"] - resources.requests.storage = "8Gi" - storageClassName = "slow" - } -} -``` - -Run with kcl, we will see the generated yaml files as output as below: - -KCL command: - -``` -kcl server.k -``` - -Stdout: - -```yaml -server: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod - pvc: - name: my_pvc - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 8Gi - storageClassName: slow ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: my_pvc -spec: - accessModes: - - ReadWriteOnce - storageClassName: slow - resources: - requests: - storage: 8Gi -``` - -If we don't want a persistent volume, just remove the pvc config block. - -## 11. Share and Reuse Schema - -The Server schema could be shared via `import`, we can simply package our code with KCL. - -```python -import pkg - -server = pkg.Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -Another skill we should know about sharing code is, modules under the same package do not need to import each other. - -Suppose we have models in a pkg: - -``` -pkg/ - - deploy.k - - server.k - - pvc.k -``` - -And in `server.k`, we can just use Deployment schema in `deploy.k` and pvc schema in `pvc.k` without import: - -```python -# no import needed -schema Server(Deployment): - mixin [PersistentVolumeClaimMixin] - pvc?: {str:} - """ pvc user interface data defined by PersistentVolumeClaimMixin """ -``` - -And then users must import the pkg to use it as a whole: - -```python -import pkg - -server = pkg.Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [pkg.Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } - service.ports = [pkg.Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -Run kcl command: - -``` -kcl pkg_server.k -``` - -Output: - -```yaml -server: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 12. The Final Step - -Congratulations! - -We have completed the second lesson about KCL, we have used KCL to replace our key-value text file to get better programming support. diff --git a/versioned_docs/version-0.6.0/reference/lang/codelab/simple.md b/versioned_docs/version-0.6.0/reference/lang/codelab/simple.md deleted file mode 100644 index 56be5805..00000000 --- a/versioned_docs/version-0.6.0/reference/lang/codelab/simple.md +++ /dev/null @@ -1,495 +0,0 @@ ---- -title: "Write simple config with KCL" -linkTitle: "Write simple config with KCL" -type: "docs" -weight: 2 -description: Write simple config with KCL -sidebar_position: 1 ---- - -## 1. Introduction - -KCL is a simple and easy-to-use configuration language, where users can simply write the reusable configuration code. - -In this first codelab, we will learn how to write a simple config with KCL. - -Learning this codelab only requires basic programming knowledge, and experience with python will make it even easier. - -### What We Will Learn - -1. Write simple key-value configuration in a programmable way -2. Write simple logic in KCL code -3. Write collections in KCL code -4. Test and debug with KCL code -5. Use built-in support in KCL code -6. Share and reuse KCL code -7. Write config with dynamic input arguments - -## 2. Write Key-Value Pairs - -Generate a simple config by creating a `my_config.k`, we can fill in the following code without strict format which describes the configuration of deploy. - -```python -cpu = 256 -memory = 512 -image = "nginx:1.14.2" -service = "my-service" -``` - -In the code above, cpu and memory are declared as int value, while image and service are string literal. - -Run with KCL, we will see the generated data in yaml format as below: - -KCL command: - -```bash -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -The exported variable is immutable by default so that once it is declared, we can't modify it some where else. - -## 3. Write Simple Logic - -Sometimes we want to write a logic in configuration, then we can use: - -- Mutable and non-exported variable starting with `_` -- If-else statement - -A non-exported variable means it will not appear in the output YAML, and it can be assigned multiple times. - -Here is a sample to show how to adjust the resource with conditions. - -KCL command: - -```python -kcl my_config.k -``` - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -image = "nginx:1.14.2" -service = "my-service" -``` - -Run with KCL, we will see the generated data in yaml format as below: - -```python -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -.. note:: -KCL has rich support of operators and string member functions, please read manual and specification for more details. - -## 4. Write Collections - -We can use collections to represent complex data types. The collections which are already supported are: - -- list -- dict - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -command = ["nginx"] # a list -labels = {run = "my-nginx"} # a dict -image = "nginx:1.14.2" -service = "my-service" -``` - -Run with kcl, we will see the generated data as yaml format as below: - -KCL command: - -```bash -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx -image: nginx:1.14.2 -service: my-service -``` - -> Check manual and specification out for more about collection date type and member functions. - -## 5. Append Items Into Collections - -We can combine logical expressions, comprehensions, slices, unions and other characteristics to dynamically add elements to the collection - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable -_env = "pre-prod" - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -_command = ["nginx"] # a list -_command = _command + ["-f", "file"] # Append items into command using + operator to contact two lists -command = [c.lower() for c in _command] # Take each element in the list to lowercase -_labels = { - run = "my-nginx" - if _env: - env = _env # Append a dict key-value pair when the _env is not None/Undefined or empty using if expressions -} # a dict -labels = _labels -image = "nginx:1.14.2" -service = "my-service" -``` - -Run with kcl, we will see the generated data as yaml format as below: - -```python -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 256 -memory: 512 -command: - - nginx - - -f - - file -labels: - run: my-nginx -image: nginx:1.14.2 -service: my-service -``` - -## 6. Write Assert - -To make code testable and robust, we can verify config data with assertions. - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -command = ["nginx"] # a list -labels = {run = "my-nginx"} # a dict -image = "nginx:1.14.2" -service = "my-service" -assert "env" in labels, "env label is a must" -assert cpu >= 256, "cpu cannot be less than 256" -``` - -Run with KCL, we will see eval failure with an error message as output as below: - -```bash -kcl my_config.k -``` - -Stderr: - -```bash -Assertion failure: env label is a must. -``` - -After adding env:pre-prod pair into labels, we will get the output as: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 7. Use Handy Built-in Support - -What's more, we can use built-in functions to help we debug or simplify coding. - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -_name = "nginx" -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # a list -labels = { - run = "my-{}".format(_name) - env = "pre-prod" -} # a dict -image = "{}:1.14.2".format(_name) # string format -service = "my-service" - -# debugging -print(labels) # debugging by print - -# test -assert len(labels) > 0, "labels can't be empty" # use len() to get list length -assert "env" in labels, "env label is a must" -assert cpu >= 256, "cpu cannot be less than 256" -``` - -This sample shows how we use `format()`, `len()`, `print()` function to help customize the config. - -Run with KCL, we will see the generated data in yaml format as below: - -KCL command: - -```bash -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -run: my-nginx -env: pre-prod -``` - -Note: more built-in functions and modules can be seen in spec/module - -## 8. Reuse Variables in Another Module - -To make our code well-organized, we can simply separate our code to `my_config.k` and `my_config_test.k`. - -Config data defined in `my_config.k`, - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 -_name = "nginx" - -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # a list -labels = { - run = "my-{}".format(_name) - env = "pre-prod" -} # a dict -image = "{}:1.14.2".format(_name) # string format -service = "my-service" -``` - -And test code defined in `my_config_test.k`, in which we can import `my_config.k`: - -```python -import my_config - -# debugging -print(my_config.labels) # debugging by print - -# test -assert len(my_config.labels) > 0, "labels can't be empty" # use len() to get list length -assert "env" in my_config.labels, "env label is a must" -assert my_config.cpu >= 256, "cpu cannot be less than256" -``` - -## 9. Config with Input Arguments - -Sometimes we need to get external input via parameters dynamically from the end user or platform. - -In this case, we can pass in `priority` and `env` on demand: - -- Pass in arguments: `-D priority=1 -D env=pre-prod` -- Get value by `option` keyword in KCL code - -```python -_priority = option("priority") # a non-exported and mutable variable -_env = option("env") # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -_name = "nginx" -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # a list -labels = { - run = "my-{}".format(_name) - env = _env -} # a dict -image = "{}:1.14.2".format(_name) # string format -service = "my-service" -``` - -Run with KCL, we will see the generated data in yaml format as below: - -```bash -kcl my_config.k -D priority=2 -D env=pre-prod -``` - -Stdout: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 10. Simplify Logic Expression using Dict - -When we need to write complex logic, we can use dict to simplify the writing of logic. - -```python -_priority = option("priority") # a non-exported and mutable variable -_env = option("env") # a non-exported and mutable variable -_priorityCpuMap = { - "1" = 256 - "2" = 512 - "3" = 1024 -} -# Using a dict to simplify logic and the default value is 2048 -_cpu = _priorityCpuMap[_priority] or 2048 -_name = "nginx" -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # a list -labels = { - run = "my-{}".format(_name) - env = _env -} # a dict -image = "{}:1.14.2".format(_name) # string format -service = "my-service" -``` - -Run with KCL, we will see the generated data in yaml format as below: - -KCL command: - -```bash -kcl my_config.k -D priority=2 -D env=pre-prod -``` - -Stdout: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 11. The Final Step - -Congratulations! - -We have completed the first lesson about KCL, we have used KCL to replace our key-value text file to get better programming support. - -Please check schema codelab out now to learn how to write an advanced config collaboratively with KCL `schema` mechanism. diff --git a/versioned_docs/version-0.6.0/reference/lang/error/_category_.json b/versioned_docs/version-0.6.0/reference/lang/error/_category_.json deleted file mode 100644 index 95062745..00000000 --- a/versioned_docs/version-0.6.0/reference/lang/error/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Errors and Warnings", - "position": 4 -} diff --git a/versioned_docs/version-0.6.0/reference/lang/error/index.md b/versioned_docs/version-0.6.0/reference/lang/error/index.md deleted file mode 100644 index 15fbda6f..00000000 --- a/versioned_docs/version-0.6.0/reference/lang/error/index.md +++ /dev/null @@ -1 +0,0 @@ -# Errors and Warnings diff --git a/versioned_docs/version-0.6.0/reference/lang/spec/_category_.json b/versioned_docs/version-0.6.0/reference/lang/spec/_category_.json deleted file mode 100644 index 7b24faae..00000000 --- a/versioned_docs/version-0.6.0/reference/lang/spec/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Spec", - "position": 3 -} diff --git a/versioned_docs/version-0.6.0/reference/lang/spec/codestyle.md b/versioned_docs/version-0.6.0/reference/lang/spec/codestyle.md deleted file mode 100644 index dd40925e..00000000 --- a/versioned_docs/version-0.6.0/reference/lang/spec/codestyle.md +++ /dev/null @@ -1,608 +0,0 @@ ---- -title: "Code Style" -linkTitle: "Code Style" -type: "docs" -weight: 2 -description: Code Style ---- - -## Introduction - -This document gives the KCL code style conventions. Good code style can play a vital role in the development and maintenance of the project. We can learn the KCL code style by referring to the full text of the description and sample codes, and use KCL format and lint tools to help coding. - -## Source File Encoding - -KCL file encoding should always use **UTF-8**. - -## Code Layout - -### Indentation - -Use **4 spaces** per indentation level such as in the schema statement and if statement. - -```python -schema PersonA: - name: str # non-recommended - age: int - -schema PersonB: - name: str # recommended - age: int - -if True: - a = 1 # recommended -elif True: - b = 2 # non-recommended -else: - c = 3 # non-recommended -``` - -The closing brace/bracket/parenthesis on multiline constructs should line up under **first character** of the line that starts the multiline construct, as in: - -```python -# valid and recommended -my_list = [ - 1, 2, 3, - 4, 5, 6, -] -``` - -```python -# invalid -my_list = [ - 1, 2, 3, - 4, 5, 6, - ] -``` - -### Tabs or Spaces - -- Spaces are the preferred indentation method. -- Tabs should be used solely to remain consistent with code that is already indented with tabs. - -KCL disallows mixing the use of tabs and spaces for indentation and an error will be reported during the compile time. - -### Blank Lines - -- Surround top-level schema definitions with one blank line. -- Keep at most one blank line between two statements and remove redundant blank lines. -- Remove extra blank characters at the end of the line -- Remove extra blank characters in a blank line. -- There is no blank line in the header of the file, start writing from the first line. -- Only one blank line will be left at the end of the KCL file. - -```python -# Remove blank lines in the file header -a = 1 # Remove white space at the end of the line -# Keep at most one blank line between two statements - -b = 2 -# Only leave one blank line at the end of the file - -``` - -### Inline Expressions - -Write indentation of KCL `if`, `elif`, `else` and other conditions on different lines. - -```python -if True: print("") # non-recommended - -if True: # recommended - print("") -``` - -### Line Break and Continuation lines - -- For long expressions, use the line continuation symbol `\` and keep the left end of multiple expressions aligned. -- The 4-space rule is optional for continuation lines. - -```python -anotherString = "Too long expression " + \ - "Too long expression " # non-recommended - -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " # recommended -``` - -### When to Use Trailing Commas - -- Always use trailing commas. - -### Maximum Line Length - -- The general recommendation is **80 characters** but not absolute. - -### Symbol Break White Space - -Try to keep the spaces between different symbols, but not too many, usually one is good. - -```python -a = 1 # recommended -b = 1 + 2 # non-recommended -``` - -### Whitespace in Expressions and Statements - -Avoid extraneous whitespace in the following situations: - -- The parentheses `()`, brackets `[]` and braces `{}` in the expression have no spaces inside. - -```python -a = (1 + 2) # recommended -b = ( 1 + 2 ) # non-recommended - -c = [1, 2, 3] # recommended -d = [ 1, 2, 3 ] # non-recommended - -e = {key = "value"} # recommended -f = { key = "value" } # non-recommended -``` - -```python -spam(ham[1], {eggs = 2}) # recommended -spam( ham[ 1 ], { eggs = 2 } ) # non-recommended -``` - -- Between a trailing comma and a following close parenthesis. - -```python -foo = [0,] # recommended -bar = [0, ] # non-recommended -``` - -- Immediately before the open parenthesis that starts the argument list of a function call. - -```python -print(1) # recommended -print (1) # non-recommended -``` - -- Immediately before the open parenthesis that starts indexing or slicing. - -```python -dct = {key = "value"} -lst = [1, 2, 3] - -a = dct['key'] # recommended -b = dct ['key'] # non-recommended - -c = lst[0] # recommended -d = lst [1] # non-recommended -``` - -- More than one space around an assignment `=` (or other) operator to align it with another. - -```python -# recommended: -x = 1 -y = 2 -long_variable = 3 -``` - -```python -# non-recommended: -x = 1 -y = 2 -long_variable = 3 -``` - -- Always surround these binary operators with a single space on either side: assignment (`=`), augmented assignment (`+=`, `-=`, etc.), comparisons (`==`, `<`, `>`, `!=`, `<=`, `>=`, `in`, `not in`, `is`, `is not`), booleans (`and`, `or`, `not`). - -```python -# recommended: -i = i + 1 -submitted += 1 -x = x * 2 - 1 -hypot2 = x * x + y * y -c = (a + b) * (a - b) -``` - -```python -# non-recommended: -i = i+1 -submitted+=1 -x = x*2 - 1 -hypot2 = x*x + y*y -c = (a+b) * (a-b) -``` - -- Break one blank line between different statements e.g., import, schema and expression statements. - -```python -import math -import net - -schema Person: - name: str - -person = Person { - name = "Alice" -} -``` - -- Compound statements (multiple statements on the same line) are generally discouraged - -```python -# recommended: -if foo == 'blah': - do_blah_thing() -do_one() -do_two() -do_three() -``` - -```python -# non-recommended: -if foo == 'blah': do_blah_thing() -do_one(); do_two(); do_three() -``` - -## Naming Conventions - -### Naming Styles - -The following naming styles are commonly distinguished: - -- `b` (single lowercase letter) -- `B` (single uppercase letter) -- `lowercase` -- `lower_case_with_underscores` -- `UPPERCASE` -- `UPPER_CASE_WITH_UNDERSCORES` -- `CapitalizedWords` (capitalize all letters of the acronym in `CapitalizedWords` e.g., `HTTPServer`.) -- `mixedCase` (differs from `CapitalizedWords` by initial lowercase character) -- `Capitalized_Words_With_Underscores` (ugly and non-recommended) - -### Names to Avoid - -Never use the characters 'l' (lowercase letter el), 'O' (uppercase letter oh), or 'I' (uppercase letter eye) as single-character variable names. - -### Package and Module Names - -Package and module names should have short, all-lowercase names. - -### Schema Names - -Schema names should normally use the `CapWords` convention. - -### Constants - -Constants are usually defined on a module level and written in all capital letters with underscores separating words such as `MAX_OVERFLOW` and `TOTAL`. - -## Import - -- Imports should usually be on separate lines. -- Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants. -- Imports should be grouped in the following order and we should put a blank line between each group of imports. - 1. Standard library imports. - 2. Related third party plugin imports. - 3. Local application/library specific imports. -- Use an alias when we import a package name with a relatively long path. -- Leave only one space between the Import keyword and the package name. - -```python -import net # recommended -import math # non-recommended - -import ..pkg.internal_pkg as alias_pkg # recommended -``` - -## Comments - -- Comments should be complete sentences. The first word should be capitalized unless it is an identifier that begins with a lower-case letter (never alter the case of identifiers!). -- Block comments generally consist of one or more paragraphs built out of complete sentences, with each sentence ending in a period. -- Use two spaces after a sentence-ending period in multi-sentence comments, except after the final sentence. - -### Block Comments - -Block comments generally apply to some (or all) code that follows them, and are indented to the same level as that code. Each line of a block comment starts with a `#` and **a single space**(unless it is indented text inside the comment). - -Paragraphs inside a block comment are separated by a line containing a single `#`. - -```python -# This is a block comment -a = 1 -``` - -### Inline Comments - -Use inline comments sparingly. - -An inline comment is a comment on the same line as a statement. Inline comments should be separated by **at least two spaces** from the statement. They should start with a `#` and **a single space**. - -```python -a = 1 # This is an inline comment -``` - -### Documentation Strings - -Write doc strings for all public schema and schema attributes. - -```python -schema Person: - """ - Person schema doc string - """ - - name: str = "Alice" -``` - -## String - -- Single-quoted strings and double-quoted strings are the same in KCL. -- Use double-quoted string with lowercase prefix -- For triple-quoted strings, always use double quote characters to be consistent with the docstring convention. -- When a string contains single or double quote characters, use the other one to avoid backslashes in the string. - -```python -strC = "'123'" # recommended -strD = "\"123\"" # non-recommended -``` - -## Number - -- Use lowercase for the prefix of non-decimal numbers, and use uppercase for the number itself. - -```python -foo = 0xAB # recommended -bar = 0Xab # non-recommended -``` - -## Operators - -### Binary Operators - -- Leave only one space before and after the assignment `=`. -- Leave only one space before and after the binary operator in the expression. - -```python -a = 1 # recommended -b=2 # non-recommended -c= 3 # non-recommended -d =4 # non-recommended - -_value = (1 + 2 * 3) # recommended -_value = (1+2*3) # non-recommended -``` - -### Unary Operators - -- There is only no space after unary operators e.g., `~`, `+` and `-`. - -```python -_value = 1 + -2 * ~3 # recommended -_value = 1+ - 2 * ~ 3 # non-recommended -``` - -- There is no space after `**` and `*` in the dict/list deduction expressions and argument expressions. - -```python -_list = [1, 2, 3] -_list = [*_list, [4, 5 ,6]] # recommended -_list = [* _list, [4, 5 ,6]] # non-recommended - -_dict = {**{k = "v"}, **{k = "v"}} # recommended -_dict = {** {k = "v"}, ** {k = "v"}} # non-recommended -``` - -- Use `is not` operator rather than `not ... is`. - -```python -# recommended: -if foo is not None: - a = 1 -``` - -```python -# non-recommended: -if not foo is None: - a = 1 -``` - -## Dict - -- There is no space before the colon `:` at the instantiation of KCL dict and schema config, and a space after the colon `:`. - -```python -d1 = {labels: {k1 = "v1"}} # recommended -d2 = {labels : {k1 = "v1"}} # non-recommended -d3 = {labels :{k1 = "v1"}} # non-recommended -``` - -- Always surround the override attribute operator `=` and the insert attribute operator `+=` with a single space on either sid. - -```python -d1 = {key = "value"} # recommended -d2 = {key= "value"} # non-recommended -d3 = {key ="value"} # non-recommended -``` - -```python -d1 = {key += [0, 1, 2]} # recommended -d2 = {key+= [0, 1, 2]} # non-recommended -d3 = {key +=[0, 1, 2]} # non-recommended -``` - -- Remove all commas at the end of the line in the KCL multiline dict because the end commas of each line are optional. - -```python -d = { - key1 = "value1" - key2 = "value2" - key3 = "value3" - key4 = "value4" -} -``` - -## List - -- Keep only **one space** after the comma `,` separating elements in the list - -```python -a = [1, 2, 3] # recommended -b = [1,2,3] # non-recommended -``` - -- Keep only **one space** before and after the comprehension expression token `for` and `in` in the dict and list. - -```python -a = [i for i in range(10)] # recommended -b = [i for i in range(10)] # non-recommended -``` - -## Slice - -- Keep the same number of spaces before and after the colon `:` of the list slice. - -```python -l = [1, 2, 3] -a = l[0:2] # recommended -b = l[0 : 2] # non-recommended -c = l[0: 2] # non-recommended - -d = l[0 + 0 : 1 + 1] # recommended -e = l[0 + 0:1 + 1] # non-recommended -``` - -## Schema - -- Leave only one space before and after the schema attribute assignment `=`. -- Always add a doc string to a schema, which is a good programming habit. - -```python -schema Person: - """ - Schema doc string - """ - name: str = "Alice" # recommended - age : int=12 # non-recommended - -person = Person {} -``` - -- Keep **no spaces** around the schema inheritance operator `()` - -```python -schema Base: - name: str - -schema Person(Base): # recommended - age: int - -schema Schema ( Base ): # non-recommended - age: int -``` - -- Keep **only one space** between the brackets and the schema name of the config at schema instantiation. - -```python -schema Base: - name: str - -schema Person(Base): - age: int - -personA = Person{} # non-recommended -personB = Person {} # recommended -``` - -- Keep **only one space** between the **mixin** keyword and the following `[]` operator - -```python -schema NameMixin: - name: str = "name" - -schema Person: - mixin [NameMixin] # non-recommended - age: int - -schema Parent: - mixin [NameMixin] # recommended - age: int -``` - -### Attribute Annotations - -- Annotations for schema attributes should have a single space after the colon `:` and no space before the colon `:`. - -```python -# recommended: -schema Person: - name: str # No space before the colon `:` - age: int = 18 # Spaces around assignment`=` -``` - -```python -# non-recommended: -schema Person: - codeA:int # No space after the colon `:` - codeB : int # Space before the colon `:` - name: str="Alice" # No spaces around assignment`=` -``` - -- There are no spaces around the colon `:` in the dict type annotation. - -```python -schema Person: - labels: {str:str} # recommended - keyValues: {str : str} # non-recommended -``` - -### Arguments - -- There are no spaces around the assignment `=` in the function/schema/decorator keyword arguments (kwargs). - -```python -schema Person[nameVar]: - # Decorator kwargs - @deprecated(strict=False) # recommended - name: str = nameVar - - @deprecated(strict = False) # non-recommended - age: int - -# Schema kwargs -personA = Person(nameVar="Alice") {} # recommended -personB = Person(nameVar = "Bob") {} # non-recommended - -# Function kwargs -print("", end='') # recommended -print("", end = '') # non-recommended -``` - -## Keywords - -- Only one space is usually reserved around the keyword, such as `schema`, `mixin`, `is` and `not`, etc. - -```python -schema NameMixin: - check: - name not None - -schema Person: - """ - Person schema definition - """ - mixin [NameMixin] - - name: str = "Alice" - age: int - -person = Person { - age = 18 -} -``` - -## Function - -- There are no spaces around the function/package select operator `.` -- There are no spaces between the function name and the parentheses `()`. - -```python -import math - -print(math.log(10)) # recommended -print( math . log (10)) # non-recommended -``` diff --git a/versioned_docs/version-0.6.0/reference/lang/spec/datatypes.md b/versioned_docs/version-0.6.0/reference/lang/spec/datatypes.md deleted file mode 100644 index ef7ea71a..00000000 --- a/versioned_docs/version-0.6.0/reference/lang/spec/datatypes.md +++ /dev/null @@ -1,452 +0,0 @@ ---- -title: "Data Types" -linkTitle: "Data Types" -type: "docs" -weight: 2 -description: Data Types ---- - -## Syntax - -### Bool - -Boolean values are the two constant objects `False` and `True`. They are used to represent truth values (although other values can also be considered false or true). The built-in function bool() can be used to convert any value to a Boolean, if the value can be interpreted as a truth value. - -### Int - -Int, or integer, is an arbitrarily sized integer, positive or negative, without decimals, of 64 binary digits precision(-9,223,372,036,854,775,808~9,223,372,036,854,775,807). Int is created by int literals or as the result of built-in functions and operators. Unadorned integer literals (including `hex`, `octal` and `binary` numbers) yield integers. The constructor int() can be used to produce int of a specific type. - -Besides, integer literals may have an `SI` or `IEC` multiplier. - -- `SI`: General integer or fixed-point number form: `P`, `T`, `G`, `M`, `K`, `k`, `m`, `u`, `n`. -- `IEC`: Corresponding power of 2: `Pi`, `Ti`, `Gi`, `Mi`, `Ki`. - -```python -a = 1 # positive integer: 1 -b = -1 # negative integer: -1 -c = 0x10 # hexadecimal literal: 16 -d = 0o10 # octal literal: 8, or the form `010` -e = 0b10 # binary literal: 2 -f = 10Ki # integer literal with IEC multiplier: 10240 -g = 1M # integer literal with SI multiplier: 1000000 -h = int("10") # int constructor: 10 -i = int("10Ki") # int constructor with multiplier: 10240 -``` - -Notes: - -- Report an error if unable to represent an integer value precisely. - -### Float - -Float, floating-point, approximation to real numbers, positive or negative, containing one or more decimals, of 64 bit IEEE 754 floats. The constructor float() can be used to produce int of a specific type. - -```python -a = 1.10 -b = 1.0 -c = -35.59 -d = 32.3+e18 -f = -90. -g = -32.54e100 -h = 70.2-E12 -i = float("112") # float constructor -``` - -Notes: - -- Report an error if unable to represent a floating-point value due to overflow -- Report a warning if unable to represent a floating-point value due to underflow. Round to the nearest representable value if unable to represent a floating-point value due to limits on precision. These requirements apply to the result of any expression except for built-in functions for which an unusual loss of precision must be explicitly documented. - -#### None - -In KCL, `None` can indicate that the value of the object is empty, which is similar to `nil` in Go or `null` in Java, and corresponds to `null` in YAML and JSON. - -```python -a = None -b = [1, 2, None] -c = {"key1" = "value1", "key2" = None} -``` - -Please note that `None` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + None # error -b = int(None) # error -c = not None # True -d = None == None # True -e = None or 1 # 1 -f = str(None) # None -``` - -#### Undefined - -`Undefined` is similar to None, but its semantics is that a variable is not assigned any value and will not be output to YAML or JSON. - -```python -a = Undefined -b = [1, 2, Undefined] -c = {"key1" = "value1", "key2" = Undefined} -``` - -Please note that `Undefined` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + Undefined # error -b = int(Undefined) # error -c = not Undefined # True -d = Undefined == Undefined # True -e = Undefined or 1 # 1 -f = str(Undefined) # Undefined -``` - -### Common Numeric Operations - -Int and Float support the following operations (see built-in proposal for built-in details): - -- `x + y`: sum of x and y. -- `x - y`: difference of x and y. -- `x * y`: product of x and y. -- `x / y`: quotient of x and y. -- `x // y`: floored quotient of x and y. -- `x % y`: remainder of x / y. -- `x ** y`: x to the power y. -- `-x`: x negated. -- `+x`: x unchanged. -- `~x`: x bitwise negation. -- `abs(x)`: absolute value or magnitude of x. -- `int(x)`: x converted to integer. -- `float(x)`: x converted to floating point. - -KCL supports mixed arithmetic: when a binary arithmetic operator has operands of different numeric types, the operand with the "narrower" type is widened to that of the other, where integer is narrower than floating-point. - -### String - -Strings are immutable sequences of Unicode characters. String literals are written in a variety of ways: - -```python -'allows embedded "double" quotes' # Single quotes -"allows embedded 'single' quotes" # Double quotes -'''Three single quotes''', """Three double quotes""" # Triple quoted -``` - -Triple quoted strings may span multiple lines. - -Indexing a string produces strings of length 1, for a non-empty string s, `s[0] == s[0:1]`. - -```python -a = "Hello, World!" -b = a[2:5] # "llo" -c = a[-5:-2] # "orl" -d = a[::-1] # "'!dlroW ,olleH'" -``` - -- `str(x=None) -> str` - -Return a string. If _x_ is not provided, raise a runtime error. - -```python -x = str(3.5) # "3.5" -``` - -#### Members - -Built-in function and members of a string - -- `str#len() -> int` - Return the number of characters in the string. -- `capitalize() -> str` - Return a copy of the string with its first character (if any) capitalized and the rest lowercased. -- `count(sub: str, start: int = 0, end: int = -1) -> int` - Returns the number of (non-overlapping) occurrences of substring sub in string, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `endswith(suffix: str, start: int = 0, end: int = -1) -> bool` - Returns `True` if the string ends with the specified suffix, otherwise return `False`, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `find(sub: str, start: int = 0, end: int = -1) -> int` - Returns the lowest index where substring sub is found, or -1 if no such index exists, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `format(*args, **kwargs) -> str` - Perform string interpolation. Format strings contain replacement fields surrounded by curly braces {}. Anything that is not contained in braces is considered literal text, which is copied unchanged to the output. If you need to include a bracket character in the literal text, it can be escaped by doubling: A replacement field can be either a name, a number or empty. Values are converted to strings using the str function. -- `index(sub: str, start: int = 0, end: int = -1) -> int` - Returns the first index where sub is found, or raises an error if no such index exists, optionally restricting to `[start:end]` start being inclusive and end being exclusive. -- `isalnum() -> bool` - Returns True if all characters in the string are alphanumeric (`[a-zA-Z0-9]`) and there is at least one character, False otherwise. -- `isalpha() -> bool` - Returns True if all characters in the string are alphabetic (`[a-zA-Z]`) and there is at least one character. -- `isdigit() -> bool` - Returns True if all characters in the string are digits (`[0-9]`) and there is at least one character. -- `islower() -> bool` - Returns True if all cased characters in the string are lowercase and there is at least one character. -- `isspace() -> bool` - Returns True if all characters are white space characters and the string contains at least one character. -- `istitle() -> bool` - Returns True if the string is in title case and it contains at least one character. This means that every uppercase character must follow an uncased one (e.g., whitespace) and every lowercase character must follow a cased one (e.g., uppercase or lowercase). -- `isupper() -> bool` - Returns True if all cased characters in the string are uppercase and there is at least one character. -- `join(iterable: list) -> str` - Return a string which is the concatenation of the strings in iterable. A TypeError will be raised if there are any non-string values in iterable. The separator between elements is the string providing this method. Example: - - ```python - >>> "|".join(["a", "b", "c"]) - "a|b|c" - ``` - -- `lower() -> str` - Returns a copy of the string with all the cased characters converted to lowercase. -- `lstrip(chars: str) -> str` - Return a copy of the string with leading characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.lstrip() - 'spacious ' - >>> 'www.example.com'.lstrip('cmowz.') - 'example.com' - ``` - -- `replace(old: str, new: str, count: int) -> str` - Return a copy of the string with all occurrences of substring old replaced by new. If the optional argument count is given, only the first count occurrences are replaced. -- `rfind(sub: str, start: int = 0, end: int = -1) -> int` - Return the highest index in the string where substring sub is found, such that sub is contained within s[start:end]. Optional arguments start and end are interpreted as in slice notation. Return -1 on failure. -- `rindex(sub: str, start: int = 0, end: int = -1) -> int` - Returns the last index where sub is found, or raises an ValueError if no such index exists, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `rsplit(sep: str, maxsplit: int = -1) -> list` - Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done, the rightmost ones. If sep is not specified or None, any whitespace string is a separator. Except for splitting from the right, rsplit() behaves like split() which is described in detail below. -- `rstrip(chars: str) -> str` - Return a copy of the string with trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a suffix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.rstrip() - ' spacious' - >>> 'mississippi'.rstrip('ipz') - 'mississ' - ``` - -- `split(sep: str, maxsplit: int) -> list` - Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done (thus, the list will have at most maxsplit+1 elements). If maxsplit is not specified or -1, then there is no limit on the number of splits (all possible splits are made). - - If sep is given, consecutive delimiters are not grouped together and are deemed to delimit empty strings (for example, `'1,,2'.split(',')` returns `['1', '', '2']`). The sep argument may consist of multiple characters (for example, `'1<>2<>3'.split('<>')` returns `['1', '2', '3']`). Splitting an empty string with a specified separator returns `['']`. - - For example: - - ```python - >>> '1,2,3'.split(',') - ['1', '2', '3'] - >>> '1,2,3'.split(',', maxsplit=1) - ['1', '2,3'] - >>> '1,2,,3,'.split(',') - ['1', '2', '', '3', ''] - ``` - - If sep is not specified or is None, a different splitting algorithm is applied: runs of consecutive whitespace are regarded as a single separator, and the result will contain no empty strings at the start or end if the string has leading or trailing whitespace. Consequently, splitting an empty string or a string consisting of just whitespace with a `None` separator returns `[]`. - - For example: - - ```python - >>> '1 2 3'.split() - ['1', '2', '3'] - >>> '1 2 3'.split(maxsplit=1) - ['1', '2 3'] - >>> ' 1 2 3 '.split() - ['1', '2', '3'] - ``` - -- `splitlines(keepends: str) -> list` - Return a list of the lines in the string, breaking at line boundaries('\n', '\r\n', '\r'). Line breaks are not included in the resulting list unless keepends is given and true. - - This method splits on the following line boundaries. In particular, the boundaries are a superset of universal newlines. - - For example: - - ```python - >>> 'ab c\n\nde fg\rkl\r\n'.splitlines() - ['ab c', '', 'de fg', 'kl'] - >>> 'ab c\n\nde fg\rkl\r\n'.splitlines(keepends=True) - ['ab c\n', '\n', 'de fg\r', 'kl\r\n'] - ``` - - Unlike `split()` when a delimiter string sep is given, this method returns an empty list for the empty string, and a terminal line break does not result in an extra line: - - ```python - >>> "".splitlines() - [] - >>> "One line\n".splitlines() - ['One line'] - ``` - - For comparison, `split('\n')` gives: - - ```python - >>> ''.split('\n') - [''] - >>> 'Two lines\n'.split('\n') - ['Two lines', ''] - ``` - -- `startswith(prefix: str, start: int = 0, end: int = -1) -> bool` - Return `True` if string starts with the prefix, otherwise return False. prefix can also be a list of prefixes to look for. With optional start, test string beginning at that position. With optional end, stop comparing string at that position. -- `strip(chars: str) -> str` - Return a copy of the string with the leading and trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix or suffix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.strip() - 'spacious' - >>> 'www.example.com'.strip('cmowz.') - 'example' - ``` - - The outermost leading and trailing chars argument values are stripped from the string. Characters are removed from the leading end until reaching a string character that is not contained in the set of characters in chars. A similar action takes place on the trailing end. For example: - - ```python - >>> comment_string = '#....... Section 3.2.1 Issue #32 .......' - >>> comment_string.strip('.#! ') - 'Section 3.2.1 Issue #32' - ``` - -- `title() -> str` - Return a titlecased version of the string where words start with an uppercase character and the remaining characters are lowercase. - - For example: - - ```python - >>> 'Hello world'.title() - 'Hello World' - ``` - - The algorithm uses a simple language-independent definition of a word as groups of consecutive letters. The definition works in many contexts but it means that apostrophes in contractions and possessives form word boundaries, which may not be the desired result: - - ```python - >>> "they're bill's friends from the UK".title() - "They'Re Bill'S Friends From The Uk" - ``` - -- `upper() -> str` - Return a copy of the string with all the cased characters 4 converted to uppercase. Note that `s.upper().isupper()` might be `False` if s contains uncased characters or if the Unicode category of the resulting character(s) is not “Lu” (Letter, uppercase), but e.g., “Lt” (Letter, titlecase). -- `removeprefix(prefix: str) -> str` - If the string starts with the prefix string, return string[len(prefix):]. Otherwise, return a copy of the original string. - ```python - >>> "prefix-data".removeprefix("prefix-") - "data" - ``` -- `rermovesuffix(suffix: str) -> str` - If the string ends with the suffix string and that suffix is not empty, return string[:-len(suffix)]. Otherwise, return a copy of the original string. - ```python - >>> "data-suffix".removesuffix("-suffix") - "data" - ``` - -### List - -Lists are immutable sequences, typically used to store collections of homogeneous items (where the precise degree of similarity will vary by application). - -Lists may be constructed in several ways: - -- Using a pair of square brackets to denote the empty list: `[]` -- Using square brackets, separating items with commas: `[a]`, `[a, b, c]` -- Using a list comprehension: `[x for x in iterable]` -- Using the type constructor: list() or list(iterable) - -The constructor builds a list whose items are the same and in the same order as iterable’s items.Iterable may be either a sequence, a container that supports iteration, or an iterator object. If iterable is already a list, a copy is made and returned, similar to `iterable[:]`. For example, `list('abc')` returns `['a', 'b', 'c']` and `list([1, 2, 3])` returns `[1, 2, 3]`. If no argument is given, the constructor creates a new empty list `[]`. - -Lists implement all of the common sequence operations. - -#### Members - -- `len()` - Return the number of items in the list. - -### Common Sequence Operations - -The operations in the following table are supported by List and Dict. - -This table lists the sequence operations sorted in ascending priority. In the table, s and t are sequences of the same type, n, i, j and k are integers and x is an arbitrary object that meets any type and value restrictions imposed by s. - -The `in` and `not in` operations have the same priorities as the comparison operations. The + -(concatenation) and \* (repetition) operations have the same priority as the corresponding numeric operations. - -| Operation | Result | Notes | -| ------------ | -------------------------------------------------- | ----- | -| `x in s` | `True` if an item of s is equal to x, else `False` | #1 | -| `x not in s` | `False` if an item of s is equal to x, else `True` | #1 | -| `s + t` | the concatenation of s and t | #5 | -| `s[i]` | ith item of s, origin 0 | #2 | -| `s[i:j]` | slice of s from i to j | #2 #3 | -| `s[i:j:k]` | slice of s from i to j with step k | #2 #4 | -| `min(s)` | smallest item of s | | -| `max(s)` | largest item of s | | - -Notes: - -- 1. While the in and not in operations are used only for simple containment testing in the - general case, some specialized sequences (str) also use them for subsequence testing: - -```python ->>> "gg" in "eggs" -True -``` - -- 2. If i or j is negative, the index is relative to the end of sequence s: `s.len() + i` or `s.len() + j` is substituted. But note that -0 is still 0. -- 3. The slice of s from i to j is defined as the sequence of items with index k such that `i <= k < j`. If i or j is greater than `s.len()`, use `s.len()`. If i is omitted or None, use 0. If j is omitted or None, use `s.len()`. If i is greater than or equal to j, the slice is empty. -- 4. The slice of s from i to j with step k is defined as the sequence of items with index `x = i + n*k` such that `0 <= n < (j-i)/k`. In other words, the indices are `i`, `i+k`, `i+2*k`, `i+3*k` and so on, stopping when j is reached (but never including j). When k is positive, i and j are reduced to s.len() if they are greater. When k is negative, i and j are reduced to s.len() - - - If they are greater. If i or j are omitted or None, they become “end” values (which end depends on the sign of k). Note, k cannot be zero. If k is None, it is treated like 1. - -- 5. Concatenating immutable sequences always results in a new object. This means that building up a sequence by repeated concatenation will have a quadratic runtime cost in the total sequence length. To get a linear runtime cost, you must switch to one of the alternatives below: - - - if concatenating str objects, you can build a list and use `str.join()` at the end - -- 6. `index` raises `ValueError` when x is not found in s. Not all implementations support passing the additional arguments i and j. These arguments allow efficient searching of subsections of the sequence. Passing the extra arguments is roughly equivalent to using `s[i:j].index(x)`, only without copying any data and with the returned index being relative to the start of the sequence rather than the start of the slice. - -### Dict - -Dict is an immutable mapping object maps hashable values to arbitrary objects. A dictionary’s keys are almost arbitrary values. Values that are not hashable, that is, values containing lists, dictionaries may not be used as keys. Numeric types used for keys obey the normal rules for numeric comparison: if two numbers compare equal (such as 1 and 1.0) then they can be used interchangeably to index the same dictionary entry. (Note however, that since computers store floating-point numbers as approximations it is usually unwise to use them as dictionary keys.) Dict is ordered. The order of the keys is the order of their declaration. - -Dictionaries can be created by placing a comma-separated list of keys: value pairs within braces, for example: `{'jack': 4098, 'sjoerd': 4127}` or `{4098: 'jack', 4127: 'sjoerd'}`, by the dict constructor, or list/dict comprehension. - -- `dict(obj)` - -Return a new dictionary initialized from an optional positional argument and a possibly empty set of keyword arguments.If no positional argument is given, an empty dictionary is created. If a positional argument is given and it is a mapping object, a dictionary is created with the same key-value pairs as the mapping object. Otherwise, the positional argument must be an iterable object. Each item in the iterable must itself be an iterable with exactly two objects. The first object of each item becomes a key in the new dictionary, and the second object the corresponding value. If a key occurs more than once, the last value for that key becomes the corresponding value in the new dictionary. If keyword arguments are given, the keyword arguments and their values are added to the dictionary created from the positional argument. If a key being added is already present, the value from the keyword argument replaces the value from the positional argument. To illustrate, the following examples all return a dictionary equal to `{"one": 1, "two": 2, "three": 3}`: - -```python ->>> a = {'two': 2, 'one': 1, 'three': 3} ->>> b = {'one': 1, 'two': 2, 'three': 3} ->>> c = {'three': 3, 'one': 1, 'two': 2} ->>> a == b == c -True -``` - -Providing keyword arguments as in the first example only works for keys that are valid KCL identifiers. Otherwise, any valid keys can be used. - -In the dict comprehension, key/value pairs yielded by the generator expression is set in the dictionary in the order yielded: the first occurrence of the key determines its insertion order, and the last determines the value associated to it. - -```python ->>> {str(i): 2 * i for i in range(3)} -{"0": 0, "1": 2, "2": 4} - ->>> a = {"one": 1, "two": 2, "three": 3} ->>> b = {k: v for k, v in a if v >= 2} -{two: 2, three: 3} -``` - -#### Operations & Members - -These are the operations that dictionaries the support. - -- `list(d)` - Return a list of all the keys used in the dictionary d. -- `len()` - Return the number of items in the dictionary d. -- `d[key]` - Return the item of d with key. Return Undefined if key is not in the map. -- `key in d` - Return True if d has a key, else False. -- `key not in d` - Equivalent to not key in d. -- `d.key` - Return the item of d with key. Return Undefined if key is not in the map. - -Dictionaries compare equal if and only if they have the same (key, value) pairs(keys' ordering matters). Order comparisons (‘<’, ‘<=’, ‘>=’, ‘>’) raise TypeError. - -```python ->>> d = {"one": 1, "two": 2, "three": 3, "four": 4} ->>> d -{'one': 1, 'two': 2, 'three': 3, 'four': 4} ->>> list(d) -['one', 'two', 'three', 'four'] -``` diff --git a/versioned_docs/version-0.6.0/reference/lang/spec/error.md b/versioned_docs/version-0.6.0/reference/lang/spec/error.md deleted file mode 100644 index 2a58b553..00000000 --- a/versioned_docs/version-0.6.0/reference/lang/spec/error.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: "Errors" -linkTitle: "Errors" -type: "docs" -weight: 2 -description: Errors ---- - -When errors happen, developers should be able to detect the error and abort -execution. Thus, KCL introduce the `assert` syntax. - -In the previous topic of `schema` syntax. Errors can also be raised when a -schema is violated. - -## Syntax - -The syntax of the `assert` statement is the following. - -```bnf -assert_stmt: 'assert' test ['if' test] [',' test] -``` - -In the basic form, an `assert` statement evaluates an expression. If the -expression is evaluated to `False`, the assertion is failed, and an error -should be reported. - -In the extended form, an error message can be provided. The error message is -another expression. It is only evaluated when the expression to be evaluated -is evaluated to `False`. The evaluation result of the error message is printed -when reporting the error. - -The following is an example: - -```python -a = 1 -b = 3 -condition = False -# a != b evaluates to True, therefore no error should happen. -assert a != b -# a == b is False, in the reported error message, the message "SOS" should be printed. -assert a == b, "SOS" -# if condition is True, then assert `a == b`, if failed, the message "error message" will be printed. -assert a == b if condition, "error message" -``` - -## The Implementation - -When an error happens, no matter it is caused by the `assert` or the `schema` syntax, -the virtual machine should exit with an exit code greater than `0`. - -The virtual machine may choose to dump the back trace information, and it is strongly recommended to implement it. - -In practice, KCL can dump back trace by default, and an argument can be introduced to disable it. diff --git a/versioned_docs/version-0.6.0/reference/lang/spec/index.md b/versioned_docs/version-0.6.0/reference/lang/spec/index.md deleted file mode 100644 index 88bbaa59..00000000 --- a/versioned_docs/version-0.6.0/reference/lang/spec/index.md +++ /dev/null @@ -1 +0,0 @@ -# KCL Spec diff --git a/versioned_docs/version-0.6.0/reference/lang/spec/kcl-spec.md b/versioned_docs/version-0.6.0/reference/lang/spec/kcl-spec.md deleted file mode 100644 index 63a9d6e7..00000000 --- a/versioned_docs/version-0.6.0/reference/lang/spec/kcl-spec.md +++ /dev/null @@ -1,343 +0,0 @@ ---- -title: "KCL Spec" -linkTitle: "KCL Spec" -type: "docs" -weight: 2 -description: KCL Spec ---- - -## Lexical rules - -### Keywords and reserved words - -The following are the keywords of the KCL: - -```python -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -The following are reserved words for the KCL: - -```python -pass return validate rule flow -def del raise except try -finally while from with yield -global nonlocal struct class final -``` - -### Line comment - -```python -# a comment -``` - -### Operators - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != = -+= -= *= **= /= //= %= -<<= >>= &= ^= -``` - -### Delimiters - -```python -( ) [ ] { } -, : . ; @ -``` - -### Operator precedence - -The following list of operators is ordered from **highest to lowest**: - -| Operator | Description | -| -------------------------------------------------------------------------------- | -------------------------------------------------------- | -| `**` | Exponentiation (highest priority) | -| `+x` `-x` `~x` | Positive, negative, bitwise NOT | -| `*` `/` `%` `//` | Multiplication, division, floor division and remainder | -| `+` `-` | Addition and subtraction | -| `<<` `>>` | Left and right shifts | -| `&` | Bitwise AND | -| `^` | Bitwise XOR | -| \| | Bitwise OR | -| `in`, `not in`, `is`, `is not`, `<`, `<=`, `>`, `>=`, `!=`, `==` | Comparisons, including membership and identity operators | -| `not` | Boolean NOT | -| `and` | Boolean AND | -| `or` | Boolean OR | -| `if – else` | Conditional expression = | -| `=`, `+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `=`, `^=`, `\*\*=`, `//=`, `<<=`, `>>=` | Assign | - -## Grammar - -KCL uses Python's [LarkParser](https://lark-parser.readthedocs.io/en/latest/) tool to describe the grammar, and the specification rules are as follows: - -```bnf -//////////// KCL grammar //////////// -start: (NEWLINE | statement)* - -statement: simple_stmt | compound_stmt -simple_stmt: (assign_stmt | unification_stmt | expr_stmt | assert_stmt | import_stmt | type_alias_stmt) NEWLINE -compound_stmt: if_stmt | schema_stmt | rule_stmt - -//////////// import_stmt //////////// -import_stmt: IMPORT dot_name (AS NAME)? -dot_name: (leading_dots identifier) | identifier -leading_dots: DOT+ - -/////////// assert_stmt //////////// -assert_stmt: ASSERT simple_expr (IF simple_expr)? (COMMA test)? - -//////////// if_stmt //////////// -if_stmt: IF test COLON execution_block (ELIF test COLON execution_block)* (ELSE COLON execution_block)? -execution_block: if_simple_stmt | NEWLINE _INDENT schema_init_stmt+ _DEDENT -if_simple_stmt: (simple_assign_stmt | unification_stmt | expr_stmt | assert_stmt) NEWLINE - -//////////// assign_stmt //////////// -assign_stmt: identifier [COLON type] (ASSIGN identifier)* ASSIGN test - | identifier (COMP_PLUS | COMP_MINUS | COMP_MULTIPLY | COMP_DOUBLE_STAR | COMP_DIVIDE - | COMP_DOUBLE_DIVIDE | COMP_MOD | COMP_AND | COMP_OR | COMP_XOR | COMP_SHIFT_LEFT - | COMP_SHIFT_RIGHT) test - -simple_assign_stmt: identifier ASSIGN test - | identifier (COMP_PLUS | COMP_MINUS | COMP_MULTIPLY | COMP_DOUBLE_STAR | COMP_DIVIDE - | COMP_DOUBLE_DIVIDE | COMP_MOD | COMP_AND | COMP_OR | COMP_XOR | COMP_SHIFT_LEFT - | COMP_SHIFT_RIGHT) test - -//////////// unification_stmt //////////// -unification_stmt: identifier COLON schema_expr - -//////////// schema_stmt //////////// -schema_stmt: [decorators] (SCHEMA|MIXIN|PROTOCOL) NAME [LEFT_BRACKETS [schema_arguments] RIGHT_BRACKETS] [LEFT_PARENTHESES identifier (COMMA identifier)* RIGHT_PARENTHESES] [for_host] COLON NEWLINE [schema_body] -schema_arguments: schema_argument (COMMA schema_argument)* -schema_argument: NAME [COLON type] [ASSIGN test] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt|schema_init_stmt|schema_index_signature)* [check_block] _DEDENT -schema_attribute_stmt: attribute_stmt NEWLINE -attribute_stmt: [decorators] identifier [QUESTION] COLON type [(ASSIGN|COMP_OR) test] -schema_init_stmt: if_simple_stmt | if_stmt -schema_index_signature: LEFT_BRACKETS [NAME COLON] [ELLIPSIS] basic_type RIGHT_BRACKETS COLON type [ASSIGN test] NEWLINE - -//////////// rule_stmt //////////// -rule_stmt: [decorators] RULE NAME [LEFT_BRACKETS [schema_arguments] RIGHT_BRACKETS] [LEFT_PARENTHESES identifier (COMMA identifier)* RIGHT_PARENTHESES] [for_host] COLON NEWLINE [rule_body] -rule_body: _INDENT (string NEWLINE)* check_expr+ _DEDENT - -for_host: FOR identifier - -/////////// decorators //////////// -decorators: (AT decorator_expr NEWLINE)+ -decorator_expr: identifier [call_suffix] - -//////////// type //////////// -type: type_element (OR type_element)* -type_element: schema_type | basic_type | compound_type | literal_type -schema_type: identifier -basic_type: STRING_TYPE | INT_TYPE | FLOAT_TYPE | BOOL_TYPE | ANY_TYPE -compound_type: list_type | dict_type -list_type: LEFT_BRACKETS (type)? RIGHT_BRACKETS -dict_type: LEFT_BRACE (type)? COLON (type)? RIGHT_BRACE -literal_type: string | number | TRUE | FALSE | NONE - -//////////// type alias //////////// -type_alias_stmt: TYPE NAME ASSIGN type - -//////////// check_stmt //////////// -check_block: CHECK COLON NEWLINE _INDENT check_expr+ _DEDENT -check_expr: simple_expr [IF simple_expr] [COMMA primary_expr] NEWLINE - -//////////// mixin_stmt //////////// -mixin_stmt: MIXIN LEFT_BRACKETS [mixins | multiline_mixins] RIGHT_BRACKETS NEWLINE -multiline_mixins: NEWLINE _INDENT mixins NEWLINE _DEDENT -mixins: identifier (COMMA (NEWLINE mixins | identifier))* - - -//////////// expression_stmt //////////// -expr_stmt: testlist_expr -testlist_expr: test (COMMA test)* -test: if_expr | simple_expr -if_expr: simple_expr IF simple_expr ELSE test - -simple_expr: unary_expr | binary_expr | primary_expr - -unary_expr: un_op simple_expr -binary_expr: simple_expr bin_op simple_expr - -bin_op: L_OR | L_AND - | OR | XOR | AND - | SHIFT_LEFT | SHIFT_RIGHT - | PLUS | MINUS | MULTIPLY | DIVIDE | MOD | DOUBLE_DIVIDE - | DOUBLE_STAR - | EQUAL_TO | NOT_EQUAL_TO - | LESS_THAN | GREATER_THAN | LESS_THAN_OR_EQUAL_TO | GREATER_THAN_OR_EQUAL_TO - | IN | L_NOT IN | IS | IS L_NOT | L_NOT | AS -un_op: L_NOT | PLUS | MINUS | NOT - -primary_expr: identifier call_suffix | operand | primary_expr select_suffix | primary_expr call_suffix | primary_expr slice_suffix -operand: identifier | number | string | constant | quant_expr | list_expr | list_comp | config_expr | dict_comp | schema_expr | lambda_expr | LEFT_PARENTHESES test RIGHT_PARENTHESES -select_suffix: [QUESTION] DOT NAME -call_suffix: LEFT_PARENTHESES [arguments [COMMA]] RIGHT_PARENTHESES -slice_suffix: [QUESTION] LEFT_BRACKETS (test | [test] COLON [test] [COLON [test]]) RIGHT_BRACKETS -arguments: argument (COMMA argument)* -argument: test | NAME ASSIGN test | MULTIPLY test | DOUBLE_STAR test - - -//////////// operand //////////// -identifier: NAME (DOT NAME)* -quant_expr: quant_op [ identifier COMMA ] identifier IN quant_target LEFT_BRACE (simple_expr [IF simple_expr] | NEWLINE _INDENT simple_expr [IF simple_expr] NEWLINE _DEDENT)? RIGHT_BRACE -quant_target: string | identifier | list_expr | list_comp | config_expr | dict_comp -quant_op: ALL | ANY | FILTER | MAP -list_expr: LEFT_BRACKETS [list_items | NEWLINE [_INDENT list_items _DEDENT]] RIGHT_BRACKETS -list_items: list_item ((COMMA [NEWLINE] | [NEWLINE]) list_item)* [COMMA] [NEWLINE] -list_item: test | star_expr | if_item -list_comp: LEFT_BRACKETS (list_item comp_clause+ | NEWLINE _INDENT list_item comp_clause+ _DEDENT) RIGHT_BRACKETS -dict_comp: LEFT_BRACE (entry comp_clause+ | NEWLINE _INDENT entry comp_clause+ _DEDENT) RIGHT_BRACE -entry: test (COLON | ASSIGN | COMP_PLUS) test -comp_clause: FOR loop_variables [COMMA] IN simple_expr [NEWLINE] [IF test [NEWLINE]] -if_entry: IF test COLON if_entry_exec_block (ELIF test COLON if_entry_exec_block)* (ELSE COLON if_entry_exec_block)? -if_entry_exec_block: (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry) [NEWLINE] | NEWLINE _INDENT (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry) ((COMMA [NEWLINE] | [NEWLINE]) (test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry))* [COMMA] [NEWLINE] _DEDENT -if_item: IF test COLON if_item_exec_block (ELIF test COLON if_item_exec_block)* (ELSE COLON if_item_exec_block)? -if_item_exec_block: list_item [NEWLINE] | NEWLINE _INDENT list_item ((COMMA [NEWLINE] | NEWLINE) list_item)* [COMMA] [NEWLINE] _DEDENT - -star_expr: MULTIPLY test -double_star_expr: DOUBLE_STAR test -loop_variables: primary_expr (COMMA primary_expr)* -schema_expr: identifier (LEFT_PARENTHESES [arguments] RIGHT_PARENTHESES)? config_expr -config_expr: LEFT_BRACE [config_entries | NEWLINE [_INDENT config_entries _DEDENT]] RIGHT_BRACE -config_entries: config_entry ((COMMA [NEWLINE] | [NEWLINE]) config_entry)* [COMMA] [NEWLINE] -config_entry: test (COLON | ASSIGN | COMP_PLUS) test | double_star_expr | if_entry - -//////////// lambda_expr //////////// -lambda_expr: LAMBDA [schema_arguments] [RIGHT_ARROW type] LEFT_BRACE [expr_stmt | NEWLINE _INDENT schema_init_stmt+ _DEDENT] RIGHT_BRACE - -//////////// misc //////////// -number: DEC_NUMBER [multiplier] | HEX_NUMBER | BIN_NUMBER | OCT_NUMBER | FLOAT_NUMBER -multiplier: SI_N_L | SI_U_L | SI_M_L | SI_K_L | SI_K | SI_M | SI_G | SI_T | SI_P - | SI_K_IEC | SI_M_IEC | SI_G_IEC | SI_T_IEC | SI_P_IEC -string: STRING | LONG_STRING -constant : TRUE | FALSE | NONE | UNDEFINED -// Tokens - -ASSIGN: "=" -COLON: ":" -SEMI_COLON: ";" -COMMA: "," -QUESTION: "?" -ELLIPSIS: "..." -RIGHT_ARROW: "->" -LEFT_PARENTHESES: "(" -RIGHT_PARENTHESES: ")" -LEFT_BRACKETS: "[" -RIGHT_BRACKETS: "]" -LEFT_BRACE: "{" -RIGHT_BRACE: "}" -PLUS: "+" -MINUS: "-" -MULTIPLY: "*" -DIVIDE: "/" -MOD: "%" -DOT: "." -AND: "&" -OR: "|" -XOR: "^" -NOT: "~" -LESS_THAN: "<" -GREATER_THAN: ">" -EQUAL_TO: "==" -NOT_EQUAL_TO: "!=" -GREATER_THAN_OR_EQUAL_TO: ">=" -LESS_THAN_OR_EQUAL_TO: "<=" -DOUBLE_STAR: "**" -DOUBLE_DIVIDE: "//" -SHIFT_LEFT: "<<" -SHIFT_RIGHT: ">>" -AT: "@" - -COMP_PLUS: "+=" -COMP_MINUS: "-=" -COMP_MULTIPLY: "*=" -COMP_DIVIDE: "/=" -COMP_MOD: "%=" -COMP_AND: "&=" -COMP_OR: "|=" -COMP_XOR: "^=" -COMP_DOUBLE_STAR: "**=" -COMP_DOUBLE_DIVIDE: "//=" -COMP_SHIFT_LEFT: "<<=" -COMP_SHIFT_RIGHT: ">>=" - -// Special tokens -IMPORT: "import" -AS: "as" -RULE: "rule" -SCHEMA: "schema" -MIXIN: "mixin" -PROTOCOL: "protocol" -CHECK: "check" -FOR: "for" -ASSERT: "assert" -IF: "if" -ELIF: "elif" -ELSE: "else" -L_OR: "or" -L_AND: "and" -L_NOT: "not" -IN: "in" -IS: "is" -LAMBDA: "lambda" -ALL: "all" -ANY: "any" -FILTER: "filter" -MAP: "map" -TYPE: "type" - -ANY_TYPE: "any" -STRING_TYPE: "str" -INT_TYPE: "int" -FLOAT_TYPE: "float" -BOOL_TYPE: "bool" - -// Constant tokens -TRUE: "True" -FALSE: "False" -NONE: "None" -UNDEFINED: "Undefined" - -// Binary prefix -SI_N_L: "n" -SI_U_L: "u" -SI_M_L: "m" -SI_K_L: "k" -SI_K: "K" -SI_M: "M" -SI_G: "G" -SI_T: "T" -SI_P: "P" -SI_K_IEC: "Ki" -SI_M_IEC: "Mi" -SI_G_IEC: "Gi" -SI_T_IEC: "Ti" -SI_P_IEC: "Pi" -IEC: "i" - -NAME: /\$?[a-zA-Z_]\w*/ -COMMENT: /#[^\n]*/ -NEWLINE: ( /\r?\n[\t ]*/ | COMMENT )+ - -STRING: /r?("(?!"").*?(? **note** -> -> Any character except the ASCII space, tab (`\t`) and formfeed (`\f`) is considered a none-space character. - -- A line ending in a backslash cannot carry a comment (, which will be introduced shortly afterwards). -- A backslash does not continue a comment. -- A backslash does not continue a token except for string literals (i.e., tokens other than string literals cannot be split across physical lines using a backslash). -- A backslash is illegal elsewhere on a line outside a string literal. - -### Implicit Line Joining - -Expressions in parentheses, square brackets or curly braces can be split over more than one physical line without using backslashes. - -- Implicitly continued lines can carry comments. -- The indentation of the continuation lines is not important. -- Blank continuation lines are allowed. -- There is no `NEWLINE` token between implicit continuation lines. -- Implicitly continued lines can also occur within triple-quoted strings (see below); in that case they cannot carry comments. - -### Blank Lines - -### Indentation - -### Comments - -Starting with a `#` character that is not part of a string literal is a comment. A comment ends at the end of the physical line. - -A comment signifies the end of the logical line unless the implicit line joining rules are invoked. - -Comments are ignored by the syntax. - -### Identifiers and Keywords - -Identifiers (also referred to as names) are described by the following lexical definitions. - -Within the ASCII range (from `U+0001` to `U+007F`), the valid characters for identifiers are the uppercase and lowercase letters `A` through `Z`, the underscore `_` and, except for the first character, the digits `0` through `9`. - -Identifiers are unlimited in length. The case is significant. - -### Keywords - -The following identifiers are used as reserved words, or keywords of the language, and cannot be used as ordinary identifiers. They must be spelled exactly as written here: - -``` -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -The following tokens are not used, but they are reserved as possible future keywords: - -``` -pass return validate rule flow -def del raise except try -finally while from with yield -global nonlocal struct class final -``` - -### Literals - -Literals are notations for constant values of some built-in types. - -### String Literals - -String literals are described by the following lexical definitions: - -``` -stringliteral ::= [stringprefix](shortstring | longstring) -stringprefix ::= "r" | "R" -shortstring ::= "'" shortstringitem* "'" | '"' shortstringitem* '"' -longstring ::= "'''" longstringitem* "'''" | '"""' longstringitem* '"""' -shortstringitem ::= shortstringchar | stringescapeseq -longstringitem ::= longstringchar | stringescapeseq -shortstringchar ::= -longstringchar ::= -stringescapeseq ::= "\" -``` - -Multiple adjacent string or bytes literals (delimited by whitespace),possibly using different quoting conventions, are allowed, and their meaning is the same as their concatenation. - -### Numeric Literals - -There are two types of numeric literals: integers and floating-point numbers. - -Integer literals are described by the following lexical definitions: - -``` -integer ::= decinteger | bininteger | octinteger | hexinteger -decinteger ::= nonzerodigit (["_"] digit)* | "0"+ (["_"] "0")* -bininteger ::= "0" ("b" | "B") (["_"] bindigit)+ -octinteger ::= "0" ("o" | "O") (["_"] octdigit)+ -hexinteger ::= "0" ("x" | "X") (["_"] hexdigit)+ -nonzerodigit ::= "1"..."9" -digit ::= "0"..."9" -bindigit ::= "0" | "1" -octdigit ::= "0"..."7" -hexdigit ::= digit | "a"..."f" | "A"..."F" -``` - -Floating-point literals are described by the following lexical definitions: - -``` -floatnumber ::= pointfloat | exponentfloat -pointfloat ::= [digitpart] fraction | digitpart "." -exponentfloat ::= (digitpart | pointfloat) exponent -digitpart ::= digit (["_"] digit)* -fraction ::= "." digitpart -exponent ::= ("e" | "E") ["+" | "-"] digitpart -``` - -## Operators and Delimiters - -### Operators - -The following tokens are operators: - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != @ -``` - -### Delimiters - -The following tokens serve as delimiters in the grammar: - -```python -( ) [ ] { } -, : . ; = += --= *= **= /= //= %= -<<= >>= &= |= ^= -``` - -The period can also occur in floating-point literals. - -The following printing ASCII characters have special meaning as part of other tokens or are otherwise significant to the lexical analyzer: - -``` -' " # \ -``` - -The following printing ASCII characters are not used in KCL. Their occurrence outside string literals and comments is an unconditional error: - -``` -? ` -``` - -## Reference - -Since the lexical conventions of KCL is very similar to that of Python, we use the following document as the reference when writing this chapter. - -- [https://docs.python.org/3/reference/lexical_analysis.html](https://docs.python.org/3/reference/lexical_analysis.html) diff --git a/versioned_docs/version-0.6.0/reference/lang/spec/modules.md b/versioned_docs/version-0.6.0/reference/lang/spec/modules.md deleted file mode 100644 index f8608619..00000000 --- a/versioned_docs/version-0.6.0/reference/lang/spec/modules.md +++ /dev/null @@ -1,621 +0,0 @@ ---- -title: "Modules" -linkTitle: "Modules" -type: "docs" -weight: 2 -description: Modules ---- - -## Modules and the Import System - -KCL code is organized in **modules**. For code in one module to access the code defined in another module, a process called **importing** must be used. - -Importing is undertaken at compile-time in KCL. The advantage is to have static checking enabled. - -A regular KCL module is a file on the file system. It is required to have a `.k` suffix. - -## Packages - -To help manage modules and provide a naming hierarchy, KCL has the concept of packages. In KCL, a package maps to exactly a file system directory, and a regular module maps to a file. - -Files directly under a package are considered parts of the package, instead of individual regular modules. - -Packages can have sub-packages. - -Packages are special modules: - -- All packages in KCL are modules. -- A single-file module can never be a package. - -All modules have a name. - -Sub package names are separated from their parent package name by dots. - -To summary, a regular KCL module is a `.k` file, and a package is a directory on the file system. All `.k` files directly under the directory are included in the package, other files are ignored. If the directory has subdirectories, they become sub-packages as long as there are `.k` files underneath. - -### Intra-Package Name Space Sharing - -Inside a package, all `.k` files are considered parts of the package, instead of regular modules. Code in these files share a single name space and can access names defined in other files, without explicitly granted. - -### Package Initialization - -A package can have the initialization code. The code must exist in only one of the `.k` files under this package. The interpreter guarantees that the initialization code is executed after all definitions. - -## Searching - -The searching begins when an `import` statement is used to import a module. - -### Module Cache - -In KCL, only standard system modules are cached. When a cached module is imported, the cached version is used. In other words, KCL runtime would not create another copy of the standard system module in memory. - -However, other modules are uncached. Importing a module multiple time would create multiple instances of the module. - -### Module Names - -An `import` statement specifies the name of the module to import. The syntax is: - -``` -import [as ] -``` - -The rule to search with the module name is very simple: - -- **Step 1**: Searches the module name from the **standard system modules**, then **plugins modules**. - - See **standard system modules** and **plugins modules** for more details. If matched, the module is imported. Otherwise, continue to **Step 2**. -- **Step 2**. Whether a module name starts with a `.` is checked. If yes, the name is a so-called relative pathname, and we go to **Step 5**. Otherwise, continue to **Step 3**. -- **Step 3**: If the module name does not start with any `.`, then the compiler searches the nearest `root path` directory from this directory to the parent, and find the module according to the name just from the `root path`. If no `root path` is found, find the module according to the name from the folder the `.k` file including this `import` statement exists. - - **root path**: the directory contains a `kcl.mod` file. If matched, the module is imported. Otherwise, continue to **Step 4**. -- **Step 4**: Then the compiler checks if the name is the name of any library module that requires explicit loading. If matched, the library module is imported. Otherwise, continue to **Step 6**. -- **Step 5**. For relative importing, find the module according to the name from the folder the `.k` file including this `import` statement exists. Interpret leading dots using the following rule: -- One dot: Ignore. -- Tow or more dots: Suppose there are `n` leading dots, then the searching starts at `n - 1` levels above this folder. If matched, the module is imported. Otherwise, continue to **Step 6**. -- **Step 6**. Module not found, report an error. - -Do case-sensitive search when the operating system allows. If case-sensitive search is not allowed, search directories before regular files. - -In KCL, the `from <> import <>` is unsupported, and relative import is performed with the `import <>` syntax. - -### Uniqueness of Module - -Each module has a unique location path in its scope, so that a module or package could be located with a unique location path, such as `a.b.c`. - -Searching by location path should be supported by the kcl compiler, which needs to provide corresponding searching features through the command line and api form. - -## Standard System Packages - -KCL supports a few standard system modules. The following is the full list of these standard system modules: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PackageMember
datetimetoday
now
ticks
date
mathceil
exp
expm1
factorial
floor
gcd
isfinite
isinf
isnan
log
log1p
log2
log10
modf
pow
sqrt
regexreplace
match
compile
findall
search
split
unitsn
u
m
k
K
M
G
T
P
Ki
Mi
Gi
Ti
Pi
to_n
to_u
to_m
to_K
to_M
to_G
to_T
to_P
to_Ki
to_Mi
to_Gi
to_Ti
to_Pi
jsonencode
decode
dump_to_file
yamlencode
decode
dump_to_file
netsplit_host_port
join_host_port
fqdn
parse_IP
to_IP4
to_IP16
IP_string
is_IPv4
is_IP
is_loopback_IP
is_multicast_IP
is_interface_local_multicast_IP
is_link_local_multicast_IP
is_link_local_unicast_IP
is_global_unicast_IP
is_unspecified_IP
base64encode
decode
cryptomd5
sha1
sha224
sha256
sha384
sha512
- -- datetime - - ticks() -> float - Return the current time in seconds since the Epoch. Fractions of a second may be present if the system clock provides them. - - date() -> str - return the `%Y-%m-%d %H:%M:%S` format date. - - now() -> str - return the local time. e.g. `'Sat Jun 06 16:26:11 1998'` - - today() -> str - return the `%Y-%m-%d %H:%M:%S.%{ticks}` format date. -- math - - ceil(x) -> int - Return the ceiling of x as an Integral. This is the smallest integer >= x. - - factorial(x) -> int - Return x!. Raise a error if x is negative or non-integral. - - floor(x) -> int - Return the floor of x as an Integral. This is the largest integer <= x. - - gcd(a: int, b: int) -> int - Return the greatest common divisor of x and y - - isfinite(x) -> bool - Return True if x is neither an infinity nor a NaN, and False otherwise. - - isinf(x) -> bool - Return True if x is a positive or negative infinity, and False otherwise. - - isnan(x) -> bool - Return True if x is a NaN (not a number), and False otherwise. - - modf(x) -> Listfloat, float] - Return the fractional and integer parts of x. Both results carry the sign of x and are floats. - - exp(x) -> float - Return e raised to the power of x. - - expm1(x) -> float - Return exp(x)-1. This function avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small x. - - log(x, base=2.71828182845904523536028747135266250) -> float - Return the logarithm of x to the base e. - - log1p(x) -> float - Return the natural logarithm of 1+x (base e). The result is computed in a way which is accurate for x near zero. - - log2(x) -> float - Return the base 2 logarithm of x. - - log10(x) -> float - Return the base 10 logarithm of x. - - pow(x, y) -> float - Return x\*\*y (x to the power of y). - - sqrt(x) -> float - Return the square root of x. -- regex - - replace(string: str, pattern: str, replace: str, count=0) -> str - Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement. - - match(string: str, pattern: str) -> bool - Try to apply the pattern at the start of the string, returning a bool value True if any match was found, or False if no match was found. - - compile(pattern: str) -> bool - Compile a regular expression pattern, returning a bool value denoting whether the pattern is valid. - - findall(string: str, pattern: str) -> List[str] - Return a list of all non-overlapping matches in the string. - - search(string: str, pattern: str) -> bool - Scan through string looking for a match to the pattern, returning a bool value True if any match was found, or False if no match was found. - - split(string: str, pattern: str, maxsplit=0) -> List[str] - Scan through string looking for a match to the pattern, returning a Match object, or None if no match was found. -- units - - Unit constants - - Fixed point: `n`, `u`, `m`, `k`, `K`, `G`, `T` and `P`. - - Power of 2: `Ki`, `Mi`, `Gi`, `Ti` and `Pi`. - - Functions - - to_n(num: int) -> str - Int literal to string with `n` suffix - - to_u(num: int) -> str - Int literal to string with `u` suffix - - to_m(num: int) -> str - Int literal to string with `m` suffix - - to_K(num: int) -> str - Int literal to string with `K` suffix - - to_M(num: int) -> str - Int literal to string with `M` suffix - - to_G(num: int) -> str - Int literal to string with `G` suffix - - to_T(num: int) -> str - Int literal to string with `T` suffix - - to_P(num: int) -> str - Int literal to string with `P` suffix - - to_Ki(num: int) -> str - Int literal to string with `Ki` suffix - - to_Mi(num: int) -> str - Int literal to string with `Mi` suffix - - to_Gi(num: int) -> str - Int literal to string with `Gi` suffix - - to_Ti(num: int) -> str - Int literal to string with `Ti` suffix - - to_Pi(num: int) -> str - Int literal to string with `Pi` suffix -- json - - encode(data: any, sort_keys: bool = False, indent: int = None, ignore_private: bool = False, ignore_none: bool = False) -> str - Serialize a KCL object `data` to a JSON formatted str. - - decode(value: str) -> any - Deserialize `value` (a string instance containing a JSON document) to a KCL object. - - dump_to_file(data: any, filename: str, ignore_private: bool = False, ignore_none: bool = False) -> None - Serialize a KCL object `data` to a JSON formatted str and write it into the file `filename`. -- yaml - - encode(data: any, sort_keys: bool = False, ignore_private: bool = False, ignore_none: bool = False) -> str - Serialize a KCL object `data` to a YAML formatted str. - - decode(value: str) -> any - Deserialize `value` (a string instance containing a YAML document) to a KCL object. - - dump_to_file(data: any, filename: str, ignore_private: bool = False, ignore_none: bool = False) -> None - Serialize a KCL object `data` to a YAML formatted str and write it into the file `filename`. -- net - - split_host_port(ip_end_point: str) -> List[str] - Split the 'host' and 'port' from the ip end point. - - join_host_port(host, port) -> str - Merge the 'host' and 'port'. - - fqdn(name: str = '') -> str - Return Fully Qualified Domain Name (FQDN). - - parse_IP(ip) -> str - Parse 'ip' to a real IP address - - to_IP4(ip) -> str - Get the IP4 form of 'ip'. - - to_IP16(ip) -> int - Get the IP16 form of 'ip'. - - IP_string(ip: str | int) -> str - Get the IP string. - - is_IPv4(ip: str) -> bool - Whether 'ip' is a IPv4 one. - - is_IP(ip: str) -> bool - Whether ip is a valid ip address. - - is_loopback_IP(ip: str) -> bool - Whether 'ip' is a loopback one. - - is_multicast_IP(ip: str) -> bool - Whether 'ip' is a multicast one. - - is_interface_local_multicast_IP(ip: str) -> bool - Whether 'ip' is a interface, local and multicast one. - - is_link_local_multicast_IP(ip: str) -> bool - Whether 'ip' is a link local and multicast one. - - is_link_local_unicast_IP(ip: str) -> bool - Whether 'ip' is a link local and unicast one. - - is_global_unicast_IP(ip: str) -> bool - Whether 'ip' is a global and unicast one. - - is_unspecified_IP(ip: str) -> bool - Whether 'ip' is a unspecified one. -- base64 - - encode(value: str, encoding: str = "utf-8") -> str - Encode the string `value` using the codec registered for encoding. - - decode(value: str, encoding: str = "utf-8") -> str - Decode the string `value` using the codec registered for encoding. -- crypto - - md5(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `MD5` and the codec registered for encoding. - - sha1(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA1` and the codec registered for encoding. - - sha224(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA224` and the codec registered for encoding. - - sha256(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA256` and the codec registered for encoding. - - sha384(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA384` and the codec registered for encoding. - - sha512(value: str, encoding: str = "utf-8") -> str - Encrypt the string `value` using `SHA512` and the codec registered for encoding. -- manifests - - `yaml_stream(values: [any], opts: {str:} = {sort_keys = False, ignore_private = True, ignore_none = False, sep = "---"}`. This function is used to serialize the KCL object list into YAML output with the `---` separator - -### The Built-in System Package - -KCL provides a list of built-in system modules, which are loaded automatically and can be directly used without providing any module name. For example, `print` is a widely used built-in module. - -The following is the full list of these built-in system modules: - -- print() - - The print function. -- multiplyof(a, b) - - Check if the modular result of a and b is 0 -- isunique(inval) - - Check if a list has duplicated elements -- len(inval) - Return the length of a value -- abs(x) - Return the absolute value of the argument. -- all(iterable) - Return True if bool(x) is True for all values x in the iterable. If the iterable is empty, return True. -- any(iterable) - Return True if bool(x) is True for any x in the iterable. If the iterable is empty, return False. -- bin(number) - Return the binary representation of an integer. -- hex(number) - Return the hexadecimal representation of an integer. -- oct(number) - Return the octal representation of an integer. -- ord(c) -> int - Return the Unicode code point for a one-character string. -- sorted(iterable) - Return a new list containing all items from the iterable in ascending order. A custom key function can be supplied to customize the sort order, and the reverse flag can be set to request the result in descending order. -- range(start, end, step=1) - Return the range of a value with start, end and step parameter. -- min(iterable) - With a single iterable argument, return its smallest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the smallest argument. -- max(iterable) - With a single iterable argument, return its biggest item. The default keyword-only argument specifies an object to return if the provided iterable is empty. With two or more arguments, return the largest argument. -- sum(iterable, start) - Return the sum of a 'start' value (default: 0) plus an iterable of numbers. When the iterable is empty, return the start value. This function is intended specifically for use with numeric values and may reject non-numeric types. -- pow(x, y, z) - Equivalent to `x**y` (with two arguments) or `x**y % z` (with three arguments). Some types, such as ints, are able to use a more efficient algorithm when invoked using the three argument form. -- round(number, ndigits) - Round a number to a given precision in decimal digits. The return value is an integer if ndigits is omitted or None. Otherwise the return value has the same type as the number. ndigits may be negative. -- typeof(x: any, \*, full_name: bool = False) -> str - Return the type of the value 'x' at runtime. When the 'full_name' is 'True', return the full package type name such as `pkg.schema`. - -### Plugin Modules - -KCL compiler needs to provide the ability to dynamically expand and load plugin modules without modifying the compiler itself. KCL compiler needs to support flexible pluggable module extension mechanism, so that KCL users can use more abundant built-in function capabilities to simplify writing. - -KCL compiler needs to ensure the stability and safety of the expansion mechanism, without affecting the core of the compiler. - -Searching extended plugin module is performed after the standard system module. The standard system module has a higher priority in naming. If it exists a standard or built-in system module with the same name, the extended plugin module will be ignored. - -Importing and using the extended plugin module should be consistent with the standard or built-in system module. - -### Replacing Standard System Packages - -Replacing standard system modules is not allowed. - -## Examples - -We show more module features through an example. - -Suppose we have the following directories and files: - -``` - . - ├── mod1.k - ├── mod2.k - ├── pkg1 - │   ├── def1.k - │   ├── def2.k - │   └── def3init.k - └── pkg2 - ├── file2.k - └── subpkg3 - └── file3.k -``` - -From the structure we can see that `pkg1` and `pkg2` are two packages, `subpkg3` is a subpackage of `pkg2`, and `mod1.k` and `mod2.k` are regular modules. - -### Importing a Standard System Package - -The following statement can import the standard system module `math` - -```python -import math -``` - -This is the only way to import a standard system module. After importing a standard system module, functions, variables and schemas defined in it can be used. For example, the following statement uses the `log10` function -defined in `math` - -```python -a = math.log10(100) # a is 2 after computation. -``` - -### Importing a Regular Module - -In `mod1.k`, we can import `mod2` using one of the following syntaxes. - -```python -import mod2 -``` - -```python -import .mod2 -``` - -The difference is that in the first syntax, the KCL compiler will first try to check if `mod2` matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where `mod1.k` resists in, like what the second statement does. - -Suppose in `mod2.k` there is a definition of a variable:: - -```python -a = 100 -``` - -After importing `mod2`, we can access `a` in `mod1.k` using the following syntax - -```python -b = mod2.a -``` - -### Importing a Package - -In `mod1.k`, we can import `pkg1` using one of the following syntaxes. - -```python -import pkg1 -``` - -```python -import .pkg1 -``` - -The difference is that in the first syntax, the KCL compiler will first try to check if `pkg1` matches any of the standard system modules' name. Since it does not match any standard system module's name, the statement will check the directory where `mod1.k` resists in, like what the second statement does. - -We can use similar statements to import `pkg2`. Note that importing `pkg2` will not import `subpkg3`. - -The name of the package is the name of the imported module. - -Suppose in `file2.k` that is inside `pkg2` there is a definition to variable `foo` - -```python -foo = 100 -``` - -This variable can be used in `mod1.k` after importing `pkg2` like the following - -```python -bar = pkg2.foo -``` - -### Importing a Subpackage - -To import `subpkg3` from `mod1.k`, one of the following statements can be used. - -```python -import pkg2.subpkg3 -``` - -```python -import .pkg2.subpkg3 -``` - -The behaviors of these statements are identical. - -The name of the subpackage is the name of the imported module. - -Suppose in `file3.k` that is inside `subpkg3` there is a definition to variable `foo` - -```python -foo = 100 -``` - -This variable can be used in `mod1.k` after importing `subpkg3` like the following - -```python -bar = subpkg3.foo -``` - -### Relative Importing - -Relative importing is useful when there is code trying to import modules that does not exist recursively inside the current directory. - -For example, the following statements, if written in `file3.k`, can be used to import `pkg2`, `pkg1` and `mod2` respectively. - -```python -import ...pkg2 # Go two levels up then import pkg2 -import ...pkg1 # Go two levels up then import pkg1 -import ...mod2 # Go two levels up then import mod2 -``` - -### Importing from a Root Path - -Suppose we have a `kcl.mod` file in the directory to mark it as a root path, then we have the following files: - -``` - . - |── kcl.mod - ├── mod1.k - ├── mod2.k - ├── pkg1 - │   ├── def1.k - │   ├── def2.k - │   └── def3init.k - └── pkg2 - ├── file2.k - └── subpkg3 - └── file3.k -``` - -In `pkg1` `def1.k`, we can import `pkg2.subpkg3` `file3` using the following syntaxes. - -```python -import pkg2.subpkg3.file3 -``` - -Importing from the root path is very convenient when the code is trying to import modules from a directory needs to look up multiple directories above this directory. At also, it is helpful to organize a large number of files in a root directory. - -### Importing a Module Inside a Package - -Note that `subpkg3` is only implemented with one file `file3.k`. The file can be regarded as a regular module and imported directly. - -In `mod1.k`, the importing statement would be:: - -```python -import pkg2.subpkg3.file3 -``` - -Different from importing `subpkg3`, now the name of the module is `file3`. We can access the variable `foo` defined in this module with the following -statement - -```python -bar = file3.foo -``` - -### Precedence of Importing - -When an import statement specifies a package to import, the virtual machine first looks for a directory named according to the import statement in the file system. - -If such a directory is not found, the virtual machine looks for a single file module. - -For example, when the statement `import a.b.c` appears, the virtual machine first looks for the directory `a/b/c` from the directory of the current file. If `a/b/c` is not found, the virtual machine looks for a file named `a/b/c.k`. If the file is also absent, an error is reported. - -### Package Implemented with Multiple Files - -Package `pkg1` is implemented with multiple KCL files. - -Multiple files can be used to define variables, schemas and functions, and they can access names defined in other files of this package. - -For example, suppose `def1.k` defines a variable `foo`, `def2.k` defines `bar`, and `def3init.k` defines a variable `baz`, when `pkg1` is imported by `mod1.k`, all these variable can be used - -```python -import pkg1 -a = pkg1.foo + pkg1.bar + pkg1.baz -``` - -Inside a module, names defined in a file can be accessed in another file without further importing. For example, suppose `bar` in `def2.k` would invoke `foo` defined in `def1.k`, it can directly use `foo` like the following - -```python -bar = foo + 1 -``` diff --git a/versioned_docs/version-0.6.0/reference/lang/spec/schema.md b/versioned_docs/version-0.6.0/reference/lang/spec/schema.md deleted file mode 100644 index c3d09f65..00000000 --- a/versioned_docs/version-0.6.0/reference/lang/spec/schema.md +++ /dev/null @@ -1,916 +0,0 @@ ---- -title: "Schema" -linkTitle: "Schema" -type: "docs" -weight: 2 -description: Schema ---- - -## Syntax - -### Schema Definition - -A schema is a language element to define a type of configuration data. - -To define a schema, the syntax is the following: - -```bnf -schema_stmt: [decorators] "schema" ["relaxed"] identifier ["[" [arguments] "]"] ["(" operand_name ")"] ":" NEWLINE [schema_body] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt | schema_index_signature | statement)* [check_block] _DEDENT -``` - -Attributes could be defined in a schema, the syntax is the following: - -```bnf -schema_attribute_stmt: [decorators] identifier ["?"] ":" type [(ASSIGN | augassign) test] NEWLINE -``` - -Index signature could be defined in a schema, the syntax is the following: - -```bnf -schema_index_signature: LEFT_BRACKETS [NAME COLON] [ELLIPSIS] basic_type RIGHT_BRACKETS COLON type [ASSIGN test] NEWLINE -``` - -Once defined, an attribute must have a valid type: - -```bnf -type: type_element ("|" type_element)* -type_element: schema_type | basic_type | list_type | dict_type -schema_type: operand_name -basic_type: "str" | "int" | "float" | "bool" -list_type: "[" (type)? "]" -dict_type: "{" (type)? COLON (type)? "}" -``` - -The followings are some basic examples: - -```python -# A person has a first name, a last name and an age. -schema person: - firstName: str - lastName: str - # fullName is generated by firstName and lastName - fullName: str = firstName + ' ' + lastName - # The default value of age is 0 - age: int = 0 - -# An employee IS a person, and has some additional information. -schema employee(person): - bankCard: int - nationality: str - -# A company has a name and many employees. -schema company: - name: str - employees: [employee] -``` - -More complex schema definitions will be elaborated after other concepts are -introduced. - -#### Optional Attribute - -Each attribute **must** be assigned with a not-None value as a schema instance unless it is modified by a question mark as an optional attribute. - -Examples: - -```bnf -schema employee(person): - bankCard?: int # bankCard is an optional attribute - nationality?: str # # nationality is an optional attribute -``` - -When there is an inheritance relationship: - -- If the attribute is optional in the base schema, it could be optional or required in the sub-schema. -- If the attribute is required in the base schema, it must be required in the sub-schema. - -### Configuration Definition - -A configuration is structured data stored in a dict-like structure. In KCL, we have introduced -the configuration definition syntax as a variant of dict definition syntax. - -```bnf -schema_expr: operand_name ("(" [arguments] ")")? dict_expr -``` - -As can be seen, apart from having an identifier as schema type, a configuration definition -is just an ordinary dict definition, and each key in the dict matches an attribute in the schema. - -To simplify configuration, schema attribute key is much easier to define as: - -- schema attribute key can be unquoted. When the attribute key has the same name as a variable, it must be quoted as a normal dict to avoid naming conflict. -- schema attribute key can be defined nested through `select expression`, such as `a.b.c`. - -The comma at the end of each line can be omitted. - -For example, we can define a `person` named `John Doe` using the following statement: - -```python -johnDoe = person { - # In the result, 'lastName' appears later than 'firstName', according the schema - lastName = 'Doe' - firstName = 'John' - # If we don't specify the 'age', the default value 0 is used. - # 'age': 20 -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' - 'age': 0 -} -``` - -Compared to the ordinary dict definition, a configuration definition has the following features: - -- Each attribute defined in the schema (or one of the schemas) could be configured, and config data has higher priority than the default value. -- When an attribute defined in the schema (or one of the schemas) is not configured in the configuration definition statement, and it has a default value, the default value is used. -- Unless the schema (or one of the schemas) is a **relaxed schema**, no more attributes can be defined. -- The quotation marks of dict key can be omitted. -- The comma at the end of each line can be omitted. -- Cases of **inheritance** will be discussed separately. - -For attributes of list, dict and schema types, the config data is added by **union** instead of reassignment. For instance: - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name = { - firstNam = "John" - lastName = "default" - } - -JohnDoe = Person { - name.lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' -} -``` - -#### Attribute Identify - -Each key identifier in the configuration expr identifies an element or a range of elements in a schema. The key identifier may consist of multiple attribute identifiers, and each attribute may be a basic type value, a list, a dict or schema. For example, the key identifier 'a.b.c' identifies the element 'c' in the 'A' schema: - -```python - -schema C: - c: int - -schema B: - b: C - -schema A: - a: B - -A { - a.b.c: 5 -} -``` - -To make the key identifier usage rules as clear as possible, we define the way of identifying with complex data types as follows. - -##### List - -Suppose we have a list attribute a. - -Identify an element in a: - -```python -a[0] # the first element -a[3] # the 4th element -a[-1] # the last element -a[-2] # the penultimate element -``` - -Identify a range of elements in the list: - -```python -a[2:5] # a slice of the third, 4th, and 5th elements -a[:5] # a slice of the first to 5th elements -``` - -#### Attribute Operator - -Once we identified the element(s), we can declare operation on it. It follows the pattern of `identifier op E`. - -#### Union - -Pattern: `identifier : E` - -The value of the expression `E` will be unioned into the element value. - -Examples: - -```python -a = A { - # union {d:4} into the element b.c, suppose c is a schema with an int type attribute d. - b.c : { - d : 4 - } -} -``` - -See 'union' in `expressions` spec for more details. - -#### Override - -Pattern: `identifier = E` - -The value of the expression `E` will override the element value. - -Examples: - -```python -a = A { - # override {c:4} to the element b, suppose b is a schema with an int type attribute c. - b = { - c: 4 - } -} -``` - -Unlike union, the override operation will reassign the element with a brand new value. -For basic type value, `union` and `override` have equivalent effects. - -Note: - -- Especially, we can "delete" its content by overriding the element to `Undefined`, such as `{ a = Undefined }`. - -#### Insert - -Pattern: `identifier += E` -Insert only works for list type `identifier`. - -List `E` will be inserted just after the specified index of the list `identifier`, and the following elements after the index will be automatically shifted. - -Examples: - -```python -a = A { - # insert {c:4} to the end position(just after index=1), suppose b is a list of schema with an int type attribute c. - b += { - c: 4 - } -} -``` - -If no index is specified, the last index will be used. - -The type of 'E' must be compatible with the type of list. See `types` for more details. - -#### Index Signature - -Index signatures can be defined in the KCL schema, and it means that the key-value constraints of the index signature can be used to construct a dict with the schema type, or additional checks can be added to the relaxed schema attributes to enhance the KCL type and semantic checks. - -- Use the form `[{attr_alias}: {key_type}]: {value_type}` to define an index signature in the schema, and `{attr_alias}` can be omitted. - -```python -schema Map: - """ - Map is a relaxed schema with a key of str type and a value of str type - """ - [str]: str # `{attr_alias}` can be omitted. - -data = Map { - key1 = "value1" - key2 = "value2" -} -``` - -- Mandatory all attributes of the schema key and value types - -```python -schema Person: - name: str - age: int # error, conflicts with the index signature definition `[str]: str` - [str]: str # The values of all attributes of the schema can only be strings -``` - -- Mandatory all attribute key and value types are defined in the schema, which is equivalent to restricting all attribute types except the relaxed attributes. - -```python -schema Person: - name: str - age: int - [...str]: str # Except for the `name` and `age` attributes, the key type of all other attributes of the schema must be `str`, and the value type must also be `str`. -``` - -- Define the index signature attribute alias and use it with the check block. - -```python -schema Data: - [dataName: str]: str - check: - dataName in ["Alice", "Bob", "John"] - -data = Data { - Alice = "10" - Bob = "12" - Jonn = "8" # error Jonn not in ["Alice", "Bob", "John"] -} -``` - -```python -import regex - -schema DataMap: - [attr: str]: str - check: - regex.match(attr, r'^[-._a-zA-Z0-9]+$') - -data = DataMap { - key1 = "value1" - "foo.bar" = "value2" # check error -} -``` - -### Schema Context - -The schema definition space can be regarded as a separate function context. - -Init statement could be defined inside the schema, the syntax is the following: - -```bnf -statement: small_stmt NEWLINE | if_stmt -``` - -The following is an example: - -```python -schema Person: - firstName: str = "John" - lastName: str - # fullName is generated by firstName and lastName in a separate init statement - fullName: str = firstName + ' ' + lastName - -JohnDoe = Person { - lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' -} -``` - -If statement, expr statement and assert statement are supported as a schema init -statement. See more in statement spec. - -- The attributes must be defined first, including inherited ones, and then used in the init statement. -- Statements in the schema context will be executed sequentially. -- The value of attributes referenced in the init statement will be evaluated at runtime. - See the **Configuration Definition** section for the assignment rules of non-referenced attributes. For example, `"fullName"` in Person is generated by `"firstName"` and `"lastName"` evaluated at runtime, in which firstName is 'John', and lastName is "Doe". - -The immutability of attributes in the schema context follows the same rules as the immutability of global variables: - -```python -schema Person: - age: int = 1 # Immutable attribute - _name: str = "Alice" # Mutable attribute - - age = 10 # Error - _name = "Bob" # Ok -``` - -#### Arguments - -Schema context can also have arguments. The following is an example. - -```python -schema Person[separator]: - firstName: str = "John" - lastName: str - fullName: str = firstName + separator + lastName - -JohnDoe = Person('_') { - lastName = "Doe" -} -``` - -The example is similar to the previous one, except that the separator character used in -the `"fullName"` member is passed in as an argument. The way to perform a schema generation -when the schema has an initialization function with arguments is demonstrated in the code. - -### Check Block - -Optionally, a check block can be added to a schema definition to allow -additional checking to be performed. - -The syntax is the following: - -```bnf -check_block: "check" ":" NEWLINE _INDENT check_expr+ _DEDENT -check_expr: test (IF test)? [":" primary_expr] NEWLINE -``` - -In terms of grammatical definition, a check block consists of a list of conditional expressions. The following is an example: - -```python -schema employee(person): - bankCard: int - gender: str - - check: - len(str(bankCard)) == 16 - gender in ['male', 'female'], "The gender {} is unsupported".format(gender) -``` - -The ability of KCL check expressions covers the abilities that can be defined by OpenAPI spec and is aligned with the ability of logical expressions. We consider further aligning the syntax with `CEL` spec. -Whether to support `lambda expressions` is still under discussion. - -Summary: - -- A check block consists of one or more logical **expressions**. -- When defining a configuration, the expressions in the check block are evaluated - in any order. If any of the expression is `False`, an error is reported. -- A custom error message can be provided after an expression. - -### Specifying Types - -Optionally, the type of any member of a schema can be specified. As previous examples have shown. - -A member can be of a basic type, such as a string (`str`), a floating-point number (`float`), a fixed-point number (`int`) or a boolean number (`bool`). - -A member can also be of a dictionary generated from another schema. In such a case, the name of the other schema is used as the type name. - -A member can also be a list or an ordinary dict: - -- A list with unspecified type of elements is `[]`. -- A list with elements of type `t` is `[t]`. Here `t` is another type. -- A dict with keys of type `kt` and values of type `vt` is `{kt:vt}`. -- `kt`, `vt` or both of them can be missing, like a list with unspecified type of elements. - -The followings are some more examples: - -- A list of lists of strings: `[[str]]`. -- A dict of keys with the type string and unspecified value types: `{str:}`. - -A member can be a **union type** defined by `|`, such as `a | b`, which means the type of the member could be a or b. - -A union type can include types of `int`, `str`, `float`, `bool`, `list` and `dict` and support type nesting e.g. `{str:str|int}` and `[[int|str]|str|float]`, etc. - -Examples: - -```python -schema x: - p: int | str # p could be defined as a int or string -``` - -### Immutability - -KCL pursues strict immutability of schema attributes. It's generally followed the rules: - -- For the attributes of the basic type, such as string, int and float, it's allowed to be reassigned - through the init statement in **schema context** or by the **configuration definition**. -- For the attributes of list, dict and schema type, it's allowed to be reassigned only by the init statement in **schema context**. The content of it is allowed to be operated in **schema context** or by the **configuration definition**. -- Any other attempt to reassign or modify schema attribute will report an error. - -#### Assign by Value - -When using a schema variable to assign the value to another variable, we can only get a deep copy of its value, not a pointer or reference. That is, modifying the assigned value will not change the assigned schema variable. - -```python -schema Person: - name: str - -person = { - name = "Alice" -} -personCopy = person # 'personCopy' is a deep copy of 'person' and modifying 'personCopy' will not affect 'person' -``` - -### Union Operator - -For list, dict and schema, we can union delta to existing data. For example: - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name = { - firstName = "John" - } - - # union a schema and a dict - name: Name { - lastName = "Doe" - } - -person = Person {} -``` - -The result is a **dict**: - -```python -{ - 'person': { - 'name': { - 'firstName': 'Jhon', - 'lastName': 'Doe' - } - } -} -``` - -### Other Operators - -Except for `assignment` and `union assignment`, it's not support other operators on schema type data. -Report an error if trying to use other operators on schema type data. - -### Deprecated - -The schema attribute can be marked as deprecated once it's considered invalid. - -```python -schema Person: - @deprecated(version="1.1.0", reason="use fullName instead", strict=True) - name: str - ... # Omitted contents - -person = Person { - # report an error on configing a deprecated attribute - name = "name" -} -``` - -- Deprecated attributes cannot be configured under any circumstances. Report an error or warning once the attribute is assigned. -- Define the expired version of the attribute through **version**, and define the reason for the attribute expired through **reason**. -- When strict is true, the attribute assignment will cause an error, otherwise it will report a warning and ignore the attribute assignment. - -### Composition - -The composition is a common way to define complex structures. KCL provides simplified means for the configuration definition of combined structures. - -Assuming we have the following schemas, which is defined by a combination of multiple schemas. - -```python -schema Name: - firstName: str - lastName: str - -schema Person: - name: Name - age: int - -schema Group: - name: str - persons: [Person] -``` - -To config a group: - -```python -group = Group { - name = "group" - persons = [{ - name = { - firstName = "John" - lastName = "Doe" - } - age = 24 - }] -} -``` - -- Top-level schema name is required to config a schema. -- The schema of the attributes in the schema can be omitted. - -Multi-level nested schemas will make the configuration verbose. KCL supports defining attributes in the schema through `selector expression`. The selector form is **x.y.z**, see the following example: - -```python -group = Group { - name = "group" - persons = [{ - name.firstName = "John" - name.lastName = "Doe" - age = 24 - }] -} -``` - -- Selector can be used to represent attribute in a schema - -### Inheritance - -Inheritance is an effective means to define a hierarchical structure definition, and KCL supports limited **single inheritance** of the schema. - -```python -schema Person: - firstName: str - lastName: str - -# schema Scholar inherits schema Person -schema Scholar(Person): - fullName: str = firstName + '_' + lastName - subject: str - -JohnDoe = Scholar { - firstName = "John", - lastName = "Doe", - subject = "CS" -} -``` - -The result is a **dict**: - -```python -{ - 'JohnDoe': { - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' - 'subject': 'CS' - } -} -``` - -Each schema can be treated as a separated function context. Statements, including attribute statements and init statements, in the context of schemas will be evaluated from base schema to subschema according to the inheritance order. Each schema context is evaluated only once sequentially. The same goes for expressions in the check block. In the example, firstName and lastName are configured in the context of Person schema, and fullName is formed by splicing firstName and lastName in the context of Scholar schema. - -The default value can be modified in each schema. Value defined in **Configuration Definition** has a higher priority than the default value. Attributes with default values in any schema context ​​will eventually be unioned by configuration data. References to attributes in the schema context statements will use the value with unioned configuration data on evaluating at runtime. For example: - -```python -schema a: - x = 1 - y = x * 2 - -schema b(a): - x = 2 - -v = a { - x = 3 -} - -``` - -The result is a **dict**: - -```python -{ - 'v': { - 'x': 3 - 'y': 6 - } -} -``` - -Notes: - -- Report an error if inheriting more than one base schema. -- The type of the base schema attribute cannot be modified in the subschema. -- Report an error if inheriting a **mixin**. -- Report an error when a circular dependency occurs. - -Limitations: - -Since inheritance will derive some complex demands, we are cautious about these complex demands. There are still some restrictions on inheritance, and it's still under discussion. - -- KCL provides limited and deterministic polymorphism support, more complex and flexible polymorphism support, such as **self**, **super** keywords, are temporarily not included in the schema definition. -- Currently, KCL only supports the polymorphism of the inherited attributes of the schema, and does not support the polymorphism of the expressions in the check block. -- For the case of multiple levels of schema inheritance, the schema arguments can only be passed to the last level of sub-schema. - -### Mixin - -In addition to **composition** and **inheritance**, KCL supports declarative reuse of schema code through the **mixin** mechanism. To use a mixin, we only need to declare the **mixin** in the schema definition. - -The **mixin** syntax is the following: - -```bnf -//////////// mixin_stmt //////////// -mixin_stmt: "mixin" "[" [mixins | multiline_mixins] "]" "\n" -multiline_mixins: "\n" _INDENT mixins "\n" _DEDENT -mixins: operand_name ("," ("\n" mixins | operand_name))* -``` - -Here is a simple example: - -```python -schema Person: - mixin [FullNameMixin] - firstName: str = "default" - lastName: str - -schema FullNameMixin: - fullName: str = "{} {}".format(firstName, lastName) - -JohnDoe = Person { - firstName = "John" - lastName = "Doe" -} -``` - -The result is a **dict**: - -```python -{ - 'JohnDoe': { - 'firstName': 'John' - 'lastName': 'Doe' - 'fullName': 'John Doe' - } -} -``` - -Multiple mixins can be added to a single schema, and mixins context will be evaluated after the host schema context at runtime. In the inheritance scenario, the mixin context can be regarded as a part of the host schema context, and the overall evaluation of schema context order is not affected. - -Notes: - -- The name of **mixin** schema must end with 'Mixin', otherwise an error will be reported. -- The attributes referenced in the **mixin** must be defined in the **mixin** itself or host schema, otherwise an error will be reported. - -### Protocol - -In addition to schema, an additional type definition method `protocol` is provided in KCL, and its properties are as follows: - -- In a protocol, only attributes and their types can be defined, complex logic and check expressions cannot be written, and mixins cannot be used. -- A protocol can only inherit or refer to other protocols, but cannot inherit or refer to other schemas. - -We can use **protocol** to add an optional host type to the dynamically inserted **mixin**. - -The **mixin** can define its host type through the `for` keyword, and internally it will query the type corresponding to the attribute from the host type. - -```python -protocol DataProtocol: # A mixin host type - data: str - -mixin DataMixin for DataProtocol: # Using the `for` keyword to define a mixin host type - x: int = data # The type of `data` is `str`, which is from `data` of `DataProtocol` -``` - -In `DataMixin`, the `data` attribute is obtained according to the `DataProtocol` host type as `str` type, and then a type error will occur when the value is assigned to `x` of type `int`: - -```python -protocol DataProtocol: - data: str - -mixin DataMixin for DataProtocol: - x: int = data # Error: expect int, got str - x: str = data # Error: can't change schema field type of 'x' from int to str -``` - -Please note that the host type **protocol** can only be used for **mixin** definitions (the suffix name is `Mixin`), otherwise an error will be reported. - -```python -protocol DataProtocol: - data: str - -schema Data for DataProtocol: # Error: only schema mixin can inherit from protocol - x: str = data -``` - -### Schema Context Evaluation - -The schema definition is composed of attribute statements, configuration data, init statements, mixins, and checks. In a separate schema context, the evaluation top-down order is as follows: - -``` -|------------------------------------------| -| attribute defaulting | -|------------------------------------------| -| configuration union | -|------------------------------------------| -| attribute templating | -|------------------------------------------| -| statements in declaration order | -|------------------------------------------| -| mixins in declaration order | -|------------------------------------------| -| check expressions in any order | -|------------------------------------------| -``` - -In the case of schema inheritance, each schema context is evaluated from the base schema in the order of inheritance, and each context is evaluated only once. -Suppose there are schemas a, b, and c, where c inherits b and b inherits a. Schema contexts will be evaluated in top-down order as: - -``` -|-----------------| -| schema a | -|-----------------| -| schema b | -|-----------------| -| schema c | -|-----------------| -``` - -### Members - -Built-in function and members of schema - -- instances() - Return the list of existing instances of a schema. - -### Irrelevant Order Calculation - -The irrelevant order calculation in the schema indicates the reference relationship between the internal attributes of the schema. For example, when we declare an expression of the form `a = b + 1`, the calculation of the value of `a` depends on the calculation of the value of `b`. When the compiler calculate the value of `a` and the value of `a` depends on the value of `b`, the compiler will choose to first calculate the value of `b`, and then calculate the value of a according to the expression `a = b + 1`, which is slightly different from the calculation method of traditional procedural language the difference. - -Since the calculation of values in the schema is based on dependencies, just like a directed acyclic graph traverses each node in the graph according to the order of topological sorting, the order of declaration of attributes in the schema is not so important, so the feature is called the irrelevant order calculation. - -Please note that there can be no circular references between different schema attribute values. - -We can see this feature through the following examples. - -```python -schema Person: - name?: str - age: int = _age - - _age = 10 - - if name == "Son": - _age = 18 - -schema Son(Person): - name: str = "Son" - -person = Person {} -son = Son {} -``` - -The output is - -```yaml -person: - name: null - age: 10 -son: - name: Son - age: 18 -``` - -Besides, we can achieve KCL polymorphism such as - -```python -schema Person: - name?: str - _age: int = _age - - _age = 10 - if name == "Son": - _age = 18 - elif name == "SonConf": - _age = 24 - -schema Son(Person): - name: str = "Son" - -person = Person() {} -son = Son() { - name = "SonConf" -} -``` - -The output is - -```yaml -person: - name: null - age: 10 -son: - name: SonConf - age: 24 -``` - -More examples: - -```python -schema Fib: - n1: int = n - 1 - n2: int = n1 - 1 - n: int - value: int = _value - - if n <= 2: - _value = 1 - else: - _value = (Fib {n = n1}).value + (Fib {n = n2}).value - -fib8 = (Fib {n = 8}).value -``` - -The output is - -```yaml -fib8: 21 -``` - -As in the above examples, we can see that in the schema, we only need to simply specify the dependency between attributes, and the compiler will automatically calculate the value based on the dependency, which can help us save a lot of boilerplate code and reduce configuration difficulty of writing. diff --git a/versioned_docs/version-0.6.0/reference/lang/spec/statements.md b/versioned_docs/version-0.6.0/reference/lang/spec/statements.md deleted file mode 100644 index b09488b9..00000000 --- a/versioned_docs/version-0.6.0/reference/lang/spec/statements.md +++ /dev/null @@ -1,185 +0,0 @@ ---- -title: "Statements" -linkTitle: "Statements" -type: "docs" -weight: 2 -description: Statements ---- - -## Syntax - -In KCL, statements consist of small statements and compound statements. The syntax is the following: - -```bnf -preamble_statement: preamble_small_stmt | preamble_compound_stmt -preamble_small_stmt: (small_stmt | import_stmt) NEWLINE -preamble_compound_stmt: compound_stmt | schema_stmt -statement: small_stmt NEWLINE | compound_stmt -compound_stmt: if_stmt -small_stmt: assign_stmt | expr_stmt | assert_stmt -``` - -The preamble statement is used to define the module level statements, consist of `statement`, `import_stmt`, and `schema_stmt`. The statement is used to define the block level statements, which are used in the `if` statement and `schema` statement. - -### Small Statements - -A small statement is comprised of a single logical line. Multiple statements in one-line are not allowed. - -#### Assignment Statements - -Generally, assign_stmt is divided into assignment and augmented assignment. The syntax is the following: - -```bnf -assign_stmt: target_primary ("=" target_primary)* "=" test | target_primary augassign test -augassign: "+=" | "-=" | "*=" | "**=" | "/=" | "//=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>=" | "or" | "and" -target_primary: identifier | target_primary DOT identifier -``` - -An assignment statement has the form `lhs = rhs`. It evaluates the expression on the right-hand side then assigns its value (or values) to the variable (or variables) on the left-hand side. - -The **target_primary** on the left-hand side is an `identifier` or an `identifier` followed by select dots. - -Note: When using **target_primary** will cause collisions, use **primary_expr** as an alternative. - -Examples: - -```python -k = 1 -a.b = "a.b" -``` - -To keep it simple, the compound target is not supported as **target_primary**. - -The right value of an assignment statement is a conditional expression, which is discussed separately. - -An augmented assignment, which has the form `lhs op= rhs` updates the variable `lhs` by applying a binary arithmetic operator op (one of +, -, \*, /, //, %, &, |, ^, <<, >>) to the previous value of `lhs` and the value of `rhs`. - -The **target_primary** on the left-hand side is the same as assignment statement. Examples: - -```python -_x -= 1 -_filename += ".k" -``` - -There is no concept of in-place modification in KCL. The `augassign` statement will modify a copy of the **target_primary** and assign the copy to **target_primary**. - -In particular, in KCL, the `|=` symbol represents the **union** operation, which is defined as follows: - -- The behavior of the **union** operation needs to be consistent with the behavior of the **configuration definition**. - -See **expressions** spec for more details of union operator in **Arithmetic Operations**. - -#### Expression Statements - -An expression statement evaluates an expression and discards its result. - -Syntax: - -```bnf -expr_stmt: expression -``` - -An expression statement supported in KCL is function invocation expression, which is discussed in **expression** spec. - -```python -print(k) # print a variable -``` - -#### Import Statements - -Import statements are used to **search** and **load** a module, and define a name or names in the local namespace for the scope where the import statement occurs. - -Syntax: - -```bnf -import_stmt: "import" dot_name ("as" NAME)? -dot_name: [leading_dots] identifier (DOT identifier)* -leading_dots: "."+ -``` - -Examples: - -```python -import math # import a built-in module math -import pkg # import pkg -import pkg.foo # import pkg.foo -import pkg.subpkg # import a subpkg in a pkg -import .pkg2.subpkg3 # import a subpkg in a pkg inside of current pkg -import ...pkg2 # Go two levels up then import pkg2 -``` - -See **module** spec for more details of module spec. - -#### Assert Statements - -Assert statements are a convenient way to insert debugging assertions into KCL code. - -The syntax is the following: - -``` -assert_stmt: ASSERT test ("," test)? -``` - -The conditional expression in assert will be evaluated and get a boolean. Report an error if returning a `False`. - -Examples: - -```python -assert: x > 1 # report an error on x <= 1 -``` - -#### Conditional Statements - -KCL allows using conditional statements to control the instructions to -be executed. They are also called the control-flow statements. - -The only type of control-flow syntax is the well-known `if-elif-else` syntax. - -The syntax of the `if-elif-else` statement is the following. - -```bnf -if_stmt: "if" test ":" suite ("elif" test ":" suite)* (ELSE ":" suite)? -suite: small_stmt | NEWLINE _INDENT statement+ _DEDENT -``` - -An `if` or `elif` statement evaluates a given expression. When the expression -is evaluated to `True`, a list of statements following `:` are executed. - -The following is an example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - print("maybe a is negative") -else: - print("a >= 100") -``` - -`if-elif-else` statements can be nested. For example: - -```python -a = 10 -if a == 0: - print("a is zero") -elif a < 100: - print("a < 100") - if a < 0: - print("a is negative") - print("No matter a is negative or positive, this message is printed") -else: - print("a >= 100") -``` - -#### Schema Statements - -Schema statements are used to define a type of configuration data. The syntax is the following: - -```bnf -schema_stmt: [decorators] "schema" ["relaxed"] identifier ["[" [arguments] "]"] ["(" operand_name ")"] ":" NEWLINE [schema_body] -schema_body: _INDENT (string NEWLINE)* [mixin_stmt] (schema_attribute_stmt | statement)* [check_block] _DEDENT -``` - -See **schema** spec for more details of schema spec. diff --git a/versioned_docs/version-0.6.0/reference/lang/spec/variables.md b/versioned_docs/version-0.6.0/reference/lang/spec/variables.md deleted file mode 100644 index b3e1c539..00000000 --- a/versioned_docs/version-0.6.0/reference/lang/spec/variables.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: "Variables" -linkTitle: "Variable" -type: "docs" -weight: 2 -description: Variable ---- - -In KCL, variables can be defined using assign statements. For example, the following statement defines a variable `spam` to a string `"ham"`. - -```python -spam = "ham" -``` - -There are two types of variables, which are global variables and list comprehension local variables. - -- A global variable is defined not within any context. -- A comprehension local variable is defined inside a comprehension. - -A variable can be used after definition, until the end of the current scope. - -For a global variable, the scope is the module it is defined in. Note that a module can consists of multiple source files. - -For a list comprehension local variable, the scope is the list comprehension it is defined in. - -More information on modules, list comprehensions and scopes will be discussed in later chapters. - -## Immutability - -Global variables are immutable. In other words, once defined such a variable cannot be redefined (or, i.e., modified). - -The following code is illegal, and KCL will report an error during evaluation. - -```python -spam = "ham" -spam = "eggs" # Error: The immutability rule is violated! -``` - -- A variable starts with the `_` character is mutable. - -```python -_spam -cond = True -if cond: - _spam = "ham" -else: - _spam = "eggs" -``` - -## Variable Exporting - -As shown in the preview chapter, KCL is able to export evaluation results to the standard output according to a target data format. - -The rules are the followings: - -- Living global variables at the end of an evaluation will be dumped out. -- If the name of a variable starts with the `_` character, it will not be dumped out. - -## Uniqueness of Exported Variable Identifier - -Each exported variable identifier must be unique in its package, so that an exported variable could be located uniquely by package location path and variable identifier, such as 'a.b.c:var', in which 'a.b.c' locates a package. - -Two variable identifiers are different if: - -- they are spelled differently -- they are defined in different packages and are not compiled in a single execution - -Identifying an exported variable should be supported by the kcl compiler, which needs to provide corresponding identifying features through the command line and api form. diff --git a/versioned_docs/version-0.6.0/reference/lang/types/_category_.json b/versioned_docs/version-0.6.0/reference/lang/types/_category_.json deleted file mode 100644 index 8b257445..00000000 --- a/versioned_docs/version-0.6.0/reference/lang/types/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Types", - "position": 4 -} diff --git a/versioned_docs/version-0.6.0/reference/lang/types/types.md b/versioned_docs/version-0.6.0/reference/lang/types/types.md deleted file mode 100644 index ee88c64d..00000000 --- a/versioned_docs/version-0.6.0/reference/lang/types/types.md +++ /dev/null @@ -1,1381 +0,0 @@ -# Type System - -This document describes the type system of KCL, including: - -- Type rules -- Type checking -- Type conversion -- Type inference - -## Type Rules - -### Basic Definition - -#### Assertion - -All free variables of $S$ are defined in $\Gamma$ - -$$ -\Gamma \vdash S -$$ - -$\Gamma$ is a variable's well-formed environment, such as $x_1:T_1$, ..., $x_n:T_n$ - -The assertion of $S$ has three forms: - -**Environment assertion** indicates that $\Gamma$ is a well-formed type. - -$$ -\Gamma \vdash ◇ -$$ - -**Well-formed type assertion**. In the environment $\Gamma$, $nat$ is a type expression. - -$$ -\Gamma \vdash nat -$$ - -**Typing judgment assertion**. In the environment $\Gamma$,$E$ has the type $T$. - -$$ -\Gamma \vdash E: T -$$ - -#### Inference Rules - -Representation - -$$ -\frac{\Gamma \vdash S_1, ..., \Gamma \vdash S_n}{\Gamma \vdash S} -$$ - -In the inference rules, $u$, $v$, and $w$ are used to represent variables, $i$, $j$, $k$ are used to represent integers, $a$ and $b$ are used to represent floating point numbers, $s$ is used to represent strings, $c$ is used to represent literal values of constants (integers, floating point numbers, strings, boolean), $f$ is used to represent functions, $T$, $S$, $U$ are used to represent types. - -## Environment Rules - -Env ⌀ - -$$ -\frac{}{⌀ \vdash ◇ } -$$ - -## Type Definitions - -Type Bool - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash boolean} -$$ - -Type Int - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash integer} -$$ - -Type Float - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash float} -$$ - -Type String - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash string} -$$ - -Type Literal - -$$ -\frac{ c \in \{boolean, integer, float, string\}}{\Gamma \vdash literalof(c)} -$$ - -Type List - -$$ -\frac{\Gamma \vdash T \ T \neq Void}{\Gamma \vdash listof(T) } -$$ - -Type Dict - -$$ -\frac{\Gamma \vdash T_1 \ \Gamma \vdash T_2\ T_1 \neq Void \ \ T_2 \neq Void}{\Gamma \vdash dictof(T_k=T_1, T_v=T_2)} -$$ - -Type Struct - -$$ -\frac{\Gamma \vdash T_{1} \ ... \ \Gamma \vdash T_{n} \ \ T_i \neq Void \ K_1 \neq K_n}{\Gamma \vdash structof(K_1 : T_{1}, ... , K_n : T_{n})} -$$ - -Type Union - -$$ -\frac{\Gamma \vdash T_1 \ ... \ \Gamma \vdash T_n \ \ T_i \neq Void}{\Gamma \vdash unionof(T_1, ..., T_n)} -$$ - -Type None - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash None} -$$ - -Type Undefined - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Undefined} -$$ - -Type Void - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Void} -$$ - -Type Any - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Any} -$$ - -Type Nothing - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Nothing} -$$ - -## Typing Judgment Rules - -### Operand Expr - -Exp Truth - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash true: boolean} -$$ - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash false: boolean} -$$ - -Exp Int - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash int: integer} -$$ - -Exp Flt - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash flt: float} -$$ - -Exp Str - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash str: string} -$$ - -Exp None - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash none: none} -$$ - -Exp Undefined - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash undefined: undefined} -$$ - -Expr ListExp - -$$ -\frac{\Gamma \vdash E_1: T_1 \ E_2: T_2 \ ... \ E_n: T_n}{\Gamma \vdash [E_1, E_2, ..., E_n]: listof \ sup(T_1, T_2, ..., T_n)} -$$ - -Expr ListComp - -$$ -\frac{\Gamma \vdash E_1: T_1 \ \Gamma \vdash v: T \ \Gamma \vdash E_2: listof \ T \ \Gamma \vdash E_3: boolean}{\Gamma \vdash [E_1 \ for \ v \ in \ E_2 \ if \ E_3]: listof(T_1) } -$$ - -Expr DictExp - -$$ -\frac{\Gamma \vdash E_{k1}: T_{k1} \ \Gamma \vdash E_{v1}: T_{v1} \ ... \ \Gamma \vdash E_{kn}: T_{kN} \ \Gamma \vdash E_{vn}: T_{vN}}{\Gamma \vdash \{E_{k1}: E_{v1}, ..., E_{{kn}}: E_{vn}\}: dictof(T_{k}=sup(T_{k1}, T_{k2}, ... T_{kn}), \ T_{v}=sup(T_{v1}, T_{v2}, ..., T_{vn}))} -$$ - -Expr DictComp - -$$ -\frac{\Gamma \vdash E_1: T_{rki} \ \Gamma \vdash E_2: T_{rvi} \ \Gamma \vdash v_1: T_k \ \Gamma \vdash v_2: T_v \ \Gamma \vdash E_3: dictof(T_{k}, \ T_{v}) \ \Gamma \vdash E_4: boolean}{\Gamma \vdash \{E_1:E_2 \ for \ (v_1, v_2) \ in \ E_3 \ if \ E_4\}: dictof(T_{k}=sup(T_{rk1}, T_{rk2}, ..., T_{rkn}), T_{v}=sup(T_{rv1}, T_{rv2}, ..., T_{rvn})) } -$$ - -Expr StructExpr - -$$ -\frac{\Gamma \vdash E_{1}: T_{1} \ ... \ \Gamma \vdash E_{n}: T_{n} \ K_1 \neq K_n}{\Gamma \vdash \{K_{1} = E_{1}, ..., K_{{n}} = E_{n}\}: structof(K_1 : T_{1}, ... , K_n : T_{n})} -$$ - -The literal type is the value type of basic type, the union type is the combination type of types, void, any, nothing are special type references, and there is no direct value expression correspondence. - -### Primary Expr - -Expr Index - -$$ -\frac{\Gamma \vdash E: listof(T) \ \Gamma \vdash Index: integer}{\Gamma \vdash E[Index]: T} -$$ - -Expr Call - -$$ -\frac{\Gamma \vdash E_1: T_1 \rightarrow T_2 \ \Gamma \vdash E_2: T_1}{\Gamma \vdash E_1 \ (E_2): T_2} -$$ - -Expr List Selector - -$$ -\frac{\Gamma \vdash E: listof(T) \ \Gamma \vdash Index: integer}{\Gamma \vdash E.[Index]: T} -$$ - -Expr Dict Selector - -$$ -\frac{\Gamma \vdash E: dictof(T_k = T_1, T_v=T_2) \ \Gamma \vdash S_1: string \ ... \ \Gamma \vdash S_n: string}{\Gamma \vdash E.\{S_1, ..., S_n\}: dictof(T_k = T_1, T_v=T_2)} -$$ - -Expr Struct Selector - -$$ -\frac{\Gamma \vdash E: structof(K_1 : T_{1}, ... , K_n : T_{n}) \ \Gamma \vdash K_i: string}{\Gamma \vdash E.K_i: T_{i}} -$$ - -### Unary Expr - -Expr + - -$$ -\frac{\Gamma \vdash E: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash \ +E: T} -$$ - -Expr - - -$$ -\frac{\Gamma \vdash E: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash \ -E: T} -$$ - -Expr ~ - -$$ -\frac{\Gamma \vdash E: integer}{\Gamma \vdash \ ~E: integer} -$$ - -Expr not - -$$ -\frac{\Gamma \vdash E: boolean}{\Gamma \vdash \ not \ E: boolean} -$$ - -### Binary Expr - -Expr op, op $\in$ {-, /, %, \*\*, //} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash E_1 \ op \ E_2: T} -$$ - -Expr + - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, float, string, listof(T_1)\}}{\Gamma \vdash E_1 \ + \ E_2: T} -$$ - -Expr \* - -$$ -\frac{\Gamma \vdash E_1: T_1 \ \ \ \Gamma \vdash E_2: T_2 \ \ \ \ (T_1==T_2 \in \{integer, float\}) \ or \ (T_1 == interger \ and \ T_2 \ \in \ \{string, listof(T_3)\}) \ or \ (T_2 == interger \ and \ T_1 \ \in \ \{string, listof(T_3)\})} {\Gamma \vdash E_1 \ * \ E_2: T} -$$ - -Expr % - -$$ -\frac{\Gamma \vdash E_1: interger \ \ \ \Gamma \vdash E_2: integer}{\Gamma \vdash E_1 \ \% \ E_2: interger} -$$ - -Expr op, op $\in$ \{or, and\} - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ op \ E_2: boolean} -$$ - -示例 - -Expr and - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ and \ E_2: boolean} -$$ - -Expr op, op $\in$ \{==, !=, <, >, <=, >=\} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T}{\Gamma \vdash E_1 \ op \ E_2: boolean} -$$ - -Expr > - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ > \ E_2: boolean} -$$ - -Expr op, op $\in$ {&, ^, ~, <<, >>} - -$$ -\frac{\Gamma \vdash E_1: integer \ \ \ \Gamma \vdash E_2: integer}{\Gamma \vdash E_1 \ op \ E_2: integer} -$$ - -Expr | - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, listof(T_1), dictof(T_k, T_v), structof(K_1=T_1, ..., K_n=T_n)\}}{\Gamma \vdash E_1 \ | \ E_2: T} -$$ - -Expr op, op $\in$ {in, not in} - -$$ -\frac{\Gamma \vdash E_1: string \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{dictof, structof\}}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: listof(S), T \sqsubseteq S}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -Expr op $\in$ {is, is not} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -### IF Expr - -Expr If - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: T \ \ \ \Gamma \vdash E_3: T}{\Gamma \vdash if \ E_1 \ then \ E_2 \ else \ E_3: T} -$$ - -### Stmt - -Stmt If - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash S_1: Void \ \ \ \Gamma \vdash S_2: Void}{\Gamma \vdash if \ E_1 \ then \ S_1 \ else \ S_2: Void} -$$ - -Stmt Assign - -$$ -\frac{\Gamma \vdash id: T_0 \ \ \ \Gamma \vdash T_1 \ \ \ \Gamma \vdash E: T_2}{\Gamma \vdash id: T_1 \ = \ E : Void} -$$ - -Type Alias - -$$ -\frac{\Gamma \vdash id: T_0 \ \ \ \Gamma \vdash T_1}{\Gamma \vdash type \ id \ = \ T_1 : Void} -$$ - -## Union - -List Union - -$$ -\frac{\Gamma \vdash \ listof(T) \ \ \ \Gamma \vdash \ listof(S)}{\Gamma \vdash \ listof(unionof(T, S))} -$$ - -Dict Union - -$$ -\frac{\Gamma \vdash \ dictof(T_1, T_2) \ \ \ \Gamma \vdash \ dictof(S_1, S_2)}{\Gamma \vdash \ dictof(unionof(T_1, S_1), unionof(T_2, S_2))} -$$ - -Struct Union - -Define two structures: $structof(K_{1}: T_{1}, ..., K_{n}: T_{n}),structof(H_{1}: S_{1}, ..., H_{m}: S_{n})$ - -Define their union types: - -$$ -structof(J_{1}: U_{1}, ..., J_{p}: U_{n}) = structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \bigcup structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) -$$ - -Example - -$$ -structof() \ \bigcup \ structof(H_{1}: T_{1}, ..., H_{m}: T_{n}) = structof(H_{1}: T_{1}, ..., H_{m}: T_{n}) -$$ - -$$ -structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \ \bigcup \ structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) = structof(K_1: T_1) :: (structof(K_{2}: T_{2}, ..., K_{n}: T_{n}) \ \bigcup \ structof(H_{1}: S_{1}, ..., H_{m}: S_{n})) -$$ - -where "::" denotes the operation of adding a dual to a structure, which is defined as follows: - -$$ -structof(K_{1}: T_{1}) :: structof() = structof(K_{1}: T_{1}) -$$ - -$$ -structof(K_{1}: T_{1}) :: structof(K_{1}: T_{1}', ..., K_n: T_{n}) = structof(K_{1}: union\_op(T_{1}, T_{1}'), ..., K_{n}: T_{n}) -$$ - -$$ -structof(K_{1}: T_{1}) :: structof(K_{2}: T_{2}, ..., K_n: T_{n}) = structof(K_{2}: T_2) :: structof(K_{1}: T_1) :: structof(K_{3}: T_3, ..., K_{n}: T_{n}) -$$ - -Based on this, the union of two structures is defined as: - -$$ -\frac{\Gamma \vdash structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \ \Gamma \vdash structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) \ structof(J_{1}: U_{1}, ..., J_{p}: U_{n}) = structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \bigcup structof(H_{1}: S_{1}, ..., H_{m}: S_{n})}{\Gamma \vdash structof(J_{1}: U_{1}, ..., J_{p}: U_{n}))} -$$ - -where $union\_op(T_1, T_2)$ denotes different types of judgment operations for the same $K_i$. - -- When $T_1$ and $T_2$ have the partial order relation. If $T_1 \sqsubseteq T_2$, return $T_2$, otherwise return $T_1$, which is the minimum upper bound -- When $T_1$ and $T_2$ have no partial order relationship, there are three optional processing logic: - - Structure union failed, return a type error. - - Return the type of the latter $T_2$. - - Return the type $unionof (T_1, T_2)$. - -Here, we need to choose the appropriate processing method according to the actual needs. - -Structure inheritance can be regarded as a special union. The overall logic is similar to that of union, but in $union\_op(T_1, T_2)$ for the same $K_i$, the different types of judgment operations are as follows: - -- When $T_1$ and $T_2$ have the partial order relation and $T_1 \sqsubseteq T_2$, return $T_1$, that is, only if $T_1$ is the lower bound of $T_2$, the lower bound of $T_1$ shall prevail. -- Otherwise, a type error is returned. - -Through such inheritance design, we can achieve hierarchical, bottom-up and layer-by-layer contraction of type definition. - -## Operation - -KCL supports operations on structure attributes in the form of $p op E$. That is, for the given structure $A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})$, the path $p$ in the structure is specified with the value of $E$ (such as union, assign, insert, etc.). - -Define the following update operations: - -$$ -\frac{{\Gamma\vdash A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})}  {\Gamma\vdash p \in (K_{1}, ..., K_{n})} \ {\Gamma\vdash e:T}   k \neq k_1, ..., k \neq k_n} -{ A \{p \ op \ e\}:\{K_1:T_1, ..., K_n:T_n\}∪\{p:T\}} -$$ - -That is to say, the operation on the path $p$ is essentially a union of two structures. The rules for the same name attribute type union depend on the situation. For example, the path $p$ is an identifier $p=k_1$ that can be used as a field name $k_1$, and the field name in structure A is also $k_1$, its type is $T_1$, and the type of the expression $e$ is also $T_1$, then - -$$ -\frac{{\Gamma\vdash A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})}  {\Gamma\vdash p = K_{1}} \ {\Gamma\vdash e:T_1}   k \neq k_1, ..., k \neq k_n} -{ A \{p \ op \ e\}:\{K_1:T_1, ..., K_n:T_n\}} -$$ - -Note: - -- The type $T_1$ of the expression $e$ have the same type with the original attribute of the same name $K_1$. It can be relaxed appropriately according to the actual situation, such as the type of $e$ $\sqsubseteq T_1$ is enough. -- For the operation of nested multi-layer structures, the above rules can be used recursively. - -## Type Partial Order - -### Basic Types - -$$ -Type \ T \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ T -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Bool \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Int \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Float \sqsubseteq Type \ Any -$$ - -$$ -Type \ Int \sqsubseteq Type \ Float -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ String \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Literal \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ List \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Dict \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Struct \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ None \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Void \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Any -$$ - -### Literal Type - -$$ -Type \ Literal(Bool) \sqsubseteq Type \ Bool -$$ - -$$ -Type \ Literal(Int) \sqsubseteq Type \ Int -$$ - -$$ -Type \ Literal(Float) \sqsubseteq Type \ Float -$$ - -$$ -Type \ Literal(String) \sqsubseteq Type \ String -$$ - -### Union Type - -$$ -Type \ X \sqsubseteq Type \ Union(X, Y) -$$ - -### Introspect - -$$ -Type \ X \sqsubseteq Type \ X -$$ - -Example - -$$ -Type \ Bool \sqsubseteq Type \ Bool -$$ - -$$ -Type \ Int \sqsubseteq Type \ Int -$$ - -$$ -Type \ Float \sqsubseteq Type \ Float -$$ - -$$ -Type \ String \sqsubseteq Type \ String -$$ - -$$ -Type \ List \sqsubseteq Type \ List -$$ - -$$ -Type \ Dict \sqsubseteq Type \ Dict -$$ - -$$ -Type \ Struct \sqsubseteq Type \ Struct -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Nothing -$$ - -$$ -Type \ Any \sqsubseteq Type \ Any -$$ - -$$ -Type \ Union(Type Int, Type Bool) \sqsubseteq Type \ Union(Type Int, Type Bool) -$$ - -### Transmit - -$$ -Type \ X \sqsubseteq Type \ Z \ if \ Type \ X \sqsubseteq Type \ Y \ and \ Type \ Y \sqsubseteq \ Type \ Z -$$ - -### Contained - -$$ -Type \ List(T_1) \sqsubseteq Type \ List(T_2) \ if \ T_1 \sqsubseteq T_2 -$$ - -$$ -Type \ Dict(T_{k1}, T_{v1}) \sqsubseteq Type \ Dict(T_{k2}, T_{v2}) \ if \ T_{k1} \sqsubseteq T_{k2} \ and \ T_{v1} \sqsubseteq T_{v1} -$$ - -$$ -Type \ Structure(K_1: T_{a1}, K_2: T_{a2}, ..., K_n: T_{an}) \sqsubseteq Type \ Structure(K_1: T_{b1}, K_2: T_{b2}, ..., K_n: T_{bn}) \ if \ T_{a1} \sqsubseteq T_{b1} \ and \ T_{a2} \sqsubseteq T_{b2} \ and \ ... \ and \ T_{an} \sqsubseteq T_{bn} -$$ - -### Inheritance - -$$ -Type \ Struct \ A \sqsubseteq Type \ Struct \ B \ if \ A \ inherits \ B -$$ - -### None - -$$ -Type \ None \sqsubseteq Type \ X, X \notin \{Type \ Nothing, \ Type \ Void\} -$$ - -### Undefined - -$$ -Type \ Undefined \sqsubseteq Type \ X, X \notin \{Type \ Nothing, \ Type \ Void\} -$$ - -## Equality - -- Commutative law - -$$ -Type \ Union(X, Y) == Type \ Union(Y, X) -$$ - -Example - -$$ -Type \ Union(Int, Bool) == Type \ Union(Bool, Int) -$$ - -- Associative law - -$$ -Type \ Union(Union(X, Y), Z) == Type \ Union(X, Union(Y, Z)) -$$ - -Example - -$$ -Type \ Union(Union(Int, String), Bool) == Type \ Union(Int, Union(String, Bool)) -$$ - -- Idempotent - -$$ -Type \ Union(X, X) == Type \ X -$$ - -Example - -$$ -Type \ Union(Int, Int) == Type \ Int -$$ - -Partial order derivation - -$$ -Type \ Union(X, Y) == Type \ Y \ if \ X \sqsubseteq Y -$$ - -Example - -Assume that Struct A inherits Struct B - -$$ -Type \ Union(A, B) == Type \ B -$$ - -Idempotency is a special case of partial order reflexivity - -### List - -$$ -Type \ List(X) == Type \ List(Y) \ if \ X == Y -$$ - -### Dict - -$$ -Type \ Dict(T_k, T_v) == Type \ Dict(S_k, S_v) \ if \ T_k == S_k \ and \ T_v == S_v -$$ - -### Struct - -$$ -Type \ Struct(K_1: T_{1}, K_2: T_{2}, ..., K_n: T_{n}) == Type \ Struct(K_1: S_{1}, K_2: S_{2}, ..., K_n: S_{n}) \ if \ T_{1} == S_{1} \ and \ ... \ and \ T_{n} == S_{n} -$$ - -### Partial Order Checking - -$$ -Type \ X == Type \ Y \ if \ Type \ X \sqsubseteq Type \ Y \ and \ Type \ Y \sqsubseteq \ Type \ X -$$ - -## Basic Methods - -- `sup(t1: T, t2: T) -> T`: Calculate the minimum upper bound of two types `t1` and `t2` according to the type partial order. The union type needs to be created dynamically. -- `typeEqual(t1: T, t2: T) -> bool`: Compare whether the two types `t1` and `t2` are equal. -- `typeToString(t: T) -> string`: Resolve and convert the type to the corresponding string type recursively from top to bottom. - -### Sup Function - -- Type parameters, condition types and other characteristics are not considered temporarily. -- Use an ordered collection to store all types of `UnionType`. -- Use a global map to store all generated union types according to the name of `UnionType`. -- Calculate the inclusion relationship between types according to the partial order relationship. - -```go -// The Sup function returns the minimum supremum of all types in an array of types -func Sup(types: T[]) -> T { - typeOf(types, removeSubTypes=true) -} - -// Build a sup type from types [T1, T2, ... , Tn] -func typeOf(types: T[], removeSubTypes: bool = false) -> T { - assert isNotNullOrEmpty(types) - // 1. Initialize an ordered set to store the type array - typeSet: Set[T] = {} - // 2. Add the type array to the ordered set for sorting by the type id and de-duplication - addTypesToTypeSet(typeSet, types) - // 3. Remove sub types according to partial order relation rules e.g. sub schema types - if removeSubTypes { - removeSubTypes(typeSet) - } - if len(typeSet) == 1 { - // If the typeSet has only one type, return it - return typeSet[0] - } - // 4. Get or set the union type from the global union type map - id := getIdentifierFromTypeSet(typeSet) - unionType := globalUnionTypeMap.get(id) - if !unionType { - unionType = createUnionType(typeSet) // Build a new union type - globalUnionTypeMap.set(id, unionType) - } - return unionType -} - -// Add many types into the type set -func addTypesToTypeSet(typeSet: Set[T], types: T[]) -> void { - for type in types { - addTypeToTypeSet(typeSet, type) - } -} - -// Add one type into the type set -func addTypeToTypeSet(typeSet: Set[T], type: T) -> void { - if isUnion(type) { - return addTypesToTypeSet(typeSet, toUnionOf(type).types) - } - // Ignore the void type check - if !isVoid(type) { - // De-duplication according to the type of id - typeSet.add(type) - } -} - -func removeSubTypes(types: Set[T]) -> void { - for source in types { - for target in types { - if !typeEqual(source, target) { - // If the two types have an inheritance relationship, the base class is retained, or if the two types have a partial order relationship according to the relation table. - if (isPartialOrderRelatedTo(source, target)) { - types.remove(source) - } - } - } - } -} - -// isPartialOrderRelatedTo function Determine whether two types have a partial order relationship `source \sqsubseteq target` -// according to the partial order relationship table and rules -func isPartialOrderRelatedTo(source: T, target: T) -> bool { - assert isNotNullOrEmpty(source) - assert isNotNullOrEmpty(target) - if isNoneOrUndefined(source) and !isNothing(target) and !isVoid(target) { - return true - } - if isAny(target) { - return true - } - if typeEqual(source, target) { - return true - } - if isUnion(target) and source in target.types { - return true - } - // Literal Type - if (isStringLiteral(source) and isString(target)) or \ - (isBooleanLiteral(source) and isBool(target)) or \ - (isIntLiteral(source) and isInt(target)) or \ - (isFloatLiteral(source) and isFloat(target)) { - return true - } - if isInt(source) and isFloat(target) { - return true - } - if isList(source) and isList(target) { - return isPartialOrderRelatedTo(toListOf(source).eleType, toListOf(target).eleType - } - if isDict(source) and isDict(target) { - return isPartialOrderRelatedTo(toDictOf(source).keyType, toDictOf(target).keyType) and isPartialOrderRelatedTo(toDictOf(source).valueType, toDictOf(target).valueType) - } - if isStruct(source) and isStruct(target) { - if isTypeDerivedFrom(source, target) { - return true - } - // Empty Object - if len(target.keys) == 0 { - return true - } - if any([key Not in source.keys for key in target.keys]) { - return false - } - for key, sourceType in (source.keys, source.types) { - targetType = getKeyType(target, key) ? getKeyType(target, key) : anyTypeOf() - if !isPartialOrderRelatedTo(sourceType, targetType) { - return false - } - } - return true - } - return false -} -``` - -## Type Checking - -### Checker - -The type checker traverses the syntax tree from top to bottom through syntax-directed translation, and determines whether the program structure is a well-typed program according to context-sensitive training rules. - -The type checker depends on type rules, and the information of type environment $\Gamma$ is recorded in the symbol table. Use abstract syntax for type expressions, such as `listof (T)`. When the type check fails, a type mismatch error is generated, and the error message is generated according to the syntax context. - -### Basic Methods - -1. `isUpperBound(t1, t2): supUnify(t1, t2) == t2` -2. `supUnify(t1, t2):` - -- For the foundation type, `sup(t1, t2)` is calculated according to the partial order relationship -- For list, dict, Struct, recursively `supUnify` the types of elements -- When there is no partial order relationship, return `Nothing` - -### Checking Logic - -#### Operand Expr - -$D \to id: T$ - -``` -env.addtype(id.entry, T.type) -``` - -$T \to boolean$ - -``` -T.type = boolean -``` - -$T \to integer$ - -``` -T.type = integer -``` - -$T \to float$ - -``` -T.type = float -``` - -$T \to string$ - -``` -T.type = string -``` - -$T \to c, \ c \in \{boolean, integer, float, string\}$ - -``` -T.type = literalof(c) -``` - -$T \to None$ - -``` -T.type = None -``` - -$T \to Undefined$ - -``` -T.type = Undefined -``` - -$T \to \ [T_1]$ - -``` -T.type = listof (T1.type) -``` - -$T \to { \{T_1: T_2\} }$ - -``` -T.type = dictof (T1.type: T2.type) -``` - -$T \to { \{N_1: T_1, N2: T_2, ..., N_n: T_n\} }$ - -``` -T.type = structof (N1: T1.type, N2: T2.type, ..., Nn: Tn.type) -``` - -$E \to id$ - -``` -E.type = env.lookup(id.entry) -``` - -$E \to [E_1, E_2, ..., E_n]$ - -``` -func listExpr(E) { - supe = sup([e.type for e in E]]) - E.type = listof(type) -} -``` - -$E \to [E_1 \ for \ E_2 \ in \ E_3 \ if \ E_4]$ - -``` -func listComp(E) { - if !typeEqual(E4.type, boolean) { - raise type_error - } - if !isUpperBound(listof(Any), E3.type) { - raise type_error(E) - } - if !isUpperBound(E3.type, E2.type) { - raise type_error(E) - } - E.type = listof(E1.type) -} -``` - -$E \to \{E_{k1}: E_{v1}, ..., E_{kn}: E_{vn}\}$ - -``` -func dictExpr(E) { - supk := sup([e.type for e in E.keys()]]) - supv := sup([e.type for e in E.values()]]) - E.type = dictof(supk, supv) -} -``` - -$E \to \{E_1:E_2 \ for \ (E_3, E_4) \ in \ E_5 \ if \ E_6\}$ - -``` -func dictComp(E) { - if !typeEqual(E6.type, boolean) { - raise type_error(E) - } - if !isUpperBound(dictof(Any, Any), E5.type) { - raise type_error(E) - } - if !isUpperBound(E5.type, dictof(E3.type, E4.type)) { - raise type_error(E) - } - E.type = dictof(E1.type, E2.type) -} -``` - -$E \to \{E_{k1}: E_{v1}, ..., E_{kn}: E_{vn}\}$ - -``` -func dictExpr(E) { - supk := sup(Ek1, ..., Ekn) - supv = sup(Ev1, ..., Evn) - E.type = dictof(supk, supv) -} -``` - -$E \to \{N_{1} = E_{1}, ..., N_{{n}} = E_{n}\}$ - -``` -func structExpr(E) { - Struct = structof() - for n, e in E { - Struct.add(n, e.type) - } - E.type = Struct -} -``` - -#### Primary Expr - -$E \to E_1[E_2]$ - -``` -func sliceSuffix(E) { - if !isUpperBound(listof(Any), E.E1.type) { - raise type_error(E) - } - if typeEqual(E.E2.type, integer) { - raise type_error(E) - } - E.type = E.E1.type.eleType -} -``` - -$E \to E_1(E_2)$ - -``` -func callSuffix(E) { - if !typeEqual(E.E1.type, func) { - raise type_error(E) - } - if !isUpperBound(listof(E.E1.arguType), E.E2.type) { - raise type_error(E) - } - E.type = E.E1.returnType -} -``` - -#### Unary Expr - -According to the reasoning rules of each binocular operator, take `+` as an example. - -$E \to + E_1$ - -``` -func Plus(E) { - if !typeEqual(E.E1.type, [integer, float]) { - raise type_error(E) - } - E.type = E.E1.type -} -``` - -#### Binary Expr - -According to the reasoning rules of each binocular operator, take `%` as an example. - -$E \to E_1 \ % \ E_2$ - -``` -func Mod(E) { - if !(typeEqual(E.E1.type, [integer, float]) && typeEqual(E.E2.type, [integer, float])) { - raise type_error(E) - } - E.type = E.E1.type -} -``` - -#### IF Binary Expr - -$E \to if E_1 \ then \ E_2 else \ E_3$ - -``` -func ifExpr(E) { - if !typeEqual(E.type, boolean) { - raise type_error(E) - } - if !typeEqual(E_2.type, E_3.type) { - raise type_error(E) - } - E.type = E_2.type -} -``` - -#### Stmt - -$S \to if \ E \ then \ S_1 \ else \ S_2$ - -``` -func ifStmt(S) { - if !typeEqual(S.E.type, boolean) { - raise type_error(E) - } - if !typeEqual(S.S1.type, S.S2.type) { - raise type_error(E) - } - S.type = S.S1.type -} -``` - -$S \to id: T = E$ - -$S \to id = T E$ - -``` -func assignStmt(S) { - tpe := env.lookup(id.entry) - if tpe != nil && tpe != S.T { - raise type_error(E) - } - if isUpperBound(tpe, E.type) { - raise type_error(E) - } - env.addtype(id.entry, T.type) -} -``` - -## Type Conversion - -### Basic Definition - -Through syntax-directed translation, the value types involved in the operation are automatically converted according to the operator characteristics. - -### Conversion Rules - -$E \to E_1 \ op \ E_2, , op \in \{+, -, *, /, \%, **, //\}$ - -``` -func binOp(E) { - if E.E1.type == integer and E.E2.type == integer { - E.type = integer - } else if E.E1.type == integer and E.E2.type == float { - E.type = float - } else if E.E1.type == float and E.E2.type == integer { - E.type = float - } else if E.E1.type == float and E.E2.type == float { - E.type = float - } -} -``` - -## Type Inference - -### Basic Definition - -- Type rule derivation and type reconstruction in case of incomplete type information -- Derive and reconstruct the data structure types in the program from the bottom up, such as basic type, e.g., list, dict and struct types. - -### Basic Methods - -1. `typeOf(expr, subst)`: The input is the expression and substitution rule set, and the type of expr and the new substitution rule set are returned. -2. `unifier(t1, t2, subst, expr)`: Try substitution with `t1=t2`. If the substitution is successful (no occurrence and no conflict), add `t1=t2` to the subst and return the subst. Otherwise, an error has occurred or there is a conflict. - -### Inferential Logic - -$E \to id = E_1$ - -``` -func assignExpr(E, subst) { - return unifier(E.id.type, E.E_1.type, subst, E) -} -``` - -$unifier(t1, t2, subst, expr) \rightarrow subst$ - -``` -func unifier(t1, t2, subst, expr) { - t1 = applySubstToTypeEquation(t1, subst) - t2 = applySubstToTypeEquation(t2, subst) - - if t1 == t2 { - return subst - } - - if isTypeVar(t1) { - if isNoOccur(t1, t2) { - addTypeEquationToSubst(subst, t1, t2) - return subst - } else { - raise occurrence_violation_error(t1, t2, expr) - } - } - - if isTypeVar(t2) { - if isNoOccur(t2, t1) { - addTypeEquationToSubst(subst, t2, t1) - return subst - } else { - raise occurrence_violation_error(t2, t1, expr) - } - } - - if isList(t1) and isList(t2) { - return unifier(toListOf(t1).eleType, toListOf(t2).eleType, subst, expr) - } - if isDict(t1) and isDict(t2) { - dict1of := toDictOf(t1) - dict2of := toDictOf(t2) - subst = unifier(dict1of.keyType, dict2of.keyType, subst, expr) - subst = unifier(dict1of.valueType, dict2of.valueType, subst, expr) - return subst - } - if isStruct(t1) and isStruct(t2) { - Struct1of := tostructof(t1) - Struct2of := tostructof(t2) - for key, _ in Struct1of { - subst = unifier(t1[key].type, t2[key].type, subst, expr) - } - return subst - } - - raise unification_error(t1, t2, expr) -} - -func applySubstToTypeEquation(t, subst) { - // walks through the type t, replacing each type variable by its binding in the substitution -σ. If a variable is Not bound in the substitution, then it is left unchanged. - if isBasicType(t) { - return t - } - if isList(t) { - return listOf(applySubstToTypeEquation(toListOf(t).eleType, subst)) - } - if isDict(t) { - dictof := toDictOf(t) - kT := applySubstToTypeEquation(dictof.keyType, subst) - vT := applySubstToTypeEquation(dictof.valueType, subst) - return dictOf(kT, vT) - } - if isStruct(t) { - structof := tostructof(t) - s := structof() - for key, type in Struct1of { - kT := applySubstToTypeEquation(type, subst) - s.add(key, kT) - } - return s - } - if hasTypeVar(t) { - for tvar in t.vars { - if tvar in subst { - *tvar = subst[tvar] - } - } - } - return t -} - -func addTypeEquationToSubst(subst, tvar, t) { - // takes the substitution σ and adds the equation tv = t to it - for _, t in subst { - for tvar in t.vars { - tmp := applyOneSubst(tsvar, tvar, t) - *tvar = tmp - } - } - subst.add(tvar, t) -} - -func applyOneSubst(t0, tvar, t1) { - // substituting t1 for every occurrence of tv in t0. - if isBasicType(t0) { - return t0 - } - if isList(t0) { - return listOf(applyOneSubst(toListOf(t).eleType, tvar, t1)) - } - if isDict(t0) { - dictof := toDictOf(t) - kT := applyOneSubst(dictof.keyType, tvar, t1) - vT := applyOneSubst(dictof.valueType, tvar, t1) - return dictOf(kT, vT) - } - if isStruct(t0) { - structof := tostructof(t) - s := structof() - for key, type in Struct1of { - kT := applyOneSubst(type, tvar, t1) - s.add(key, kT) - } - return s - } - if t0 == tvar { - return t1 - } - return t0 -} - -func isNoOccur(tvar, t) { - // No variable bound in the substitution occurs in any of the right-hand sides of the substitution. - if isBasicType(t) { - return true - } - if isList(t) { - return isNoOccur(tvar, toListOf(t).eleType) - } - if isDict(t) { - dictof := toDictOf(t) - return isNoOccur(tvar, dictof.keyType) and isNoOccur(tvar, dictof.valueType) - } - if isStruct(t) { - structof := tostructof(t) - noOccur := true - for _, type in structof { - noOccur = noOccur and isNoOccur(tvar, type) - } - return noOccur - } - return tvar != t -} -``` - -### Example - -#### Normal Inference - -``` -T : { - a = 1 - b = "2" - c = a * 2 - d = { - d0 = [a, c] - } -} - -x: T = { - a = 10 -} -``` - -#### Occurrence Violation Error - -``` -T = { - a = a -} -``` - -#### Type Unification Error - -``` -T : { - a = 1 -} - -T : { - a = "1" -} -``` - -## Reference - -- [https://en.wikipedia.org/wiki/Type_system](https://en.wikipedia.org/wiki/Type_system) -- Pierce, Benjamin C. (2002). Types and Programming Languages. MIT Press. -- [https://www.cs.cornell.edu/courses/cs4110/2010fa/](https://www.cs.cornell.edu/courses/cs4110/2010fa/) -- [https://www.typescriptlang.org/docs/handbook/basic-types.html](https://www.typescriptlang.org/docs/handbook/basic-types.html) -- [https://www.typescriptlang.org/docs/handbook/advanced-types.html](https://www.typescriptlang.org/docs/handbook/advanced-types.html) diff --git a/versioned_docs/version-0.6.0/reference/model/_category_.json b/versioned_docs/version-0.6.0/reference/model/_category_.json deleted file mode 100644 index 398617be..00000000 --- a/versioned_docs/version-0.6.0/reference/model/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "System Package", - "position": 2 -} diff --git a/versioned_docs/version-0.6.0/reference/model/base64.md b/versioned_docs/version-0.6.0/reference/model/base64.md deleted file mode 100644 index 3f6e617b..00000000 --- a/versioned_docs/version-0.6.0/reference/model/base64.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: "base64" -linkTitle: "base64" -type: "docs" -description: base64 system module - base64 encode and decode function -weight: 100 ---- - -## encode - -`encode(value: str, encoding: str = "utf-8") -> str` - -Encode the string `value` using the codec registered for encoding. - -## decode - -`decode(value: str, encoding: str = "utf-8") -> str` - -Decode the string `value` using the codec registered for encoding. diff --git a/versioned_docs/version-0.6.0/reference/model/builtin.md b/versioned_docs/version-0.6.0/reference/model/builtin.md deleted file mode 100644 index 4bb34766..00000000 --- a/versioned_docs/version-0.6.0/reference/model/builtin.md +++ /dev/null @@ -1,386 +0,0 @@ ---- -title: "builtin" -sidebar_position: 1 ---- - -KCL provides a list of built-in functions that are automatically loaded and can be used directly without providing any module name. For example, `print` is a function provided by a widely used built-in module. - -## Type Conversion Functions - -KCL's `bool`, `int`, `float`, `str`, `list`, `dict` and other types have built-in conversion functions of the same name. Among them, `int` can not only be used to truncate floating-point numbers, but also can be used to convert strings to integers (decimal when parsing, other values can also be specified). - -The following are common uses of type-related functions: - -```py -b1 = bool(1) # true -b2 = bool(1.5) # true -b3 = bool("true") # true -b4 = bool("") # false -b5 = bool([]) # false -b6 = bool({}) # false - -i1 = int("11") # 11 -i2 = int("11", base=8) # 9 -i3 = int("11", base=2) # 3 - -f1 = float(1) # 1.0 -f2 = float("1.5") # 1.5 - -s1 = str(1) # 1 - -l1 = list([1, 2, 3]) -``` - -## String Builtin Member Functions - -- [String Spec](/docs/reference/lang/spec/datatypes) - -## print - -`print(*args:any, end:str='\n')` - -The built-in print function, which provides different types of variable parameter printing, adds a newline at the end by default. The following are common usages: - -```python -print("hello KCL") -print() -print(None, end=':') -print(None) -print(True) -print(False) -print(123) -print(123.0) -print('abc ${123}') -print("abc ${456}") -print([1,'a', True]) -print(1,'a', True) -print({}) -print({a: 123}) -``` - -The output is: - -```shell -hello KCL - -None:None -True -False -123 -123.0 -abc 123 -abc 456 -[1, 'a', True] -1 a True -{} -{'a': 123} -``` - -If you do not want the default newline, you can re-specify the ending string with the `end=''` named parameter. - -```python -print("Hello KCL", end='') -``` - -## multiplyof - -`multiplyof(a:int, b:int) -> bool` - -Check whether the integer `a` is an integer multiple of `b`, and return a boolean value: - -```python -print(multiplyof(2, 1)) # True -print(multiplyof(1, 2)) # False -print(multiplyof(0, 1)) # True -print(multiplyof(0, 2)) # True -print(multiplyof(1, 0)) # Error -``` - -`0` is a multiple of any number. But `b` cannot be `0`, otherwise an exception will be thrown. - -## isunique - -`isunique(list: [any]) -> bool` - -Check if there are duplicate elements in an array, and return a boolean value: - -```python -print(isunique([])) # True -print(isunique([1])) # True -print(isunique([1, 2])) # True - -print(isunique([1, 1])) # False -print(isunique([1, 1.0])) # False -print(isunique([1.1, 1.1])) # False - -print(isunique(['abc', "abc"])) # False -print(isunique(['abc', "a${'bc'}"])) # False -``` - -It should be noted that integers and floating-point numbers ignore the type difference and judge whether the values are equal. - -## len - -`len(x: str | [any] | {:}) -> int` - -Return the length of strings, lists, and arrays: - -```python -print(len([])) # 0 -print(len({})) # 0 - -print(len([1])) # 1 -print(len({abc:123})) # 1 - -print("abc") # 3 -``` - -Note: Calculating lengths on `schema` objects is not supported. - -## abs - -`abs(x: number) -> number` - -Calculate the absolute value of `x`. - -## all_true - -`all_true(x:str|[]|{:}) -> bool` - -Judging that all elements of a list or dictionary class are true, the usage is as follows: - -```python -print(all_true([])) # True -print(all_true({})) # True - -print(all_true([True])) # True -print(all_true([1])) # True - -print(all_true([True, False])) # False -print(all_true([True, None])) # False -``` - -Returns true when the list is empty. - -## any_true - -`any_true(x:str|[]|{:}) -> bool` - -Judging that at least one element in the iterable object is true, the usage is as follows: - -```python -print(any_true([])) # False -print(any_true([1])) # True -``` - -## bin - -`bin(x:number) -> str` - -A string that returns the binary representation of an integer, used as follows: - -```python -print(bin(8)) # 0b1000 -``` - -## hex - -`hex(number)` - -A string that returns the hexadecimal representation of an integer, used as follows: - -```python -print(hex(18)) # 0x12 -``` - -## oct - -`oct(number)` - -A string that returns the octal representation of an integer, used as follows: - -```python -print(oct(10)) # 0o12 -``` - -## option - -`option(key:str, type:str='', required=False, default=None, help="") -> any` - -Gets the value of the command line top level argument input. - -## ord - -`ord(c) -> int` - -Get the Unicode code point value of the character, the usage is as follows: - -```python -print(ord('A')) # 65 -print(ord('B')) # 66 -print(ord('C')) # 67 -``` - -## sorted - -`sorted(x: []) -> []` - -Returns the sorted list, used as follows: - -```python -_a = [] -_b = [2, 1] - -_c = sorted(_a) -_d = sorted(_b) - -print(_a) # [] -print(_b) # [2, 1] -print(_c) # [] -print(_d) # [1, 2] -``` - -## range - -`range(start:int, end:int, step=1) -> [int]` - -Generates an iterable list, used as follows: - -```python -print(range(1,5)) # [1, 2, 3, 4] -print(range(1,5, 2)) # [1, 3] -print(range(5, 1, -1)) # [5, 4, 3, 2] -``` - -## min - -`min(x:[number]) -> number` - -Returns the smallest element in the list, used as follows: - -```python -print(min([1,2])) # 1 -print(min([2,1])) # 1 -``` - -## max - -`max(x:[number]) -> number` - -Returns the largest element in the list, used as follows: - -```python -print(max([1,2])) # 2 -print(max([2,1])) # 2 -``` - -## sum - -`sum(x:[number], init_value=0) -> number` - -Returns the sum of all elements in the list, used as follows: - -``` -print(sum([1,2])) # 3 -print(sum([2,1], 1000)) # 1003 -``` - -## pow - -`pow(x: number, y: number, z: number = None) -> number` - -Computes `x**y`, or `(x**y)%z` if `z` is not empty, supports integer and floating point numbers, used as follows: - -```python -print(pow(2,3)) # 8 -print(pow(2, 3, 5)) # 8%5 == 3 - -print(pow(2, 0.5)) # 1.414 -``` - -## round - -`round(number: int|float, ndigits:int|None) -> float | int` - -Returns the rounded approximation of `number`. If `ndigits` is not `None` returns a float with the specified number of decimal places (cannot be negative), otherwise returns an integer structure, used as follows: - -```python -print(round(1)) # 1 -print(round(1.4)) # 1 -print(round(1.5)) # 2 - -print(round(1.5555, 1)) # 1.6 -print(round(1.5555, 2)) # 1.56 - -print(round(1.5555)) # 2 -print(round(1.5555, 0)) # 2.0 -``` - -It should be noted that the difference between `ndigits` being `None` and `0` is that the prefix returns `int` type, the latter returns `float` type. - -## typeof - -`typeof(x: any, full_name: bool = False) -> str` - -Output the type of `x` at runtime. When the `full_name` parameter is set to `True`, the package prefix of the form `pkg.schema` will be returned, used as follows: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person{} -t3 = typeof(_x1) - -_x2 = pkg.Person{} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# Output -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -## zip - -`zip(*args: str|list|dict)` - -It is used to take an iterable object as a parameter, pack the corresponding elements in the object into tuples, and then return a list composed of these tuples, used as follows: - -```py -a = zip([0, 1, 2], [3, 4, 5]) -b = zip([0, 1], [3, 4, 5]) -c = zip([0, 1, 2], [3, 4, 5, 6]) - -# Output -# a: -# - - 0 -# - 3 -# - - 1 -# - 4 -# - - 2 -# - 5 -# b: -# - - 0 -# - 3 -# - - 1 -# - 4 -# c: -# - - 0 -# - 3 -# - - 1 -# - 4 -# - - 2 -``` diff --git a/versioned_docs/version-0.6.0/reference/model/crypto.md b/versioned_docs/version-0.6.0/reference/model/crypto.md deleted file mode 100644 index 7fab7e50..00000000 --- a/versioned_docs/version-0.6.0/reference/model/crypto.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "crypto" -linkTitle: "crypto" -type: "docs" -description: crypto system module -weight: 100 ---- - -## md5 - -`md5(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `MD5` and the codec registered for encoding. - -## sha1 - -`sha1(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA1` and the codec registered for encoding. - -## sha224 - -`sha224(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA224` and the codec registered for encoding. - -## sha256 - -`sha256(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA256` and the codec registered for encoding. - -## sha384 - -`sha384(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA384` and the codec registered for encoding. - -## sha512 - -`sha512(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA512` and the codec registered for encoding. diff --git a/versioned_docs/version-0.6.0/reference/model/index.md b/versioned_docs/version-0.6.0/reference/model/index.md deleted file mode 100644 index 163e8db3..00000000 --- a/versioned_docs/version-0.6.0/reference/model/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# System Package - -KCL provides engineering extensibility through system modules, user modules and plug-in modules. This section describes the basic concepts of system modules. diff --git a/versioned_docs/version-0.6.0/reference/model/manifests.md b/versioned_docs/version-0.6.0/reference/model/manifests.md deleted file mode 100644 index ab31ad47..00000000 --- a/versioned_docs/version-0.6.0/reference/model/manifests.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: "manifests" -linkTitle: "manifests" -type: "docs" -description: manifests system module -weight: 100 ---- - -## yaml_stream - -```python -yaml_stream(values: [any], opts: {str:} = { - sort_keys = False - ignore_private = True - ignore_none = False - sep = "---" -}) -``` - -This function is used to serialize the KCL object list into YAML output with the --- separator. It has two parameters: - -- `values` - A list of KCL objects -- `opts` - The YAML serialization options - - `sort_keys`: Whether to sort the serialized results in the dictionary order of attribute names (the default is `False`). - - `ignore_private`: Whether to ignore the attribute output whose name starts with the character `_` (the default value is `True`). - - `ignore_none`: Whether to ignore the attribute with the value of' None '(the default value is `False`). - - `sep`: Set the separator between multiple YAML documents (the default value is `"---"`). - -Here's an example: - -```python -# Use the `import` keyword to import the `manifests` module. -import manifests - -# The schema `Deployment` definition. -schema Deployment: - apiVersion: str = "v1" - kind: str = "Deployment" - metadata: {str:} = { - name = "deploy" - } - spec: {str:} = { - replica = 2 - } - -# The schema `Service` definition. -schema Service: - apiVersion: str = "v1" - kind: str = "Service" - metadata: {str:} = { - name = "svc" - } - spec: {str:} = {} - -# Define two `Deployment` resources. -deployments = [Deployment {}, Deployment {}] -# Define two `Service` resources. -services = [Service {}, Service {}] -# Put them into a KCL list and call the `manifests.yaml_stream` function. -manifests.yaml_stream(deployments + services) -``` - -First, we use the `import` keyword to import the `manifests` module and define two deployment resources and two service resources. When we want to output these four resources in YAML stream format with `---` as the separator, we can put them into a KCL list and use the `manifests.yaml_stream` function pass it to the `values` parameter (if there is no special requirement, the `opts` parameter can generally use the default value). Finally, the YAML output is: - -```yaml -apiVersion: v1 -kind: Deployment -metadata: - name: deploy -spec: - replica: 2 ---- -apiVersion: v1 -kind: Deployment -metadata: - name: deploy -spec: - replica: 2 ---- -apiVersion: v1 -kind: Service -metadata: - name: svc ---- -apiVersion: v1 -kind: Service -metadata: - name: svc -``` diff --git a/versioned_docs/version-0.6.0/reference/model/net.md b/versioned_docs/version-0.6.0/reference/model/net.md deleted file mode 100644 index a4e83659..00000000 --- a/versioned_docs/version-0.6.0/reference/model/net.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: "net" -linkTitle: "net" -type: "docs" -description: net system module -weight: 100 ---- - -## split_host_port - -`split_host_port(ip_end_point: str) -> List[str]` - -Split the `host` and `port` from the `ip_end_point`. - -## join_host_port - -`join_host_port(host, port) -> str` - -Merge the `host` and `port`. - -## fqdn - -`fqdn(name: str = '') -> str` - -Return Fully Qualified Domain Name (FQDN). - -## parse_IP - -`parse_IP(ip) -> str` - -Parse `ip` to a real IP address - -## to_IP4 - -`to_IP4(ip) -> str` - -Get the IP4 form of `ip`. - -## to_IP16 - -`to_IP16(ip) -> int` - -Get the IP16 form of `ip`. - -## IP_string - -`IP_string(ip: str | int) -> str` - -Get the IP string. - -## is_IPv4 - -`is_IPv4(ip: str) -> bool` - -Whether `ip` is a IPv4 one. - -## is_IP - -`is_IP(ip: str) -> bool` - -Whether `ip` is a valid ip address. - -## is_loopback_IP - -`is_loopback_IP(ip: str) -> bool` - -Whether `ip` is a loopback one. - -## is_multicast_IP - -`is_multicast_IP(ip: str) -> bool` - -Whether `ip` is a multicast one. - -## is_interface_local_multicast_IP - -`is_interface_local_multicast_IP(ip: str) -> bool` - -Whether `ip` is a interface, local and multicast one. - -## is_link_local_multicast_IP - -`is_link_local_multicast_IP(ip: str) -> bool` - -Whether `ip` is a link local and multicast one. - -## is_link_local_unicast_IP - -`is_link_local_unicast_IP(ip: str) -> bool` - -Whether `ip` is a link local and unicast one. - -## is_global_unicast_IP - -`is_global_unicast_IP(ip: str) -> bool` - -Whether `ip` is a global and unicast one. - -## is_unspecified_IP - -`is_unspecified_IP(ip: str) -> bool` - -Whether `ip` is a unspecified one. diff --git a/versioned_docs/version-0.6.0/reference/model/overview.md b/versioned_docs/version-0.6.0/reference/model/overview.md deleted file mode 100644 index 36365ac1..00000000 --- a/versioned_docs/version-0.6.0/reference/model/overview.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -sidebar_position: 0 ---- - -# Overview - -KCL provides engineering extensibility through built-in modules, system modules and plug-in modules. - -![](/img/docs/reference/lang/model/kcl-module.png) - -The user code does not need to import functions that directly use builtin functions (such as calculating the length of a list with `len`, obtaining the type of value through `typeof`, etc.), and for basic types such as strings, it also provides some built-in methods (such as converting the case of strings, etc.). - -For relatively complex general logic, it is provided through the system modules. For example, by importing the `math` module, we can use related mathematical functions, and we can use the regular expression by importing the `regex` module. For KCL code, it can also be organized into different user modules. - -In addition, Python and Go can be used to develop plug-ins for KCL through the plugin mechanism. For example, there are the app-context plug-in can be used to obtain the context information of the current application to simplify code writing. diff --git a/versioned_docs/version-0.6.0/reference/model/regex.md b/versioned_docs/version-0.6.0/reference/model/regex.md deleted file mode 100644 index adde0630..00000000 --- a/versioned_docs/version-0.6.0/reference/model/regex.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "regex" -linkTitle: "regex" -type: "docs" -description: regex system module -weight: 100 ---- - -## replace - -`replace(string: str, pattern: str, replace: str, count=0) -> str` - -Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement. - -## match - -`match(string: str, pattern: str) -> bool` - -Try to apply the pattern at the start of the string, returning a bool value `True` if any match was found, or `False` if no match was found. - -## compile - -`compile(pattern: str) -> bool` - -Compile a regular expression pattern, returning a bool value denoting whether the pattern is valid. - -## findall - -`findall(string: str, pattern: str) -> List[str]` - -Return a list of all non-overlapping matches in the string. - -## search - -`search(string: str, pattern: str) -> bool` - -Scan through string looking for a match to the pattern, returning a bool value `True` if any match was found, or `False` if no match was found. - -## split - -`split(string: str, pattern: str, maxsplit=0) -> List[str]` - -Return a list composed of words from the string, splitting up to a maximum of `maxsplit` times using `pattern` as the separator. diff --git a/versioned_docs/version-0.6.0/reference/model/units.md b/versioned_docs/version-0.6.0/reference/model/units.md deleted file mode 100644 index 34465a53..00000000 --- a/versioned_docs/version-0.6.0/reference/model/units.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: "units" -linkTitle: "units" -type: "docs" -description: units system module - Unit handlers -weight: 100 ---- - -## Constants - -- Fixed point unit constants: `n`, `u`, `m`, `k`, `K`, `G`, `T` and `P`. -- Power of 2 unit constants: `Ki`, `Mi`, `Gi`, `Ti` and `Pi`. - -## Functions - -- `to_n(num: int) -> str` - Int literal to string with `n` suffix -- `to_u(num: int) -> str` - Int literal to string with `u` suffix -- `to_m(num: int) -> str` - Int literal to string with `m` suffix -- `to_K(num: int) -> str` - Int literal to string with `K` suffix -- `to_M(num: int) -> str` - Int literal to string with `M` suffix -- `to_G(num: int) -> str` - Int literal to string with `G` suffix -- `to_T(num: int) -> str` - Int literal to string with `T` suffix -- `to_P(num: int) -> str` - Int literal to string with `P` suffix -- `to_Ki(num: int) -> str` - Int literal to string with `Ki` suffix -- `to_Mi(num: int) -> str` - Int literal to string with `Mi` suffix -- `to_Gi(num: int) -> str` - Int literal to string with `Gi` suffix -- `to_Ti(num: int) -> str` - Int literal to string with `Ti` suffix -- `to_Pi(num: int) -> str` - Int literal to string with `Pi` suffix diff --git a/versioned_docs/version-0.6.0/reference/model/yaml.md b/versioned_docs/version-0.6.0/reference/model/yaml.md deleted file mode 100644 index 4b952dcf..00000000 --- a/versioned_docs/version-0.6.0/reference/model/yaml.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: "yaml" -linkTitle: "yaml" -type: "docs" -description: yaml encode and decode function -weight: 300 ---- - -## encode - -``` -encode( - data: any, - sort_keys: bool = False, - ignore_private: bool = False, - ignore_none: bool = False -) -> str -``` - -Serialize a KCL object `data` to a YAML formatted str. - -## decode - -`decode(value: str) -> any` - -Deserialize `value` (a string instance containing a YAML document) to a KCL object. - -## dump_to_file - -``` -dump_to_file( - data: any, - filename: str, - ignore_private: bool = False, - ignore_none: bool = False -) -> None -``` - -Serialize a KCL object `data` to a YAML formatted str and write it into the file `filename`. diff --git a/versioned_docs/version-0.6.0/reference/plugin/_category_.json b/versioned_docs/version-0.6.0/reference/plugin/_category_.json deleted file mode 100644 index e77dfb1c..00000000 --- a/versioned_docs/version-0.6.0/reference/plugin/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Plugin System", - "position": 4 -} diff --git a/versioned_docs/version-0.6.0/reference/plugin/index.md b/versioned_docs/version-0.6.0/reference/plugin/index.md deleted file mode 100644 index df299e93..00000000 --- a/versioned_docs/version-0.6.0/reference/plugin/index.md +++ /dev/null @@ -1 +0,0 @@ -# Plugin System diff --git a/versioned_docs/version-0.6.0/reference/plugin/overview.md b/versioned_docs/version-0.6.0/reference/plugin/overview.md deleted file mode 100644 index f9561ddc..00000000 --- a/versioned_docs/version-0.6.0/reference/plugin/overview.md +++ /dev/null @@ -1,187 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Introduction - -KCL provides plugin support through a plugin agent and auxiliary command line tools, and the KCL plugin framework supports different general-purpose languages to develop plugins. Here we take Python as an example to briefly explain the use of plugins. - -KCL plugin Git repository: [https://github.com/kcl-lang/kcl-plugin](https://github.com/kcl-lang/kcl-plugin) - -## 0. Prerequisites - -Using the KCL Python plugin requires the presence of `Python 3.7+` in your `PATH`. - -## 1. Hello Plugin - -KCL plugins are installed in the `plugins` subdirectory of KCL (usually installed in the `$HOME/.kcl/plugins` directory), or set through the `$KCL_PLUGINS_ROOT` environment variable. Besides, the `plugins` directory could also be placed at the `pwd` path. KCL plugins are managed in the Git repository: [https://github.com/kcl-lang/kcl-plugin](https://github.com/kcl-lang/kcl-plugin), we can clone the repository for development. - -Enter the `kcl-plugin info` command to view the plugin directory (replace `/Users/kcl_user` with the local `$HOME` path): - -```shell -$ kcl-plugin info -# plugin_root: /Users/kcl_user/.kcl/plugins -``` - -View the list of plugins with the `kcl-plugin list` subcommand: - -```shell -$ kcl-plugin list -hello: hello doc - 0.0.1 -``` - -Where `hello` is an example builtin plugin (do not modify the plugin). - -In KCL code, the `hello` plugin can be imported via `import kcl_plugin.hello`. `main.k` code is as follows: - -```python -import kcl_plugin.hello - -name = "kcl" -three = hello.add(1,2) -``` - -The output result is - -```shell -$ python3 -m kclvm main.k -name: kcl -three: 3 -``` - -## 2. `kcl-plugin` Command - -`kcl-plugin` is a plugin helper command line tool, the command line help is as follows: - -```shell -$ kcl-plugin -usage: kcl-plugin [-h] {list,info,init,gendoc,test} ... -positional arguments: - {list,info,init,gendoc,test} - kcl plugin sub commands - list list all plugins - info show plugin document - init init a new plugin - gendoc gen all plugins document - test test plugin -optional arguments: - -h, --help show this help message and exit -``` - -- The `list` subcommand is used to view the list of plugins. -- The `info` subcommand is used to view the plugin directory and information about each plugin. -- The `init` subcommand is used to initialize new plugins. -- The `gendoc` subcommand is used to update the API documentation of all plugins. -- The `test` subcommand is used to test specified plugins. - -## 3. Plugin Information and Documentation - -Enter `kcl-plugin info hello` to view the `hello` plugin information: - -```shell -$ kcl-plugin info hello -{ - "name": "hello", - "describe": "hello doc", - "long_describe": "long describe", - "version": "0.0.1", - "method": { - "add": "add two numbers, and return result", - "foo": "no doc", - "list_append": "no doc", - "say_hello": "no doc", - "tolower": "no doc", - "update_dict": "no doc" - } -} -``` - -The information of the plugin mainly includes the name and version information of the plugin, and the function information provided by the plugin. This information is consistent with the automatically generated `api.md` file in the plugin directory (regenerate the `api.md` file for all plugins via `kcl-plugin gendoc` when the plugin API document changes). - -## 4. Plugin Directory Structure - -The directory structure of the plugin is as follows (replace `/Users/kcl_user` with the local `$HOME` path): - -```shell -$ tree /Users/kcl_user/.kcl/plugins/ -/Users/kcl_user/.kcl/plugins/ -├── _examples -├── _test -└── hello - ├── api.md - ├── plugin.py - └── plugin_test.py -$ -``` - -The `_examples` directory is the sample code of the plugin, the `_test` directory is the KCL test code of the plugin, and the other directories starting with letters are ordinary plugins. The content of the plugin is as follows: - -```shell -$ cat ./hello/plugin.py -# Copyright 2020 The KCL Authors. All rights reserved. -INFO = { - 'name': 'hello', - 'describe': 'hello doc', - 'long_describe': 'long describe', - 'version': '0.0.1', -} -def add(a: int, b: int) -> int: - """add two numbers, and return result""" - return a + b -... -``` - -Where `INFO` specifies the name of the plugin, a brief description, a detailed description and version information. And all the functions whose names start with letters are the functions provided by the plugin, so the `add` function can be called directly in KCL. - -> Note: KCL plugins are implemented in an independent pure Python code file, and plugins cannot directly call each other. - -## 5. Create Plugin - -A plugin can be created with the `kcl-plugin init` command: - -``` -$ kcl-plugin init hi -$ kcl-plugin list -hello: hello doc - 0.0.1 -hi: hi doc - 0.0.1 -``` - -The `kcl-plugin init` command will construct a new plugin from the built-in template, and then we can view the created plugin information with the `kcl-plugin list` command. - -## 6. Remove Plugin - -KCL plugins are located in the `plugins` subdirectory of KCL (usually installed in the `$HOME/.kcl/plugins` directory). -We can query the plugin installation directory with the command `kcl-plugin info`. - -```shell -$ kcl-plugin info -/Users/kcl_user/.kcl/plugins/ -$ tree /Users/kcl_user/.kcl/plugins/ -/Users/kcl_user/.kcl/plugins/ -├── _examples -├── _test -└── hello -- Delete this directory to delete the hello plugin - ├── api.md - ├── plugin.py - └── plugin_test.py -$ -``` - -## 7. Test Plugin - -There is a `plugin_test.py` file in the plugin directory, which is the unit test file of the plugin (based on the `pytest` testing framework). Also placed in the `_test` directory are plugin integration tests for KCL files. The `plugin_test.py` unit test is required, and the KCL integration tests in the `_test` directory can be added as needed. - -Unit tests for plugins can be executed via `kcl-plugin test`: - -```shell -$ kcl-plugin test hello -============================= test session starts ============================== -platform darwin -- Python 3.7.6+, pytest-5.3.5, py-1.9.0, pluggy-0.13.1 -rootdir: /Users/kcl_user -collected 5 items -.kcl/plugins/hello/plugin_test.py ..... [100%] -============================== 5 passed in 0.03s =============================== -$ -``` - -Integration tests can be tested by executing the `python3 -m pytest` command in the `_test` directory. diff --git a/versioned_docs/version-0.6.0/reference/plugin/project_context.md b/versioned_docs/version-0.6.0/reference/plugin/project_context.md deleted file mode 100644 index 0be02e78..00000000 --- a/versioned_docs/version-0.6.0/reference/plugin/project_context.md +++ /dev/null @@ -1,59 +0,0 @@ -# project_context - -project_context extract base info from project.yaml&stack.yaml - -_version: 0.0.1_ - -## `get_project_current_path` - -return the relative path of first file - -Example: - -```py -import kcl_plugin.project_context as ctx - -path = ctx.get_project_current_path() -print(path) -``` - -## `get_project_input_file` - -return compiling file list - -Example: - -```py -import kcl_plugin.project_context as ctx - -input_file = ctx.get_project_input_file() -print(input_file) -``` - -## `get_project_context` - -return the current project context from project.yaml - -Example: - -```py -import kcl_plugin.project_context as ctx - -project = ctx.get_project_context() -# Get project name -print(project?.name) -``` - -## `get_stack_context` - -return the current stack context from stack.yaml - -Example: - -```py -import kcl_plugin.project_context as ctx - -stack = ctx.get_stack_context() -# Get stack name -print(stack?.name) -``` diff --git a/versioned_docs/version-0.6.0/reference/xlang-api/_category_.json b/versioned_docs/version-0.6.0/reference/xlang-api/_category_.json deleted file mode 100644 index c2aafb21..00000000 --- a/versioned_docs/version-0.6.0/reference/xlang-api/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Multi-Language", - "position": 4 -} diff --git a/versioned_docs/version-0.6.0/reference/xlang-api/go-api.md b/versioned_docs/version-0.6.0/reference/xlang-api/go-api.md deleted file mode 100644 index 2a978250..00000000 --- a/versioned_docs/version-0.6.0/reference/xlang-api/go-api.md +++ /dev/null @@ -1,665 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Go API - -```go -import kcl "kcl-lang.io/kcl-go" -``` - -## KCL Go SDK - -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ kcl files │ │ KCL-Go-API │ │ KCLResultList │ -│ ┌───────────┐ │ │ │ │ │ -│ │ 1.k │ │ │ │ │ │ -│ └───────────┘ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ ┌───────────┐ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.Get("a.b.c") │ -│ │ 2.k │ │ │ │ Run(path) │ │ │ └───────────┘ │ └───────────────┘ -│ └───────────┘ │────┐ │ └───────────┘ │ │ │ -│ ┌───────────┐ │ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ │ 3.k │ │ │ │ │ │ │ KCLResult │──┼────────▶│x.Get("k", &v) │ -│ └───────────┘ │ │ │ │ │ └───────────┘ │ └───────────────┘ -│ ┌───────────┐ │ ├───▶│ ┌───────────┐ │──────────▶│ │ -│ │setting.yml│ │ │ │ │RunFiles() │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ └───────────┘ │ │ │ └───────────┘ │ │ │ KCLResult │──┼────────▶│x.JSONString() │ -└─────────────────┘ │ │ │ │ └───────────┘ │ └───────────────┘ - │ │ │ │ │ -┌─────────────────┐ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ Options │ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.YAMLString() │ -│WithOptions │ │ │ │MustRun() │ │ │ └───────────┘ │ └───────────────┘ -│WithOverrides │────┘ │ └───────────┘ │ │ │ -│WithWorkDir │ │ │ │ │ -│WithDisableNone │ │ │ │ │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ -``` - -
Example -

- -```go -{ - const k_code = ` -name = "kcl" -age = 1 - -two = 2 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {} -x1 = Person { - age = 101 -} -` - - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First().YAMLString() - fmt.Println(yaml) - - fmt.Println("----") - - result := kcl.MustRun("./testdata/main.k").First() - fmt.Println(result.JSONString()) - - fmt.Println("----") - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - - fmt.Println("----") - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x1", &person)) -} -``` - -

-
- -## Index - -- [Go API](#go-api) - - [KCL Go SDK](#kcl-go-sdk) - - [Index](#index) - - [Constants](#constants) - - [func FormatCode](#func-formatcode) - - [func FormatPath](#func-formatpath) - - [func InitKclvmPath](#func-initkclvmpath) - - [func InitKclvmRuntime](#func-initkclvmruntime) - - [func LintPath](#func-lintpath) - - [func ListDepFiles](#func-listdepfiles) - - [func ListDownStreamFiles](#func-listdownstreamfiles) - - [func ListUpStreamFiles](#func-listupstreamfiles) - - [func OverrideFile](#func-overridefile) - - [func ValidateCode](#func-validatecode) - - [type KCLResult](#type-kclresult) - - [type KCLResultList](#type-kclresultlist) - - [func MustRun](#func-mustrun) - - [func Run](#func-run) - - [func RunFiles](#func-runfiles) - - [type KclType](#type-kcltype) - - [func GetSchemaType](#func-getschematype) - - [type ListDepFilesOption](#type-listdepfilesoption) - - [type ListDepsOptions](#type-listdepsoptions) - - [type Option](#type-option) - - [func WithCode](#func-withcode) - - [func WithDisableNone](#func-withdisablenone) - - [func WithKFilenames](#func-withkfilenames) - - [func WithOptions](#func-withoptions) - - [func WithOverrides](#func-withoverrides) - - [func WithPrintOverridesAST](#func-withprintoverridesast) - - [func WithSettings](#func-withsettings) - - [func WithSortKeys](#func-withsortkeys) - - [func WithWorkDir](#func-withworkdir) - - [type ValidateOptions](#type-validateoptions) - -## Constants - -KclvmAbiVersion is the current kclvm ABI version. - -```go -const KclvmAbiVersion = scripts.KclvmAbiVersion -``` - -## func [FormatCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L110) - -```go -func FormatCode(code interface{}) ([]byte, error) -``` - -FormatCode returns the formatted code. - -
Example -

- -```go -{ - out, err := kcl.FormatCode(`a = 1+2`) - if err != nil { - log.Fatal(err) - } - fmt.Println(string(out)) - -} -``` - -``` -a = 1 + 2 -``` - -

-
- -## func [FormatPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L122) - -```go -func FormatPath(path string) (changedPaths []string, err error) -``` - -FormatPath formats files from the given path path: if path is \`.\` or empty string, all KCL files in current directory will be formatted, not recursively if path is \`path/file.k\`, the specified KCL file will be formatted if path is \`path/to/dir\`, all KCL files in the specified dir will be formatted, not recursively if path is \`path/to/dir/...\`, all KCL files in the specified dir will be formatted recursively - -the returned changedPaths are the changed file paths \(relative path\) - -
Example -

- -```go -{ - changedPaths, err := kcl.FormatPath("testdata/fmt") - if err != nil { - log.Fatal(err) - } - fmt.Println(changedPaths) -} -``` - -

-
- -## func [InitKclvmPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L54) - -```go -func InitKclvmPath(kclvmRoot string) -``` - -InitKclvmPath init kclvm path. - -## func [InitKclvmRuntime](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L59) - -```go -func InitKclvmRuntime(n int) -``` - -InitKclvmRuntime init kclvm process. - -## func [LintPath](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L142) - -```go -func LintPath(paths []string) (results []string, err error) -``` - -LintPath lint files from the given path - -
Example -

- -```go -{ - - results, err := kcl.LintPath([]string{"testdata/lint/import.k"}) - if err != nil { - log.Fatal(err) - } - for _, s := range results { - fmt.Println(s) - } - -} -``` - -``` -Module 'a' is reimported multiple times -Module 'a' imported but unused -``` - -

-
- -## func [ListDepFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L127) - -```go -func ListDepFiles(workDir string, opt *ListDepFilesOption) (files []string, err error) -``` - -ListDepFiles return the depend files from the given path - -## func [ListDownStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L137) - -```go -func ListDownStreamFiles(workDir string, opt *ListDepsOptions) ([]string, error) -``` - -ListDownStreamFiles return a list of downstream depend files from the given changed path list. - -## func [ListUpStreamFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L132) - -```go -func ListUpStreamFiles(workDir string, opt *ListDepsOptions) (deps []string, err error) -``` - -ListUpStreamFiles return a list of upstream depend files from the given path list - -## func [OverrideFile](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L154) - -```go -func OverrideFile(file string, specs, importPaths []string) (bool, error) -``` - -OverrideFile rewrites a file with override spec file: string. The File that need to be overridden specs: \[\]string. List of specs that need to be overridden. - -``` -Each spec string satisfies the form: := or :- -When the pkgpath is '__main__', it can be omitted. -``` - -importPaths. List of import statements that need to be added - -## func [ValidateCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L159) - -```go -func ValidateCode(data, code string, opt *ValidateOptions) (ok bool, err error) -``` - -ValidateCode validate data match code - -## type [KCLResult](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L47) - -```go -type KCLResult = kcl.KCLResult -``` - -
Example -

- -```go -{ - const k_code = ` -name = "kcl" -age = 1 - -two = 2 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {name = "kcl-go"} -x1 = Person {age = 101} -` - - result := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First() - - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - -} -``` - -``` -x0.name: kcl-go -x1.age: 101 -``` - -

-
- -
Example ('et_struct) -

- -```go -{ - const k_code = ` -schema Person: - name: str = "kcl" - age: int = 1 - X: int = 2 - -x = { - "a": Person {age = 101} - "b": 123 -} -` - - result := kcl.MustRun("testdata/main.k", kcl.WithCode(k_code)).First() - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x.a", &person)) - fmt.Printf("person: %+v\n", person) - -} -``` - -``` -person: &{Name:kcl Age:101} -person: {Name:kcl Age:101} -``` - -

-
- -## type [KCLResultList](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L48) - -```go -type KCLResultList = kcl.KCLResultList -``` - -### func [MustRun](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L64) - -```go -func MustRun(path string, opts ...Option) *KCLResultList -``` - -MustRun is like Run but panics if return any error. - -
Example -

- -```go -{ - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(`name = "kcl"`)).First().YAMLString() - fmt.Println(yaml) - -} -``` - -``` -name: kcl -``` - -

-
- -
Example (Raw Yaml) -

- -```go -{ - const code = ` -b = 1 -a = 2 -` - yaml := kcl.MustRun("testdata/main.k", kcl.WithCode(code)).GetRawYamlResult() - fmt.Println(yaml) - - yaml_sorted := kcl.MustRun("testdata/main.k", kcl.WithCode(code), kcl.WithSortKeys(true)).GetRawYamlResult() - fmt.Println(yaml_sorted) - -} -``` - -``` -b: 1 -a: 2 -a: 2 -b: 1 -``` - -

-
- -
Example (Schema Type) -

- -```go -{ - const code = ` -schema Person: - name: str = "" - -x = Person() -` - json := kcl.MustRun("testdata/main.k", kcl.WithCode(code)).First().JSONString() - fmt.Println(json) - -} -``` - -``` -{ - "x": { - "name": "" - } -} -``` - -

-
- -
Example (Settings) -

- -```go -{ - yaml := kcl.MustRun("./testdata/app0/kcl.yaml").First().YAMLString() - fmt.Println(yaml) -} -``` - -

-
- -### func [Run](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L69) - -```go -func Run(path string, opts ...Option) (*KCLResultList, error) -``` - -Run evaluates the KCL program with path and opts, then returns the object list. - -
Example (Get Field) -

- -```go -{ - - x, err := kcl.Run("./testdata/app0/kcl.yaml") - assert(err == nil, err) - - fmt.Println(x.First().Get("deploy_topology.1.zone")) - -} -``` - -``` -R000A -``` - -

-
- -### func [RunFiles](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L74) - -```go -func RunFiles(paths []string, opts ...Option) (*KCLResultList, error) -``` - -RunFiles evaluates the KCL program with multi file path and opts, then returns the object list. - -
Example -

- -```go -{ - result, _ := kcl.RunFiles([]string{"./testdata/app0/kcl.yaml"}) - fmt.Println(result.First().YAMLString()) -} -``` - -

-
- -## type [KclType](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L50) - -```go -type KclType = kcl.KclType -``` - -### func [GetSchemaType](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L176) - -```go -func GetSchemaType(file, code, schemaName string) ([]*KclType, error) -``` - -GetSchemaType returns schema types from a kcl file or code. - -file: string - -``` -The kcl filename -``` - -code: string - -``` -The kcl code string -``` - -schema_name: string - -``` -The schema name got, when the schema name is empty, all schemas are returned. -``` - -## type [ListDepFilesOption](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L45) - -```go -type ListDepFilesOption = list.Option -``` - -## type [ListDepsOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L44) - -```go -type ListDepsOptions = list.DepOptions -``` - -## type [Option](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L43) - -```go -type Option = kcl.Option -``` - -### func [WithCode](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L79) - -```go -func WithCode(codes ...string) Option -``` - -WithCode returns a Option which hold a kcl source code list. - -### func [WithDisableNone](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L97) - -```go -func WithDisableNone(disableNone bool) Option -``` - -WithDisableNone returns a Option which hold a disable none switch. - -### func [WithKFilenames](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L82) - -```go -func WithKFilenames(filenames ...string) Option -``` - -WithKFilenames returns a Option which hold a filenames list. - -### func [WithOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L85) - -```go -func WithOptions(key_value_list ...string) Option -``` - -WithOptions returns a Option which hold a key=value pair list for option function. - -
Example -

- -```go -{ - const code = ` -name = option("name") -age = option("age") -` - x, err := kcl.Run("hello.k", kcl.WithCode(code), - kcl.WithOptions("name=kcl", "age=1"), - ) - if err != nil { - log.Fatal(err) - } - - fmt.Println(x.First().YAMLString()) - -} -``` - -``` -age: 1 -name: kcl -``` - -

-
- -### func [WithOverrides](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L88) - -```go -func WithOverrides(override_list ...string) Option -``` - -WithOverrides returns a Option which hold a override list. - -### func [WithPrintOverridesAST](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L100) - -```go -func WithPrintOverridesAST(printOverridesAST bool) Option -``` - -WithPrintOverridesAST returns a Option which hold a printOverridesAST switch. - -### func [WithSettings](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L91) - -```go -func WithSettings(filename string) Option -``` - -WithSettings returns a Option which hold a settings file. - -### func [WithSortKeys](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L105) - -```go -func WithSortKeys(sortKeys bool) Option -``` - -WithSortKeys returns a Option which hold a sortKeys switch. - -### func [WithWorkDir](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L94) - -```go -func WithWorkDir(workDir string) Option -``` - -WithWorkDir returns a Option which hold a work dir. - -## type [ValidateOptions](https://github.com/kcl-lang/kcl-go/blob/main/kclvm.go#L46) - -```go -type ValidateOptions = validate.ValidateOptions -``` diff --git a/versioned_docs/version-0.6.0/reference/xlang-api/index.md b/versioned_docs/version-0.6.0/reference/xlang-api/index.md deleted file mode 100644 index f6f8e076..00000000 --- a/versioned_docs/version-0.6.0/reference/xlang-api/index.md +++ /dev/null @@ -1 +0,0 @@ -# Multi-Language diff --git a/versioned_docs/version-0.6.0/reference/xlang-api/java-api.md b/versioned_docs/version-0.6.0/reference/xlang-api/java-api.md deleted file mode 100644 index 52c8cf34..00000000 --- a/versioned_docs/version-0.6.0/reference/xlang-api/java-api.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Java API - -At present, the KCL Java SDK is still in the early preview version. The KCL team will continue to update and provide more functions in the future. For more information, see [https://github.com/kcl-lang/kcl-java](https://github.com/kcl-lang/kcl-java) diff --git a/versioned_docs/version-0.6.0/reference/xlang-api/overview.md b/versioned_docs/version-0.6.0/reference/xlang-api/overview.md deleted file mode 100644 index e63422d4..00000000 --- a/versioned_docs/version-0.6.0/reference/xlang-api/overview.md +++ /dev/null @@ -1,293 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Introduction - -The KCL language provides general programming language interfaces such as C/Rust/Go/Python/Java, and the related languages are under development. - -## C/Rust API - -The core of KCL is developed in Rust, and the C language API is exported externally for packaging and integration in high-level languages such as Go/Python/Java. - -## Go API - -Go API is a C-API provided by CGO wrapping KCL, while providing deeper customization features to meet the needs of upper-level tools. - -### Abstract Model - -The abstract model of the KCL Go API is as follows: - -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ kcl files │ │ KCL-Go-API │ │ KCLResultList │ -│ ┌───────────┐ │ │ │ │ │ -│ │ 1.k │ │ │ │ │ │ -│ └───────────┘ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ ┌───────────┐ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.Get("a.b.c") │ -│ │ 2.k │ │ │ │ Run(path) │ │ │ └───────────┘ │ └───────────────┘ -│ └───────────┘ │────┐ │ └───────────┘ │ │ │ -│ ┌───────────┐ │ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ │ 3.k │ │ │ │ │ │ │ KCLResult │──┼────────▶│x.Get("k", &v) │ -│ └───────────┘ │ │ │ │ │ └───────────┘ │ └───────────────┘ -│ ┌───────────┐ │ ├───▶│ ┌───────────┐ │──────────▶│ │ -│ │setting.yml│ │ │ │ │RunFiles() │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ └───────────┘ │ │ │ └───────────┘ │ │ │ KCLResult │──┼────────▶│x.JSONString() │ -└─────────────────┘ │ │ │ │ └───────────┘ │ └───────────────┘ - │ │ │ │ │ -┌─────────────────┐ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ Options │ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.YAMLString() │ -│WithOptions │ │ │ │MustRun() │ │ │ └───────────┘ │ └───────────────┘ -│WithOverrides │────┘ │ └───────────┘ │ │ │ -│WithWorkDir │ │ │ │ │ -│WithDisableNone │ │ │ │ │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ -``` - -The input file contains the KCL file and the `setting.yml` configuration file, and `Options` can be used to specify additional parameters and information such as working directory. The "KCL-Go-API" part is the provided KCL execution function. The execution function executes the KCL program according to the input file and additional parameters, and finally outputs the result of `KCLResultList`. `KCLResultList` is a list of `KCLResult`, each `KCLResult` corresponding to a generated configuration file or `map[string]interface{}`. - -### Example - -```go -package main - -import ( - "fmt" - - kcl "kcl-lang.io/kcl-go" -) - - -func main() { - const k_code = ` -name = "kcl" -age = 1 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person{} -x1 = Person{age:101} -` - - result := kcl.MustRun("hello.k", kcl.WithCode(k_code)).First() - fmt.Println(result.YAMLString()) - - fmt.Println("----") - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - - fmt.Println("----") - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x1", &person)) -} -``` - -Output result: - -```yaml -age: 1 -name: kcl -x0: - age: 1 - name: kcl -x1: - age: 101 - name: kcl - ----- -x0.name: kcl -x1.age: 101 ----- -person: &{Name:kcl Age:101} -``` - -## Python API - -Using the Python SDK requires that you have a local Python version higher than 3.7.3 and a local pip package management tool. You can use the following command to install and obtain helpful information. - -```bash -python3 -m pip install kclvm --user && python3 -m kclvm --help -``` - -### Command Line Tool - -Prepare a KCL file named `main.k` - -```python -name = "kcl" -age = 1 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {} -x1 = Person { - age = 101 -} -``` - -Execute the following command and get the output: - -```shell -$ python3 -m kclvm hello.k -name: kcl -age: 1 -x0: - name: kcl - age: 1 -x1: - name: kcl - age: 101 -``` - -### API - -In addition, we can also execute KCL files through Python code. - -Prepare a KCL file named `main.py` - -```python -import kclvm.program.exec as kclvm_exec -import kclvm.vm.planner as planner - -print(planner.plan(kclvm_exec.Run(["hello.k"]).filter_by_path_selector())) -``` - -Execute the following command and get the output: - -```shell -$ python3 main.py -name: kcl -age: 1 -x0: - name: kcl - age: 1 -x1: - name: kcl - age: 101 -``` - -You can see that the same output can be obtained through command line tools and APIs. - -At present, the KCL Python SDK is still in the early preview version. The KCL team will continue to update and provide more functions in the future. For more information, see [https://github.com/kcl-lang/kcl-py](https://github.com/kcl-lang/kcl-py) - -## REST-API - -The C-API provided by KCL does not have a REST-API. The REST-API is defined by Protobuf. - -### Start REST Service - -The RestAPI service can be started in the following way: - -```shell -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -The service can then be requested via the POST protocol: - -```shell -$ curl -X POST http://127.0.0.1:2021/api:protorpc/BuiltinService.Ping --data '{}' -{ - "error": "", - "result": {} -} -``` - -The POST request and the returned JSON data are consistent with the structure defined by Protobuf. - -### `BuiltinService` - -Where the `/api:protorpc/BuiltinService.Ping` path represents the `Ping` method of the `BuiltinService` service. - -The complete `BuiltinService` is defined by Protobuf: - -```protobuf -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} -``` - -The `Ping` method can verify whether the service is normal, and the `ListMethod` method can query the list of all services and functions provided. - -### `KclvmService` - -The `KclvmService` service is a service related to KCL functionality. The usage is the same as the `BuiltinService` service. - -For example, there is the following `Person` structure definition: - -```python -schema Person: - key: str - - check: - "value" in key # 'key' is required and 'key' must contain "value" -``` - -Then we want to use `Person` to verify the following JSON data: - -```json -{ "key": "value" } -``` - -This can be done through the `ValidateCode` method of the `KclvmService` service. Refer to the `ValidateCode_Args` structure of the `ValidateCode` method: - -```protobuf -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} -``` - -Construct the JSON data required by the POST request according to the `ValidateCode_Args` structure, which contains the `Person` definition and the JSON data to be verified: - -```json -{ - "code": "\nschema Person:\n key: str\n\n check:\n \"value\" in key # 'key' is required and 'key' must contain \"value\"\n", - "data": "{\"key\": \"value\"}" -} -``` - -Save this JSON data to the `vet-hello.json` file and verify it with the following command: - -```shell -$ curl -X POST \ - http://127.0.0.1:2021/api:protorpc/KclvmService.ValidateCode \ - -H "accept: application/json" \ - --data @./vet-hello.json -{ - "error": "", - "result": { - "success": true - } -} -``` - -## APIs in other languages - -Coming soon diff --git a/versioned_docs/version-0.6.0/reference/xlang-api/python-api.md b/versioned_docs/version-0.6.0/reference/xlang-api/python-api.md deleted file mode 100644 index e6ce67dc..00000000 --- a/versioned_docs/version-0.6.0/reference/xlang-api/python-api.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Python API - -At present, the KCL Python SDK is still in the early preview version. The KCL team will continue to update and provide more functions in the future. For more information, see [https://github.com/kcl-lang/kcl-py](https://github.com/kcl-lang/kcl-py) diff --git a/versioned_docs/version-0.6.0/reference/xlang-api/rest-api.md b/versioned_docs/version-0.6.0/reference/xlang-api/rest-api.md deleted file mode 100644 index 11f23305..00000000 --- a/versioned_docs/version-0.6.0/reference/xlang-api/rest-api.md +++ /dev/null @@ -1,443 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Rest API - -## 1. Start REST Service - -The RestAPI service can be started in the following ways: - -```shell -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -or - -```shell -go install kcl-lang.io/kcl-go/cmds/kcl-go@main -kcl-go rest-server -``` - -The service can then be requested via the POST protocol: - -```shell -$ curl -X POST http://127.0.0.1:2021/api:protorpc/BuiltinService.Ping --data '{}' -{ - "error": "", - "result": {} -} -``` - -The POST request and the returned JSON data are consistent with the structure defined by Protobuf. - -## 2. `BuiltinService` - -Where the `/api:protorpc/BuiltinService.Ping` path represents the `Ping` method of the `BuiltinService` service. - -The complete `BuiltinService` is defined by Protobuf: - -```protobuf -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} -``` - -The `Ping` method can verify whether the service is normal, and the `ListMethod` method can query the list of all services and functions provided. - -## 3. `KclvmService` - -The `KclvmService` service is a service related to KCL functionality. The usage is the same as the `BuiltinService` service. - -For example, there is the following `Person` structure definition: - -```python -schema Person: - key: str - - check: - "value" in key # 'key' is required and 'key' must contain "value" -``` - -Then we want to use `Person` to verify the following JSON data: - -```json -{ "key": "value" } -``` - -This can be done through the `ValidateCode` method of the `KclvmService` service. Refer to the `ValidateCode_Args` structure of the `ValidateCode` method: - -```protobuf -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} -``` - -Construct the JSON data required by the POST request according to the `ValidateCode_Args` structure, which contains the `Person` definition and the JSON data to be verified: - -```json -{ - "code": "\nschema Person:\n key: str\n\n check:\n \"value\" in key # 'key' is required and 'key' must contain \"value\"\n", - "data": "{\"key\": \"value\"}" -} -``` - -Save this JSON data to the `vet-hello.json` file and verify it with the following command: - -```shell -$ curl -X POST \ - http://127.0.0.1:2021/api:protorpc/KclvmService.ValidateCode \ - -H "accept: application/json" \ - --data @./vet-hello.json -{ - "error": "", - "result": { - "success": true - } -} -``` - -## 4. Complete Protobuf Service Definition - -Cross-language APIs defined via Protobuf([https://github.com/kcl-lang/kcl-go/blob/main/pkg/spec/gpyrpc/gpyrpc.proto](https://github.com/kcl-lang/kcl-go/blob/main/pkg/spec/gpyrpc/gpyrpc.proto)): - -```protobuf -// Copyright 2023 The KCL Authors. All rights reserved. -// -// This file defines the request parameters and return structure of the KCL RPC server. -// We can use the following command to start a KCL RPC server. - -syntax = "proto3"; - -package gpyrpc; - -import "google/protobuf/any.proto"; -import "google/protobuf/descriptor.proto"; - -// ---------------------------------------------------------------------------- - -// kcl main.k -D name=value -message CmdArgSpec { - string name = 1; - string value = 2; -} - -// kcl main.k -O pkgpath:path.to.field=field_value -message CmdOverrideSpec { - string pkgpath = 1; - string field_path = 2; - string field_value = 3; - string action = 4; -} - -// ---------------------------------------------------------------------------- -// gpyrpc request/response/error types -// ---------------------------------------------------------------------------- - -message RestResponse { - google.protobuf.Any result = 1; - string error = 2; - KclError kcl_err = 3; -} - -message KclError { - string ewcode = 1; // See kclvm/kcl/error/kcl_err_msg.py - string name = 2; - string msg = 3; - repeated KclErrorInfo error_infos = 4; -} - -message KclErrorInfo { - string err_level = 1; - string arg_msg = 2; - string filename = 3; - string src_code = 4; - string line_no = 5; - string col_no = 6; -} - -// ---------------------------------------------------------------------------- -// service request/response -// ---------------------------------------------------------------------------- - -// gpyrpc.BuiltinService -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -// gpyrpc.KclvmService -service KclvmService { - rpc Ping(Ping_Args) returns(Ping_Result); - - rpc ExecProgram(ExecProgram_Args) returns(ExecProgram_Result); - - rpc FormatCode(FormatCode_Args) returns(FormatCode_Result); - rpc FormatPath(FormatPath_Args) returns(FormatPath_Result); - rpc LintPath(LintPath_Args) returns(LintPath_Result); - rpc OverrideFile(OverrideFile_Args) returns (OverrideFile_Result); - - rpc GetSchemaType(GetSchemaType_Args) returns(GetSchemaType_Result); - rpc GetSchemaTypeMapping(GetSchemaTypeMapping_Args) returns(GetSchemaTypeMapping_Result); - rpc ValidateCode(ValidateCode_Args) returns(ValidateCode_Result); - - rpc ListDepFiles(ListDepFiles_Args) returns(ListDepFiles_Result); - rpc LoadSettingsFiles(LoadSettingsFiles_Args) returns(LoadSettingsFiles_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} - -message ParseFile_AST_Args { - string filename = 1; - string source_code = 2; -} -message ParseFile_AST_Result { - string ast_json = 1; // json value - KclError kcl_err = 2; -} - -message ParseProgram_AST_Args { - repeated string k_filename_list = 1; -} -message ParseProgram_AST_Result { - string ast_json = 1; // json value - KclError kcl_err = 2; -} - -message ExecProgram_Args { - string work_dir = 1; - - repeated string k_filename_list = 2; - repeated string k_code_list = 3; - - repeated CmdArgSpec args = 4; - repeated CmdOverrideSpec overrides = 5; - - bool disable_yaml_result = 6; - - bool print_override_ast = 7; - - // -r --strict-range-check - bool strict_range_check = 8; - - // -n --disable-none - bool disable_none = 9; - // -v --verbose - int32 verbose = 10; - - // -d --debug - int32 debug = 11; - - // yaml/json: sort keys - bool sort_keys = 12; - // include schema type path in JSON/YAML result - bool include_schema_type_path = 13; -} -message ExecProgram_Result { - string json_result = 1; - string yaml_result = 2; - - string escaped_time = 101; -} - -message ResetPlugin_Args { - string plugin_root = 1; -} -message ResetPlugin_Result { - // empty -} - -message FormatCode_Args { - string source = 1; -} - -message FormatCode_Result { - bytes formatted = 1; -} - -message FormatPath_Args { - string path = 1; -} - -message FormatPath_Result { - repeated string changed_paths = 1; -} - -message LintPath_Args { - repeated string paths = 1; -} - -message LintPath_Result { - repeated string results = 1; -} - -message OverrideFile_Args { - string file = 1; - repeated string specs = 2; - repeated string import_paths = 3; -} - -message OverrideFile_Result { - bool result = 1; -} - -message EvalCode_Args { - string code = 1; -} -message EvalCode_Result { - string json_result = 2; -} - -message ResolveCode_Args { - string code = 1; -} - -message ResolveCode_Result { - bool success = 1; -} - -message GetSchemaType_Args { - string file = 1; - string code = 2; - string schema_name = 3; -} -message GetSchemaType_Result { - repeated KclType schema_type_list = 1; -} - -message GetSchemaTypeMapping_Args { - string file = 1; - string code = 2; - string schema_name = 3; -} -message GetSchemaTypeMapping_Result { - map schema_type_mapping = 1; -} - -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} - -message ValidateCode_Result { - bool success = 1; - string err_message = 2; -} - -message Position { - int64 line = 1; - int64 column = 2; - string filename = 3; -} - -message ListDepFiles_Args { - string work_dir = 1; - bool use_abs_path = 2; - bool include_all = 3; - bool use_fast_parser = 4; -} - -message ListDepFiles_Result { - string pkgroot = 1; - string pkgpath = 2; - repeated string files = 3; -} - -// --------------------------------------------------------------------------------- -// LoadSettingsFiles API -// Input work dir and setting files and return the merged kcl singleton config. -// --------------------------------------------------------------------------------- - -message LoadSettingsFiles_Args { - string work_dir = 1; - repeated string files = 2; -} - -message LoadSettingsFiles_Result { - CliConfig kcl_cli_configs = 1; - repeated KeyValuePair kcl_options = 2; -} - -message CliConfig { - repeated string files = 1; - string output = 2; - repeated string overrides = 3; - repeated string path_selector = 4; - bool strict_range_check = 5; - bool disable_none = 6; - int64 verbose = 7; - bool debug = 8; -} - -message KeyValuePair { - string key = 1; - string value = 2; -} - -// ---------------------------------------------------------------------------- -// JSON Schema Lit -// ---------------------------------------------------------------------------- - -message KclType { - string type = 1; // schema, dict, list, str, int, float, bool, any, union, number_multiplier - repeated KclType union_types = 2 ; // union types - string default = 3; // default value - - string schema_name = 4; // schema name - string schema_doc = 5; // schema doc - map properties = 6; // schema properties - repeated string required = 7; // required schema properties, [property_name1, property_name2] - - KclType key = 8; // dict key type - KclType item = 9; // dict/list item type - - int32 line = 10; - - repeated Decorator decorators = 11; // schema decorators -} - -message Decorator { - string name = 1; - repeated string arguments = 2; - map keywords = 3; -} - -// ---------------------------------------------------------------------------- -// END -// ---------------------------------------------------------------------------- -``` diff --git a/versioned_docs/version-0.6.0/tools/Ide/_category_.json b/versioned_docs/version-0.6.0/tools/Ide/_category_.json deleted file mode 100644 index d9bfcdd7..00000000 --- a/versioned_docs/version-0.6.0/tools/Ide/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "IDE", - "position": 2 -} diff --git a/versioned_docs/version-0.6.0/tools/_category_.json b/versioned_docs/version-0.6.0/tools/_category_.json deleted file mode 100644 index 5ecd522f..00000000 --- a/versioned_docs/version-0.6.0/tools/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Tools", - "position": 3 -} diff --git a/versioned_docs/version-0.6.0/tools/cli/_category_.json b/versioned_docs/version-0.6.0/tools/cli/_category_.json deleted file mode 100644 index 887061ef..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Command Line Tools", - "position": 1 -} diff --git a/versioned_docs/version-0.6.0/tools/cli/index.md b/versioned_docs/version-0.6.0/tools/cli/index.md deleted file mode 100644 index ef4f69dc..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# Command Line Tools - -KCL provides IDE plug-ins, rich language tools and OpenAPI tools. These tools provide a complete set of solutions, including configuration languages, model interfaces, automation tools, and best practices. diff --git a/versioned_docs/version-0.6.0/tools/cli/kcl/_category_.json b/versioned_docs/version-0.6.0/tools/cli/kcl/_category_.json deleted file mode 100644 index 4c605bd0..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/kcl/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KCL Tools", - "position": 2 -} diff --git a/versioned_docs/version-0.6.0/tools/cli/kcl/docgen.md b/versioned_docs/version-0.6.0/tools/cli/kcl/docgen.md deleted file mode 100644 index ca647228..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/kcl/docgen.md +++ /dev/null @@ -1,317 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Docgen - -The KCL Docgen tool supports extracting model documents from KCL source code and supports multiple output formats: JSON, YAML and Markdown. This article introduces the document specification of the KCL language, gives an example of how to use the KCL Docgen tool to extract documents, and shows the process of importing localization documents. - -## 1. Document Specification of KCL - -The documentation of the KCL file mainly contains the following two parts: - -- Current KCL Module document: description of the current KCL file -- All schema documents contained in the KCL file: a description of the current schema, including schema description, schema attribute descriptions, and Examples. The specific format is as follows: - -1. Schema description - -```python -"""This is a brief description of the Schema -""" -``` - -2. Description of each attribute of Schema: including attribute description, attribute type, default value, optional or required - -```python -""" -Attributes ----------- -x : type, default is a, optional. - Description of parameter `x`. -y : type, default is b, required. - Description of parameter `y`. -""" -``` - -`----------` indicates that `Attributes` is a title (the length of the symbol `-` is the same as the length of the title), the attribute name and attribute type are separated by a colon `:`, the description of the attribute is written on another line with indentation. The default value of the attribute is separated by a comma `,` after the attribute type, and it is written in the form of `default is {default value}`. In addition, it is necessary to indicate whether the attribute is optional/required. Write `optional` after the default value for an optional attribute, and write `required` after the default value for a required attribute. - -3. Examples - -```python -""" -Examples --------- -val = Schema { - name = "Alice" - age = 18 -} -""" -``` - -In addition, the KCL docstring syntax should use a subset of the [re-structured text (reST)](https://docutils.sourceforge.io/rst.html) and be rendered using the [Sphinx](https://www.sphinx-doc.org/en/master/). - -## 2. Generating Documentation From KCL - -Use the `kcl-doc generate` command to extract documentation from a user-specified file or directory and output it to the specified directory. - -1. Args - -``` -usage: kcl-doc generate [-h] [--format YAML] [-o OUTPUT] [--r] - [--i18n-locale LOCALE] [--repo-url REPO_URL] - [files [files ...]] - -positional arguments: - files KCL file paths. If there's more than one files to - generate, separate them by space - -optional arguments: - -h, --help show this help message and exit - --format YAML Doc file format, support YAML, JSON and MARKDOWN. - Defaults to MARKDOWN - -o OUTPUT, --output-path OUTPUT - Specify the output directory. Defaults to ./kcl_doc - --r, -R, --recursive Search directory recursively - --i18n-locale LOCALE I18n locale, e.g.: zh, zh_cn, en, en_AS. Defaults to - en - --repo-url REPO_URL The source code repository url. It will be displayed in - the generated doc to link to the source code. -``` - -2. Extract documents from the file(s) and output them to the specified directory - -```text -kcl-doc generate your_config.k your_another_config.k -o your_docs_output_dir -``` - -3. From the specified directory, recursively find the KCL file(s) and extract the documentation - -```text -kcl-doc generate your_config_dir -r -o your_docs_output_dir -``` - -4. When generating documentation, specify the source code repository address. The generated documentation will contain links to source files - -```text -kcl-doc generate your_config.k -o your_docs_output_dir --repo-url https://url/to/source_code -``` - -## 3. Add Documentation for Localized Languages - -As shown before, by default, the documentation extracted by the documentation generation tool is based on the content of the source docstring, and thus the language of the documentation depends on the language in which the docstring was written. If you need to add localized language documentation to the source file, you can follow the steps below: - -1. Initialize the i18n configuration file. This step generates the corresponding i18n configuration file based on the specified KCL file. The file format can be JSON/YAML, and the default is YAML. The output profile name will end in the specified target localization language - -```text -kcl-doc init-i18n your_config.k --format JSON --i18n-locale your_target_locale -``` - -2. Modify the i18n configuration file and update each doc field in your locale language - -3. Generate localized documents from the modified i18n configuration file - -```text -kcl-doc generate your_config_dir --i18n-locale your_target_locale --format Markdown -``` - -Next, a simple example is used to demonstrate the process of adding localized language documents. - -3.1 Prepare the KCL file, such as `server.k`: - - ```python - schema Server: - """Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - - Attributes - ---------- - workloadType : str, default is "Deployment", required - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - name : str, required - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - labels : {str:str}, optional - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - - Examples - ---------------------- - myCustomApp = AppConfiguration { - name = "componentName" - } - """ - - workloadType: str = "Deployment" - name: str - labels?: {str: str} - ``` - -3.2 Get the initialized i18n configuration file from the `server.k`. For example, if you want to add Chinese documents to it, specify the format of the generated configuration file as YAML - - ```text - kcl-doc init-i18n server.k --format YAML --i18n-locale zh_cn - ``` - - This command will create the directory `kcl_doc` under the current directory and generate the i18n configuration file `kcl_doc/i18n_server_zh_cn.yaml`. Its contents are as follows: - - ```yaml - name: server - relative_path: ./server.k - schemas: - - name: Server - doc: | - Server is the common user interface for long-running - services adopting the best practice of Kubernetes. - attributes: - - name: workloadType - doc: | - Use this attribute to specify which kind of long-running service you want. - Valid values: Deployment, CafeDeployment. - See also: k8s/core/v1/workload_metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - default_value: '"Deployment"' - is_optional: false - - name: name - doc: | - A Server-level attribute. - The name of the long-running service. - See also: k8s/core/v1/metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: false - default_value: '' - - name: labels - doc: | - A Server-level attribute. - The labels of the long-running service. - See also: k8s/core/v1/metadata.k. - type: - type_str: '{str: str}' - type_category: DICT - dict_type: - key_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - value_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: true - default_value: '' - examples: | - myCustomApp = AppConfiguration { - name = "componentName" - } - doc: '' - source_code_url: '' - ``` - -3.3 Modify all the `doc` fields to the Chinese description. The modified configuration is as follows: - - ```yaml - name: server - relative_path: ./server.k - schemas: - - name: Server - doc: | - Server 模型定义了采用 Kubernetes 最佳实践的持续运行的服务的通用配置接口 - attributes: - - name: workloadType - doc: | - workloadType 属性定义了服务的类型,是服务级别的属性。合法的取值有:Deployment, CafeDeployment. - 另请查看:k8s/core/v1/workload_metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - default_value: '"Deployment"' - is_optional: false - - name: name - doc: | - name 为服务的名称,是服务级别的属性。 - 另请查看:k8s/core/v1/metadata.k. - type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: false - default_value: '' - - name: labels - doc: | - labels 为服务的标签,是服务级别的属性。 - 另请查看:k8s/core/v1/metadata.k. - type: - type_str: '{str: str}' - type_category: DICT - dict_type: - key_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - value_type: - type_str: str - type_category: BUILTIN - builtin_type: STRING - is_optional: true - default_value: '' - examples: | - myCustomApp = AppConfiguration { - name = "componentName" - } - doc: '' - source_code_url: '' - ``` - -3.4 Based on the modified i18n configuration, generate documents in localized languages. Execute the following command to output the Chinese document `kcl_doc/doc_server_zh_cn.md`. The commands and the contents of the generated documents are as follows: - -```text -kcl-doc generate server.k --i18n-locale zh_cn --format Markdown -``` - -````markdown -# server - -## Schema Server - -Server 模型定义了采用 Kubernetes 最佳实践的持续运行的服务的通用配置接口 - -### Attributes - -| Name and Description | Type | Default Value | Required | -| -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | ------------- | ------------ | -| **workloadType**
workloadType 属性定义了服务的类型,是服务级别的属性。合法的取值有:Deployment, CafeDeployment.
另请查看:k8s/core/v1/workload_metadata.k. | str | "Deployment" | **required** | -| **name**
name 为服务的名称,是服务级别的属性。
另请查看:k8s/core/v1/metadata.k. | str | Undefined | **required** | -| **labels**
labels 为服务的标签,是服务级别的属性。
另请查看:k8s/core/v1/metadata.k. | {str: str} | Undefined | optional | - -### Examples - -``` -myCustomApp = AppConfiguration { - name = "componentName" -} -``` - - -```` - -## 4. Appendix - -### 1. Concept of reST - -For documents in reST format, paragraphs and indentation are important, new paragraphs are marked with blank lines, and indentation is the indentation indicated in the output. Font styles can be expressed as follows: - -- \*Italic\* -- \*\*Bold\*\* -- \`\`Monospaced\`\` - -Refer to [reST](https://docutils.sourceforge.io/rst.html) for more information. diff --git a/versioned_docs/version-0.6.0/tools/cli/kcl/fmt.md b/versioned_docs/version-0.6.0/tools/cli/kcl/fmt.md deleted file mode 100644 index dc41e94c..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/kcl/fmt.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Format - -The KCL Format tool supports reformatting KCL files to the standard code style. This article demonstrates the KCL code style and how to use the KCL Format tool. - -## Code Style - -The KCL Format tool modifies the files according to the KCL code style: [Style Guide for KCL Code](/docs/reference/lang/spec/codestyle) - -## How to use - -- Formatting Single File - -```text -kcl-fmt your_config.k -``` - -- Formatting multiple files - -```text -kcl-fmt your_config_path -R -``` - -- Args - - `-R|--recursive` Whether to recursively traverse subfolder - - `-w|--fmt-output` Whether to output to STDOUT, without `-w` indicates in-place modification. - -## Display of formatting files - -- Before formatting - -```py -import math -mixin DeploymentMixin: - service:str ="my-service" -schema DeploymentBase: - name: str - image : str -schema Deployment[replicas] ( DeploymentBase ) : - mixin[DeploymentMixin] - replicas : int = replicas - command: [str ] - labels: {str: str} -deploy = Deployment(replicas = 3){} -``` - -- After formatting - -```py -import math - -mixin DeploymentMixin: - service: str = "my-service" - -schema DeploymentBase: - name: str - image: str - -schema Deployment[replicas](DeploymentBase): - mixin [DeploymentMixin] - replicas: int = replicas - command: [str] - labels: {str:str} - -deploy = Deployment(replicas=3) {} - -``` diff --git a/versioned_docs/version-0.6.0/tools/cli/kcl/index.md b/versioned_docs/version-0.6.0/tools/cli/kcl/index.md deleted file mode 100644 index b750f652..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/kcl/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# KCL Language Tools - -KCL not only provides the command `kcl` to compile and execute configuration programs but also provides fmt, lint, test, vet, docgen and other supporting tools. diff --git a/versioned_docs/version-0.6.0/tools/cli/kcl/lint.md b/versioned_docs/version-0.6.0/tools/cli/kcl/lint.md deleted file mode 100644 index ec75e422..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/kcl/lint.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Lint - -The KCL Lint tool supports checking some warning-level defects in KCL code and supports multiple output formats. This document shows how to use the KCL Lint tool. - -## Example - -### Project Structure - -```text -. -└── Test - └── kcl.mod - └── a.k - └── b.k - └── dir - └── c.k - └── test.k -``` - -`a.k`, `b.k`, `c.k` and `test.k` are the kcl file to be checked. - -Args: - -```shell -kcl-lint your_config.k -``` - -or - -```shell -kcl-lint your_config_path -``` - -## KCL Lint Tool - -### Args - -```shell -USAGE: - kcl-lint [OPTIONS] [--] [input]... - -ARGS: - ... Sets the input file to use - -OPTIONS: - --emit_warning Emit warning message - -h, --help Print help information - -v, --verbose Print test information verbosely - -Y, --setting ... Sets the input file to use -``` - -- input: the path of a single `*.k` file or directory to be checked. Support the absolute path or relative path of the current directory. diff --git a/versioned_docs/version-0.6.0/tools/cli/kcl/overview.md b/versioned_docs/version-0.6.0/tools/cli/kcl/overview.md deleted file mode 100644 index b1354b8c..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/kcl/overview.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Overview - -KCL toolchain is a toolset of KCL language, which aims to improve the efficiency of batch migration, writing, compiling and running of KCL. - -| | Name | Description | -| ---------- | ------------------------ | ------------------------------------------------------------------- | -| Main Tools | **kcl** | Provide support for KCL in coding, compiling and running | -| | kcl-test | Coming soon | -| | kcl-lint | Check code style for KCL | -| | kcl-doc | Parses the KCL code and generate documents | -| | kcl-fmt | Format the kcl code | -| | kcl-vet | Validate data files such as JSON and YAML using KCL | -| IDE Plugin | IntelliJ IDEA KCL plugin | Provide assistance for KCL in coding and compiling on IntelliJ IDEA | -| | VS Code KCL plugin | Provide assistance for KCL in coding and compiling on VS Code | - -## KCL Tool - -### Args - -```shell -USAGE: - kcl [OPTIONS] [--] [input]... - -Arguments: - [input]... Specify the input files to run - -Options: - -o, --output - Specify the YAML output file path - -Y, --setting ... - Specify the input setting file - -v, --verbose... - Print test information verbosely - -n, --disable_none - Disable dumping None values - -r, --strict_range_check - Do perform strict numeric range checks - -d, --debug - Run in debug mode (for developers only) - -k, --sort_keys - Sort result keys - -D, --argument ... - Specify the top-level argument - -S, --path_selector ... - Specify the path selector - -O, --overrides ... - Specify the configuration override path and value - --target - Specify the target type - -E, --external ... - Mapping of package name and path where the package is located - -h, --help - Print help -``` diff --git a/versioned_docs/version-0.6.0/tools/cli/kcl/test.md b/versioned_docs/version-0.6.0/tools/cli/kcl/test.md deleted file mode 100644 index 4f99e53d..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/kcl/test.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Test Tool - -Coming soon. diff --git a/versioned_docs/version-0.6.0/tools/cli/kcl/vet.md b/versioned_docs/version-0.6.0/tools/cli/kcl/vet.md deleted file mode 100644 index d2f2220e..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/kcl/vet.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Validation - -## Intro - -The KCL Validation tool supports basic configuration data verification capabilities. You can write a KCL schema to verify the type and value of the input JSON/YAML files. - -## How to use - -There is a JSON format file `data.json`: - -```json -{ - "name": "Alice", - "age": 18, - "message": "This is Alice", - "data": { - "id": 1, - "value": "value1" - }, - "labels": { - "key": "value" - }, - "hc": [1, 2, 3] -} -``` - -Build a validated KCL file `schema.k`: - -```py -schema User: - name: str - age: int - message?: str - data: Data - labels: {str:} - hc: [int] - - check: - age > 10 - -schema Data: - id: int - value: str -``` - -Execute the following command: - -```shell -kcl-vet data.json schema.k -``` - -## Specify the schema for validation - -When multiple schema definitions exist in the KCL file, by default, the KCL Validation tool will use the first schema to check. If you need to specify a schema for verification, you can use the `-d|--schema` parameter - -```shell -kcl-vet data.json schema.k -d User -``` - -## Args - -```shell -$ kcl-vet -h -USAGE: - kcl-vet [OPTIONS] [ARGS] - -ARGS: - Validation data file - KCL file - -OPTIONS: - -d, --schema - Iterate through subdirectories recursively - - --format - Validation data file format, support YAML and JSON, default is JSON - - -h, --help - Print help information - - -n, --attribute_name - The attribute name for the data loading -``` diff --git a/versioned_docs/version-0.6.0/tools/cli/openapi/_category_.json b/versioned_docs/version-0.6.0/tools/cli/openapi/_category_.json deleted file mode 100644 index 58e4c68a..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/openapi/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "OpenAPI Tools", - "position": 3 -} diff --git a/versioned_docs/version-0.6.0/tools/cli/openapi/crd-to-kcl.md b/versioned_docs/version-0.6.0/tools/cli/openapi/crd-to-kcl.md deleted file mode 100644 index aafebcd9..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/openapi/crd-to-kcl.md +++ /dev/null @@ -1,118 +0,0 @@ -# CRD to KCL - -To convert from models defined in the Kubernetes CRD file to KCL schema, we could run the following script: - -```shell -kcl-openapi generate model --crd -f ${your_CRD.yaml} -t ${the_kcl_files_output_dir} --skip-validation -``` - -## Example - -- There is the Kubernetes CRD file that we need to convert: `test_crontab_CRD.yaml`: - -```yaml -# Deprecated in v1.16 in favor of apiextensions.k8s.io/v1 -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - # name must match the spec fields below, and be in the form: . - name: crontabs.stable.example.com -spec: - # group name to use for REST API: /apis// - group: stable.example.com - # list of versions supported by this CustomResourceDefinition - versions: - - name: v1 - # Each version can be enabled/disabled by Served flag. - served: true - # One and only one version must be marked as the storage version. - storage: true - # either Namespaced or Cluster - scope: Namespaced - names: - # plural name to be used in the URL: /apis/// - plural: crontabs - # singular name to be used as an alias on the CLI and for display - singular: crontab - # kind is normally the CamelCased singular type. Your resource manifests use this. - kind: CronTab - # shortNames allow shorter string to match your resource on the CLI - shortNames: - - ct - preserveUnknownFields: false - validation: - openAPIV3Schema: - type: object - properties: - spec: - type: object - properties: - cronSpec: - type: string - image: - type: string - replicas: - type: integer -``` - -- The script will be: - -```shell -kcl-openapi generate model -f test_crontab_CRD.yaml -t ~/ --skip-validation --crd -``` - -- Then we can find the generated file here: `~/models/stable_example_com_v1_cron_tab.k` - -```python -""" -This file was generated by the KCL auto-gen tool. DO NOT EDIT. -Editing this file might prove futile when you re-run the KCL auto-gen generate command. -""" -import kusion_kubernetes.apimachinery.apis - - -schema CronTab: - """stable example com v1 cron tab - - Attributes - ---------- - apiVersion : str, default is "stable.example.com/v1", required - APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - kind : str, default is "CronTab", required - Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - metadata : apis.ObjectMeta, default is Undefined, optional - metadata - spec : StableExampleComV1CronTabSpec, default is Undefined, optional - spec - """ - - - apiVersion: "stable.example.com/v1" = "stable.example.com/v1" - - kind: "CronTab" = "CronTab" - - metadata?: apis.ObjectMeta - - spec?: StableExampleComV1CronTabSpec - - -schema StableExampleComV1CronTabSpec: - """stable example com v1 cron tab spec - - Attributes - ---------- - cronSpec : str, default is Undefined, optional - cron spec - image : str, default is Undefined, optional - image - replicas : int, default is Undefined, optional - replicas - """ - - - cronSpec?: str - - image?: str - - replicas?: int -``` diff --git a/versioned_docs/version-0.6.0/tools/cli/openapi/index.md b/versioned_docs/version-0.6.0/tools/cli/openapi/index.md deleted file mode 100644 index 236d6e36..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/openapi/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# OpenAPI Tools - -The KCL OpenAPI tool can not only convert common models but also support CRD and other models. diff --git a/versioned_docs/version-0.6.0/tools/cli/openapi/openapi-to-kcl.md b/versioned_docs/version-0.6.0/tools/cli/openapi/openapi-to-kcl.md deleted file mode 100644 index bef582ec..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/openapi/openapi-to-kcl.md +++ /dev/null @@ -1,64 +0,0 @@ -# OpenAPI to KCL - -To convert from models defined in the OpenAPI spec file to KCL schema, we could run the following script: - -```shell -kcl-openapi generate model -f ${your_open_api_spec.yaml} -t ${the_kcl_files_output_dir} -``` - -For example: - -- There is the OpenAPI spec file that we need to convert: `test_open_api_spec.yaml` - -```yaml -definitions: - v1.TestInt: - type: object - properties: - name: - type: string - format: int-or-string - required: - - name - x-kcl-type: - import: - package: v1.test_int - alias: test_int - type: TestInt -swagger: "2.0" -info: - title: KCL - version: v0.0.2 -paths: {} -``` - -- The script will be: - -```shell -kcl-openapi generate model -f test_open_api_spec.yaml -t ~/ --skip-validation -``` - -- Then we can find the generated file here: `~/models/v1/test_int.k` - -```python -""" -This is the test_int module in v1 package. -This file was generated by the KCL auto-gen tool. DO NOT EDIT. -Editing this file might prove futile when you re-run the KCL auto-gen generate command. -""" - - -schema TestInt: - """v1 test int - - Attributes - ---------- - name : int | str, default is Undefined, required - name - """ - - - name: int | str - - -``` diff --git a/versioned_docs/version-0.6.0/tools/cli/openapi/quick-start.md b/versioned_docs/version-0.6.0/tools/cli/openapi/quick-start.md deleted file mode 100644 index dc67ef5d..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/openapi/quick-start.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Quick Start - -## 1. Install KCLOpenAPI Tool - -The kcl-openapi tool can be installed in following ways: - -- [Quick Start](#quick-start) - - [1. Install KCLOpenAPI Tool](#1-install-kclopenapi-tool) - - [1.1 go install](#11-go-install) - - [1.2 Curl|sh install (MacOS \& Linux)](#12-curlsh-install-macos--linux) - - [1.3 Download from release](#13-download-from-release) - - [1.4 Verify your installation](#14-verify-your-installation) - - [2. Generate KCL Files](#2-generate-kcl-files) - -## 1.1 go install - -```shell -go install kcl-lang.io/kcl-openapi@latest -``` - -## 1.2 Curl|sh install (MacOS & Linux) - -If you don't have go, you can install the CLI with this one-liner: - -```shell -curl -fsSL https://kcl-lang.io/script/install-kcl-openapi.sh | /bin/bash -``` - -## 1.3 Download from release - -```shell -# 1. download the released binary from: -# https://github.com/kcl-lang/kcl-openapi/releases - -# 2. Unzip the package and add the binary location to PATH -export PATH=":$PATH" -``` - -## 1.4 Verify your installation - -```shell -➜ kcl-openapi -v -kcl-openapi 0.5.0 -``` - -## 2. Generate KCL Files - -- [OpenAPI to KCL](../openapi/openapi-to-kcl.md) -- [CRD to KCL](../openapi/crd-to-kcl.md) diff --git a/versioned_docs/version-0.6.0/tools/cli/package-management/_category_.json b/versioned_docs/version-0.6.0/tools/cli/package-management/_category_.json deleted file mode 100644 index 7848e437..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/package-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Package Management Tools", - "position": 4 -} diff --git a/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/1.init.md b/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/1.init.md deleted file mode 100644 index 6a46976a..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/1.init.md +++ /dev/null @@ -1,45 +0,0 @@ -# kpm init - -Init a kcl package. - -## Usage - -```shell -kpm init [options][package_name] -``` - -## Description - -`kpm init` will initialize a kcl package in the current directory. If the package name is not provided, the name of the current directory will be used. - -If the package name is provided, a subdirectory with the name of the package will be created and the package will be initialized in that directory. - -`kpm init` will create `kcl.mod`, `kcl.mod.lock` and `main.k` under the package directory. - -## Options - -### --help, -h - -Show help for `kpm init` command. - -## Examples - -### Init the current directory into a kcl package - -```shell -# create an empty directory -$ mkdir my_package - -# cd into the directory -$ cd my_package - -# init the current directory into a kcl package -$ kpm init -``` - -### Init a kcl package with a name - -```shell -# init a kcl package with a name 'my_package' -kpm init my_package -``` diff --git a/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/10.help.md b/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/10.help.md deleted file mode 100644 index 94c078f5..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/10.help.md +++ /dev/null @@ -1,21 +0,0 @@ -# kpm help - -Print help information for kpm commands. - -## Usage - -```shell -kpm help -``` - -## Description - -`kpm help` will print help information for kpm commands. - -## Examples - -Use `kpm help` to print help information for kpm commands. - -```shell -kpm help -``` diff --git a/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/2.add.md b/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/2.add.md deleted file mode 100644 index 1d2517fb..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/2.add.md +++ /dev/null @@ -1,53 +0,0 @@ -# kpm add - -Add a dependency to a kcl package. - -## Usage - -```shell -kpm add [options][package_reference] -``` - -## Description - -`kpm add` will add a dependency to a kcl package. The dependency can be from a git repository, or a kcl registry. - -`package_reference` is a kcl package reference, looks like `package_name:version`. - -## options - -### --git - -Specify the git url of the dependency from a git repository. - -### --tag - -Specify the tag of the dependency from a git repository. - -### --help, -h - -Show help for `kpm add` command. - -## Examples - -### Add a dependency from kcl registry - -Add kcl dependency named `k8s` to the current package.The version of the dependency will be the latest version. - -```shell -kpm add k8s -``` - -Add kcl dependency named 'k8s' with version 'v1.27.2'. - -```shell -kpm add k8s:v1.27.2 -``` - -### Add a dependency from git repository - -Add kcl dependency named `konfig` with version `v0.1.0` from git repository. - -```shell -kpm add --git https://github.com/awesome-kusion/konfig.git --tag v0.1.0 -``` diff --git a/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/3.pkg.md b/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/3.pkg.md deleted file mode 100644 index 9b4298a5..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/3.pkg.md +++ /dev/null @@ -1,33 +0,0 @@ -# kpm pkg - -Package a kcl package into `*.tar`. - -## Usage - -```shell -kpm pkg [options] -``` - -## Description - -`kpm pkg` will package a kcl package into `*.tar`. - -Option `--target` is required to specify the tar file path of the package. - -## options - -### --target - -Specify the tar file path of the package. - -### --help, -h - -Show help for `kpm pkm` command. - -## Examples - -### Package a kcl package - -```shell -kpm pkg --target /Users/my_package_tar -``` diff --git a/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/4.metadata.md b/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/4.metadata.md deleted file mode 100644 index 3074a8d5..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/4.metadata.md +++ /dev/null @@ -1,41 +0,0 @@ -# kpm metadata - -Print the metadata of a kcl package. - -## Usage - -```shell -kpm metadata [options] -``` - -## Description - -`kpm metadata` will print the metadata of a kcl package. The metadata includes the dependency information of the package. - -`--update` option is used to automatically download the missing dependency packages. - -## options - -### --update - -Automatically download the missing dependency packages. - -### --help, -h - -Show help for `kpm metadata` command. - -## Examples - -### Print the metadata of a kcl package - -Print the metadata of a kcl package. - -```shell -kpm metadata -``` - -Print the metadata of a kcl package and automatically download the missing dependency packages. - -```shell -kpm metadata --update -``` diff --git a/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/5.run.md b/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/5.run.md deleted file mode 100644 index b5001185..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/5.run.md +++ /dev/null @@ -1,69 +0,0 @@ -# kpm run - -Compile a kcl package. - -## Usage - -```shell -kpm run [options][package_source] -``` - -## Description - -`kpm run` will compile a kcl package. - -## options - -### --input - -Specify the entry file path of the package. - -### --tag - -Specify the tag of the package specified by oci url `package_source`. - -### --vendor - -`--vendor` will move the dependency packages into the current packages and automatically download the missing dependency packages. - -### --kcl_args - -`--kcl_args` specifies the arguments passed to the kcl compiler. - -### --help, -h - -Show help for `kpm run` command. - -## Examples - -### compile the current kcl package - -Under the kcl package directory, `kpm run` can be used to compile the current kcl package. - -```shell -kpm run -``` - -### compile a kcl package tar file - -`kpm run` can be used to compile a kcl package tar file. - -```shell -kpm run /Users/demo/my_package.tar -``` - -### compile a kcl package from oci url - -`kpm run` can be used to compile a kcl package from oci url. - -```shell -kpm run --tag 0.0.1 oci://localhost:5001/test/my_package -``` - -### compile a kcl package from oci ref - -`kpm run` can be used to compile a kcl package from oci ref. - -```shell -kpm run test/my_package:0.0.1 -``` diff --git a/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/6.login.md b/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/6.login.md deleted file mode 100644 index 68ca0f1b..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/6.login.md +++ /dev/null @@ -1,68 +0,0 @@ -# kpm login - -Login to the kpm registry. - -## Usage - -```shell -kpm login [options][kpm_registry] -``` - -## Description - -`kpm login` will login the kpm registry. - -## options - -### --username - -Specify the username of the kpm registry. - -### --password - -Specify the password of the kpm registry. - -### --help, -h - -Show help for `kpm login` command. - -## Examples - -### login to a registry with account and password - -```shell -kpm login -u -p -``` - -The output is - -```shell -Login succeeded -``` - -### login to a registry with account, and enter the password interactively - -```shell -kpm login -u -``` - -The output is - -```shell -Password: -Login succeeded -``` - -### login to a registry, and enter the account and password interactively - -```shell -kpm login -``` - -The output is - -```shell -Username: -Password: -Login succeeded -``` diff --git a/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/7.logout.md b/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/7.logout.md deleted file mode 100644 index 6c5d9aec..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/7.logout.md +++ /dev/null @@ -1,27 +0,0 @@ -# kpm logout - -Logout from the kpm registry. - -## Usage - -```shell -kpm logout [options][kpm_registry] -``` - -## Description - -`kpm logout` will logout from the kpm registry. - -## options - -### --help, -h - -Show help for `kpm logout` command. - -## Examples - -### logout from oci registry - -```shell -kpm logout -``` diff --git a/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/8.push.md b/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/8.push.md deleted file mode 100644 index a70c5bc1..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/8.push.md +++ /dev/null @@ -1,46 +0,0 @@ -# kpm push - -Push a package to the kpm registry. - -## Usage - -```shell -kpm push [options][kpm_registry] -``` - -## Description - -`kpm push` will push a package to the kpm registry. - -## options - -### --tar_path - -The path to the tar file to push. - -### --help, -h - -Show help for `kpm push` command. - -## Examples - -### push the current package - -You can use `kpm push` under the kcl package root directory to upload a kcl package to an OCI-based registry. - -```shell -# create a new kcl package. -$ kpm init -# enter the kcl package root directory -$ cd -# push it to an oci registry -$ kpm push -``` - -### push a tar to the registry - -You can also use `kpm push` to upload a tar file to an OCI-based registry. - -```shell -kpm push --tar_path -``` diff --git a/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/9.pull.md b/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/9.pull.md deleted file mode 100644 index b0126bcf..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/9.pull.md +++ /dev/null @@ -1,42 +0,0 @@ -# kpm pull - -Pull a package from the kpm registry. - -## Usage - -```shell -kpm pull [options][package_source] -``` - -## Description - -`kpm pull` will pull a package from the kpm registry. - -## options - -### --tag - -The tag of the package to pull. - -### --help, -h - -Show help for `kpm push` command. - -## Examples - -### pull the package by package name - -You can use `kpm pull` to download a kcl package from the default OCI registry by kcl package name. -`kpm` will download the kcl package from the default OCI registry specified in the configuration file `kpm.json`. - -```shell -kpm pull : -``` - -### pull the package by oci url - -You can download a kcl package from an OCI-based registry url. - -```shell -kpm pull --tag -``` diff --git a/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/_category_.json b/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/_category_.json deleted file mode 100644 index 8c705ed9..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Command Reference", - "position": 4 -} diff --git a/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/index.md b/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/index.md deleted file mode 100644 index ab6cc90c..00000000 --- a/versioned_docs/version-0.6.0/tools/cli/package-management/command-reference/index.md +++ /dev/null @@ -1,36 +0,0 @@ -# kpm - -The kpm cli - -## Usage - -```shell -kpm [arguments]... -``` - -## Description - -`kpm` is a kcl package manager. It is used to install, remove, and update kcl packages. - -## Options - -### --help, -h - -Show help for kpm command - -### --version, -v - -Print the version of kpm - -## Subcommands - -- [kpm init](./1.init.md) - Init a kcl package -- [kpm add](./2.add.md) - Add a dependency to a kcl package -- [kpm pkg](./3.pkg.md) - Package a kcl package into `\*.tar`` -- [kpm metadata](./4.metadata.md) - Print the metadata of a kcl package -- [kpm run](./5.run.md) - Compile a kcl package into yaml -- [kpm login](./6.login.md) - Login to a kcl registry -- [kpm logout](./7.logout.md) - Logout from a kcl registry -- [kpm push](./8.push.md) - Push a kcl package to a registry -- [kpm pull](./9.pull.md) - Pull a kcl package from a registry -- [kpm help](./10.help.md) - print help for kpm command diff --git a/versioned_docs/version-0.6.0/user_docs/concepts/_category_.json b/versioned_docs/version-0.6.0/user_docs/concepts/_category_.json deleted file mode 100644 index d40bb9de..00000000 --- a/versioned_docs/version-0.6.0/user_docs/concepts/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Concepts", - "position": 5 -} diff --git a/versioned_docs/version-0.6.0/user_docs/concepts/concepts.md b/versioned_docs/version-0.6.0/user_docs/concepts/concepts.md deleted file mode 100644 index 627212ad..00000000 --- a/versioned_docs/version-0.6.0/user_docs/concepts/concepts.md +++ /dev/null @@ -1,3 +0,0 @@ -# Concepts - -Learn more about KCL concepts. diff --git a/versioned_docs/version-0.6.0/user_docs/concepts/package-and-module.md b/versioned_docs/version-0.6.0/user_docs/concepts/package-and-module.md deleted file mode 100644 index a36e45c9..00000000 --- a/versioned_docs/version-0.6.0/user_docs/concepts/package-and-module.md +++ /dev/null @@ -1,156 +0,0 @@ -# Module and Package - -This section mainly describes how to organize files in KCL. - -## Overview - -Within a **module**, KCL organizes files grouped by **package**. A package can be defined within a module or be imported externally (through KCL package manager `kpm`). In the latter case, KCL maintains a copy of the package within the module in a dedicated location. - -## Module - -A KCL module contains a configuration laid out in a directory hierarchy. It contains everything that is needed to deterministically determine the outcome of a KCL configuration. The root of this directory is marked by containing a `kcl.mod` directory. The contents of this directory are mostly managed by the kcl tool such as `kpm`, etc. In that sense, `kcl.mod` is analogous to the `.git` directory marking the root directory of a repo, but where its contents are mostly managed by the git tool. Besides, a KCL module is the largest unit of the file organization, has a fixed location of all KCL files and dependencies. - -> Note: The use of a KCL module e.g., `kcl.mod` is optional, but required if one wants to manage, distribute, share and reuse code with a semantic version. - -### Creating a module - -A module can be created by running the following command within the module root: - -```bash -kpm init [module name] -``` - -The module name is **required** if a package within the module needs to import another package within the module. A module can also be created by setting up the `kcl.mod` file manually. - -## Package - -In KCL, a package is usually composed of a "folder" containing KCL files. This folder can be a real disk physical path, or it can be composed of multiple KCL files (usually main package). Different packages are uniquely located by different package paths (such as `kubernetes.core.v1`) - -Within the same module, different packages can be imported from each other through the import statement of relative or absolute path. During the KCL parsing process, the relative import will be replaced by absolute import and the corresponding KCL code will be found through the package path. - -### Relative Import Path - -We can use the operator `.` to realize the relative path import of KCL entry files. - -main.k: - -```python -import .model1 # Current directory module -import ..service # Parent directory -import ...root # Parent of parent directory - -s = service.ImageService {} -m = root.Schema {} -``` - -### Absolute Import Path - -The semantics of `import a.b.c.d` is - -1. If `kcl.mod` not exist, regard the current directory as the package root and search the path `a/b/c/d` from the current directory. -2. If the current directory search fails, search from the root path `ROOT_PATH/a/b/c/d`, else raise an import error. - -The definition of the root path `ROOT_PATH` is the directory corresponding to the `kcl.mod` file from the current directory. - -Code structure: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -### Builtin Package - -KCL has a collection of builtin packages such as `math`, `regex`, etc. To use a builtin package, import it directly and invoke the functions using its qualified identifier. For instance, - -```python -import regex - -image = "nginx:1.14.2" -is_match = regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$") - -``` - -The output YAML is - -```yaml -image: nginx:1.14.2 -is_match: true -``` - -### Plugin Package - - - -KCL also has a collection of plugin packages such as `hello`, `project_context`, etc. To use a plugin package, import it with a `kcl_plugin.` package path prefix and invoke the functions using its qualified identifier. For instance, - -```python -import kcl_plugin.hello - -result = hello.add(1, 1) -``` - -The output YAML is - -```yaml -result: 2 -``` - -### Main Package - -In KCL, the composition of the main package is usually determined by the compiler parameters. This is because the KCL schema and constraints can be split across files in the package, or even organized across directories, considering the convenience of writing and maintaining the configuration in isolated blocks. - -#### Files belonging to a main package - -It is up to the user to decide which configurations and constraints to use using the KCL command line. For example, - -```bash -kcl file1.k file2.k -``` - -Thus, the main package contains two KCL files named `file1.k` and `file2.k`. - -If KCL is told to load the files for a specific directory, for example: - -```bash -kcl ./path/to/package -``` - -It will only look KCL files with `.k` suffix and ignore files with `_` prefix or `_test.k` into the main package. Besides, if the `./path/to/package` contains `kcl.yaml` files, `kcl.yaml` files be ignored. - -In addition, we can set main package files through configuring the command-line compilation setting file (e.g., `kcl.yaml`) as follows: - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k -``` - -```bash -kcl -Y kcl.yaml -``` - -> Note: If we do not specify any input files for KCL, KCL will find the default `kcl.yaml` from the command line execution path to read the input file. Besides, if we tell KCL both the input files and the compilation setting file, KCL will take input files entered by the user as the final value. - -```bash -# Whether the 'files' field is configured in `kcl.yaml` or not, the final value of input files is ["file1.k", "file2.k"] -kcl -Y kcl.yaml file1.k file2.k -``` - -## The relationship and difference between `kcl.mod` and `kcl.yaml` - -First of all, in KCL, `kcl.mod` and `kcl.yaml` are both optional. The difference is that `kcl.mod` determines the root path of the package path and whether a KCL module has the requirement of distribution and reuse, and `kcl.yaml` determines the KCL file composition of the main package. - -Secondly, for a kcl module for external use only, `kcl.yaml` is optional but `kcl.mod` is required, because it needs to declare the KCL version, module version, dependency and other information. - -Finally, for the KCL IDE plug-in, it needs to know the main package information to form a complete compilation process, so it needs to automatically look up the composition of the main package according to the position of the cursor, because no one can specify this information through the KCL command line. The general query logic is to find whether `kcl.yaml` exists. If it is found, the main package consists of the `files` attribute in `kcl.yaml`, and if not found, the main package consists of the current file. The KCL IDE plug-in is selectively aware of the `kcl.mod` file. When the `kcl.mod` file exists, the IDE plug-in reads the corresponding information of all package paths and their real paths in the external dependencies. diff --git a/versioned_docs/version-0.6.0/user_docs/getting-started/_category_.json b/versioned_docs/version-0.6.0/user_docs/getting-started/_category_.json deleted file mode 100644 index 1bf165d4..00000000 --- a/versioned_docs/version-0.6.0/user_docs/getting-started/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Get Started", - "position": 1 -} diff --git a/versioned_docs/version-0.6.0/user_docs/getting-started/index.md b/versioned_docs/version-0.6.0/user_docs/getting-started/index.md deleted file mode 100644 index c50dbaa6..00000000 --- a/versioned_docs/version-0.6.0/user_docs/getting-started/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# Get Started - -Get started include a quick overview of the KCL programming language. diff --git a/versioned_docs/version-0.6.0/user_docs/getting-started/kcl-quick-start.md b/versioned_docs/version-0.6.0/user_docs/getting-started/kcl-quick-start.md deleted file mode 100644 index 2316d9a6..00000000 --- a/versioned_docs/version-0.6.0/user_docs/getting-started/kcl-quick-start.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Quick Start - -KCL is a cloud-native domain configuration and policy language. At the beginning of its design, KCL was inspired by Python3, and at the same time absorbed the conceptual design of declarative and OOP programming paradigms. In this section we will quickly demonstrate the basic features of the KCL language. - -## 1. Hello KCL - -The best way to learn a new language is to write a few small programs, and the same goes for configuring languages. We can write KCL programs just like writing configuration. - -Here is a simple `hello.k`: - -```python -hello = "KCL" -``` - -Set the `hello` attribute to the `"KCL"` string. Then save the code to the `hello.k` file. - -How to execute this program depends on the specific development environment, we first assume that the local macOS or Linux system has installed the `kcl` command (or enter the **Docker** environment test by `docker run --rm -it kcllang/kcl`) and then run the following command: - -```shell -kcl hello.k -``` - -The output is - -```yaml -hello: KCL -``` - -The effect of command line execution is shown as follows: - -![](/img/docs/user_docs/getting-started/hello.gif) - -The output is configuration data in YAML format. Although this program is simple, we can verify the basic usage of the development environment and the `kcl` command line by executing the KCL configuration program to the output. - -## 2. A little more complicated configuration - -In addition to the common key-value pairs, common configuration data also has nested dictionary and list types, and the value basic type includes boolean and numeric types in addition to strings. Here's a slightly more complex `server.k` configuration: - -```python -# This is a KCL document - -title = "KCL Example" - -owner = { - name = "The KCL Authors" - data = "2020-01-02T03:04:05" -} - -database = { - enabled = True - ports = [8000, 8001, 8002] - data = [["delta", "phi"], [3.14]] - temp_targets = {cpu = 79.5, case = 72.0} -} - -servers = [ - {ip = "10.0.0.1", role = "frontend"} - {ip = "10.0.0.2", role = "backend"} -] -``` - -where `#` begins with a line comment. The value of `owner` is a dictionary. The value of the dictionary contains the content in the form of `{}`. The key-value inside the dictionary is similar to the `hello = "KCL"` example. `database` is another dictionary in which the value of the dictionary attribute appears boolean `True`, list `[]` and dictionary `{}`, in which the value of the numeric type also appears in the list and dictionary. The `servers` attribute is a list with dictionaries nested inside the list (dictionaries and lists, as well as the `schema` that will be discussed later, can be nested within each other). - -The YAML output of this configuration is as follows: - -```yaml -$ kcl server.k -title: KCL Example -owner: - name: The KCL Authors - data: '2020-01-02T03:04:05' -database: - enabled: true - ports: - - 8000 - - 8001 - - 8002 - data: - - - delta - - phi - - - 3.14 - temp_targets: - cpu: 79.5 - case: 72.0 -servers: -- ip: 10.0.0.1 - role: frontend -- ip: 10.0.0.2 - role: backend -``` - -## 3. Define the structure of the configuration using KCL schema - -The KCL provides abstract support for attributes with a fixed attribute structure and default value behavior through the `schema` syntax. - -For example, the configuration of `database` in the above example is generally the default value. We can define a structure for the default configuration of the database: - -```python -schema DatabaseConfig: - enabled: bool = True - ports: [int] = [8000, 8001, 8002] - data: [[str|float]] = [["delta", "phi"], [3.14]] - temp_targets: {str: float} = {cpu = 79.5, case = 72.0} -``` - -`enabled` is a boolean type; `ports` is an integer list type; `data` is a list of lists, and the inner list elements are strings or floats; `temp_targets` is a dictionary type, and the attribute value of the dictionary is floating point type. And each attribute of `DatabaseConfig` defines a default value. - -Then pass `database = DatabaseConfig {}` to generate a structure with the same attributes as the default values. We can also modify the default value: - -```python -database = DatabaseConfig { - ports = [2020, 2021] -} -``` - -`schema DatabaseConfig` not only provides default values for attributes, but also adds type information to attributes. Therefore, if we accidentally writes the wrong attribute value type, KCL will give a friendly error prompt, such as the following example where `ports` is wrongly written as a floating point type: - -```python -database = DatabaseConfig { - ports = [1.2, 1.3] -} -``` - -When executed, an error similar to the following will be generated (the displayed file path depends on the local environment): - -```shell -kcl server.k -``` - -The output is - -```shell -error[E2G22]: TypeError - --> /path/to/server.k:8:5 - | -8 | ports = [1.2, 1.3] - | ^ expected [int], got [float(1.2)|float(1.3)] - | - - --> /path/to/server.k:3:5 - | -3 | ports: [int] = [8000, 8001, 8002] - | ^ variable is defined here, its type is [int], but got [float(1.2)|float(1.3)] - | -``` - -Similarly we can encapsulate the attributes of the `servers` section with the following code: - -```python -schema ServerConfig: - ip: str - role: "frontend" | "backend" - -servers = [ - ServerConfig {ip = "10.0.0.1", role = "frontend"} - ServerConfig {ip = "10.0.0.2", role = "backend"} -] -``` - -The attribute `ip` of `ServerConfig` is a string type, and no default value is given. We must manually add the value of the `ip` attribute when generating the `ServerConfig` type attribute, otherwise the KCL will report a missing required attribute error. The `role` attribute is a `"frontend" | "backend"` enumerated string type. - -In addition, `schema` can also combine `check`, `mixin`, optional attributes, inheritance and extension modules to achieve more complex configuration and policy data abstraction, full language details can be found at [here](/docs/reference/lang/tour). diff --git a/versioned_docs/version-0.6.0/user_docs/guides/_category_.json b/versioned_docs/version-0.6.0/user_docs/guides/_category_.json deleted file mode 100644 index 40b1340d..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "User Guide", - "position": 4 -} diff --git a/versioned_docs/version-0.6.0/user_docs/guides/_working-with-terraform/1-overview.md b/versioned_docs/version-0.6.0/user_docs/guides/_working-with-terraform/1-overview.md deleted file mode 100644 index c2ec836d..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/_working-with-terraform/1-overview.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -id: overview -sidebar_label: Overview ---- - -# Overview - -Coming Soon diff --git a/versioned_docs/version-0.6.0/user_docs/guides/_working-with-terraform/2-abstraction.md b/versioned_docs/version-0.6.0/user_docs/guides/_working-with-terraform/2-abstraction.md deleted file mode 100644 index 18a25571..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/_working-with-terraform/2-abstraction.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -id: abstraction -sidebar_label: Abstraction ---- - -# Abstract Your Terraform Modules - -Coming Soon diff --git a/versioned_docs/version-0.6.0/user_docs/guides/_working-with-terraform/3-coverter.md b/versioned_docs/version-0.6.0/user_docs/guides/_working-with-terraform/3-coverter.md deleted file mode 100644 index 1dc975bb..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/_working-with-terraform/3-coverter.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -id: converter -sidebar_label: Converter ---- - -# Convert Your Terraform Provider Schema to KCL Schema - -Coming Soon diff --git a/versioned_docs/version-0.6.0/user_docs/guides/_working-with-terraform/_category_.json b/versioned_docs/version-0.6.0/user_docs/guides/_working-with-terraform/_category_.json deleted file mode 100644 index 3e72e820..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/_working-with-terraform/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Terraform", - "position": 13 -} diff --git a/versioned_docs/version-0.6.0/user_docs/guides/abstraction.md b/versioned_docs/version-0.6.0/user_docs/guides/abstraction.md deleted file mode 100644 index cec40e2c..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/abstraction.md +++ /dev/null @@ -1,151 +0,0 @@ ---- -title: "Abstraction" -sidebar_position: 3 ---- - -## Introduction - -Abstraction refers to a simplified representation of an entity, typically used in computing. It allows for the concealment of specific details while presenting the most relevant information to the programmer. Each abstraction is tailored to suit a specific need, and can greatly enhance the usability of a given entity. In the context of KCL, abstraction can make code easier to understand and maintain, while also simplifying the user interface. - -It should be noted that code abstraction is not meant to reduce code size, but rather to improve maintainability and extendability. During the process of abstracting code, factors such as reusability, readability, and scalability should be taken into consideration, and the code should be optimized as needed. - -The values of the good abstraction - -1. Provides distinct focal points for better comprehension for specific identities, roles, and scenarios. -2. Shields lower-level details to avoid potential errors. -3. Enhances user-friendliness and automation with better portability and good APIs. - -KCL may not assess the rationality of a user's abstraction, but it offers technical solutions to facilitate the process. - -## Use KCL for Abstraction - -**Now, let's begin to abstract Docker Compose and Kubernetes models into an application config.** - -Application centric development allows developers to focus on their workload's architecture rather than the tech stack in the target environment, infrastructure or platform. We define our application once with the `App` schema and then use the KCL CLI to translate it to multiple platforms, such as `Docker Compose` or `Kubernetes` with different versions. - -`Docker Compose` is a tool for defining and running multi-container Docker applications. With Docker Compose, you can define your application's services, networks, and volumes in a single file, and then use it to start and stop your application as a single unit. Docker Compose simplifies the process of running complex, multi-container applications by handling the details of networking, storage, and other infrastructure concerns. - -`Kubernetes manifests` are YAML files that define Kubernetes objects such as Pods, Deployments, and Services. Manifests provide a declarative way to define the desired state of your application, including the number of replicas, the image to use, and the network configuration. Kubernetes uses the manifests to create and manage the resources needed to deploy and run your application. - -Here are some references to learn more about Docker Compose and Kubernetes manifests: - -- [Docker Compose documentation](https://docs.docker.com/compose/) -- [Kubernetes manifest documentation](https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/) - -The application model aims to reduce developer toil and cognitive load by only having to define a single KCL file that works across multiple platforms, and it is designed to be applied to multiple environments to reduce the amount of configuration. Now, let's learn how to do this. - -### 0. Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/abstraction -``` - -We can run the following command to show the config. - -```bash -cat main.k -``` - -The output is - -```python -import .app - -app.App { - name = "app" - containers.nginx = { - image = "nginx" - ports = [{containerPort = 80}] - } - service.ports = [{ port = 80 }] -} -``` - -In the above code, we defined a configuration using the `App` schema, where we configured an `nginx` container and configured it with an `80` service port. - -Besides, KCL allows developers to define the resources required for their applications in a declarative manner and is tied to a platform such as Docker Compose or Kubernetes manifests and allows to generate a platform-specific configuration file such as `docker-compose.yaml` or a Kubernetes `manifests.yaml` file. Next, let's generate the corresponding configuration. - -### 2. Transform the Application Config into Docker Compose Config - -If we want to transform the application config into the docker compose config, we can run the command simply: - -```shell -kcl main.k docker_compose_render.k -``` - -The output is - -```yaml -services: - app: - image: nginx - ports: - - published: 80 - target: 80 - protocol: TCP -``` - -### 3. Transform the Application Config into Kubernetes Deployment and Service Manifests - -If we want to transform the application config into the Kubernetes manifests, we can run the command simply: - -```shell -kcl main.k kubernetes_render.k -``` - -The output is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: app - labels: - app: app -spec: - replicas: 1 - selector: - matchLabels: - app: app - template: - metadata: - labels: - app: app - spec: - containers: - - name: nginx - image: nginx - ports: - - protocol: TCP - containerPort: 80 ---- -apiVersion: v1 -kind: Service -metadata: - name: app - labels: - app: app -spec: - selector: - app: app - ports: - - port: 80 - protocol: TCP -``` - -Look, it's so simple. If you want to learn more information about the application model, you can refer to [here](https://github.com/kcl-lang/kcl-lang.io/tree/main/examples/abstraction). - -## Summary - -Through the use of KCL, we are able to separate the abstraction and implementation details of a model, allowing for the abstract model to be mapped to various infrastructures or platforms. This is achieved through flexible switching between different implementations and the combination of compilation, which shields configuration differences and ultimately reduces the cognitive burden. - -## Further Information - -In addition to manually maintaining the configuration, we can also use KCL APIs to integrate **automatic configuration changes** into our applications. For specific instructions, please refer to [here](/docs/user_docs/guides/automation). diff --git a/versioned_docs/version-0.6.0/user_docs/guides/automation.md b/versioned_docs/version-0.6.0/user_docs/guides/automation.md deleted file mode 100644 index 561b3302..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/automation.md +++ /dev/null @@ -1,189 +0,0 @@ ---- -title: "Automation" -sidebar_position: 6 ---- - -## Introduction - -KCL provides many automation related capabilities, mainly including tools and multilingual APIs. Via `package_identifier : key_identifier` mode, KCL supports the indexing of any configured key value, thus completing the addition, deletion, modification and query of any key value. For example, the following figure shows that we can directly execute the following command to modify the image. The code diff before and after modification is also shown in the figure. - -![](/img/blog/2022-09-15-declarative-config-overview/14-kcl-image-update.png) - -In addition, the automation capability of KCL can be realized and integrated into CI/CD. - -![](/img/blog/2022-09-15-declarative-config-overview/15-kcl-automation.png) - -## Use KCL for Automation - -### 0. Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/automation -``` - -We can run the following command to show the config. - -```bash -cat main.k -``` - -The output is - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "app" - replicas = 1 - labels.key = "value" -} -``` - -We can run the command to get the config - -```bash -kcl main.k -``` - -The output is - -```yaml -app: - name: app - replicas: 1 - labels: - app: app - key: value -``` - -### 2. Use KCL CLI for Automation - -KCL allows us to directly modify the values in the configuration model through the KCL CLI `-O|--overrides` parameter. The parameter contains three parts e.g., `pkg`, `identifier`, `attribute` and `override_value`. - -```bash -kcl main.k -O override_spec -``` - -- `override_spec` represents a unified representation of the configuration model fields and values that need to be modified - -```bash -override_spec: [[pkgpath] ":"] identifier ("=" value | "-") -``` - -- `pkgpath`: indicates the package path where the identifier needs to be modified, usually in the form of `a.b.c`. For the main package,`pkgpath` is represented as `__ main__`. When omitted or not written, it indicates the main package -- `identifier` indicates the identifier that needs to modify the configuration, usually in the form of `a.b.c`. -- `value` indicates the value of the configuration that needs to be modified, which can be any legal KCL expression, such as number/string literal value, list/dict/schema expression, etc. -- `=` denotes modifying of the value of the identifier. -- `-` denotes deleting of the identifier. - -#### Override Configuration - -Run the command to update the application name. - -```bash -kcl main.k -O app.name='new_app' -``` - -The output is - -```yaml -app: - name: new_app - replicas: 1 - labels: - app: new_app - key: value -``` - -We can see the `name` attribute of the `app` config is updated to `new_app`. - -Besides, when we use KCL CLI `-d` argument, the KCL file will be modified to the following content at the same time. - -```bash -kcl main.k -O app.name='new_app' -d -``` - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "new_app" - replicas = 1 - labels: {key = "value"} -} -``` - -#### Delete Configuration - -Run the command to delete the `key` attribute of `labels`. - -```bash -kcl main.k -O app.labels.key- -``` - -The output is - -```yaml -app: - name: app - replicas: 1 - labels: - app: app -``` - -### 3. Use KCL API for Automation - -In addition, we can automatically modify the configuration attributes through the [multilingual API](/docs/reference/xlang-api/overview). - -Take the RestAPI as an example. The RestAPI service can be started in the following way: - -```bash -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -The service can then be requested via the POST protocol: - -```bash -curl -X POST http://127.0.0.1:2021/api:protorpc/KclvmService.OverrideFile -H 'content-type: accept/json' -d '{ - "file": "main.k", - "specs": ["app.name=\"nginx\""] -}' -``` - -After the service call is completed, main.k will be modified as follows: - -```python -schema App: - """The application model.""" - name: str - replicas: int - labels?: {str:str} = {app = name} - -app: App { - name = "nginx" - replicas = 1 - labels: { - "key" = "value" - } -} -``` - -## Summary - -The document introduces the automation capabilities of KCL, including tools and multilingual APIs. It supports indexing of any configured key value, allowing for the addition, deletion, modification, and querying of any key value. It can also be integrated into CI/CD. The document provides an example of using KCL to automate configuration management, including using the KCL CLI to override and delete configurations, and using the KCL API to modify configuration attributes. For more information about KCL automation and Override API, please refer to [here](/docs/reference/lang/tour#kcl-cli-variable-override). diff --git a/versioned_docs/version-0.6.0/user_docs/guides/ci-integration/1-github-actions.md b/versioned_docs/version-0.6.0/user_docs/guides/ci-integration/1-github-actions.md deleted file mode 100644 index c4a09c6e..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/ci-integration/1-github-actions.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -id: github-actions -sidebar_label: Github Actions ---- - -# Github Actions Integration - -## Introduction - -In the GitOps section, we have introduced how to integrate KCL with GitOps. In this section, we will continue to provide sample solutions for KCL and CI integrations. We hope to implement the end-to-end application development process by using containers, Continuous Integration (CI) for generation, and GitOps for Continuous Deployment (CD). In this scheme, we use a **Flask application** and **Github Actions** as examples. - -> Note: You can use any containerized application and different CI systems such as **Gitlab CI**, **Jenkins CI**, etc. in this solution. - -The overall workflow is as follows: - -- Develop application code and submit it to the GitHub repository to trigger CI. -- GitHub Actions generate container images from application code and push them to the `docker.io` container registry. -- GitHub Actions automatically synchronizes and updates the KCL manifest deployment file based on the version of the container image in the docker.io container registry. - -## Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -## How to - -### 1. Get the Example - -We put the application source code and infrastructure deployment code in different repos, which can be maintained by different roles to achieve the separation of concerns. - -- Get the application code - -```shell -git clone https://github.com/kcl-lang/flask-demo.git/ -cd flask-demo -``` - -This is a web application written in Python. We can use the `Dockerfile` in the application directory to generate a container image of this application, and also use Github CI to automatically build a image named `flask_demo`, the CI configuration is as follows - -```yaml -# This is a basic workflow to help you get started with Actions - -name: CI - -# Controls when the workflow will run -on: - # Triggers the workflow on push or pull request events but only for the main branch - push: - branches: [main] - pull_request: - branches: [main] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "build" - build: - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - - - name: Docker Login - uses: docker/login-action@v1.10.0 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - logout: true - - # Runs a set of commands using the runners shell - - name: build image - run: | - make image - docker tag flask_demo:latest ${{ secrets.DOCKER_USERNAME }}/flask_demo:${{ github.sha }} - docker push ${{ secrets.DOCKER_USERNAME }}/flask_demo:${{ github.sha }} - - # Trigger KCL manifest - - name: Trigger CI - uses: InformaticsMatters/trigger-ci-action@1.0.1 - with: - ci-owner: kcl-lang - ci-repository: flask-demo-kcl-manifests - ci-ref: refs/heads/main - ci-user: kcl-bot - ci-user-token: ${{ secrets.DEPLOY_ACCESS_TOKEN }} - ci-name: CI - ci-inputs: >- - image=${{ secrets.DOCKER_USERNAME }}/flask_demo - sha-tag=${{ github.sha }} -``` - -We need the workflow in the source code repository to automatically trigger the workflow in the deployment manifest repository. At this point, we need to create a `secrets.DEPLOY_ACCESS_TOKEN` with Github CI operation permissions and **Docker Hub** image push account information `secrets.DOCKER_USERNAME` and `secrets.DOCKER_PASSWORD` can be configured in the `Secrets and variables` settings of the Github, as shown in the following figure - -![](/img/docs/user_docs/guides/ci-integration/github-secrets.png) - -### 2. Commit the Application Code - -After submitting in the `flask-demo` repository, Github will automatically build a container image and push it to the Docker hub. It will also then trigger the Action of the `flask-demo-kcl-manifest` repository and modify the image value in the deployment manifest repository through [KCL Automation API](/docs/user_docs/guides/automation). Now let's create a submission in the `flask-demo` repository, and we can see that the code submission triggers the Github CI process for the application repository. - -![](/img/docs/user_docs/guides/ci-integration/app-ci.png) - -### 3. Configuration Automatic Update - -After the Github CI process in the application repository is completed, an automatic update configuration CI will be triggered in the repository where the KCL configuration is stored and submitted to the main branch of the `flask-demo-kcl-manifests` repository. The commit information is as follows - -![](/img/docs/user_docs/guides/ci-integration/image-auto-update.png) - -- We can obtain the deployment manifest source code for compilation and validation - -```shell -git clone https://github.com/kcl-lang/flask-demo-kcl-manifests.git/ -cd flask-demo-kcl-manifests -git checkout main && git pull && kcl -``` - -The output YAML is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - replicas: 1 - selector: - matchLabels: - app: flask_demo - template: - metadata: - labels: - app: flask_demo - spec: - containers: - - name: flask_demo - image: "kcllang/flask_demo:6428cff4309afc8c1c40ad180bb9cfd82546be3e" - ports: - - protocol: TCP - containerPort: 5000 ---- -apiVersion: v1 -kind: Service -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - type: NodePort - selector: - app: flask_demo - ports: - - port: 5000 - protocol: TCP - targetPort: 5000 -``` - -From the above configuration, it can be seen that the image of the resource is indeed automatically updated to the newly constructed image value. In addition, we can also use the **Argo CD KCL plugin** to automatically synchronize data from the Git repository and deploy the application to the Kubernetes cluster. - -## Summary - -By integrating KCL and Github CI, we can integrate the container build and delivery workflow by automatically updating the image values in the configuration, in order to achieve end-to-end application development process and improve R&D deployment efficiency. diff --git a/versioned_docs/version-0.6.0/user_docs/guides/ci-integration/2-gitlab-ci.md b/versioned_docs/version-0.6.0/user_docs/guides/ci-integration/2-gitlab-ci.md deleted file mode 100644 index 124e9bd9..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/ci-integration/2-gitlab-ci.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -id: gitlab-ci -sidebar_label: Gitlab CI ---- - -# Gitlab CI Integration - -## Introduction - -In the GitOps section, we have introduced how to integrate KCL with GitOps. In this section, we will continue to provide sample solutions for KCL and CI integrations. We hope to implement the end-to-end application development process by using containers, Continuous Integration (CI) for generation, and GitOps for Continuous Deployment (CD). In this scheme, we use a **Flask application** and **Gitlab CI** as examples. - -> Note: You can use any containerized application and different CI systems such as **Github Actions**, **Jenkins CI**, etc. in this solution. - -The overall workflow is as follows: - -- Develop application code and submit it to the Gitlab repository to trigger CI. -- Gitlab generate container images from application code and push them to the `docker.io` container registry. -- Gitlab CI automatically synchronizes and updates the KCL manifest deployment file based on the version of the container image in the docker.io container registry. - -## Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -## How to - -We put the application source code and infrastructure deployment code in different repos, which can be maintained by different roles to achieve the separation of concerns. - -### 1. Get the Example - -- Get the application code - -```shell -git clone https://gitlab.com/kcl-lang/flask-demo.git/ -cd flask-demo -``` - -This is a web application written in Python. We can use the `Dockerfile` in the application directory to generate a container image of this application, and also use Gitlab CI to automatically build a image named `flask_demo`, the CI configuration is as follows - -```yaml -stages: - - publish - - deploy - -publish: - stage: publish - image: - name: cnych/kaniko-executor:v0.22.0 - entrypoint: [""] - script: - - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json - - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile ./Dockerfile --destination $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA - only: - - main - -deploy: - stage: deploy - image: cnych/kustomize:v1.0 - before_script: - - git remote set-url origin https://gitlab.com/kcl-lang/flask-demo - - git config --global user.email "gitlab@git.local" - - git config --global user.name "GitLab CI/CD" - # Install KCL - - wget -q https://kcl-lang.io/script/install.sh -O - | /bin/bash - script: - - git checkout -B main - - cd deployment - # Image auto update - - /usr/local/kclvm/bin/kcl -d -O config.containers.flask_demo.image="$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" - - git commit -am '[skip ci] image update to $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA' - - git push origin main - only: - - main -``` - -We need the workflow in the source code repository to automatically trigger the workflow in the deployment manifest repository. At this point, we need to config `Settings -> CI/CD -> Variables` including `CI_REGISTRY`, `CI_REGISTRY_IMAGE`, `CI_REGISTRY_USER`, `CI_REGISTRY_PASSWORD`, `CI_USERNAME` and `CI_PASSWORD` and update application code to trigger automation build and deploy. - -![](/img/docs/user_docs/guides/ci-integration/gitlab-ci-variables.jpg) - -### 2. Commit the Application Code - -After submitting in the `flask-demo` repository, Gitlab will automatically build a container image and push it to the Docker hub. It will also then trigger the Action of the `flask-demo-kcl-manifest` repository and modify the image value in the deployment manifest repository through [KCL Automation API](/docs/user_docs/guides/automation). Now let's create a submission in the `flask-demo` repository, and we can see that the code submission triggers the Gitlab CI process for the application repository `Build -> Pipelines` page. - -### 3. Configuration Automatic Update - -After the Gitlab CI process in the application repository is completed, an automatic update configuration CI will be triggered in the repository where the KCL configuration is stored and submitted to the main branch of the `flask-demo` repository. - -- We can obtain the deployment manifest source code for compilation and validation - -```shell -git checkout main && git pull && cd deploy && kcl -``` - -The output YAML is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - replicas: 1 - selector: - matchLabels: - app: flask_demo - template: - metadata: - labels: - app: flask_demo - spec: - containers: - - name: flask_demo - image: "kcllang/flask_demo:6428cff4309afc8c1c40ad180bb9cfd82546be3e" - ports: - - protocol: TCP - containerPort: 5000 ---- -apiVersion: v1 -kind: Service -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - type: NodePort - selector: - app: flask_demo - ports: - - port: 5000 - protocol: TCP - targetPort: 5000 -``` - -From the above configuration, it can be seen that the image of the resource is indeed automatically updated to the newly constructed image value. In addition, we can also use the **Argo CD KCL plugin** to automatically synchronize data from the Git repository and deploy the application to the Kubernetes cluster. - -## Summary - -By integrating KCL and Gitlab CI, we can integrate the container build and delivery workflow by automatically updating the image values in the configuration, in order to achieve end-to-end application development process and improve R&D deployment efficiency. diff --git a/versioned_docs/version-0.6.0/user_docs/guides/ci-integration/_3-jenkins-ci.md b/versioned_docs/version-0.6.0/user_docs/guides/ci-integration/_3-jenkins-ci.md deleted file mode 100644 index f85d231f..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/ci-integration/_3-jenkins-ci.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -id: github-ci -sidebar_label: Github CI ---- - -Coming Soon - -## Introduction - -## How to - -## Summary diff --git a/versioned_docs/version-0.6.0/user_docs/guides/ci-integration/_category_.json b/versioned_docs/version-0.6.0/user_docs/guides/ci-integration/_category_.json deleted file mode 100644 index 3145ed7f..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/ci-integration/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "CI Integration", - "position": 12 -} \ No newline at end of file diff --git a/versioned_docs/version-0.6.0/user_docs/guides/configuration.md b/versioned_docs/version-0.6.0/user_docs/guides/configuration.md deleted file mode 100644 index e6060815..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/configuration.md +++ /dev/null @@ -1,129 +0,0 @@ ---- -title: "Configuration" -sidebar_position: 1 ---- - -## Introduction - -Configuration is a vital aspect of software systems that are constantly in flux due to evolving business requirements, infrastructure demands, and other factors. Often, changing these systems' behavior quickly can be challenging, especially when doing so requires a costly and time-consuming reconstruction and redeployment process. In such cases, making changes to the business code may not be sufficient. Fortunately, the configuration provides a low-overhead way to modify system functions. For instance, many developers write JSON or YAML files to configure their systems. - -We can store the static configuration in JSON and YAML files as needed. Moreover, the configuration can also be stored in a high-level language that allows for more flexible configuration. This language can be coded, rendered, and statically configured. KCL is a configuration language that offers such functionality. Developers can write KCL code to generate JSON/YAML and other configurations. - -## Use KCL for Configuration - -KCL's core features are its modeling and constraint capabilities, and its basic functions revolve around these two key elements. Additionally, KCL follows a user-centric configuration concept when designing its basic functions. Configuration code has requirements for configuration data constraints, such as type constraints and required/optional constraints on configuration attributes, range constraints, and immutability constraints. These are also some of the core issues that KCL is committed to resolving. - -Now that we have an understanding of KCL's capabilities, let's explore how to use it to generate configurations. - -### 0. Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. Get the Example - -Firstly, let's get the example. - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/configuration -``` - -We can run the following command to show the config. - -```bash -cat nginx.k -``` - -The output is - -```python -schema Nginx: - """Schema for Nginx configuration files""" - http: Http - -schema Http: - server: Server - -schema Server: - listen: int | str # The attribute `listen` can be int type or a string type. - location?: Location # Optional, but must be non-empty when specified - -schema Location: - root: str - index: str - -nginx = Nginx { - http.server = { - listen = 80 - location = { - root = "/var/www/html" - index = "index.html" - } - } -} -``` - -### 2. Generate YAML using KCL - -Run the following command - -```bash -kcl nginx.k -``` - -We can get the output YAML - -```yaml -nginx: - http: - server: - listen: 80 - location: - root: /var/www/html - index: index.html -``` - -### 3. Configuration with Dynamic Parameters - -Besides, we can dynamically receive external parameters through the KCL builtin function `option`. For example, for the following KCL file (db.k), we can use the KCL command line `-D` flag to receive an external dynamic parameter. - -```python -env: str = option("env") or "dev" # The attribute `env` has a default value "den" -database: str = option("database") -hosts = { - dev = "postgres.dev" - stage = "postgres.stage" - prod = "postgres.prod" -} -dbConfig = { - host = hosts[env] - database = database - port = "2023" - conn = "postgres://${host}:${port}/${database}" -} -``` - -```bash -# Use the `-D` flag to input external parameters. -kcl db.k -D database="foo" -``` - -The output is - -```yaml -env: dev -database: foo -hosts: - dev: postgres.dev - stage: postgres.stage - prod: postgres.prod -dbConfig: - host: postgres.dev - database: foo - port: "2023" - conn: "postgres://postgres.dev:2023/foo" -``` - -## Summary - -By using KCL, we can generate low-level data configurations. For different situations, we set dynamic parameters through the `-D` flag to meet the scene requirements. For more KCL features, please refer to [here](/docs/reference/lang/tour). diff --git a/versioned_docs/version-0.6.0/user_docs/guides/data-integration.md b/versioned_docs/version-0.6.0/user_docs/guides/data-integration.md deleted file mode 100644 index c05b2e7b..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/data-integration.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: "Data Integration" -sidebar_position: 4 ---- - -## Introduction - -In KCL, we can not only compile and output the configuration code written by KCL into YAML format data, but also directly embed JSON/YAML and other data into the KCL language. - -## Use KCL for Data Integration - -### 0. Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/data-integration -``` - -### 2. YAML Integration - -We can run the following command to show the YAML integration config. - -```bash -cat yaml.k -``` - -```python -import yaml - -schema Server: - ports: [int] - -server: Server = yaml.decode("""\ -ports: -- 80 -- 8080 -""") -server_yaml = yaml.encode({ - ports = [80, 8080] -}) -``` - -In the above code, we use the built-in `yaml` module of KCL and its `yaml.decode` function directly integrates YAML data, and uses the `Server` schema to directly verify the integrated YAML data. In addition, we can use `yaml.encode` to serialize YAML data. We can obtain the configuration output through the following command: - -```shell -kcl yaml.k -``` - -The output is - -```yaml -server: - ports: - - 80 - - 8080 -server_yaml: | - ports: - - 80 - - 8080 -``` - -### 3. JSON Integration - -Similarly, for JSON data, we can use `json.encode` and `json.decode` function performs data integration in the same way. - -We can run the following command to show the JSON integration config. - -```bash -cat json.k -``` - -```python -import json - -schema Server: - ports: [int] - -server: Server = json.decode('{"ports": [80, 8080]}') -server_json = json.encode({ - ports = [80, 8080] -}) -``` - -The output of the execution command is: - -```shell -kcl json.k -``` - -```yaml -server: - ports: - - 80 - - 8080 -server_json: '{"ports": [80, 8080]}' -``` - -## Summary - -This document introduces how to perform data integration in KCL, using the built-in yaml and json modules to directly integrate YAML and JSON data into the KCL language, and verify and serialize it using the corresponding decoding and encoding functions. diff --git a/versioned_docs/version-0.6.0/user_docs/guides/gitops/1-quick-start.md b/versioned_docs/version-0.6.0/user_docs/guides/gitops/1-quick-start.md deleted file mode 100644 index 04570df1..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/gitops/1-quick-start.md +++ /dev/null @@ -1,163 +0,0 @@ ---- -id: gitops-quick-start -sidebar_label: Quick Start ---- - -# Quick Start - -## Introduction - -### What is GitOps - -GitOps is a modern way to do continuous delivery. Its core idea is to have a Git repository which contains environmental and application configurations. An automated process is also needed for sync the config to cluster. - -By changing the files in repository, developers can apply the applications automatically. The benefits of applying GitOps include: - -- Increased productivity. Continuous delivery can speed up the time of deployment. -- Lower the barrier for developer to deploy. By pushing code instead of container configuration, developers can easily deploy Kubernetes without knowing its internal implementation. -- Trace the change records. Managing the cluster with Git makes every change traceable, enhancing the audit trail. -- Recover the cluster with Git's rollback and branch. - -### GitOps with KCL - -Benefits of Using KCL and ArgoCD Together: - -- KCL can help us **simplify complex Kubernetes deployment configuration files**, reduce the error rate of manually writing YAML files, and improve code readability and maintainability. -- ArgoCD can **automate** the deployment of Kubernetes applications, achieve continuous deployment, and provide comprehensive monitoring and control functions. -- By combining KCL and ArgoCD, deployment efficiency can be improved, errors reduced, and management and monitoring of Kubernetes applications strengthened. -- The combination of KCL and ArgoCD can also help us achieve **Infrastructure as Code (IaC)**, simplify application deployment and management, and better implement DevOps principles. - -With GitOps, developer and operation teams can manage application deployment and configuration by modifying KCL code and generating YAML files. The GitOps toolchain will automatically synchronize the changes to the Kubernetes cluster, enabling continuous deployment and ensuring consistency. If there are issues, the GitOps toolchain can be used to quickly rollback. - -## Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -## How to - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/gitops -``` - -We can run the following command to show the config. - -```bash -cat config/main.k -``` - -The output is - -```python -import .app - -config = app.App { - name = "kcl-guestbook-ui" - containers.guestbook = { - image = "gcr.io/heptio-images/ks-guestbook-demo:0.2" - ports = [{containerPort = 80}] - } - service.ports = [{ port = 80 }] - service.type = "LoadBalancer" -} -``` - -In the above code, we defined a configuration using the `App` schema, where we configured an `gcr.io/heptio-images/ks-guestbook-demo:0.2` container and configured it with an `80` service port. - -### 2. Install Kubernetes and GitOps Tool - -#### Setup Kubernetes Cluster and ArgoCD Controllers - -- Install [K3d](https://github.com/k3d-io/k3d) to create a default cluster. - -```bash -k3d cluster create mycluster -``` - -- Install [ArgoCD](https://github.com/argoproj/argo-cd/releases/). - -```bash -kubectl create namespace argocd -kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml -``` - -- Enable ArgoCD KCL Plugin - -Write the patch YAML configuration file and update the ArgoCD configuration: - -```bash -kubectl apply -f ./install/kcl-cmp.yaml -``` - -After completing the first step, ArgoCD will recognize the KCL plugin, but the KCL plugin has not been loaded into the ArgoCD image. To implement configuration drift detection, we have to tune the Deployment of argocd-repo-server. - -```bash -kubectl -n argocd patch deploy/argocd-repo-server -p "$(cat ./install/patch-argocd-repo-server.yaml)" -``` - -Wait for the init container to complete execution (Running). - -```bash -kubectl get pod -n argocd -l app.kubernetes.io/name=argocd-repo-server -``` - -- To access the ArgoCD web UI - -```bash -kubectl port-forward svc/argocd-server -n argocd 8080:443 -``` - -- Open a browser and go to: `https://localhost:8080` - -- The username is "admin" and password get be obtained from the following command: - -```bash -kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d -``` - -#### Setup ArgoCD CLI - -- Install [ArgoCD CLI](https://github.com/argoproj/argo-cd/releases) - -Use "admin" and password to login to ArgoCD - -```bash -argocd login localhost:8080 -``` - -Create ArgoCD Application - -```bash -argocd app create guestbook \ ---repo https://github.com/kcl-lang/kcl-lang.io \ ---path examples/gitops/config \ ---dest-namespace default \ ---dest-server https://kubernetes.default.svc \ ---config-management-plugin kcl-v1.0 -``` - -If you are using a private repository, you need to configure the private repository access with private key credentials before executing the create command. - -Please refer [Private Repositories](https://argo-cd.readthedocs.io/en/stable/user-guide/private-repositories/#ssh-private-key-credential) for more details. - -After successfully creating, you can see the following output: - -```bash -application 'guestbook' created -``` - -Through the ArgoCD UI, you can see that the created applications have not been synchronized yet. Here, you can manually synchronize or set automatic synchronization. - -![](/img/docs/user_docs/guides/gitops/argocd-kcl-app.jpg) - -For more information on synchronization strategies, see [Sync Options](https://argo-cd.readthedocs.io/en/stable/user-guide/sync-options/) - -![](/img/docs/user_docs/guides/gitops/argocd-kcl-app-dashboard.jpg) - -## Summary - -With GitOps, you can easily manage your applications and configuration in your Kubernetes cluster with KCL, ensuring that your applications are always in the desired state. diff --git a/versioned_docs/version-0.6.0/user_docs/guides/gitops/_category_.json b/versioned_docs/version-0.6.0/user_docs/guides/gitops/_category_.json deleted file mode 100644 index 29a73c67..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/gitops/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "GitOps", - "position": 11 -} \ No newline at end of file diff --git a/versioned_docs/version-0.6.0/user_docs/guides/index.md b/versioned_docs/version-0.6.0/user_docs/guides/index.md deleted file mode 100644 index cd3d4522..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/index.md +++ /dev/null @@ -1 +0,0 @@ -# User Guide diff --git a/versioned_docs/version-0.6.0/user_docs/guides/package-management/1-overview.md b/versioned_docs/version-0.6.0/user_docs/guides/package-management/1-overview.md deleted file mode 100644 index cffccc67..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/package-management/1-overview.md +++ /dev/null @@ -1,3 +0,0 @@ -# Overview - -KCL manages packages through the package management tool [kpm](https://github.com/kcl-lang/kpm). diff --git a/versioned_docs/version-0.6.0/user_docs/guides/package-management/2-installation.md b/versioned_docs/version-0.6.0/user_docs/guides/package-management/2-installation.md deleted file mode 100644 index 11d1da5d..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/package-management/2-installation.md +++ /dev/null @@ -1,55 +0,0 @@ -# Installation - -## Install `kpm` - -Before installing and using kpm, ensure that KCL has been installed successfully. - -[How to install KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### Go install - -You can download kpm via go install. - -```shell -go install kcl-lang.io/kpm@latest -``` - -### Download from GITHUB release page - -You can get `kpm` from the [kpm github release](https://github.com/kcl-lang/kpm/releases) and set the `kpm` binary path to the environment variable PATH. - -```shell -# KPM_INSTALLATION_PATH is the path of the `kpm` binary. -export PATH=$KPM_INSTALLATION_PATH:$PATH -``` - -Use the following command to ensure that you install `kpm` successfully. - -```shell -kpm --help -``` - -If you get the following output, you have successfully installed `kpm` and you can proceed to the following steps. - -```shell -NAME: - kpm - kpm is a kcl package manager - -USAGE: - kpm [arguments]... - -COMMANDS: - init initialize new module in current directory - add add new dependency - pkg package a kcl package into tar - metadata output the resolved dependencies of a package - run compile kcl package. - login login to a registry - logout logout from a registry - push push kcl package to OCI registry. - pull pull kcl package from OCI registry. - help, h Shows a list of commands or help for one command - -GLOBAL OPTIONS: - --help, -h show help -``` diff --git a/versioned_docs/version-0.6.0/user_docs/guides/package-management/3-quick-start.md b/versioned_docs/version-0.6.0/user_docs/guides/package-management/3-quick-start.md deleted file mode 100644 index 689e9530..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/package-management/3-quick-start.md +++ /dev/null @@ -1,112 +0,0 @@ -# Quick Start - -## 0. Prerequisite - -- Install [kpm](https://kcl-lang.io/docs/user_docs/guides/package-management/installation) - -## 1. Init an Empty KCL Package - -Create a new kcl package named `my_package`. And after we have created the package `my_package`, we need to go inside the package by `cd my_package` to complete the following operations. - -```shell -kpm init my_package && cd my_package -``` - -![kpm_init](/img/docs/user_docs/guides/package-management/gifs/kpm_init.gif) - -`kpm` will create two kcl package configuration files: `kcl.mod` and `kcl.mod.lock` in the directory where you executed the command. - -```shell -- my_package - |- kcl.mod - |- kcl.mod.lock - |- # You can write your kcl program directly in this directory. -``` - -`kcl.mod.lock` is the file generated by `kpm` to fix the dependency version. Do not modify this file manually. - -`kpm` initializes `kcl.mod` for an empty project as shown below: - -```shell -[package] -name = "my_package" -edition = "0.0.1" -version = "0.0.1" -``` - -## 2. Add a Dependency from OCI Registry - -You can then add a dependency to the current kcl package using the `kpm add` command - -As shown below, taking the example of adding a package dependency named `k8s`, the version of the package is `1.27.2`. - -```shell -kpm add k8s:1.27.2 -``` - -![kpm_add_k8s](/img/docs/user_docs/guides/package-management/gifs/kpm_add_k8s.gif) - -You can see that `kpm` adds the dependency you just added to kcl.mod. - -```shell -[package] -name = "my_package" -edition = "0.0.1" -version = "0.0.1" - -[dependencies] -k8s = "1.27.2" # The dependency 'k8s' with version '1.27.2' -``` - -### Write a kcl program that uses the content in `k8s` - -Create the `main.k` file in the current package. - -```shell -- my_package - |- kcl.mod - |- kcl.mod.lock - |- main.k # Your KCL program. -``` - -And write the following into the `main.k` file. - -```kcl -# Import and use the contents of the external dependency 'k8s'. -import k8s.api.core.v1 as k8core - -k8core.Pod { - metadata.name = "web-app" - spec.containers = [{ - name = "main-container" - image = "nginx" - ports = [{containerPort = 80}] - }] -} - -``` - -## 3. Run the KCL Code - -In the `my_package` directory, you can use `kpm` to compile the `main.k` file you just wrote. - -```shell -kpm run -``` - -The output is - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: web-app -spec: - containers: - - image: nginx - name: main-container - ports: - - containerPort: 80 -``` - -![kpm_run](/img/docs/user_docs/guides/package-management/gifs/kpm_run.gif) diff --git a/versioned_docs/version-0.6.0/user_docs/guides/package-management/4-how-to/_category_.json b/versioned_docs/version-0.6.0/user_docs/guides/package-management/4-how-to/_category_.json deleted file mode 100644 index e3409c62..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/package-management/4-how-to/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "How to", - "position": 4 -} diff --git a/versioned_docs/version-0.6.0/user_docs/guides/package-management/_category_.json b/versioned_docs/version-0.6.0/user_docs/guides/package-management/_category_.json deleted file mode 100644 index 1211443e..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/package-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Package Management Tools", - "position": 7 -} diff --git a/versioned_docs/version-0.6.0/user_docs/guides/schema-definition.md b/versioned_docs/version-0.6.0/user_docs/guides/schema-definition.md deleted file mode 100644 index ecb118ac..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/schema-definition.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -title: "Schema Definition" -sidebar_position: 3 ---- - -## Introduction - -The core scenario of KCL is write configurations and constraints. and a core feature of KCL is **modeling**. The keyword `schema` in KCL can be used to define structures and constraints, such as attribute types, default values, range check, and various other constraints. In addition, structures defined with KCL schema can be used in turn to verify implementation, validate input (JSON, YAML and other structured data) or generate code (multilingual structures, OpenAPI, and so on). - -## Use KCL for Defining Structures and Constraints - -### 0. Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/definition -``` - -We can run the following command to show the config. - -```bash -cat main.k -``` - -The output is - -```python -import .app_module # A relative path import - -app: app_module.App { - domainType = "Standard" - containerPort = 80 - volumes = [ - { - mountPath = "/tmp" - } - ] - services = [ - { - clusterIP = "None" - $type = "ClusterIP" - } - ] -} -``` - -We put the `app` model into a separate `app_module.k`, then we can use the `import` keyword in `main.k` for modular management, such as the following file structure - -``` -. -├── app_module.k -└── main.k -``` - -The content of `app_module.k` is - -```python -schema App: - domainType: "Standard" | "Customized" | "Global" - containerPort: int - volumes: [Volume] - services: [Service] - - check: - 1 <= containerPort <= 65535 - -schema Service: - clusterIP: str - $type: str - - check: - clusterIP == "None" if $type == "ClusterIP" - -schema Volume: - container: str = "*" # The default value of `container` is "*" - mountPath: str - - check: - mountPath not in ["/", "/boot", "/home", "dev", "/etc", "/root"] -``` - -In the above file, we use the `schema` keyword to define three models `App`, `Service` and `Volume`. The `App` model has four attributes `domainType`, `containerPort`, `volumes` and `services`, where - -- The type of `domainType` is a string literal union type, similar to an "enumeration", which means that the value of `domainType` can only take one of `"Standard"`, `"Customized"` and `"Global"`. -- The type of `containerPort` is an integer (`int`). In addition, we use the `check` keyword to define its value range from 1 to 65535. -- The type of `services` is `Service` schema list type, and we use `?` to mark it as an optional attribute. -- The type of `volumes` is a `Volume` schema list type, and we use `?` to mark it as an optional attribute. - -We can get the YAML output of the `app` instance by using the following command line - -```shell -kcl main.k -``` - -The output is - -```yaml -app: - domainType: Standard - containerPort: 80 - volumes: - - container: "*" - mountPath: /tmp - services: - - clusterIP: None - type: ClusterIP -``` - -### 2. Output Configuration - -We can still get the YAML output of the `app` instance by using the following command line - -```shell -kcl main.k -``` - -The output is - -```yaml -app: - domainType: Standard - containerPort: 80 - volumes: - - container: "*" - mountPath: /tmp - services: - - clusterIP: None - type: ClusterIP -``` - -## Summary - -KCL is a language for defining configurations and constraints, with a core feature of modeling using the schema keyword. This allows for the definition of structures with attributes, default values, range checks, and other constraints. Structures defined using KCL schema can be used to validate data, or generate code. The example demonstrates how to define models using schema, import them for modular management, and output the YAML configuration of an instance of the defined structure using the kcl command. diff --git a/versioned_docs/version-0.6.0/user_docs/guides/secret-management/1-vault.md b/versioned_docs/version-0.6.0/user_docs/guides/secret-management/1-vault.md deleted file mode 100644 index 6da58286..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/secret-management/1-vault.md +++ /dev/null @@ -1,142 +0,0 @@ ---- -id: vault -sidebar_label: Vault ---- - -# Vault - -## Introduction - -This guide will show you that KCL solves the secret management problem by integrating [Vault](https://developer.hashicorp.com/vault) and [Vals](https://github.com/helmfile/vals). - -## Prerequisites - -- Install [KCL](/docs/user_docs/getting-started/install) -- Prepare a [Kubernetes Cluster](https://kubernetes.io/) -- Install [Vault](https://developer.hashicorp.com/vault/downloads) -- Install [Vals](https://github.com/helmfile/vals) - -## How to - -### 1. Get the Example - -We put the application source code and infrastructure deployment code in different repos, which can be maintained by different roles to achieve the separation of concerns. - -- Get the application code - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/secret-management/vault -``` - -- Show the config - -```shell -cat main.k -``` - -The output is - -```python -# Secret Management using Vault and Vals - -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" - annotations: { - "secret-store": "vault" - # Valid format: - # "ref+vault://PATH/TO/KV_BACKEND#/KEY" - "foo": "ref+vault://secret/foo#/foo" - "bar": "ref+vault://secret/bar#/bar" - } -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -The main.k file extends the configuration of the Nginx application and customizes annotations. Among them, the value of annotation `foo` and `bar` follow secret reference format (`ref+vault://PATH/TO/KV_BACKEND#/KEY`): - -- `ref+vault`: indicates that this is a secret reference, and the external storage service is `Vault`. -- `PATH/TO/KV_BACKEND`: specifies the path where a secret is stored. -- `KEY`: specifies the key to reading secret. - -The complete format is concatenated using a style similar to URI expressions, which can retrieve a secret stored externally. - -### 2. Pre-store Secrets - -Start the Vault Server - -```shell -vault server -dev -export VAULT_ADDR='http://127.0.0.1:8200' -# Note: Replace with your token -export VAULT_TOKEN=yourtoken -``` - -After Vault is started in development mode and unpacked, secrets are pre-stored, and the path and keys are consistent with `main.k`: - -```shell -vault kv put secret/foo foo=foo -vault kv put secret/bar bar=bar -``` - -### 3. Deploy Configuration - -Using the following command to apply the deployment manifest. - -```shell -kcl main.k | vals eval -f - | kubectl apply -f - -``` - -The expect output is - -```shell -deployment.apps/nginx created -``` - -### 4. Verify Secrets - -Next, verify that the secrets have been retrieved from Vault and replace the values of annotations of Nginx: - -- Verify the `foo` annotation - -```shell -kubectl get deploy nginx -o yaml | grep 'foo:' -``` - -The output is - -```yaml -foo: foo -``` - -- Verify the `bar` annotation - -```shell -kubectl get deploy nginx -o yaml | grep 'bar:' -``` - -The output is - -```yaml -bar: bar -``` - -So far, we have retrieved the secrets hosted in `Vault` and put them into use. - -## Summary - -This guide introduces how KCL solves the secret management by integrating Vault and Vals. By following these steps, we can retrieve the secrets hosted in Vault and utilize them. diff --git a/versioned_docs/version-0.6.0/user_docs/guides/secret-management/_category_.json b/versioned_docs/version-0.6.0/user_docs/guides/secret-management/_category_.json deleted file mode 100644 index c57bb30e..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/secret-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Secret Management", - "position": 13 -} diff --git a/versioned_docs/version-0.6.0/user_docs/guides/validation.md b/versioned_docs/version-0.6.0/user_docs/guides/validation.md deleted file mode 100644 index f589d7fa..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/validation.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: "Validation" -sidebar_position: 2 ---- - -## Introduction - -Validation is the process of verifying that data is accurate, reliable, and meets certain requirements or constraints. This includes checking the data for completeness, consistency, accuracy, and relevance. Data validation is performed to ensure that the data is fit for its intended purpose and that it can be used effectively and efficiently. - -We can use KCL and its vet tools to manually or automatically perform data validation to ensure data consistency. - -## Use KCL for Validation - -In addition to using KCL code to generate configuration formats such as JSON/YAML, KCL also supports format validation of JSON/YAML data. As a configuration language, KCL covers almost all features of [OpenAPI](https://www.openapis.org/). - -In KCL, a structure definition can be used to validate configuration data. At the same time, it supports user-defined constraint rules through the check block, and writes validation expressions in the schema to check and validate the attributes defined by the schema. It is very clear and simple to check whether the input JSON/YAML satisfies the corresponding schema structure definition and constraints. - -### 0. Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. Get the Example - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/validation -``` - -We can run the following command to show the config. - -```bash -cat schema.k -``` - -```python -schema User: - name: str - age: int - message?: str - data: Data - labels: {str:} - hc: [int] - - check: - age > 10, "age must > 10" - -schema Data: - id: int - value: str -``` - -In the schema, we can use the `check` keyword to write the validation rules of every schema attribute. Each line in the check block corresponds to a conditional expression. When the condition is satisfied, the validation is successful. The conditional expression can be followed by `, "check error message"` to indicate the message to be displayed when the check fails. - -To sum up, the validation kinds supported in KCL schema are: - -| Kind | Method | -| ----------------- | ----------------------------------------------------------------------------------------- | -| Range | Using comparison operators such as `<`, `>` | -| Regex | Using methods such as `match` from the `regex` system module | -| Length | Using the `len` built-in function to get the length of a variable of type `list/dict/str` | -| Enum | Using literal union types | -| Optional/Required | Using optional/required attributes of schema | -| Condition | Using the check if conditional expression | - -### 2. Validate the Data - -There is a JSON format file `data.json`: - -```json -{ - "name": "Alice", - "age": 18, - "message": "This is Alice", - "data": { - "id": 1, - "value": "value1" - }, - "labels": { - "key": "value" - }, - "hc": [1, 2, 3] -} -``` - -Execute the following command: - -```bash -kcl-vet data.json schema.k -``` - -## Summary - -KCL is a configuration language that supports data validation through its structure definition and user-defined constraint rules. Validation kinds supported in KCL schema include range, regex, length, enum, optional/required, and condition. To validate data, a schema is defined with validation rules written using the check keyword, and the data is validated using the validation tool or a visualization product built on top of it. - -## Further Information - -The improvement of KCL validation capabilities will gradually focus on the "static" aspect, that is, at compile time, combined with the ability of formal validation, it can directly analyze whether the data meets the constraints, whether the constraints conflict with each other, etc., and can be exposed in real-time through the IDE. - -We also expect that KCL models and constraints can be managed as a package (this package has only KCL files). For example, the Kubernetes models and constraints can be used out of the box. Users can generate configurations or verify existing configurations, and can simply extend the models and constraints users want through KCL inheritance. diff --git a/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md b/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md deleted file mode 100644 index ea65e2f1..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md +++ /dev/null @@ -1,249 +0,0 @@ ---- -title: "Generate Kubernetes Manifests" -sidebar_position: 2 ---- - -## Introduction - -When we manage the Kubernetes resources, we often maintain it by hand, or use Helm and Kustomize tools to maintain our YAML configurations or configuration templates, and then apply the resources to the cluster through kubectl tools. However, as a "YAML engineer", maintaining YAML configuration every day is undoubtedly trivial and boring, and prone to errors. For example as follows: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: ... # Omit -spec: - selector: - matchlabels: - cell: RZ00A - replicas: 2 - template: - metadata: ... # Omit - spec: - tolerations: - - effect: NoSchedules - key: is-over-quota - operator: Equal - value: 'true' - containers: - - name: test-app - image: images.example/app:v1 # Wrong ident - resources: - limits: - cpu: 2 # Wrong type. The type of cpu should be str - memory: 4Gi - # Field missing: ephemeral-storage - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: is-over-quota - operator: In - values: - - 'true' -``` - -- The structured data in YAML is untyped and lacks validation methods, so the validity of all data cannot be checked immediately. -- YAML has poor programming ability. It is easy to write incorrect indents and has no common code organization methods such as logical judgment. It is easy to write a large number of repeated configurations and difficult to maintain. -- The design of Kubernetes is complex, and it is difficult for users to understand all the details, such as the `toleration` and `affinity` fields in the above configuration. If users do not understand the scheduling logic, it may be wrongly omitted or superfluous added. - -Therefore, KCL expects to solve the following problems in Kubernetes YAML resource management: - -- Use **production level high-performance programming language** to **write code** to improve the flexibility of configuration, such as conditional statements, loops, functions, package management and other features to improve the ability of configuration reuse. -- Improve the ability of **configuration semantic verification** at the code level, such as optional/required fields, types, ranges, and other configuration checks. -- Provide **the ability to write, combine and abstract configuration blocks**, such as structure definition, structure inheritance, constraint definition, etc. - -## Prerequisite - -First, you can visit the [KCL Quick Start](/docs/user_docs/getting-started/kcl-quick-start) to download and install KCL according to the instructions, and then prepare a [Kubernetes](https://kubernetes.io/) environment. - -## Quick Start - -### 1. Generate Kubernetes Resource - -We can write the following KCL code and name it `main.k`. KCL is inspired by Python. Its basic syntax is very close to Python, which is easy to learn. The configuration mode is simple, `k [: T] = v`, where `k` denotes the configured attribute name, `v` denotes the configured attribute value and `: T` denotes an optional type annotation. - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -In the above KCL code, we declare the `apiVersion`, `kind`, `metadata`, `spec` and other variables of a Kubernetes `Deployment` resource, and assign the corresponding contents respectively. In particular, we will assign `metadata.labels` fields are reused in `spec.selector.matchLabels` and `spec.template.metadata.labels` field. It can be seen that, compared with YAML, the data structure defined by KCL is more compact, and configuration reuse can be realized by defining local variables. - -We can get a Kubernetes YAML file by executing the following command line - -```bash -kcl main.k -``` - -The output is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -Of course, we can use KCL together with kubectl and other tools. Let's execute the following commands and see the result: - -```shell -kcl main.k | kubectl apply -f - -``` - -The output is - -```shell -deployment.apps/nginx-deployment configured -``` - -It can be seen from the command line that it is completely consistent with the deployment experience of using YAML configuration and kubectl application directly. - -Check the deployment status through kubectl - -```shell -kubectl get deploy -``` - -The output is - -```shell -NAME READY UP-TO-DATE AVAILABLE AGE -nginx-deployment 3/3 3 3 15s -``` - -### 2. Write Code to Manage Kubernetes resources - -When publishing Kubernetes resources, we often encounter scenarios where configuration parameters need to be dynamically specified. For example, different environments need to set different `image` field values to generate resources in different environments. For this scenario, we can dynamically receive external parameters through KCL conditional statements and `option` functions. Based on the above example, we can adjust the configuration parameters according to different environments. For example, for the following code, we wrote a conditional statement and entered a dynamic parameter named `env`. - -```python -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" if option("env") == "prod" else "${metadata.name}:latest" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -Use the KCL command line `-D` flag to receive an external dynamic parameter: - -```bash -kcl main.k -D env=prod -``` - -The output is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -The `image=metadata.name+": 1.14.2" if option ("env")=="prod" else metadata.name + ": latest"` in the above code snippet means that when the value of the dynamic parameter `env` is set to `prod`, the value of the image field is `nginx: 1.14.2`; otherwise, it is' nginx: latest'. Therefore, we can set env to different values as required to obtain Kubernetes resources with different contents. - -KCL also supports maintaining the dynamic parameters of the option function in the configuration file, such as writing the `kcl.yaml` file. - -```yaml -kcl_options: - - key: env - value: prod -``` - -The same YAML output can be obtained by using the following command line to simplify the input process of KCL dynamic parameters. - -```bash -kcl main.k -Y kcl.yaml -``` - -The output is: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## Summary - -KCL can be used to generate and manage Kubernetes resources, addressing the limitations of managing YAML configurations, such as a lack of validation methods and poor programming capabilities. It can also dynamically receive external parameters through conditional statements and option functions, allowing configuration parameters to be adjusted according to different environments. In addition, KCL can be used in conjunction with other tools such as kubectl to apply configuration to the cluster. diff --git a/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md b/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md deleted file mode 100644 index 17918b29..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: "Kubectl KCL Plugin" -sidebar_position: 1 ---- - -## Introduction - -[Kubectl](https://kubernetes.io/docs/reference/kubectl/) is a command line tool for communicating with a Kubernetes cluster's control plane, using the Kubernetes API. You can use the `Kubectl-KCL-Plugin` to - -- Edit the YAML configuration in a hook way to separate data and logic for the Kubernetes manifests management. -- For multi-environment and multi-tenant scenarios, you can maintain these configurations gracefully rather than simply copy and paste. -- Validate all KRM resources using the KCL schema. - -## Prerequisites - -- Install [Kubectl](https://github.com/kubernetes/kubectl) -- Install [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=krm-kcl` only to `Deployment` resources in the helm chart. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/kubectl-kcl.git/ -cd ./kubectl-kcl/examples/ -``` - -### 2. Test and Run - -Run the KCL code via the `Kubectl KCL Plugin`. - -```bash -kubectl kcl run -f ./kcl-run.yaml -``` - -The output yaml is - -```yaml -apiVersion: config.kubernetes.io/v1 -kind: ResourceList -items: - - apiVersion: apps/v1 - kind: Deployment - metadata: - annotations: - managed-by: krm-kcl - labels: - app: nginx - name: nginx-deployment - spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - image: "nginx:1.14.2" - name: nginx - ports: - - containerPort: 80 - - apiVersion: v1 - kind: Service - metadata: - name: test - spec: - ports: - - port: 80 - protocol: TCP - targetPort: 9376 - selector: - app: MyApp -functionConfig: - # kcl-fn-config.yaml - apiVersion: krm.kcl.dev/v1alpha1 - kind: KCLRun - metadata: - # EDIT THE SOURCE! - # This should be your KCL code which preloads the `ResourceList` to `option("resource_list") - spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "krm-kcl"}} for resource in option("resource_list").items] -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Kubectl KCL Plugin](https://github.com/kcl-lang/kubectl-kcl) diff --git a/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md b/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md deleted file mode 100644 index 01897f37..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: "Helm KCL Plugin" -sidebar_position: 2 ---- - -## Introduction - -[Helm](https://github.com/helm/helm) is a tool for managing Charts. Charts are packages of pre-configured Kubernetes resources. You can use the `Helm-KCL-Plugin` to - -- Edit the helm charts in a hook way to separate data and logic for the Kubernetes manifests management. -- For multi-environment and multi-tenant scenarios, you can maintain these configurations gracefully rather than simply copy and paste. -- Validate all KRM resources using the KCL schema. - -## Prerequisites - -- Install [Helm](https://github.com/helm/helm) -- Install [Helm KCL Plugin](https://github.com/kcl-lang/helm-kcl) - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=helm-kcl-plugin` only to `Deployment` resources in the helm chart. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/helm-kcl.git/ -cd ./helm-kcl/examples/workload-charts-with-kcl -``` - -### 2. Test and Run - -Run the KCL code via the `Helm KCL Plugin`. - -```bash -helm kcl template --file ./kcl-run.yaml -``` - -The output yaml is - -```yaml -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: workload - app.kubernetes.io/version: 0.1.0 - helm.sh/chart: workload-0.1.0 - name: workload -spec: - ports: - - name: www - port: 80 - protocol: TCP - targetPort: 80 - selector: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - type: ClusterIP ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: workload - app.kubernetes.io/version: 0.1.0 - helm.sh/chart: workload-0.1.0 - name: workload - annotations: - managed-by: helm-kcl-plugin -spec: - selector: - matchLabels: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - template: - metadata: - labels: - app.kubernetes.io/instance: workload - app.kubernetes.io/name: workload - spec: - containers: - - image: nginx:alpine - name: frontend -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Helm KCL Plugin](https://github.com/kcl-lang/helm-kcl) diff --git a/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md b/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md deleted file mode 100644 index ae0c7a07..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: "Kustomize KCL Plugin" -sidebar_position: 3 ---- - -## Introduction - -[Kustomize](https://github.com/kubernetes-sigs/kustomize) lets you customize raw, template-free YAML files for multiple purposes, leaving the original YAML untouched and usable as is. - -KCL can be used to create functions to mutate and/or validate the YAML Kubernetes Resource Model (KRM) input/output format, and we provide Kustomize KCL functions to simplify the function authoring process. - -## Prerequisites - -- Install [kustomize](https://github.com/kubernetes-sigs/kustomize) -- Install [Docker](https://www.docker.com/) - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=kustomize-kcl` only to Deployment resources. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/kustomize-kcl.git -cd ./kustomize-kcl/examples/set-annotation/ -``` - -### 2. Test and Run - -```bash -kustomize fn run ./local-resource/ --dry-run -``` - -The output YAML is - -```yaml -apiVersion: krm.kcl.dev/v1alpha1 -kind: KCLRun -metadata: - name: set-annotation - annotations: - config.kubernetes.io/function: | - container: - image: docker.io/kcllang/kustomize-kcl:v0.2.0 - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml -# EDIT THE SOURCE! -# This should be your KCL code which preloads the `ResourceList` to `option("resource_list") -spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "kustomize-kcl"}} for resource in option("resource_list").items] ---- -apiVersion: v1 -kind: Service -metadata: - name: test - annotations: - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml -spec: - selector: - app: MyApp - ports: - - protocol: TCP - port: 80 - targetPort: 9376 ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx - annotations: - config.kubernetes.io/path: example-use.yaml - internal.config.kubernetes.io/path: example-use.yaml - managed-by: kustomize-kcl -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [Kustomize KCL Plugin](https://github.com/kcl-lang/kustomize-kcl) diff --git a/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md b/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md deleted file mode 100644 index 3a029bdd..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: "KPT KCL SDK" -sidebar_position: 4 ---- - -## Introduction - -[kpt](https://github.com/GoogleContainerTools/kpt) is a package-centric toolchain that enables a configuration authoring, automation, and delivery experience, which simplifies managing Kubernetes platforms and KRM-driven infrastructure (e.g., Config Connector, Crossplane) at scale by manipulating declarative Configuration as Data for automating Kubernetes configuration editing including transforming and validating. - -KCL can be used to create functions to transform and/or validate the YAML Kubernetes Resource Model (KRM) input/output format, but we provide KPT KCL SDKs to simplify the function authoring process. - -## Prerequisites - -- Install [kpt](https://github.com/GoogleContainerTools/kpt) -- Install [Docker](https://www.docker.com/) - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=kpt` only to Deployment resources. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/kpt-kcl-sdk.git/ -cd ./kpt-kcl-sdk/get-started/set-annotation -``` - -### 2. Show the KRM - -```bash -kpt pkg tree -``` - -The output is - -```bash -set-annotation -├── [kcl-fn-config.yaml] KCLRun set-annotation -└── data - ├── [resources.yaml] Deployment nginx-deployment - └── [resources.yaml] Service test -``` - -### 3. Show and Update the KCL `FunctionConfig` - -```bash -cat ./kcl-fn-config.yaml -``` - -The output is - -```yaml -# kcl-fn-config.yaml -apiVersion: krm.kcl.dev/v1alpha1 -kind: KCLRun -metadata: # kpt-merge: /set-annotation - name: set-annotation -spec: - # EDIT THE SOURCE! - # This should be your KCL code which preloads the `ResourceList` to `option("resource_list")` - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "kpt"}} for resource in option("resource_list").items] -``` - -### 4. Test and Run - -Run the KCL code via kpt - -```bash -kpt fn eval ./data -i docker.io/kcllang/kpt-kcl:v0.2.0 --fn-config kcl-fn-config.yaml - -# Verify that the annotation is added to the `Deployment` resource and the other resource `Service` -# does not have this annotation. -cat ./data/resources.yaml | grep annotations -A1 -B0 -``` - -The output is - -```bash - annotations: - managed-by: kpt -``` - -It can be seen that we have indeed added the annotation `managed-by=kpt`. - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [KPT KCL SDK](https://github.com/kcl-lang/kpt-kcl-sdk) diff --git a/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md b/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md deleted file mode 100644 index 03d34ec8..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: "Helmfile KCL Plugin" -sidebar_position: 5 ---- - -## Introduction - -[Helmfile](https://github.com/helmfile/helmfile) is a declarative spec for deploying helm charts. It lets you... - -- Keep a directory of chart value files and maintain changes in version control. -- Apply CI/CD to configuration changes. -- Periodically sync to avoid skew in environments. - -KCL can be used to create functions to mutate and/or validate the YAML Kubernetes Resource Model (KRM) input/output format, and we provide Kustomize KCL functions to simplify the function authoring process. - -## Prerequisites - -- Install [helmfile](https://github.com/helmfile/helmfile) -- Prepare a Kubernetes cluster - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=helmfile-kcl` only to Deployment resources. - -### 1. Get the Example - -```bash -git clone https://github.com/kcl-lang/helmfile-kcl.git -cd ./helmfile-kcl/examples/hello-world/ -``` - -We can execute the command to show config - -```bash -cat helmfile.yaml -``` - -The output is - -```yaml -repositories: - - name: prometheus-community - url: https://prometheus-community.github.io/helm-charts - -releases: - - name: prom-norbac-ubuntu - namespace: prometheus - chart: prometheus-community/prometheus - set: - - name: rbac.create - value: false - transformers: - # Use KCL Plugin to mutate or validate Kubernetes manifests. - - apiVersion: krm.kcl.dev/v1alpha1 - kind: KCLRun - metadata: - name: "set-annotation" - annotations: - config.kubernetes.io/function: | - container: - image: docker.io/kcllang/kustomize-kcl:v0.2.0 - spec: - source: | - [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "helmfile-kcl"}} for resource in option("resource_list").items] -``` - -In the above config, we use a `KCLRun` plugin to assign the `transfomer` field. This means that we will add annotations to all deployment resources in the prometheus helm chart. - -### 2. Test and Run - -Firstly, init the helmfile tool. - -```bash -helmfile init -``` - -The output may looks like this: - -```bash -The helm plugin helm-git is not installed, do you need to install it [y/n]: y -Install helm plugin helm-git -Installed plugin: helm-git - -helmfile initialization completed! -... -``` - -Then apply the configuration. - -```bash -helmfile apply -``` - -The output is - -```bash -Adding repo prometheus-community https://prometheus-community.github.io/helm-charts -"prometheus-community" has been added to your repositories - -... -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("resource_list")["items"]` and the `functionConfig` from `option("resource_list")["functionConfig"]`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [KRM KCL Spec](https://github.com/kcl-lang/krm-kcl) diff --git a/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/6-kcl-operator.md b/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/6-kcl-operator.md deleted file mode 100644 index dd07e8ea..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/6-kcl-operator.md +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: "KCL Operator" -sidebar_position: 6 ---- - -## Introduction - -[KCL Operator](https://github.com/kcl-lang/kcl-operator) provides cluster integration, allowing you to use Access Webhook to generate, mutate, or validate resources based on KCL configuration when apply resources to the cluster. Webhook will capture creation, application, and editing operations, and execute `KCLRun` resource on the configuration associated with each operation, and the KCL programming language can be used to - -- **Add** labels or annotations based on a condition. -- **Inject** a sidecar container in all KRM resources that contain a PodTemplate. -- **Validate** all KRM resources using KCL schema. -- Use an abstract model to **generate** KRM resources. - -## Prerequisites - -- Install Kubectl -- Prepare a Kubernetes cluster - -## Quick Start - -Let’s write a KCL function which add annotation `managed-by=kcl-operator` only to Pod resources at runtime. - -### 1. Install KCL Operator - -```bash -kubectl apply -f https://raw.githubusercontent.com/kcl-lang/kcl-operator/main/config/all.yaml -``` - -Use the following command to watch and wait the pod status is Running. - -```shell -kubectl get po -``` - -### 2. Deploy the KCL source - -```bash -kubectl apply -f- << EOF -apiVersion: krm.kcl.dev/v1alpha1 -kind: KCLRun -metadata: - name: set-annotation -spec: - source: | - items = [item | { - metadata.annotations: { - "managed-by" = "kcl-operator" - } - } for item in option("items")] -EOF -``` - -### 3. Validate the result - -Validate the mutation result by creating a nginx Pod YAML. - -```shell -kubectl apply -f- << EOF -apiVersion: v1 -kind: Pod -metadata: - name: nginx - annotations: - app: nginx -spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 -EOF -kubectl get po nginx -o yaml | grep kcl-operator -``` - -The output is - -```shell - managed-by: kcl-operator -``` - -## Guides for Developing KCL - -Here's what you can do in the KCL code: - -- Read resources from `option("resource_list")`. The `option("resource_list")` complies with the [KRM Functions Specification](https://kpt.dev/book/05-developing-functions/01-functions-specification). You can read the input resources from `option("items")` and the params from `option("params")`. -- Return a KPM list for output resources. -- Return an error using `assert {condition}, {error_message}`. - -## More Documents and Examples - -- [KRM KCL Spec](https://github.com/kcl-lang/krm-kcl) diff --git a/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json b/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json deleted file mode 100644 index 6e90c03c..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Mutate or Validate Kubernetes Manifests", - "position": 3 -} diff --git a/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/_category_.json b/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/_category_.json deleted file mode 100644 index 42681f2b..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Kubernetes", - "position": 9 -} diff --git a/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/index.md b/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/index.md deleted file mode 100644 index 8d6340de..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/index.md +++ /dev/null @@ -1 +0,0 @@ -# Kubernetes diff --git a/versioned_docs/version-0.6.0/user_docs/guides/working-with-konfig/4-best-practice.md b/versioned_docs/version-0.6.0/user_docs/guides/working-with-konfig/4-best-practice.md deleted file mode 100644 index ee0cc576..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/working-with-konfig/4-best-practice.md +++ /dev/null @@ -1,449 +0,0 @@ ---- -id: practice -sidebar_label: Best Practice ---- - -# Best Practice - -This document aims to explain the best practices for integrating new models into the Konfig library and designing, building and writing KCL code models. New models are generally designed and abstracted using the best practice of separating front-end and back-end models. The direct purpose of distinguishing between front-end and back-end models is to separate `"user interface"` and `"model implementation"`, achieving a user-friendly and simple configuration interface as well as automated configuration query and modification interfaces. - -## Workflow - -![](/img/docs/user_docs/guides/konfig/workflow.png) - -1. **Coding**. Use the KCL OpenAPI tool to generate KCL schemas from the Customer Resources Definitions (CRDs) or OpenAPI Swagger models. These schemas define the atomic capabilities of the platform. -1. **Abstraction**. Based on these atomic capabilities, the platform abstracts user-oriented front-end models and provides a set of templates. These front- - end models cannot work independently, and corresponding back-end models are required. These back-end models will eventually obtain an instance of the front-end model at runtime; it parses the input front-end model and converts it into Kubernetes resources. -1. **Configuration**. Developers or SREs describe the requirements of applications based on front-end models. Users can define the base and different environment configurations for different environments e.g., base, development and production and different localities. In most cases, defining configurations only requires declaring key-value pairs. For some complex scenarios, users can define the logic to generate configurations. -1. **Automation**. After defining the user's configuration, all components have been defined and are ready to be automated. The platform can compile, execute, output, modify, query, and perform other automatic works through the KCL CLI or GPL-binding APIs. Users can also deploy the KCL configuration to the Kubernetes cluster with tools. - -## Model Structure - -Just as web applications provide a friendly user interface, and user input is further inferred at the backend of the application to obtain the final data that falls into the database, similarly, using KCL for model design also follows the logic of front-end and back-end separation. In addition, when the downstream required data content changes, we only need to modify the rendering/logic of the user configuration data to the backend model, thereby avoiding large-scale modification of user configurations. - -Taking the sidecar configuration of application services as an example: - -```python -# Config user interface. -user_sidecar_feature_gates: str - -# Downstream config of processing. -sidecars = [ - { - name = "sidecar_name" # Additional template for sidecars parameters, users do not need to configure them. - feature_gates = user_sidecar_feature_gates - } -] -``` - -## Best Practices for Konfig Modeling - -### Use Single Attribute Instead of Configuration Templates - -For some backend models, the configuration attributes that need to be filled in are often large and comprehensive designs, requiring users to actively input more complex configuration templates, and the filling content of this attribute is basically the same for different users. For example, the configuration of logic shown below requires users to fill in a large amount of template data, which has a high mental cost. - -A simple best practice is to abstract such commonly used and complex templates into a simple attribute `overQuota` with the `bool` type in the front-end model, allowing users to do multiple-choice questions instead of filling in blank questions. For example, when the `overQuota` attribute is `True`, the back-end model will render this complex logic. - -- The front-end attribute `overQuota` - -```python -overQuota: bool -``` - -- The back-end YAML output: - -```yaml -spec: - template: - spec: - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: k8s/is-over-quota - operator: In - values: - - "true" -``` - -In addition, different template names can be designed according to specific business scenarios to fill in the blanks, such as designing an attribute template in the code shown below to assist users in template selection instead of directly filling in the template content. The legal template value can be `"success_ratio"` or `"service_cost"`. When the backend model extends more templates, the front-end code does not need to make any modifications, only needs to adapt the corresponding template logic in the backend model. - -```python -schema SLI: - template: str = "success_ratio" -``` - -In addition, it is recommended to avoid using complex structures directly as front-end model attributes to avoid users needing to rely on too many KCL syntax features (such as unpacking, looping, etc.) or writing many temporary variables to complete the instantiation of the structure when using the model. - -### Use Literal Type and Union Type - -In the above section, it was mentioned that a string attribute can be used to represent different template names, and further, a literal type can be used to express the optional content of the template. For example, the following improvements can be made. - -```python -schema SLI: - template: "success_ratio" | "service_cost" = "success_ratio" -``` - -The type of template is a combination of two string types, indicating that the template can only be `"success_ratio"` or `"service_cost"`. When the user fills in the values of other strings, the KCL compiler will report an error. - -In addition to using union types for literal types, KCL also supports union for complex types such as schema types. For the support of this backend **oneof** configuration, KCL has built-in composite structure union types for support. For example, we can define our own SLI front-end types for various scenarios: `CustomSliDataSource`, `PQLSLIDataSource`, and `StackSLIDataSource`. - -```python -schema CustomSLIDataSource: - customPluginUrl: str - -schema PQLSLIDataSource: - total?: str - error?: str - success?: str - cost?: str - count?: str - -schema StackSLIDataSource: - stack: str - groupBy?: str - metric?: str - -# Simplify type definitions using type aliases -type DataSource = CustomSLIDataSource | PQLSLIDataSource | StackSLIDataSource - -schema DataConfiguration: - sources: {str: DataSource} -``` - -The advantage of designing this front-end model is that the compiler can statically check that the type written by the user can only be a certain type. If the back-end model is used directly, it cannot directly obtain the mapping relationship between different types of types and the fields that need to be filled in from the model. - -In addition, the overall design of the front-end model should also consider horizontal scalability, using the union type as much as possible, fully utilizing the advantages of coding, and avoiding unnecessary large amounts of code restructuring and modification when connecting to different backend or backend models. In addition, for the factory pattern commonly used in other GPL languages, union types can also be used instead in KCL. For example, if you want to obtain a constructor of a type based on the content of a string, you can directly use union types for optimization. - -Using the factory pattern in KCL: - -```python -schema DataA: - id?: int = 1 - value?: str = "value" - -schema DataB: - name?: str = "DataB" - -_dataFactory: {str:} = { - DataA = DataA - DataB = DataB -} -dataA = _dataFactory["DataA"]() -dataB = _dataFactory["DataB"]() -``` - -Replacing the factory pattern with the KCL union type. - -```python -schema DataA: - id?: int = 1 - value?: str = "value" - -schema DataB: - name?: str = "DataB" - -# Just use the union type. -dataA: DataA | DataB = DataA() -dataB: DataA | DataB = DataB() -``` - -### Use Dict Instead of List As Much As Possible - -To make it easier to modify configurations on-site or automate queries, it is advisable to define list or array attributes as dictionary types for easy indexing. In many complex configuration scenarios, the index of a list is arbitrary and the order of elements has no impact on the configuration. Using a dictionary type instead of a list type allows for more convenient data querying and modification. For example: - -```python -schema Person: - name: str - age: int - -schema House: - persons: [Person] - -house = House { - persons = [ - Person { - name = "Alice" - age = 18 - } - Person { - name = "Bob" - age = 10 - } - ] -} -``` - -For example, in the above example, if you want to query the age of the person named `"Alice"` from the list of persons in the house, you need to loop through the list to find Alice's age. However, if you define persons as a dictionary like the following code, it not only looks more concise in code, but you can also directly retrieve Alice's age by using house.persons.Alice.age. In addition, the information of the entire configuration is complete and has no redundant information. - -```python -schema Person: - age: int - -schema House: - persons: {str: Person} # Use Dict Instead of List - -house = House { - persons = { - Alice = Person { age = 18 } - Bob = Person { age = 10 } - } -} -``` - -### Write Validation Expressions for Models - -For frontend models, it is often necessary to validate the fields filled in by users. In this case, KCL's check expressions can be used in conjunction with KCL's built-in functions/syntax/system libraries to perform field validation. For frontend model validation, it is recommended to directly write it in the frontend model definition as a prerequisite for validation, in order to avoid unexpected errors that may occur when the errors are passed to the backend model. - -Use all/any expressions and check expressions for validation - -```python -import regex - -schema ConfigMap: - name: str - data: {str:str} - configMounts?: [ConfigMount] - - check: - all k in data { - regex.match(k, r"[A-Za-z0-9_.-]*") - }, "a valid config key must consist of alphanumeric characters, '-', '_' or '.'" - -schema ConfigMount: - containerName: str - mountPath: str - subPath?: str - - check: - ":" not in mountPath, "mount path must not contain ':'" -``` - -### Use Numerical Unit Type - -Numbers with units in KCL have a built-in type of `units.NumberMultiplier`, and any arithmetic operations are not allowed. - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -x0: NumberMultiplier = 1M # Ok -x1: NumberMultiplier = x0 # Ok -x2 = x0 + x1 # Error: unsupported operand type(s) for +: 'number_multiplier(1M)' and 'number_multiplier(1M)' -``` - -We can use the `int()/float()` function and `str()` function to convert the number unit type to integer or string type, and the resulting string retains the units of the original number unit type. - -```python -a: int = int(1Ki) # 1024 -b: str = str(1Mi) # "1Mi" -``` - -The definitions related to Kubernetes Resource in Konfig can be written using numerical unit types - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -schema Resource: - cpu?: NumberMultiplier | int = 1 - memory?: NumberMultiplier = 1024Mi - disk?: NumberMultiplier = 10Gi - epchygontee?: int -``` - -### Automated Modification of Front-end Model Instances - -In KCL, automated modification of front-end model instances can be achieved through the CLI and API. For example, if we want to modify the image content of an application (Konfig Stack Path: apps/nginx example/dev) configuration, we can directly execute the following command to modify the image content. - -```python -kcl -Y kcl.yaml ci-test/settings.yaml -o ci-test/stdout.golden.yaml -d -O :appConfiguration.image=\"test-image-v1\" -``` - -For more documentation related to automation, please refer to the [Automation Documents](/docs/user_docs/guides/automation) section. - -### Use Functions - -```python -# Define a function that adds two numbers and returns the result。 -add = lambda x, y { - x + y -} -# Define a function that subs two numbers and returns the result。 -sub = lambda x, y { - x - y -} -# Call the function, pass in arguments, and obtain the return value. -result = sub(add(2, 3), 2) # The result is 3. -``` - -The output YAML is - -```yaml -result: 3 -``` - -### Use Package and Module - -Create a package called `utils.k`, define a KCL function called `add` in it, and import it into another file for use. - -- `utils.k` - -```python -# utils.k - -# Define a function that adds two numbers and returns the result。 -add = lambda x, y { - x + y -} - -# Define a function that subs two numbers and returns the result。 -sub = lambda x, y { - x - y -} -``` - -- `main.k` - -```python -# main.k -import .utils - -# Call the function, pass in arguments, and obtain the return value. -result = utils.sub(utils.add(2, 3), 2) # The result is 3. -``` - -### Simplify Logical Expressions Using Configuration - -```python -# Complex Logic, `_cpu` is a non-exported and mutable attribute. -_cpu = 256 -_priority = "1" - -if _priority == "1": - _cpu = 256 -elif _priority == "2": - _cpu = 512 -elif _priority == "3": - _cpu = 1024 -else: - _cpu = 2048 - -# Simplify Logic Expression using Config -cpuMap = { - "1" = 256 - "2" = 512 - "3" = 1024 -} -# Get cpu from the cpuMap, when not found, use the default value 2048. -cpu = cpuMap[_priority] or 2048 -``` - -The output is - -```yaml -cpuMap: - "1": 256 - "2": 512 - "3": 1024 -cpu256: 256 -cpu2048: 2048 -``` - -### Separate Logic and Data - -We can use KCL **schema**, **config**, and **lambda** to separate **data** and **logic** as much as possible. - -For example, we can write the following code (main.k). - -```python -schema Student: - """Define a `Student` schema model with documents. - - Attributes - ---------- - name : str, required - The name of the student. - id : int, required. - The id number of the student. - grade : int, required. - The grade of the student. - - Examples - -------- - s = Student { - name = "Alice" - id = 1 - grade = 80 - } - - """ - name: str - id: int - grade: int - - # Define constraints for the `Student` model. - check: - id >= 0 - 0 <= grade <= 100 - -# Student data. -students: [Student] = [ - {name = "Alice", id = 1, grade = 85} - {name = "Bob", id = 2, grade = 70} - {name = "Charlie", id = 3, grade = 90} - {name = "David", id = 4, grade = 80} - {name = "Eve", id = 5, grade = 95} -] - -# Student logic. -query_student_where_name = lambda students: [Student], name: str { - # Query the first student where name is `name` - filter s in students { - s.name == name - }?[0] -} - -alice = query_student_where_name(students, name="Alice") -bob = query_student_where_name(students, name="Bob") -``` - -The output is - -```yaml -students: - - name: Alice - id: 1 - grade: 85 - - name: Bob - id: 2 - grade: 70 - - name: Charlie - id: 3 - grade: 90 - - name: David - id: 4 - grade: 80 - - name: Eve - id: 5 - grade: 95 -alice: - name: Alice - id: 1 - grade: 85 -bob: - name: Bob - id: 2 - grade: 70 -``` - -### Add Comments for Models - -To facilitate user understanding and automatic model documentation generation, it is necessary to write comments for the defined model. The comment content usually includes an explanation of the model, an explanation of model fields, types, default values, usage examples, and more. For detailed KCL schema code commenting guidelines and automatic model documentation generation, please refer to the [KCL Documentation Specification](/docs/tools/cli/kcl/docgen). Additionally, we can use the `kcl-doc generate` command to extract documentation from the user-specified file or directory and output it to the specified directory. - -## Backend Model - -The backend model is an "implementation model," which mainly includes the logical code to map the frontend model to the backend model. After the frontend model is written, we can use the frontend model schema to create frontend model instances, and write the corresponding backend mapping/rendering code to convert these frontend instances into the backend model. By using KCL's multi-file compilation and `Schema.instances()` function, the frontend and backend code can be highly decoupled, so that users only need to focus on frontend configuration without being aware of the complex validation and logical code of the model. diff --git a/versioned_docs/version-0.6.0/user_docs/guides/working-with-konfig/_category_.json b/versioned_docs/version-0.6.0/user_docs/guides/working-with-konfig/_category_.json deleted file mode 100644 index a71426f9..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/working-with-konfig/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Konfig", - "position": 10 -} diff --git a/versioned_docs/version-0.6.0/user_docs/guides/working-with-kusion/_category_.json b/versioned_docs/version-0.6.0/user_docs/guides/working-with-kusion/_category_.json deleted file mode 100644 index 9f914498..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/working-with-kusion/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KusionStack", - "position": 15 -} diff --git a/versioned_docs/version-0.6.0/user_docs/guides/working-with-kusion/index.md b/versioned_docs/version-0.6.0/user_docs/guides/working-with-kusion/index.md deleted file mode 100644 index 2565ad03..00000000 --- a/versioned_docs/version-0.6.0/user_docs/guides/working-with-kusion/index.md +++ /dev/null @@ -1,15 +0,0 @@ -# KusionStack - -**KusionStack is an open-source cloud-native programmable technology stack!** - -KusionStack is a highly flexible programmable technology stack to enable unified application delivery and operation, inspired by the word Fusion, which aims to help enterprises build an application-centric configuration management plane and DevOps ecosystem. - -1. Fusion of hybrid scenarios of **private cloud**, **hybrid cloud**, and **multi-cloud** -2. Fusion of hybrid platform technologies of **cloud-native** and a variety of other platform technologies -3. Fusion of enterprise-level demands of **multi-project**, **multi-team**, **multi-role**, **multi-tenant**, and **multi-environment** - -Based on the concept of Platform as Code, developers can quickly unify the full configuration schemas, constraints, policies and configs across the application life cycle, work with the **hybrid technologies and cloud environment**, go through the **end-to-end workflow** from programming to launching, and truly achieve **write once, deliver anywhere**. - -![](/img/docs/user_docs/intro/kusion-stack-1.png) - -More documents and use cases at [https://kusionstack.io/](https://kusionstack.io/) diff --git a/versioned_docs/version-0.6.0/user_docs/support/_category_.json b/versioned_docs/version-0.6.0/user_docs/support/_category_.json deleted file mode 100644 index 60548d80..00000000 --- a/versioned_docs/version-0.6.0/user_docs/support/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "FAQ", - "position": 6 -} diff --git a/versioned_docs/version-0.6.0/user_docs/support/faq-cli.md b/versioned_docs/version-0.6.0/user_docs/support/faq-cli.md deleted file mode 100644 index ab012a34..00000000 --- a/versioned_docs/version-0.6.0/user_docs/support/faq-cli.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Command Line Tool - -## 1. What is the function of the `settings.yaml` in the application directory of the Konfig? - -The `settings.yaml` in KCL indicates the configuration file of the KCL command line tool. You can put the compiled configuration into it, such as the file to be compiled, the option dynamic parameter that needs to be input(`-d`), whether to ignore the null value(`-n`) and other configurations. - -For example, for the following arguments: - -```shell -kcl main.k -D key=value -n -r -``` - -It can be replaced by the following command line arguments and `settings.yaml` - -```shell -kcl -Y settings.yaml -``` - -settings.yaml - -```yaml -kcl_cli_configs: - files: - - main.k - disable_none: true - strict_range_check: true -kcl_options: - - key: key - value: value -``` - -- `kcl_cli_configs` indicates configurable compilation arguments, `file` indicates the KCL file used for compilation,`disable_none` indicates whether to use `-n`, `strict_range_check` indicates whether to use `-r`. -- `kcl_options` indicates dynamic options that can be configured, `key` indicates option name, `value` indicates option value - -Note: The file name does not need to be `settings.yaml`, but the configuration in it must meet the requirements. - -### 2. How to input dynamic options? How to get dynamic options in code? - -KCL supports multiple ways to input dynamic options - -- `-D`: Use the command line argument `-D` to input dynamic options. It supports basic data types str/int/float/bool and structured data types list/dict - -```shell -kcl main.k -D env-type=TEST -D deploy-topology='[{"cluster":"my-cluster","idc":"my-idc","replicas":2,"workspace":"my-idc","zone":"my-zone"}]' -``` - -- `-Y`: Use the command line argument `-Y` to input dynamic options by configuration file: - -```yaml -kcl_options: - - key: env-type - value: TEST - - key: deploy-topology - value: - - cluster: my-cluster - idc: my-idc - replicas: 2 - workspace: my-workspace - zone: my-zone -``` - -Use the built-in function `option()` to get it: - -```python -env = option("env-type") -deploy_topology = option("deploy-topology") -``` - -Output: - -```yaml -env: TEST -deploy_topology: - - cluster: my-cluster - idc: my-idc - replicas: 2 - workspace: my-workspace - zone: my-zone -``` - -### 3. How to compile multiple files? - -- Input multiple files in the command line: - -```shell -kcl file1.k file2.k file3.k -``` - -- Set multiple files in configuration file and use command line argument `-Y`: - -settings.yaml - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - - file3.k -``` - -```shell -kcl -Y settings.yaml -``` diff --git a/versioned_docs/version-0.6.0/user_docs/support/faq-yaml.md b/versioned_docs/version-0.6.0/user_docs/support/faq-yaml.md deleted file mode 100644 index b13a0f7a..00000000 --- a/versioned_docs/version-0.6.0/user_docs/support/faq-yaml.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -sidebar_position: 3 ---- - -# YAML - -## 1. What is the difference between single and double quote YAML strings? - -- YAML double-quoted strings are the only style that can express arbitrary strings, by using `\` escape characters, such as `\"` to escape double quotes `"`, `\\` to escape backslashes `\`, and a single backslash `\` can be used as a continuation character for double-quoted strings. -- YAML single-quoted strings differ from YAML double-quoted strings in that `\` and `"` can be used freely without escaping, but two single-quotes `''` are used to escape single-quote `'` characters. - -For the following example, the contents of the three string variables are the same. - -```yaml -string1: 'here '' s to "quotes"' -string2: 'here''s to "quotes"' -string3: here's to "quotes" -``` - -> Note: KCL's strategy for outputting YAML strings is to output unquoted strings or double-quoted strings preferentially when single quotes appear in the string content, and output single-quoted strings in other cases to avoid the burden of understanding. - -For more details, please refer to [YAML Spec v1.2](https://yaml.org/spec/1.2.1/) - -## 2. What is the meaning of symbols such as | - + > in YAML? - -When using KCL multi-line strings (triple quote strings), the output YAML often carries some special tokens, such as `|`, `-`, `+` and `>`, etc. These tokens usually are the representation method of YAML multi-line string, such as the following KCL code: - -```python -data = """This is a KCL multi line string (the first line) -This is a KCL multi line string (the second line) -This is a KCL multi line string (the third line) - - -""" -var = 1 -``` - -The output YAML is - -```yaml -data: |+ - This is a KCL multi line string (the first line) - This is a KCL multi line string (the second line) - This is a KCL multi line string (the third line) - - -var: 1 -``` - -- `|` represents **block style**, which is used to represent a multi-line string, where all newlines in the string represent the real newlines. -- `>` represents **folding style**, in which all newlines in the string will be replaced by spaces. -- `+` and `-` are used to control the use of newlines at the end of strings. The default is to keep a single newline at the end of the string. If we want to remove all newlines, we can put a `-` after the style indicator `|` or `>`. If we want to keep the newline at the end, we need to put a `+` after `|` or `>`. - -For more details, please refer to [YAML Multiline String](https://yaml-multiline.info/) and [YAML Spec v1.2](https://yaml.org/spec/1.2.1/) - -## 3. What is the meaning of numbers that appear after symbols | - + > such as |1 and |2 in YAML? - -Numbers represent **explicit indentation indicators** in YAML. For long strings in YAML, YAML usually the first non-blank line determines the indentation level of the string, and when the first non-blank line is preceded by a non-leading character, such as a newline, we must use **explicit indent indicators** to specify the indent level of the content, such as `|1` and `|2` etc. - -For example, for the following KCL code: - -```python -longStringStartWithNewline = """ -This is the second line -This is the third line -""" - -``` - -```yaml -longStringStartWithNewline: |2 - - This is the second line - This is the third line -``` - -- Writing long strings from the first line. - -```python -longString = """This is the second line -This is the third line -""" -``` - -- Writing long strings with line continuation characters. - -```python -longString = """\ -This is the second line -This is the third line -""" -``` - -The YAML output by the above two methods is: - -```yaml -longString: | - This is the second line - This is the third line -``` - -For more details, please refer to [YAML Spec v1.2](https://yaml.org/spec/1.2.1/) diff --git a/versioned_docs/version-0.6.0/user_docs/support/support.md b/versioned_docs/version-0.6.0/user_docs/support/support.md deleted file mode 100644 index fac13ef2..00000000 --- a/versioned_docs/version-0.6.0/user_docs/support/support.md +++ /dev/null @@ -1,3 +0,0 @@ -# FAQ - -KCL frequently asked questions. diff --git a/versioned_docs/version-0.5.1/community/contribute/_category_.json b/versioned_docs/version-0.6/community/contribute/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/community/contribute/_category_.json rename to versioned_docs/version-0.6/community/contribute/_category_.json diff --git a/versioned_docs/version-0.5.1/community/contribute/contribute-code.md b/versioned_docs/version-0.6/community/contribute/contribute-code.md similarity index 100% rename from versioned_docs/version-0.5.1/community/contribute/contribute-code.md rename to versioned_docs/version-0.6/community/contribute/contribute-code.md diff --git a/versioned_docs/version-0.5.1/community/contribute/contribute-docs.md b/versioned_docs/version-0.6/community/contribute/contribute-docs.md similarity index 100% rename from versioned_docs/version-0.5.1/community/contribute/contribute-docs.md rename to versioned_docs/version-0.6/community/contribute/contribute-docs.md diff --git a/versioned_docs/version-0.5.1/community/contribute/contribute.md b/versioned_docs/version-0.6/community/contribute/contribute.md similarity index 100% rename from versioned_docs/version-0.5.1/community/contribute/contribute.md rename to versioned_docs/version-0.6/community/contribute/contribute.md diff --git a/versioned_docs/version-0.5.1/community/contribute/git-guideline.md b/versioned_docs/version-0.6/community/contribute/git-guideline.md similarity index 100% rename from versioned_docs/version-0.5.1/community/contribute/git-guideline.md rename to versioned_docs/version-0.6/community/contribute/git-guideline.md diff --git a/versioned_docs/version-0.5.1/community/intro/_category_.json b/versioned_docs/version-0.6/community/intro/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/community/intro/_category_.json rename to versioned_docs/version-0.6/community/intro/_category_.json diff --git a/versioned_docs/version-0.5.1/community/intro/intro.md b/versioned_docs/version-0.6/community/intro/intro.md similarity index 100% rename from versioned_docs/version-0.5.1/community/intro/intro.md rename to versioned_docs/version-0.6/community/intro/intro.md diff --git a/versioned_docs/version-0.5.1/community/intro/license.md b/versioned_docs/version-0.6/community/intro/license.md similarity index 100% rename from versioned_docs/version-0.5.1/community/intro/license.md rename to versioned_docs/version-0.6/community/intro/license.md diff --git a/versioned_docs/version-0.5.1/community/intro/support.md b/versioned_docs/version-0.6/community/intro/support.md similarity index 100% rename from versioned_docs/version-0.5.1/community/intro/support.md rename to versioned_docs/version-0.6/community/intro/support.md diff --git a/versioned_docs/version-0.5.1/community/release-policy/_category_.json b/versioned_docs/version-0.6/community/release-policy/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/community/release-policy/_category_.json rename to versioned_docs/version-0.6/community/release-policy/_category_.json diff --git a/versioned_docs/version-0.5.1/community/release-policy/index.md b/versioned_docs/version-0.6/community/release-policy/index.md similarity index 100% rename from versioned_docs/version-0.5.1/community/release-policy/index.md rename to versioned_docs/version-0.6/community/release-policy/index.md diff --git a/versioned_docs/version-0.5.1/community/release-policy/kcl.md b/versioned_docs/version-0.6/community/release-policy/kcl.md similarity index 100% rename from versioned_docs/version-0.5.1/community/release-policy/kcl.md rename to versioned_docs/version-0.6/community/release-policy/kcl.md diff --git a/versioned_docs/version-0.5.1/community/release-policy/roadmap.md b/versioned_docs/version-0.6/community/release-policy/roadmap.md similarity index 100% rename from versioned_docs/version-0.5.1/community/release-policy/roadmap.md rename to versioned_docs/version-0.6/community/release-policy/roadmap.md diff --git a/versioned_docs/version-0.5.1/reference/_advanced-concepts/_category_.json b/versioned_docs/version-0.6/reference/_advanced-concepts/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/reference/_advanced-concepts/_category_.json rename to versioned_docs/version-0.6/reference/_advanced-concepts/_category_.json diff --git a/versioned_docs/version-0.5.1/reference/_advanced-concepts/build_cache.md b/versioned_docs/version-0.6/reference/_advanced-concepts/build_cache.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/_advanced-concepts/build_cache.md rename to versioned_docs/version-0.6/reference/_advanced-concepts/build_cache.md diff --git a/versioned_docs/version-0.5.1/reference/_category_.json b/versioned_docs/version-0.6/reference/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/reference/_category_.json rename to versioned_docs/version-0.6/reference/_category_.json diff --git a/versioned_docs/version-0.5.1/reference/cheatsheets/_category_.json b/versioned_docs/version-0.6/reference/cheatsheets/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/reference/cheatsheets/_category_.json rename to versioned_docs/version-0.6/reference/cheatsheets/_category_.json diff --git a/versioned_docs/version-0.5.1/reference/cheatsheets/index.md b/versioned_docs/version-0.6/reference/cheatsheets/index.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/cheatsheets/index.md rename to versioned_docs/version-0.6/reference/cheatsheets/index.md diff --git a/versioned_docs/version-0.5.1/reference/lang/_category_.json b/versioned_docs/version-0.6/reference/lang/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/reference/lang/_category_.json rename to versioned_docs/version-0.6/reference/lang/_category_.json diff --git a/versioned_docs/version-0.5.1/reference/lang/codelab/_category_.json b/versioned_docs/version-0.6/reference/lang/codelab/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/reference/lang/codelab/_category_.json rename to versioned_docs/version-0.6/reference/lang/codelab/_category_.json diff --git a/versioned_docs/version-0.5.1/reference/lang/codelab/collaborative.md b/versioned_docs/version-0.6/reference/lang/codelab/collaborative.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/lang/codelab/collaborative.md rename to versioned_docs/version-0.6/reference/lang/codelab/collaborative.md diff --git a/versioned_docs/version-0.5.1/reference/lang/codelab/index.md b/versioned_docs/version-0.6/reference/lang/codelab/index.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/lang/codelab/index.md rename to versioned_docs/version-0.6/reference/lang/codelab/index.md diff --git a/versioned_docs/version-0.5.1/reference/lang/codelab/schema.md b/versioned_docs/version-0.6/reference/lang/codelab/schema.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/lang/codelab/schema.md rename to versioned_docs/version-0.6/reference/lang/codelab/schema.md diff --git a/versioned_docs/version-0.5.1/reference/lang/codelab/simple.md b/versioned_docs/version-0.6/reference/lang/codelab/simple.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/lang/codelab/simple.md rename to versioned_docs/version-0.6/reference/lang/codelab/simple.md diff --git a/versioned_docs/version-0.5.1/reference/lang/error/_category_.json b/versioned_docs/version-0.6/reference/lang/error/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/reference/lang/error/_category_.json rename to versioned_docs/version-0.6/reference/lang/error/_category_.json diff --git a/versioned_docs/version-0.6.0/reference/lang/error/exception.md b/versioned_docs/version-0.6/reference/lang/error/exception.md similarity index 100% rename from versioned_docs/version-0.6.0/reference/lang/error/exception.md rename to versioned_docs/version-0.6/reference/lang/error/exception.md diff --git a/versioned_docs/version-0.5.1/reference/lang/error/index.md b/versioned_docs/version-0.6/reference/lang/error/index.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/lang/error/index.md rename to versioned_docs/version-0.6/reference/lang/error/index.md diff --git a/versioned_docs/version-0.5.1/reference/lang/spec/_category_.json b/versioned_docs/version-0.6/reference/lang/spec/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/reference/lang/spec/_category_.json rename to versioned_docs/version-0.6/reference/lang/spec/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/codestyle.md b/versioned_docs/version-0.6/reference/lang/spec/codestyle.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/lang/spec/codestyle.md rename to versioned_docs/version-0.6/reference/lang/spec/codestyle.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/datatypes.md b/versioned_docs/version-0.6/reference/lang/spec/datatypes.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/datatypes.md rename to versioned_docs/version-0.6/reference/lang/spec/datatypes.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/spec/error.md b/versioned_docs/version-0.6/reference/lang/spec/error.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/spec/error.md rename to versioned_docs/version-0.6/reference/lang/spec/error.md diff --git a/versioned_docs/version-0.5.6/reference/lang/spec/expressions.md b/versioned_docs/version-0.6/reference/lang/spec/expressions.md similarity index 100% rename from versioned_docs/version-0.5.6/reference/lang/spec/expressions.md rename to versioned_docs/version-0.6/reference/lang/spec/expressions.md diff --git a/versioned_docs/version-0.5.1/reference/lang/spec/index.md b/versioned_docs/version-0.6/reference/lang/spec/index.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/lang/spec/index.md rename to versioned_docs/version-0.6/reference/lang/spec/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/spec/kcl-spec.md b/versioned_docs/version-0.6/reference/lang/spec/kcl-spec.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/spec/kcl-spec.md rename to versioned_docs/version-0.6/reference/lang/spec/kcl-spec.md diff --git a/versioned_docs/version-0.5.1/reference/lang/spec/lexical.md b/versioned_docs/version-0.6/reference/lang/spec/lexical.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/lang/spec/lexical.md rename to versioned_docs/version-0.6/reference/lang/spec/lexical.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/spec/modules.md b/versioned_docs/version-0.6/reference/lang/spec/modules.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/spec/modules.md rename to versioned_docs/version-0.6/reference/lang/spec/modules.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/spec/schema.md b/versioned_docs/version-0.6/reference/lang/spec/schema.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/spec/schema.md rename to versioned_docs/version-0.6/reference/lang/spec/schema.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/spec/statements.md b/versioned_docs/version-0.6/reference/lang/spec/statements.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/lang/spec/statements.md rename to versioned_docs/version-0.6/reference/lang/spec/statements.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/variables.md b/versioned_docs/version-0.6/reference/lang/spec/variables.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/variables.md rename to versioned_docs/version-0.6/reference/lang/spec/variables.md diff --git a/versioned_docs/version-0.6.0/reference/lang/tour.md b/versioned_docs/version-0.6/reference/lang/tour.md similarity index 100% rename from versioned_docs/version-0.6.0/reference/lang/tour.md rename to versioned_docs/version-0.6/reference/lang/tour.md diff --git a/versioned_docs/version-0.5.1/reference/lang/types/_category_.json b/versioned_docs/version-0.6/reference/lang/types/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/reference/lang/types/_category_.json rename to versioned_docs/version-0.6/reference/lang/types/_category_.json diff --git a/versioned_docs/version-0.5.1/reference/lang/types/types.md b/versioned_docs/version-0.6/reference/lang/types/types.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/lang/types/types.md rename to versioned_docs/version-0.6/reference/lang/types/types.md diff --git a/versioned_docs/version-0.5.1/reference/model/_category_.json b/versioned_docs/version-0.6/reference/model/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/reference/model/_category_.json rename to versioned_docs/version-0.6/reference/model/_category_.json diff --git a/versioned_docs/version-0.5.1/reference/model/base64.md b/versioned_docs/version-0.6/reference/model/base64.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/model/base64.md rename to versioned_docs/version-0.6/reference/model/base64.md diff --git a/versioned_docs/version-0.5.1/reference/model/builtin.md b/versioned_docs/version-0.6/reference/model/builtin.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/model/builtin.md rename to versioned_docs/version-0.6/reference/model/builtin.md diff --git a/versioned_docs/version-0.5.1/reference/model/crypto.md b/versioned_docs/version-0.6/reference/model/crypto.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/model/crypto.md rename to versioned_docs/version-0.6/reference/model/crypto.md diff --git a/versioned_docs/version-0.6.0/reference/model/datetime.md b/versioned_docs/version-0.6/reference/model/datetime.md similarity index 100% rename from versioned_docs/version-0.6.0/reference/model/datetime.md rename to versioned_docs/version-0.6/reference/model/datetime.md diff --git a/versioned_docs/version-0.5.1/reference/model/index.md b/versioned_docs/version-0.6/reference/model/index.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/model/index.md rename to versioned_docs/version-0.6/reference/model/index.md diff --git a/versioned_docs/version-0.6.0/reference/model/json.md b/versioned_docs/version-0.6/reference/model/json.md similarity index 100% rename from versioned_docs/version-0.6.0/reference/model/json.md rename to versioned_docs/version-0.6/reference/model/json.md diff --git a/versioned_docs/version-0.5.1/reference/model/manifests.md b/versioned_docs/version-0.6/reference/model/manifests.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/model/manifests.md rename to versioned_docs/version-0.6/reference/model/manifests.md diff --git a/versioned_docs/version-0.6.0/reference/model/math.md b/versioned_docs/version-0.6/reference/model/math.md similarity index 100% rename from versioned_docs/version-0.6.0/reference/model/math.md rename to versioned_docs/version-0.6/reference/model/math.md diff --git a/versioned_docs/version-0.5.1/reference/model/net.md b/versioned_docs/version-0.6/reference/model/net.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/model/net.md rename to versioned_docs/version-0.6/reference/model/net.md diff --git a/versioned_docs/version-0.5.1/reference/model/overview.md b/versioned_docs/version-0.6/reference/model/overview.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/model/overview.md rename to versioned_docs/version-0.6/reference/model/overview.md diff --git a/versioned_docs/version-0.5.1/reference/model/regex.md b/versioned_docs/version-0.6/reference/model/regex.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/model/regex.md rename to versioned_docs/version-0.6/reference/model/regex.md diff --git a/versioned_docs/version-0.5.1/reference/model/units.md b/versioned_docs/version-0.6/reference/model/units.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/model/units.md rename to versioned_docs/version-0.6/reference/model/units.md diff --git a/versioned_docs/version-0.5.1/reference/model/yaml.md b/versioned_docs/version-0.6/reference/model/yaml.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/model/yaml.md rename to versioned_docs/version-0.6/reference/model/yaml.md diff --git a/versioned_docs/version-0.5.1/reference/plugin/_category_.json b/versioned_docs/version-0.6/reference/plugin/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/reference/plugin/_category_.json rename to versioned_docs/version-0.6/reference/plugin/_category_.json diff --git a/versioned_docs/version-0.5.1/reference/plugin/index.md b/versioned_docs/version-0.6/reference/plugin/index.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/plugin/index.md rename to versioned_docs/version-0.6/reference/plugin/index.md diff --git a/versioned_docs/version-0.5.1/reference/plugin/overview.md b/versioned_docs/version-0.6/reference/plugin/overview.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/plugin/overview.md rename to versioned_docs/version-0.6/reference/plugin/overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/plugin/project_context.md b/versioned_docs/version-0.6/reference/plugin/project_context.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.4/reference/plugin/project_context.md rename to versioned_docs/version-0.6/reference/plugin/project_context.md diff --git a/versioned_docs/version-0.5.1/reference/xlang-api/_category_.json b/versioned_docs/version-0.6/reference/xlang-api/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/reference/xlang-api/_category_.json rename to versioned_docs/version-0.6/reference/xlang-api/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/xlang-api/go-api.md b/versioned_docs/version-0.6/reference/xlang-api/go-api.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.3/reference/xlang-api/go-api.md rename to versioned_docs/version-0.6/reference/xlang-api/go-api.md diff --git a/versioned_docs/version-0.5.1/reference/xlang-api/index.md b/versioned_docs/version-0.6/reference/xlang-api/index.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/xlang-api/index.md rename to versioned_docs/version-0.6/reference/xlang-api/index.md diff --git a/versioned_docs/version-0.5.1/reference/xlang-api/java-api.md b/versioned_docs/version-0.6/reference/xlang-api/java-api.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/xlang-api/java-api.md rename to versioned_docs/version-0.6/reference/xlang-api/java-api.md diff --git a/versioned_docs/version-0.5.1/reference/xlang-api/overview.md b/versioned_docs/version-0.6/reference/xlang-api/overview.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/xlang-api/overview.md rename to versioned_docs/version-0.6/reference/xlang-api/overview.md diff --git a/versioned_docs/version-0.5.1/reference/xlang-api/python-api.md b/versioned_docs/version-0.6/reference/xlang-api/python-api.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/xlang-api/python-api.md rename to versioned_docs/version-0.6/reference/xlang-api/python-api.md diff --git a/versioned_docs/version-0.5.6/reference/xlang-api/rest-api.md b/versioned_docs/version-0.6/reference/xlang-api/rest-api.md similarity index 100% rename from versioned_docs/version-0.5.6/reference/xlang-api/rest-api.md rename to versioned_docs/version-0.6/reference/xlang-api/rest-api.md diff --git a/versioned_docs/version-0.5.1/tools/Ide/_category_.json b/versioned_docs/version-0.6/tools/Ide/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/tools/Ide/_category_.json rename to versioned_docs/version-0.6/tools/Ide/_category_.json diff --git a/versioned_docs/version-0.6.0/tools/Ide/index.md b/versioned_docs/version-0.6/tools/Ide/index.md similarity index 100% rename from versioned_docs/version-0.6.0/tools/Ide/index.md rename to versioned_docs/version-0.6/tools/Ide/index.md diff --git a/versioned_docs/version-0.5.6/tools/Ide/intellij.md b/versioned_docs/version-0.6/tools/Ide/intellij.md similarity index 100% rename from versioned_docs/version-0.5.6/tools/Ide/intellij.md rename to versioned_docs/version-0.6/tools/Ide/intellij.md diff --git a/versioned_docs/version-0.5.6/tools/Ide/neovim.md b/versioned_docs/version-0.6/tools/Ide/neovim.md similarity index 100% rename from versioned_docs/version-0.5.6/tools/Ide/neovim.md rename to versioned_docs/version-0.6/tools/Ide/neovim.md diff --git a/versioned_docs/version-0.6.0/tools/Ide/vs-code.md b/versioned_docs/version-0.6/tools/Ide/vs-code.md similarity index 100% rename from versioned_docs/version-0.6.0/tools/Ide/vs-code.md rename to versioned_docs/version-0.6/tools/Ide/vs-code.md diff --git a/versioned_docs/version-0.5.1/tools/_category_.json b/versioned_docs/version-0.6/tools/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/tools/_category_.json rename to versioned_docs/version-0.6/tools/_category_.json diff --git a/versioned_docs/version-0.5.1/tools/cli/_category_.json b/versioned_docs/version-0.6/tools/cli/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/tools/cli/_category_.json rename to versioned_docs/version-0.6/tools/cli/_category_.json diff --git a/versioned_docs/version-0.5.1/tools/cli/index.md b/versioned_docs/version-0.6/tools/cli/index.md similarity index 100% rename from versioned_docs/version-0.5.1/tools/cli/index.md rename to versioned_docs/version-0.6/tools/cli/index.md diff --git a/versioned_docs/version-0.5.1/tools/cli/kcl/_category_.json b/versioned_docs/version-0.6/tools/cli/kcl/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/tools/cli/kcl/_category_.json rename to versioned_docs/version-0.6/tools/cli/kcl/_category_.json diff --git a/versioned_docs/version-0.5.1/tools/cli/kcl/docgen.md b/versioned_docs/version-0.6/tools/cli/kcl/docgen.md similarity index 100% rename from versioned_docs/version-0.5.1/tools/cli/kcl/docgen.md rename to versioned_docs/version-0.6/tools/cli/kcl/docgen.md diff --git a/versioned_docs/version-0.5.6/tools/cli/kcl/fmt.md b/versioned_docs/version-0.6/tools/cli/kcl/fmt.md similarity index 100% rename from versioned_docs/version-0.5.6/tools/cli/kcl/fmt.md rename to versioned_docs/version-0.6/tools/cli/kcl/fmt.md diff --git a/versioned_docs/version-0.5.1/tools/cli/kcl/index.md b/versioned_docs/version-0.6/tools/cli/kcl/index.md similarity index 100% rename from versioned_docs/version-0.5.1/tools/cli/kcl/index.md rename to versioned_docs/version-0.6/tools/cli/kcl/index.md diff --git a/versioned_docs/version-0.5.6/tools/cli/kcl/lint.md b/versioned_docs/version-0.6/tools/cli/kcl/lint.md similarity index 100% rename from versioned_docs/version-0.5.6/tools/cli/kcl/lint.md rename to versioned_docs/version-0.6/tools/cli/kcl/lint.md diff --git a/versioned_docs/version-0.5.2/tools/cli/kcl/overview.md b/versioned_docs/version-0.6/tools/cli/kcl/overview.md similarity index 100% rename from versioned_docs/version-0.5.2/tools/cli/kcl/overview.md rename to versioned_docs/version-0.6/tools/cli/kcl/overview.md diff --git a/versioned_docs/version-0.5.1/tools/cli/kcl/test.md b/versioned_docs/version-0.6/tools/cli/kcl/test.md similarity index 100% rename from versioned_docs/version-0.5.1/tools/cli/kcl/test.md rename to versioned_docs/version-0.6/tools/cli/kcl/test.md diff --git a/versioned_docs/version-0.5.1/tools/cli/kcl/vet.md b/versioned_docs/version-0.6/tools/cli/kcl/vet.md similarity index 100% rename from versioned_docs/version-0.5.1/tools/cli/kcl/vet.md rename to versioned_docs/version-0.6/tools/cli/kcl/vet.md diff --git a/versioned_docs/version-0.5.1/tools/cli/openapi/_category_.json b/versioned_docs/version-0.6/tools/cli/openapi/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/tools/cli/openapi/_category_.json rename to versioned_docs/version-0.6/tools/cli/openapi/_category_.json diff --git a/versioned_docs/version-0.5.1/tools/cli/openapi/crd-to-kcl.md b/versioned_docs/version-0.6/tools/cli/openapi/crd-to-kcl.md similarity index 100% rename from versioned_docs/version-0.5.1/tools/cli/openapi/crd-to-kcl.md rename to versioned_docs/version-0.6/tools/cli/openapi/crd-to-kcl.md diff --git a/versioned_docs/version-0.5.1/tools/cli/openapi/index.md b/versioned_docs/version-0.6/tools/cli/openapi/index.md similarity index 100% rename from versioned_docs/version-0.5.1/tools/cli/openapi/index.md rename to versioned_docs/version-0.6/tools/cli/openapi/index.md diff --git a/versioned_docs/version-0.5.1/tools/cli/openapi/openapi-to-kcl.md b/versioned_docs/version-0.6/tools/cli/openapi/openapi-to-kcl.md similarity index 100% rename from versioned_docs/version-0.5.1/tools/cli/openapi/openapi-to-kcl.md rename to versioned_docs/version-0.6/tools/cli/openapi/openapi-to-kcl.md diff --git a/versioned_docs/version-0.5.6/tools/cli/openapi/quick-start.md b/versioned_docs/version-0.6/tools/cli/openapi/quick-start.md similarity index 100% rename from versioned_docs/version-0.5.6/tools/cli/openapi/quick-start.md rename to versioned_docs/version-0.6/tools/cli/openapi/quick-start.md diff --git a/versioned_docs/version-0.5.6/tools/cli/openapi/spec.md b/versioned_docs/version-0.6/tools/cli/openapi/spec.md similarity index 100% rename from versioned_docs/version-0.5.6/tools/cli/openapi/spec.md rename to versioned_docs/version-0.6/tools/cli/openapi/spec.md diff --git a/versioned_docs/version-0.5.1/reference/package-management/_category_.json b/versioned_docs/version-0.6/tools/cli/package-management/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/reference/package-management/_category_.json rename to versioned_docs/version-0.6/tools/cli/package-management/_category_.json diff --git a/versioned_docs/version-0.5.1/reference/package-management/command-reference/1.init.md b/versioned_docs/version-0.6/tools/cli/package-management/command-reference/1.init.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/package-management/command-reference/1.init.md rename to versioned_docs/version-0.6/tools/cli/package-management/command-reference/1.init.md diff --git a/versioned_docs/version-0.5.1/reference/package-management/command-reference/10.help.md b/versioned_docs/version-0.6/tools/cli/package-management/command-reference/10.help.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/package-management/command-reference/10.help.md rename to versioned_docs/version-0.6/tools/cli/package-management/command-reference/10.help.md diff --git a/versioned_docs/version-0.5.1/reference/package-management/command-reference/2.add.md b/versioned_docs/version-0.6/tools/cli/package-management/command-reference/2.add.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/package-management/command-reference/2.add.md rename to versioned_docs/version-0.6/tools/cli/package-management/command-reference/2.add.md diff --git a/versioned_docs/version-0.5.1/reference/package-management/command-reference/3.pkg.md b/versioned_docs/version-0.6/tools/cli/package-management/command-reference/3.pkg.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/package-management/command-reference/3.pkg.md rename to versioned_docs/version-0.6/tools/cli/package-management/command-reference/3.pkg.md diff --git a/versioned_docs/version-0.5.1/reference/package-management/command-reference/4.metadata.md b/versioned_docs/version-0.6/tools/cli/package-management/command-reference/4.metadata.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/package-management/command-reference/4.metadata.md rename to versioned_docs/version-0.6/tools/cli/package-management/command-reference/4.metadata.md diff --git a/versioned_docs/version-0.5.1/reference/package-management/command-reference/5.run.md b/versioned_docs/version-0.6/tools/cli/package-management/command-reference/5.run.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/package-management/command-reference/5.run.md rename to versioned_docs/version-0.6/tools/cli/package-management/command-reference/5.run.md diff --git a/versioned_docs/version-0.5.1/reference/package-management/command-reference/6.login.md b/versioned_docs/version-0.6/tools/cli/package-management/command-reference/6.login.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/package-management/command-reference/6.login.md rename to versioned_docs/version-0.6/tools/cli/package-management/command-reference/6.login.md diff --git a/versioned_docs/version-0.5.1/reference/package-management/command-reference/7.logout.md b/versioned_docs/version-0.6/tools/cli/package-management/command-reference/7.logout.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/package-management/command-reference/7.logout.md rename to versioned_docs/version-0.6/tools/cli/package-management/command-reference/7.logout.md diff --git a/versioned_docs/version-0.5.1/reference/package-management/command-reference/8.push.md b/versioned_docs/version-0.6/tools/cli/package-management/command-reference/8.push.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/package-management/command-reference/8.push.md rename to versioned_docs/version-0.6/tools/cli/package-management/command-reference/8.push.md diff --git a/versioned_docs/version-0.5.1/reference/package-management/command-reference/9.pull.md b/versioned_docs/version-0.6/tools/cli/package-management/command-reference/9.pull.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/package-management/command-reference/9.pull.md rename to versioned_docs/version-0.6/tools/cli/package-management/command-reference/9.pull.md diff --git a/versioned_docs/version-0.5.1/reference/package-management/command-reference/_category_.json b/versioned_docs/version-0.6/tools/cli/package-management/command-reference/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/reference/package-management/command-reference/_category_.json rename to versioned_docs/version-0.6/tools/cli/package-management/command-reference/_category_.json diff --git a/versioned_docs/version-0.5.1/reference/package-management/command-reference/index.md b/versioned_docs/version-0.6/tools/cli/package-management/command-reference/index.md similarity index 100% rename from versioned_docs/version-0.5.1/reference/package-management/command-reference/index.md rename to versioned_docs/version-0.6/tools/cli/package-management/command-reference/index.md diff --git a/versioned_docs/version-0.5.1/user_docs/concepts/_category_.json b/versioned_docs/version-0.6/user_docs/concepts/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/user_docs/concepts/_category_.json rename to versioned_docs/version-0.6/user_docs/concepts/_category_.json diff --git a/versioned_docs/version-0.5.1/user_docs/concepts/concepts.md b/versioned_docs/version-0.6/user_docs/concepts/concepts.md similarity index 100% rename from versioned_docs/version-0.5.1/user_docs/concepts/concepts.md rename to versioned_docs/version-0.6/user_docs/concepts/concepts.md diff --git a/versioned_docs/version-0.5.1/user_docs/concepts/package-and-module.md b/versioned_docs/version-0.6/user_docs/concepts/package-and-module.md similarity index 100% rename from versioned_docs/version-0.5.1/user_docs/concepts/package-and-module.md rename to versioned_docs/version-0.6/user_docs/concepts/package-and-module.md diff --git a/versioned_docs/version-0.5.5/user_docs/concepts/type-and-definition.md b/versioned_docs/version-0.6/user_docs/concepts/type-and-definition.md similarity index 100% rename from versioned_docs/version-0.5.5/user_docs/concepts/type-and-definition.md rename to versioned_docs/version-0.6/user_docs/concepts/type-and-definition.md diff --git a/versioned_docs/version-0.5.1/user_docs/getting-started/_category_.json b/versioned_docs/version-0.6/user_docs/getting-started/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/user_docs/getting-started/_category_.json rename to versioned_docs/version-0.6/user_docs/getting-started/_category_.json diff --git a/versioned_docs/version-0.5.1/user_docs/getting-started/index.md b/versioned_docs/version-0.6/user_docs/getting-started/index.md similarity index 100% rename from versioned_docs/version-0.5.1/user_docs/getting-started/index.md rename to versioned_docs/version-0.6/user_docs/getting-started/index.md diff --git a/versioned_docs/version-0.6.0/user_docs/getting-started/install.md b/versioned_docs/version-0.6/user_docs/getting-started/install.md similarity index 100% rename from versioned_docs/version-0.6.0/user_docs/getting-started/install.md rename to versioned_docs/version-0.6/user_docs/getting-started/install.md diff --git a/versioned_docs/version-0.6.0/user_docs/getting-started/intro.md b/versioned_docs/version-0.6/user_docs/getting-started/intro.md similarity index 100% rename from versioned_docs/version-0.6.0/user_docs/getting-started/intro.md rename to versioned_docs/version-0.6/user_docs/getting-started/intro.md diff --git a/versioned_docs/version-0.5.1/user_docs/getting-started/kcl-quick-start.md b/versioned_docs/version-0.6/user_docs/getting-started/kcl-quick-start.md similarity index 100% rename from versioned_docs/version-0.5.1/user_docs/getting-started/kcl-quick-start.md rename to versioned_docs/version-0.6/user_docs/getting-started/kcl-quick-start.md diff --git a/versioned_docs/version-0.5.1/user_docs/guides/_category_.json b/versioned_docs/version-0.6/user_docs/guides/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/user_docs/guides/_category_.json rename to versioned_docs/version-0.6/user_docs/guides/_category_.json diff --git a/versioned_docs/version-0.5.1/user_docs/guides/_working-with-terraform/1-overview.md b/versioned_docs/version-0.6/user_docs/guides/_working-with-terraform/1-overview.md similarity index 100% rename from versioned_docs/version-0.5.1/user_docs/guides/_working-with-terraform/1-overview.md rename to versioned_docs/version-0.6/user_docs/guides/_working-with-terraform/1-overview.md diff --git a/versioned_docs/version-0.5.1/user_docs/guides/_working-with-terraform/2-abstraction.md b/versioned_docs/version-0.6/user_docs/guides/_working-with-terraform/2-abstraction.md similarity index 100% rename from versioned_docs/version-0.5.1/user_docs/guides/_working-with-terraform/2-abstraction.md rename to versioned_docs/version-0.6/user_docs/guides/_working-with-terraform/2-abstraction.md diff --git a/versioned_docs/version-0.5.1/user_docs/guides/_working-with-terraform/3-coverter.md b/versioned_docs/version-0.6/user_docs/guides/_working-with-terraform/3-coverter.md similarity index 100% rename from versioned_docs/version-0.5.1/user_docs/guides/_working-with-terraform/3-coverter.md rename to versioned_docs/version-0.6/user_docs/guides/_working-with-terraform/3-coverter.md diff --git a/versioned_docs/version-0.5.1/user_docs/guides/_working-with-terraform/_category_.json b/versioned_docs/version-0.6/user_docs/guides/_working-with-terraform/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/user_docs/guides/_working-with-terraform/_category_.json rename to versioned_docs/version-0.6/user_docs/guides/_working-with-terraform/_category_.json diff --git a/versioned_docs/version-0.5.3/user_docs/guides/abstraction.md b/versioned_docs/version-0.6/user_docs/guides/abstraction.md similarity index 100% rename from versioned_docs/version-0.5.3/user_docs/guides/abstraction.md rename to versioned_docs/version-0.6/user_docs/guides/abstraction.md diff --git a/versioned_docs/version-0.5.3/user_docs/guides/automation.md b/versioned_docs/version-0.6/user_docs/guides/automation.md similarity index 100% rename from versioned_docs/version-0.5.3/user_docs/guides/automation.md rename to versioned_docs/version-0.6/user_docs/guides/automation.md diff --git a/versioned_docs/version-0.5.3/user_docs/guides/ci-integration/1-github-actions.md b/versioned_docs/version-0.6/user_docs/guides/ci-integration/1-github-actions.md similarity index 100% rename from versioned_docs/version-0.5.3/user_docs/guides/ci-integration/1-github-actions.md rename to versioned_docs/version-0.6/user_docs/guides/ci-integration/1-github-actions.md diff --git a/versioned_docs/version-0.5.3/user_docs/guides/ci-integration/2-gitlab-ci.md b/versioned_docs/version-0.6/user_docs/guides/ci-integration/2-gitlab-ci.md similarity index 100% rename from versioned_docs/version-0.5.3/user_docs/guides/ci-integration/2-gitlab-ci.md rename to versioned_docs/version-0.6/user_docs/guides/ci-integration/2-gitlab-ci.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/ci-integration/_3-jenkins-ci.md b/versioned_docs/version-0.6/user_docs/guides/ci-integration/_3-jenkins-ci.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/ci-integration/_3-jenkins-ci.md rename to versioned_docs/version-0.6/user_docs/guides/ci-integration/_3-jenkins-ci.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/ci-integration/_category_.json b/versioned_docs/version-0.6/user_docs/guides/ci-integration/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/ci-integration/_category_.json rename to versioned_docs/version-0.6/user_docs/guides/ci-integration/_category_.json diff --git a/versioned_docs/version-0.5.3/user_docs/guides/configuration.md b/versioned_docs/version-0.6/user_docs/guides/configuration.md similarity index 100% rename from versioned_docs/version-0.5.3/user_docs/guides/configuration.md rename to versioned_docs/version-0.6/user_docs/guides/configuration.md diff --git a/versioned_docs/version-0.5.3/user_docs/guides/data-integration.md b/versioned_docs/version-0.6/user_docs/guides/data-integration.md similarity index 100% rename from versioned_docs/version-0.5.3/user_docs/guides/data-integration.md rename to versioned_docs/version-0.6/user_docs/guides/data-integration.md diff --git a/versioned_docs/version-0.5.3/user_docs/guides/gitops/1-quick-start.md b/versioned_docs/version-0.6/user_docs/guides/gitops/1-quick-start.md similarity index 100% rename from versioned_docs/version-0.5.3/user_docs/guides/gitops/1-quick-start.md rename to versioned_docs/version-0.6/user_docs/guides/gitops/1-quick-start.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/gitops/_category_.json b/versioned_docs/version-0.6/user_docs/guides/gitops/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/gitops/_category_.json rename to versioned_docs/version-0.6/user_docs/guides/gitops/_category_.json diff --git a/versioned_docs/version-0.5.1/user_docs/guides/index.md b/versioned_docs/version-0.6/user_docs/guides/index.md similarity index 100% rename from versioned_docs/version-0.5.1/user_docs/guides/index.md rename to versioned_docs/version-0.6/user_docs/guides/index.md diff --git a/versioned_docs/version-0.5.1/user_docs/guides/package-management/1-overview.md b/versioned_docs/version-0.6/user_docs/guides/package-management/1-overview.md similarity index 100% rename from versioned_docs/version-0.5.1/user_docs/guides/package-management/1-overview.md rename to versioned_docs/version-0.6/user_docs/guides/package-management/1-overview.md diff --git a/versioned_docs/version-0.5.3/user_docs/guides/package-management/2-installation.md b/versioned_docs/version-0.6/user_docs/guides/package-management/2-installation.md similarity index 100% rename from versioned_docs/version-0.5.3/user_docs/guides/package-management/2-installation.md rename to versioned_docs/version-0.6/user_docs/guides/package-management/2-installation.md diff --git a/versioned_docs/version-0.5.3/user_docs/guides/package-management/3-quick-start.md b/versioned_docs/version-0.6/user_docs/guides/package-management/3-quick-start.md similarity index 100% rename from versioned_docs/version-0.5.3/user_docs/guides/package-management/3-quick-start.md rename to versioned_docs/version-0.6/user_docs/guides/package-management/3-quick-start.md diff --git a/versioned_docs/version-0.6.0/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md b/versioned_docs/version-0.6/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md similarity index 100% rename from versioned_docs/version-0.6.0/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md rename to versioned_docs/version-0.6/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md diff --git a/versioned_docs/version-0.6.0/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md b/versioned_docs/version-0.6/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md similarity index 100% rename from versioned_docs/version-0.6.0/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md rename to versioned_docs/version-0.6/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md diff --git a/versioned_docs/version-0.6.0/user_docs/guides/package-management/4-how-to/6-push_github_action.md b/versioned_docs/version-0.6/user_docs/guides/package-management/4-how-to/6-push_github_action.md similarity index 100% rename from versioned_docs/version-0.6.0/user_docs/guides/package-management/4-how-to/6-push_github_action.md rename to versioned_docs/version-0.6/user_docs/guides/package-management/4-how-to/6-push_github_action.md diff --git a/versioned_docs/version-0.5.0/user_docs/guides/package-management/4-how-to/_category_.json b/versioned_docs/version-0.6/user_docs/guides/package-management/4-how-to/_category_.json similarity index 100% rename from versioned_docs/version-0.5.0/user_docs/guides/package-management/4-how-to/_category_.json rename to versioned_docs/version-0.6/user_docs/guides/package-management/4-how-to/_category_.json diff --git a/versioned_docs/version-0.5.1/user_docs/guides/package-management/_category_.json b/versioned_docs/version-0.6/user_docs/guides/package-management/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/user_docs/guides/package-management/_category_.json rename to versioned_docs/version-0.6/user_docs/guides/package-management/_category_.json diff --git a/versioned_docs/version-0.5.3/user_docs/guides/schema-definition.md b/versioned_docs/version-0.6/user_docs/guides/schema-definition.md similarity index 100% rename from versioned_docs/version-0.5.3/user_docs/guides/schema-definition.md rename to versioned_docs/version-0.6/user_docs/guides/schema-definition.md diff --git a/versioned_docs/version-0.5.2/user_docs/guides/secret-management/1-vault.md b/versioned_docs/version-0.6/user_docs/guides/secret-management/1-vault.md similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/guides/secret-management/1-vault.md rename to versioned_docs/version-0.6/user_docs/guides/secret-management/1-vault.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/secret-management/_category_.json b/versioned_docs/version-0.6/user_docs/guides/secret-management/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/secret-management/_category_.json rename to versioned_docs/version-0.6/user_docs/guides/secret-management/_category_.json diff --git a/versioned_docs/version-0.5.3/user_docs/guides/validation.md b/versioned_docs/version-0.6/user_docs/guides/validation.md similarity index 100% rename from versioned_docs/version-0.5.3/user_docs/guides/validation.md rename to versioned_docs/version-0.6/user_docs/guides/validation.md diff --git a/versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md b/versioned_docs/version-0.6/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md similarity index 100% rename from versioned_docs/version-0.6.0/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md rename to versioned_docs/version-0.6/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md diff --git a/versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md b/versioned_docs/version-0.6/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md similarity index 100% rename from versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md rename to versioned_docs/version-0.6/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md diff --git a/versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md b/versioned_docs/version-0.6/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md similarity index 100% rename from versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md rename to versioned_docs/version-0.6/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md diff --git a/versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md b/versioned_docs/version-0.6/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md similarity index 100% rename from versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md rename to versioned_docs/version-0.6/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md diff --git a/versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md b/versioned_docs/version-0.6/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md similarity index 100% rename from versioned_docs/version-0.5.3/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md rename to versioned_docs/version-0.6/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md diff --git a/versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md b/versioned_docs/version-0.6/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md similarity index 100% rename from versioned_docs/version-0.5.1/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md rename to versioned_docs/version-0.6/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md diff --git a/versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md b/versioned_docs/version-0.6/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md similarity index 100% rename from versioned_docs/version-0.5.4/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md rename to versioned_docs/version-0.6/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md diff --git a/versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/6-kcl-operator.md b/versioned_docs/version-0.6/user_docs/guides/working-with-k8s/3-mutate-manifests/6-kcl-operator.md similarity index 100% rename from versioned_docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/6-kcl-operator.md rename to versioned_docs/version-0.6/user_docs/guides/working-with-k8s/3-mutate-manifests/6-kcl-operator.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json b/versioned_docs/version-0.6/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json rename to versioned_docs/version-0.6/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/_category_.json b/versioned_docs/version-0.6/user_docs/guides/working-with-k8s/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/_category_.json rename to versioned_docs/version-0.6/user_docs/guides/working-with-k8s/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/index.md b/versioned_docs/version-0.6/user_docs/guides/working-with-k8s/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-k8s/index.md rename to versioned_docs/version-0.6/user_docs/guides/working-with-k8s/index.md diff --git a/versioned_docs/version-0.6.0/user_docs/guides/working-with-konfig/1-overview.md b/versioned_docs/version-0.6/user_docs/guides/working-with-konfig/1-overview.md similarity index 100% rename from versioned_docs/version-0.6.0/user_docs/guides/working-with-konfig/1-overview.md rename to versioned_docs/version-0.6/user_docs/guides/working-with-konfig/1-overview.md diff --git a/versioned_docs/version-0.6.0/user_docs/guides/working-with-konfig/2-structure.md b/versioned_docs/version-0.6/user_docs/guides/working-with-konfig/2-structure.md similarity index 100% rename from versioned_docs/version-0.6.0/user_docs/guides/working-with-konfig/2-structure.md rename to versioned_docs/version-0.6/user_docs/guides/working-with-konfig/2-structure.md diff --git a/versioned_docs/version-0.6.0/user_docs/guides/working-with-konfig/3-quick-start.md b/versioned_docs/version-0.6/user_docs/guides/working-with-konfig/3-quick-start.md similarity index 100% rename from versioned_docs/version-0.6.0/user_docs/guides/working-with-konfig/3-quick-start.md rename to versioned_docs/version-0.6/user_docs/guides/working-with-konfig/3-quick-start.md diff --git a/versioned_docs/version-0.5.1/user_docs/guides/working-with-konfig/4-best-practice.md b/versioned_docs/version-0.6/user_docs/guides/working-with-konfig/4-best-practice.md similarity index 100% rename from versioned_docs/version-0.5.1/user_docs/guides/working-with-konfig/4-best-practice.md rename to versioned_docs/version-0.6/user_docs/guides/working-with-konfig/4-best-practice.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-konfig/_category_.json b/versioned_docs/version-0.6/user_docs/guides/working-with-konfig/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/user_docs/guides/working-with-konfig/_category_.json rename to versioned_docs/version-0.6/user_docs/guides/working-with-konfig/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-kusion/_category_.json b/versioned_docs/version-0.6/user_docs/guides/working-with-kusion/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-kusion/_category_.json rename to versioned_docs/version-0.6/user_docs/guides/working-with-kusion/_category_.json diff --git a/versioned_docs/version-0.5.1/user_docs/guides/working-with-kusion/index.md b/versioned_docs/version-0.6/user_docs/guides/working-with-kusion/index.md similarity index 100% rename from versioned_docs/version-0.5.1/user_docs/guides/working-with-kusion/index.md rename to versioned_docs/version-0.6/user_docs/guides/working-with-kusion/index.md diff --git a/versioned_docs/version-0.6.0/user_docs/guides/working-with-terraform/3-validation.md b/versioned_docs/version-0.6/user_docs/guides/working-with-terraform/3-validation.md similarity index 100% rename from versioned_docs/version-0.6.0/user_docs/guides/working-with-terraform/3-validation.md rename to versioned_docs/version-0.6/user_docs/guides/working-with-terraform/3-validation.md diff --git a/versioned_docs/version-0.6.0/user_docs/guides/working-with-terraform/_1-adopt-from-terraform.md b/versioned_docs/version-0.6/user_docs/guides/working-with-terraform/_1-adopt-from-terraform.md similarity index 100% rename from versioned_docs/version-0.6.0/user_docs/guides/working-with-terraform/_1-adopt-from-terraform.md rename to versioned_docs/version-0.6/user_docs/guides/working-with-terraform/_1-adopt-from-terraform.md diff --git a/versioned_docs/version-0.6.0/user_docs/guides/working-with-terraform/_2-abstraction.md b/versioned_docs/version-0.6/user_docs/guides/working-with-terraform/_2-abstraction.md similarity index 100% rename from versioned_docs/version-0.6.0/user_docs/guides/working-with-terraform/_2-abstraction.md rename to versioned_docs/version-0.6/user_docs/guides/working-with-terraform/_2-abstraction.md diff --git a/versioned_docs/version-0.6.0/user_docs/guides/working-with-terraform/_category_.json b/versioned_docs/version-0.6/user_docs/guides/working-with-terraform/_category_.json similarity index 100% rename from versioned_docs/version-0.6.0/user_docs/guides/working-with-terraform/_category_.json rename to versioned_docs/version-0.6/user_docs/guides/working-with-terraform/_category_.json diff --git a/versioned_docs/version-0.5.1/user_docs/support/_category_.json b/versioned_docs/version-0.6/user_docs/support/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/user_docs/support/_category_.json rename to versioned_docs/version-0.6/user_docs/support/_category_.json diff --git a/versioned_docs/version-0.5.1/user_docs/support/faq-cli.md b/versioned_docs/version-0.6/user_docs/support/faq-cli.md similarity index 100% rename from versioned_docs/version-0.5.1/user_docs/support/faq-cli.md rename to versioned_docs/version-0.6/user_docs/support/faq-cli.md diff --git a/versioned_docs/version-0.6.0/user_docs/support/faq-install.md b/versioned_docs/version-0.6/user_docs/support/faq-install.md similarity index 100% rename from versioned_docs/version-0.6.0/user_docs/support/faq-install.md rename to versioned_docs/version-0.6/user_docs/support/faq-install.md diff --git a/versioned_docs/version-0.6.0/user_docs/support/faq-kcl.md b/versioned_docs/version-0.6/user_docs/support/faq-kcl.md similarity index 100% rename from versioned_docs/version-0.6.0/user_docs/support/faq-kcl.md rename to versioned_docs/version-0.6/user_docs/support/faq-kcl.md diff --git a/versioned_docs/version-0.5.1/user_docs/support/faq-yaml.md b/versioned_docs/version-0.6/user_docs/support/faq-yaml.md similarity index 100% rename from versioned_docs/version-0.5.1/user_docs/support/faq-yaml.md rename to versioned_docs/version-0.6/user_docs/support/faq-yaml.md diff --git a/versioned_docs/version-0.5.1/user_docs/support/support.md b/versioned_docs/version-0.6/user_docs/support/support.md similarity index 100% rename from versioned_docs/version-0.5.1/user_docs/support/support.md rename to versioned_docs/version-0.6/user_docs/support/support.md diff --git a/versioned_docs/version-0.7.0/community/contribute/_category_.json b/versioned_docs/version-0.7.0/community/contribute/_category_.json deleted file mode 100644 index e2dca064..00000000 --- a/versioned_docs/version-0.7.0/community/contribute/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Contribution Guide", - "position": 4 -} diff --git a/versioned_docs/version-0.7.0/community/contribute/contribute-code.md b/versioned_docs/version-0.7.0/community/contribute/contribute-code.md deleted file mode 100644 index f4e9169b..00000000 --- a/versioned_docs/version-0.7.0/community/contribute/contribute-code.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -sidebar_position: 2 ---- - -# How to Contribute Code? - -Welcome to participate in the KCL co construction to improve the code, documentation and testing, and also welcome to provide feedback through Issues. If you want to add KCL language features, please submit through the [KEP](https://github.com/kcl-lang/KEP) process. - -## 1. Misspellings in Code and Comments - -If you only need to modify the typos in the code and comments, you can directly modify and submit the PR to the repository. It is important to keep the code style as consistent as possible. - -## 2. How to Contribute KCL - -See [KCL contribute guide](https://github.com/kcl-lang/kcl/blob/main/docs/dev_guide/1.about_this_guide.md) for more information. - -## 3. How to Contribute VS Code KCL Plugin - -See [VS Code KCL plugin contribute guide](https://github.com/kcl-lang/vscode-kcl/blob/main/docs/CONTRIBUTING.md) for more information. diff --git a/versioned_docs/version-0.7.0/community/contribute/contribute-docs.md b/versioned_docs/version-0.7.0/community/contribute/contribute-docs.md deleted file mode 100644 index 2b400a52..00000000 --- a/versioned_docs/version-0.7.0/community/contribute/contribute-docs.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -sidebar_position: 1 ---- - -# How to Contribute Document? - -This document mainly makes partial modifications to existing documents. If you are submitting blog posts, adding new documents or adjusting the document directory structure, please contact team members first. - -KCL documents are divided into user guides, development documents, internal documents, reference manuals and blog articles. Their differences are as follows: - -- User's Guide: The corresponding usage document allows users to quickly use the KCL tool to complete their work at the minimum cost, without involving too much internal principles and implementation -- Reference: KCL language, tools, IDE and other documents with all features, covering the most extensive but trivial content -- Blog: There are no special restrictions. They can be shared for specific scenarios, technical points or overall development prospects - -When contributing different types of documents, it is better to combine the above positioning to make some appropriate tailoring for different content to give readers the best experience. - -## 1. Basic Specifications - -- In addition to the title, the internal subtitles shall be numbered as much as possible for easy reading -- The document automatically output by the tool needs a link to the source code, and the subtitle can be without number -- Try not to paste large pieces of code (within 30 lines). It is better to provide text explanations and corresponding reference links for the code -- There are diagrams and truths, but overly complex architecture diagrams are not recommended -- Internal link: in the form of [`/docs/user_docs/getting-started/intro`](/docs/user_docs/getting-started/intro) absolute path - -**Punctuation and space** - -- Chinese punctuation is preferred in Chinese documents -- One space is required between Chinese and English -- One space needs to be added between Chinese and numbers -- Chinese uses full width punctuation without adding spaces before and after punctuation -- English content uses half width punctuation, with a space after the punctuation -- You need to leave a space before and after the link, but you do not need to add a space near the beginning of the paragraph and Chinese full width punctuation. - -**Picture and resource file names** - -- The file name and directory name can only use numbers, English letters and underscores`_` And minus sign '-' -- Pictures of the current document are placed in the images directory of the current directory -- Vector pictures can be viewed through [drawio offline version](https://github.com/jgraph/drawio-desktop/releases) (and submit source files at the same time), and export png format pictures at 200% resolution - -## 2. Basic mode of using document content - -Each usage document can be regarded as a relatively complete sharing or blog post (the reference manual is no longer such). Using documents to organize content follows the following pattern: - -1. Overview: What problems do you want to solve and what effects do you want to achieve in this article? You can put a screenshot of the final effect first -2. Dependent environment: what tools need to be installed, and provide relevant links -3. Introduce this article to build a relationship diagram or architecture diagram of resources -4. Give the test method. Try to use community common methods (such as kube, curl command, or browser) to test -5. Summary and Outlook. Briefly review the current operation process and some places that can be expanded (some links can be given) - -## 3. Test and submit PR - -First, clone the document warehouse, and then test the viewing effect locally with the 'npm run start' and 'npm run build' commands to ensure that you can browse normally and then submit PR. diff --git a/versioned_docs/version-0.7.0/community/contribute/contribute.md b/versioned_docs/version-0.7.0/community/contribute/contribute.md deleted file mode 100644 index dd6e2b3f..00000000 --- a/versioned_docs/version-0.7.0/community/contribute/contribute.md +++ /dev/null @@ -1,3 +0,0 @@ -# Contribute Guide - -If it is the first time to participate in the open-source community, you can first check the similar changes in Issue and PR (PullRequest). Then you can fully discuss your own problems with the community or development team classmates, and you can also feedback the problems encountered by creating issues, and then you can provide code patches for related issues. At the beginning, you can start with document improvement and partial code improvement, such as: documentation, Examples, multi-language Binding, etc. At the same time, students who want to participate deeply can contribute to core features such as language functions, language testing, programming frameworks, and various backends. diff --git a/versioned_docs/version-0.7.0/community/intro/_category_.json b/versioned_docs/version-0.7.0/community/intro/_category_.json deleted file mode 100644 index a9646363..00000000 --- a/versioned_docs/version-0.7.0/community/intro/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Community", - "position": 1 -} diff --git a/versioned_docs/version-0.7.0/community/intro/intro.md b/versioned_docs/version-0.7.0/community/intro/intro.md deleted file mode 100644 index 4b1a7f02..00000000 --- a/versioned_docs/version-0.7.0/community/intro/intro.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Community - -Welcome to the KCL open-source community, everyone's participation is the driving force for the healthy growth of all open-source projects! There are many ways to participate in open-source. Everyone can create Issues or fix bugs, improve documentation or modify code by submitting PR (Pull Request), or open new feature discussions by submitting KEP, or share stories about the process of evangelism and use of KCL with surrounding friends. - -See the [community](https://github.com/kcl-lang/community) for ways to join us. diff --git a/versioned_docs/version-0.7.0/community/intro/license.md b/versioned_docs/version-0.7.0/community/intro/license.md deleted file mode 100644 index 4d0097b4..00000000 --- a/versioned_docs/version-0.7.0/community/intro/license.md +++ /dev/null @@ -1,211 +0,0 @@ ---- -sidebar_position: 99 ---- - -# License - -KCL Use [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) License: - -``` - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2023 The KCL Authors. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -``` diff --git a/versioned_docs/version-0.7.0/community/intro/support.md b/versioned_docs/version-0.7.0/community/intro/support.md deleted file mode 100644 index 7ed2e1a8..00000000 --- a/versioned_docs/version-0.7.0/community/intro/support.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Ask for help - -KCL has a developer and user community of many enthusiasts. - -On this page, we list the KCL-related communities you can participate in; see other pages in this section for additional online and offline learning materials. - -Before joining the KCL community, please read the [Contributor Covenant](https://www.contributor-covenant.org/version/2/0/code_of_conduct/) , which is expected to be followed by all community members. - -## Discussions - -- Submit an issue on Github -- Communicate in the Github discussion group -- Get the latest status through official website, Github, Twitter, Slack, Wechat and other accounts. See the [community](https://github.com/kcl-lang/community) for ways to join us. - -## New Features - -Please try to avoid submitting pull requests for new features, we may already have someone working on them, or maybe this feature is already part of our future plans. In conclusion, please contact us before submitting new features! diff --git a/versioned_docs/version-0.7.0/community/release-policy/_category_.json b/versioned_docs/version-0.7.0/community/release-policy/_category_.json deleted file mode 100644 index bc39d651..00000000 --- a/versioned_docs/version-0.7.0/community/release-policy/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Release Policy", - "position": 3 -} diff --git a/versioned_docs/version-0.7.0/community/release-policy/index.md b/versioned_docs/version-0.7.0/community/release-policy/index.md deleted file mode 100644 index c87091d0..00000000 --- a/versioned_docs/version-0.7.0/community/release-policy/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# Release Policy - -The release policy defines the semantics of the release, the release process, etc. In order to maximize the concurrent development process, KCL, etc. adopt independent release strategies. diff --git a/versioned_docs/version-0.7.0/reference/_advanced-concepts/_category_.json b/versioned_docs/version-0.7.0/reference/_advanced-concepts/_category_.json deleted file mode 100644 index 85a16abb..00000000 --- a/versioned_docs/version-0.7.0/reference/_advanced-concepts/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Advanced-Concepts", - "position": 6 -} diff --git a/versioned_docs/version-0.7.0/reference/_advanced-concepts/build_cache.md b/versioned_docs/version-0.7.0/reference/_advanced-concepts/build_cache.md deleted file mode 100644 index 746e2351..00000000 --- a/versioned_docs/version-0.7.0/reference/_advanced-concepts/build_cache.md +++ /dev/null @@ -1 +0,0 @@ -# Building Cache diff --git a/versioned_docs/version-0.7.0/reference/_category_.json b/versioned_docs/version-0.7.0/reference/_category_.json deleted file mode 100644 index 1b337d5a..00000000 --- a/versioned_docs/version-0.7.0/reference/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Reference", - "position": 5 -} diff --git a/versioned_docs/version-0.7.0/reference/cheatsheets/_category_.json b/versioned_docs/version-0.7.0/reference/cheatsheets/_category_.json deleted file mode 100644 index 80464148..00000000 --- a/versioned_docs/version-0.7.0/reference/cheatsheets/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Cheat Sheet", - "position": 10 -} diff --git a/versioned_docs/version-0.7.0/reference/cheatsheets/index.md b/versioned_docs/version-0.7.0/reference/cheatsheets/index.md deleted file mode 100644 index da4189eb..00000000 --- a/versioned_docs/version-0.7.0/reference/cheatsheets/index.md +++ /dev/null @@ -1,5 +0,0 @@ -# KCL Cheat Sheet - -![](/img/docs/reference/cheatsheets/cheatsheet.png) - -[Download PDF](https://github.com/kcl-lang/kcl-lang.io/blob/main/cheatsheet/cheatsheet.pdf) diff --git a/versioned_docs/version-0.7.0/reference/lang/_category_.json b/versioned_docs/version-0.7.0/reference/lang/_category_.json deleted file mode 100644 index 4c823148..00000000 --- a/versioned_docs/version-0.7.0/reference/lang/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Tutorial", - "position": 1 -} diff --git a/versioned_docs/version-0.7.0/reference/lang/codelab/_category_.json b/versioned_docs/version-0.7.0/reference/lang/codelab/_category_.json deleted file mode 100644 index 2e047bcb..00000000 --- a/versioned_docs/version-0.7.0/reference/lang/codelab/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Code Lab", - "position": 2 -} diff --git a/versioned_docs/version-0.7.0/reference/lang/codelab/collaborative.md b/versioned_docs/version-0.7.0/reference/lang/codelab/collaborative.md deleted file mode 100644 index 84ee8160..00000000 --- a/versioned_docs/version-0.7.0/reference/lang/codelab/collaborative.md +++ /dev/null @@ -1,345 +0,0 @@ ---- -title: "Co-configuration with config operations" -linkTitle: "Co-configuration with config operations" -type: "docs" -weight: 2 -description: Co-configuration with config operations -sidebar_position: 3 ---- - -## 1. Introduction - -KCL is a simple and easy-to-use configuration language, where users can simply write the reusable configuration code. - -In this codelab, we will learn how to write the config in a collaborative way using the KCL config operation features. - -### What We Will Learn - -1. Define schemas and organize project directories. -2. Create multiple environment configurations via the KCL config operation features. -3. Configure compiling parameters and tests. - -## 2. Define Schemas and Organize Project Directories - -### Schema Definitions - -Suppose we want to define a server configuration with certain attributes, we can create a simple config by creating a `server.k`, we can fill in the following code as below which defines a reusable schema of the configuration of a server. - -```python -import units - -type Unit = units.NumberMultiplier - -schema Server: - replicas: int = 1 - image: str - resource: Resource = {} - mainContainer: Main = {} - labels?: {str:str} - annotations?: {str:str} - -schema Main: - name: str = "main" - command?: [str] - args?: [str] - ports?: [Port] - -schema Resource: - cpu?: int = 1 - memory?: Unit = 1024Mi - disk?: Unit = 10Gi - -schema Port: - name?: str - protocol: "HTTP" | "TCP" - port: 80 | 443 - targetPort: int - - check: - targetPort > 1024, "targetPort must be larger than 1024" -``` - -In the code above, we define a schema named `Server`, which represents the configuration type that the user will write, which contains some basic type attributes (e.g., `replicas`, `image`, etc) and some composite type attributes (e.g., `resource`, `main`, etc). In addition to some basic types mentioned in the [schema codelab](./schema.md), we can see two types in the above code `Unit` and `units.NumberMultiplier`. Among them, `units.NumberMultiplier` denotes the KCL number unit type, which means that a natural unit or binary unit can be added after the KCL number, such as `1K` for `1000`, `1Ki` for `1024`. `Unit` is the type alias of `units.NumberMultiplier`, which is used to simplify the writing of type annotations. - -### Project Directories - -In order to complete the collaborative configuration development, we first need a configuration project, which contains the configuration of the test application and the differential configuration of different environments, so we are creating the following project directory: - -``` -. -├── appops -│ └── test_app -│ ├── base -│ │ └── base.k -│ ├── dev -│ │ ├── ci-test -│ │ │ └── stdout.golden.yaml -│ │ ├── kcl.yaml -│ │ └── main.k -│ └── prod -│ ├── ci-test -│ │ └── stdout.golden.yaml -│ ├── kcl.yaml -│ └── main.k -├── kcl.mod -└── pkg - └── sever.k -``` - -The directory of the project mainly contains three parts: - -- `kcl.mod`: The file used to identify the root directory of the KCL project. -- `pkg`: `Server` Schema structure reused by different application configurations. -- `appops`: Server configurations of different applications, currently only one application `test_app` is placed. - - `base`: Application common configurations for all environments. - - `dev`: Application configuration for the development environment. - - `prod`: Application configuration for the production environment. - -The meaning of `base.k`, `main.k`, `kcl.yaml` and `ci-test/stdout.golden.yaml` will be mentioned in subsequent sections. - -## 3. Create multiple environment configurations via the KCL config operation features - -### Create a baseline configuration - -After we have organized the project directory and the basic server configuration model, we can write the configuration of the user application. We can create our own test application folder `test_app` and place it in the application configuration folder `appops`. - -For the configuration of an application, we often divide it into a basic configuration and the differential configuration of multiple environments and merge them. Through the configuration merging feature of KCL, we can easily do this. Assuming that we have two configurations of development environment and production environment, we can create three folders: `base`, `dev` and `prod` to store baseline, development environment and production environment configurations respectively. First, we write the configuration of `base/base.k`: - -```python -import pkg - -server: pkg.Server { - # Set the image with the value "nginx:1.14.2" - image = "nginx:1.14.2" - # Add a label app into labels - labels.app = "test_app" - # Add a mainContainer config, and its ports are [{protocol = "HTTP", port = 80, targetPort = 1100}] - mainContainer.ports = [{ - protocol = "HTTP" - port = 80 - targetPort = 1100 - }] -} -``` - -As in the above code, we use the `import` keyword in `base.k` to import the `Server` schema placed under `pkg` and use it to instantiate a configuration named `server`, in which we set `image` attribute to `"nginx:1.14.2"`, and a label `app` with the value `test_app` is added. In addition, we also added the configuration of the main container `mainContainer` with the value `[{protocol = "HTTP", port = 80, targetPort = 1100}]` for the ports attribute. - -KCL command: - -```bash -kcl appops/test_app/base/base.k -``` - -Output: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2 - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app -``` - -At this point, we have a baseline configuration. - -### Create multiple environment configurations - -Next we configure a differentiated multi-environment configuration. First assume that we want to use a temporary image of our own `nginx:1.14.2-dev` in the development environment, and then use it to override the server configuration in the baseline, we can write the following configuration in `dev/main.k`: - -```python -import pkg - -server: pkg.Server { - # Override the image declared in the base - image = "nginx:1.14.2-dev" -} -``` - -KCL command: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -Output: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app -``` - -It can be seen that the `image` field of the output YAML is overwritten to `nginx:1.14.2-dev`. Suppose we also want to add a label to the `dev` environment with a key of `env` and a value of `dev`, we add the following code to `dev/main.k`: - -```python -import pkg - -server: pkg.Server { - # Override the image declared in the base - image = "nginx:1.14.2-dev" - # Union a new label env into base labels - labels.env = "dev" -} -``` - -KCL command: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app - env: dev -``` - -It can be seen that there are two labels in the `labels` field of the output YAML. - -In addition, we can also use the `+=` operator to add new values to list type attributes, such as the `mainContainer.ports` configuration in the baseline environment, continue to modify the code in `dev/main.k`: - -```python -import pkg - -server: pkg.Server { - # Override the base image. - image = "nginx:1.14.2-dev" - # Union a new label env into base labels. - labels.env = "dev" - # Append a port into base ports. - mainContainer.ports += [{ - protocol = "TCP" - port = 443 - targetPort = 1100 - }] -} -``` - -KCL command: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -Output: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - - protocol: TCP - port: 443 - targetPort: 1100 - labels: - app: test_app - env: dev -``` - -Using the same method, we can build the production configuration, write the code in the `dev/main.k` file, and add a label to it. - -```python -import pkg - -server: pkg.Server { - # Union a new label env into base labels - labels.env = "prod" -} -``` - -KCL command: - -```bash -kcl appops/test_app/base/base.k appops/test_app/prod/main.k -``` - -Output: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2 - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app - env: prod -``` - -## 4. Configure compiling parameters and tests - -In the previous section, we built a multi-environment configuration through code. It can be seen that the KCL command line compilation parameters of different environments are similar, so we can configure these compilation parameters into a file and input them to the KCL command line for invocation. Configure the following code in `dev/kcl.yaml`: - -```yaml -kcl_cli_configs: - files: - - ../base/base.k - - main.k - output: ./ci-test/stdout.golden.yaml -``` - -Then we can compile the configuration in the development environment with the following command: - -```bash -cd appops/test_app/dev && kcl -Y ./kcl.yaml -``` - -In addition, we have configured the `output` field in `dev/kcl.yaml` to output YAML to a file for subsequent configuration distribution or testing. You can verify that the application's configuration is as expected by walking through the `kcl.yaml` builds in each environment and comparing with `./ci-test/stdout.golden.yaml`. - -## 5. The Final Step - -Congratulations! - -We have completed the third lesson about KCL. diff --git a/versioned_docs/version-0.7.0/reference/lang/codelab/index.md b/versioned_docs/version-0.7.0/reference/lang/codelab/index.md deleted file mode 100644 index dbe554a9..00000000 --- a/versioned_docs/version-0.7.0/reference/lang/codelab/index.md +++ /dev/null @@ -1 +0,0 @@ -# Code Lab diff --git a/versioned_docs/version-0.7.0/reference/lang/codelab/schema.md b/versioned_docs/version-0.7.0/reference/lang/codelab/schema.md deleted file mode 100644 index 02f792d4..00000000 --- a/versioned_docs/version-0.7.0/reference/lang/codelab/schema.md +++ /dev/null @@ -1,817 +0,0 @@ ---- -title: "Write complex config using KCL Schema" -linkTitle: "Write complex config using KCL Schema" -type: "docs" -weight: 2 -description: Write complex config using KCL Schema -sidebar_position: 2 ---- - -## 1. Introduction - -KCL is a simple and easy-to-use configuration language, where users can simply write the reusable configuration code. - -In this codelab, we will learn how to write customized config using KCL, such that we can define a schema and write the config in a collaborative way. - -### What We Will Learn - -1. Define a simple schema -2. Set default immutable values to schema fields -3. Create config based on a simple schema -4. Write complex logic in schema -5. Create a new schema via schema combinations -6. Create a config of a deeply nested schema using dict/map -7. Create new schema via schema inheritance -8. Create new schema via multiple mixin schemas -9. Declare validation rules for the schema -10. Config schema output layout -11. Share and reuse schema - -## 2. Write Simple Schema - -Suppose we want to define a workload with certain attributes, we can create a simple config by creating a `my_config.k`, we can fill in the following code as below which defines a reusable schema of the configuration of deploy. - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels: {str:str} -``` - -In the code above, `cpu` and `memory` are defined as int value; `name`, `image` and `service` are string; `command` is a list of string type; `labels` is a dict type, whose key type and value type are both string. - -Besides, each attribute **must** be assigned with a not-None value as a schema instance unless it is modified by a question mark **?** as an optional attribute. - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels?: {str:str} # labels is an optional attribute -``` - -When there is an inheritance relationship: - -- If the attribute is optional in the base schema, it could be optional or required in the sub-schema. -- If the attribute is required in the base schema, it must be required in the sub-schema. - -## 3. Enhance Schema as Needed - -Suppose we need to set default values to service and replica, we can make them as below: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str = "my-service" # defaulting - replica: int = 1 # defaulting - command: [str] - labels?: {str:str} # labels is an optional attribute -``` - -And then we can set the service type annotation as the string literal type to make it immutable: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: "my-service" = "my-service" - replica: int = 1 - command: [str] - labels?: {str:str} -``` - -In the schema, type hint is a `must`, for example we can define cpu as `cpu: int`. - -Specially, we can define a string-interface dict as `{str:}`, and in case we want to define an object or interface, just define as `{:}`. - -## 4. Create Config Based on Simple Schema - -Now we have a simple schema definition, we can use it to define config as: - -```python -nginx = Deployment { - name = "my-nginx" - cpu = 256 - memory = 512 - image = "nginx:1.14.2" - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } -} -``` - -Run with the following KCL command, we should be able to see the generated yaml files as the output as below: - -KCL command: - -``` - kcl my_config.k -``` - -Stdout: - -```yaml -nginx: - name: my-nginx - cpu: 256 - memory: 512 - image: nginx:1.14.2 - service: my-service - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -> Check the manual and specification out for more details about collection data types and block. - -In addition, the **config selector expressions** can be used to init a schema instance, and we can ignore the comma at the end of the line in the config expression. - -```python -nginx = Deployment { - name = "my-nginx" - cpu = 256 - memory = 512 - image = "nginx:1.14.2" - command = ["nginx"] # Ignore the comma at the end of the line - labels.run = "my-nginx" # A dict variable in schema can use selector expressions - labels.env = "pre-prod" # A dict variable in schema can use selector expressions -} -``` - -## 5. Write More Complex Logic in Schema - -Suppose we have some schema logic, we can wrapper it into schema: - -```python -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - image: str - service: "my-service" = "my-service" - replica: int = 1 - command: [str] - labels?: {str:str} - - _cpu = 2048 - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 -``` - -Now, we can define a config by creating a schema instance and pass in priority as an argument to schema: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -Run with kcl, we should see the generated yaml files as output as below: - -KCL command: - -``` -kcl my_config.k -``` - -Stdout: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - image: nginx:1.14.2 - service: my-service - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 6. Create New Schema via Schema Combinations - -Now we want to define a detailed schema with service and volumes, we can do it as follows: - -```python -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - volumes?: [Volume] - image: str - service?: Service - replica: int = 1 - command: [str] - labels?: {str:str} - - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 - -schema Port: - name: str - protocol: str - port: int - targetPort: int - -schema Service: - name: "my-service" = "my-service" - ports: [Port] - -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -In this case, Deployment is composed of Service and a list of Volumes, and Service is composed of a list of Ports. - -## 7. Create Config of Deeply Nested Schema using Dict/Map - -Now we have a new Deployment schema, however, we may notice that it contains multiple layers of nested structures, in fact, this is very common in complex structure definitions, and we often have to write imperative assembly code to generate the final structure. - -With KCL, we can create the config with simple dict declaration, with the capability of full schema initialization and validation. For example, we can simply config nginx by the new Deployment schema as follows: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -Run with KCL, we will see the generated yaml files as below: - -KCL command: - -``` -kcl my_config.k -``` - -Stdout: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -Note that, the dict that we use to define Deployment config must be aligned with the schema definition, otherwise we will get an error. For example, suppose we define a wrong type of service port as below: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = [80] # wrong data type, trying to assign List to int - targetPort = 9376 - }] -} -``` - -Run with KCL, we will see the error message as output as below: - -KCL command: - -```python -kcl my_config.k -``` - -Stderr: - -``` -The type got is inconsistent with the type expected: expect int, got [int(80)] -``` - -## 8. Declare Schema Validation Rules - -Now we have seen a complex schema, in which every field has a type hint to make it less error-prone. But this is not good enough, we want to support more enhanced verifications to our schemas, so that code errors in schemas and configs can be discovered as soon as possible. - -Lots of validation rules, like None type check, range check, value check, length check, regular expression matching, enum check have already been added or in progress. Here is a code sample: - -```python -import regex - -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - volumes?: [Volume] - image: str - service?: Service - replica: int = 1 - command: [str] - labels?: {str:str} - - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 - - check: - multiplyof(cpu, 256), "cpu must be a multiplier of 256" - regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$"), "image name should be like 'nginx:1.14.2'" - 1 <= replica < 100, "replica should be in range (1, 100)" - len(labels) >= 2 if labels, "the length of labels should be large or equal to 2" - "env" in labels, "'env' must be in labels" - len(command) > 0, "the command list should be non-empty" - -schema Port: - name: str - protocol: str - port: int - targetPort: int - - check: - port in [80, 443], "we can only expose 80 and 443 port" - protocol in ["HTTP", "TCP"], "protocol must be either HTTP or TCP" - 1024 < targetPort, "targetPort must be larger than 1024" - -schema Service: - name: "my-service" = "my-service" - ports: [Port] - - check: - len(ports) > 0, "ports list must be non-empty" - -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -Since the attributes defined by the schema are **required** by default, the verification that judges that the variable cannot be None/Undefined can be omitted. - -```python -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -Now we can write the config based on the new schema and expose config errors in time. For example, with the invalid config as below: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1142" # image value is not matching the regex - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -Every field is type-valid, but the image name is invalid. - -Run with KCL, we will see the error message as below: - -KCL command: - -``` -kcl my_config.k -``` - -Stderr: - -``` -Schema check is failed to check condition: regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$"), "image name should be like 'nginx:1.14.2'" -``` - -> The verification capability of KCL covers the verification defined by Openapi so that we can write any API verifications through KCL. - -## 9. Create New Schema via Schema Inheritance - -Now we have a solid Deployment schema definition and we can use it to declare config. - -Usually, schema Deployment will be used in multiple scenarios. We can directly use the schema to declare the configurations in different use cases (see the above section), or we can produce a more specific schema definition through inheritance. - -For example, we can use the Deployment schema as a basis, to define the nginx's base schema, and extend the definition -in each scenario. - -In this case, we define some commonly used attributes. Please note that we mark the name to be immutable with the 'final' keyword to prevent it from being overwritten. - -```python -schema Nginx(Deployment): - """ A base nginx schema """ - name: "my-nginx" = "my-nginx" - image: str = "nginx:1.14.2" - replica: int = 3 - command: [str] = ["nginx"] - -schema NginxProd(Nginx): - """ A prod nginx schema with stable configurations """ - volumes: [Volume] = [{ - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - """ A volume mapped to host path """ - service: Service = { - ports = [{ - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] - } - """ An 80 port to target backend server """ -``` - -Now we have some static configurations for nginx. It is recommended to declare configurations that we think are static there, and put more dynamic configurations as below: - -```python -nginx = Nginx { - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -```python -nginx = NginxProd { - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -Now, we can simply define nginx prod config just with runtime label value "prod" which is not that static. - -In fact, under some complex situation, we can split all configurations into the basic, business, and environment configuration definitions in this way, and achieve collaboration among team members based on this. - -Run with KCL, we will see the generated yaml files as output as below: - -KCL command: - -``` -kcl prod_config.k -``` - -Stdout: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 3 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 10. Create New Schema by Multiple Protocol and Mixin Schemas Inheritance - -Now, we can complete the declaration of the server configuration through the Deployment schema. - -However, usually, the actual situation is more complicated, and the deployment may have a variety of optional variable accessories. - -For example, we want to support a persistent volume claim based on an existing schema, as a reusable Kubernetes schema. In this case, we can just wrapper it with a `mixin` and a `protocol` as follows: - -```python -import k8spkg.api.core.v1 - -protocol PVCProtocol: - pvc?: {str:} - -mixin PersistentVolumeClaimMixin for PVCProtocol: - """ - PersistentVolumeClaim (PVC) sample: - Link: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims - """ - - # Mix in a new attribute `kubernetesPVC` - kubernetesPVC?: v1.PersistentVolumeClaim - - if pvc: - kubernetesPVC = v1.PersistentVolumeClaim { - metadata.name = pvc.name - metadata.labels = pvc.labels - spec = { - accessModes = pvc.accessModes - resources = pvc.resources - storageClassName = pvc.storageClassName - } - } -``` - -With this PersistentVolumeClaimMixin, we define a PVC schema with a clear `user interface`, and use Kubernetes PVC as an implementation. Then, we can define a server schema with Deployment schema, and PVC mixin schema. - -``` -schema Server(Deployment): - mixin [PersistentVolumeClaimMixin] - pvc?: {str:} - """ pvc user interface data defined by PersistentVolumeClaimMixin """ -``` - -In the Server schema, Deployment is the base schema, and PersistentVolumeClaimMixin is an optional add-on whose user interface data is `pvc?: {str:}`. - -Note, the `mixin` is often used to add new attributes to the host schema, or to modify the existing attributes of the host schema. Thus, `mixin` can use the attributes in the host schema. Since the `mixin` is designed to be reusable, we need an additional `protocol` to constrain the attribute names and types in the host schema for the `mixin`. - -Now, if we want a deploy with a PVC, just declare as user interface: - -```python -server = Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] - pvc = { - name = "my_pvc" - accessModes = ["ReadWriteOnce"] - resources.requests.storage = "8Gi" - storageClassName = "slow" - } -} -``` - -Run with kcl, we will see the generated yaml files as output as below: - -KCL command: - -``` -kcl server.k -``` - -Stdout: - -```yaml -server: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod - pvc: - name: my_pvc - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 8Gi - storageClassName: slow ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: my_pvc -spec: - accessModes: - - ReadWriteOnce - storageClassName: slow - resources: - requests: - storage: 8Gi -``` - -If we don't want a persistent volume, just remove the pvc config block. - -## 11. Share and Reuse Schema - -The Server schema could be shared via `import`, we can simply package our code with KCL. - -```python -import pkg - -server = pkg.Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -Another skill we should know about sharing code is, modules under the same package do not need to import each other. - -Suppose we have models in a pkg: - -``` -pkg/ - - deploy.k - - server.k - - pvc.k -``` - -And in `server.k`, we can just use Deployment schema in `deploy.k` and pvc schema in `pvc.k` without import: - -```python -# no import needed -schema Server(Deployment): - mixin [PersistentVolumeClaimMixin] - pvc?: {str:} - """ pvc user interface data defined by PersistentVolumeClaimMixin """ -``` - -And then users must import the pkg to use it as a whole: - -```python -import pkg - -server = pkg.Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [pkg.Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } - service.ports = [pkg.Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -Run kcl command: - -``` -kcl pkg_server.k -``` - -Output: - -```yaml -server: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 12. The Final Step - -Congratulations! - -We have completed the second lesson about KCL, we have used KCL to replace our key-value text file to get better programming support. diff --git a/versioned_docs/version-0.7.0/reference/lang/codelab/simple.md b/versioned_docs/version-0.7.0/reference/lang/codelab/simple.md deleted file mode 100644 index 56be5805..00000000 --- a/versioned_docs/version-0.7.0/reference/lang/codelab/simple.md +++ /dev/null @@ -1,495 +0,0 @@ ---- -title: "Write simple config with KCL" -linkTitle: "Write simple config with KCL" -type: "docs" -weight: 2 -description: Write simple config with KCL -sidebar_position: 1 ---- - -## 1. Introduction - -KCL is a simple and easy-to-use configuration language, where users can simply write the reusable configuration code. - -In this first codelab, we will learn how to write a simple config with KCL. - -Learning this codelab only requires basic programming knowledge, and experience with python will make it even easier. - -### What We Will Learn - -1. Write simple key-value configuration in a programmable way -2. Write simple logic in KCL code -3. Write collections in KCL code -4. Test and debug with KCL code -5. Use built-in support in KCL code -6. Share and reuse KCL code -7. Write config with dynamic input arguments - -## 2. Write Key-Value Pairs - -Generate a simple config by creating a `my_config.k`, we can fill in the following code without strict format which describes the configuration of deploy. - -```python -cpu = 256 -memory = 512 -image = "nginx:1.14.2" -service = "my-service" -``` - -In the code above, cpu and memory are declared as int value, while image and service are string literal. - -Run with KCL, we will see the generated data in yaml format as below: - -KCL command: - -```bash -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -The exported variable is immutable by default so that once it is declared, we can't modify it some where else. - -## 3. Write Simple Logic - -Sometimes we want to write a logic in configuration, then we can use: - -- Mutable and non-exported variable starting with `_` -- If-else statement - -A non-exported variable means it will not appear in the output YAML, and it can be assigned multiple times. - -Here is a sample to show how to adjust the resource with conditions. - -KCL command: - -```python -kcl my_config.k -``` - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -image = "nginx:1.14.2" -service = "my-service" -``` - -Run with KCL, we will see the generated data in yaml format as below: - -```python -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -.. note:: -KCL has rich support of operators and string member functions, please read manual and specification for more details. - -## 4. Write Collections - -We can use collections to represent complex data types. The collections which are already supported are: - -- list -- dict - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -command = ["nginx"] # a list -labels = {run = "my-nginx"} # a dict -image = "nginx:1.14.2" -service = "my-service" -``` - -Run with kcl, we will see the generated data as yaml format as below: - -KCL command: - -```bash -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx -image: nginx:1.14.2 -service: my-service -``` - -> Check manual and specification out for more about collection date type and member functions. - -## 5. Append Items Into Collections - -We can combine logical expressions, comprehensions, slices, unions and other characteristics to dynamically add elements to the collection - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable -_env = "pre-prod" - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -_command = ["nginx"] # a list -_command = _command + ["-f", "file"] # Append items into command using + operator to contact two lists -command = [c.lower() for c in _command] # Take each element in the list to lowercase -_labels = { - run = "my-nginx" - if _env: - env = _env # Append a dict key-value pair when the _env is not None/Undefined or empty using if expressions -} # a dict -labels = _labels -image = "nginx:1.14.2" -service = "my-service" -``` - -Run with kcl, we will see the generated data as yaml format as below: - -```python -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 256 -memory: 512 -command: - - nginx - - -f - - file -labels: - run: my-nginx -image: nginx:1.14.2 -service: my-service -``` - -## 6. Write Assert - -To make code testable and robust, we can verify config data with assertions. - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -command = ["nginx"] # a list -labels = {run = "my-nginx"} # a dict -image = "nginx:1.14.2" -service = "my-service" -assert "env" in labels, "env label is a must" -assert cpu >= 256, "cpu cannot be less than 256" -``` - -Run with KCL, we will see eval failure with an error message as output as below: - -```bash -kcl my_config.k -``` - -Stderr: - -```bash -Assertion failure: env label is a must. -``` - -After adding env:pre-prod pair into labels, we will get the output as: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 7. Use Handy Built-in Support - -What's more, we can use built-in functions to help we debug or simplify coding. - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -_name = "nginx" -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # a list -labels = { - run = "my-{}".format(_name) - env = "pre-prod" -} # a dict -image = "{}:1.14.2".format(_name) # string format -service = "my-service" - -# debugging -print(labels) # debugging by print - -# test -assert len(labels) > 0, "labels can't be empty" # use len() to get list length -assert "env" in labels, "env label is a must" -assert cpu >= 256, "cpu cannot be less than 256" -``` - -This sample shows how we use `format()`, `len()`, `print()` function to help customize the config. - -Run with KCL, we will see the generated data in yaml format as below: - -KCL command: - -```bash -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -run: my-nginx -env: pre-prod -``` - -Note: more built-in functions and modules can be seen in spec/module - -## 8. Reuse Variables in Another Module - -To make our code well-organized, we can simply separate our code to `my_config.k` and `my_config_test.k`. - -Config data defined in `my_config.k`, - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 -_name = "nginx" - -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # a list -labels = { - run = "my-{}".format(_name) - env = "pre-prod" -} # a dict -image = "{}:1.14.2".format(_name) # string format -service = "my-service" -``` - -And test code defined in `my_config_test.k`, in which we can import `my_config.k`: - -```python -import my_config - -# debugging -print(my_config.labels) # debugging by print - -# test -assert len(my_config.labels) > 0, "labels can't be empty" # use len() to get list length -assert "env" in my_config.labels, "env label is a must" -assert my_config.cpu >= 256, "cpu cannot be less than256" -``` - -## 9. Config with Input Arguments - -Sometimes we need to get external input via parameters dynamically from the end user or platform. - -In this case, we can pass in `priority` and `env` on demand: - -- Pass in arguments: `-D priority=1 -D env=pre-prod` -- Get value by `option` keyword in KCL code - -```python -_priority = option("priority") # a non-exported and mutable variable -_env = option("env") # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -_name = "nginx" -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # a list -labels = { - run = "my-{}".format(_name) - env = _env -} # a dict -image = "{}:1.14.2".format(_name) # string format -service = "my-service" -``` - -Run with KCL, we will see the generated data in yaml format as below: - -```bash -kcl my_config.k -D priority=2 -D env=pre-prod -``` - -Stdout: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 10. Simplify Logic Expression using Dict - -When we need to write complex logic, we can use dict to simplify the writing of logic. - -```python -_priority = option("priority") # a non-exported and mutable variable -_env = option("env") # a non-exported and mutable variable -_priorityCpuMap = { - "1" = 256 - "2" = 512 - "3" = 1024 -} -# Using a dict to simplify logic and the default value is 2048 -_cpu = _priorityCpuMap[_priority] or 2048 -_name = "nginx" -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # a list -labels = { - run = "my-{}".format(_name) - env = _env -} # a dict -image = "{}:1.14.2".format(_name) # string format -service = "my-service" -``` - -Run with KCL, we will see the generated data in yaml format as below: - -KCL command: - -```bash -kcl my_config.k -D priority=2 -D env=pre-prod -``` - -Stdout: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 11. The Final Step - -Congratulations! - -We have completed the first lesson about KCL, we have used KCL to replace our key-value text file to get better programming support. - -Please check schema codelab out now to learn how to write an advanced config collaboratively with KCL `schema` mechanism. diff --git a/versioned_docs/version-0.7.0/reference/lang/error/_category_.json b/versioned_docs/version-0.7.0/reference/lang/error/_category_.json deleted file mode 100644 index 95062745..00000000 --- a/versioned_docs/version-0.7.0/reference/lang/error/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Errors and Warnings", - "position": 4 -} diff --git a/versioned_docs/version-0.7.0/reference/lang/error/index.md b/versioned_docs/version-0.7.0/reference/lang/error/index.md deleted file mode 100644 index 15fbda6f..00000000 --- a/versioned_docs/version-0.7.0/reference/lang/error/index.md +++ /dev/null @@ -1 +0,0 @@ -# Errors and Warnings diff --git a/versioned_docs/version-0.7.0/reference/lang/spec/_category_.json b/versioned_docs/version-0.7.0/reference/lang/spec/_category_.json deleted file mode 100644 index 7b24faae..00000000 --- a/versioned_docs/version-0.7.0/reference/lang/spec/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Spec", - "position": 3 -} diff --git a/versioned_docs/version-0.7.0/reference/lang/spec/codestyle.md b/versioned_docs/version-0.7.0/reference/lang/spec/codestyle.md deleted file mode 100644 index dd40925e..00000000 --- a/versioned_docs/version-0.7.0/reference/lang/spec/codestyle.md +++ /dev/null @@ -1,608 +0,0 @@ ---- -title: "Code Style" -linkTitle: "Code Style" -type: "docs" -weight: 2 -description: Code Style ---- - -## Introduction - -This document gives the KCL code style conventions. Good code style can play a vital role in the development and maintenance of the project. We can learn the KCL code style by referring to the full text of the description and sample codes, and use KCL format and lint tools to help coding. - -## Source File Encoding - -KCL file encoding should always use **UTF-8**. - -## Code Layout - -### Indentation - -Use **4 spaces** per indentation level such as in the schema statement and if statement. - -```python -schema PersonA: - name: str # non-recommended - age: int - -schema PersonB: - name: str # recommended - age: int - -if True: - a = 1 # recommended -elif True: - b = 2 # non-recommended -else: - c = 3 # non-recommended -``` - -The closing brace/bracket/parenthesis on multiline constructs should line up under **first character** of the line that starts the multiline construct, as in: - -```python -# valid and recommended -my_list = [ - 1, 2, 3, - 4, 5, 6, -] -``` - -```python -# invalid -my_list = [ - 1, 2, 3, - 4, 5, 6, - ] -``` - -### Tabs or Spaces - -- Spaces are the preferred indentation method. -- Tabs should be used solely to remain consistent with code that is already indented with tabs. - -KCL disallows mixing the use of tabs and spaces for indentation and an error will be reported during the compile time. - -### Blank Lines - -- Surround top-level schema definitions with one blank line. -- Keep at most one blank line between two statements and remove redundant blank lines. -- Remove extra blank characters at the end of the line -- Remove extra blank characters in a blank line. -- There is no blank line in the header of the file, start writing from the first line. -- Only one blank line will be left at the end of the KCL file. - -```python -# Remove blank lines in the file header -a = 1 # Remove white space at the end of the line -# Keep at most one blank line between two statements - -b = 2 -# Only leave one blank line at the end of the file - -``` - -### Inline Expressions - -Write indentation of KCL `if`, `elif`, `else` and other conditions on different lines. - -```python -if True: print("") # non-recommended - -if True: # recommended - print("") -``` - -### Line Break and Continuation lines - -- For long expressions, use the line continuation symbol `\` and keep the left end of multiple expressions aligned. -- The 4-space rule is optional for continuation lines. - -```python -anotherString = "Too long expression " + \ - "Too long expression " # non-recommended - -longString = "Too long expression " + \ - "Too long expression " + \ - "Too long expression " # recommended -``` - -### When to Use Trailing Commas - -- Always use trailing commas. - -### Maximum Line Length - -- The general recommendation is **80 characters** but not absolute. - -### Symbol Break White Space - -Try to keep the spaces between different symbols, but not too many, usually one is good. - -```python -a = 1 # recommended -b = 1 + 2 # non-recommended -``` - -### Whitespace in Expressions and Statements - -Avoid extraneous whitespace in the following situations: - -- The parentheses `()`, brackets `[]` and braces `{}` in the expression have no spaces inside. - -```python -a = (1 + 2) # recommended -b = ( 1 + 2 ) # non-recommended - -c = [1, 2, 3] # recommended -d = [ 1, 2, 3 ] # non-recommended - -e = {key = "value"} # recommended -f = { key = "value" } # non-recommended -``` - -```python -spam(ham[1], {eggs = 2}) # recommended -spam( ham[ 1 ], { eggs = 2 } ) # non-recommended -``` - -- Between a trailing comma and a following close parenthesis. - -```python -foo = [0,] # recommended -bar = [0, ] # non-recommended -``` - -- Immediately before the open parenthesis that starts the argument list of a function call. - -```python -print(1) # recommended -print (1) # non-recommended -``` - -- Immediately before the open parenthesis that starts indexing or slicing. - -```python -dct = {key = "value"} -lst = [1, 2, 3] - -a = dct['key'] # recommended -b = dct ['key'] # non-recommended - -c = lst[0] # recommended -d = lst [1] # non-recommended -``` - -- More than one space around an assignment `=` (or other) operator to align it with another. - -```python -# recommended: -x = 1 -y = 2 -long_variable = 3 -``` - -```python -# non-recommended: -x = 1 -y = 2 -long_variable = 3 -``` - -- Always surround these binary operators with a single space on either side: assignment (`=`), augmented assignment (`+=`, `-=`, etc.), comparisons (`==`, `<`, `>`, `!=`, `<=`, `>=`, `in`, `not in`, `is`, `is not`), booleans (`and`, `or`, `not`). - -```python -# recommended: -i = i + 1 -submitted += 1 -x = x * 2 - 1 -hypot2 = x * x + y * y -c = (a + b) * (a - b) -``` - -```python -# non-recommended: -i = i+1 -submitted+=1 -x = x*2 - 1 -hypot2 = x*x + y*y -c = (a+b) * (a-b) -``` - -- Break one blank line between different statements e.g., import, schema and expression statements. - -```python -import math -import net - -schema Person: - name: str - -person = Person { - name = "Alice" -} -``` - -- Compound statements (multiple statements on the same line) are generally discouraged - -```python -# recommended: -if foo == 'blah': - do_blah_thing() -do_one() -do_two() -do_three() -``` - -```python -# non-recommended: -if foo == 'blah': do_blah_thing() -do_one(); do_two(); do_three() -``` - -## Naming Conventions - -### Naming Styles - -The following naming styles are commonly distinguished: - -- `b` (single lowercase letter) -- `B` (single uppercase letter) -- `lowercase` -- `lower_case_with_underscores` -- `UPPERCASE` -- `UPPER_CASE_WITH_UNDERSCORES` -- `CapitalizedWords` (capitalize all letters of the acronym in `CapitalizedWords` e.g., `HTTPServer`.) -- `mixedCase` (differs from `CapitalizedWords` by initial lowercase character) -- `Capitalized_Words_With_Underscores` (ugly and non-recommended) - -### Names to Avoid - -Never use the characters 'l' (lowercase letter el), 'O' (uppercase letter oh), or 'I' (uppercase letter eye) as single-character variable names. - -### Package and Module Names - -Package and module names should have short, all-lowercase names. - -### Schema Names - -Schema names should normally use the `CapWords` convention. - -### Constants - -Constants are usually defined on a module level and written in all capital letters with underscores separating words such as `MAX_OVERFLOW` and `TOTAL`. - -## Import - -- Imports should usually be on separate lines. -- Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants. -- Imports should be grouped in the following order and we should put a blank line between each group of imports. - 1. Standard library imports. - 2. Related third party plugin imports. - 3. Local application/library specific imports. -- Use an alias when we import a package name with a relatively long path. -- Leave only one space between the Import keyword and the package name. - -```python -import net # recommended -import math # non-recommended - -import ..pkg.internal_pkg as alias_pkg # recommended -``` - -## Comments - -- Comments should be complete sentences. The first word should be capitalized unless it is an identifier that begins with a lower-case letter (never alter the case of identifiers!). -- Block comments generally consist of one or more paragraphs built out of complete sentences, with each sentence ending in a period. -- Use two spaces after a sentence-ending period in multi-sentence comments, except after the final sentence. - -### Block Comments - -Block comments generally apply to some (or all) code that follows them, and are indented to the same level as that code. Each line of a block comment starts with a `#` and **a single space**(unless it is indented text inside the comment). - -Paragraphs inside a block comment are separated by a line containing a single `#`. - -```python -# This is a block comment -a = 1 -``` - -### Inline Comments - -Use inline comments sparingly. - -An inline comment is a comment on the same line as a statement. Inline comments should be separated by **at least two spaces** from the statement. They should start with a `#` and **a single space**. - -```python -a = 1 # This is an inline comment -``` - -### Documentation Strings - -Write doc strings for all public schema and schema attributes. - -```python -schema Person: - """ - Person schema doc string - """ - - name: str = "Alice" -``` - -## String - -- Single-quoted strings and double-quoted strings are the same in KCL. -- Use double-quoted string with lowercase prefix -- For triple-quoted strings, always use double quote characters to be consistent with the docstring convention. -- When a string contains single or double quote characters, use the other one to avoid backslashes in the string. - -```python -strC = "'123'" # recommended -strD = "\"123\"" # non-recommended -``` - -## Number - -- Use lowercase for the prefix of non-decimal numbers, and use uppercase for the number itself. - -```python -foo = 0xAB # recommended -bar = 0Xab # non-recommended -``` - -## Operators - -### Binary Operators - -- Leave only one space before and after the assignment `=`. -- Leave only one space before and after the binary operator in the expression. - -```python -a = 1 # recommended -b=2 # non-recommended -c= 3 # non-recommended -d =4 # non-recommended - -_value = (1 + 2 * 3) # recommended -_value = (1+2*3) # non-recommended -``` - -### Unary Operators - -- There is only no space after unary operators e.g., `~`, `+` and `-`. - -```python -_value = 1 + -2 * ~3 # recommended -_value = 1+ - 2 * ~ 3 # non-recommended -``` - -- There is no space after `**` and `*` in the dict/list deduction expressions and argument expressions. - -```python -_list = [1, 2, 3] -_list = [*_list, [4, 5 ,6]] # recommended -_list = [* _list, [4, 5 ,6]] # non-recommended - -_dict = {**{k = "v"}, **{k = "v"}} # recommended -_dict = {** {k = "v"}, ** {k = "v"}} # non-recommended -``` - -- Use `is not` operator rather than `not ... is`. - -```python -# recommended: -if foo is not None: - a = 1 -``` - -```python -# non-recommended: -if not foo is None: - a = 1 -``` - -## Dict - -- There is no space before the colon `:` at the instantiation of KCL dict and schema config, and a space after the colon `:`. - -```python -d1 = {labels: {k1 = "v1"}} # recommended -d2 = {labels : {k1 = "v1"}} # non-recommended -d3 = {labels :{k1 = "v1"}} # non-recommended -``` - -- Always surround the override attribute operator `=` and the insert attribute operator `+=` with a single space on either sid. - -```python -d1 = {key = "value"} # recommended -d2 = {key= "value"} # non-recommended -d3 = {key ="value"} # non-recommended -``` - -```python -d1 = {key += [0, 1, 2]} # recommended -d2 = {key+= [0, 1, 2]} # non-recommended -d3 = {key +=[0, 1, 2]} # non-recommended -``` - -- Remove all commas at the end of the line in the KCL multiline dict because the end commas of each line are optional. - -```python -d = { - key1 = "value1" - key2 = "value2" - key3 = "value3" - key4 = "value4" -} -``` - -## List - -- Keep only **one space** after the comma `,` separating elements in the list - -```python -a = [1, 2, 3] # recommended -b = [1,2,3] # non-recommended -``` - -- Keep only **one space** before and after the comprehension expression token `for` and `in` in the dict and list. - -```python -a = [i for i in range(10)] # recommended -b = [i for i in range(10)] # non-recommended -``` - -## Slice - -- Keep the same number of spaces before and after the colon `:` of the list slice. - -```python -l = [1, 2, 3] -a = l[0:2] # recommended -b = l[0 : 2] # non-recommended -c = l[0: 2] # non-recommended - -d = l[0 + 0 : 1 + 1] # recommended -e = l[0 + 0:1 + 1] # non-recommended -``` - -## Schema - -- Leave only one space before and after the schema attribute assignment `=`. -- Always add a doc string to a schema, which is a good programming habit. - -```python -schema Person: - """ - Schema doc string - """ - name: str = "Alice" # recommended - age : int=12 # non-recommended - -person = Person {} -``` - -- Keep **no spaces** around the schema inheritance operator `()` - -```python -schema Base: - name: str - -schema Person(Base): # recommended - age: int - -schema Schema ( Base ): # non-recommended - age: int -``` - -- Keep **only one space** between the brackets and the schema name of the config at schema instantiation. - -```python -schema Base: - name: str - -schema Person(Base): - age: int - -personA = Person{} # non-recommended -personB = Person {} # recommended -``` - -- Keep **only one space** between the **mixin** keyword and the following `[]` operator - -```python -schema NameMixin: - name: str = "name" - -schema Person: - mixin [NameMixin] # non-recommended - age: int - -schema Parent: - mixin [NameMixin] # recommended - age: int -``` - -### Attribute Annotations - -- Annotations for schema attributes should have a single space after the colon `:` and no space before the colon `:`. - -```python -# recommended: -schema Person: - name: str # No space before the colon `:` - age: int = 18 # Spaces around assignment`=` -``` - -```python -# non-recommended: -schema Person: - codeA:int # No space after the colon `:` - codeB : int # Space before the colon `:` - name: str="Alice" # No spaces around assignment`=` -``` - -- There are no spaces around the colon `:` in the dict type annotation. - -```python -schema Person: - labels: {str:str} # recommended - keyValues: {str : str} # non-recommended -``` - -### Arguments - -- There are no spaces around the assignment `=` in the function/schema/decorator keyword arguments (kwargs). - -```python -schema Person[nameVar]: - # Decorator kwargs - @deprecated(strict=False) # recommended - name: str = nameVar - - @deprecated(strict = False) # non-recommended - age: int - -# Schema kwargs -personA = Person(nameVar="Alice") {} # recommended -personB = Person(nameVar = "Bob") {} # non-recommended - -# Function kwargs -print("", end='') # recommended -print("", end = '') # non-recommended -``` - -## Keywords - -- Only one space is usually reserved around the keyword, such as `schema`, `mixin`, `is` and `not`, etc. - -```python -schema NameMixin: - check: - name not None - -schema Person: - """ - Person schema definition - """ - mixin [NameMixin] - - name: str = "Alice" - age: int - -person = Person { - age = 18 -} -``` - -## Function - -- There are no spaces around the function/package select operator `.` -- There are no spaces between the function name and the parentheses `()`. - -```python -import math - -print(math.log(10)) # recommended -print( math . log (10)) # non-recommended -``` diff --git a/versioned_docs/version-0.7.0/reference/lang/spec/datatypes.md b/versioned_docs/version-0.7.0/reference/lang/spec/datatypes.md deleted file mode 100644 index ef7ea71a..00000000 --- a/versioned_docs/version-0.7.0/reference/lang/spec/datatypes.md +++ /dev/null @@ -1,452 +0,0 @@ ---- -title: "Data Types" -linkTitle: "Data Types" -type: "docs" -weight: 2 -description: Data Types ---- - -## Syntax - -### Bool - -Boolean values are the two constant objects `False` and `True`. They are used to represent truth values (although other values can also be considered false or true). The built-in function bool() can be used to convert any value to a Boolean, if the value can be interpreted as a truth value. - -### Int - -Int, or integer, is an arbitrarily sized integer, positive or negative, without decimals, of 64 binary digits precision(-9,223,372,036,854,775,808~9,223,372,036,854,775,807). Int is created by int literals or as the result of built-in functions and operators. Unadorned integer literals (including `hex`, `octal` and `binary` numbers) yield integers. The constructor int() can be used to produce int of a specific type. - -Besides, integer literals may have an `SI` or `IEC` multiplier. - -- `SI`: General integer or fixed-point number form: `P`, `T`, `G`, `M`, `K`, `k`, `m`, `u`, `n`. -- `IEC`: Corresponding power of 2: `Pi`, `Ti`, `Gi`, `Mi`, `Ki`. - -```python -a = 1 # positive integer: 1 -b = -1 # negative integer: -1 -c = 0x10 # hexadecimal literal: 16 -d = 0o10 # octal literal: 8, or the form `010` -e = 0b10 # binary literal: 2 -f = 10Ki # integer literal with IEC multiplier: 10240 -g = 1M # integer literal with SI multiplier: 1000000 -h = int("10") # int constructor: 10 -i = int("10Ki") # int constructor with multiplier: 10240 -``` - -Notes: - -- Report an error if unable to represent an integer value precisely. - -### Float - -Float, floating-point, approximation to real numbers, positive or negative, containing one or more decimals, of 64 bit IEEE 754 floats. The constructor float() can be used to produce int of a specific type. - -```python -a = 1.10 -b = 1.0 -c = -35.59 -d = 32.3+e18 -f = -90. -g = -32.54e100 -h = 70.2-E12 -i = float("112") # float constructor -``` - -Notes: - -- Report an error if unable to represent a floating-point value due to overflow -- Report a warning if unable to represent a floating-point value due to underflow. Round to the nearest representable value if unable to represent a floating-point value due to limits on precision. These requirements apply to the result of any expression except for built-in functions for which an unusual loss of precision must be explicitly documented. - -#### None - -In KCL, `None` can indicate that the value of the object is empty, which is similar to `nil` in Go or `null` in Java, and corresponds to `null` in YAML and JSON. - -```python -a = None -b = [1, 2, None] -c = {"key1" = "value1", "key2" = None} -``` - -Please note that `None` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + None # error -b = int(None) # error -c = not None # True -d = None == None # True -e = None or 1 # 1 -f = str(None) # None -``` - -#### Undefined - -`Undefined` is similar to None, but its semantics is that a variable is not assigned any value and will not be output to YAML or JSON. - -```python -a = Undefined -b = [1, 2, Undefined] -c = {"key1" = "value1", "key2" = Undefined} -``` - -Please note that `Undefined` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + Undefined # error -b = int(Undefined) # error -c = not Undefined # True -d = Undefined == Undefined # True -e = Undefined or 1 # 1 -f = str(Undefined) # Undefined -``` - -### Common Numeric Operations - -Int and Float support the following operations (see built-in proposal for built-in details): - -- `x + y`: sum of x and y. -- `x - y`: difference of x and y. -- `x * y`: product of x and y. -- `x / y`: quotient of x and y. -- `x // y`: floored quotient of x and y. -- `x % y`: remainder of x / y. -- `x ** y`: x to the power y. -- `-x`: x negated. -- `+x`: x unchanged. -- `~x`: x bitwise negation. -- `abs(x)`: absolute value or magnitude of x. -- `int(x)`: x converted to integer. -- `float(x)`: x converted to floating point. - -KCL supports mixed arithmetic: when a binary arithmetic operator has operands of different numeric types, the operand with the "narrower" type is widened to that of the other, where integer is narrower than floating-point. - -### String - -Strings are immutable sequences of Unicode characters. String literals are written in a variety of ways: - -```python -'allows embedded "double" quotes' # Single quotes -"allows embedded 'single' quotes" # Double quotes -'''Three single quotes''', """Three double quotes""" # Triple quoted -``` - -Triple quoted strings may span multiple lines. - -Indexing a string produces strings of length 1, for a non-empty string s, `s[0] == s[0:1]`. - -```python -a = "Hello, World!" -b = a[2:5] # "llo" -c = a[-5:-2] # "orl" -d = a[::-1] # "'!dlroW ,olleH'" -``` - -- `str(x=None) -> str` - -Return a string. If _x_ is not provided, raise a runtime error. - -```python -x = str(3.5) # "3.5" -``` - -#### Members - -Built-in function and members of a string - -- `str#len() -> int` - Return the number of characters in the string. -- `capitalize() -> str` - Return a copy of the string with its first character (if any) capitalized and the rest lowercased. -- `count(sub: str, start: int = 0, end: int = -1) -> int` - Returns the number of (non-overlapping) occurrences of substring sub in string, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `endswith(suffix: str, start: int = 0, end: int = -1) -> bool` - Returns `True` if the string ends with the specified suffix, otherwise return `False`, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `find(sub: str, start: int = 0, end: int = -1) -> int` - Returns the lowest index where substring sub is found, or -1 if no such index exists, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `format(*args, **kwargs) -> str` - Perform string interpolation. Format strings contain replacement fields surrounded by curly braces {}. Anything that is not contained in braces is considered literal text, which is copied unchanged to the output. If you need to include a bracket character in the literal text, it can be escaped by doubling: A replacement field can be either a name, a number or empty. Values are converted to strings using the str function. -- `index(sub: str, start: int = 0, end: int = -1) -> int` - Returns the first index where sub is found, or raises an error if no such index exists, optionally restricting to `[start:end]` start being inclusive and end being exclusive. -- `isalnum() -> bool` - Returns True if all characters in the string are alphanumeric (`[a-zA-Z0-9]`) and there is at least one character, False otherwise. -- `isalpha() -> bool` - Returns True if all characters in the string are alphabetic (`[a-zA-Z]`) and there is at least one character. -- `isdigit() -> bool` - Returns True if all characters in the string are digits (`[0-9]`) and there is at least one character. -- `islower() -> bool` - Returns True if all cased characters in the string are lowercase and there is at least one character. -- `isspace() -> bool` - Returns True if all characters are white space characters and the string contains at least one character. -- `istitle() -> bool` - Returns True if the string is in title case and it contains at least one character. This means that every uppercase character must follow an uncased one (e.g., whitespace) and every lowercase character must follow a cased one (e.g., uppercase or lowercase). -- `isupper() -> bool` - Returns True if all cased characters in the string are uppercase and there is at least one character. -- `join(iterable: list) -> str` - Return a string which is the concatenation of the strings in iterable. A TypeError will be raised if there are any non-string values in iterable. The separator between elements is the string providing this method. Example: - - ```python - >>> "|".join(["a", "b", "c"]) - "a|b|c" - ``` - -- `lower() -> str` - Returns a copy of the string with all the cased characters converted to lowercase. -- `lstrip(chars: str) -> str` - Return a copy of the string with leading characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.lstrip() - 'spacious ' - >>> 'www.example.com'.lstrip('cmowz.') - 'example.com' - ``` - -- `replace(old: str, new: str, count: int) -> str` - Return a copy of the string with all occurrences of substring old replaced by new. If the optional argument count is given, only the first count occurrences are replaced. -- `rfind(sub: str, start: int = 0, end: int = -1) -> int` - Return the highest index in the string where substring sub is found, such that sub is contained within s[start:end]. Optional arguments start and end are interpreted as in slice notation. Return -1 on failure. -- `rindex(sub: str, start: int = 0, end: int = -1) -> int` - Returns the last index where sub is found, or raises an ValueError if no such index exists, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `rsplit(sep: str, maxsplit: int = -1) -> list` - Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done, the rightmost ones. If sep is not specified or None, any whitespace string is a separator. Except for splitting from the right, rsplit() behaves like split() which is described in detail below. -- `rstrip(chars: str) -> str` - Return a copy of the string with trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a suffix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.rstrip() - ' spacious' - >>> 'mississippi'.rstrip('ipz') - 'mississ' - ``` - -- `split(sep: str, maxsplit: int) -> list` - Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done (thus, the list will have at most maxsplit+1 elements). If maxsplit is not specified or -1, then there is no limit on the number of splits (all possible splits are made). - - If sep is given, consecutive delimiters are not grouped together and are deemed to delimit empty strings (for example, `'1,,2'.split(',')` returns `['1', '', '2']`). The sep argument may consist of multiple characters (for example, `'1<>2<>3'.split('<>')` returns `['1', '2', '3']`). Splitting an empty string with a specified separator returns `['']`. - - For example: - - ```python - >>> '1,2,3'.split(',') - ['1', '2', '3'] - >>> '1,2,3'.split(',', maxsplit=1) - ['1', '2,3'] - >>> '1,2,,3,'.split(',') - ['1', '2', '', '3', ''] - ``` - - If sep is not specified or is None, a different splitting algorithm is applied: runs of consecutive whitespace are regarded as a single separator, and the result will contain no empty strings at the start or end if the string has leading or trailing whitespace. Consequently, splitting an empty string or a string consisting of just whitespace with a `None` separator returns `[]`. - - For example: - - ```python - >>> '1 2 3'.split() - ['1', '2', '3'] - >>> '1 2 3'.split(maxsplit=1) - ['1', '2 3'] - >>> ' 1 2 3 '.split() - ['1', '2', '3'] - ``` - -- `splitlines(keepends: str) -> list` - Return a list of the lines in the string, breaking at line boundaries('\n', '\r\n', '\r'). Line breaks are not included in the resulting list unless keepends is given and true. - - This method splits on the following line boundaries. In particular, the boundaries are a superset of universal newlines. - - For example: - - ```python - >>> 'ab c\n\nde fg\rkl\r\n'.splitlines() - ['ab c', '', 'de fg', 'kl'] - >>> 'ab c\n\nde fg\rkl\r\n'.splitlines(keepends=True) - ['ab c\n', '\n', 'de fg\r', 'kl\r\n'] - ``` - - Unlike `split()` when a delimiter string sep is given, this method returns an empty list for the empty string, and a terminal line break does not result in an extra line: - - ```python - >>> "".splitlines() - [] - >>> "One line\n".splitlines() - ['One line'] - ``` - - For comparison, `split('\n')` gives: - - ```python - >>> ''.split('\n') - [''] - >>> 'Two lines\n'.split('\n') - ['Two lines', ''] - ``` - -- `startswith(prefix: str, start: int = 0, end: int = -1) -> bool` - Return `True` if string starts with the prefix, otherwise return False. prefix can also be a list of prefixes to look for. With optional start, test string beginning at that position. With optional end, stop comparing string at that position. -- `strip(chars: str) -> str` - Return a copy of the string with the leading and trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix or suffix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.strip() - 'spacious' - >>> 'www.example.com'.strip('cmowz.') - 'example' - ``` - - The outermost leading and trailing chars argument values are stripped from the string. Characters are removed from the leading end until reaching a string character that is not contained in the set of characters in chars. A similar action takes place on the trailing end. For example: - - ```python - >>> comment_string = '#....... Section 3.2.1 Issue #32 .......' - >>> comment_string.strip('.#! ') - 'Section 3.2.1 Issue #32' - ``` - -- `title() -> str` - Return a titlecased version of the string where words start with an uppercase character and the remaining characters are lowercase. - - For example: - - ```python - >>> 'Hello world'.title() - 'Hello World' - ``` - - The algorithm uses a simple language-independent definition of a word as groups of consecutive letters. The definition works in many contexts but it means that apostrophes in contractions and possessives form word boundaries, which may not be the desired result: - - ```python - >>> "they're bill's friends from the UK".title() - "They'Re Bill'S Friends From The Uk" - ``` - -- `upper() -> str` - Return a copy of the string with all the cased characters 4 converted to uppercase. Note that `s.upper().isupper()` might be `False` if s contains uncased characters or if the Unicode category of the resulting character(s) is not “Lu” (Letter, uppercase), but e.g., “Lt” (Letter, titlecase). -- `removeprefix(prefix: str) -> str` - If the string starts with the prefix string, return string[len(prefix):]. Otherwise, return a copy of the original string. - ```python - >>> "prefix-data".removeprefix("prefix-") - "data" - ``` -- `rermovesuffix(suffix: str) -> str` - If the string ends with the suffix string and that suffix is not empty, return string[:-len(suffix)]. Otherwise, return a copy of the original string. - ```python - >>> "data-suffix".removesuffix("-suffix") - "data" - ``` - -### List - -Lists are immutable sequences, typically used to store collections of homogeneous items (where the precise degree of similarity will vary by application). - -Lists may be constructed in several ways: - -- Using a pair of square brackets to denote the empty list: `[]` -- Using square brackets, separating items with commas: `[a]`, `[a, b, c]` -- Using a list comprehension: `[x for x in iterable]` -- Using the type constructor: list() or list(iterable) - -The constructor builds a list whose items are the same and in the same order as iterable’s items.Iterable may be either a sequence, a container that supports iteration, or an iterator object. If iterable is already a list, a copy is made and returned, similar to `iterable[:]`. For example, `list('abc')` returns `['a', 'b', 'c']` and `list([1, 2, 3])` returns `[1, 2, 3]`. If no argument is given, the constructor creates a new empty list `[]`. - -Lists implement all of the common sequence operations. - -#### Members - -- `len()` - Return the number of items in the list. - -### Common Sequence Operations - -The operations in the following table are supported by List and Dict. - -This table lists the sequence operations sorted in ascending priority. In the table, s and t are sequences of the same type, n, i, j and k are integers and x is an arbitrary object that meets any type and value restrictions imposed by s. - -The `in` and `not in` operations have the same priorities as the comparison operations. The + -(concatenation) and \* (repetition) operations have the same priority as the corresponding numeric operations. - -| Operation | Result | Notes | -| ------------ | -------------------------------------------------- | ----- | -| `x in s` | `True` if an item of s is equal to x, else `False` | #1 | -| `x not in s` | `False` if an item of s is equal to x, else `True` | #1 | -| `s + t` | the concatenation of s and t | #5 | -| `s[i]` | ith item of s, origin 0 | #2 | -| `s[i:j]` | slice of s from i to j | #2 #3 | -| `s[i:j:k]` | slice of s from i to j with step k | #2 #4 | -| `min(s)` | smallest item of s | | -| `max(s)` | largest item of s | | - -Notes: - -- 1. While the in and not in operations are used only for simple containment testing in the - general case, some specialized sequences (str) also use them for subsequence testing: - -```python ->>> "gg" in "eggs" -True -``` - -- 2. If i or j is negative, the index is relative to the end of sequence s: `s.len() + i` or `s.len() + j` is substituted. But note that -0 is still 0. -- 3. The slice of s from i to j is defined as the sequence of items with index k such that `i <= k < j`. If i or j is greater than `s.len()`, use `s.len()`. If i is omitted or None, use 0. If j is omitted or None, use `s.len()`. If i is greater than or equal to j, the slice is empty. -- 4. The slice of s from i to j with step k is defined as the sequence of items with index `x = i + n*k` such that `0 <= n < (j-i)/k`. In other words, the indices are `i`, `i+k`, `i+2*k`, `i+3*k` and so on, stopping when j is reached (but never including j). When k is positive, i and j are reduced to s.len() if they are greater. When k is negative, i and j are reduced to s.len() - - - If they are greater. If i or j are omitted or None, they become “end” values (which end depends on the sign of k). Note, k cannot be zero. If k is None, it is treated like 1. - -- 5. Concatenating immutable sequences always results in a new object. This means that building up a sequence by repeated concatenation will have a quadratic runtime cost in the total sequence length. To get a linear runtime cost, you must switch to one of the alternatives below: - - - if concatenating str objects, you can build a list and use `str.join()` at the end - -- 6. `index` raises `ValueError` when x is not found in s. Not all implementations support passing the additional arguments i and j. These arguments allow efficient searching of subsections of the sequence. Passing the extra arguments is roughly equivalent to using `s[i:j].index(x)`, only without copying any data and with the returned index being relative to the start of the sequence rather than the start of the slice. - -### Dict - -Dict is an immutable mapping object maps hashable values to arbitrary objects. A dictionary’s keys are almost arbitrary values. Values that are not hashable, that is, values containing lists, dictionaries may not be used as keys. Numeric types used for keys obey the normal rules for numeric comparison: if two numbers compare equal (such as 1 and 1.0) then they can be used interchangeably to index the same dictionary entry. (Note however, that since computers store floating-point numbers as approximations it is usually unwise to use them as dictionary keys.) Dict is ordered. The order of the keys is the order of their declaration. - -Dictionaries can be created by placing a comma-separated list of keys: value pairs within braces, for example: `{'jack': 4098, 'sjoerd': 4127}` or `{4098: 'jack', 4127: 'sjoerd'}`, by the dict constructor, or list/dict comprehension. - -- `dict(obj)` - -Return a new dictionary initialized from an optional positional argument and a possibly empty set of keyword arguments.If no positional argument is given, an empty dictionary is created. If a positional argument is given and it is a mapping object, a dictionary is created with the same key-value pairs as the mapping object. Otherwise, the positional argument must be an iterable object. Each item in the iterable must itself be an iterable with exactly two objects. The first object of each item becomes a key in the new dictionary, and the second object the corresponding value. If a key occurs more than once, the last value for that key becomes the corresponding value in the new dictionary. If keyword arguments are given, the keyword arguments and their values are added to the dictionary created from the positional argument. If a key being added is already present, the value from the keyword argument replaces the value from the positional argument. To illustrate, the following examples all return a dictionary equal to `{"one": 1, "two": 2, "three": 3}`: - -```python ->>> a = {'two': 2, 'one': 1, 'three': 3} ->>> b = {'one': 1, 'two': 2, 'three': 3} ->>> c = {'three': 3, 'one': 1, 'two': 2} ->>> a == b == c -True -``` - -Providing keyword arguments as in the first example only works for keys that are valid KCL identifiers. Otherwise, any valid keys can be used. - -In the dict comprehension, key/value pairs yielded by the generator expression is set in the dictionary in the order yielded: the first occurrence of the key determines its insertion order, and the last determines the value associated to it. - -```python ->>> {str(i): 2 * i for i in range(3)} -{"0": 0, "1": 2, "2": 4} - ->>> a = {"one": 1, "two": 2, "three": 3} ->>> b = {k: v for k, v in a if v >= 2} -{two: 2, three: 3} -``` - -#### Operations & Members - -These are the operations that dictionaries the support. - -- `list(d)` - Return a list of all the keys used in the dictionary d. -- `len()` - Return the number of items in the dictionary d. -- `d[key]` - Return the item of d with key. Return Undefined if key is not in the map. -- `key in d` - Return True if d has a key, else False. -- `key not in d` - Equivalent to not key in d. -- `d.key` - Return the item of d with key. Return Undefined if key is not in the map. - -Dictionaries compare equal if and only if they have the same (key, value) pairs(keys' ordering matters). Order comparisons (‘<’, ‘<=’, ‘>=’, ‘>’) raise TypeError. - -```python ->>> d = {"one": 1, "two": 2, "three": 3, "four": 4} ->>> d -{'one': 1, 'two': 2, 'three': 3, 'four': 4} ->>> list(d) -['one', 'two', 'three', 'four'] -``` diff --git a/versioned_docs/version-0.7.0/reference/lang/spec/index.md b/versioned_docs/version-0.7.0/reference/lang/spec/index.md deleted file mode 100644 index 88bbaa59..00000000 --- a/versioned_docs/version-0.7.0/reference/lang/spec/index.md +++ /dev/null @@ -1 +0,0 @@ -# KCL Spec diff --git a/versioned_docs/version-0.7.0/reference/lang/spec/lexical.md b/versioned_docs/version-0.7.0/reference/lang/spec/lexical.md deleted file mode 100644 index 8c85ee7b..00000000 --- a/versioned_docs/version-0.7.0/reference/lang/spec/lexical.md +++ /dev/null @@ -1,213 +0,0 @@ ---- -title: "Lexical" -linkTitle: "Lexical" -type: "docs" -weight: 2 -description: Lexical ---- - -## Lexical Conventions - -This chapter covers the KCL lexical conventions including grammar notation, lines, comments and tokens. - -## Grammar Notation - -The syntax is specified using Extended Backus-Naur Form (EBNF), porting to lark parser ([https://github.com/lark-parser/lark](https://github.com/lark-parser/lark)). - -``` -- name grammar production -- NAME lexical token -- "x" lexical token -- () grouping -- | alternation -- [] option (0 or 1 times) -- ? option (0 or 1 times) -- * repetition (0 to n times) -- + repetition (1 to n times) -``` - -## Source File Encoding - -KCL source code is Unicode text encoded in **UTF-8**. - -The following are basic Unicode elements, which will be used in literal notations. - -``` -newline ::= U+000A -quota ::= singlequote | doublequote -singlequote ::= U+0027 -doublequote ::= U+0022 -source character ::= Unicode code point -``` - -The form a...b in literal notations represents the set of characters from a through b. - -## Line Structure - -The line structure of KCL programs is equivalent to that of Python. - -A KCL program is divided into a number of logical lines. Each logical line consists of one or more physical lines. - -A token named `NEWLINE` is used to divide logical lines. - -A physical line is a sequence of characters end with a line termination sequence, which can be the ASCII LF (linefeed) character, the ASCII sequence CR LF (return followed by linefeed), or the ASCII CR (return) character. - -### Explicit Line Joining - -To join multiple physical lines into one logical line, the `\` character can be used. The character should be the last none-space character in each physical line except the very last line. - -> **note** -> -> Any character except the ASCII space, tab (`\t`) and formfeed (`\f`) is considered a none-space character. - -- A line ending in a backslash cannot carry a comment (, which will be introduced shortly afterwards). -- A backslash does not continue a comment. -- A backslash does not continue a token except for string literals (i.e., tokens other than string literals cannot be split across physical lines using a backslash). -- A backslash is illegal elsewhere on a line outside a string literal. - -### Implicit Line Joining - -Expressions in parentheses, square brackets or curly braces can be split over more than one physical line without using backslashes. - -- Implicitly continued lines can carry comments. -- The indentation of the continuation lines is not important. -- Blank continuation lines are allowed. -- There is no `NEWLINE` token between implicit continuation lines. -- Implicitly continued lines can also occur within triple-quoted strings (see below); in that case they cannot carry comments. - -### Blank Lines - -### Indentation - -### Comments - -Starting with a `#` character that is not part of a string literal is a comment. A comment ends at the end of the physical line. - -A comment signifies the end of the logical line unless the implicit line joining rules are invoked. - -Comments are ignored by the syntax. - -### Identifiers and Keywords - -Identifiers (also referred to as names) are described by the following lexical definitions. - -Within the ASCII range (from `U+0001` to `U+007F`), the valid characters for identifiers are the uppercase and lowercase letters `A` through `Z`, the underscore `_` and, except for the first character, the digits `0` through `9`. - -Identifiers are unlimited in length. The case is significant. - -### Keywords - -The following identifiers are used as reserved words, or keywords of the language, and cannot be used as ordinary identifiers. They must be spelled exactly as written here: - -``` -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -The following tokens are not used, but they are reserved as possible future keywords: - -``` -pass return validate rule flow -def del raise except try -finally while from with yield -global nonlocal struct class final -``` - -### Literals - -Literals are notations for constant values of some built-in types. - -### String Literals - -String literals are described by the following lexical definitions: - -``` -stringliteral ::= [stringprefix](shortstring | longstring) -stringprefix ::= "r" | "R" -shortstring ::= "'" shortstringitem* "'" | '"' shortstringitem* '"' -longstring ::= "'''" longstringitem* "'''" | '"""' longstringitem* '"""' -shortstringitem ::= shortstringchar | stringescapeseq -longstringitem ::= longstringchar | stringescapeseq -shortstringchar ::= -longstringchar ::= -stringescapeseq ::= "\" -``` - -Multiple adjacent string or bytes literals (delimited by whitespace),possibly using different quoting conventions, are allowed, and their meaning is the same as their concatenation. - -### Numeric Literals - -There are two types of numeric literals: integers and floating-point numbers. - -Integer literals are described by the following lexical definitions: - -``` -integer ::= decinteger | bininteger | octinteger | hexinteger -decinteger ::= nonzerodigit (["_"] digit)* | "0"+ (["_"] "0")* -bininteger ::= "0" ("b" | "B") (["_"] bindigit)+ -octinteger ::= "0" ("o" | "O") (["_"] octdigit)+ -hexinteger ::= "0" ("x" | "X") (["_"] hexdigit)+ -nonzerodigit ::= "1"..."9" -digit ::= "0"..."9" -bindigit ::= "0" | "1" -octdigit ::= "0"..."7" -hexdigit ::= digit | "a"..."f" | "A"..."F" -``` - -Floating-point literals are described by the following lexical definitions: - -``` -floatnumber ::= pointfloat | exponentfloat -pointfloat ::= [digitpart] fraction | digitpart "." -exponentfloat ::= (digitpart | pointfloat) exponent -digitpart ::= digit (["_"] digit)* -fraction ::= "." digitpart -exponent ::= ("e" | "E") ["+" | "-"] digitpart -``` - -## Operators and Delimiters - -### Operators - -The following tokens are operators: - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != @ -``` - -### Delimiters - -The following tokens serve as delimiters in the grammar: - -```python -( ) [ ] { } -, : . ; = += --= *= **= /= //= %= -<<= >>= &= |= ^= -``` - -The period can also occur in floating-point literals. - -The following printing ASCII characters have special meaning as part of other tokens or are otherwise significant to the lexical analyzer: - -``` -' " # \ -``` - -The following printing ASCII characters are not used in KCL. Their occurrence outside string literals and comments is an unconditional error: - -``` -? ` -``` - -## Reference - -Since the lexical conventions of KCL is very similar to that of Python, we use the following document as the reference when writing this chapter. - -- [https://docs.python.org/3/reference/lexical_analysis.html](https://docs.python.org/3/reference/lexical_analysis.html) diff --git a/versioned_docs/version-0.7.0/reference/lang/spec/variables.md b/versioned_docs/version-0.7.0/reference/lang/spec/variables.md deleted file mode 100644 index b3e1c539..00000000 --- a/versioned_docs/version-0.7.0/reference/lang/spec/variables.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: "Variables" -linkTitle: "Variable" -type: "docs" -weight: 2 -description: Variable ---- - -In KCL, variables can be defined using assign statements. For example, the following statement defines a variable `spam` to a string `"ham"`. - -```python -spam = "ham" -``` - -There are two types of variables, which are global variables and list comprehension local variables. - -- A global variable is defined not within any context. -- A comprehension local variable is defined inside a comprehension. - -A variable can be used after definition, until the end of the current scope. - -For a global variable, the scope is the module it is defined in. Note that a module can consists of multiple source files. - -For a list comprehension local variable, the scope is the list comprehension it is defined in. - -More information on modules, list comprehensions and scopes will be discussed in later chapters. - -## Immutability - -Global variables are immutable. In other words, once defined such a variable cannot be redefined (or, i.e., modified). - -The following code is illegal, and KCL will report an error during evaluation. - -```python -spam = "ham" -spam = "eggs" # Error: The immutability rule is violated! -``` - -- A variable starts with the `_` character is mutable. - -```python -_spam -cond = True -if cond: - _spam = "ham" -else: - _spam = "eggs" -``` - -## Variable Exporting - -As shown in the preview chapter, KCL is able to export evaluation results to the standard output according to a target data format. - -The rules are the followings: - -- Living global variables at the end of an evaluation will be dumped out. -- If the name of a variable starts with the `_` character, it will not be dumped out. - -## Uniqueness of Exported Variable Identifier - -Each exported variable identifier must be unique in its package, so that an exported variable could be located uniquely by package location path and variable identifier, such as 'a.b.c:var', in which 'a.b.c' locates a package. - -Two variable identifiers are different if: - -- they are spelled differently -- they are defined in different packages and are not compiled in a single execution - -Identifying an exported variable should be supported by the kcl compiler, which needs to provide corresponding identifying features through the command line and api form. diff --git a/versioned_docs/version-0.7.0/reference/lang/types/_category_.json b/versioned_docs/version-0.7.0/reference/lang/types/_category_.json deleted file mode 100644 index 8b257445..00000000 --- a/versioned_docs/version-0.7.0/reference/lang/types/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Types", - "position": 4 -} diff --git a/versioned_docs/version-0.7.0/reference/lang/types/types.md b/versioned_docs/version-0.7.0/reference/lang/types/types.md deleted file mode 100644 index ee88c64d..00000000 --- a/versioned_docs/version-0.7.0/reference/lang/types/types.md +++ /dev/null @@ -1,1381 +0,0 @@ -# Type System - -This document describes the type system of KCL, including: - -- Type rules -- Type checking -- Type conversion -- Type inference - -## Type Rules - -### Basic Definition - -#### Assertion - -All free variables of $S$ are defined in $\Gamma$ - -$$ -\Gamma \vdash S -$$ - -$\Gamma$ is a variable's well-formed environment, such as $x_1:T_1$, ..., $x_n:T_n$ - -The assertion of $S$ has three forms: - -**Environment assertion** indicates that $\Gamma$ is a well-formed type. - -$$ -\Gamma \vdash ◇ -$$ - -**Well-formed type assertion**. In the environment $\Gamma$, $nat$ is a type expression. - -$$ -\Gamma \vdash nat -$$ - -**Typing judgment assertion**. In the environment $\Gamma$,$E$ has the type $T$. - -$$ -\Gamma \vdash E: T -$$ - -#### Inference Rules - -Representation - -$$ -\frac{\Gamma \vdash S_1, ..., \Gamma \vdash S_n}{\Gamma \vdash S} -$$ - -In the inference rules, $u$, $v$, and $w$ are used to represent variables, $i$, $j$, $k$ are used to represent integers, $a$ and $b$ are used to represent floating point numbers, $s$ is used to represent strings, $c$ is used to represent literal values of constants (integers, floating point numbers, strings, boolean), $f$ is used to represent functions, $T$, $S$, $U$ are used to represent types. - -## Environment Rules - -Env ⌀ - -$$ -\frac{}{⌀ \vdash ◇ } -$$ - -## Type Definitions - -Type Bool - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash boolean} -$$ - -Type Int - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash integer} -$$ - -Type Float - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash float} -$$ - -Type String - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash string} -$$ - -Type Literal - -$$ -\frac{ c \in \{boolean, integer, float, string\}}{\Gamma \vdash literalof(c)} -$$ - -Type List - -$$ -\frac{\Gamma \vdash T \ T \neq Void}{\Gamma \vdash listof(T) } -$$ - -Type Dict - -$$ -\frac{\Gamma \vdash T_1 \ \Gamma \vdash T_2\ T_1 \neq Void \ \ T_2 \neq Void}{\Gamma \vdash dictof(T_k=T_1, T_v=T_2)} -$$ - -Type Struct - -$$ -\frac{\Gamma \vdash T_{1} \ ... \ \Gamma \vdash T_{n} \ \ T_i \neq Void \ K_1 \neq K_n}{\Gamma \vdash structof(K_1 : T_{1}, ... , K_n : T_{n})} -$$ - -Type Union - -$$ -\frac{\Gamma \vdash T_1 \ ... \ \Gamma \vdash T_n \ \ T_i \neq Void}{\Gamma \vdash unionof(T_1, ..., T_n)} -$$ - -Type None - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash None} -$$ - -Type Undefined - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Undefined} -$$ - -Type Void - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Void} -$$ - -Type Any - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Any} -$$ - -Type Nothing - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Nothing} -$$ - -## Typing Judgment Rules - -### Operand Expr - -Exp Truth - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash true: boolean} -$$ - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash false: boolean} -$$ - -Exp Int - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash int: integer} -$$ - -Exp Flt - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash flt: float} -$$ - -Exp Str - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash str: string} -$$ - -Exp None - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash none: none} -$$ - -Exp Undefined - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash undefined: undefined} -$$ - -Expr ListExp - -$$ -\frac{\Gamma \vdash E_1: T_1 \ E_2: T_2 \ ... \ E_n: T_n}{\Gamma \vdash [E_1, E_2, ..., E_n]: listof \ sup(T_1, T_2, ..., T_n)} -$$ - -Expr ListComp - -$$ -\frac{\Gamma \vdash E_1: T_1 \ \Gamma \vdash v: T \ \Gamma \vdash E_2: listof \ T \ \Gamma \vdash E_3: boolean}{\Gamma \vdash [E_1 \ for \ v \ in \ E_2 \ if \ E_3]: listof(T_1) } -$$ - -Expr DictExp - -$$ -\frac{\Gamma \vdash E_{k1}: T_{k1} \ \Gamma \vdash E_{v1}: T_{v1} \ ... \ \Gamma \vdash E_{kn}: T_{kN} \ \Gamma \vdash E_{vn}: T_{vN}}{\Gamma \vdash \{E_{k1}: E_{v1}, ..., E_{{kn}}: E_{vn}\}: dictof(T_{k}=sup(T_{k1}, T_{k2}, ... T_{kn}), \ T_{v}=sup(T_{v1}, T_{v2}, ..., T_{vn}))} -$$ - -Expr DictComp - -$$ -\frac{\Gamma \vdash E_1: T_{rki} \ \Gamma \vdash E_2: T_{rvi} \ \Gamma \vdash v_1: T_k \ \Gamma \vdash v_2: T_v \ \Gamma \vdash E_3: dictof(T_{k}, \ T_{v}) \ \Gamma \vdash E_4: boolean}{\Gamma \vdash \{E_1:E_2 \ for \ (v_1, v_2) \ in \ E_3 \ if \ E_4\}: dictof(T_{k}=sup(T_{rk1}, T_{rk2}, ..., T_{rkn}), T_{v}=sup(T_{rv1}, T_{rv2}, ..., T_{rvn})) } -$$ - -Expr StructExpr - -$$ -\frac{\Gamma \vdash E_{1}: T_{1} \ ... \ \Gamma \vdash E_{n}: T_{n} \ K_1 \neq K_n}{\Gamma \vdash \{K_{1} = E_{1}, ..., K_{{n}} = E_{n}\}: structof(K_1 : T_{1}, ... , K_n : T_{n})} -$$ - -The literal type is the value type of basic type, the union type is the combination type of types, void, any, nothing are special type references, and there is no direct value expression correspondence. - -### Primary Expr - -Expr Index - -$$ -\frac{\Gamma \vdash E: listof(T) \ \Gamma \vdash Index: integer}{\Gamma \vdash E[Index]: T} -$$ - -Expr Call - -$$ -\frac{\Gamma \vdash E_1: T_1 \rightarrow T_2 \ \Gamma \vdash E_2: T_1}{\Gamma \vdash E_1 \ (E_2): T_2} -$$ - -Expr List Selector - -$$ -\frac{\Gamma \vdash E: listof(T) \ \Gamma \vdash Index: integer}{\Gamma \vdash E.[Index]: T} -$$ - -Expr Dict Selector - -$$ -\frac{\Gamma \vdash E: dictof(T_k = T_1, T_v=T_2) \ \Gamma \vdash S_1: string \ ... \ \Gamma \vdash S_n: string}{\Gamma \vdash E.\{S_1, ..., S_n\}: dictof(T_k = T_1, T_v=T_2)} -$$ - -Expr Struct Selector - -$$ -\frac{\Gamma \vdash E: structof(K_1 : T_{1}, ... , K_n : T_{n}) \ \Gamma \vdash K_i: string}{\Gamma \vdash E.K_i: T_{i}} -$$ - -### Unary Expr - -Expr + - -$$ -\frac{\Gamma \vdash E: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash \ +E: T} -$$ - -Expr - - -$$ -\frac{\Gamma \vdash E: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash \ -E: T} -$$ - -Expr ~ - -$$ -\frac{\Gamma \vdash E: integer}{\Gamma \vdash \ ~E: integer} -$$ - -Expr not - -$$ -\frac{\Gamma \vdash E: boolean}{\Gamma \vdash \ not \ E: boolean} -$$ - -### Binary Expr - -Expr op, op $\in$ {-, /, %, \*\*, //} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash E_1 \ op \ E_2: T} -$$ - -Expr + - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, float, string, listof(T_1)\}}{\Gamma \vdash E_1 \ + \ E_2: T} -$$ - -Expr \* - -$$ -\frac{\Gamma \vdash E_1: T_1 \ \ \ \Gamma \vdash E_2: T_2 \ \ \ \ (T_1==T_2 \in \{integer, float\}) \ or \ (T_1 == interger \ and \ T_2 \ \in \ \{string, listof(T_3)\}) \ or \ (T_2 == interger \ and \ T_1 \ \in \ \{string, listof(T_3)\})} {\Gamma \vdash E_1 \ * \ E_2: T} -$$ - -Expr % - -$$ -\frac{\Gamma \vdash E_1: interger \ \ \ \Gamma \vdash E_2: integer}{\Gamma \vdash E_1 \ \% \ E_2: interger} -$$ - -Expr op, op $\in$ \{or, and\} - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ op \ E_2: boolean} -$$ - -示例 - -Expr and - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ and \ E_2: boolean} -$$ - -Expr op, op $\in$ \{==, !=, <, >, <=, >=\} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T}{\Gamma \vdash E_1 \ op \ E_2: boolean} -$$ - -Expr > - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ > \ E_2: boolean} -$$ - -Expr op, op $\in$ {&, ^, ~, <<, >>} - -$$ -\frac{\Gamma \vdash E_1: integer \ \ \ \Gamma \vdash E_2: integer}{\Gamma \vdash E_1 \ op \ E_2: integer} -$$ - -Expr | - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, listof(T_1), dictof(T_k, T_v), structof(K_1=T_1, ..., K_n=T_n)\}}{\Gamma \vdash E_1 \ | \ E_2: T} -$$ - -Expr op, op $\in$ {in, not in} - -$$ -\frac{\Gamma \vdash E_1: string \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{dictof, structof\}}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: listof(S), T \sqsubseteq S}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -Expr op $\in$ {is, is not} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -### IF Expr - -Expr If - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: T \ \ \ \Gamma \vdash E_3: T}{\Gamma \vdash if \ E_1 \ then \ E_2 \ else \ E_3: T} -$$ - -### Stmt - -Stmt If - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash S_1: Void \ \ \ \Gamma \vdash S_2: Void}{\Gamma \vdash if \ E_1 \ then \ S_1 \ else \ S_2: Void} -$$ - -Stmt Assign - -$$ -\frac{\Gamma \vdash id: T_0 \ \ \ \Gamma \vdash T_1 \ \ \ \Gamma \vdash E: T_2}{\Gamma \vdash id: T_1 \ = \ E : Void} -$$ - -Type Alias - -$$ -\frac{\Gamma \vdash id: T_0 \ \ \ \Gamma \vdash T_1}{\Gamma \vdash type \ id \ = \ T_1 : Void} -$$ - -## Union - -List Union - -$$ -\frac{\Gamma \vdash \ listof(T) \ \ \ \Gamma \vdash \ listof(S)}{\Gamma \vdash \ listof(unionof(T, S))} -$$ - -Dict Union - -$$ -\frac{\Gamma \vdash \ dictof(T_1, T_2) \ \ \ \Gamma \vdash \ dictof(S_1, S_2)}{\Gamma \vdash \ dictof(unionof(T_1, S_1), unionof(T_2, S_2))} -$$ - -Struct Union - -Define two structures: $structof(K_{1}: T_{1}, ..., K_{n}: T_{n}),structof(H_{1}: S_{1}, ..., H_{m}: S_{n})$ - -Define their union types: - -$$ -structof(J_{1}: U_{1}, ..., J_{p}: U_{n}) = structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \bigcup structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) -$$ - -Example - -$$ -structof() \ \bigcup \ structof(H_{1}: T_{1}, ..., H_{m}: T_{n}) = structof(H_{1}: T_{1}, ..., H_{m}: T_{n}) -$$ - -$$ -structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \ \bigcup \ structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) = structof(K_1: T_1) :: (structof(K_{2}: T_{2}, ..., K_{n}: T_{n}) \ \bigcup \ structof(H_{1}: S_{1}, ..., H_{m}: S_{n})) -$$ - -where "::" denotes the operation of adding a dual to a structure, which is defined as follows: - -$$ -structof(K_{1}: T_{1}) :: structof() = structof(K_{1}: T_{1}) -$$ - -$$ -structof(K_{1}: T_{1}) :: structof(K_{1}: T_{1}', ..., K_n: T_{n}) = structof(K_{1}: union\_op(T_{1}, T_{1}'), ..., K_{n}: T_{n}) -$$ - -$$ -structof(K_{1}: T_{1}) :: structof(K_{2}: T_{2}, ..., K_n: T_{n}) = structof(K_{2}: T_2) :: structof(K_{1}: T_1) :: structof(K_{3}: T_3, ..., K_{n}: T_{n}) -$$ - -Based on this, the union of two structures is defined as: - -$$ -\frac{\Gamma \vdash structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \ \Gamma \vdash structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) \ structof(J_{1}: U_{1}, ..., J_{p}: U_{n}) = structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \bigcup structof(H_{1}: S_{1}, ..., H_{m}: S_{n})}{\Gamma \vdash structof(J_{1}: U_{1}, ..., J_{p}: U_{n}))} -$$ - -where $union\_op(T_1, T_2)$ denotes different types of judgment operations for the same $K_i$. - -- When $T_1$ and $T_2$ have the partial order relation. If $T_1 \sqsubseteq T_2$, return $T_2$, otherwise return $T_1$, which is the minimum upper bound -- When $T_1$ and $T_2$ have no partial order relationship, there are three optional processing logic: - - Structure union failed, return a type error. - - Return the type of the latter $T_2$. - - Return the type $unionof (T_1, T_2)$. - -Here, we need to choose the appropriate processing method according to the actual needs. - -Structure inheritance can be regarded as a special union. The overall logic is similar to that of union, but in $union\_op(T_1, T_2)$ for the same $K_i$, the different types of judgment operations are as follows: - -- When $T_1$ and $T_2$ have the partial order relation and $T_1 \sqsubseteq T_2$, return $T_1$, that is, only if $T_1$ is the lower bound of $T_2$, the lower bound of $T_1$ shall prevail. -- Otherwise, a type error is returned. - -Through such inheritance design, we can achieve hierarchical, bottom-up and layer-by-layer contraction of type definition. - -## Operation - -KCL supports operations on structure attributes in the form of $p op E$. That is, for the given structure $A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})$, the path $p$ in the structure is specified with the value of $E$ (such as union, assign, insert, etc.). - -Define the following update operations: - -$$ -\frac{{\Gamma\vdash A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})}  {\Gamma\vdash p \in (K_{1}, ..., K_{n})} \ {\Gamma\vdash e:T}   k \neq k_1, ..., k \neq k_n} -{ A \{p \ op \ e\}:\{K_1:T_1, ..., K_n:T_n\}∪\{p:T\}} -$$ - -That is to say, the operation on the path $p$ is essentially a union of two structures. The rules for the same name attribute type union depend on the situation. For example, the path $p$ is an identifier $p=k_1$ that can be used as a field name $k_1$, and the field name in structure A is also $k_1$, its type is $T_1$, and the type of the expression $e$ is also $T_1$, then - -$$ -\frac{{\Gamma\vdash A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})}  {\Gamma\vdash p = K_{1}} \ {\Gamma\vdash e:T_1}   k \neq k_1, ..., k \neq k_n} -{ A \{p \ op \ e\}:\{K_1:T_1, ..., K_n:T_n\}} -$$ - -Note: - -- The type $T_1$ of the expression $e$ have the same type with the original attribute of the same name $K_1$. It can be relaxed appropriately according to the actual situation, such as the type of $e$ $\sqsubseteq T_1$ is enough. -- For the operation of nested multi-layer structures, the above rules can be used recursively. - -## Type Partial Order - -### Basic Types - -$$ -Type \ T \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ T -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Bool \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Int \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Float \sqsubseteq Type \ Any -$$ - -$$ -Type \ Int \sqsubseteq Type \ Float -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ String \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Literal \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ List \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Dict \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Struct \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ None \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Void \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Any -$$ - -### Literal Type - -$$ -Type \ Literal(Bool) \sqsubseteq Type \ Bool -$$ - -$$ -Type \ Literal(Int) \sqsubseteq Type \ Int -$$ - -$$ -Type \ Literal(Float) \sqsubseteq Type \ Float -$$ - -$$ -Type \ Literal(String) \sqsubseteq Type \ String -$$ - -### Union Type - -$$ -Type \ X \sqsubseteq Type \ Union(X, Y) -$$ - -### Introspect - -$$ -Type \ X \sqsubseteq Type \ X -$$ - -Example - -$$ -Type \ Bool \sqsubseteq Type \ Bool -$$ - -$$ -Type \ Int \sqsubseteq Type \ Int -$$ - -$$ -Type \ Float \sqsubseteq Type \ Float -$$ - -$$ -Type \ String \sqsubseteq Type \ String -$$ - -$$ -Type \ List \sqsubseteq Type \ List -$$ - -$$ -Type \ Dict \sqsubseteq Type \ Dict -$$ - -$$ -Type \ Struct \sqsubseteq Type \ Struct -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Nothing -$$ - -$$ -Type \ Any \sqsubseteq Type \ Any -$$ - -$$ -Type \ Union(Type Int, Type Bool) \sqsubseteq Type \ Union(Type Int, Type Bool) -$$ - -### Transmit - -$$ -Type \ X \sqsubseteq Type \ Z \ if \ Type \ X \sqsubseteq Type \ Y \ and \ Type \ Y \sqsubseteq \ Type \ Z -$$ - -### Contained - -$$ -Type \ List(T_1) \sqsubseteq Type \ List(T_2) \ if \ T_1 \sqsubseteq T_2 -$$ - -$$ -Type \ Dict(T_{k1}, T_{v1}) \sqsubseteq Type \ Dict(T_{k2}, T_{v2}) \ if \ T_{k1} \sqsubseteq T_{k2} \ and \ T_{v1} \sqsubseteq T_{v1} -$$ - -$$ -Type \ Structure(K_1: T_{a1}, K_2: T_{a2}, ..., K_n: T_{an}) \sqsubseteq Type \ Structure(K_1: T_{b1}, K_2: T_{b2}, ..., K_n: T_{bn}) \ if \ T_{a1} \sqsubseteq T_{b1} \ and \ T_{a2} \sqsubseteq T_{b2} \ and \ ... \ and \ T_{an} \sqsubseteq T_{bn} -$$ - -### Inheritance - -$$ -Type \ Struct \ A \sqsubseteq Type \ Struct \ B \ if \ A \ inherits \ B -$$ - -### None - -$$ -Type \ None \sqsubseteq Type \ X, X \notin \{Type \ Nothing, \ Type \ Void\} -$$ - -### Undefined - -$$ -Type \ Undefined \sqsubseteq Type \ X, X \notin \{Type \ Nothing, \ Type \ Void\} -$$ - -## Equality - -- Commutative law - -$$ -Type \ Union(X, Y) == Type \ Union(Y, X) -$$ - -Example - -$$ -Type \ Union(Int, Bool) == Type \ Union(Bool, Int) -$$ - -- Associative law - -$$ -Type \ Union(Union(X, Y), Z) == Type \ Union(X, Union(Y, Z)) -$$ - -Example - -$$ -Type \ Union(Union(Int, String), Bool) == Type \ Union(Int, Union(String, Bool)) -$$ - -- Idempotent - -$$ -Type \ Union(X, X) == Type \ X -$$ - -Example - -$$ -Type \ Union(Int, Int) == Type \ Int -$$ - -Partial order derivation - -$$ -Type \ Union(X, Y) == Type \ Y \ if \ X \sqsubseteq Y -$$ - -Example - -Assume that Struct A inherits Struct B - -$$ -Type \ Union(A, B) == Type \ B -$$ - -Idempotency is a special case of partial order reflexivity - -### List - -$$ -Type \ List(X) == Type \ List(Y) \ if \ X == Y -$$ - -### Dict - -$$ -Type \ Dict(T_k, T_v) == Type \ Dict(S_k, S_v) \ if \ T_k == S_k \ and \ T_v == S_v -$$ - -### Struct - -$$ -Type \ Struct(K_1: T_{1}, K_2: T_{2}, ..., K_n: T_{n}) == Type \ Struct(K_1: S_{1}, K_2: S_{2}, ..., K_n: S_{n}) \ if \ T_{1} == S_{1} \ and \ ... \ and \ T_{n} == S_{n} -$$ - -### Partial Order Checking - -$$ -Type \ X == Type \ Y \ if \ Type \ X \sqsubseteq Type \ Y \ and \ Type \ Y \sqsubseteq \ Type \ X -$$ - -## Basic Methods - -- `sup(t1: T, t2: T) -> T`: Calculate the minimum upper bound of two types `t1` and `t2` according to the type partial order. The union type needs to be created dynamically. -- `typeEqual(t1: T, t2: T) -> bool`: Compare whether the two types `t1` and `t2` are equal. -- `typeToString(t: T) -> string`: Resolve and convert the type to the corresponding string type recursively from top to bottom. - -### Sup Function - -- Type parameters, condition types and other characteristics are not considered temporarily. -- Use an ordered collection to store all types of `UnionType`. -- Use a global map to store all generated union types according to the name of `UnionType`. -- Calculate the inclusion relationship between types according to the partial order relationship. - -```go -// The Sup function returns the minimum supremum of all types in an array of types -func Sup(types: T[]) -> T { - typeOf(types, removeSubTypes=true) -} - -// Build a sup type from types [T1, T2, ... , Tn] -func typeOf(types: T[], removeSubTypes: bool = false) -> T { - assert isNotNullOrEmpty(types) - // 1. Initialize an ordered set to store the type array - typeSet: Set[T] = {} - // 2. Add the type array to the ordered set for sorting by the type id and de-duplication - addTypesToTypeSet(typeSet, types) - // 3. Remove sub types according to partial order relation rules e.g. sub schema types - if removeSubTypes { - removeSubTypes(typeSet) - } - if len(typeSet) == 1 { - // If the typeSet has only one type, return it - return typeSet[0] - } - // 4. Get or set the union type from the global union type map - id := getIdentifierFromTypeSet(typeSet) - unionType := globalUnionTypeMap.get(id) - if !unionType { - unionType = createUnionType(typeSet) // Build a new union type - globalUnionTypeMap.set(id, unionType) - } - return unionType -} - -// Add many types into the type set -func addTypesToTypeSet(typeSet: Set[T], types: T[]) -> void { - for type in types { - addTypeToTypeSet(typeSet, type) - } -} - -// Add one type into the type set -func addTypeToTypeSet(typeSet: Set[T], type: T) -> void { - if isUnion(type) { - return addTypesToTypeSet(typeSet, toUnionOf(type).types) - } - // Ignore the void type check - if !isVoid(type) { - // De-duplication according to the type of id - typeSet.add(type) - } -} - -func removeSubTypes(types: Set[T]) -> void { - for source in types { - for target in types { - if !typeEqual(source, target) { - // If the two types have an inheritance relationship, the base class is retained, or if the two types have a partial order relationship according to the relation table. - if (isPartialOrderRelatedTo(source, target)) { - types.remove(source) - } - } - } - } -} - -// isPartialOrderRelatedTo function Determine whether two types have a partial order relationship `source \sqsubseteq target` -// according to the partial order relationship table and rules -func isPartialOrderRelatedTo(source: T, target: T) -> bool { - assert isNotNullOrEmpty(source) - assert isNotNullOrEmpty(target) - if isNoneOrUndefined(source) and !isNothing(target) and !isVoid(target) { - return true - } - if isAny(target) { - return true - } - if typeEqual(source, target) { - return true - } - if isUnion(target) and source in target.types { - return true - } - // Literal Type - if (isStringLiteral(source) and isString(target)) or \ - (isBooleanLiteral(source) and isBool(target)) or \ - (isIntLiteral(source) and isInt(target)) or \ - (isFloatLiteral(source) and isFloat(target)) { - return true - } - if isInt(source) and isFloat(target) { - return true - } - if isList(source) and isList(target) { - return isPartialOrderRelatedTo(toListOf(source).eleType, toListOf(target).eleType - } - if isDict(source) and isDict(target) { - return isPartialOrderRelatedTo(toDictOf(source).keyType, toDictOf(target).keyType) and isPartialOrderRelatedTo(toDictOf(source).valueType, toDictOf(target).valueType) - } - if isStruct(source) and isStruct(target) { - if isTypeDerivedFrom(source, target) { - return true - } - // Empty Object - if len(target.keys) == 0 { - return true - } - if any([key Not in source.keys for key in target.keys]) { - return false - } - for key, sourceType in (source.keys, source.types) { - targetType = getKeyType(target, key) ? getKeyType(target, key) : anyTypeOf() - if !isPartialOrderRelatedTo(sourceType, targetType) { - return false - } - } - return true - } - return false -} -``` - -## Type Checking - -### Checker - -The type checker traverses the syntax tree from top to bottom through syntax-directed translation, and determines whether the program structure is a well-typed program according to context-sensitive training rules. - -The type checker depends on type rules, and the information of type environment $\Gamma$ is recorded in the symbol table. Use abstract syntax for type expressions, such as `listof (T)`. When the type check fails, a type mismatch error is generated, and the error message is generated according to the syntax context. - -### Basic Methods - -1. `isUpperBound(t1, t2): supUnify(t1, t2) == t2` -2. `supUnify(t1, t2):` - -- For the foundation type, `sup(t1, t2)` is calculated according to the partial order relationship -- For list, dict, Struct, recursively `supUnify` the types of elements -- When there is no partial order relationship, return `Nothing` - -### Checking Logic - -#### Operand Expr - -$D \to id: T$ - -``` -env.addtype(id.entry, T.type) -``` - -$T \to boolean$ - -``` -T.type = boolean -``` - -$T \to integer$ - -``` -T.type = integer -``` - -$T \to float$ - -``` -T.type = float -``` - -$T \to string$ - -``` -T.type = string -``` - -$T \to c, \ c \in \{boolean, integer, float, string\}$ - -``` -T.type = literalof(c) -``` - -$T \to None$ - -``` -T.type = None -``` - -$T \to Undefined$ - -``` -T.type = Undefined -``` - -$T \to \ [T_1]$ - -``` -T.type = listof (T1.type) -``` - -$T \to { \{T_1: T_2\} }$ - -``` -T.type = dictof (T1.type: T2.type) -``` - -$T \to { \{N_1: T_1, N2: T_2, ..., N_n: T_n\} }$ - -``` -T.type = structof (N1: T1.type, N2: T2.type, ..., Nn: Tn.type) -``` - -$E \to id$ - -``` -E.type = env.lookup(id.entry) -``` - -$E \to [E_1, E_2, ..., E_n]$ - -``` -func listExpr(E) { - supe = sup([e.type for e in E]]) - E.type = listof(type) -} -``` - -$E \to [E_1 \ for \ E_2 \ in \ E_3 \ if \ E_4]$ - -``` -func listComp(E) { - if !typeEqual(E4.type, boolean) { - raise type_error - } - if !isUpperBound(listof(Any), E3.type) { - raise type_error(E) - } - if !isUpperBound(E3.type, E2.type) { - raise type_error(E) - } - E.type = listof(E1.type) -} -``` - -$E \to \{E_{k1}: E_{v1}, ..., E_{kn}: E_{vn}\}$ - -``` -func dictExpr(E) { - supk := sup([e.type for e in E.keys()]]) - supv := sup([e.type for e in E.values()]]) - E.type = dictof(supk, supv) -} -``` - -$E \to \{E_1:E_2 \ for \ (E_3, E_4) \ in \ E_5 \ if \ E_6\}$ - -``` -func dictComp(E) { - if !typeEqual(E6.type, boolean) { - raise type_error(E) - } - if !isUpperBound(dictof(Any, Any), E5.type) { - raise type_error(E) - } - if !isUpperBound(E5.type, dictof(E3.type, E4.type)) { - raise type_error(E) - } - E.type = dictof(E1.type, E2.type) -} -``` - -$E \to \{E_{k1}: E_{v1}, ..., E_{kn}: E_{vn}\}$ - -``` -func dictExpr(E) { - supk := sup(Ek1, ..., Ekn) - supv = sup(Ev1, ..., Evn) - E.type = dictof(supk, supv) -} -``` - -$E \to \{N_{1} = E_{1}, ..., N_{{n}} = E_{n}\}$ - -``` -func structExpr(E) { - Struct = structof() - for n, e in E { - Struct.add(n, e.type) - } - E.type = Struct -} -``` - -#### Primary Expr - -$E \to E_1[E_2]$ - -``` -func sliceSuffix(E) { - if !isUpperBound(listof(Any), E.E1.type) { - raise type_error(E) - } - if typeEqual(E.E2.type, integer) { - raise type_error(E) - } - E.type = E.E1.type.eleType -} -``` - -$E \to E_1(E_2)$ - -``` -func callSuffix(E) { - if !typeEqual(E.E1.type, func) { - raise type_error(E) - } - if !isUpperBound(listof(E.E1.arguType), E.E2.type) { - raise type_error(E) - } - E.type = E.E1.returnType -} -``` - -#### Unary Expr - -According to the reasoning rules of each binocular operator, take `+` as an example. - -$E \to + E_1$ - -``` -func Plus(E) { - if !typeEqual(E.E1.type, [integer, float]) { - raise type_error(E) - } - E.type = E.E1.type -} -``` - -#### Binary Expr - -According to the reasoning rules of each binocular operator, take `%` as an example. - -$E \to E_1 \ % \ E_2$ - -``` -func Mod(E) { - if !(typeEqual(E.E1.type, [integer, float]) && typeEqual(E.E2.type, [integer, float])) { - raise type_error(E) - } - E.type = E.E1.type -} -``` - -#### IF Binary Expr - -$E \to if E_1 \ then \ E_2 else \ E_3$ - -``` -func ifExpr(E) { - if !typeEqual(E.type, boolean) { - raise type_error(E) - } - if !typeEqual(E_2.type, E_3.type) { - raise type_error(E) - } - E.type = E_2.type -} -``` - -#### Stmt - -$S \to if \ E \ then \ S_1 \ else \ S_2$ - -``` -func ifStmt(S) { - if !typeEqual(S.E.type, boolean) { - raise type_error(E) - } - if !typeEqual(S.S1.type, S.S2.type) { - raise type_error(E) - } - S.type = S.S1.type -} -``` - -$S \to id: T = E$ - -$S \to id = T E$ - -``` -func assignStmt(S) { - tpe := env.lookup(id.entry) - if tpe != nil && tpe != S.T { - raise type_error(E) - } - if isUpperBound(tpe, E.type) { - raise type_error(E) - } - env.addtype(id.entry, T.type) -} -``` - -## Type Conversion - -### Basic Definition - -Through syntax-directed translation, the value types involved in the operation are automatically converted according to the operator characteristics. - -### Conversion Rules - -$E \to E_1 \ op \ E_2, , op \in \{+, -, *, /, \%, **, //\}$ - -``` -func binOp(E) { - if E.E1.type == integer and E.E2.type == integer { - E.type = integer - } else if E.E1.type == integer and E.E2.type == float { - E.type = float - } else if E.E1.type == float and E.E2.type == integer { - E.type = float - } else if E.E1.type == float and E.E2.type == float { - E.type = float - } -} -``` - -## Type Inference - -### Basic Definition - -- Type rule derivation and type reconstruction in case of incomplete type information -- Derive and reconstruct the data structure types in the program from the bottom up, such as basic type, e.g., list, dict and struct types. - -### Basic Methods - -1. `typeOf(expr, subst)`: The input is the expression and substitution rule set, and the type of expr and the new substitution rule set are returned. -2. `unifier(t1, t2, subst, expr)`: Try substitution with `t1=t2`. If the substitution is successful (no occurrence and no conflict), add `t1=t2` to the subst and return the subst. Otherwise, an error has occurred or there is a conflict. - -### Inferential Logic - -$E \to id = E_1$ - -``` -func assignExpr(E, subst) { - return unifier(E.id.type, E.E_1.type, subst, E) -} -``` - -$unifier(t1, t2, subst, expr) \rightarrow subst$ - -``` -func unifier(t1, t2, subst, expr) { - t1 = applySubstToTypeEquation(t1, subst) - t2 = applySubstToTypeEquation(t2, subst) - - if t1 == t2 { - return subst - } - - if isTypeVar(t1) { - if isNoOccur(t1, t2) { - addTypeEquationToSubst(subst, t1, t2) - return subst - } else { - raise occurrence_violation_error(t1, t2, expr) - } - } - - if isTypeVar(t2) { - if isNoOccur(t2, t1) { - addTypeEquationToSubst(subst, t2, t1) - return subst - } else { - raise occurrence_violation_error(t2, t1, expr) - } - } - - if isList(t1) and isList(t2) { - return unifier(toListOf(t1).eleType, toListOf(t2).eleType, subst, expr) - } - if isDict(t1) and isDict(t2) { - dict1of := toDictOf(t1) - dict2of := toDictOf(t2) - subst = unifier(dict1of.keyType, dict2of.keyType, subst, expr) - subst = unifier(dict1of.valueType, dict2of.valueType, subst, expr) - return subst - } - if isStruct(t1) and isStruct(t2) { - Struct1of := tostructof(t1) - Struct2of := tostructof(t2) - for key, _ in Struct1of { - subst = unifier(t1[key].type, t2[key].type, subst, expr) - } - return subst - } - - raise unification_error(t1, t2, expr) -} - -func applySubstToTypeEquation(t, subst) { - // walks through the type t, replacing each type variable by its binding in the substitution -σ. If a variable is Not bound in the substitution, then it is left unchanged. - if isBasicType(t) { - return t - } - if isList(t) { - return listOf(applySubstToTypeEquation(toListOf(t).eleType, subst)) - } - if isDict(t) { - dictof := toDictOf(t) - kT := applySubstToTypeEquation(dictof.keyType, subst) - vT := applySubstToTypeEquation(dictof.valueType, subst) - return dictOf(kT, vT) - } - if isStruct(t) { - structof := tostructof(t) - s := structof() - for key, type in Struct1of { - kT := applySubstToTypeEquation(type, subst) - s.add(key, kT) - } - return s - } - if hasTypeVar(t) { - for tvar in t.vars { - if tvar in subst { - *tvar = subst[tvar] - } - } - } - return t -} - -func addTypeEquationToSubst(subst, tvar, t) { - // takes the substitution σ and adds the equation tv = t to it - for _, t in subst { - for tvar in t.vars { - tmp := applyOneSubst(tsvar, tvar, t) - *tvar = tmp - } - } - subst.add(tvar, t) -} - -func applyOneSubst(t0, tvar, t1) { - // substituting t1 for every occurrence of tv in t0. - if isBasicType(t0) { - return t0 - } - if isList(t0) { - return listOf(applyOneSubst(toListOf(t).eleType, tvar, t1)) - } - if isDict(t0) { - dictof := toDictOf(t) - kT := applyOneSubst(dictof.keyType, tvar, t1) - vT := applyOneSubst(dictof.valueType, tvar, t1) - return dictOf(kT, vT) - } - if isStruct(t0) { - structof := tostructof(t) - s := structof() - for key, type in Struct1of { - kT := applyOneSubst(type, tvar, t1) - s.add(key, kT) - } - return s - } - if t0 == tvar { - return t1 - } - return t0 -} - -func isNoOccur(tvar, t) { - // No variable bound in the substitution occurs in any of the right-hand sides of the substitution. - if isBasicType(t) { - return true - } - if isList(t) { - return isNoOccur(tvar, toListOf(t).eleType) - } - if isDict(t) { - dictof := toDictOf(t) - return isNoOccur(tvar, dictof.keyType) and isNoOccur(tvar, dictof.valueType) - } - if isStruct(t) { - structof := tostructof(t) - noOccur := true - for _, type in structof { - noOccur = noOccur and isNoOccur(tvar, type) - } - return noOccur - } - return tvar != t -} -``` - -### Example - -#### Normal Inference - -``` -T : { - a = 1 - b = "2" - c = a * 2 - d = { - d0 = [a, c] - } -} - -x: T = { - a = 10 -} -``` - -#### Occurrence Violation Error - -``` -T = { - a = a -} -``` - -#### Type Unification Error - -``` -T : { - a = 1 -} - -T : { - a = "1" -} -``` - -## Reference - -- [https://en.wikipedia.org/wiki/Type_system](https://en.wikipedia.org/wiki/Type_system) -- Pierce, Benjamin C. (2002). Types and Programming Languages. MIT Press. -- [https://www.cs.cornell.edu/courses/cs4110/2010fa/](https://www.cs.cornell.edu/courses/cs4110/2010fa/) -- [https://www.typescriptlang.org/docs/handbook/basic-types.html](https://www.typescriptlang.org/docs/handbook/basic-types.html) -- [https://www.typescriptlang.org/docs/handbook/advanced-types.html](https://www.typescriptlang.org/docs/handbook/advanced-types.html) diff --git a/versioned_docs/version-0.7.0/reference/model/_category_.json b/versioned_docs/version-0.7.0/reference/model/_category_.json deleted file mode 100644 index 398617be..00000000 --- a/versioned_docs/version-0.7.0/reference/model/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "System Package", - "position": 2 -} diff --git a/versioned_docs/version-0.7.0/reference/model/base64.md b/versioned_docs/version-0.7.0/reference/model/base64.md deleted file mode 100644 index 3f6e617b..00000000 --- a/versioned_docs/version-0.7.0/reference/model/base64.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: "base64" -linkTitle: "base64" -type: "docs" -description: base64 system module - base64 encode and decode function -weight: 100 ---- - -## encode - -`encode(value: str, encoding: str = "utf-8") -> str` - -Encode the string `value` using the codec registered for encoding. - -## decode - -`decode(value: str, encoding: str = "utf-8") -> str` - -Decode the string `value` using the codec registered for encoding. diff --git a/versioned_docs/version-0.7.0/reference/model/builtin.md b/versioned_docs/version-0.7.0/reference/model/builtin.md deleted file mode 100644 index 4bb34766..00000000 --- a/versioned_docs/version-0.7.0/reference/model/builtin.md +++ /dev/null @@ -1,386 +0,0 @@ ---- -title: "builtin" -sidebar_position: 1 ---- - -KCL provides a list of built-in functions that are automatically loaded and can be used directly without providing any module name. For example, `print` is a function provided by a widely used built-in module. - -## Type Conversion Functions - -KCL's `bool`, `int`, `float`, `str`, `list`, `dict` and other types have built-in conversion functions of the same name. Among them, `int` can not only be used to truncate floating-point numbers, but also can be used to convert strings to integers (decimal when parsing, other values can also be specified). - -The following are common uses of type-related functions: - -```py -b1 = bool(1) # true -b2 = bool(1.5) # true -b3 = bool("true") # true -b4 = bool("") # false -b5 = bool([]) # false -b6 = bool({}) # false - -i1 = int("11") # 11 -i2 = int("11", base=8) # 9 -i3 = int("11", base=2) # 3 - -f1 = float(1) # 1.0 -f2 = float("1.5") # 1.5 - -s1 = str(1) # 1 - -l1 = list([1, 2, 3]) -``` - -## String Builtin Member Functions - -- [String Spec](/docs/reference/lang/spec/datatypes) - -## print - -`print(*args:any, end:str='\n')` - -The built-in print function, which provides different types of variable parameter printing, adds a newline at the end by default. The following are common usages: - -```python -print("hello KCL") -print() -print(None, end=':') -print(None) -print(True) -print(False) -print(123) -print(123.0) -print('abc ${123}') -print("abc ${456}") -print([1,'a', True]) -print(1,'a', True) -print({}) -print({a: 123}) -``` - -The output is: - -```shell -hello KCL - -None:None -True -False -123 -123.0 -abc 123 -abc 456 -[1, 'a', True] -1 a True -{} -{'a': 123} -``` - -If you do not want the default newline, you can re-specify the ending string with the `end=''` named parameter. - -```python -print("Hello KCL", end='') -``` - -## multiplyof - -`multiplyof(a:int, b:int) -> bool` - -Check whether the integer `a` is an integer multiple of `b`, and return a boolean value: - -```python -print(multiplyof(2, 1)) # True -print(multiplyof(1, 2)) # False -print(multiplyof(0, 1)) # True -print(multiplyof(0, 2)) # True -print(multiplyof(1, 0)) # Error -``` - -`0` is a multiple of any number. But `b` cannot be `0`, otherwise an exception will be thrown. - -## isunique - -`isunique(list: [any]) -> bool` - -Check if there are duplicate elements in an array, and return a boolean value: - -```python -print(isunique([])) # True -print(isunique([1])) # True -print(isunique([1, 2])) # True - -print(isunique([1, 1])) # False -print(isunique([1, 1.0])) # False -print(isunique([1.1, 1.1])) # False - -print(isunique(['abc', "abc"])) # False -print(isunique(['abc', "a${'bc'}"])) # False -``` - -It should be noted that integers and floating-point numbers ignore the type difference and judge whether the values are equal. - -## len - -`len(x: str | [any] | {:}) -> int` - -Return the length of strings, lists, and arrays: - -```python -print(len([])) # 0 -print(len({})) # 0 - -print(len([1])) # 1 -print(len({abc:123})) # 1 - -print("abc") # 3 -``` - -Note: Calculating lengths on `schema` objects is not supported. - -## abs - -`abs(x: number) -> number` - -Calculate the absolute value of `x`. - -## all_true - -`all_true(x:str|[]|{:}) -> bool` - -Judging that all elements of a list or dictionary class are true, the usage is as follows: - -```python -print(all_true([])) # True -print(all_true({})) # True - -print(all_true([True])) # True -print(all_true([1])) # True - -print(all_true([True, False])) # False -print(all_true([True, None])) # False -``` - -Returns true when the list is empty. - -## any_true - -`any_true(x:str|[]|{:}) -> bool` - -Judging that at least one element in the iterable object is true, the usage is as follows: - -```python -print(any_true([])) # False -print(any_true([1])) # True -``` - -## bin - -`bin(x:number) -> str` - -A string that returns the binary representation of an integer, used as follows: - -```python -print(bin(8)) # 0b1000 -``` - -## hex - -`hex(number)` - -A string that returns the hexadecimal representation of an integer, used as follows: - -```python -print(hex(18)) # 0x12 -``` - -## oct - -`oct(number)` - -A string that returns the octal representation of an integer, used as follows: - -```python -print(oct(10)) # 0o12 -``` - -## option - -`option(key:str, type:str='', required=False, default=None, help="") -> any` - -Gets the value of the command line top level argument input. - -## ord - -`ord(c) -> int` - -Get the Unicode code point value of the character, the usage is as follows: - -```python -print(ord('A')) # 65 -print(ord('B')) # 66 -print(ord('C')) # 67 -``` - -## sorted - -`sorted(x: []) -> []` - -Returns the sorted list, used as follows: - -```python -_a = [] -_b = [2, 1] - -_c = sorted(_a) -_d = sorted(_b) - -print(_a) # [] -print(_b) # [2, 1] -print(_c) # [] -print(_d) # [1, 2] -``` - -## range - -`range(start:int, end:int, step=1) -> [int]` - -Generates an iterable list, used as follows: - -```python -print(range(1,5)) # [1, 2, 3, 4] -print(range(1,5, 2)) # [1, 3] -print(range(5, 1, -1)) # [5, 4, 3, 2] -``` - -## min - -`min(x:[number]) -> number` - -Returns the smallest element in the list, used as follows: - -```python -print(min([1,2])) # 1 -print(min([2,1])) # 1 -``` - -## max - -`max(x:[number]) -> number` - -Returns the largest element in the list, used as follows: - -```python -print(max([1,2])) # 2 -print(max([2,1])) # 2 -``` - -## sum - -`sum(x:[number], init_value=0) -> number` - -Returns the sum of all elements in the list, used as follows: - -``` -print(sum([1,2])) # 3 -print(sum([2,1], 1000)) # 1003 -``` - -## pow - -`pow(x: number, y: number, z: number = None) -> number` - -Computes `x**y`, or `(x**y)%z` if `z` is not empty, supports integer and floating point numbers, used as follows: - -```python -print(pow(2,3)) # 8 -print(pow(2, 3, 5)) # 8%5 == 3 - -print(pow(2, 0.5)) # 1.414 -``` - -## round - -`round(number: int|float, ndigits:int|None) -> float | int` - -Returns the rounded approximation of `number`. If `ndigits` is not `None` returns a float with the specified number of decimal places (cannot be negative), otherwise returns an integer structure, used as follows: - -```python -print(round(1)) # 1 -print(round(1.4)) # 1 -print(round(1.5)) # 2 - -print(round(1.5555, 1)) # 1.6 -print(round(1.5555, 2)) # 1.56 - -print(round(1.5555)) # 2 -print(round(1.5555, 0)) # 2.0 -``` - -It should be noted that the difference between `ndigits` being `None` and `0` is that the prefix returns `int` type, the latter returns `float` type. - -## typeof - -`typeof(x: any, full_name: bool = False) -> str` - -Output the type of `x` at runtime. When the `full_name` parameter is set to `True`, the package prefix of the form `pkg.schema` will be returned, used as follows: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person{} -t3 = typeof(_x1) - -_x2 = pkg.Person{} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# Output -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -## zip - -`zip(*args: str|list|dict)` - -It is used to take an iterable object as a parameter, pack the corresponding elements in the object into tuples, and then return a list composed of these tuples, used as follows: - -```py -a = zip([0, 1, 2], [3, 4, 5]) -b = zip([0, 1], [3, 4, 5]) -c = zip([0, 1, 2], [3, 4, 5, 6]) - -# Output -# a: -# - - 0 -# - 3 -# - - 1 -# - 4 -# - - 2 -# - 5 -# b: -# - - 0 -# - 3 -# - - 1 -# - 4 -# c: -# - - 0 -# - 3 -# - - 1 -# - 4 -# - - 2 -``` diff --git a/versioned_docs/version-0.7.0/reference/model/crypto.md b/versioned_docs/version-0.7.0/reference/model/crypto.md deleted file mode 100644 index 7fab7e50..00000000 --- a/versioned_docs/version-0.7.0/reference/model/crypto.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "crypto" -linkTitle: "crypto" -type: "docs" -description: crypto system module -weight: 100 ---- - -## md5 - -`md5(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `MD5` and the codec registered for encoding. - -## sha1 - -`sha1(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA1` and the codec registered for encoding. - -## sha224 - -`sha224(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA224` and the codec registered for encoding. - -## sha256 - -`sha256(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA256` and the codec registered for encoding. - -## sha384 - -`sha384(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA384` and the codec registered for encoding. - -## sha512 - -`sha512(value: str, encoding: str = "utf-8") -> str` - -Encrypt the string `value` using `SHA512` and the codec registered for encoding. diff --git a/versioned_docs/version-0.7.0/reference/model/manifests.md b/versioned_docs/version-0.7.0/reference/model/manifests.md deleted file mode 100644 index ab31ad47..00000000 --- a/versioned_docs/version-0.7.0/reference/model/manifests.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: "manifests" -linkTitle: "manifests" -type: "docs" -description: manifests system module -weight: 100 ---- - -## yaml_stream - -```python -yaml_stream(values: [any], opts: {str:} = { - sort_keys = False - ignore_private = True - ignore_none = False - sep = "---" -}) -``` - -This function is used to serialize the KCL object list into YAML output with the --- separator. It has two parameters: - -- `values` - A list of KCL objects -- `opts` - The YAML serialization options - - `sort_keys`: Whether to sort the serialized results in the dictionary order of attribute names (the default is `False`). - - `ignore_private`: Whether to ignore the attribute output whose name starts with the character `_` (the default value is `True`). - - `ignore_none`: Whether to ignore the attribute with the value of' None '(the default value is `False`). - - `sep`: Set the separator between multiple YAML documents (the default value is `"---"`). - -Here's an example: - -```python -# Use the `import` keyword to import the `manifests` module. -import manifests - -# The schema `Deployment` definition. -schema Deployment: - apiVersion: str = "v1" - kind: str = "Deployment" - metadata: {str:} = { - name = "deploy" - } - spec: {str:} = { - replica = 2 - } - -# The schema `Service` definition. -schema Service: - apiVersion: str = "v1" - kind: str = "Service" - metadata: {str:} = { - name = "svc" - } - spec: {str:} = {} - -# Define two `Deployment` resources. -deployments = [Deployment {}, Deployment {}] -# Define two `Service` resources. -services = [Service {}, Service {}] -# Put them into a KCL list and call the `manifests.yaml_stream` function. -manifests.yaml_stream(deployments + services) -``` - -First, we use the `import` keyword to import the `manifests` module and define two deployment resources and two service resources. When we want to output these four resources in YAML stream format with `---` as the separator, we can put them into a KCL list and use the `manifests.yaml_stream` function pass it to the `values` parameter (if there is no special requirement, the `opts` parameter can generally use the default value). Finally, the YAML output is: - -```yaml -apiVersion: v1 -kind: Deployment -metadata: - name: deploy -spec: - replica: 2 ---- -apiVersion: v1 -kind: Deployment -metadata: - name: deploy -spec: - replica: 2 ---- -apiVersion: v1 -kind: Service -metadata: - name: svc ---- -apiVersion: v1 -kind: Service -metadata: - name: svc -``` diff --git a/versioned_docs/version-0.7.0/reference/model/net.md b/versioned_docs/version-0.7.0/reference/model/net.md deleted file mode 100644 index a4e83659..00000000 --- a/versioned_docs/version-0.7.0/reference/model/net.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: "net" -linkTitle: "net" -type: "docs" -description: net system module -weight: 100 ---- - -## split_host_port - -`split_host_port(ip_end_point: str) -> List[str]` - -Split the `host` and `port` from the `ip_end_point`. - -## join_host_port - -`join_host_port(host, port) -> str` - -Merge the `host` and `port`. - -## fqdn - -`fqdn(name: str = '') -> str` - -Return Fully Qualified Domain Name (FQDN). - -## parse_IP - -`parse_IP(ip) -> str` - -Parse `ip` to a real IP address - -## to_IP4 - -`to_IP4(ip) -> str` - -Get the IP4 form of `ip`. - -## to_IP16 - -`to_IP16(ip) -> int` - -Get the IP16 form of `ip`. - -## IP_string - -`IP_string(ip: str | int) -> str` - -Get the IP string. - -## is_IPv4 - -`is_IPv4(ip: str) -> bool` - -Whether `ip` is a IPv4 one. - -## is_IP - -`is_IP(ip: str) -> bool` - -Whether `ip` is a valid ip address. - -## is_loopback_IP - -`is_loopback_IP(ip: str) -> bool` - -Whether `ip` is a loopback one. - -## is_multicast_IP - -`is_multicast_IP(ip: str) -> bool` - -Whether `ip` is a multicast one. - -## is_interface_local_multicast_IP - -`is_interface_local_multicast_IP(ip: str) -> bool` - -Whether `ip` is a interface, local and multicast one. - -## is_link_local_multicast_IP - -`is_link_local_multicast_IP(ip: str) -> bool` - -Whether `ip` is a link local and multicast one. - -## is_link_local_unicast_IP - -`is_link_local_unicast_IP(ip: str) -> bool` - -Whether `ip` is a link local and unicast one. - -## is_global_unicast_IP - -`is_global_unicast_IP(ip: str) -> bool` - -Whether `ip` is a global and unicast one. - -## is_unspecified_IP - -`is_unspecified_IP(ip: str) -> bool` - -Whether `ip` is a unspecified one. diff --git a/versioned_docs/version-0.7.0/reference/model/regex.md b/versioned_docs/version-0.7.0/reference/model/regex.md deleted file mode 100644 index adde0630..00000000 --- a/versioned_docs/version-0.7.0/reference/model/regex.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "regex" -linkTitle: "regex" -type: "docs" -description: regex system module -weight: 100 ---- - -## replace - -`replace(string: str, pattern: str, replace: str, count=0) -> str` - -Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement. - -## match - -`match(string: str, pattern: str) -> bool` - -Try to apply the pattern at the start of the string, returning a bool value `True` if any match was found, or `False` if no match was found. - -## compile - -`compile(pattern: str) -> bool` - -Compile a regular expression pattern, returning a bool value denoting whether the pattern is valid. - -## findall - -`findall(string: str, pattern: str) -> List[str]` - -Return a list of all non-overlapping matches in the string. - -## search - -`search(string: str, pattern: str) -> bool` - -Scan through string looking for a match to the pattern, returning a bool value `True` if any match was found, or `False` if no match was found. - -## split - -`split(string: str, pattern: str, maxsplit=0) -> List[str]` - -Return a list composed of words from the string, splitting up to a maximum of `maxsplit` times using `pattern` as the separator. diff --git a/versioned_docs/version-0.7.0/reference/model/units.md b/versioned_docs/version-0.7.0/reference/model/units.md deleted file mode 100644 index 34465a53..00000000 --- a/versioned_docs/version-0.7.0/reference/model/units.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: "units" -linkTitle: "units" -type: "docs" -description: units system module - Unit handlers -weight: 100 ---- - -## Constants - -- Fixed point unit constants: `n`, `u`, `m`, `k`, `K`, `G`, `T` and `P`. -- Power of 2 unit constants: `Ki`, `Mi`, `Gi`, `Ti` and `Pi`. - -## Functions - -- `to_n(num: int) -> str` - Int literal to string with `n` suffix -- `to_u(num: int) -> str` - Int literal to string with `u` suffix -- `to_m(num: int) -> str` - Int literal to string with `m` suffix -- `to_K(num: int) -> str` - Int literal to string with `K` suffix -- `to_M(num: int) -> str` - Int literal to string with `M` suffix -- `to_G(num: int) -> str` - Int literal to string with `G` suffix -- `to_T(num: int) -> str` - Int literal to string with `T` suffix -- `to_P(num: int) -> str` - Int literal to string with `P` suffix -- `to_Ki(num: int) -> str` - Int literal to string with `Ki` suffix -- `to_Mi(num: int) -> str` - Int literal to string with `Mi` suffix -- `to_Gi(num: int) -> str` - Int literal to string with `Gi` suffix -- `to_Ti(num: int) -> str` - Int literal to string with `Ti` suffix -- `to_Pi(num: int) -> str` - Int literal to string with `Pi` suffix diff --git a/versioned_docs/version-0.7.0/reference/plugin/_category_.json b/versioned_docs/version-0.7.0/reference/plugin/_category_.json deleted file mode 100644 index e77dfb1c..00000000 --- a/versioned_docs/version-0.7.0/reference/plugin/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Plugin System", - "position": 4 -} diff --git a/versioned_docs/version-0.7.0/reference/plugin/index.md b/versioned_docs/version-0.7.0/reference/plugin/index.md deleted file mode 100644 index df299e93..00000000 --- a/versioned_docs/version-0.7.0/reference/plugin/index.md +++ /dev/null @@ -1 +0,0 @@ -# Plugin System diff --git a/versioned_docs/version-0.7.0/reference/plugin/project_context.md b/versioned_docs/version-0.7.0/reference/plugin/project_context.md deleted file mode 100644 index 0be02e78..00000000 --- a/versioned_docs/version-0.7.0/reference/plugin/project_context.md +++ /dev/null @@ -1,59 +0,0 @@ -# project_context - -project_context extract base info from project.yaml&stack.yaml - -_version: 0.0.1_ - -## `get_project_current_path` - -return the relative path of first file - -Example: - -```py -import kcl_plugin.project_context as ctx - -path = ctx.get_project_current_path() -print(path) -``` - -## `get_project_input_file` - -return compiling file list - -Example: - -```py -import kcl_plugin.project_context as ctx - -input_file = ctx.get_project_input_file() -print(input_file) -``` - -## `get_project_context` - -return the current project context from project.yaml - -Example: - -```py -import kcl_plugin.project_context as ctx - -project = ctx.get_project_context() -# Get project name -print(project?.name) -``` - -## `get_stack_context` - -return the current stack context from stack.yaml - -Example: - -```py -import kcl_plugin.project_context as ctx - -stack = ctx.get_stack_context() -# Get stack name -print(stack?.name) -``` diff --git a/versioned_docs/version-0.7.0/reference/xlang-api/_category_.json b/versioned_docs/version-0.7.0/reference/xlang-api/_category_.json deleted file mode 100644 index c2aafb21..00000000 --- a/versioned_docs/version-0.7.0/reference/xlang-api/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Multi-Language", - "position": 4 -} diff --git a/versioned_docs/version-0.7.0/reference/xlang-api/index.md b/versioned_docs/version-0.7.0/reference/xlang-api/index.md deleted file mode 100644 index f6f8e076..00000000 --- a/versioned_docs/version-0.7.0/reference/xlang-api/index.md +++ /dev/null @@ -1 +0,0 @@ -# Multi-Language diff --git a/versioned_docs/version-0.7.0/reference/xlang-api/java-api.md b/versioned_docs/version-0.7.0/reference/xlang-api/java-api.md deleted file mode 100644 index 52c8cf34..00000000 --- a/versioned_docs/version-0.7.0/reference/xlang-api/java-api.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Java API - -At present, the KCL Java SDK is still in the early preview version. The KCL team will continue to update and provide more functions in the future. For more information, see [https://github.com/kcl-lang/kcl-java](https://github.com/kcl-lang/kcl-java) diff --git a/versioned_docs/version-0.7.0/reference/xlang-api/overview.md b/versioned_docs/version-0.7.0/reference/xlang-api/overview.md deleted file mode 100644 index e63422d4..00000000 --- a/versioned_docs/version-0.7.0/reference/xlang-api/overview.md +++ /dev/null @@ -1,293 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Introduction - -The KCL language provides general programming language interfaces such as C/Rust/Go/Python/Java, and the related languages are under development. - -## C/Rust API - -The core of KCL is developed in Rust, and the C language API is exported externally for packaging and integration in high-level languages such as Go/Python/Java. - -## Go API - -Go API is a C-API provided by CGO wrapping KCL, while providing deeper customization features to meet the needs of upper-level tools. - -### Abstract Model - -The abstract model of the KCL Go API is as follows: - -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ kcl files │ │ KCL-Go-API │ │ KCLResultList │ -│ ┌───────────┐ │ │ │ │ │ -│ │ 1.k │ │ │ │ │ │ -│ └───────────┘ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ ┌───────────┐ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.Get("a.b.c") │ -│ │ 2.k │ │ │ │ Run(path) │ │ │ └───────────┘ │ └───────────────┘ -│ └───────────┘ │────┐ │ └───────────┘ │ │ │ -│ ┌───────────┐ │ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ │ 3.k │ │ │ │ │ │ │ KCLResult │──┼────────▶│x.Get("k", &v) │ -│ └───────────┘ │ │ │ │ │ └───────────┘ │ └───────────────┘ -│ ┌───────────┐ │ ├───▶│ ┌───────────┐ │──────────▶│ │ -│ │setting.yml│ │ │ │ │RunFiles() │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ └───────────┘ │ │ │ └───────────┘ │ │ │ KCLResult │──┼────────▶│x.JSONString() │ -└─────────────────┘ │ │ │ │ └───────────┘ │ └───────────────┘ - │ │ │ │ │ -┌─────────────────┐ │ │ │ │ ┌───────────┐ │ ┌───────────────┐ -│ Options │ │ │ ┌───────────┐ │ │ │ KCLResult │──┼────────▶│x.YAMLString() │ -│WithOptions │ │ │ │MustRun() │ │ │ └───────────┘ │ └───────────────┘ -│WithOverrides │────┘ │ └───────────┘ │ │ │ -│WithWorkDir │ │ │ │ │ -│WithDisableNone │ │ │ │ │ -└─────────────────┘ └─────────────────┘ └─────────────────┘ -``` - -The input file contains the KCL file and the `setting.yml` configuration file, and `Options` can be used to specify additional parameters and information such as working directory. The "KCL-Go-API" part is the provided KCL execution function. The execution function executes the KCL program according to the input file and additional parameters, and finally outputs the result of `KCLResultList`. `KCLResultList` is a list of `KCLResult`, each `KCLResult` corresponding to a generated configuration file or `map[string]interface{}`. - -### Example - -```go -package main - -import ( - "fmt" - - kcl "kcl-lang.io/kcl-go" -) - - -func main() { - const k_code = ` -name = "kcl" -age = 1 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person{} -x1 = Person{age:101} -` - - result := kcl.MustRun("hello.k", kcl.WithCode(k_code)).First() - fmt.Println(result.YAMLString()) - - fmt.Println("----") - fmt.Println("x0.name:", result.Get("x0.name")) - fmt.Println("x1.age:", result.Get("x1.age")) - - fmt.Println("----") - - var person struct { - Name string - Age int - } - fmt.Printf("person: %+v\n", result.Get("x1", &person)) -} -``` - -Output result: - -```yaml -age: 1 -name: kcl -x0: - age: 1 - name: kcl -x1: - age: 101 - name: kcl - ----- -x0.name: kcl -x1.age: 101 ----- -person: &{Name:kcl Age:101} -``` - -## Python API - -Using the Python SDK requires that you have a local Python version higher than 3.7.3 and a local pip package management tool. You can use the following command to install and obtain helpful information. - -```bash -python3 -m pip install kclvm --user && python3 -m kclvm --help -``` - -### Command Line Tool - -Prepare a KCL file named `main.k` - -```python -name = "kcl" -age = 1 - -schema Person: - name: str = "kcl" - age: int = 1 - -x0 = Person {} -x1 = Person { - age = 101 -} -``` - -Execute the following command and get the output: - -```shell -$ python3 -m kclvm hello.k -name: kcl -age: 1 -x0: - name: kcl - age: 1 -x1: - name: kcl - age: 101 -``` - -### API - -In addition, we can also execute KCL files through Python code. - -Prepare a KCL file named `main.py` - -```python -import kclvm.program.exec as kclvm_exec -import kclvm.vm.planner as planner - -print(planner.plan(kclvm_exec.Run(["hello.k"]).filter_by_path_selector())) -``` - -Execute the following command and get the output: - -```shell -$ python3 main.py -name: kcl -age: 1 -x0: - name: kcl - age: 1 -x1: - name: kcl - age: 101 -``` - -You can see that the same output can be obtained through command line tools and APIs. - -At present, the KCL Python SDK is still in the early preview version. The KCL team will continue to update and provide more functions in the future. For more information, see [https://github.com/kcl-lang/kcl-py](https://github.com/kcl-lang/kcl-py) - -## REST-API - -The C-API provided by KCL does not have a REST-API. The REST-API is defined by Protobuf. - -### Start REST Service - -The RestAPI service can be started in the following way: - -```shell -python3 -m pip install kclvm -U -python3 -m gunicorn "kclvm.program.rpc-server.__main__:create_app()" -t 120 -w 4 -k uvicorn.workers.UvicornWorker -b :2021 -``` - -The service can then be requested via the POST protocol: - -```shell -$ curl -X POST http://127.0.0.1:2021/api:protorpc/BuiltinService.Ping --data '{}' -{ - "error": "", - "result": {} -} -``` - -The POST request and the returned JSON data are consistent with the structure defined by Protobuf. - -### `BuiltinService` - -Where the `/api:protorpc/BuiltinService.Ping` path represents the `Ping` method of the `BuiltinService` service. - -The complete `BuiltinService` is defined by Protobuf: - -```protobuf -service BuiltinService { - rpc Ping(Ping_Args) returns(Ping_Result); - rpc ListMethod(ListMethod_Args) returns(ListMethod_Result); -} - -message Ping_Args { - string value = 1; -} -message Ping_Result { - string value = 1; -} - -message ListMethod_Args { - // empty -} -message ListMethod_Result { - repeated string method_name_list = 1; -} -``` - -The `Ping` method can verify whether the service is normal, and the `ListMethod` method can query the list of all services and functions provided. - -### `KclvmService` - -The `KclvmService` service is a service related to KCL functionality. The usage is the same as the `BuiltinService` service. - -For example, there is the following `Person` structure definition: - -```python -schema Person: - key: str - - check: - "value" in key # 'key' is required and 'key' must contain "value" -``` - -Then we want to use `Person` to verify the following JSON data: - -```json -{ "key": "value" } -``` - -This can be done through the `ValidateCode` method of the `KclvmService` service. Refer to the `ValidateCode_Args` structure of the `ValidateCode` method: - -```protobuf -message ValidateCode_Args { - string data = 1; - string code = 2; - string schema = 3; - string attribute_name = 4; - string format = 5; -} -``` - -Construct the JSON data required by the POST request according to the `ValidateCode_Args` structure, which contains the `Person` definition and the JSON data to be verified: - -```json -{ - "code": "\nschema Person:\n key: str\n\n check:\n \"value\" in key # 'key' is required and 'key' must contain \"value\"\n", - "data": "{\"key\": \"value\"}" -} -``` - -Save this JSON data to the `vet-hello.json` file and verify it with the following command: - -```shell -$ curl -X POST \ - http://127.0.0.1:2021/api:protorpc/KclvmService.ValidateCode \ - -H "accept: application/json" \ - --data @./vet-hello.json -{ - "error": "", - "result": { - "success": true - } -} -``` - -## APIs in other languages - -Coming soon diff --git a/versioned_docs/version-0.7.0/reference/xlang-api/python-api.md b/versioned_docs/version-0.7.0/reference/xlang-api/python-api.md deleted file mode 100644 index e6ce67dc..00000000 --- a/versioned_docs/version-0.7.0/reference/xlang-api/python-api.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Python API - -At present, the KCL Python SDK is still in the early preview version. The KCL team will continue to update and provide more functions in the future. For more information, see [https://github.com/kcl-lang/kcl-py](https://github.com/kcl-lang/kcl-py) diff --git a/versioned_docs/version-0.7.0/tools/Ide/_category_.json b/versioned_docs/version-0.7.0/tools/Ide/_category_.json deleted file mode 100644 index d9bfcdd7..00000000 --- a/versioned_docs/version-0.7.0/tools/Ide/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "IDE", - "position": 2 -} diff --git a/versioned_docs/version-0.7.0/tools/_category_.json b/versioned_docs/version-0.7.0/tools/_category_.json deleted file mode 100644 index 5ecd522f..00000000 --- a/versioned_docs/version-0.7.0/tools/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Tools", - "position": 3 -} diff --git a/versioned_docs/version-0.7.0/tools/cli/_category_.json b/versioned_docs/version-0.7.0/tools/cli/_category_.json deleted file mode 100644 index 887061ef..00000000 --- a/versioned_docs/version-0.7.0/tools/cli/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Command Line Tools", - "position": 1 -} diff --git a/versioned_docs/version-0.7.0/tools/cli/index.md b/versioned_docs/version-0.7.0/tools/cli/index.md deleted file mode 100644 index ef4f69dc..00000000 --- a/versioned_docs/version-0.7.0/tools/cli/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# Command Line Tools - -KCL provides IDE plug-ins, rich language tools and OpenAPI tools. These tools provide a complete set of solutions, including configuration languages, model interfaces, automation tools, and best practices. diff --git a/versioned_docs/version-0.7.0/tools/cli/kcl/_category_.json b/versioned_docs/version-0.7.0/tools/cli/kcl/_category_.json deleted file mode 100644 index 4c605bd0..00000000 --- a/versioned_docs/version-0.7.0/tools/cli/kcl/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KCL Tools", - "position": 2 -} diff --git a/versioned_docs/version-0.7.0/tools/cli/openapi/_category_.json b/versioned_docs/version-0.7.0/tools/cli/openapi/_category_.json deleted file mode 100644 index 58e4c68a..00000000 --- a/versioned_docs/version-0.7.0/tools/cli/openapi/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "OpenAPI Tools", - "position": 3 -} diff --git a/versioned_docs/version-0.7.0/tools/cli/openapi/index.md b/versioned_docs/version-0.7.0/tools/cli/openapi/index.md deleted file mode 100644 index 236d6e36..00000000 --- a/versioned_docs/version-0.7.0/tools/cli/openapi/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# OpenAPI Tools - -The KCL OpenAPI tool can not only convert common models but also support CRD and other models. diff --git a/versioned_docs/version-0.7.0/tools/cli/package-management/command-reference/_category_.json b/versioned_docs/version-0.7.0/tools/cli/package-management/command-reference/_category_.json deleted file mode 100644 index 8c705ed9..00000000 --- a/versioned_docs/version-0.7.0/tools/cli/package-management/command-reference/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Command Reference", - "position": 4 -} diff --git a/versioned_docs/version-0.7.0/user_docs/concepts/_category_.json b/versioned_docs/version-0.7.0/user_docs/concepts/_category_.json deleted file mode 100644 index d40bb9de..00000000 --- a/versioned_docs/version-0.7.0/user_docs/concepts/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Concepts", - "position": 5 -} diff --git a/versioned_docs/version-0.7.0/user_docs/concepts/package-and-module.md b/versioned_docs/version-0.7.0/user_docs/concepts/package-and-module.md deleted file mode 100644 index a36e45c9..00000000 --- a/versioned_docs/version-0.7.0/user_docs/concepts/package-and-module.md +++ /dev/null @@ -1,156 +0,0 @@ -# Module and Package - -This section mainly describes how to organize files in KCL. - -## Overview - -Within a **module**, KCL organizes files grouped by **package**. A package can be defined within a module or be imported externally (through KCL package manager `kpm`). In the latter case, KCL maintains a copy of the package within the module in a dedicated location. - -## Module - -A KCL module contains a configuration laid out in a directory hierarchy. It contains everything that is needed to deterministically determine the outcome of a KCL configuration. The root of this directory is marked by containing a `kcl.mod` directory. The contents of this directory are mostly managed by the kcl tool such as `kpm`, etc. In that sense, `kcl.mod` is analogous to the `.git` directory marking the root directory of a repo, but where its contents are mostly managed by the git tool. Besides, a KCL module is the largest unit of the file organization, has a fixed location of all KCL files and dependencies. - -> Note: The use of a KCL module e.g., `kcl.mod` is optional, but required if one wants to manage, distribute, share and reuse code with a semantic version. - -### Creating a module - -A module can be created by running the following command within the module root: - -```bash -kpm init [module name] -``` - -The module name is **required** if a package within the module needs to import another package within the module. A module can also be created by setting up the `kcl.mod` file manually. - -## Package - -In KCL, a package is usually composed of a "folder" containing KCL files. This folder can be a real disk physical path, or it can be composed of multiple KCL files (usually main package). Different packages are uniquely located by different package paths (such as `kubernetes.core.v1`) - -Within the same module, different packages can be imported from each other through the import statement of relative or absolute path. During the KCL parsing process, the relative import will be replaced by absolute import and the corresponding KCL code will be found through the package path. - -### Relative Import Path - -We can use the operator `.` to realize the relative path import of KCL entry files. - -main.k: - -```python -import .model1 # Current directory module -import ..service # Parent directory -import ...root # Parent of parent directory - -s = service.ImageService {} -m = root.Schema {} -``` - -### Absolute Import Path - -The semantics of `import a.b.c.d` is - -1. If `kcl.mod` not exist, regard the current directory as the package root and search the path `a/b/c/d` from the current directory. -2. If the current directory search fails, search from the root path `ROOT_PATH/a/b/c/d`, else raise an import error. - -The definition of the root path `ROOT_PATH` is the directory corresponding to the `kcl.mod` file from the current directory. - -Code structure: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -### Builtin Package - -KCL has a collection of builtin packages such as `math`, `regex`, etc. To use a builtin package, import it directly and invoke the functions using its qualified identifier. For instance, - -```python -import regex - -image = "nginx:1.14.2" -is_match = regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$") - -``` - -The output YAML is - -```yaml -image: nginx:1.14.2 -is_match: true -``` - -### Plugin Package - - - -KCL also has a collection of plugin packages such as `hello`, `project_context`, etc. To use a plugin package, import it with a `kcl_plugin.` package path prefix and invoke the functions using its qualified identifier. For instance, - -```python -import kcl_plugin.hello - -result = hello.add(1, 1) -``` - -The output YAML is - -```yaml -result: 2 -``` - -### Main Package - -In KCL, the composition of the main package is usually determined by the compiler parameters. This is because the KCL schema and constraints can be split across files in the package, or even organized across directories, considering the convenience of writing and maintaining the configuration in isolated blocks. - -#### Files belonging to a main package - -It is up to the user to decide which configurations and constraints to use using the KCL command line. For example, - -```bash -kcl file1.k file2.k -``` - -Thus, the main package contains two KCL files named `file1.k` and `file2.k`. - -If KCL is told to load the files for a specific directory, for example: - -```bash -kcl ./path/to/package -``` - -It will only look KCL files with `.k` suffix and ignore files with `_` prefix or `_test.k` into the main package. Besides, if the `./path/to/package` contains `kcl.yaml` files, `kcl.yaml` files be ignored. - -In addition, we can set main package files through configuring the command-line compilation setting file (e.g., `kcl.yaml`) as follows: - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k -``` - -```bash -kcl -Y kcl.yaml -``` - -> Note: If we do not specify any input files for KCL, KCL will find the default `kcl.yaml` from the command line execution path to read the input file. Besides, if we tell KCL both the input files and the compilation setting file, KCL will take input files entered by the user as the final value. - -```bash -# Whether the 'files' field is configured in `kcl.yaml` or not, the final value of input files is ["file1.k", "file2.k"] -kcl -Y kcl.yaml file1.k file2.k -``` - -## The relationship and difference between `kcl.mod` and `kcl.yaml` - -First of all, in KCL, `kcl.mod` and `kcl.yaml` are both optional. The difference is that `kcl.mod` determines the root path of the package path and whether a KCL module has the requirement of distribution and reuse, and `kcl.yaml` determines the KCL file composition of the main package. - -Secondly, for a kcl module for external use only, `kcl.yaml` is optional but `kcl.mod` is required, because it needs to declare the KCL version, module version, dependency and other information. - -Finally, for the KCL IDE plug-in, it needs to know the main package information to form a complete compilation process, so it needs to automatically look up the composition of the main package according to the position of the cursor, because no one can specify this information through the KCL command line. The general query logic is to find whether `kcl.yaml` exists. If it is found, the main package consists of the `files` attribute in `kcl.yaml`, and if not found, the main package consists of the current file. The KCL IDE plug-in is selectively aware of the `kcl.mod` file. When the `kcl.mod` file exists, the IDE plug-in reads the corresponding information of all package paths and their real paths in the external dependencies. diff --git a/versioned_docs/version-0.7.0/user_docs/concepts/type-and-definition.md b/versioned_docs/version-0.7.0/user_docs/concepts/type-and-definition.md deleted file mode 100644 index ed82315f..00000000 --- a/versioned_docs/version-0.7.0/user_docs/concepts/type-and-definition.md +++ /dev/null @@ -1,94 +0,0 @@ -# Type and Definition - -This section mainly covers the concepts related to types and definitions. - -## Type - -KCL features a **gradual static type system**, initially designed to consider scalability. Its aim is to significantly reduce the configuration writing difficulties for users while maintaining stability. Static typing enhances code quality, acts as documentation, and helps detect errors at an early stage when needed. For instance, defining a complete static type for data like JSON/YAML can be challenging, similar to how TypeScript adds complexity in handling type gymnastics due to the lack of runtime type checks for Javascript. In contrast, KCL incorporates a similar TypeScript type system while still retaining runtime type checks. Thus, type errors will always appear at runtime. Consequently, KCL has types, but they can be selectively used when necessary, and it handles interactions between typed and untyped code elegantly and securely. - -The configuration of attributes and types in KCL usually follows a simple pattern: - -$$ -k = (T) v -$$ - -where $k$ is the attribute name, $v$ is the attributes value, and $T$ is the type annotation. Since KCL has the ability of the type inference, $T$ is usually omitted. - -By default, KCL does not require type annotations and performs type checks at runtime. - -```python -name = "nginx" # The type of `name` is `str` -port = 80 # The type of `port` is `int` -``` - -As long as we operate on basic types such as integers and strings, it is generally sufficient to annotate the default type and directly write the configuration. KCL can infer the type of basic data. We recommend writing types for complex structures and function definitions, which will clearly provide a good input prompt for other users who use structures and functions. - -```python -# Types for schema -schema App: - name: str - domainType: "Standard" | "Customized" | "Global" - containerPort: int - volumes: [Volume] - services: [Service] - - check: - 1 <= containerPort <= 65535 - -schema Service: - clusterIP: str - $type: str - - check: - clusterIP == "None" if $type == "ClusterIP" - -schema Volume: - container: str = "*" # The default value of `container` is "*" - mountPath: str - - check: - mountPath not in ["/", "/boot", "/home", "dev", "/etc", "/root"] - -# Types for lambda -appFilterFunc = lambda apps: [App], name: str -> [App] { - [a for a in apps if a.name == name] -} -``` - -More formal definitions and usage of types are at the [type specification document](/docs/reference/lang/types/) and the [tour document of the type system](/docs/reference/lang/tour#type-system) - -**Schema** is the core type in KCL, just like a database schema, which defines the organization of configuration data. This includes logical constraints such as schema names, fields, data types, and the relationships between these entities. Patterns typically use visual representations to convey the architecture of a database, becoming the foundation for organizing configuration data. The process of designing schema patterns is also known as configuration modeling. KCL Schema typically serves various roles, such as application developers, DevOps platform administrators, and SRE, and provides them with a unified configuration interaction interface. - -In addition, the ability to enforce constraints from top to bottom is crucial for any large-scale configuration setting. Therefore, KCL not only provides the ability to define static types but also provides the rich ability to define constraints, which is to some extent equivalent to assertion statements in programming languages. To prevent assertions from constantly expanding, we place structural constraints together with structural type definitions and support custom error messages. - -In KCL, we can use schema to organize the configuration data to meet the requirements of model definition, abstraction, and templating. Schema is the core feature of KCL, which defines attributes, operations, and check-blocks. Usually, a formal form of KCL Schema can be written in the following form: - -$$ -S = \Sigma_{i = 1}^{N} \{s_i, T_i, \mathcal{T}[s_i]\}, -$$ - -where $N$ is the total number of attributes, $\mathcal{T}$ is the attribute constraint, $s_i$ and $T_i$ denotes the $i$-th attribute name and type. Simultaneously, to improve the reusability of the code and meet the needs of hierarchical definition, KCL draws on the experience of OOP and uses single inheritance to reuse and extend the schema. Schema inheritance can be regarded as a special type of partial order relationship, and satisfies - -$$ -unionof(T_1, T_2) = T_2 \Leftrightarrow T_1 \subseteq T_2, -$$ - -where $T_1$ and $T_2$ are both schema types. When the above equation is not satisfied, the KCL will throw a type check error. - -A typical schema with constraints is defined as follows: - -```python -import regex - -schema Secret: - name: str - # Data defines the keys and data that will be used by secret. - data?: {str:str} - - check: - all k in data { - regex.match(k, r"[A-Za-z0-9_.-]*") - } if data, "a valid secret data key must consist of alphanumeric characters, '-', '_' or '.'" -``` - -More specifications and usage of KCL schema and constraint is [here](/docs/reference/lang/spec/schema). diff --git a/versioned_docs/version-0.7.0/user_docs/getting-started/_category_.json b/versioned_docs/version-0.7.0/user_docs/getting-started/_category_.json deleted file mode 100644 index 1bf165d4..00000000 --- a/versioned_docs/version-0.7.0/user_docs/getting-started/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Get Started", - "position": 1 -} diff --git a/versioned_docs/version-0.7.0/user_docs/getting-started/kcl-quick-start.md b/versioned_docs/version-0.7.0/user_docs/getting-started/kcl-quick-start.md deleted file mode 100644 index 2316d9a6..00000000 --- a/versioned_docs/version-0.7.0/user_docs/getting-started/kcl-quick-start.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Quick Start - -KCL is a cloud-native domain configuration and policy language. At the beginning of its design, KCL was inspired by Python3, and at the same time absorbed the conceptual design of declarative and OOP programming paradigms. In this section we will quickly demonstrate the basic features of the KCL language. - -## 1. Hello KCL - -The best way to learn a new language is to write a few small programs, and the same goes for configuring languages. We can write KCL programs just like writing configuration. - -Here is a simple `hello.k`: - -```python -hello = "KCL" -``` - -Set the `hello` attribute to the `"KCL"` string. Then save the code to the `hello.k` file. - -How to execute this program depends on the specific development environment, we first assume that the local macOS or Linux system has installed the `kcl` command (or enter the **Docker** environment test by `docker run --rm -it kcllang/kcl`) and then run the following command: - -```shell -kcl hello.k -``` - -The output is - -```yaml -hello: KCL -``` - -The effect of command line execution is shown as follows: - -![](/img/docs/user_docs/getting-started/hello.gif) - -The output is configuration data in YAML format. Although this program is simple, we can verify the basic usage of the development environment and the `kcl` command line by executing the KCL configuration program to the output. - -## 2. A little more complicated configuration - -In addition to the common key-value pairs, common configuration data also has nested dictionary and list types, and the value basic type includes boolean and numeric types in addition to strings. Here's a slightly more complex `server.k` configuration: - -```python -# This is a KCL document - -title = "KCL Example" - -owner = { - name = "The KCL Authors" - data = "2020-01-02T03:04:05" -} - -database = { - enabled = True - ports = [8000, 8001, 8002] - data = [["delta", "phi"], [3.14]] - temp_targets = {cpu = 79.5, case = 72.0} -} - -servers = [ - {ip = "10.0.0.1", role = "frontend"} - {ip = "10.0.0.2", role = "backend"} -] -``` - -where `#` begins with a line comment. The value of `owner` is a dictionary. The value of the dictionary contains the content in the form of `{}`. The key-value inside the dictionary is similar to the `hello = "KCL"` example. `database` is another dictionary in which the value of the dictionary attribute appears boolean `True`, list `[]` and dictionary `{}`, in which the value of the numeric type also appears in the list and dictionary. The `servers` attribute is a list with dictionaries nested inside the list (dictionaries and lists, as well as the `schema` that will be discussed later, can be nested within each other). - -The YAML output of this configuration is as follows: - -```yaml -$ kcl server.k -title: KCL Example -owner: - name: The KCL Authors - data: '2020-01-02T03:04:05' -database: - enabled: true - ports: - - 8000 - - 8001 - - 8002 - data: - - - delta - - phi - - - 3.14 - temp_targets: - cpu: 79.5 - case: 72.0 -servers: -- ip: 10.0.0.1 - role: frontend -- ip: 10.0.0.2 - role: backend -``` - -## 3. Define the structure of the configuration using KCL schema - -The KCL provides abstract support for attributes with a fixed attribute structure and default value behavior through the `schema` syntax. - -For example, the configuration of `database` in the above example is generally the default value. We can define a structure for the default configuration of the database: - -```python -schema DatabaseConfig: - enabled: bool = True - ports: [int] = [8000, 8001, 8002] - data: [[str|float]] = [["delta", "phi"], [3.14]] - temp_targets: {str: float} = {cpu = 79.5, case = 72.0} -``` - -`enabled` is a boolean type; `ports` is an integer list type; `data` is a list of lists, and the inner list elements are strings or floats; `temp_targets` is a dictionary type, and the attribute value of the dictionary is floating point type. And each attribute of `DatabaseConfig` defines a default value. - -Then pass `database = DatabaseConfig {}` to generate a structure with the same attributes as the default values. We can also modify the default value: - -```python -database = DatabaseConfig { - ports = [2020, 2021] -} -``` - -`schema DatabaseConfig` not only provides default values for attributes, but also adds type information to attributes. Therefore, if we accidentally writes the wrong attribute value type, KCL will give a friendly error prompt, such as the following example where `ports` is wrongly written as a floating point type: - -```python -database = DatabaseConfig { - ports = [1.2, 1.3] -} -``` - -When executed, an error similar to the following will be generated (the displayed file path depends on the local environment): - -```shell -kcl server.k -``` - -The output is - -```shell -error[E2G22]: TypeError - --> /path/to/server.k:8:5 - | -8 | ports = [1.2, 1.3] - | ^ expected [int], got [float(1.2)|float(1.3)] - | - - --> /path/to/server.k:3:5 - | -3 | ports: [int] = [8000, 8001, 8002] - | ^ variable is defined here, its type is [int], but got [float(1.2)|float(1.3)] - | -``` - -Similarly we can encapsulate the attributes of the `servers` section with the following code: - -```python -schema ServerConfig: - ip: str - role: "frontend" | "backend" - -servers = [ - ServerConfig {ip = "10.0.0.1", role = "frontend"} - ServerConfig {ip = "10.0.0.2", role = "backend"} -] -``` - -The attribute `ip` of `ServerConfig` is a string type, and no default value is given. We must manually add the value of the `ip` attribute when generating the `ServerConfig` type attribute, otherwise the KCL will report a missing required attribute error. The `role` attribute is a `"frontend" | "backend"` enumerated string type. - -In addition, `schema` can also combine `check`, `mixin`, optional attributes, inheritance and extension modules to achieve more complex configuration and policy data abstraction, full language details can be found at [here](/docs/reference/lang/tour). diff --git a/versioned_docs/version-0.7.0/user_docs/guides/_category_.json b/versioned_docs/version-0.7.0/user_docs/guides/_category_.json deleted file mode 100644 index 40b1340d..00000000 --- a/versioned_docs/version-0.7.0/user_docs/guides/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "User Guide", - "position": 4 -} diff --git a/versioned_docs/version-0.7.0/user_docs/guides/abstraction.md b/versioned_docs/version-0.7.0/user_docs/guides/abstraction.md deleted file mode 100644 index cec40e2c..00000000 --- a/versioned_docs/version-0.7.0/user_docs/guides/abstraction.md +++ /dev/null @@ -1,151 +0,0 @@ ---- -title: "Abstraction" -sidebar_position: 3 ---- - -## Introduction - -Abstraction refers to a simplified representation of an entity, typically used in computing. It allows for the concealment of specific details while presenting the most relevant information to the programmer. Each abstraction is tailored to suit a specific need, and can greatly enhance the usability of a given entity. In the context of KCL, abstraction can make code easier to understand and maintain, while also simplifying the user interface. - -It should be noted that code abstraction is not meant to reduce code size, but rather to improve maintainability and extendability. During the process of abstracting code, factors such as reusability, readability, and scalability should be taken into consideration, and the code should be optimized as needed. - -The values of the good abstraction - -1. Provides distinct focal points for better comprehension for specific identities, roles, and scenarios. -2. Shields lower-level details to avoid potential errors. -3. Enhances user-friendliness and automation with better portability and good APIs. - -KCL may not assess the rationality of a user's abstraction, but it offers technical solutions to facilitate the process. - -## Use KCL for Abstraction - -**Now, let's begin to abstract Docker Compose and Kubernetes models into an application config.** - -Application centric development allows developers to focus on their workload's architecture rather than the tech stack in the target environment, infrastructure or platform. We define our application once with the `App` schema and then use the KCL CLI to translate it to multiple platforms, such as `Docker Compose` or `Kubernetes` with different versions. - -`Docker Compose` is a tool for defining and running multi-container Docker applications. With Docker Compose, you can define your application's services, networks, and volumes in a single file, and then use it to start and stop your application as a single unit. Docker Compose simplifies the process of running complex, multi-container applications by handling the details of networking, storage, and other infrastructure concerns. - -`Kubernetes manifests` are YAML files that define Kubernetes objects such as Pods, Deployments, and Services. Manifests provide a declarative way to define the desired state of your application, including the number of replicas, the image to use, and the network configuration. Kubernetes uses the manifests to create and manage the resources needed to deploy and run your application. - -Here are some references to learn more about Docker Compose and Kubernetes manifests: - -- [Docker Compose documentation](https://docs.docker.com/compose/) -- [Kubernetes manifest documentation](https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/) - -The application model aims to reduce developer toil and cognitive load by only having to define a single KCL file that works across multiple platforms, and it is designed to be applied to multiple environments to reduce the amount of configuration. Now, let's learn how to do this. - -### 0. Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/abstraction -``` - -We can run the following command to show the config. - -```bash -cat main.k -``` - -The output is - -```python -import .app - -app.App { - name = "app" - containers.nginx = { - image = "nginx" - ports = [{containerPort = 80}] - } - service.ports = [{ port = 80 }] -} -``` - -In the above code, we defined a configuration using the `App` schema, where we configured an `nginx` container and configured it with an `80` service port. - -Besides, KCL allows developers to define the resources required for their applications in a declarative manner and is tied to a platform such as Docker Compose or Kubernetes manifests and allows to generate a platform-specific configuration file such as `docker-compose.yaml` or a Kubernetes `manifests.yaml` file. Next, let's generate the corresponding configuration. - -### 2. Transform the Application Config into Docker Compose Config - -If we want to transform the application config into the docker compose config, we can run the command simply: - -```shell -kcl main.k docker_compose_render.k -``` - -The output is - -```yaml -services: - app: - image: nginx - ports: - - published: 80 - target: 80 - protocol: TCP -``` - -### 3. Transform the Application Config into Kubernetes Deployment and Service Manifests - -If we want to transform the application config into the Kubernetes manifests, we can run the command simply: - -```shell -kcl main.k kubernetes_render.k -``` - -The output is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: app - labels: - app: app -spec: - replicas: 1 - selector: - matchLabels: - app: app - template: - metadata: - labels: - app: app - spec: - containers: - - name: nginx - image: nginx - ports: - - protocol: TCP - containerPort: 80 ---- -apiVersion: v1 -kind: Service -metadata: - name: app - labels: - app: app -spec: - selector: - app: app - ports: - - port: 80 - protocol: TCP -``` - -Look, it's so simple. If you want to learn more information about the application model, you can refer to [here](https://github.com/kcl-lang/kcl-lang.io/tree/main/examples/abstraction). - -## Summary - -Through the use of KCL, we are able to separate the abstraction and implementation details of a model, allowing for the abstract model to be mapped to various infrastructures or platforms. This is achieved through flexible switching between different implementations and the combination of compilation, which shields configuration differences and ultimately reduces the cognitive burden. - -## Further Information - -In addition to manually maintaining the configuration, we can also use KCL APIs to integrate **automatic configuration changes** into our applications. For specific instructions, please refer to [here](/docs/user_docs/guides/automation). diff --git a/versioned_docs/version-0.7.0/user_docs/guides/ci-integration/1-github-actions.md b/versioned_docs/version-0.7.0/user_docs/guides/ci-integration/1-github-actions.md deleted file mode 100644 index c4a09c6e..00000000 --- a/versioned_docs/version-0.7.0/user_docs/guides/ci-integration/1-github-actions.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -id: github-actions -sidebar_label: Github Actions ---- - -# Github Actions Integration - -## Introduction - -In the GitOps section, we have introduced how to integrate KCL with GitOps. In this section, we will continue to provide sample solutions for KCL and CI integrations. We hope to implement the end-to-end application development process by using containers, Continuous Integration (CI) for generation, and GitOps for Continuous Deployment (CD). In this scheme, we use a **Flask application** and **Github Actions** as examples. - -> Note: You can use any containerized application and different CI systems such as **Gitlab CI**, **Jenkins CI**, etc. in this solution. - -The overall workflow is as follows: - -- Develop application code and submit it to the GitHub repository to trigger CI. -- GitHub Actions generate container images from application code and push them to the `docker.io` container registry. -- GitHub Actions automatically synchronizes and updates the KCL manifest deployment file based on the version of the container image in the docker.io container registry. - -## Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -## How to - -### 1. Get the Example - -We put the application source code and infrastructure deployment code in different repos, which can be maintained by different roles to achieve the separation of concerns. - -- Get the application code - -```shell -git clone https://github.com/kcl-lang/flask-demo.git/ -cd flask-demo -``` - -This is a web application written in Python. We can use the `Dockerfile` in the application directory to generate a container image of this application, and also use Github CI to automatically build a image named `flask_demo`, the CI configuration is as follows - -```yaml -# This is a basic workflow to help you get started with Actions - -name: CI - -# Controls when the workflow will run -on: - # Triggers the workflow on push or pull request events but only for the main branch - push: - branches: [main] - pull_request: - branches: [main] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "build" - build: - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - - - name: Docker Login - uses: docker/login-action@v1.10.0 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - logout: true - - # Runs a set of commands using the runners shell - - name: build image - run: | - make image - docker tag flask_demo:latest ${{ secrets.DOCKER_USERNAME }}/flask_demo:${{ github.sha }} - docker push ${{ secrets.DOCKER_USERNAME }}/flask_demo:${{ github.sha }} - - # Trigger KCL manifest - - name: Trigger CI - uses: InformaticsMatters/trigger-ci-action@1.0.1 - with: - ci-owner: kcl-lang - ci-repository: flask-demo-kcl-manifests - ci-ref: refs/heads/main - ci-user: kcl-bot - ci-user-token: ${{ secrets.DEPLOY_ACCESS_TOKEN }} - ci-name: CI - ci-inputs: >- - image=${{ secrets.DOCKER_USERNAME }}/flask_demo - sha-tag=${{ github.sha }} -``` - -We need the workflow in the source code repository to automatically trigger the workflow in the deployment manifest repository. At this point, we need to create a `secrets.DEPLOY_ACCESS_TOKEN` with Github CI operation permissions and **Docker Hub** image push account information `secrets.DOCKER_USERNAME` and `secrets.DOCKER_PASSWORD` can be configured in the `Secrets and variables` settings of the Github, as shown in the following figure - -![](/img/docs/user_docs/guides/ci-integration/github-secrets.png) - -### 2. Commit the Application Code - -After submitting in the `flask-demo` repository, Github will automatically build a container image and push it to the Docker hub. It will also then trigger the Action of the `flask-demo-kcl-manifest` repository and modify the image value in the deployment manifest repository through [KCL Automation API](/docs/user_docs/guides/automation). Now let's create a submission in the `flask-demo` repository, and we can see that the code submission triggers the Github CI process for the application repository. - -![](/img/docs/user_docs/guides/ci-integration/app-ci.png) - -### 3. Configuration Automatic Update - -After the Github CI process in the application repository is completed, an automatic update configuration CI will be triggered in the repository where the KCL configuration is stored and submitted to the main branch of the `flask-demo-kcl-manifests` repository. The commit information is as follows - -![](/img/docs/user_docs/guides/ci-integration/image-auto-update.png) - -- We can obtain the deployment manifest source code for compilation and validation - -```shell -git clone https://github.com/kcl-lang/flask-demo-kcl-manifests.git/ -cd flask-demo-kcl-manifests -git checkout main && git pull && kcl -``` - -The output YAML is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - replicas: 1 - selector: - matchLabels: - app: flask_demo - template: - metadata: - labels: - app: flask_demo - spec: - containers: - - name: flask_demo - image: "kcllang/flask_demo:6428cff4309afc8c1c40ad180bb9cfd82546be3e" - ports: - - protocol: TCP - containerPort: 5000 ---- -apiVersion: v1 -kind: Service -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - type: NodePort - selector: - app: flask_demo - ports: - - port: 5000 - protocol: TCP - targetPort: 5000 -``` - -From the above configuration, it can be seen that the image of the resource is indeed automatically updated to the newly constructed image value. In addition, we can also use the **Argo CD KCL plugin** to automatically synchronize data from the Git repository and deploy the application to the Kubernetes cluster. - -## Summary - -By integrating KCL and Github CI, we can integrate the container build and delivery workflow by automatically updating the image values in the configuration, in order to achieve end-to-end application development process and improve R&D deployment efficiency. diff --git a/versioned_docs/version-0.7.0/user_docs/guides/ci-integration/2-gitlab-ci.md b/versioned_docs/version-0.7.0/user_docs/guides/ci-integration/2-gitlab-ci.md deleted file mode 100644 index 124e9bd9..00000000 --- a/versioned_docs/version-0.7.0/user_docs/guides/ci-integration/2-gitlab-ci.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -id: gitlab-ci -sidebar_label: Gitlab CI ---- - -# Gitlab CI Integration - -## Introduction - -In the GitOps section, we have introduced how to integrate KCL with GitOps. In this section, we will continue to provide sample solutions for KCL and CI integrations. We hope to implement the end-to-end application development process by using containers, Continuous Integration (CI) for generation, and GitOps for Continuous Deployment (CD). In this scheme, we use a **Flask application** and **Gitlab CI** as examples. - -> Note: You can use any containerized application and different CI systems such as **Github Actions**, **Jenkins CI**, etc. in this solution. - -The overall workflow is as follows: - -- Develop application code and submit it to the Gitlab repository to trigger CI. -- Gitlab generate container images from application code and push them to the `docker.io` container registry. -- Gitlab CI automatically synchronizes and updates the KCL manifest deployment file based on the version of the container image in the docker.io container registry. - -## Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -## How to - -We put the application source code and infrastructure deployment code in different repos, which can be maintained by different roles to achieve the separation of concerns. - -### 1. Get the Example - -- Get the application code - -```shell -git clone https://gitlab.com/kcl-lang/flask-demo.git/ -cd flask-demo -``` - -This is a web application written in Python. We can use the `Dockerfile` in the application directory to generate a container image of this application, and also use Gitlab CI to automatically build a image named `flask_demo`, the CI configuration is as follows - -```yaml -stages: - - publish - - deploy - -publish: - stage: publish - image: - name: cnych/kaniko-executor:v0.22.0 - entrypoint: [""] - script: - - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json - - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile ./Dockerfile --destination $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA - only: - - main - -deploy: - stage: deploy - image: cnych/kustomize:v1.0 - before_script: - - git remote set-url origin https://gitlab.com/kcl-lang/flask-demo - - git config --global user.email "gitlab@git.local" - - git config --global user.name "GitLab CI/CD" - # Install KCL - - wget -q https://kcl-lang.io/script/install.sh -O - | /bin/bash - script: - - git checkout -B main - - cd deployment - # Image auto update - - /usr/local/kclvm/bin/kcl -d -O config.containers.flask_demo.image="$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" - - git commit -am '[skip ci] image update to $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA' - - git push origin main - only: - - main -``` - -We need the workflow in the source code repository to automatically trigger the workflow in the deployment manifest repository. At this point, we need to config `Settings -> CI/CD -> Variables` including `CI_REGISTRY`, `CI_REGISTRY_IMAGE`, `CI_REGISTRY_USER`, `CI_REGISTRY_PASSWORD`, `CI_USERNAME` and `CI_PASSWORD` and update application code to trigger automation build and deploy. - -![](/img/docs/user_docs/guides/ci-integration/gitlab-ci-variables.jpg) - -### 2. Commit the Application Code - -After submitting in the `flask-demo` repository, Gitlab will automatically build a container image and push it to the Docker hub. It will also then trigger the Action of the `flask-demo-kcl-manifest` repository and modify the image value in the deployment manifest repository through [KCL Automation API](/docs/user_docs/guides/automation). Now let's create a submission in the `flask-demo` repository, and we can see that the code submission triggers the Gitlab CI process for the application repository `Build -> Pipelines` page. - -### 3. Configuration Automatic Update - -After the Gitlab CI process in the application repository is completed, an automatic update configuration CI will be triggered in the repository where the KCL configuration is stored and submitted to the main branch of the `flask-demo` repository. - -- We can obtain the deployment manifest source code for compilation and validation - -```shell -git checkout main && git pull && cd deploy && kcl -``` - -The output YAML is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - replicas: 1 - selector: - matchLabels: - app: flask_demo - template: - metadata: - labels: - app: flask_demo - spec: - containers: - - name: flask_demo - image: "kcllang/flask_demo:6428cff4309afc8c1c40ad180bb9cfd82546be3e" - ports: - - protocol: TCP - containerPort: 5000 ---- -apiVersion: v1 -kind: Service -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - type: NodePort - selector: - app: flask_demo - ports: - - port: 5000 - protocol: TCP - targetPort: 5000 -``` - -From the above configuration, it can be seen that the image of the resource is indeed automatically updated to the newly constructed image value. In addition, we can also use the **Argo CD KCL plugin** to automatically synchronize data from the Git repository and deploy the application to the Kubernetes cluster. - -## Summary - -By integrating KCL and Gitlab CI, we can integrate the container build and delivery workflow by automatically updating the image values in the configuration, in order to achieve end-to-end application development process and improve R&D deployment efficiency. diff --git a/versioned_docs/version-0.7.0/user_docs/guides/ci-integration/_3-jenkins-ci.md b/versioned_docs/version-0.7.0/user_docs/guides/ci-integration/_3-jenkins-ci.md deleted file mode 100644 index f85d231f..00000000 --- a/versioned_docs/version-0.7.0/user_docs/guides/ci-integration/_3-jenkins-ci.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -id: github-ci -sidebar_label: Github CI ---- - -Coming Soon - -## Introduction - -## How to - -## Summary diff --git a/versioned_docs/version-0.7.0/user_docs/guides/ci-integration/_category_.json b/versioned_docs/version-0.7.0/user_docs/guides/ci-integration/_category_.json deleted file mode 100644 index 3145ed7f..00000000 --- a/versioned_docs/version-0.7.0/user_docs/guides/ci-integration/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "CI Integration", - "position": 12 -} \ No newline at end of file diff --git a/versioned_docs/version-0.7.0/user_docs/guides/data-integration.md b/versioned_docs/version-0.7.0/user_docs/guides/data-integration.md deleted file mode 100644 index c05b2e7b..00000000 --- a/versioned_docs/version-0.7.0/user_docs/guides/data-integration.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: "Data Integration" -sidebar_position: 4 ---- - -## Introduction - -In KCL, we can not only compile and output the configuration code written by KCL into YAML format data, but also directly embed JSON/YAML and other data into the KCL language. - -## Use KCL for Data Integration - -### 0. Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/data-integration -``` - -### 2. YAML Integration - -We can run the following command to show the YAML integration config. - -```bash -cat yaml.k -``` - -```python -import yaml - -schema Server: - ports: [int] - -server: Server = yaml.decode("""\ -ports: -- 80 -- 8080 -""") -server_yaml = yaml.encode({ - ports = [80, 8080] -}) -``` - -In the above code, we use the built-in `yaml` module of KCL and its `yaml.decode` function directly integrates YAML data, and uses the `Server` schema to directly verify the integrated YAML data. In addition, we can use `yaml.encode` to serialize YAML data. We can obtain the configuration output through the following command: - -```shell -kcl yaml.k -``` - -The output is - -```yaml -server: - ports: - - 80 - - 8080 -server_yaml: | - ports: - - 80 - - 8080 -``` - -### 3. JSON Integration - -Similarly, for JSON data, we can use `json.encode` and `json.decode` function performs data integration in the same way. - -We can run the following command to show the JSON integration config. - -```bash -cat json.k -``` - -```python -import json - -schema Server: - ports: [int] - -server: Server = json.decode('{"ports": [80, 8080]}') -server_json = json.encode({ - ports = [80, 8080] -}) -``` - -The output of the execution command is: - -```shell -kcl json.k -``` - -```yaml -server: - ports: - - 80 - - 8080 -server_json: '{"ports": [80, 8080]}' -``` - -## Summary - -This document introduces how to perform data integration in KCL, using the built-in yaml and json modules to directly integrate YAML and JSON data into the KCL language, and verify and serialize it using the corresponding decoding and encoding functions. diff --git a/versioned_docs/version-0.7.0/user_docs/guides/gitops/1-quick-start.md b/versioned_docs/version-0.7.0/user_docs/guides/gitops/1-quick-start.md deleted file mode 100644 index 04570df1..00000000 --- a/versioned_docs/version-0.7.0/user_docs/guides/gitops/1-quick-start.md +++ /dev/null @@ -1,163 +0,0 @@ ---- -id: gitops-quick-start -sidebar_label: Quick Start ---- - -# Quick Start - -## Introduction - -### What is GitOps - -GitOps is a modern way to do continuous delivery. Its core idea is to have a Git repository which contains environmental and application configurations. An automated process is also needed for sync the config to cluster. - -By changing the files in repository, developers can apply the applications automatically. The benefits of applying GitOps include: - -- Increased productivity. Continuous delivery can speed up the time of deployment. -- Lower the barrier for developer to deploy. By pushing code instead of container configuration, developers can easily deploy Kubernetes without knowing its internal implementation. -- Trace the change records. Managing the cluster with Git makes every change traceable, enhancing the audit trail. -- Recover the cluster with Git's rollback and branch. - -### GitOps with KCL - -Benefits of Using KCL and ArgoCD Together: - -- KCL can help us **simplify complex Kubernetes deployment configuration files**, reduce the error rate of manually writing YAML files, and improve code readability and maintainability. -- ArgoCD can **automate** the deployment of Kubernetes applications, achieve continuous deployment, and provide comprehensive monitoring and control functions. -- By combining KCL and ArgoCD, deployment efficiency can be improved, errors reduced, and management and monitoring of Kubernetes applications strengthened. -- The combination of KCL and ArgoCD can also help us achieve **Infrastructure as Code (IaC)**, simplify application deployment and management, and better implement DevOps principles. - -With GitOps, developer and operation teams can manage application deployment and configuration by modifying KCL code and generating YAML files. The GitOps toolchain will automatically synchronize the changes to the Kubernetes cluster, enabling continuous deployment and ensuring consistency. If there are issues, the GitOps toolchain can be used to quickly rollback. - -## Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -## How to - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/gitops -``` - -We can run the following command to show the config. - -```bash -cat config/main.k -``` - -The output is - -```python -import .app - -config = app.App { - name = "kcl-guestbook-ui" - containers.guestbook = { - image = "gcr.io/heptio-images/ks-guestbook-demo:0.2" - ports = [{containerPort = 80}] - } - service.ports = [{ port = 80 }] - service.type = "LoadBalancer" -} -``` - -In the above code, we defined a configuration using the `App` schema, where we configured an `gcr.io/heptio-images/ks-guestbook-demo:0.2` container and configured it with an `80` service port. - -### 2. Install Kubernetes and GitOps Tool - -#### Setup Kubernetes Cluster and ArgoCD Controllers - -- Install [K3d](https://github.com/k3d-io/k3d) to create a default cluster. - -```bash -k3d cluster create mycluster -``` - -- Install [ArgoCD](https://github.com/argoproj/argo-cd/releases/). - -```bash -kubectl create namespace argocd -kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml -``` - -- Enable ArgoCD KCL Plugin - -Write the patch YAML configuration file and update the ArgoCD configuration: - -```bash -kubectl apply -f ./install/kcl-cmp.yaml -``` - -After completing the first step, ArgoCD will recognize the KCL plugin, but the KCL plugin has not been loaded into the ArgoCD image. To implement configuration drift detection, we have to tune the Deployment of argocd-repo-server. - -```bash -kubectl -n argocd patch deploy/argocd-repo-server -p "$(cat ./install/patch-argocd-repo-server.yaml)" -``` - -Wait for the init container to complete execution (Running). - -```bash -kubectl get pod -n argocd -l app.kubernetes.io/name=argocd-repo-server -``` - -- To access the ArgoCD web UI - -```bash -kubectl port-forward svc/argocd-server -n argocd 8080:443 -``` - -- Open a browser and go to: `https://localhost:8080` - -- The username is "admin" and password get be obtained from the following command: - -```bash -kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d -``` - -#### Setup ArgoCD CLI - -- Install [ArgoCD CLI](https://github.com/argoproj/argo-cd/releases) - -Use "admin" and password to login to ArgoCD - -```bash -argocd login localhost:8080 -``` - -Create ArgoCD Application - -```bash -argocd app create guestbook \ ---repo https://github.com/kcl-lang/kcl-lang.io \ ---path examples/gitops/config \ ---dest-namespace default \ ---dest-server https://kubernetes.default.svc \ ---config-management-plugin kcl-v1.0 -``` - -If you are using a private repository, you need to configure the private repository access with private key credentials before executing the create command. - -Please refer [Private Repositories](https://argo-cd.readthedocs.io/en/stable/user-guide/private-repositories/#ssh-private-key-credential) for more details. - -After successfully creating, you can see the following output: - -```bash -application 'guestbook' created -``` - -Through the ArgoCD UI, you can see that the created applications have not been synchronized yet. Here, you can manually synchronize or set automatic synchronization. - -![](/img/docs/user_docs/guides/gitops/argocd-kcl-app.jpg) - -For more information on synchronization strategies, see [Sync Options](https://argo-cd.readthedocs.io/en/stable/user-guide/sync-options/) - -![](/img/docs/user_docs/guides/gitops/argocd-kcl-app-dashboard.jpg) - -## Summary - -With GitOps, you can easily manage your applications and configuration in your Kubernetes cluster with KCL, ensuring that your applications are always in the desired state. diff --git a/versioned_docs/version-0.7.0/user_docs/guides/gitops/_category_.json b/versioned_docs/version-0.7.0/user_docs/guides/gitops/_category_.json deleted file mode 100644 index 29a73c67..00000000 --- a/versioned_docs/version-0.7.0/user_docs/guides/gitops/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "GitOps", - "position": 11 -} \ No newline at end of file diff --git a/versioned_docs/version-0.7.0/user_docs/guides/package-management/4-how-to/_category_.json b/versioned_docs/version-0.7.0/user_docs/guides/package-management/4-how-to/_category_.json deleted file mode 100644 index e3409c62..00000000 --- a/versioned_docs/version-0.7.0/user_docs/guides/package-management/4-how-to/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "How to", - "position": 4 -} diff --git a/versioned_docs/version-0.7.0/user_docs/guides/package-management/_category_.json b/versioned_docs/version-0.7.0/user_docs/guides/package-management/_category_.json deleted file mode 100644 index 1211443e..00000000 --- a/versioned_docs/version-0.7.0/user_docs/guides/package-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Package Management Tools", - "position": 7 -} diff --git a/versioned_docs/version-0.7.0/user_docs/guides/schema-definition.md b/versioned_docs/version-0.7.0/user_docs/guides/schema-definition.md deleted file mode 100644 index ecb118ac..00000000 --- a/versioned_docs/version-0.7.0/user_docs/guides/schema-definition.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -title: "Schema Definition" -sidebar_position: 3 ---- - -## Introduction - -The core scenario of KCL is write configurations and constraints. and a core feature of KCL is **modeling**. The keyword `schema` in KCL can be used to define structures and constraints, such as attribute types, default values, range check, and various other constraints. In addition, structures defined with KCL schema can be used in turn to verify implementation, validate input (JSON, YAML and other structured data) or generate code (multilingual structures, OpenAPI, and so on). - -## Use KCL for Defining Structures and Constraints - -### 0. Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/definition -``` - -We can run the following command to show the config. - -```bash -cat main.k -``` - -The output is - -```python -import .app_module # A relative path import - -app: app_module.App { - domainType = "Standard" - containerPort = 80 - volumes = [ - { - mountPath = "/tmp" - } - ] - services = [ - { - clusterIP = "None" - $type = "ClusterIP" - } - ] -} -``` - -We put the `app` model into a separate `app_module.k`, then we can use the `import` keyword in `main.k` for modular management, such as the following file structure - -``` -. -├── app_module.k -└── main.k -``` - -The content of `app_module.k` is - -```python -schema App: - domainType: "Standard" | "Customized" | "Global" - containerPort: int - volumes: [Volume] - services: [Service] - - check: - 1 <= containerPort <= 65535 - -schema Service: - clusterIP: str - $type: str - - check: - clusterIP == "None" if $type == "ClusterIP" - -schema Volume: - container: str = "*" # The default value of `container` is "*" - mountPath: str - - check: - mountPath not in ["/", "/boot", "/home", "dev", "/etc", "/root"] -``` - -In the above file, we use the `schema` keyword to define three models `App`, `Service` and `Volume`. The `App` model has four attributes `domainType`, `containerPort`, `volumes` and `services`, where - -- The type of `domainType` is a string literal union type, similar to an "enumeration", which means that the value of `domainType` can only take one of `"Standard"`, `"Customized"` and `"Global"`. -- The type of `containerPort` is an integer (`int`). In addition, we use the `check` keyword to define its value range from 1 to 65535. -- The type of `services` is `Service` schema list type, and we use `?` to mark it as an optional attribute. -- The type of `volumes` is a `Volume` schema list type, and we use `?` to mark it as an optional attribute. - -We can get the YAML output of the `app` instance by using the following command line - -```shell -kcl main.k -``` - -The output is - -```yaml -app: - domainType: Standard - containerPort: 80 - volumes: - - container: "*" - mountPath: /tmp - services: - - clusterIP: None - type: ClusterIP -``` - -### 2. Output Configuration - -We can still get the YAML output of the `app` instance by using the following command line - -```shell -kcl main.k -``` - -The output is - -```yaml -app: - domainType: Standard - containerPort: 80 - volumes: - - container: "*" - mountPath: /tmp - services: - - clusterIP: None - type: ClusterIP -``` - -## Summary - -KCL is a language for defining configurations and constraints, with a core feature of modeling using the schema keyword. This allows for the definition of structures with attributes, default values, range checks, and other constraints. Structures defined using KCL schema can be used to validate data, or generate code. The example demonstrates how to define models using schema, import them for modular management, and output the YAML configuration of an instance of the defined structure using the kcl command. diff --git a/versioned_docs/version-0.7.0/user_docs/guides/secret-management/1-vault.md b/versioned_docs/version-0.7.0/user_docs/guides/secret-management/1-vault.md deleted file mode 100644 index 6da58286..00000000 --- a/versioned_docs/version-0.7.0/user_docs/guides/secret-management/1-vault.md +++ /dev/null @@ -1,142 +0,0 @@ ---- -id: vault -sidebar_label: Vault ---- - -# Vault - -## Introduction - -This guide will show you that KCL solves the secret management problem by integrating [Vault](https://developer.hashicorp.com/vault) and [Vals](https://github.com/helmfile/vals). - -## Prerequisites - -- Install [KCL](/docs/user_docs/getting-started/install) -- Prepare a [Kubernetes Cluster](https://kubernetes.io/) -- Install [Vault](https://developer.hashicorp.com/vault/downloads) -- Install [Vals](https://github.com/helmfile/vals) - -## How to - -### 1. Get the Example - -We put the application source code and infrastructure deployment code in different repos, which can be maintained by different roles to achieve the separation of concerns. - -- Get the application code - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/secret-management/vault -``` - -- Show the config - -```shell -cat main.k -``` - -The output is - -```python -# Secret Management using Vault and Vals - -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" - annotations: { - "secret-store": "vault" - # Valid format: - # "ref+vault://PATH/TO/KV_BACKEND#/KEY" - "foo": "ref+vault://secret/foo#/foo" - "bar": "ref+vault://secret/bar#/bar" - } -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -The main.k file extends the configuration of the Nginx application and customizes annotations. Among them, the value of annotation `foo` and `bar` follow secret reference format (`ref+vault://PATH/TO/KV_BACKEND#/KEY`): - -- `ref+vault`: indicates that this is a secret reference, and the external storage service is `Vault`. -- `PATH/TO/KV_BACKEND`: specifies the path where a secret is stored. -- `KEY`: specifies the key to reading secret. - -The complete format is concatenated using a style similar to URI expressions, which can retrieve a secret stored externally. - -### 2. Pre-store Secrets - -Start the Vault Server - -```shell -vault server -dev -export VAULT_ADDR='http://127.0.0.1:8200' -# Note: Replace with your token -export VAULT_TOKEN=yourtoken -``` - -After Vault is started in development mode and unpacked, secrets are pre-stored, and the path and keys are consistent with `main.k`: - -```shell -vault kv put secret/foo foo=foo -vault kv put secret/bar bar=bar -``` - -### 3. Deploy Configuration - -Using the following command to apply the deployment manifest. - -```shell -kcl main.k | vals eval -f - | kubectl apply -f - -``` - -The expect output is - -```shell -deployment.apps/nginx created -``` - -### 4. Verify Secrets - -Next, verify that the secrets have been retrieved from Vault and replace the values of annotations of Nginx: - -- Verify the `foo` annotation - -```shell -kubectl get deploy nginx -o yaml | grep 'foo:' -``` - -The output is - -```yaml -foo: foo -``` - -- Verify the `bar` annotation - -```shell -kubectl get deploy nginx -o yaml | grep 'bar:' -``` - -The output is - -```yaml -bar: bar -``` - -So far, we have retrieved the secrets hosted in `Vault` and put them into use. - -## Summary - -This guide introduces how KCL solves the secret management by integrating Vault and Vals. By following these steps, we can retrieve the secrets hosted in Vault and utilize them. diff --git a/versioned_docs/version-0.7.0/user_docs/guides/secret-management/_category_.json b/versioned_docs/version-0.7.0/user_docs/guides/secret-management/_category_.json deleted file mode 100644 index c57bb30e..00000000 --- a/versioned_docs/version-0.7.0/user_docs/guides/secret-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Secret Management", - "position": 13 -} diff --git a/versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json b/versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json deleted file mode 100644 index 6e90c03c..00000000 --- a/versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Mutate or Validate Kubernetes Manifests", - "position": 3 -} diff --git a/versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/_category_.json b/versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/_category_.json deleted file mode 100644 index 42681f2b..00000000 --- a/versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Kubernetes", - "position": 9 -} diff --git a/versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/index.md b/versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/index.md deleted file mode 100644 index 8d6340de..00000000 --- a/versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/index.md +++ /dev/null @@ -1 +0,0 @@ -# Kubernetes diff --git a/versioned_docs/version-0.7.0/user_docs/guides/working-with-konfig/4-best-practice.md b/versioned_docs/version-0.7.0/user_docs/guides/working-with-konfig/4-best-practice.md deleted file mode 100644 index ee0cc576..00000000 --- a/versioned_docs/version-0.7.0/user_docs/guides/working-with-konfig/4-best-practice.md +++ /dev/null @@ -1,449 +0,0 @@ ---- -id: practice -sidebar_label: Best Practice ---- - -# Best Practice - -This document aims to explain the best practices for integrating new models into the Konfig library and designing, building and writing KCL code models. New models are generally designed and abstracted using the best practice of separating front-end and back-end models. The direct purpose of distinguishing between front-end and back-end models is to separate `"user interface"` and `"model implementation"`, achieving a user-friendly and simple configuration interface as well as automated configuration query and modification interfaces. - -## Workflow - -![](/img/docs/user_docs/guides/konfig/workflow.png) - -1. **Coding**. Use the KCL OpenAPI tool to generate KCL schemas from the Customer Resources Definitions (CRDs) or OpenAPI Swagger models. These schemas define the atomic capabilities of the platform. -1. **Abstraction**. Based on these atomic capabilities, the platform abstracts user-oriented front-end models and provides a set of templates. These front- - end models cannot work independently, and corresponding back-end models are required. These back-end models will eventually obtain an instance of the front-end model at runtime; it parses the input front-end model and converts it into Kubernetes resources. -1. **Configuration**. Developers or SREs describe the requirements of applications based on front-end models. Users can define the base and different environment configurations for different environments e.g., base, development and production and different localities. In most cases, defining configurations only requires declaring key-value pairs. For some complex scenarios, users can define the logic to generate configurations. -1. **Automation**. After defining the user's configuration, all components have been defined and are ready to be automated. The platform can compile, execute, output, modify, query, and perform other automatic works through the KCL CLI or GPL-binding APIs. Users can also deploy the KCL configuration to the Kubernetes cluster with tools. - -## Model Structure - -Just as web applications provide a friendly user interface, and user input is further inferred at the backend of the application to obtain the final data that falls into the database, similarly, using KCL for model design also follows the logic of front-end and back-end separation. In addition, when the downstream required data content changes, we only need to modify the rendering/logic of the user configuration data to the backend model, thereby avoiding large-scale modification of user configurations. - -Taking the sidecar configuration of application services as an example: - -```python -# Config user interface. -user_sidecar_feature_gates: str - -# Downstream config of processing. -sidecars = [ - { - name = "sidecar_name" # Additional template for sidecars parameters, users do not need to configure them. - feature_gates = user_sidecar_feature_gates - } -] -``` - -## Best Practices for Konfig Modeling - -### Use Single Attribute Instead of Configuration Templates - -For some backend models, the configuration attributes that need to be filled in are often large and comprehensive designs, requiring users to actively input more complex configuration templates, and the filling content of this attribute is basically the same for different users. For example, the configuration of logic shown below requires users to fill in a large amount of template data, which has a high mental cost. - -A simple best practice is to abstract such commonly used and complex templates into a simple attribute `overQuota` with the `bool` type in the front-end model, allowing users to do multiple-choice questions instead of filling in blank questions. For example, when the `overQuota` attribute is `True`, the back-end model will render this complex logic. - -- The front-end attribute `overQuota` - -```python -overQuota: bool -``` - -- The back-end YAML output: - -```yaml -spec: - template: - spec: - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: k8s/is-over-quota - operator: In - values: - - "true" -``` - -In addition, different template names can be designed according to specific business scenarios to fill in the blanks, such as designing an attribute template in the code shown below to assist users in template selection instead of directly filling in the template content. The legal template value can be `"success_ratio"` or `"service_cost"`. When the backend model extends more templates, the front-end code does not need to make any modifications, only needs to adapt the corresponding template logic in the backend model. - -```python -schema SLI: - template: str = "success_ratio" -``` - -In addition, it is recommended to avoid using complex structures directly as front-end model attributes to avoid users needing to rely on too many KCL syntax features (such as unpacking, looping, etc.) or writing many temporary variables to complete the instantiation of the structure when using the model. - -### Use Literal Type and Union Type - -In the above section, it was mentioned that a string attribute can be used to represent different template names, and further, a literal type can be used to express the optional content of the template. For example, the following improvements can be made. - -```python -schema SLI: - template: "success_ratio" | "service_cost" = "success_ratio" -``` - -The type of template is a combination of two string types, indicating that the template can only be `"success_ratio"` or `"service_cost"`. When the user fills in the values of other strings, the KCL compiler will report an error. - -In addition to using union types for literal types, KCL also supports union for complex types such as schema types. For the support of this backend **oneof** configuration, KCL has built-in composite structure union types for support. For example, we can define our own SLI front-end types for various scenarios: `CustomSliDataSource`, `PQLSLIDataSource`, and `StackSLIDataSource`. - -```python -schema CustomSLIDataSource: - customPluginUrl: str - -schema PQLSLIDataSource: - total?: str - error?: str - success?: str - cost?: str - count?: str - -schema StackSLIDataSource: - stack: str - groupBy?: str - metric?: str - -# Simplify type definitions using type aliases -type DataSource = CustomSLIDataSource | PQLSLIDataSource | StackSLIDataSource - -schema DataConfiguration: - sources: {str: DataSource} -``` - -The advantage of designing this front-end model is that the compiler can statically check that the type written by the user can only be a certain type. If the back-end model is used directly, it cannot directly obtain the mapping relationship between different types of types and the fields that need to be filled in from the model. - -In addition, the overall design of the front-end model should also consider horizontal scalability, using the union type as much as possible, fully utilizing the advantages of coding, and avoiding unnecessary large amounts of code restructuring and modification when connecting to different backend or backend models. In addition, for the factory pattern commonly used in other GPL languages, union types can also be used instead in KCL. For example, if you want to obtain a constructor of a type based on the content of a string, you can directly use union types for optimization. - -Using the factory pattern in KCL: - -```python -schema DataA: - id?: int = 1 - value?: str = "value" - -schema DataB: - name?: str = "DataB" - -_dataFactory: {str:} = { - DataA = DataA - DataB = DataB -} -dataA = _dataFactory["DataA"]() -dataB = _dataFactory["DataB"]() -``` - -Replacing the factory pattern with the KCL union type. - -```python -schema DataA: - id?: int = 1 - value?: str = "value" - -schema DataB: - name?: str = "DataB" - -# Just use the union type. -dataA: DataA | DataB = DataA() -dataB: DataA | DataB = DataB() -``` - -### Use Dict Instead of List As Much As Possible - -To make it easier to modify configurations on-site or automate queries, it is advisable to define list or array attributes as dictionary types for easy indexing. In many complex configuration scenarios, the index of a list is arbitrary and the order of elements has no impact on the configuration. Using a dictionary type instead of a list type allows for more convenient data querying and modification. For example: - -```python -schema Person: - name: str - age: int - -schema House: - persons: [Person] - -house = House { - persons = [ - Person { - name = "Alice" - age = 18 - } - Person { - name = "Bob" - age = 10 - } - ] -} -``` - -For example, in the above example, if you want to query the age of the person named `"Alice"` from the list of persons in the house, you need to loop through the list to find Alice's age. However, if you define persons as a dictionary like the following code, it not only looks more concise in code, but you can also directly retrieve Alice's age by using house.persons.Alice.age. In addition, the information of the entire configuration is complete and has no redundant information. - -```python -schema Person: - age: int - -schema House: - persons: {str: Person} # Use Dict Instead of List - -house = House { - persons = { - Alice = Person { age = 18 } - Bob = Person { age = 10 } - } -} -``` - -### Write Validation Expressions for Models - -For frontend models, it is often necessary to validate the fields filled in by users. In this case, KCL's check expressions can be used in conjunction with KCL's built-in functions/syntax/system libraries to perform field validation. For frontend model validation, it is recommended to directly write it in the frontend model definition as a prerequisite for validation, in order to avoid unexpected errors that may occur when the errors are passed to the backend model. - -Use all/any expressions and check expressions for validation - -```python -import regex - -schema ConfigMap: - name: str - data: {str:str} - configMounts?: [ConfigMount] - - check: - all k in data { - regex.match(k, r"[A-Za-z0-9_.-]*") - }, "a valid config key must consist of alphanumeric characters, '-', '_' or '.'" - -schema ConfigMount: - containerName: str - mountPath: str - subPath?: str - - check: - ":" not in mountPath, "mount path must not contain ':'" -``` - -### Use Numerical Unit Type - -Numbers with units in KCL have a built-in type of `units.NumberMultiplier`, and any arithmetic operations are not allowed. - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -x0: NumberMultiplier = 1M # Ok -x1: NumberMultiplier = x0 # Ok -x2 = x0 + x1 # Error: unsupported operand type(s) for +: 'number_multiplier(1M)' and 'number_multiplier(1M)' -``` - -We can use the `int()/float()` function and `str()` function to convert the number unit type to integer or string type, and the resulting string retains the units of the original number unit type. - -```python -a: int = int(1Ki) # 1024 -b: str = str(1Mi) # "1Mi" -``` - -The definitions related to Kubernetes Resource in Konfig can be written using numerical unit types - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -schema Resource: - cpu?: NumberMultiplier | int = 1 - memory?: NumberMultiplier = 1024Mi - disk?: NumberMultiplier = 10Gi - epchygontee?: int -``` - -### Automated Modification of Front-end Model Instances - -In KCL, automated modification of front-end model instances can be achieved through the CLI and API. For example, if we want to modify the image content of an application (Konfig Stack Path: apps/nginx example/dev) configuration, we can directly execute the following command to modify the image content. - -```python -kcl -Y kcl.yaml ci-test/settings.yaml -o ci-test/stdout.golden.yaml -d -O :appConfiguration.image=\"test-image-v1\" -``` - -For more documentation related to automation, please refer to the [Automation Documents](/docs/user_docs/guides/automation) section. - -### Use Functions - -```python -# Define a function that adds two numbers and returns the result。 -add = lambda x, y { - x + y -} -# Define a function that subs two numbers and returns the result。 -sub = lambda x, y { - x - y -} -# Call the function, pass in arguments, and obtain the return value. -result = sub(add(2, 3), 2) # The result is 3. -``` - -The output YAML is - -```yaml -result: 3 -``` - -### Use Package and Module - -Create a package called `utils.k`, define a KCL function called `add` in it, and import it into another file for use. - -- `utils.k` - -```python -# utils.k - -# Define a function that adds two numbers and returns the result。 -add = lambda x, y { - x + y -} - -# Define a function that subs two numbers and returns the result。 -sub = lambda x, y { - x - y -} -``` - -- `main.k` - -```python -# main.k -import .utils - -# Call the function, pass in arguments, and obtain the return value. -result = utils.sub(utils.add(2, 3), 2) # The result is 3. -``` - -### Simplify Logical Expressions Using Configuration - -```python -# Complex Logic, `_cpu` is a non-exported and mutable attribute. -_cpu = 256 -_priority = "1" - -if _priority == "1": - _cpu = 256 -elif _priority == "2": - _cpu = 512 -elif _priority == "3": - _cpu = 1024 -else: - _cpu = 2048 - -# Simplify Logic Expression using Config -cpuMap = { - "1" = 256 - "2" = 512 - "3" = 1024 -} -# Get cpu from the cpuMap, when not found, use the default value 2048. -cpu = cpuMap[_priority] or 2048 -``` - -The output is - -```yaml -cpuMap: - "1": 256 - "2": 512 - "3": 1024 -cpu256: 256 -cpu2048: 2048 -``` - -### Separate Logic and Data - -We can use KCL **schema**, **config**, and **lambda** to separate **data** and **logic** as much as possible. - -For example, we can write the following code (main.k). - -```python -schema Student: - """Define a `Student` schema model with documents. - - Attributes - ---------- - name : str, required - The name of the student. - id : int, required. - The id number of the student. - grade : int, required. - The grade of the student. - - Examples - -------- - s = Student { - name = "Alice" - id = 1 - grade = 80 - } - - """ - name: str - id: int - grade: int - - # Define constraints for the `Student` model. - check: - id >= 0 - 0 <= grade <= 100 - -# Student data. -students: [Student] = [ - {name = "Alice", id = 1, grade = 85} - {name = "Bob", id = 2, grade = 70} - {name = "Charlie", id = 3, grade = 90} - {name = "David", id = 4, grade = 80} - {name = "Eve", id = 5, grade = 95} -] - -# Student logic. -query_student_where_name = lambda students: [Student], name: str { - # Query the first student where name is `name` - filter s in students { - s.name == name - }?[0] -} - -alice = query_student_where_name(students, name="Alice") -bob = query_student_where_name(students, name="Bob") -``` - -The output is - -```yaml -students: - - name: Alice - id: 1 - grade: 85 - - name: Bob - id: 2 - grade: 70 - - name: Charlie - id: 3 - grade: 90 - - name: David - id: 4 - grade: 80 - - name: Eve - id: 5 - grade: 95 -alice: - name: Alice - id: 1 - grade: 85 -bob: - name: Bob - id: 2 - grade: 70 -``` - -### Add Comments for Models - -To facilitate user understanding and automatic model documentation generation, it is necessary to write comments for the defined model. The comment content usually includes an explanation of the model, an explanation of model fields, types, default values, usage examples, and more. For detailed KCL schema code commenting guidelines and automatic model documentation generation, please refer to the [KCL Documentation Specification](/docs/tools/cli/kcl/docgen). Additionally, we can use the `kcl-doc generate` command to extract documentation from the user-specified file or directory and output it to the specified directory. - -## Backend Model - -The backend model is an "implementation model," which mainly includes the logical code to map the frontend model to the backend model. After the frontend model is written, we can use the frontend model schema to create frontend model instances, and write the corresponding backend mapping/rendering code to convert these frontend instances into the backend model. By using KCL's multi-file compilation and `Schema.instances()` function, the frontend and backend code can be highly decoupled, so that users only need to focus on frontend configuration without being aware of the complex validation and logical code of the model. diff --git a/versioned_docs/version-0.7.0/user_docs/guides/working-with-konfig/_category_.json b/versioned_docs/version-0.7.0/user_docs/guides/working-with-konfig/_category_.json deleted file mode 100644 index a71426f9..00000000 --- a/versioned_docs/version-0.7.0/user_docs/guides/working-with-konfig/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Konfig", - "position": 10 -} diff --git a/versioned_docs/version-0.7.0/user_docs/guides/working-with-kusion/_category_.json b/versioned_docs/version-0.7.0/user_docs/guides/working-with-kusion/_category_.json deleted file mode 100644 index 9f914498..00000000 --- a/versioned_docs/version-0.7.0/user_docs/guides/working-with-kusion/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KusionStack", - "position": 15 -} diff --git a/versioned_docs/version-0.7.0/user_docs/guides/working-with-kusion/index.md b/versioned_docs/version-0.7.0/user_docs/guides/working-with-kusion/index.md deleted file mode 100644 index 2565ad03..00000000 --- a/versioned_docs/version-0.7.0/user_docs/guides/working-with-kusion/index.md +++ /dev/null @@ -1,15 +0,0 @@ -# KusionStack - -**KusionStack is an open-source cloud-native programmable technology stack!** - -KusionStack is a highly flexible programmable technology stack to enable unified application delivery and operation, inspired by the word Fusion, which aims to help enterprises build an application-centric configuration management plane and DevOps ecosystem. - -1. Fusion of hybrid scenarios of **private cloud**, **hybrid cloud**, and **multi-cloud** -2. Fusion of hybrid platform technologies of **cloud-native** and a variety of other platform technologies -3. Fusion of enterprise-level demands of **multi-project**, **multi-team**, **multi-role**, **multi-tenant**, and **multi-environment** - -Based on the concept of Platform as Code, developers can quickly unify the full configuration schemas, constraints, policies and configs across the application life cycle, work with the **hybrid technologies and cloud environment**, go through the **end-to-end workflow** from programming to launching, and truly achieve **write once, deliver anywhere**. - -![](/img/docs/user_docs/intro/kusion-stack-1.png) - -More documents and use cases at [https://kusionstack.io/](https://kusionstack.io/) diff --git a/versioned_docs/version-0.7.0/user_docs/support/_category_.json b/versioned_docs/version-0.7.0/user_docs/support/_category_.json deleted file mode 100644 index 60548d80..00000000 --- a/versioned_docs/version-0.7.0/user_docs/support/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "FAQ", - "position": 6 -} diff --git a/versioned_docs/version-0.7.0/user_docs/support/faq-cli.md b/versioned_docs/version-0.7.0/user_docs/support/faq-cli.md deleted file mode 100644 index ab012a34..00000000 --- a/versioned_docs/version-0.7.0/user_docs/support/faq-cli.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Command Line Tool - -## 1. What is the function of the `settings.yaml` in the application directory of the Konfig? - -The `settings.yaml` in KCL indicates the configuration file of the KCL command line tool. You can put the compiled configuration into it, such as the file to be compiled, the option dynamic parameter that needs to be input(`-d`), whether to ignore the null value(`-n`) and other configurations. - -For example, for the following arguments: - -```shell -kcl main.k -D key=value -n -r -``` - -It can be replaced by the following command line arguments and `settings.yaml` - -```shell -kcl -Y settings.yaml -``` - -settings.yaml - -```yaml -kcl_cli_configs: - files: - - main.k - disable_none: true - strict_range_check: true -kcl_options: - - key: key - value: value -``` - -- `kcl_cli_configs` indicates configurable compilation arguments, `file` indicates the KCL file used for compilation,`disable_none` indicates whether to use `-n`, `strict_range_check` indicates whether to use `-r`. -- `kcl_options` indicates dynamic options that can be configured, `key` indicates option name, `value` indicates option value - -Note: The file name does not need to be `settings.yaml`, but the configuration in it must meet the requirements. - -### 2. How to input dynamic options? How to get dynamic options in code? - -KCL supports multiple ways to input dynamic options - -- `-D`: Use the command line argument `-D` to input dynamic options. It supports basic data types str/int/float/bool and structured data types list/dict - -```shell -kcl main.k -D env-type=TEST -D deploy-topology='[{"cluster":"my-cluster","idc":"my-idc","replicas":2,"workspace":"my-idc","zone":"my-zone"}]' -``` - -- `-Y`: Use the command line argument `-Y` to input dynamic options by configuration file: - -```yaml -kcl_options: - - key: env-type - value: TEST - - key: deploy-topology - value: - - cluster: my-cluster - idc: my-idc - replicas: 2 - workspace: my-workspace - zone: my-zone -``` - -Use the built-in function `option()` to get it: - -```python -env = option("env-type") -deploy_topology = option("deploy-topology") -``` - -Output: - -```yaml -env: TEST -deploy_topology: - - cluster: my-cluster - idc: my-idc - replicas: 2 - workspace: my-workspace - zone: my-zone -``` - -### 3. How to compile multiple files? - -- Input multiple files in the command line: - -```shell -kcl file1.k file2.k file3.k -``` - -- Set multiple files in configuration file and use command line argument `-Y`: - -settings.yaml - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - - file3.k -``` - -```shell -kcl -Y settings.yaml -``` diff --git a/versioned_docs/version-0.7.0/user_docs/support/faq-yaml.md b/versioned_docs/version-0.7.0/user_docs/support/faq-yaml.md deleted file mode 100644 index b13a0f7a..00000000 --- a/versioned_docs/version-0.7.0/user_docs/support/faq-yaml.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -sidebar_position: 3 ---- - -# YAML - -## 1. What is the difference between single and double quote YAML strings? - -- YAML double-quoted strings are the only style that can express arbitrary strings, by using `\` escape characters, such as `\"` to escape double quotes `"`, `\\` to escape backslashes `\`, and a single backslash `\` can be used as a continuation character for double-quoted strings. -- YAML single-quoted strings differ from YAML double-quoted strings in that `\` and `"` can be used freely without escaping, but two single-quotes `''` are used to escape single-quote `'` characters. - -For the following example, the contents of the three string variables are the same. - -```yaml -string1: 'here '' s to "quotes"' -string2: 'here''s to "quotes"' -string3: here's to "quotes" -``` - -> Note: KCL's strategy for outputting YAML strings is to output unquoted strings or double-quoted strings preferentially when single quotes appear in the string content, and output single-quoted strings in other cases to avoid the burden of understanding. - -For more details, please refer to [YAML Spec v1.2](https://yaml.org/spec/1.2.1/) - -## 2. What is the meaning of symbols such as | - + > in YAML? - -When using KCL multi-line strings (triple quote strings), the output YAML often carries some special tokens, such as `|`, `-`, `+` and `>`, etc. These tokens usually are the representation method of YAML multi-line string, such as the following KCL code: - -```python -data = """This is a KCL multi line string (the first line) -This is a KCL multi line string (the second line) -This is a KCL multi line string (the third line) - - -""" -var = 1 -``` - -The output YAML is - -```yaml -data: |+ - This is a KCL multi line string (the first line) - This is a KCL multi line string (the second line) - This is a KCL multi line string (the third line) - - -var: 1 -``` - -- `|` represents **block style**, which is used to represent a multi-line string, where all newlines in the string represent the real newlines. -- `>` represents **folding style**, in which all newlines in the string will be replaced by spaces. -- `+` and `-` are used to control the use of newlines at the end of strings. The default is to keep a single newline at the end of the string. If we want to remove all newlines, we can put a `-` after the style indicator `|` or `>`. If we want to keep the newline at the end, we need to put a `+` after `|` or `>`. - -For more details, please refer to [YAML Multiline String](https://yaml-multiline.info/) and [YAML Spec v1.2](https://yaml.org/spec/1.2.1/) - -## 3. What is the meaning of numbers that appear after symbols | - + > such as |1 and |2 in YAML? - -Numbers represent **explicit indentation indicators** in YAML. For long strings in YAML, YAML usually the first non-blank line determines the indentation level of the string, and when the first non-blank line is preceded by a non-leading character, such as a newline, we must use **explicit indent indicators** to specify the indent level of the content, such as `|1` and `|2` etc. - -For example, for the following KCL code: - -```python -longStringStartWithNewline = """ -This is the second line -This is the third line -""" - -``` - -```yaml -longStringStartWithNewline: |2 - - This is the second line - This is the third line -``` - -- Writing long strings from the first line. - -```python -longString = """This is the second line -This is the third line -""" -``` - -- Writing long strings with line continuation characters. - -```python -longString = """\ -This is the second line -This is the third line -""" -``` - -The YAML output by the above two methods is: - -```yaml -longString: | - This is the second line - This is the third line -``` - -For more details, please refer to [YAML Spec v1.2](https://yaml.org/spec/1.2.1/) diff --git a/versioned_docs/version-0.5.2/community/contribute/_category_.json b/versioned_docs/version-0.7/community/contribute/_category_.json similarity index 100% rename from versioned_docs/version-0.5.2/community/contribute/_category_.json rename to versioned_docs/version-0.7/community/contribute/_category_.json diff --git a/versioned_docs/version-0.5.2/community/contribute/contribute-code.md b/versioned_docs/version-0.7/community/contribute/contribute-code.md similarity index 100% rename from versioned_docs/version-0.5.2/community/contribute/contribute-code.md rename to versioned_docs/version-0.7/community/contribute/contribute-code.md diff --git a/versioned_docs/version-0.5.2/community/contribute/contribute-docs.md b/versioned_docs/version-0.7/community/contribute/contribute-docs.md similarity index 100% rename from versioned_docs/version-0.5.2/community/contribute/contribute-docs.md rename to versioned_docs/version-0.7/community/contribute/contribute-docs.md diff --git a/versioned_docs/version-0.5.2/community/contribute/contribute.md b/versioned_docs/version-0.7/community/contribute/contribute.md similarity index 100% rename from versioned_docs/version-0.5.2/community/contribute/contribute.md rename to versioned_docs/version-0.7/community/contribute/contribute.md diff --git a/versioned_docs/version-0.7.0/community/contribute/git-guideline.md b/versioned_docs/version-0.7/community/contribute/git-guideline.md similarity index 100% rename from versioned_docs/version-0.7.0/community/contribute/git-guideline.md rename to versioned_docs/version-0.7/community/contribute/git-guideline.md diff --git a/versioned_docs/version-0.5.2/community/intro/_category_.json b/versioned_docs/version-0.7/community/intro/_category_.json similarity index 100% rename from versioned_docs/version-0.5.2/community/intro/_category_.json rename to versioned_docs/version-0.7/community/intro/_category_.json diff --git a/versioned_docs/version-0.5.2/community/intro/intro.md b/versioned_docs/version-0.7/community/intro/intro.md similarity index 100% rename from versioned_docs/version-0.5.2/community/intro/intro.md rename to versioned_docs/version-0.7/community/intro/intro.md diff --git a/versioned_docs/version-0.5.2/community/intro/license.md b/versioned_docs/version-0.7/community/intro/license.md similarity index 100% rename from versioned_docs/version-0.5.2/community/intro/license.md rename to versioned_docs/version-0.7/community/intro/license.md diff --git a/versioned_docs/version-0.5.2/community/intro/support.md b/versioned_docs/version-0.7/community/intro/support.md similarity index 100% rename from versioned_docs/version-0.5.2/community/intro/support.md rename to versioned_docs/version-0.7/community/intro/support.md diff --git a/versioned_docs/version-0.5.2/community/release-policy/_category_.json b/versioned_docs/version-0.7/community/release-policy/_category_.json similarity index 100% rename from versioned_docs/version-0.5.2/community/release-policy/_category_.json rename to versioned_docs/version-0.7/community/release-policy/_category_.json diff --git a/versioned_docs/version-0.5.2/community/release-policy/index.md b/versioned_docs/version-0.7/community/release-policy/index.md similarity index 100% rename from versioned_docs/version-0.5.2/community/release-policy/index.md rename to versioned_docs/version-0.7/community/release-policy/index.md diff --git a/versioned_docs/version-0.7.0/community/release-policy/kcl.md b/versioned_docs/version-0.7/community/release-policy/kcl.md similarity index 100% rename from versioned_docs/version-0.7.0/community/release-policy/kcl.md rename to versioned_docs/version-0.7/community/release-policy/kcl.md diff --git a/versioned_docs/version-0.7.0/community/release-policy/roadmap.md b/versioned_docs/version-0.7/community/release-policy/roadmap.md similarity index 100% rename from versioned_docs/version-0.7.0/community/release-policy/roadmap.md rename to versioned_docs/version-0.7/community/release-policy/roadmap.md diff --git a/versioned_docs/version-0.5.2/reference/_advanced-concepts/_category_.json b/versioned_docs/version-0.7/reference/_advanced-concepts/_category_.json similarity index 100% rename from versioned_docs/version-0.5.2/reference/_advanced-concepts/_category_.json rename to versioned_docs/version-0.7/reference/_advanced-concepts/_category_.json diff --git a/versioned_docs/version-0.5.2/reference/_advanced-concepts/build_cache.md b/versioned_docs/version-0.7/reference/_advanced-concepts/build_cache.md similarity index 100% rename from versioned_docs/version-0.5.2/reference/_advanced-concepts/build_cache.md rename to versioned_docs/version-0.7/reference/_advanced-concepts/build_cache.md diff --git a/versioned_docs/version-0.5.2/reference/_category_.json b/versioned_docs/version-0.7/reference/_category_.json similarity index 100% rename from versioned_docs/version-0.5.2/reference/_category_.json rename to versioned_docs/version-0.7/reference/_category_.json diff --git a/versioned_docs/version-0.5.2/reference/cheatsheets/_category_.json b/versioned_docs/version-0.7/reference/cheatsheets/_category_.json similarity index 100% rename from versioned_docs/version-0.5.2/reference/cheatsheets/_category_.json rename to versioned_docs/version-0.7/reference/cheatsheets/_category_.json diff --git a/versioned_docs/version-0.5.2/reference/cheatsheets/index.md b/versioned_docs/version-0.7/reference/cheatsheets/index.md similarity index 100% rename from versioned_docs/version-0.5.2/reference/cheatsheets/index.md rename to versioned_docs/version-0.7/reference/cheatsheets/index.md diff --git a/versioned_docs/version-0.5.2/reference/lang/_category_.json b/versioned_docs/version-0.7/reference/lang/_category_.json similarity index 100% rename from versioned_docs/version-0.5.2/reference/lang/_category_.json rename to versioned_docs/version-0.7/reference/lang/_category_.json diff --git a/versioned_docs/version-0.5.2/reference/lang/codelab/_category_.json b/versioned_docs/version-0.7/reference/lang/codelab/_category_.json similarity index 100% rename from versioned_docs/version-0.5.2/reference/lang/codelab/_category_.json rename to versioned_docs/version-0.7/reference/lang/codelab/_category_.json diff --git a/versioned_docs/version-0.5.2/reference/lang/codelab/collaborative.md b/versioned_docs/version-0.7/reference/lang/codelab/collaborative.md similarity index 100% rename from versioned_docs/version-0.5.2/reference/lang/codelab/collaborative.md rename to versioned_docs/version-0.7/reference/lang/codelab/collaborative.md diff --git a/versioned_docs/version-0.5.2/reference/lang/codelab/index.md b/versioned_docs/version-0.7/reference/lang/codelab/index.md similarity index 100% rename from versioned_docs/version-0.5.2/reference/lang/codelab/index.md rename to versioned_docs/version-0.7/reference/lang/codelab/index.md diff --git a/versioned_docs/version-0.5.2/reference/lang/codelab/schema.md b/versioned_docs/version-0.7/reference/lang/codelab/schema.md similarity index 100% rename from versioned_docs/version-0.5.2/reference/lang/codelab/schema.md rename to versioned_docs/version-0.7/reference/lang/codelab/schema.md diff --git a/versioned_docs/version-0.5.2/reference/lang/codelab/simple.md b/versioned_docs/version-0.7/reference/lang/codelab/simple.md similarity index 100% rename from versioned_docs/version-0.5.2/reference/lang/codelab/simple.md rename to versioned_docs/version-0.7/reference/lang/codelab/simple.md diff --git a/versioned_docs/version-0.5.2/reference/lang/error/_category_.json b/versioned_docs/version-0.7/reference/lang/error/_category_.json similarity index 100% rename from versioned_docs/version-0.5.2/reference/lang/error/_category_.json rename to versioned_docs/version-0.7/reference/lang/error/_category_.json diff --git a/versioned_docs/version-0.7.0/reference/lang/error/exception.md b/versioned_docs/version-0.7/reference/lang/error/exception.md similarity index 100% rename from versioned_docs/version-0.7.0/reference/lang/error/exception.md rename to versioned_docs/version-0.7/reference/lang/error/exception.md diff --git a/versioned_docs/version-0.5.2/reference/lang/error/index.md b/versioned_docs/version-0.7/reference/lang/error/index.md similarity index 100% rename from versioned_docs/version-0.5.2/reference/lang/error/index.md rename to versioned_docs/version-0.7/reference/lang/error/index.md diff --git a/versioned_docs/version-0.5.2/reference/lang/spec/_category_.json b/versioned_docs/version-0.7/reference/lang/spec/_category_.json similarity index 100% rename from versioned_docs/version-0.5.2/reference/lang/spec/_category_.json rename to versioned_docs/version-0.7/reference/lang/spec/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/codestyle.md b/versioned_docs/version-0.7/reference/lang/spec/codestyle.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/lang/spec/codestyle.md rename to versioned_docs/version-0.7/reference/lang/spec/codestyle.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/datatypes.md b/versioned_docs/version-0.7/reference/lang/spec/datatypes.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/datatypes.md rename to versioned_docs/version-0.7/reference/lang/spec/datatypes.md diff --git a/versioned_docs/version-0.7.0/reference/lang/spec/error.md b/versioned_docs/version-0.7/reference/lang/spec/error.md similarity index 100% rename from versioned_docs/version-0.7.0/reference/lang/spec/error.md rename to versioned_docs/version-0.7/reference/lang/spec/error.md diff --git a/versioned_docs/version-0.6.0/reference/lang/spec/expressions.md b/versioned_docs/version-0.7/reference/lang/spec/expressions.md similarity index 100% rename from versioned_docs/version-0.6.0/reference/lang/spec/expressions.md rename to versioned_docs/version-0.7/reference/lang/spec/expressions.md diff --git a/versioned_docs/version-0.5.2/reference/lang/spec/index.md b/versioned_docs/version-0.7/reference/lang/spec/index.md similarity index 100% rename from versioned_docs/version-0.5.2/reference/lang/spec/index.md rename to versioned_docs/version-0.7/reference/lang/spec/index.md diff --git a/versioned_docs/version-0.7.0/reference/lang/spec/kcl-spec.md b/versioned_docs/version-0.7/reference/lang/spec/kcl-spec.md similarity index 100% rename from versioned_docs/version-0.7.0/reference/lang/spec/kcl-spec.md rename to versioned_docs/version-0.7/reference/lang/spec/kcl-spec.md diff --git a/versioned_docs/version-0.5.2/reference/lang/spec/lexical.md b/versioned_docs/version-0.7/reference/lang/spec/lexical.md similarity index 100% rename from versioned_docs/version-0.5.2/reference/lang/spec/lexical.md rename to versioned_docs/version-0.7/reference/lang/spec/lexical.md diff --git a/versioned_docs/version-0.7.0/reference/lang/spec/modules.md b/versioned_docs/version-0.7/reference/lang/spec/modules.md similarity index 100% rename from versioned_docs/version-0.7.0/reference/lang/spec/modules.md rename to versioned_docs/version-0.7/reference/lang/spec/modules.md diff --git a/versioned_docs/version-0.7.0/reference/lang/spec/schema.md b/versioned_docs/version-0.7/reference/lang/spec/schema.md similarity index 100% rename from versioned_docs/version-0.7.0/reference/lang/spec/schema.md rename to versioned_docs/version-0.7/reference/lang/spec/schema.md diff --git a/versioned_docs/version-0.7.0/reference/lang/spec/statements.md b/versioned_docs/version-0.7/reference/lang/spec/statements.md similarity index 100% rename from versioned_docs/version-0.7.0/reference/lang/spec/statements.md rename to versioned_docs/version-0.7/reference/lang/spec/statements.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/variables.md b/versioned_docs/version-0.7/reference/lang/spec/variables.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/reference/lang/spec/variables.md rename to versioned_docs/version-0.7/reference/lang/spec/variables.md diff --git a/versioned_docs/version-0.7.0/reference/lang/tour.md b/versioned_docs/version-0.7/reference/lang/tour.md similarity index 100% rename from versioned_docs/version-0.7.0/reference/lang/tour.md rename to versioned_docs/version-0.7/reference/lang/tour.md diff --git a/versioned_docs/version-0.5.2/reference/lang/types/_category_.json b/versioned_docs/version-0.7/reference/lang/types/_category_.json similarity index 100% rename from versioned_docs/version-0.5.2/reference/lang/types/_category_.json rename to versioned_docs/version-0.7/reference/lang/types/_category_.json diff --git a/versioned_docs/version-0.5.2/reference/lang/types/types.md b/versioned_docs/version-0.7/reference/lang/types/types.md similarity index 100% rename from versioned_docs/version-0.5.2/reference/lang/types/types.md rename to versioned_docs/version-0.7/reference/lang/types/types.md diff --git a/versioned_docs/version-0.5.2/reference/model/_category_.json b/versioned_docs/version-0.7/reference/model/_category_.json similarity index 100% rename from versioned_docs/version-0.5.2/reference/model/_category_.json rename to versioned_docs/version-0.7/reference/model/_category_.json diff --git a/versioned_docs/version-0.5.2/reference/model/base64.md b/versioned_docs/version-0.7/reference/model/base64.md similarity index 100% rename from versioned_docs/version-0.5.2/reference/model/base64.md rename to versioned_docs/version-0.7/reference/model/base64.md diff --git a/versioned_docs/version-0.5.2/reference/model/builtin.md b/versioned_docs/version-0.7/reference/model/builtin.md similarity index 100% rename from versioned_docs/version-0.5.2/reference/model/builtin.md rename to versioned_docs/version-0.7/reference/model/builtin.md diff --git a/versioned_docs/version-0.5.2/reference/model/crypto.md b/versioned_docs/version-0.7/reference/model/crypto.md similarity index 100% rename from versioned_docs/version-0.5.2/reference/model/crypto.md rename to versioned_docs/version-0.7/reference/model/crypto.md diff --git a/versioned_docs/version-0.7.0/reference/model/datetime.md b/versioned_docs/version-0.7/reference/model/datetime.md similarity index 100% rename from versioned_docs/version-0.7.0/reference/model/datetime.md rename to versioned_docs/version-0.7/reference/model/datetime.md diff --git a/versioned_docs/version-0.7.0/reference/model/json.md b/versioned_docs/version-0.7/reference/model/json.md similarity index 100% rename from versioned_docs/version-0.7.0/reference/model/json.md rename to versioned_docs/version-0.7/reference/model/json.md diff --git a/versioned_docs/version-0.5.2/reference/model/manifests.md b/versioned_docs/version-0.7/reference/model/manifests.md similarity index 100% rename from versioned_docs/version-0.5.2/reference/model/manifests.md rename to versioned_docs/version-0.7/reference/model/manifests.md diff --git a/versioned_docs/version-0.7.0/reference/model/math.md b/versioned_docs/version-0.7/reference/model/math.md similarity index 100% rename from versioned_docs/version-0.7.0/reference/model/math.md rename to versioned_docs/version-0.7/reference/model/math.md diff --git a/versioned_docs/version-0.5.2/reference/model/net.md b/versioned_docs/version-0.7/reference/model/net.md similarity index 100% rename from versioned_docs/version-0.5.2/reference/model/net.md rename to versioned_docs/version-0.7/reference/model/net.md diff --git a/versioned_docs/version-0.7.0/reference/model/overview.md b/versioned_docs/version-0.7/reference/model/overview.md similarity index 100% rename from versioned_docs/version-0.7.0/reference/model/overview.md rename to versioned_docs/version-0.7/reference/model/overview.md diff --git a/versioned_docs/version-0.5.2/reference/model/regex.md b/versioned_docs/version-0.7/reference/model/regex.md similarity index 100% rename from versioned_docs/version-0.5.2/reference/model/regex.md rename to versioned_docs/version-0.7/reference/model/regex.md diff --git a/versioned_docs/version-0.5.2/reference/model/units.md b/versioned_docs/version-0.7/reference/model/units.md similarity index 100% rename from versioned_docs/version-0.5.2/reference/model/units.md rename to versioned_docs/version-0.7/reference/model/units.md diff --git a/versioned_docs/version-0.7.0/reference/model/yaml.md b/versioned_docs/version-0.7/reference/model/yaml.md similarity index 100% rename from versioned_docs/version-0.7.0/reference/model/yaml.md rename to versioned_docs/version-0.7/reference/model/yaml.md diff --git a/versioned_docs/version-0.5.2/reference/plugin/_category_.json b/versioned_docs/version-0.7/reference/plugin/_category_.json similarity index 100% rename from versioned_docs/version-0.5.2/reference/plugin/_category_.json rename to versioned_docs/version-0.7/reference/plugin/_category_.json diff --git a/versioned_docs/version-0.5.2/reference/plugin/index.md b/versioned_docs/version-0.7/reference/plugin/index.md similarity index 100% rename from versioned_docs/version-0.5.2/reference/plugin/index.md rename to versioned_docs/version-0.7/reference/plugin/index.md diff --git a/versioned_docs/version-0.7.0/reference/plugin/overview.md b/versioned_docs/version-0.7/reference/plugin/overview.md similarity index 100% rename from versioned_docs/version-0.7.0/reference/plugin/overview.md rename to versioned_docs/version-0.7/reference/plugin/overview.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/plugin/project_context.md b/versioned_docs/version-0.7/reference/plugin/project_context.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.5/reference/plugin/project_context.md rename to versioned_docs/version-0.7/reference/plugin/project_context.md diff --git a/versioned_docs/version-0.5.2/reference/xlang-api/_category_.json b/versioned_docs/version-0.7/reference/xlang-api/_category_.json similarity index 100% rename from versioned_docs/version-0.5.2/reference/xlang-api/_category_.json rename to versioned_docs/version-0.7/reference/xlang-api/_category_.json diff --git a/versioned_docs/version-0.7.0/reference/xlang-api/go-api.md b/versioned_docs/version-0.7/reference/xlang-api/go-api.md similarity index 100% rename from versioned_docs/version-0.7.0/reference/xlang-api/go-api.md rename to versioned_docs/version-0.7/reference/xlang-api/go-api.md diff --git a/versioned_docs/version-0.5.2/reference/xlang-api/index.md b/versioned_docs/version-0.7/reference/xlang-api/index.md similarity index 100% rename from versioned_docs/version-0.5.2/reference/xlang-api/index.md rename to versioned_docs/version-0.7/reference/xlang-api/index.md diff --git a/versioned_docs/version-0.5.2/reference/xlang-api/java-api.md b/versioned_docs/version-0.7/reference/xlang-api/java-api.md similarity index 100% rename from versioned_docs/version-0.5.2/reference/xlang-api/java-api.md rename to versioned_docs/version-0.7/reference/xlang-api/java-api.md diff --git a/versioned_docs/version-0.5.2/reference/xlang-api/overview.md b/versioned_docs/version-0.7/reference/xlang-api/overview.md similarity index 100% rename from versioned_docs/version-0.5.2/reference/xlang-api/overview.md rename to versioned_docs/version-0.7/reference/xlang-api/overview.md diff --git a/versioned_docs/version-0.5.2/reference/xlang-api/python-api.md b/versioned_docs/version-0.7/reference/xlang-api/python-api.md similarity index 100% rename from versioned_docs/version-0.5.2/reference/xlang-api/python-api.md rename to versioned_docs/version-0.7/reference/xlang-api/python-api.md diff --git a/versioned_docs/version-0.7.0/reference/xlang-api/rest-api.md b/versioned_docs/version-0.7/reference/xlang-api/rest-api.md similarity index 100% rename from versioned_docs/version-0.7.0/reference/xlang-api/rest-api.md rename to versioned_docs/version-0.7/reference/xlang-api/rest-api.md diff --git a/versioned_docs/version-0.5.2/tools/Ide/_category_.json b/versioned_docs/version-0.7/tools/Ide/_category_.json similarity index 100% rename from versioned_docs/version-0.5.2/tools/Ide/_category_.json rename to versioned_docs/version-0.7/tools/Ide/_category_.json diff --git a/versioned_docs/version-0.7.0/tools/Ide/index.md b/versioned_docs/version-0.7/tools/Ide/index.md similarity index 100% rename from versioned_docs/version-0.7.0/tools/Ide/index.md rename to versioned_docs/version-0.7/tools/Ide/index.md diff --git a/versioned_docs/version-0.6.0/tools/Ide/intellij.md b/versioned_docs/version-0.7/tools/Ide/intellij.md similarity index 100% rename from versioned_docs/version-0.6.0/tools/Ide/intellij.md rename to versioned_docs/version-0.7/tools/Ide/intellij.md diff --git a/versioned_docs/version-0.6.0/tools/Ide/neovim.md b/versioned_docs/version-0.7/tools/Ide/neovim.md similarity index 100% rename from versioned_docs/version-0.6.0/tools/Ide/neovim.md rename to versioned_docs/version-0.7/tools/Ide/neovim.md diff --git a/versioned_docs/version-0.7.0/tools/Ide/vs-code.md b/versioned_docs/version-0.7/tools/Ide/vs-code.md similarity index 100% rename from versioned_docs/version-0.7.0/tools/Ide/vs-code.md rename to versioned_docs/version-0.7/tools/Ide/vs-code.md diff --git a/versioned_docs/version-0.5.2/tools/_category_.json b/versioned_docs/version-0.7/tools/_category_.json similarity index 100% rename from versioned_docs/version-0.5.2/tools/_category_.json rename to versioned_docs/version-0.7/tools/_category_.json diff --git a/versioned_docs/version-0.5.2/tools/cli/_category_.json b/versioned_docs/version-0.7/tools/cli/_category_.json similarity index 100% rename from versioned_docs/version-0.5.2/tools/cli/_category_.json rename to versioned_docs/version-0.7/tools/cli/_category_.json diff --git a/versioned_docs/version-0.5.2/tools/cli/index.md b/versioned_docs/version-0.7/tools/cli/index.md similarity index 100% rename from versioned_docs/version-0.5.2/tools/cli/index.md rename to versioned_docs/version-0.7/tools/cli/index.md diff --git a/versioned_docs/version-0.5.2/tools/cli/kcl/_category_.json b/versioned_docs/version-0.7/tools/cli/kcl/_category_.json similarity index 100% rename from versioned_docs/version-0.5.2/tools/cli/kcl/_category_.json rename to versioned_docs/version-0.7/tools/cli/kcl/_category_.json diff --git a/versioned_docs/version-0.7.0/tools/cli/kcl/docgen.md b/versioned_docs/version-0.7/tools/cli/kcl/docgen.md similarity index 100% rename from versioned_docs/version-0.7.0/tools/cli/kcl/docgen.md rename to versioned_docs/version-0.7/tools/cli/kcl/docgen.md diff --git a/versioned_docs/version-0.7.0/tools/cli/kcl/fmt.md b/versioned_docs/version-0.7/tools/cli/kcl/fmt.md similarity index 100% rename from versioned_docs/version-0.7.0/tools/cli/kcl/fmt.md rename to versioned_docs/version-0.7/tools/cli/kcl/fmt.md diff --git a/versioned_docs/version-0.7.0/tools/cli/kcl/import.md b/versioned_docs/version-0.7/tools/cli/kcl/import.md similarity index 100% rename from versioned_docs/version-0.7.0/tools/cli/kcl/import.md rename to versioned_docs/version-0.7/tools/cli/kcl/import.md diff --git a/versioned_docs/version-0.7.0/tools/cli/kcl/index.md b/versioned_docs/version-0.7/tools/cli/kcl/index.md similarity index 100% rename from versioned_docs/version-0.7.0/tools/cli/kcl/index.md rename to versioned_docs/version-0.7/tools/cli/kcl/index.md diff --git a/versioned_docs/version-0.7.0/tools/cli/kcl/lint.md b/versioned_docs/version-0.7/tools/cli/kcl/lint.md similarity index 100% rename from versioned_docs/version-0.7.0/tools/cli/kcl/lint.md rename to versioned_docs/version-0.7/tools/cli/kcl/lint.md diff --git a/versioned_docs/version-0.7.0/tools/cli/kcl/overview.md b/versioned_docs/version-0.7/tools/cli/kcl/overview.md similarity index 100% rename from versioned_docs/version-0.7.0/tools/cli/kcl/overview.md rename to versioned_docs/version-0.7/tools/cli/kcl/overview.md diff --git a/versioned_docs/version-0.7.0/tools/cli/kcl/run.md b/versioned_docs/version-0.7/tools/cli/kcl/run.md similarity index 100% rename from versioned_docs/version-0.7.0/tools/cli/kcl/run.md rename to versioned_docs/version-0.7/tools/cli/kcl/run.md diff --git a/versioned_docs/version-0.7.0/tools/cli/kcl/test.md b/versioned_docs/version-0.7/tools/cli/kcl/test.md similarity index 100% rename from versioned_docs/version-0.7.0/tools/cli/kcl/test.md rename to versioned_docs/version-0.7/tools/cli/kcl/test.md diff --git a/versioned_docs/version-0.7.0/tools/cli/kcl/vet.md b/versioned_docs/version-0.7/tools/cli/kcl/vet.md similarity index 100% rename from versioned_docs/version-0.7.0/tools/cli/kcl/vet.md rename to versioned_docs/version-0.7/tools/cli/kcl/vet.md diff --git a/versioned_docs/version-0.5.2/tools/cli/openapi/_category_.json b/versioned_docs/version-0.7/tools/cli/openapi/_category_.json similarity index 100% rename from versioned_docs/version-0.5.2/tools/cli/openapi/_category_.json rename to versioned_docs/version-0.7/tools/cli/openapi/_category_.json diff --git a/versioned_docs/version-0.7.0/tools/cli/openapi/crd-to-kcl.md b/versioned_docs/version-0.7/tools/cli/openapi/crd-to-kcl.md similarity index 100% rename from versioned_docs/version-0.7.0/tools/cli/openapi/crd-to-kcl.md rename to versioned_docs/version-0.7/tools/cli/openapi/crd-to-kcl.md diff --git a/versioned_docs/version-0.5.2/tools/cli/openapi/index.md b/versioned_docs/version-0.7/tools/cli/openapi/index.md similarity index 100% rename from versioned_docs/version-0.5.2/tools/cli/openapi/index.md rename to versioned_docs/version-0.7/tools/cli/openapi/index.md diff --git a/versioned_docs/version-0.7.0/tools/cli/openapi/openapi-to-kcl.md b/versioned_docs/version-0.7/tools/cli/openapi/openapi-to-kcl.md similarity index 100% rename from versioned_docs/version-0.7.0/tools/cli/openapi/openapi-to-kcl.md rename to versioned_docs/version-0.7/tools/cli/openapi/openapi-to-kcl.md diff --git a/versioned_docs/version-0.6.0/tools/cli/openapi/spec.md b/versioned_docs/version-0.7/tools/cli/openapi/spec.md similarity index 100% rename from versioned_docs/version-0.6.0/tools/cli/openapi/spec.md rename to versioned_docs/version-0.7/tools/cli/openapi/spec.md diff --git a/versioned_docs/version-0.7.0/tools/cli/package-management/_category_.json b/versioned_docs/version-0.7/tools/cli/package-management/_category_.json similarity index 100% rename from versioned_docs/version-0.7.0/tools/cli/package-management/_category_.json rename to versioned_docs/version-0.7/tools/cli/package-management/_category_.json diff --git a/versioned_docs/version-0.7.0/tools/cli/package-management/command-reference/1.init.md b/versioned_docs/version-0.7/tools/cli/package-management/command-reference/1.init.md similarity index 100% rename from versioned_docs/version-0.7.0/tools/cli/package-management/command-reference/1.init.md rename to versioned_docs/version-0.7/tools/cli/package-management/command-reference/1.init.md diff --git a/versioned_docs/version-0.7.0/tools/cli/package-management/command-reference/10.help.md b/versioned_docs/version-0.7/tools/cli/package-management/command-reference/10.help.md similarity index 100% rename from versioned_docs/version-0.7.0/tools/cli/package-management/command-reference/10.help.md rename to versioned_docs/version-0.7/tools/cli/package-management/command-reference/10.help.md diff --git a/versioned_docs/version-0.7.0/tools/cli/package-management/command-reference/11.update.md b/versioned_docs/version-0.7/tools/cli/package-management/command-reference/11.update.md similarity index 100% rename from versioned_docs/version-0.7.0/tools/cli/package-management/command-reference/11.update.md rename to versioned_docs/version-0.7/tools/cli/package-management/command-reference/11.update.md diff --git a/versioned_docs/version-0.7.0/tools/cli/package-management/command-reference/2.add.md b/versioned_docs/version-0.7/tools/cli/package-management/command-reference/2.add.md similarity index 100% rename from versioned_docs/version-0.7.0/tools/cli/package-management/command-reference/2.add.md rename to versioned_docs/version-0.7/tools/cli/package-management/command-reference/2.add.md diff --git a/versioned_docs/version-0.7.0/tools/cli/package-management/command-reference/3.pkg.md b/versioned_docs/version-0.7/tools/cli/package-management/command-reference/3.pkg.md similarity index 100% rename from versioned_docs/version-0.7.0/tools/cli/package-management/command-reference/3.pkg.md rename to versioned_docs/version-0.7/tools/cli/package-management/command-reference/3.pkg.md diff --git a/versioned_docs/version-0.7.0/tools/cli/package-management/command-reference/4.metadata.md b/versioned_docs/version-0.7/tools/cli/package-management/command-reference/4.metadata.md similarity index 100% rename from versioned_docs/version-0.7.0/tools/cli/package-management/command-reference/4.metadata.md rename to versioned_docs/version-0.7/tools/cli/package-management/command-reference/4.metadata.md diff --git a/versioned_docs/version-0.7.0/tools/cli/package-management/command-reference/6.login.md b/versioned_docs/version-0.7/tools/cli/package-management/command-reference/6.login.md similarity index 100% rename from versioned_docs/version-0.7.0/tools/cli/package-management/command-reference/6.login.md rename to versioned_docs/version-0.7/tools/cli/package-management/command-reference/6.login.md diff --git a/versioned_docs/version-0.7.0/tools/cli/package-management/command-reference/7.logout.md b/versioned_docs/version-0.7/tools/cli/package-management/command-reference/7.logout.md similarity index 100% rename from versioned_docs/version-0.7.0/tools/cli/package-management/command-reference/7.logout.md rename to versioned_docs/version-0.7/tools/cli/package-management/command-reference/7.logout.md diff --git a/versioned_docs/version-0.7.0/tools/cli/package-management/command-reference/8.push.md b/versioned_docs/version-0.7/tools/cli/package-management/command-reference/8.push.md similarity index 100% rename from versioned_docs/version-0.7.0/tools/cli/package-management/command-reference/8.push.md rename to versioned_docs/version-0.7/tools/cli/package-management/command-reference/8.push.md diff --git a/versioned_docs/version-0.7.0/tools/cli/package-management/command-reference/9.pull.md b/versioned_docs/version-0.7/tools/cli/package-management/command-reference/9.pull.md similarity index 100% rename from versioned_docs/version-0.7.0/tools/cli/package-management/command-reference/9.pull.md rename to versioned_docs/version-0.7/tools/cli/package-management/command-reference/9.pull.md diff --git a/versioned_docs/version-0.5.2/reference/package-management/command-reference/_category_.json b/versioned_docs/version-0.7/tools/cli/package-management/command-reference/_category_.json similarity index 100% rename from versioned_docs/version-0.5.2/reference/package-management/command-reference/_category_.json rename to versioned_docs/version-0.7/tools/cli/package-management/command-reference/_category_.json diff --git a/versioned_docs/version-0.5.2/user_docs/concepts/_category_.json b/versioned_docs/version-0.7/user_docs/concepts/_category_.json similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/concepts/_category_.json rename to versioned_docs/version-0.7/user_docs/concepts/_category_.json diff --git a/versioned_docs/version-0.7.0/user_docs/concepts/concepts.md b/versioned_docs/version-0.7/user_docs/concepts/concepts.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/concepts/concepts.md rename to versioned_docs/version-0.7/user_docs/concepts/concepts.md diff --git a/versioned_docs/version-0.5.2/user_docs/concepts/package-and-module.md b/versioned_docs/version-0.7/user_docs/concepts/package-and-module.md similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/concepts/package-and-module.md rename to versioned_docs/version-0.7/user_docs/concepts/package-and-module.md diff --git a/versioned_docs/version-0.5.6/user_docs/concepts/type-and-definition.md b/versioned_docs/version-0.7/user_docs/concepts/type-and-definition.md similarity index 100% rename from versioned_docs/version-0.5.6/user_docs/concepts/type-and-definition.md rename to versioned_docs/version-0.7/user_docs/concepts/type-and-definition.md diff --git a/versioned_docs/version-0.5.2/user_docs/getting-started/_category_.json b/versioned_docs/version-0.7/user_docs/getting-started/_category_.json similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/getting-started/_category_.json rename to versioned_docs/version-0.7/user_docs/getting-started/_category_.json diff --git a/versioned_docs/version-0.7.0/user_docs/getting-started/index.md b/versioned_docs/version-0.7/user_docs/getting-started/index.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/getting-started/index.md rename to versioned_docs/version-0.7/user_docs/getting-started/index.md diff --git a/versioned_docs/version-0.7.0/user_docs/getting-started/install.md b/versioned_docs/version-0.7/user_docs/getting-started/install.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/getting-started/install.md rename to versioned_docs/version-0.7/user_docs/getting-started/install.md diff --git a/versioned_docs/version-0.7.0/user_docs/getting-started/intro.md b/versioned_docs/version-0.7/user_docs/getting-started/intro.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/getting-started/intro.md rename to versioned_docs/version-0.7/user_docs/getting-started/intro.md diff --git a/versioned_docs/version-0.5.2/user_docs/getting-started/kcl-quick-start.md b/versioned_docs/version-0.7/user_docs/getting-started/kcl-quick-start.md similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/getting-started/kcl-quick-start.md rename to versioned_docs/version-0.7/user_docs/getting-started/kcl-quick-start.md diff --git a/versioned_docs/version-0.5.2/user_docs/guides/_category_.json b/versioned_docs/version-0.7/user_docs/guides/_category_.json similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/guides/_category_.json rename to versioned_docs/version-0.7/user_docs/guides/_category_.json diff --git a/versioned_docs/version-0.5.4/user_docs/guides/abstraction.md b/versioned_docs/version-0.7/user_docs/guides/abstraction.md similarity index 100% rename from versioned_docs/version-0.5.4/user_docs/guides/abstraction.md rename to versioned_docs/version-0.7/user_docs/guides/abstraction.md diff --git a/versioned_docs/version-0.7.0/user_docs/guides/automation.md b/versioned_docs/version-0.7/user_docs/guides/automation.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/automation.md rename to versioned_docs/version-0.7/user_docs/guides/automation.md diff --git a/versioned_docs/version-0.5.4/user_docs/guides/ci-integration/1-github-actions.md b/versioned_docs/version-0.7/user_docs/guides/ci-integration/1-github-actions.md similarity index 100% rename from versioned_docs/version-0.5.4/user_docs/guides/ci-integration/1-github-actions.md rename to versioned_docs/version-0.7/user_docs/guides/ci-integration/1-github-actions.md diff --git a/versioned_docs/version-0.5.4/user_docs/guides/ci-integration/2-gitlab-ci.md b/versioned_docs/version-0.7/user_docs/guides/ci-integration/2-gitlab-ci.md similarity index 100% rename from versioned_docs/version-0.5.4/user_docs/guides/ci-integration/2-gitlab-ci.md rename to versioned_docs/version-0.7/user_docs/guides/ci-integration/2-gitlab-ci.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/ci-integration/_3-jenkins-ci.md b/versioned_docs/version-0.7/user_docs/guides/ci-integration/_3-jenkins-ci.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/ci-integration/_3-jenkins-ci.md rename to versioned_docs/version-0.7/user_docs/guides/ci-integration/_3-jenkins-ci.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/ci-integration/_category_.json b/versioned_docs/version-0.7/user_docs/guides/ci-integration/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/ci-integration/_category_.json rename to versioned_docs/version-0.7/user_docs/guides/ci-integration/_category_.json diff --git a/versioned_docs/version-0.7.0/user_docs/guides/configuration.md b/versioned_docs/version-0.7/user_docs/guides/configuration.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/configuration.md rename to versioned_docs/version-0.7/user_docs/guides/configuration.md diff --git a/versioned_docs/version-0.5.4/user_docs/guides/data-integration.md b/versioned_docs/version-0.7/user_docs/guides/data-integration.md similarity index 100% rename from versioned_docs/version-0.5.4/user_docs/guides/data-integration.md rename to versioned_docs/version-0.7/user_docs/guides/data-integration.md diff --git a/versioned_docs/version-0.5.4/user_docs/guides/gitops/1-quick-start.md b/versioned_docs/version-0.7/user_docs/guides/gitops/1-quick-start.md similarity index 100% rename from versioned_docs/version-0.5.4/user_docs/guides/gitops/1-quick-start.md rename to versioned_docs/version-0.7/user_docs/guides/gitops/1-quick-start.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/gitops/_category_.json b/versioned_docs/version-0.7/user_docs/guides/gitops/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/gitops/_category_.json rename to versioned_docs/version-0.7/user_docs/guides/gitops/_category_.json diff --git a/versioned_docs/version-0.7.0/user_docs/guides/index.md b/versioned_docs/version-0.7/user_docs/guides/index.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/index.md rename to versioned_docs/version-0.7/user_docs/guides/index.md diff --git a/versioned_docs/version-0.7.0/user_docs/guides/package-management/3-quick-start.md b/versioned_docs/version-0.7/user_docs/guides/package-management/3-quick-start.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/package-management/3-quick-start.md rename to versioned_docs/version-0.7/user_docs/guides/package-management/3-quick-start.md diff --git a/versioned_docs/version-0.7.0/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md b/versioned_docs/version-0.7/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md rename to versioned_docs/version-0.7/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md diff --git a/versioned_docs/version-0.7.0/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md b/versioned_docs/version-0.7/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md rename to versioned_docs/version-0.7/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md diff --git a/versioned_docs/version-0.7.0/user_docs/guides/package-management/4-how-to/6-push_github_action.md b/versioned_docs/version-0.7/user_docs/guides/package-management/4-how-to/6-push_github_action.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/package-management/4-how-to/6-push_github_action.md rename to versioned_docs/version-0.7/user_docs/guides/package-management/4-how-to/6-push_github_action.md diff --git a/versioned_docs/version-0.7.0/user_docs/guides/package-management/4-how-to/7-publish_pkg_to_ah.md b/versioned_docs/version-0.7/user_docs/guides/package-management/4-how-to/7-publish_pkg_to_ah.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/package-management/4-how-to/7-publish_pkg_to_ah.md rename to versioned_docs/version-0.7/user_docs/guides/package-management/4-how-to/7-publish_pkg_to_ah.md diff --git a/versioned_docs/version-0.7.0/user_docs/guides/package-management/4-how-to/8-kcl_mod.md b/versioned_docs/version-0.7/user_docs/guides/package-management/4-how-to/8-kcl_mod.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/package-management/4-how-to/8-kcl_mod.md rename to versioned_docs/version-0.7/user_docs/guides/package-management/4-how-to/8-kcl_mod.md diff --git a/versioned_docs/version-0.7.0/user_docs/guides/package-management/4-how-to/9-kpm_oci.md b/versioned_docs/version-0.7/user_docs/guides/package-management/4-how-to/9-kpm_oci.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/package-management/4-how-to/9-kpm_oci.md rename to versioned_docs/version-0.7/user_docs/guides/package-management/4-how-to/9-kpm_oci.md diff --git a/versioned_docs/version-0.5.1/user_docs/guides/package-management/4-how-to/_category_.json b/versioned_docs/version-0.7/user_docs/guides/package-management/4-how-to/_category_.json similarity index 100% rename from versioned_docs/version-0.5.1/user_docs/guides/package-management/4-how-to/_category_.json rename to versioned_docs/version-0.7/user_docs/guides/package-management/4-how-to/_category_.json diff --git a/versioned_docs/version-0.5.2/user_docs/guides/package-management/_category_.json b/versioned_docs/version-0.7/user_docs/guides/package-management/_category_.json similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/guides/package-management/_category_.json rename to versioned_docs/version-0.7/user_docs/guides/package-management/_category_.json diff --git a/versioned_docs/version-0.5.4/user_docs/guides/schema-definition.md b/versioned_docs/version-0.7/user_docs/guides/schema-definition.md similarity index 100% rename from versioned_docs/version-0.5.4/user_docs/guides/schema-definition.md rename to versioned_docs/version-0.7/user_docs/guides/schema-definition.md diff --git a/versioned_docs/version-0.5.3/user_docs/guides/secret-management/1-vault.md b/versioned_docs/version-0.7/user_docs/guides/secret-management/1-vault.md similarity index 100% rename from versioned_docs/version-0.5.3/user_docs/guides/secret-management/1-vault.md rename to versioned_docs/version-0.7/user_docs/guides/secret-management/1-vault.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/secret-management/_category_.json b/versioned_docs/version-0.7/user_docs/guides/secret-management/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/secret-management/_category_.json rename to versioned_docs/version-0.7/user_docs/guides/secret-management/_category_.json diff --git a/versioned_docs/version-0.7.0/user_docs/guides/validation.md b/versioned_docs/version-0.7/user_docs/guides/validation.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/validation.md rename to versioned_docs/version-0.7/user_docs/guides/validation.md diff --git a/versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/0-overview.md b/versioned_docs/version-0.7/user_docs/guides/working-with-k8s/0-overview.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/0-overview.md rename to versioned_docs/version-0.7/user_docs/guides/working-with-k8s/0-overview.md diff --git a/versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md b/versioned_docs/version-0.7/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md rename to versioned_docs/version-0.7/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md diff --git a/versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md b/versioned_docs/version-0.7/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md rename to versioned_docs/version-0.7/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md diff --git a/versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md b/versioned_docs/version-0.7/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md rename to versioned_docs/version-0.7/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md diff --git a/versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md b/versioned_docs/version-0.7/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md rename to versioned_docs/version-0.7/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md diff --git a/versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md b/versioned_docs/version-0.7/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md rename to versioned_docs/version-0.7/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md diff --git a/versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md b/versioned_docs/version-0.7/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md rename to versioned_docs/version-0.7/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md diff --git a/versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md b/versioned_docs/version-0.7/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md rename to versioned_docs/version-0.7/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md diff --git a/versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/6-kcl-operator.md b/versioned_docs/version-0.7/user_docs/guides/working-with-k8s/3-mutate-manifests/6-kcl-operator.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/6-kcl-operator.md rename to versioned_docs/version-0.7/user_docs/guides/working-with-k8s/3-mutate-manifests/6-kcl-operator.md diff --git a/versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/7-crossplane-kcl-function.md b/versioned_docs/version-0.7/user_docs/guides/working-with-k8s/3-mutate-manifests/7-crossplane-kcl-function.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/working-with-k8s/3-mutate-manifests/7-crossplane-kcl-function.md rename to versioned_docs/version-0.7/user_docs/guides/working-with-k8s/3-mutate-manifests/7-crossplane-kcl-function.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json b/versioned_docs/version-0.7/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json rename to versioned_docs/version-0.7/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/_category_.json b/versioned_docs/version-0.7/user_docs/guides/working-with-k8s/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/_category_.json rename to versioned_docs/version-0.7/user_docs/guides/working-with-k8s/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/index.md b/versioned_docs/version-0.7/user_docs/guides/working-with-k8s/index.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-k8s/index.md rename to versioned_docs/version-0.7/user_docs/guides/working-with-k8s/index.md diff --git a/versioned_docs/version-0.7.0/user_docs/guides/working-with-konfig/1-overview.md b/versioned_docs/version-0.7/user_docs/guides/working-with-konfig/1-overview.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/working-with-konfig/1-overview.md rename to versioned_docs/version-0.7/user_docs/guides/working-with-konfig/1-overview.md diff --git a/versioned_docs/version-0.7.0/user_docs/guides/working-with-konfig/2-structure.md b/versioned_docs/version-0.7/user_docs/guides/working-with-konfig/2-structure.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/working-with-konfig/2-structure.md rename to versioned_docs/version-0.7/user_docs/guides/working-with-konfig/2-structure.md diff --git a/versioned_docs/version-0.7.0/user_docs/guides/working-with-konfig/3-quick-start.md b/versioned_docs/version-0.7/user_docs/guides/working-with-konfig/3-quick-start.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/working-with-konfig/3-quick-start.md rename to versioned_docs/version-0.7/user_docs/guides/working-with-konfig/3-quick-start.md diff --git a/versioned_docs/version-0.5.2/user_docs/guides/working-with-konfig/4-best-practice.md b/versioned_docs/version-0.7/user_docs/guides/working-with-konfig/4-best-practice.md similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/guides/working-with-konfig/4-best-practice.md rename to versioned_docs/version-0.7/user_docs/guides/working-with-konfig/4-best-practice.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-konfig/_category_.json b/versioned_docs/version-0.7/user_docs/guides/working-with-konfig/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.5.6/user_docs/guides/working-with-konfig/_category_.json rename to versioned_docs/version-0.7/user_docs/guides/working-with-konfig/_category_.json diff --git a/versioned_docs/version-0.7.0/user_docs/guides/working-with-kubevela/_category_.json b/versioned_docs/version-0.7/user_docs/guides/working-with-kubevela/_category_.json similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/working-with-kubevela/_category_.json rename to versioned_docs/version-0.7/user_docs/guides/working-with-kubevela/_category_.json diff --git a/versioned_docs/version-0.7.0/user_docs/guides/working-with-kubevela/index.md b/versioned_docs/version-0.7/user_docs/guides/working-with-kubevela/index.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/working-with-kubevela/index.md rename to versioned_docs/version-0.7/user_docs/guides/working-with-kubevela/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-kusion/_category_.json b/versioned_docs/version-0.7/user_docs/guides/working-with-kusion/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-kusion/_category_.json rename to versioned_docs/version-0.7/user_docs/guides/working-with-kusion/_category_.json diff --git a/versioned_docs/version-0.5.2/user_docs/guides/working-with-kusion/index.md b/versioned_docs/version-0.7/user_docs/guides/working-with-kusion/index.md similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/guides/working-with-kusion/index.md rename to versioned_docs/version-0.7/user_docs/guides/working-with-kusion/index.md diff --git a/versioned_docs/version-0.7.0/user_docs/guides/working-with-terraform/3-validation.md b/versioned_docs/version-0.7/user_docs/guides/working-with-terraform/3-validation.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/working-with-terraform/3-validation.md rename to versioned_docs/version-0.7/user_docs/guides/working-with-terraform/3-validation.md diff --git a/versioned_docs/version-0.7.0/user_docs/guides/working-with-terraform/_1-adopt-from-terraform.md b/versioned_docs/version-0.7/user_docs/guides/working-with-terraform/_1-adopt-from-terraform.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/working-with-terraform/_1-adopt-from-terraform.md rename to versioned_docs/version-0.7/user_docs/guides/working-with-terraform/_1-adopt-from-terraform.md diff --git a/versioned_docs/version-0.7.0/user_docs/guides/working-with-terraform/_2-abstraction.md b/versioned_docs/version-0.7/user_docs/guides/working-with-terraform/_2-abstraction.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/working-with-terraform/_2-abstraction.md rename to versioned_docs/version-0.7/user_docs/guides/working-with-terraform/_2-abstraction.md diff --git a/versioned_docs/version-0.7.0/user_docs/guides/working-with-terraform/_category_.json b/versioned_docs/version-0.7/user_docs/guides/working-with-terraform/_category_.json similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/guides/working-with-terraform/_category_.json rename to versioned_docs/version-0.7/user_docs/guides/working-with-terraform/_category_.json diff --git a/versioned_docs/version-0.5.2/user_docs/support/_category_.json b/versioned_docs/version-0.7/user_docs/support/_category_.json similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/support/_category_.json rename to versioned_docs/version-0.7/user_docs/support/_category_.json diff --git a/versioned_docs/version-0.5.2/user_docs/support/faq-cli.md b/versioned_docs/version-0.7/user_docs/support/faq-cli.md similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/support/faq-cli.md rename to versioned_docs/version-0.7/user_docs/support/faq-cli.md diff --git a/versioned_docs/version-0.7.0/user_docs/support/faq-install.md b/versioned_docs/version-0.7/user_docs/support/faq-install.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/support/faq-install.md rename to versioned_docs/version-0.7/user_docs/support/faq-install.md diff --git a/versioned_docs/version-0.7.0/user_docs/support/faq-kcl.md b/versioned_docs/version-0.7/user_docs/support/faq-kcl.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/support/faq-kcl.md rename to versioned_docs/version-0.7/user_docs/support/faq-kcl.md diff --git a/versioned_docs/version-0.5.2/user_docs/support/faq-yaml.md b/versioned_docs/version-0.7/user_docs/support/faq-yaml.md similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/support/faq-yaml.md rename to versioned_docs/version-0.7/user_docs/support/faq-yaml.md diff --git a/versioned_docs/version-0.7.0/user_docs/support/support.md b/versioned_docs/version-0.7/user_docs/support/support.md similarity index 100% rename from versioned_docs/version-0.7.0/user_docs/support/support.md rename to versioned_docs/version-0.7/user_docs/support/support.md diff --git a/versioned_docs/version-0.8.0/community/contribute/_category_.json b/versioned_docs/version-0.8.0/community/contribute/_category_.json deleted file mode 100644 index e2dca064..00000000 --- a/versioned_docs/version-0.8.0/community/contribute/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Contribution Guide", - "position": 4 -} diff --git a/versioned_docs/version-0.8.0/community/contribute/contribute-code.md b/versioned_docs/version-0.8.0/community/contribute/contribute-code.md deleted file mode 100644 index f4e9169b..00000000 --- a/versioned_docs/version-0.8.0/community/contribute/contribute-code.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -sidebar_position: 2 ---- - -# How to Contribute Code? - -Welcome to participate in the KCL co construction to improve the code, documentation and testing, and also welcome to provide feedback through Issues. If you want to add KCL language features, please submit through the [KEP](https://github.com/kcl-lang/KEP) process. - -## 1. Misspellings in Code and Comments - -If you only need to modify the typos in the code and comments, you can directly modify and submit the PR to the repository. It is important to keep the code style as consistent as possible. - -## 2. How to Contribute KCL - -See [KCL contribute guide](https://github.com/kcl-lang/kcl/blob/main/docs/dev_guide/1.about_this_guide.md) for more information. - -## 3. How to Contribute VS Code KCL Plugin - -See [VS Code KCL plugin contribute guide](https://github.com/kcl-lang/vscode-kcl/blob/main/docs/CONTRIBUTING.md) for more information. diff --git a/versioned_docs/version-0.8.0/community/contribute/contribute-docs.md b/versioned_docs/version-0.8.0/community/contribute/contribute-docs.md deleted file mode 100644 index 2b400a52..00000000 --- a/versioned_docs/version-0.8.0/community/contribute/contribute-docs.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -sidebar_position: 1 ---- - -# How to Contribute Document? - -This document mainly makes partial modifications to existing documents. If you are submitting blog posts, adding new documents or adjusting the document directory structure, please contact team members first. - -KCL documents are divided into user guides, development documents, internal documents, reference manuals and blog articles. Their differences are as follows: - -- User's Guide: The corresponding usage document allows users to quickly use the KCL tool to complete their work at the minimum cost, without involving too much internal principles and implementation -- Reference: KCL language, tools, IDE and other documents with all features, covering the most extensive but trivial content -- Blog: There are no special restrictions. They can be shared for specific scenarios, technical points or overall development prospects - -When contributing different types of documents, it is better to combine the above positioning to make some appropriate tailoring for different content to give readers the best experience. - -## 1. Basic Specifications - -- In addition to the title, the internal subtitles shall be numbered as much as possible for easy reading -- The document automatically output by the tool needs a link to the source code, and the subtitle can be without number -- Try not to paste large pieces of code (within 30 lines). It is better to provide text explanations and corresponding reference links for the code -- There are diagrams and truths, but overly complex architecture diagrams are not recommended -- Internal link: in the form of [`/docs/user_docs/getting-started/intro`](/docs/user_docs/getting-started/intro) absolute path - -**Punctuation and space** - -- Chinese punctuation is preferred in Chinese documents -- One space is required between Chinese and English -- One space needs to be added between Chinese and numbers -- Chinese uses full width punctuation without adding spaces before and after punctuation -- English content uses half width punctuation, with a space after the punctuation -- You need to leave a space before and after the link, but you do not need to add a space near the beginning of the paragraph and Chinese full width punctuation. - -**Picture and resource file names** - -- The file name and directory name can only use numbers, English letters and underscores`_` And minus sign '-' -- Pictures of the current document are placed in the images directory of the current directory -- Vector pictures can be viewed through [drawio offline version](https://github.com/jgraph/drawio-desktop/releases) (and submit source files at the same time), and export png format pictures at 200% resolution - -## 2. Basic mode of using document content - -Each usage document can be regarded as a relatively complete sharing or blog post (the reference manual is no longer such). Using documents to organize content follows the following pattern: - -1. Overview: What problems do you want to solve and what effects do you want to achieve in this article? You can put a screenshot of the final effect first -2. Dependent environment: what tools need to be installed, and provide relevant links -3. Introduce this article to build a relationship diagram or architecture diagram of resources -4. Give the test method. Try to use community common methods (such as kube, curl command, or browser) to test -5. Summary and Outlook. Briefly review the current operation process and some places that can be expanded (some links can be given) - -## 3. Test and submit PR - -First, clone the document warehouse, and then test the viewing effect locally with the 'npm run start' and 'npm run build' commands to ensure that you can browse normally and then submit PR. diff --git a/versioned_docs/version-0.8.0/community/contribute/contribute.md b/versioned_docs/version-0.8.0/community/contribute/contribute.md deleted file mode 100644 index dd6e2b3f..00000000 --- a/versioned_docs/version-0.8.0/community/contribute/contribute.md +++ /dev/null @@ -1,3 +0,0 @@ -# Contribute Guide - -If it is the first time to participate in the open-source community, you can first check the similar changes in Issue and PR (PullRequest). Then you can fully discuss your own problems with the community or development team classmates, and you can also feedback the problems encountered by creating issues, and then you can provide code patches for related issues. At the beginning, you can start with document improvement and partial code improvement, such as: documentation, Examples, multi-language Binding, etc. At the same time, students who want to participate deeply can contribute to core features such as language functions, language testing, programming frameworks, and various backends. diff --git a/versioned_docs/version-0.8.0/community/intro/_category_.json b/versioned_docs/version-0.8.0/community/intro/_category_.json deleted file mode 100644 index a9646363..00000000 --- a/versioned_docs/version-0.8.0/community/intro/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Community", - "position": 1 -} diff --git a/versioned_docs/version-0.8.0/community/intro/intro.md b/versioned_docs/version-0.8.0/community/intro/intro.md deleted file mode 100644 index 4b1a7f02..00000000 --- a/versioned_docs/version-0.8.0/community/intro/intro.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Community - -Welcome to the KCL open-source community, everyone's participation is the driving force for the healthy growth of all open-source projects! There are many ways to participate in open-source. Everyone can create Issues or fix bugs, improve documentation or modify code by submitting PR (Pull Request), or open new feature discussions by submitting KEP, or share stories about the process of evangelism and use of KCL with surrounding friends. - -See the [community](https://github.com/kcl-lang/community) for ways to join us. diff --git a/versioned_docs/version-0.8.0/community/intro/license.md b/versioned_docs/version-0.8.0/community/intro/license.md deleted file mode 100644 index 4d0097b4..00000000 --- a/versioned_docs/version-0.8.0/community/intro/license.md +++ /dev/null @@ -1,211 +0,0 @@ ---- -sidebar_position: 99 ---- - -# License - -KCL Use [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) License: - -``` - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2023 The KCL Authors. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -``` diff --git a/versioned_docs/version-0.8.0/community/intro/support.md b/versioned_docs/version-0.8.0/community/intro/support.md deleted file mode 100644 index 7ed2e1a8..00000000 --- a/versioned_docs/version-0.8.0/community/intro/support.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Ask for help - -KCL has a developer and user community of many enthusiasts. - -On this page, we list the KCL-related communities you can participate in; see other pages in this section for additional online and offline learning materials. - -Before joining the KCL community, please read the [Contributor Covenant](https://www.contributor-covenant.org/version/2/0/code_of_conduct/) , which is expected to be followed by all community members. - -## Discussions - -- Submit an issue on Github -- Communicate in the Github discussion group -- Get the latest status through official website, Github, Twitter, Slack, Wechat and other accounts. See the [community](https://github.com/kcl-lang/community) for ways to join us. - -## New Features - -Please try to avoid submitting pull requests for new features, we may already have someone working on them, or maybe this feature is already part of our future plans. In conclusion, please contact us before submitting new features! diff --git a/versioned_docs/version-0.8.0/community/release-policy/_category_.json b/versioned_docs/version-0.8.0/community/release-policy/_category_.json deleted file mode 100644 index bc39d651..00000000 --- a/versioned_docs/version-0.8.0/community/release-policy/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Release Policy", - "position": 3 -} diff --git a/versioned_docs/version-0.8.0/community/release-policy/index.md b/versioned_docs/version-0.8.0/community/release-policy/index.md deleted file mode 100644 index c87091d0..00000000 --- a/versioned_docs/version-0.8.0/community/release-policy/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# Release Policy - -The release policy defines the semantics of the release, the release process, etc. In order to maximize the concurrent development process, KCL, etc. adopt independent release strategies. diff --git a/versioned_docs/version-0.8.0/reference/_advanced-concepts/_category_.json b/versioned_docs/version-0.8.0/reference/_advanced-concepts/_category_.json deleted file mode 100644 index 85a16abb..00000000 --- a/versioned_docs/version-0.8.0/reference/_advanced-concepts/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Advanced-Concepts", - "position": 6 -} diff --git a/versioned_docs/version-0.8.0/reference/_advanced-concepts/build_cache.md b/versioned_docs/version-0.8.0/reference/_advanced-concepts/build_cache.md deleted file mode 100644 index 746e2351..00000000 --- a/versioned_docs/version-0.8.0/reference/_advanced-concepts/build_cache.md +++ /dev/null @@ -1 +0,0 @@ -# Building Cache diff --git a/versioned_docs/version-0.8.0/reference/_category_.json b/versioned_docs/version-0.8.0/reference/_category_.json deleted file mode 100644 index 1b337d5a..00000000 --- a/versioned_docs/version-0.8.0/reference/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Reference", - "position": 5 -} diff --git a/versioned_docs/version-0.8.0/reference/cheatsheets/_category_.json b/versioned_docs/version-0.8.0/reference/cheatsheets/_category_.json deleted file mode 100644 index 80464148..00000000 --- a/versioned_docs/version-0.8.0/reference/cheatsheets/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Cheat Sheet", - "position": 10 -} diff --git a/versioned_docs/version-0.8.0/reference/cheatsheets/index.md b/versioned_docs/version-0.8.0/reference/cheatsheets/index.md deleted file mode 100644 index da4189eb..00000000 --- a/versioned_docs/version-0.8.0/reference/cheatsheets/index.md +++ /dev/null @@ -1,5 +0,0 @@ -# KCL Cheat Sheet - -![](/img/docs/reference/cheatsheets/cheatsheet.png) - -[Download PDF](https://github.com/kcl-lang/kcl-lang.io/blob/main/cheatsheet/cheatsheet.pdf) diff --git a/versioned_docs/version-0.8.0/reference/lang/_category_.json b/versioned_docs/version-0.8.0/reference/lang/_category_.json deleted file mode 100644 index 4c823148..00000000 --- a/versioned_docs/version-0.8.0/reference/lang/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Tutorial", - "position": 1 -} diff --git a/versioned_docs/version-0.8.0/reference/lang/codelab/_category_.json b/versioned_docs/version-0.8.0/reference/lang/codelab/_category_.json deleted file mode 100644 index 2e047bcb..00000000 --- a/versioned_docs/version-0.8.0/reference/lang/codelab/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Code Lab", - "position": 2 -} diff --git a/versioned_docs/version-0.8.0/reference/lang/codelab/collaborative.md b/versioned_docs/version-0.8.0/reference/lang/codelab/collaborative.md deleted file mode 100644 index 84ee8160..00000000 --- a/versioned_docs/version-0.8.0/reference/lang/codelab/collaborative.md +++ /dev/null @@ -1,345 +0,0 @@ ---- -title: "Co-configuration with config operations" -linkTitle: "Co-configuration with config operations" -type: "docs" -weight: 2 -description: Co-configuration with config operations -sidebar_position: 3 ---- - -## 1. Introduction - -KCL is a simple and easy-to-use configuration language, where users can simply write the reusable configuration code. - -In this codelab, we will learn how to write the config in a collaborative way using the KCL config operation features. - -### What We Will Learn - -1. Define schemas and organize project directories. -2. Create multiple environment configurations via the KCL config operation features. -3. Configure compiling parameters and tests. - -## 2. Define Schemas and Organize Project Directories - -### Schema Definitions - -Suppose we want to define a server configuration with certain attributes, we can create a simple config by creating a `server.k`, we can fill in the following code as below which defines a reusable schema of the configuration of a server. - -```python -import units - -type Unit = units.NumberMultiplier - -schema Server: - replicas: int = 1 - image: str - resource: Resource = {} - mainContainer: Main = {} - labels?: {str:str} - annotations?: {str:str} - -schema Main: - name: str = "main" - command?: [str] - args?: [str] - ports?: [Port] - -schema Resource: - cpu?: int = 1 - memory?: Unit = 1024Mi - disk?: Unit = 10Gi - -schema Port: - name?: str - protocol: "HTTP" | "TCP" - port: 80 | 443 - targetPort: int - - check: - targetPort > 1024, "targetPort must be larger than 1024" -``` - -In the code above, we define a schema named `Server`, which represents the configuration type that the user will write, which contains some basic type attributes (e.g., `replicas`, `image`, etc) and some composite type attributes (e.g., `resource`, `main`, etc). In addition to some basic types mentioned in the [schema codelab](./schema.md), we can see two types in the above code `Unit` and `units.NumberMultiplier`. Among them, `units.NumberMultiplier` denotes the KCL number unit type, which means that a natural unit or binary unit can be added after the KCL number, such as `1K` for `1000`, `1Ki` for `1024`. `Unit` is the type alias of `units.NumberMultiplier`, which is used to simplify the writing of type annotations. - -### Project Directories - -In order to complete the collaborative configuration development, we first need a configuration project, which contains the configuration of the test application and the differential configuration of different environments, so we are creating the following project directory: - -``` -. -├── appops -│ └── test_app -│ ├── base -│ │ └── base.k -│ ├── dev -│ │ ├── ci-test -│ │ │ └── stdout.golden.yaml -│ │ ├── kcl.yaml -│ │ └── main.k -│ └── prod -│ ├── ci-test -│ │ └── stdout.golden.yaml -│ ├── kcl.yaml -│ └── main.k -├── kcl.mod -└── pkg - └── sever.k -``` - -The directory of the project mainly contains three parts: - -- `kcl.mod`: The file used to identify the root directory of the KCL project. -- `pkg`: `Server` Schema structure reused by different application configurations. -- `appops`: Server configurations of different applications, currently only one application `test_app` is placed. - - `base`: Application common configurations for all environments. - - `dev`: Application configuration for the development environment. - - `prod`: Application configuration for the production environment. - -The meaning of `base.k`, `main.k`, `kcl.yaml` and `ci-test/stdout.golden.yaml` will be mentioned in subsequent sections. - -## 3. Create multiple environment configurations via the KCL config operation features - -### Create a baseline configuration - -After we have organized the project directory and the basic server configuration model, we can write the configuration of the user application. We can create our own test application folder `test_app` and place it in the application configuration folder `appops`. - -For the configuration of an application, we often divide it into a basic configuration and the differential configuration of multiple environments and merge them. Through the configuration merging feature of KCL, we can easily do this. Assuming that we have two configurations of development environment and production environment, we can create three folders: `base`, `dev` and `prod` to store baseline, development environment and production environment configurations respectively. First, we write the configuration of `base/base.k`: - -```python -import pkg - -server: pkg.Server { - # Set the image with the value "nginx:1.14.2" - image = "nginx:1.14.2" - # Add a label app into labels - labels.app = "test_app" - # Add a mainContainer config, and its ports are [{protocol = "HTTP", port = 80, targetPort = 1100}] - mainContainer.ports = [{ - protocol = "HTTP" - port = 80 - targetPort = 1100 - }] -} -``` - -As in the above code, we use the `import` keyword in `base.k` to import the `Server` schema placed under `pkg` and use it to instantiate a configuration named `server`, in which we set `image` attribute to `"nginx:1.14.2"`, and a label `app` with the value `test_app` is added. In addition, we also added the configuration of the main container `mainContainer` with the value `[{protocol = "HTTP", port = 80, targetPort = 1100}]` for the ports attribute. - -KCL command: - -```bash -kcl appops/test_app/base/base.k -``` - -Output: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2 - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app -``` - -At this point, we have a baseline configuration. - -### Create multiple environment configurations - -Next we configure a differentiated multi-environment configuration. First assume that we want to use a temporary image of our own `nginx:1.14.2-dev` in the development environment, and then use it to override the server configuration in the baseline, we can write the following configuration in `dev/main.k`: - -```python -import pkg - -server: pkg.Server { - # Override the image declared in the base - image = "nginx:1.14.2-dev" -} -``` - -KCL command: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -Output: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app -``` - -It can be seen that the `image` field of the output YAML is overwritten to `nginx:1.14.2-dev`. Suppose we also want to add a label to the `dev` environment with a key of `env` and a value of `dev`, we add the following code to `dev/main.k`: - -```python -import pkg - -server: pkg.Server { - # Override the image declared in the base - image = "nginx:1.14.2-dev" - # Union a new label env into base labels - labels.env = "dev" -} -``` - -KCL command: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app - env: dev -``` - -It can be seen that there are two labels in the `labels` field of the output YAML. - -In addition, we can also use the `+=` operator to add new values to list type attributes, such as the `mainContainer.ports` configuration in the baseline environment, continue to modify the code in `dev/main.k`: - -```python -import pkg - -server: pkg.Server { - # Override the base image. - image = "nginx:1.14.2-dev" - # Union a new label env into base labels. - labels.env = "dev" - # Append a port into base ports. - mainContainer.ports += [{ - protocol = "TCP" - port = 443 - targetPort = 1100 - }] -} -``` - -KCL command: - -```bash -kcl appops/test_app/base/base.k appops/test_app/dev/main.k -``` - -Output: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2-dev - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - - protocol: TCP - port: 443 - targetPort: 1100 - labels: - app: test_app - env: dev -``` - -Using the same method, we can build the production configuration, write the code in the `dev/main.k` file, and add a label to it. - -```python -import pkg - -server: pkg.Server { - # Union a new label env into base labels - labels.env = "prod" -} -``` - -KCL command: - -```bash -kcl appops/test_app/base/base.k appops/test_app/prod/main.k -``` - -Output: - -```yaml -server: - replicas: 1 - image: nginx:1.14.2 - resource: - cpu: 1 - memory: 1073741824 - disk: 10737418240 - mainContainer: - name: main - ports: - - protocol: HTTP - port: 80 - targetPort: 1100 - labels: - app: test_app - env: prod -``` - -## 4. Configure compiling parameters and tests - -In the previous section, we built a multi-environment configuration through code. It can be seen that the KCL command line compilation parameters of different environments are similar, so we can configure these compilation parameters into a file and input them to the KCL command line for invocation. Configure the following code in `dev/kcl.yaml`: - -```yaml -kcl_cli_configs: - files: - - ../base/base.k - - main.k - output: ./ci-test/stdout.golden.yaml -``` - -Then we can compile the configuration in the development environment with the following command: - -```bash -cd appops/test_app/dev && kcl -Y ./kcl.yaml -``` - -In addition, we have configured the `output` field in `dev/kcl.yaml` to output YAML to a file for subsequent configuration distribution or testing. You can verify that the application's configuration is as expected by walking through the `kcl.yaml` builds in each environment and comparing with `./ci-test/stdout.golden.yaml`. - -## 5. The Final Step - -Congratulations! - -We have completed the third lesson about KCL. diff --git a/versioned_docs/version-0.8.0/reference/lang/codelab/index.md b/versioned_docs/version-0.8.0/reference/lang/codelab/index.md deleted file mode 100644 index dbe554a9..00000000 --- a/versioned_docs/version-0.8.0/reference/lang/codelab/index.md +++ /dev/null @@ -1 +0,0 @@ -# Code Lab diff --git a/versioned_docs/version-0.8.0/reference/lang/codelab/schema.md b/versioned_docs/version-0.8.0/reference/lang/codelab/schema.md deleted file mode 100644 index 02f792d4..00000000 --- a/versioned_docs/version-0.8.0/reference/lang/codelab/schema.md +++ /dev/null @@ -1,817 +0,0 @@ ---- -title: "Write complex config using KCL Schema" -linkTitle: "Write complex config using KCL Schema" -type: "docs" -weight: 2 -description: Write complex config using KCL Schema -sidebar_position: 2 ---- - -## 1. Introduction - -KCL is a simple and easy-to-use configuration language, where users can simply write the reusable configuration code. - -In this codelab, we will learn how to write customized config using KCL, such that we can define a schema and write the config in a collaborative way. - -### What We Will Learn - -1. Define a simple schema -2. Set default immutable values to schema fields -3. Create config based on a simple schema -4. Write complex logic in schema -5. Create a new schema via schema combinations -6. Create a config of a deeply nested schema using dict/map -7. Create new schema via schema inheritance -8. Create new schema via multiple mixin schemas -9. Declare validation rules for the schema -10. Config schema output layout -11. Share and reuse schema - -## 2. Write Simple Schema - -Suppose we want to define a workload with certain attributes, we can create a simple config by creating a `my_config.k`, we can fill in the following code as below which defines a reusable schema of the configuration of deploy. - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels: {str:str} -``` - -In the code above, `cpu` and `memory` are defined as int value; `name`, `image` and `service` are string; `command` is a list of string type; `labels` is a dict type, whose key type and value type are both string. - -Besides, each attribute **must** be assigned with a not-None value as a schema instance unless it is modified by a question mark **?** as an optional attribute. - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str - replica: int - command: [str] - labels?: {str:str} # labels is an optional attribute -``` - -When there is an inheritance relationship: - -- If the attribute is optional in the base schema, it could be optional or required in the sub-schema. -- If the attribute is required in the base schema, it must be required in the sub-schema. - -## 3. Enhance Schema as Needed - -Suppose we need to set default values to service and replica, we can make them as below: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: str = "my-service" # defaulting - replica: int = 1 # defaulting - command: [str] - labels?: {str:str} # labels is an optional attribute -``` - -And then we can set the service type annotation as the string literal type to make it immutable: - -```python -schema Deployment: - name: str - cpu: int - memory: int - image: str - service: "my-service" = "my-service" - replica: int = 1 - command: [str] - labels?: {str:str} -``` - -In the schema, type hint is a `must`, for example we can define cpu as `cpu: int`. - -Specially, we can define a string-interface dict as `{str:}`, and in case we want to define an object or interface, just define as `{:}`. - -## 4. Create Config Based on Simple Schema - -Now we have a simple schema definition, we can use it to define config as: - -```python -nginx = Deployment { - name = "my-nginx" - cpu = 256 - memory = 512 - image = "nginx:1.14.2" - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } -} -``` - -Run with the following KCL command, we should be able to see the generated yaml files as the output as below: - -KCL command: - -``` - kcl my_config.k -``` - -Stdout: - -```yaml -nginx: - name: my-nginx - cpu: 256 - memory: 512 - image: nginx:1.14.2 - service: my-service - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -> Check the manual and specification out for more details about collection data types and block. - -In addition, the **config selector expressions** can be used to init a schema instance, and we can ignore the comma at the end of the line in the config expression. - -```python -nginx = Deployment { - name = "my-nginx" - cpu = 256 - memory = 512 - image = "nginx:1.14.2" - command = ["nginx"] # Ignore the comma at the end of the line - labels.run = "my-nginx" # A dict variable in schema can use selector expressions - labels.env = "pre-prod" # A dict variable in schema can use selector expressions -} -``` - -## 5. Write More Complex Logic in Schema - -Suppose we have some schema logic, we can wrapper it into schema: - -```python -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - image: str - service: "my-service" = "my-service" - replica: int = 1 - command: [str] - labels?: {str:str} - - _cpu = 2048 - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 -``` - -Now, we can define a config by creating a schema instance and pass in priority as an argument to schema: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -Run with kcl, we should see the generated yaml files as output as below: - -KCL command: - -``` -kcl my_config.k -``` - -Stdout: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - image: nginx:1.14.2 - service: my-service - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 6. Create New Schema via Schema Combinations - -Now we want to define a detailed schema with service and volumes, we can do it as follows: - -```python -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - volumes?: [Volume] - image: str - service?: Service - replica: int = 1 - command: [str] - labels?: {str:str} - - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 - -schema Port: - name: str - protocol: str - port: int - targetPort: int - -schema Service: - name: "my-service" = "my-service" - ports: [Port] - -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -In this case, Deployment is composed of Service and a list of Volumes, and Service is composed of a list of Ports. - -## 7. Create Config of Deeply Nested Schema using Dict/Map - -Now we have a new Deployment schema, however, we may notice that it contains multiple layers of nested structures, in fact, this is very common in complex structure definitions, and we often have to write imperative assembly code to generate the final structure. - -With KCL, we can create the config with simple dict declaration, with the capability of full schema initialization and validation. For example, we can simply config nginx by the new Deployment schema as follows: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -Run with KCL, we will see the generated yaml files as below: - -KCL command: - -``` -kcl my_config.k -``` - -Stdout: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -Note that, the dict that we use to define Deployment config must be aligned with the schema definition, otherwise we will get an error. For example, suppose we define a wrong type of service port as below: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = [80] # wrong data type, trying to assign List to int - targetPort = 9376 - }] -} -``` - -Run with KCL, we will see the error message as output as below: - -KCL command: - -```python -kcl my_config.k -``` - -Stderr: - -``` -The type got is inconsistent with the type expected: expect int, got [int(80)] -``` - -## 8. Declare Schema Validation Rules - -Now we have seen a complex schema, in which every field has a type hint to make it less error-prone. But this is not good enough, we want to support more enhanced verifications to our schemas, so that code errors in schemas and configs can be discovered as soon as possible. - -Lots of validation rules, like None type check, range check, value check, length check, regular expression matching, enum check have already been added or in progress. Here is a code sample: - -```python -import regex - -schema Deployment[priority]: - name: str - cpu: int = _cpu - memory: int = _cpu * 2 - volumes?: [Volume] - image: str - service?: Service - replica: int = 1 - command: [str] - labels?: {str:str} - - if priority == 1: - _cpu = 256 - elif priority == 2: - _cpu = 512 - elif priority == 3: - _cpu = 1024 - else: - _cpu = 2048 - - check: - multiplyof(cpu, 256), "cpu must be a multiplier of 256" - regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$"), "image name should be like 'nginx:1.14.2'" - 1 <= replica < 100, "replica should be in range (1, 100)" - len(labels) >= 2 if labels, "the length of labels should be large or equal to 2" - "env" in labels, "'env' must be in labels" - len(command) > 0, "the command list should be non-empty" - -schema Port: - name: str - protocol: str - port: int - targetPort: int - - check: - port in [80, 443], "we can only expose 80 and 443 port" - protocol in ["HTTP", "TCP"], "protocol must be either HTTP or TCP" - 1024 < targetPort, "targetPort must be larger than 1024" - -schema Service: - name: "my-service" = "my-service" - ports: [Port] - - check: - len(ports) > 0, "ports list must be non-empty" - -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -Since the attributes defined by the schema are **required** by default, the verification that judges that the variable cannot be None/Undefined can be omitted. - -```python -schema Volume: - name: str - mountPath: str - hostPath: str -``` - -Now we can write the config based on the new schema and expose config errors in time. For example, with the invalid config as below: - -```python -nginx = Deployment(priority=2) { - name = "my-nginx" - image = "nginx:1142" # image value is not matching the regex - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -Every field is type-valid, but the image name is invalid. - -Run with KCL, we will see the error message as below: - -KCL command: - -``` -kcl my_config.k -``` - -Stderr: - -``` -Schema check is failed to check condition: regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$"), "image name should be like 'nginx:1.14.2'" -``` - -> The verification capability of KCL covers the verification defined by Openapi so that we can write any API verifications through KCL. - -## 9. Create New Schema via Schema Inheritance - -Now we have a solid Deployment schema definition and we can use it to declare config. - -Usually, schema Deployment will be used in multiple scenarios. We can directly use the schema to declare the configurations in different use cases (see the above section), or we can produce a more specific schema definition through inheritance. - -For example, we can use the Deployment schema as a basis, to define the nginx's base schema, and extend the definition -in each scenario. - -In this case, we define some commonly used attributes. Please note that we mark the name to be immutable with the 'final' keyword to prevent it from being overwritten. - -```python -schema Nginx(Deployment): - """ A base nginx schema """ - name: "my-nginx" = "my-nginx" - image: str = "nginx:1.14.2" - replica: int = 3 - command: [str] = ["nginx"] - -schema NginxProd(Nginx): - """ A prod nginx schema with stable configurations """ - volumes: [Volume] = [{ - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - """ A volume mapped to host path """ - service: Service = { - ports = [{ - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] - } - """ An 80 port to target backend server """ -``` - -Now we have some static configurations for nginx. It is recommended to declare configurations that we think are static there, and put more dynamic configurations as below: - -```python -nginx = Nginx { - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -```python -nginx = NginxProd { - labels.run = "my-nginx" - labels.env = "pre-prod" -} -``` - -Now, we can simply define nginx prod config just with runtime label value "prod" which is not that static. - -In fact, under some complex situation, we can split all configurations into the basic, business, and environment configuration definitions in this way, and achieve collaboration among team members based on this. - -Run with KCL, we will see the generated yaml files as output as below: - -KCL command: - -``` -kcl prod_config.k -``` - -Stdout: - -```yaml -nginx: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 3 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 10. Create New Schema by Multiple Protocol and Mixin Schemas Inheritance - -Now, we can complete the declaration of the server configuration through the Deployment schema. - -However, usually, the actual situation is more complicated, and the deployment may have a variety of optional variable accessories. - -For example, we want to support a persistent volume claim based on an existing schema, as a reusable Kubernetes schema. In this case, we can just wrapper it with a `mixin` and a `protocol` as follows: - -```python -import k8spkg.api.core.v1 - -protocol PVCProtocol: - pvc?: {str:} - -mixin PersistentVolumeClaimMixin for PVCProtocol: - """ - PersistentVolumeClaim (PVC) sample: - Link: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims - """ - - # Mix in a new attribute `kubernetesPVC` - kubernetesPVC?: v1.PersistentVolumeClaim - - if pvc: - kubernetesPVC = v1.PersistentVolumeClaim { - metadata.name = pvc.name - metadata.labels = pvc.labels - spec = { - accessModes = pvc.accessModes - resources = pvc.resources - storageClassName = pvc.storageClassName - } - } -``` - -With this PersistentVolumeClaimMixin, we define a PVC schema with a clear `user interface`, and use Kubernetes PVC as an implementation. Then, we can define a server schema with Deployment schema, and PVC mixin schema. - -``` -schema Server(Deployment): - mixin [PersistentVolumeClaimMixin] - pvc?: {str:} - """ pvc user interface data defined by PersistentVolumeClaimMixin """ -``` - -In the Server schema, Deployment is the base schema, and PersistentVolumeClaimMixin is an optional add-on whose user interface data is `pvc?: {str:}`. - -Note, the `mixin` is often used to add new attributes to the host schema, or to modify the existing attributes of the host schema. Thus, `mixin` can use the attributes in the host schema. Since the `mixin` is designed to be reusable, we need an additional `protocol` to constrain the attribute names and types in the host schema for the `mixin`. - -Now, if we want a deploy with a PVC, just declare as user interface: - -```python -server = Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] - pvc = { - name = "my_pvc" - accessModes = ["ReadWriteOnce"] - resources.requests.storage = "8Gi" - storageClassName = "slow" - } -} -``` - -Run with kcl, we will see the generated yaml files as output as below: - -KCL command: - -``` -kcl server.k -``` - -Stdout: - -```yaml -server: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod - pvc: - name: my_pvc - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 8Gi - storageClassName: slow ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: my_pvc -spec: - accessModes: - - ReadWriteOnce - storageClassName: slow - resources: - requests: - storage: 8Gi -``` - -If we don't want a persistent volume, just remove the pvc config block. - -## 11. Share and Reuse Schema - -The Server schema could be shared via `import`, we can simply package our code with KCL. - -```python -import pkg - -server = pkg.Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels.run = "my-nginx" - labels.env = "pre-prod" - service.ports = [Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -Another skill we should know about sharing code is, modules under the same package do not need to import each other. - -Suppose we have models in a pkg: - -``` -pkg/ - - deploy.k - - server.k - - pvc.k -``` - -And in `server.k`, we can just use Deployment schema in `deploy.k` and pvc schema in `pvc.k` without import: - -```python -# no import needed -schema Server(Deployment): - mixin [PersistentVolumeClaimMixin] - pvc?: {str:} - """ pvc user interface data defined by PersistentVolumeClaimMixin """ -``` - -And then users must import the pkg to use it as a whole: - -```python -import pkg - -server = pkg.Server { - name = "my-nginx" - image = "nginx:1.14.2" - volumes = [pkg.Volume { - name = "mydir" - mountPath = "/test-pd" - hostPath = "/data" - }] - command = ["nginx"] - labels = { - run = "my-nginx" - env = "pre-prod" - } - service.ports = [pkg.Port { - name = "http" - protocol = "TCP" - port = 80 - targetPort = 9376 - }] -} -``` - -Run kcl command: - -``` -kcl pkg_server.k -``` - -Output: - -```yaml -server: - name: my-nginx - cpu: 512 - memory: 1024 - volumes: - - name: mydir - mountPath: /test-pd - hostPath: /data - image: nginx:1.14.2 - service: - name: my-service - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 9376 - replica: 1 - command: - - nginx - labels: - run: my-nginx - env: pre-prod -``` - -## 12. The Final Step - -Congratulations! - -We have completed the second lesson about KCL, we have used KCL to replace our key-value text file to get better programming support. diff --git a/versioned_docs/version-0.8.0/reference/lang/codelab/simple.md b/versioned_docs/version-0.8.0/reference/lang/codelab/simple.md deleted file mode 100644 index 56be5805..00000000 --- a/versioned_docs/version-0.8.0/reference/lang/codelab/simple.md +++ /dev/null @@ -1,495 +0,0 @@ ---- -title: "Write simple config with KCL" -linkTitle: "Write simple config with KCL" -type: "docs" -weight: 2 -description: Write simple config with KCL -sidebar_position: 1 ---- - -## 1. Introduction - -KCL is a simple and easy-to-use configuration language, where users can simply write the reusable configuration code. - -In this first codelab, we will learn how to write a simple config with KCL. - -Learning this codelab only requires basic programming knowledge, and experience with python will make it even easier. - -### What We Will Learn - -1. Write simple key-value configuration in a programmable way -2. Write simple logic in KCL code -3. Write collections in KCL code -4. Test and debug with KCL code -5. Use built-in support in KCL code -6. Share and reuse KCL code -7. Write config with dynamic input arguments - -## 2. Write Key-Value Pairs - -Generate a simple config by creating a `my_config.k`, we can fill in the following code without strict format which describes the configuration of deploy. - -```python -cpu = 256 -memory = 512 -image = "nginx:1.14.2" -service = "my-service" -``` - -In the code above, cpu and memory are declared as int value, while image and service are string literal. - -Run with KCL, we will see the generated data in yaml format as below: - -KCL command: - -```bash -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -The exported variable is immutable by default so that once it is declared, we can't modify it some where else. - -## 3. Write Simple Logic - -Sometimes we want to write a logic in configuration, then we can use: - -- Mutable and non-exported variable starting with `_` -- If-else statement - -A non-exported variable means it will not appear in the output YAML, and it can be assigned multiple times. - -Here is a sample to show how to adjust the resource with conditions. - -KCL command: - -```python -kcl my_config.k -``` - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -image = "nginx:1.14.2" -service = "my-service" -``` - -Run with KCL, we will see the generated data in yaml format as below: - -```python -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 256 -memory: 512 -image: nginx:1.14.2 -service: my-service -``` - -.. note:: -KCL has rich support of operators and string member functions, please read manual and specification for more details. - -## 4. Write Collections - -We can use collections to represent complex data types. The collections which are already supported are: - -- list -- dict - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -command = ["nginx"] # a list -labels = {run = "my-nginx"} # a dict -image = "nginx:1.14.2" -service = "my-service" -``` - -Run with kcl, we will see the generated data as yaml format as below: - -KCL command: - -```bash -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx -image: nginx:1.14.2 -service: my-service -``` - -> Check manual and specification out for more about collection date type and member functions. - -## 5. Append Items Into Collections - -We can combine logical expressions, comprehensions, slices, unions and other characteristics to dynamically add elements to the collection - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable -_env = "pre-prod" - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -_command = ["nginx"] # a list -_command = _command + ["-f", "file"] # Append items into command using + operator to contact two lists -command = [c.lower() for c in _command] # Take each element in the list to lowercase -_labels = { - run = "my-nginx" - if _env: - env = _env # Append a dict key-value pair when the _env is not None/Undefined or empty using if expressions -} # a dict -labels = _labels -image = "nginx:1.14.2" -service = "my-service" -``` - -Run with kcl, we will see the generated data as yaml format as below: - -```python -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 256 -memory: 512 -command: - - nginx - - -f - - file -labels: - run: my-nginx -image: nginx:1.14.2 -service: my-service -``` - -## 6. Write Assert - -To make code testable and robust, we can verify config data with assertions. - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -cpu = _cpu -memory = _cpu * 2 -command = ["nginx"] # a list -labels = {run = "my-nginx"} # a dict -image = "nginx:1.14.2" -service = "my-service" -assert "env" in labels, "env label is a must" -assert cpu >= 256, "cpu cannot be less than 256" -``` - -Run with KCL, we will see eval failure with an error message as output as below: - -```bash -kcl my_config.k -``` - -Stderr: - -```bash -Assertion failure: env label is a must. -``` - -After adding env:pre-prod pair into labels, we will get the output as: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 7. Use Handy Built-in Support - -What's more, we can use built-in functions to help we debug or simplify coding. - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -_name = "nginx" -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # a list -labels = { - run = "my-{}".format(_name) - env = "pre-prod" -} # a dict -image = "{}:1.14.2".format(_name) # string format -service = "my-service" - -# debugging -print(labels) # debugging by print - -# test -assert len(labels) > 0, "labels can't be empty" # use len() to get list length -assert "env" in labels, "env label is a must" -assert cpu >= 256, "cpu cannot be less than 256" -``` - -This sample shows how we use `format()`, `len()`, `print()` function to help customize the config. - -Run with KCL, we will see the generated data in yaml format as below: - -KCL command: - -```bash -kcl my_config.k -``` - -Stdout: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -run: my-nginx -env: pre-prod -``` - -Note: more built-in functions and modules can be seen in spec/module - -## 8. Reuse Variables in Another Module - -To make our code well-organized, we can simply separate our code to `my_config.k` and `my_config_test.k`. - -Config data defined in `my_config.k`, - -```python -_priority = 1 # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 -_name = "nginx" - -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # a list -labels = { - run = "my-{}".format(_name) - env = "pre-prod" -} # a dict -image = "{}:1.14.2".format(_name) # string format -service = "my-service" -``` - -And test code defined in `my_config_test.k`, in which we can import `my_config.k`: - -```python -import my_config - -# debugging -print(my_config.labels) # debugging by print - -# test -assert len(my_config.labels) > 0, "labels can't be empty" # use len() to get list length -assert "env" in my_config.labels, "env label is a must" -assert my_config.cpu >= 256, "cpu cannot be less than256" -``` - -## 9. Config with Input Arguments - -Sometimes we need to get external input via parameters dynamically from the end user or platform. - -In this case, we can pass in `priority` and `env` on demand: - -- Pass in arguments: `-D priority=1 -D env=pre-prod` -- Get value by `option` keyword in KCL code - -```python -_priority = option("priority") # a non-exported and mutable variable -_env = option("env") # a non-exported and mutable variable -_cpu = 256 # a non-exported and mutable variable - -if _priority == 1: - _cpu = 256 -elif _priority == 2: - _cpu = 512 -elif _priority == 3: - _cpu = 1024 -else: - _cpu = 2048 - -_name = "nginx" -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # a list -labels = { - run = "my-{}".format(_name) - env = _env -} # a dict -image = "{}:1.14.2".format(_name) # string format -service = "my-service" -``` - -Run with KCL, we will see the generated data in yaml format as below: - -```bash -kcl my_config.k -D priority=2 -D env=pre-prod -``` - -Stdout: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 10. Simplify Logic Expression using Dict - -When we need to write complex logic, we can use dict to simplify the writing of logic. - -```python -_priority = option("priority") # a non-exported and mutable variable -_env = option("env") # a non-exported and mutable variable -_priorityCpuMap = { - "1" = 256 - "2" = 512 - "3" = 1024 -} -# Using a dict to simplify logic and the default value is 2048 -_cpu = _priorityCpuMap[_priority] or 2048 -_name = "nginx" -# exported variables -cpu = _cpu -memory = _cpu * 2 -command = [_name] # a list -labels = { - run = "my-{}".format(_name) - env = _env -} # a dict -image = "{}:1.14.2".format(_name) # string format -service = "my-service" -``` - -Run with KCL, we will see the generated data in yaml format as below: - -KCL command: - -```bash -kcl my_config.k -D priority=2 -D env=pre-prod -``` - -Stdout: - -```yaml -cpu: 512 -memory: 1024 -command: - - nginx -labels: - run: my-nginx - env: pre-prod -image: nginx:1.14.2 -service: my-service -``` - -## 11. The Final Step - -Congratulations! - -We have completed the first lesson about KCL, we have used KCL to replace our key-value text file to get better programming support. - -Please check schema codelab out now to learn how to write an advanced config collaboratively with KCL `schema` mechanism. diff --git a/versioned_docs/version-0.8.0/reference/lang/error/_category_.json b/versioned_docs/version-0.8.0/reference/lang/error/_category_.json deleted file mode 100644 index 95062745..00000000 --- a/versioned_docs/version-0.8.0/reference/lang/error/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Errors and Warnings", - "position": 4 -} diff --git a/versioned_docs/version-0.8.0/reference/lang/error/index.md b/versioned_docs/version-0.8.0/reference/lang/error/index.md deleted file mode 100644 index 15fbda6f..00000000 --- a/versioned_docs/version-0.8.0/reference/lang/error/index.md +++ /dev/null @@ -1 +0,0 @@ -# Errors and Warnings diff --git a/versioned_docs/version-0.8.0/reference/lang/spec/_category_.json b/versioned_docs/version-0.8.0/reference/lang/spec/_category_.json deleted file mode 100644 index 7b24faae..00000000 --- a/versioned_docs/version-0.8.0/reference/lang/spec/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Spec", - "position": 3 -} diff --git a/versioned_docs/version-0.8.0/reference/lang/spec/datatypes.md b/versioned_docs/version-0.8.0/reference/lang/spec/datatypes.md deleted file mode 100644 index ef7ea71a..00000000 --- a/versioned_docs/version-0.8.0/reference/lang/spec/datatypes.md +++ /dev/null @@ -1,452 +0,0 @@ ---- -title: "Data Types" -linkTitle: "Data Types" -type: "docs" -weight: 2 -description: Data Types ---- - -## Syntax - -### Bool - -Boolean values are the two constant objects `False` and `True`. They are used to represent truth values (although other values can also be considered false or true). The built-in function bool() can be used to convert any value to a Boolean, if the value can be interpreted as a truth value. - -### Int - -Int, or integer, is an arbitrarily sized integer, positive or negative, without decimals, of 64 binary digits precision(-9,223,372,036,854,775,808~9,223,372,036,854,775,807). Int is created by int literals or as the result of built-in functions and operators. Unadorned integer literals (including `hex`, `octal` and `binary` numbers) yield integers. The constructor int() can be used to produce int of a specific type. - -Besides, integer literals may have an `SI` or `IEC` multiplier. - -- `SI`: General integer or fixed-point number form: `P`, `T`, `G`, `M`, `K`, `k`, `m`, `u`, `n`. -- `IEC`: Corresponding power of 2: `Pi`, `Ti`, `Gi`, `Mi`, `Ki`. - -```python -a = 1 # positive integer: 1 -b = -1 # negative integer: -1 -c = 0x10 # hexadecimal literal: 16 -d = 0o10 # octal literal: 8, or the form `010` -e = 0b10 # binary literal: 2 -f = 10Ki # integer literal with IEC multiplier: 10240 -g = 1M # integer literal with SI multiplier: 1000000 -h = int("10") # int constructor: 10 -i = int("10Ki") # int constructor with multiplier: 10240 -``` - -Notes: - -- Report an error if unable to represent an integer value precisely. - -### Float - -Float, floating-point, approximation to real numbers, positive or negative, containing one or more decimals, of 64 bit IEEE 754 floats. The constructor float() can be used to produce int of a specific type. - -```python -a = 1.10 -b = 1.0 -c = -35.59 -d = 32.3+e18 -f = -90. -g = -32.54e100 -h = 70.2-E12 -i = float("112") # float constructor -``` - -Notes: - -- Report an error if unable to represent a floating-point value due to overflow -- Report a warning if unable to represent a floating-point value due to underflow. Round to the nearest representable value if unable to represent a floating-point value due to limits on precision. These requirements apply to the result of any expression except for built-in functions for which an unusual loss of precision must be explicitly documented. - -#### None - -In KCL, `None` can indicate that the value of the object is empty, which is similar to `nil` in Go or `null` in Java, and corresponds to `null` in YAML and JSON. - -```python -a = None -b = [1, 2, None] -c = {"key1" = "value1", "key2" = None} -``` - -Please note that `None` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + None # error -b = int(None) # error -c = not None # True -d = None == None # True -e = None or 1 # 1 -f = str(None) # None -``` - -#### Undefined - -`Undefined` is similar to None, but its semantics is that a variable is not assigned any value and will not be output to YAML or JSON. - -```python -a = Undefined -b = [1, 2, Undefined] -c = {"key1" = "value1", "key2" = Undefined} -``` - -Please note that `Undefined` cannot participate in the four arithmetic operations, but it can participate logical operators and comparison operators to perform calculations. - -```python -a = 1 + Undefined # error -b = int(Undefined) # error -c = not Undefined # True -d = Undefined == Undefined # True -e = Undefined or 1 # 1 -f = str(Undefined) # Undefined -``` - -### Common Numeric Operations - -Int and Float support the following operations (see built-in proposal for built-in details): - -- `x + y`: sum of x and y. -- `x - y`: difference of x and y. -- `x * y`: product of x and y. -- `x / y`: quotient of x and y. -- `x // y`: floored quotient of x and y. -- `x % y`: remainder of x / y. -- `x ** y`: x to the power y. -- `-x`: x negated. -- `+x`: x unchanged. -- `~x`: x bitwise negation. -- `abs(x)`: absolute value or magnitude of x. -- `int(x)`: x converted to integer. -- `float(x)`: x converted to floating point. - -KCL supports mixed arithmetic: when a binary arithmetic operator has operands of different numeric types, the operand with the "narrower" type is widened to that of the other, where integer is narrower than floating-point. - -### String - -Strings are immutable sequences of Unicode characters. String literals are written in a variety of ways: - -```python -'allows embedded "double" quotes' # Single quotes -"allows embedded 'single' quotes" # Double quotes -'''Three single quotes''', """Three double quotes""" # Triple quoted -``` - -Triple quoted strings may span multiple lines. - -Indexing a string produces strings of length 1, for a non-empty string s, `s[0] == s[0:1]`. - -```python -a = "Hello, World!" -b = a[2:5] # "llo" -c = a[-5:-2] # "orl" -d = a[::-1] # "'!dlroW ,olleH'" -``` - -- `str(x=None) -> str` - -Return a string. If _x_ is not provided, raise a runtime error. - -```python -x = str(3.5) # "3.5" -``` - -#### Members - -Built-in function and members of a string - -- `str#len() -> int` - Return the number of characters in the string. -- `capitalize() -> str` - Return a copy of the string with its first character (if any) capitalized and the rest lowercased. -- `count(sub: str, start: int = 0, end: int = -1) -> int` - Returns the number of (non-overlapping) occurrences of substring sub in string, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `endswith(suffix: str, start: int = 0, end: int = -1) -> bool` - Returns `True` if the string ends with the specified suffix, otherwise return `False`, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `find(sub: str, start: int = 0, end: int = -1) -> int` - Returns the lowest index where substring sub is found, or -1 if no such index exists, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `format(*args, **kwargs) -> str` - Perform string interpolation. Format strings contain replacement fields surrounded by curly braces {}. Anything that is not contained in braces is considered literal text, which is copied unchanged to the output. If you need to include a bracket character in the literal text, it can be escaped by doubling: A replacement field can be either a name, a number or empty. Values are converted to strings using the str function. -- `index(sub: str, start: int = 0, end: int = -1) -> int` - Returns the first index where sub is found, or raises an error if no such index exists, optionally restricting to `[start:end]` start being inclusive and end being exclusive. -- `isalnum() -> bool` - Returns True if all characters in the string are alphanumeric (`[a-zA-Z0-9]`) and there is at least one character, False otherwise. -- `isalpha() -> bool` - Returns True if all characters in the string are alphabetic (`[a-zA-Z]`) and there is at least one character. -- `isdigit() -> bool` - Returns True if all characters in the string are digits (`[0-9]`) and there is at least one character. -- `islower() -> bool` - Returns True if all cased characters in the string are lowercase and there is at least one character. -- `isspace() -> bool` - Returns True if all characters are white space characters and the string contains at least one character. -- `istitle() -> bool` - Returns True if the string is in title case and it contains at least one character. This means that every uppercase character must follow an uncased one (e.g., whitespace) and every lowercase character must follow a cased one (e.g., uppercase or lowercase). -- `isupper() -> bool` - Returns True if all cased characters in the string are uppercase and there is at least one character. -- `join(iterable: list) -> str` - Return a string which is the concatenation of the strings in iterable. A TypeError will be raised if there are any non-string values in iterable. The separator between elements is the string providing this method. Example: - - ```python - >>> "|".join(["a", "b", "c"]) - "a|b|c" - ``` - -- `lower() -> str` - Returns a copy of the string with all the cased characters converted to lowercase. -- `lstrip(chars: str) -> str` - Return a copy of the string with leading characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.lstrip() - 'spacious ' - >>> 'www.example.com'.lstrip('cmowz.') - 'example.com' - ``` - -- `replace(old: str, new: str, count: int) -> str` - Return a copy of the string with all occurrences of substring old replaced by new. If the optional argument count is given, only the first count occurrences are replaced. -- `rfind(sub: str, start: int = 0, end: int = -1) -> int` - Return the highest index in the string where substring sub is found, such that sub is contained within s[start:end]. Optional arguments start and end are interpreted as in slice notation. Return -1 on failure. -- `rindex(sub: str, start: int = 0, end: int = -1) -> int` - Returns the last index where sub is found, or raises an ValueError if no such index exists, optionally restricting to `[start:end]`, start being inclusive and end being exclusive. -- `rsplit(sep: str, maxsplit: int = -1) -> list` - Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done, the rightmost ones. If sep is not specified or None, any whitespace string is a separator. Except for splitting from the right, rsplit() behaves like split() which is described in detail below. -- `rstrip(chars: str) -> str` - Return a copy of the string with trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a suffix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.rstrip() - ' spacious' - >>> 'mississippi'.rstrip('ipz') - 'mississ' - ``` - -- `split(sep: str, maxsplit: int) -> list` - Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done (thus, the list will have at most maxsplit+1 elements). If maxsplit is not specified or -1, then there is no limit on the number of splits (all possible splits are made). - - If sep is given, consecutive delimiters are not grouped together and are deemed to delimit empty strings (for example, `'1,,2'.split(',')` returns `['1', '', '2']`). The sep argument may consist of multiple characters (for example, `'1<>2<>3'.split('<>')` returns `['1', '2', '3']`). Splitting an empty string with a specified separator returns `['']`. - - For example: - - ```python - >>> '1,2,3'.split(',') - ['1', '2', '3'] - >>> '1,2,3'.split(',', maxsplit=1) - ['1', '2,3'] - >>> '1,2,,3,'.split(',') - ['1', '2', '', '3', ''] - ``` - - If sep is not specified or is None, a different splitting algorithm is applied: runs of consecutive whitespace are regarded as a single separator, and the result will contain no empty strings at the start or end if the string has leading or trailing whitespace. Consequently, splitting an empty string or a string consisting of just whitespace with a `None` separator returns `[]`. - - For example: - - ```python - >>> '1 2 3'.split() - ['1', '2', '3'] - >>> '1 2 3'.split(maxsplit=1) - ['1', '2 3'] - >>> ' 1 2 3 '.split() - ['1', '2', '3'] - ``` - -- `splitlines(keepends: str) -> list` - Return a list of the lines in the string, breaking at line boundaries('\n', '\r\n', '\r'). Line breaks are not included in the resulting list unless keepends is given and true. - - This method splits on the following line boundaries. In particular, the boundaries are a superset of universal newlines. - - For example: - - ```python - >>> 'ab c\n\nde fg\rkl\r\n'.splitlines() - ['ab c', '', 'de fg', 'kl'] - >>> 'ab c\n\nde fg\rkl\r\n'.splitlines(keepends=True) - ['ab c\n', '\n', 'de fg\r', 'kl\r\n'] - ``` - - Unlike `split()` when a delimiter string sep is given, this method returns an empty list for the empty string, and a terminal line break does not result in an extra line: - - ```python - >>> "".splitlines() - [] - >>> "One line\n".splitlines() - ['One line'] - ``` - - For comparison, `split('\n')` gives: - - ```python - >>> ''.split('\n') - [''] - >>> 'Two lines\n'.split('\n') - ['Two lines', ''] - ``` - -- `startswith(prefix: str, start: int = 0, end: int = -1) -> bool` - Return `True` if string starts with the prefix, otherwise return False. prefix can also be a list of prefixes to look for. With optional start, test string beginning at that position. With optional end, stop comparing string at that position. -- `strip(chars: str) -> str` - Return a copy of the string with the leading and trailing characters removed. The chars argument is a string specifying the set of characters to be removed. If omitted or None, the chars argument defaults to removing whitespace. The chars argument is not a prefix or suffix; rather, all combinations of its values are stripped: - - ```python - >>> ' spacious '.strip() - 'spacious' - >>> 'www.example.com'.strip('cmowz.') - 'example' - ``` - - The outermost leading and trailing chars argument values are stripped from the string. Characters are removed from the leading end until reaching a string character that is not contained in the set of characters in chars. A similar action takes place on the trailing end. For example: - - ```python - >>> comment_string = '#....... Section 3.2.1 Issue #32 .......' - >>> comment_string.strip('.#! ') - 'Section 3.2.1 Issue #32' - ``` - -- `title() -> str` - Return a titlecased version of the string where words start with an uppercase character and the remaining characters are lowercase. - - For example: - - ```python - >>> 'Hello world'.title() - 'Hello World' - ``` - - The algorithm uses a simple language-independent definition of a word as groups of consecutive letters. The definition works in many contexts but it means that apostrophes in contractions and possessives form word boundaries, which may not be the desired result: - - ```python - >>> "they're bill's friends from the UK".title() - "They'Re Bill'S Friends From The Uk" - ``` - -- `upper() -> str` - Return a copy of the string with all the cased characters 4 converted to uppercase. Note that `s.upper().isupper()` might be `False` if s contains uncased characters or if the Unicode category of the resulting character(s) is not “Lu” (Letter, uppercase), but e.g., “Lt” (Letter, titlecase). -- `removeprefix(prefix: str) -> str` - If the string starts with the prefix string, return string[len(prefix):]. Otherwise, return a copy of the original string. - ```python - >>> "prefix-data".removeprefix("prefix-") - "data" - ``` -- `rermovesuffix(suffix: str) -> str` - If the string ends with the suffix string and that suffix is not empty, return string[:-len(suffix)]. Otherwise, return a copy of the original string. - ```python - >>> "data-suffix".removesuffix("-suffix") - "data" - ``` - -### List - -Lists are immutable sequences, typically used to store collections of homogeneous items (where the precise degree of similarity will vary by application). - -Lists may be constructed in several ways: - -- Using a pair of square brackets to denote the empty list: `[]` -- Using square brackets, separating items with commas: `[a]`, `[a, b, c]` -- Using a list comprehension: `[x for x in iterable]` -- Using the type constructor: list() or list(iterable) - -The constructor builds a list whose items are the same and in the same order as iterable’s items.Iterable may be either a sequence, a container that supports iteration, or an iterator object. If iterable is already a list, a copy is made and returned, similar to `iterable[:]`. For example, `list('abc')` returns `['a', 'b', 'c']` and `list([1, 2, 3])` returns `[1, 2, 3]`. If no argument is given, the constructor creates a new empty list `[]`. - -Lists implement all of the common sequence operations. - -#### Members - -- `len()` - Return the number of items in the list. - -### Common Sequence Operations - -The operations in the following table are supported by List and Dict. - -This table lists the sequence operations sorted in ascending priority. In the table, s and t are sequences of the same type, n, i, j and k are integers and x is an arbitrary object that meets any type and value restrictions imposed by s. - -The `in` and `not in` operations have the same priorities as the comparison operations. The + -(concatenation) and \* (repetition) operations have the same priority as the corresponding numeric operations. - -| Operation | Result | Notes | -| ------------ | -------------------------------------------------- | ----- | -| `x in s` | `True` if an item of s is equal to x, else `False` | #1 | -| `x not in s` | `False` if an item of s is equal to x, else `True` | #1 | -| `s + t` | the concatenation of s and t | #5 | -| `s[i]` | ith item of s, origin 0 | #2 | -| `s[i:j]` | slice of s from i to j | #2 #3 | -| `s[i:j:k]` | slice of s from i to j with step k | #2 #4 | -| `min(s)` | smallest item of s | | -| `max(s)` | largest item of s | | - -Notes: - -- 1. While the in and not in operations are used only for simple containment testing in the - general case, some specialized sequences (str) also use them for subsequence testing: - -```python ->>> "gg" in "eggs" -True -``` - -- 2. If i or j is negative, the index is relative to the end of sequence s: `s.len() + i` or `s.len() + j` is substituted. But note that -0 is still 0. -- 3. The slice of s from i to j is defined as the sequence of items with index k such that `i <= k < j`. If i or j is greater than `s.len()`, use `s.len()`. If i is omitted or None, use 0. If j is omitted or None, use `s.len()`. If i is greater than or equal to j, the slice is empty. -- 4. The slice of s from i to j with step k is defined as the sequence of items with index `x = i + n*k` such that `0 <= n < (j-i)/k`. In other words, the indices are `i`, `i+k`, `i+2*k`, `i+3*k` and so on, stopping when j is reached (but never including j). When k is positive, i and j are reduced to s.len() if they are greater. When k is negative, i and j are reduced to s.len() - - - If they are greater. If i or j are omitted or None, they become “end” values (which end depends on the sign of k). Note, k cannot be zero. If k is None, it is treated like 1. - -- 5. Concatenating immutable sequences always results in a new object. This means that building up a sequence by repeated concatenation will have a quadratic runtime cost in the total sequence length. To get a linear runtime cost, you must switch to one of the alternatives below: - - - if concatenating str objects, you can build a list and use `str.join()` at the end - -- 6. `index` raises `ValueError` when x is not found in s. Not all implementations support passing the additional arguments i and j. These arguments allow efficient searching of subsections of the sequence. Passing the extra arguments is roughly equivalent to using `s[i:j].index(x)`, only without copying any data and with the returned index being relative to the start of the sequence rather than the start of the slice. - -### Dict - -Dict is an immutable mapping object maps hashable values to arbitrary objects. A dictionary’s keys are almost arbitrary values. Values that are not hashable, that is, values containing lists, dictionaries may not be used as keys. Numeric types used for keys obey the normal rules for numeric comparison: if two numbers compare equal (such as 1 and 1.0) then they can be used interchangeably to index the same dictionary entry. (Note however, that since computers store floating-point numbers as approximations it is usually unwise to use them as dictionary keys.) Dict is ordered. The order of the keys is the order of their declaration. - -Dictionaries can be created by placing a comma-separated list of keys: value pairs within braces, for example: `{'jack': 4098, 'sjoerd': 4127}` or `{4098: 'jack', 4127: 'sjoerd'}`, by the dict constructor, or list/dict comprehension. - -- `dict(obj)` - -Return a new dictionary initialized from an optional positional argument and a possibly empty set of keyword arguments.If no positional argument is given, an empty dictionary is created. If a positional argument is given and it is a mapping object, a dictionary is created with the same key-value pairs as the mapping object. Otherwise, the positional argument must be an iterable object. Each item in the iterable must itself be an iterable with exactly two objects. The first object of each item becomes a key in the new dictionary, and the second object the corresponding value. If a key occurs more than once, the last value for that key becomes the corresponding value in the new dictionary. If keyword arguments are given, the keyword arguments and their values are added to the dictionary created from the positional argument. If a key being added is already present, the value from the keyword argument replaces the value from the positional argument. To illustrate, the following examples all return a dictionary equal to `{"one": 1, "two": 2, "three": 3}`: - -```python ->>> a = {'two': 2, 'one': 1, 'three': 3} ->>> b = {'one': 1, 'two': 2, 'three': 3} ->>> c = {'three': 3, 'one': 1, 'two': 2} ->>> a == b == c -True -``` - -Providing keyword arguments as in the first example only works for keys that are valid KCL identifiers. Otherwise, any valid keys can be used. - -In the dict comprehension, key/value pairs yielded by the generator expression is set in the dictionary in the order yielded: the first occurrence of the key determines its insertion order, and the last determines the value associated to it. - -```python ->>> {str(i): 2 * i for i in range(3)} -{"0": 0, "1": 2, "2": 4} - ->>> a = {"one": 1, "two": 2, "three": 3} ->>> b = {k: v for k, v in a if v >= 2} -{two: 2, three: 3} -``` - -#### Operations & Members - -These are the operations that dictionaries the support. - -- `list(d)` - Return a list of all the keys used in the dictionary d. -- `len()` - Return the number of items in the dictionary d. -- `d[key]` - Return the item of d with key. Return Undefined if key is not in the map. -- `key in d` - Return True if d has a key, else False. -- `key not in d` - Equivalent to not key in d. -- `d.key` - Return the item of d with key. Return Undefined if key is not in the map. - -Dictionaries compare equal if and only if they have the same (key, value) pairs(keys' ordering matters). Order comparisons (‘<’, ‘<=’, ‘>=’, ‘>’) raise TypeError. - -```python ->>> d = {"one": 1, "two": 2, "three": 3, "four": 4} ->>> d -{'one': 1, 'two': 2, 'three': 3, 'four': 4} ->>> list(d) -['one', 'two', 'three', 'four'] -``` diff --git a/versioned_docs/version-0.8.0/reference/lang/spec/expressions.md b/versioned_docs/version-0.8.0/reference/lang/spec/expressions.md deleted file mode 100644 index d7e8a0f3..00000000 --- a/versioned_docs/version-0.8.0/reference/lang/spec/expressions.md +++ /dev/null @@ -1,913 +0,0 @@ ---- -title: "Expressions" -linkTitle: "Expressions" -type: "docs" -weight: 2 -description: Expressions ---- - -## Syntax - -In KCL, an expression specifies the computation of a value. - -The syntax is the following: - -```bnf -expression: test ("," test)* -test: if_expr | primary_expr | unary_expr | binary_expr -``` - -KCL expressions consist of `if` expression, `primary` expression, `unary` expression, and `binary` expression. - -### Primary Expressions - -Primary expressions are the operands for unary and binary expressions. - -Operands are self-delimiting. An **operand** may be followed by any number of selector dot, a function call, or slice suffixes, to form a primary expression. The grammar uses `expression`, where a multiple-component expression is allowed, and `test` where it accepts an expression of only a single component. - -Syntax: - -```bnf -primary_expr: operand | primary_expr select_suffix | primary_expr call_suffix | primary_expr subscript_suffix -``` - -### Operands - -Operand denotes the elementary value in an expression. An operand may be an identifier, a literal, or a parenthesized expression. - -Syntax: - -```bnf -operand: operand_name | number | string | "True" | "False" | "None" | "Undefined" | list_expr | list_comp | dict_expr | dict_comp | "(" expression ")" -operand_name: identifier | qualified_identifier -``` - -### Identifiers - -In KCL, an identifier is a name, may with selectors, that identifies a value. - -Syntax: - -```bnf -identifier: NAME -``` - -Examples: - -```python -x -a -_b -``` - -Use the `$` character prefix to define keyword identifiers. - -```python -$if = 1 -$else = "s" -``` - -Please note: whether the non-keyword identifier is prefixed with `$` has the same effect. - -```python -_a = 1 -$_a = 2 # equal to `_a = 2` -``` - -To simplify the definition of the qualified identifier, such as 'pkg.type', we additionally define `qualified_identifier`: - -Syntax: - -```bnf -qualified_identifier: identifier "." identifier -``` - -Examples: - -```python -pkg.a -``` - -The package name in qualified_identifier must be imported. - -### Basic Literals - -Basic literals supported in KCL are `int`, `float`, `string` and `bool` including `True` and `False`. Evaluation of basic literal yields a value of the given type with the given value. - -Syntax: - -```bnf -operand: number | string | "True" | "False" | "None" | "Undefined" -``` - -Examples: - -```python -1 -2.3 -"abc" -True -False -None -Undefined -``` - -See more details about **data type** spec. - -### Parenthesized Expressions - -An expression enclosed in parentheses yields the result of that expression. - -Syntax: - -```bnf -operand: '(' expression ')' -``` - -Examples: - -```python -x = (1 + 2) * (3 + 4) # 21 -``` - -### Dictionary Expressions - -A dictionary expression is a comma-separated immutable list of colon-separated key/value expression pairs, enclosed in curly brackets, and it yields a new dictionary object. An optional comma may follow the final pair. - -```bnf -config_expr: '{' config_entries '}' -config_entries: config_entry [config_entry*] -config_comp: '{' (config_entry comp_clause+) '}' -config_entry: expr (':' | '=' | '+=') expr | double_star_expr | if_entry -double_star_expr: "**" expression -if_entry: - 'if' expr ';' if_entry_exec_block - ('elif' expr ':' if_entry_exec_block)* - ('else' ':' if_entry_exec_block)? -NEWLINE: '/r?/n' -``` - -Examples: - -```python -{} -{"one": 1} -{"one": 1, "two": 2} -``` - -The key and value expressions are evaluated in left-to-right order. Evaluation fails if the same key is used multiple times. - -Only hashable values may be used as the keys of a dictionary. This includes all built-in types except dictionaries, and lists. - -We can ignore the comma `,` at the end of the line for writing dict key-value pairs in multiple lines: - -```python -data = { - "key1" = "value1" # Ignore the comma ',' at the end of line - "key2" = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -We can ignore the key quotation marks when we writing simple literals on the key. - -```python -data = { - key1 = "value1" # Ignore the comma ',' at the end of line - key2 = "value2" -} # {"key1": "value1", "key2": "value2"} -``` - -In addition, the **config selector expressions** can be used to init a schema instance. - -```python -person = { - base.count = 2 - base.value = "value" - labels.key = "value" -} # {"base": {"count": 2, "value": "value"}, "labels": {"key": "value"}} -``` - -We can **merge** dict using the dict unpacking operator `**` like this: - -```python -_part1 = { - a = "b" -} - -_part2 = { - c = "d" -} - -a_dict = {**_part1, **_part2} # {"a: "b", "c": "d"} -``` - -We can use `if expressions` to dynamically add elements to the dict element, elements that meet the conditions are added to the dict, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = { - key1 = "value1" - if a == 1: key2 = "value2" - if a > 0: key3 = "value3" - if a < 0: key4 = "value4" -} # {"key1": "value1", "key2": "value2", "key3": "value3"} -``` - -```python -a = 1 # 1 -data1 = { - key1 = "value1" - if a == 1: - key2 = "value2" - elif a > 0: - key3 = "value3" - else: - key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -data2 = { - key1 = "value1" - if a == 1: key2 = "value2" - elif a > 0: key3 = "value3" - else: key4 = "value4" -} # {"key1": "value1", "key2": "value2"} -``` - -### List Expressions - -A list expression is a comma-separated immutable list of element expressions, enclosed in square brackets, and it yields a new list. An optional comma may follow the last element expression. - -```bnf -list_expr: '[' [list_item [',']] ']' -list_item: test | "*" primary_expr | if_expr -``` - -Element expressions are evaluated in left-to-right order. - -Examples: - -```python -[] # [], empty list -[1] # [1], a 1-element list -[1, 2, 3] # [1, 2, 3], a 3-element list -``` - -We can use `if expressions` to dynamically add elements to the list element, elements that meet the conditions are added to the list, and elements that do not meet the conditions are ignored. - -```python -a = 1 # 1 -data = [ - 1 - if a == 1: 2 - if a > 0: 3 - if a < 0: 4 -] # [1, 2, 3] -``` - -```python -a = 1 # 1 -data1 = [ - 1 - if a == 1: - 2 - elif a == 2: - 3 - else: - 3 -] # [1, 2] -data2 = [ - 1 - if a == 1: 2 - elif a == 2: 2 - else: 3 -] # [1, 2] -``` - -### Comprehensions - -A comprehension constructs a new list or dictionary value by looping over one or more iterables and evaluating a body expression that produces successive elements of the result. - -Syntax: - -```bnf -list_comp: '[' list_item comp_clause+ ']' . -dict_comp: '{' entry comp_clause+ '}' . - -comp_clause: 'for' loop_variables [","] 'in' test ['if' test] -loop_variables: primary_expr (',' primary_expr)* -``` - -A list comprehension consists of a single expression followed by one or more clauses, the first of which must be a `for` clause. Each `for` clause resembles a `for` statement, and specifies an iterable operand and a set of variables to be assigned by successive values of the iterable. An `if` cause resembles an `if` statement, and specifies a condition that must be met for the body expression to be evaluated. A sequence of `for` and `if` clauses acts like a nested sequence of `for` and `if` statements. - -Examples: - -```python -[x * x for x in range(5)] # [0, 1, 4, 9, 16] -[x * x for x in range(5) if x % 2 == 0] # [0, 4, 16] -[[x, y] for x in range(5) \ - if x % 2 == 0 \ - for y in range(5) \ - if y > x] # [[0, 1], [0, 2], [0, 3], [0, 4], [2, 3], [2, 4]] -``` - -Besides, we can use two variables in the list comprehension, the first variable denotes the list index and the second variable denotes the list item. - -```python -data = [1000, 2000, 3000] -# Single variable loop -dataLoop1 = [i * 2 for i in data] # [2000, 4000, 6000] -dataLoop2 = [i for i in data if i == 2000] # [2000] -dataLoop3 = [i if i > 2 else i + 1 for i in data] # [1000, 2000, 3000] -# Double variable loop -dataLoop4 = [i + v for i, v in data] # [1000, 2001, 3002] -dataLoop5 = [v for i, v in data if v == 2000] # [2000] -# Use `_` to ignore loop variables -dataLoop6 = [v if v > 2000 else v + i for i, v in data] # [1000, 2001, 3000] -dataLoop7 = [i for i, _ in data] # [0, 1, 2] -dataLoop8 = [v for _, v in data if v == 2000] # [2000] -``` - -A dict comprehension resembles a list comprehension, but its body is a pair of expressions, key: value, separated by a colon, and its result is a dictionary containing the key/value pairs for which the body expression was evaluated. Evaluation fails if the value of any key is un-hashable. - -Besides, we can use two variables in the dict comprehension, the first variable denotes the dict key and the second variable denotes the dict value of the key. - -```python -data = {"key1" = "value1", "key2" = "value2"} -# Single variable loop -dataKeys1 = {k: k for k in data} # {"key1": "key1", "key2": "key2"} -dataValues1 = {k: data[k] for k in data} # {"key1": "value1", "key2": "value2"} -# Double variable loop -dataKeys2 = {k: k for k, v in data} # {"key1": "key1", "key2": "key2"} -dataValues2 = {v: v for k, v in data} # {"value1": "value1", "value2": "value2"} -dataFilter = {k: v for k, v in data if k == "key1" and v == "value1"} # {"key1": "value1"} -# Use `_` to ignore loop variables -dataKeys3 = {k: k for k, _ in data} # {"key1": "key1", "key2": "key2"} -dataValues3 = {v: v for _, v in data} # {"value1": "value1", "value2": "value2"} -``` - -As with a `for` loop, the loop variables may exploit compound assignment: - -```python -[x * y + z for [x, y], z in [[[2, 3], 5], [["o", 2], "!"]]] # [11, 'oo!'] -``` - -KCL does not accept an un-parenthesized list as the operand of a for clause: - -```python -[x * x for x in 1, 2, 3] # parse error: unexpected comma -``` - -Comprehensions defines a new lexical block, so assignments to loop variables have no effect on variables of the same name in an enclosing block: - -```python -x = 1 -_ = [x for x in [2]] # new variable x is local to the comprehension -print(x) # 1 -``` - -The operand of a comprehension's first clause (always a for) is resolved in the lexical block enclosing the comprehension. In the examples below, identifiers referring to the outer variable named x have been distinguished by subscript. - -```python -x0 = [1, 2, 3] -[x * x for x in x0] # [1, 4, 9] -[x * x for x in x0 if x % 2 == 0] # [4] -``` - -All subsequent for and if expressions are resolved within the comprehension's lexical block, as in this rather obscure example: - -```python -x0 = [[1, 2], [3, 4], [5, 6]] -[x * x for x in x0 for x in x if x % 2 == 0] # [4, 16, 36] -``` - -which would be more clearly rewritten as: - -```python -x = [[1, 2], [3, 4], [5, 6]] -[z * z for y in x for z in y if z % 2 == 0] # [4, 16, 36] -``` - -### Conditional Expressions - -A conditional expression has the form `a if cond else b`. It first evaluates the condition `cond`. If it's true, it evaluates `a` and yields its value; otherwise it yields the value of `b`. - -Syntax: - -```bnf -if_expr: test "if" test "else" test -``` - -Examples: - -```python -x = True if enabled else False # if enabled is -``` - -### Unary Expressions - -In KCL, supported unary operators are `+`, `-`, `~`, and `not`. - -Syntax: - -```bnf -unary_expr: ("+" | "-" | "~") primary_expr - | "not" test -``` - -Usage: - -```bnf -+ number unary positive (int, float) -- number unary negation (int, float) -~ number unary bitwise inversion (int) -not x logical negation (any type) -``` - -The `+` and `-` operators may be applied to any number (int or float) and return the number. -The `not` operator returns the negation of the truth value of its operand. - -Examples: - -```python -~1 # -2 -~-1 # 0 -~0 # -1 -not True # False -not 0 # True -``` - -### Binary Expressions - -In KCL, binary expressions consist of `comparisons`, `logical operations`, `arithmetic operations` and `membership tests`. - -Syntax: - -```bnf -binary_expr: test bin_op test -bin_op: 'or' - | 'and' - | '==' | '!=' | '<' | '>' | '<=' | '>=' - | 'in' | 'not' 'in' - | '|' - | '^' - | '&' - | '-' | '+' - | '*' | '%' | '/' | '//' - | '<<' | '>>' -``` - -#### Logical Operations - -The `or` and `and` operators yield the logical disjunction and conjunction of their arguments, which need not be Booleans. - -The expression `x or y` yields the value of `x` if its truth value is `True`, or the value of `y` otherwise. - -```python -False or False # False -False or True # True -True or True # True -1 or "hello" # 1 -``` - -Similarly, `x` and `y` yields the value of `x` if its truth value is `False`, or the value of `y` otherwise. - -```python -False and False # False -False and True # False -True and True # True -1 and "hello" # "hello" -``` - -These operators use "short circuit" evaluation, so the second expression is not evaluated if the value of the first expression has already determined the result, allowing constructions like these: - -```python -x and x[0] == 1 # x[0] is not evaluated if x is empty -len(x) == 0 or x[0] == "" -not x or not x[0] -``` - -#### Comparisons - -The `==` operator reports whether its operands are equal; the `!=` operator is its negation. - -The operators `<`, `>`, `<=`, and `>=` perform an ordered comparison of their operands. It is an error to apply these operators to operands of unequal type, unless one of the operands is an `int` and the other is a `float`. Of the built-in types, only the following support ordered comparison, using the ordering relation shown: - -```bnf -NoneType # None <= None -bool # False < True -int # mathematical -float # as defined by IEEE 754 -string # lexicographical -list # lexicographical -``` - -Comparison of floating-point values follows the IEEE 754 standard, which breaks several mathematical identities. For example, if `x` is a `NaN` value, the comparisons `x < y`, `x == y`, and `x > y` all yield false for all values of `y`. - -The remaining built-in types support only equality comparisons. Values of type `dict` and `schema` compare equal if their elements compare equal, and values of type function or `builtin_function_or_method` are equal only to themselves. - -```bnf -dict # equal contents -schema # equal exported-attributes -function # identity -builtin_function_or_method # identity -``` - -#### Arithmetic Operations - -The following table summarizes the binary arithmetic operations available for built-in types: - -```bnf -Arithmetic (int or float; result has type float unless both operands have type int) - number + number # addition - number - number # subtraction - number * number # multiplication - number / number # real division (result is always a float) - number // number # floored division - number % number # remainder of floored division - number ^ number # bitwise XOR - number << number # bitwise left shift - number >> number # bitwise right shift - -Concatenation - string + string - list + list - -Repetition (string/list) - int * sequence - sequence * int - -Union - int | int - list | list - dict | dict - schema | schema - schema | dict -basictype | basictype -``` - -The operands of the arithmetic operators `+`, `-`, `*`, `//`, and `%` must both be numbers (`int` or `float`) but need not have the same type. The type of the result has type `int` only if both operands have that type. The result of real division / always has type `float`. - -The `+` operator may be applied to non-numeric operands of the same type, such as two lists, or two strings, in which case it computes the concatenation of the two operands and yields a new value of the same type. - -```python -"Hello, " + "world" # "Hello, world" -[1, 2] + [3, 4] # [1, 2, 3, 4] -``` - -The `*` operator may be applied to an integer n and a value of type `string`, `list`, in which case it yields a new value of the same sequence type consisting of n repetitions of the original sequence. The order of the operands is immaterial. Negative values of n behave like zero. - -```python -'mur' * 2 # 'murmur' -3 * range(3) # [0, 1, 2, 0, 1, 2, 0, 1, 2] -``` - -The `&` operator requires two operands of the same type, such as `int`. For integers, it yields the bitwise intersection (AND) of its operands. - -The `|` operator likewise computes bitwise, unions basic types and unions collection and schema data, such as **list**, **dict** and **schema**. - -Computing bitwise examples: - -```python -0x12345678 | 0xFF # 0x123456FF -``` - -Unioning basic types examples: - -```python -schema x: - a: int | str # attribute a could be a int or string -``` - -A union type is used to define a schema attribute type. See more details in **schema** spec. -Supported types in a union type are `int`, `str`, `float`, `bool`, `list` and `dict`. - -Unioning collection and schema data: - -- Unioning List. Overwrite the list expression on the right side of the operator `|` to the list variable on the left side of the operator one by one according to the **index**. - -```python -_a = [1, 2, 3] -_b = [4, 5, 6, 7] -x = _a | _b # [4, 5, 6, 7] 4 -> 1; 5 -> 2; 6 -> 3; 7 -> None -``` - -Unioning to the specific index or all elements is still under discussion. - -- Unioning Dict. Union the dict expression on the right side of the operator `|` one by one to the dict variable on the left side of the operator according to the **key** - -```python -_a = {key1 = "value1"} -_b = {key1 = "overwrite", key2 = "value2"} -_c = _a | _b # {"key1": "overwrite", "key2": "value2"} -``` - -The union of collection and schema is a new one whose attributes are unioning b to a, preserving the order of the attributes of the operands, left before right. - -Unioning to the specific key or all keys is still under discussion. - -- Unioning Schema. - -The union operation for schema is similar to dict. - -Schema union could be done as: - -```bnf -schema Person: - firstName: str - lastName: str - -_a = Person { - firstName = "John" -} -_b = {lastName = "Doe"} -_a = _a | _b # {"firstName": "John", "lastName": "Doe"} -``` - -Unioning to a specific attribute is still under discussion. Unioning to all attributes is not applicable to schema instances. - -See **selector expression** in **expression** spec for more details. - -The `^` operator accepts operands of `int`. For integers, it yields the bitwise XOR (exclusive OR) of its operands. - -The `<<` and `>>` operators require operands of `int` type both. They shift the first operand to the left or right by the number of bits given by the second operand. It is a dynamic error if the second operand is negative. Implementations may impose a limit on the second operand of a left shift. - -```python -0x12345678 & 0xFF # 0x00000078 -0b01011101 ^ 0b110101101 # 0b111110000 -0b01011101 >> 2 # 0b010111 -0b01011101 << 2 # 0b0101110100 -``` - -#### Membership Tests - -Usage: - -```bnf - any in sequence (list, dict, schema, string) - any not in sequence -``` - -The `in` operator reports whether its first operand is a member of its second operand, which must be a list, dict, schema, or string. The `not in` operator is its negation. Both return a Boolean. - -The meaning of membership varies by the type of the second operand: the members of a list are its elements; the members of a dict are its keys; the members of a string are all its substrings. - -```python -1 in [1, 2, 3] # True - -d = {"one" = 1, "two" = 2} -"one" in d # True -"three" in d # False -1 in d # False -[] in d # False - -"nasty" in "dynasty" # True -"a" in "banana" # True -"f" not in "way" # True - -d = data {one = 1, two = 2} # data is a schema with attributes one and two -"one" in d # True -"three" in d # False -``` - -### Function Invocations - -KCL allows calling built-in functions and functions from built-in and system modules. Whether KCL allows defining new functions is under discussion. - -Syntax: - -```bnf -call_suffix: "(" [arguments [","]] ")" -arguments: argument ("," argument)* -argument: test | identifier "=" test | "*" test | "**" test -``` - -To call a function, the basic way is shown as the following code excerpt: - -```python -print("An argument") - -import math -# 2 powers 3 is 8. -a = math.pow(2, 3) -``` - -As you can see, arguments are separated with `,`. Arguments can only be passed in this way. KCL supports positional arguments and key-value arguments. - -Note that: - -- Some functions have parameters with default values. -- Some functions accept variadic arguments. - -When an argument is not supplied for a parameter without a default value, -an error will be reported. - -### Selector Expressions - -A selector expression selects the attribute or method of the value. - -#### Select Attributes - -Syntax: - -```bnf -select_suffix: ["?"] "." identifier -``` - -KCL provides a wealth of ways to identify or filter attributes. - -x.y - -- schema: it denotes the attribute value of a schema `x` identified by `y` -- package: it denotes the identifier of a package `x` identified by `y` - -Examples: - -```python -schema Person: - name: str - age: int - -person = Person { - name = "Alice" - age = 18 -} -name = person.name # "Alice" -age = person.age # 18 -``` - -x?.y - -If the x if None/Undefined or empty(empty list or dict), just return None, otherwise behave as x.y. - -Examples - -```python -noneData = None -data?.name # None - -emptyDict = {} -emptyDict?.name # None - -emptyList = [] -emptyList?[0] # None -``` - -As a supplementary of the `selector` expression in KCL code, the KCL compiler needs to provide corresponding identifying and filtering features through the command line and api form. - -#### Select Methods - -Syntax: - -```bnf -select_suffix: "." identifier -``` - -A `identifier` identifies method belongs to the built-in types `string`, `list`, `dict`, and `schema`. - -- A selector expression fails if the value does not have an attribute of the specified name. -- A selector expression that selects a method typically appears within a call expression, as in these examples: - -Examples: - -```python -["able", "baker", "charlie"].index("baker") # 1 -"banana".count("a") # 3 -"banana".reverse() # error: string has no .reverse field or method -Person.instances() # all instances of schema Person -``` - -But when not called immediately, the selector expression evaluates to a bound method, that is, a method coupled to a specific receiver value. A bound method can be called like an ordinary function, without a receiver argument: - -```bnf -f = "banana".count -f # -f("a") # 3 -f("n") # 2 -``` - -### Index Expressions - -An index expression `a[i]` yields the `i` th element of an indexable type such as a string or list. The index `i` must be an `int` value in the range `-n` ≤ `i` < `n`, where `n` is `len(a)`; any other index results in an error. - -Syntax: - -```bnf -subscript_suffix: "[" [test] "]" -``` - -A valid negative index `i` behaves like the non-negative index `n+i`, allowing for convenient indexing relative to the end of the sequence. - -```python -"abc"[0] # "a" -"abc"[1] # "b" -"abc"[-1] # "c" - -["zero", "one", "two"][0] # "zero" -["zero", "one", "two"][1] # "one" -["zero", "one", "two"][-1] # "two" -``` - -An index expression `d[key]` may also be applied to a dictionary `d`, to obtain the value associated with the specified key. It returns `Undefined` if the dictionary contains no such key. - -An index expression appearing on the left side of an assignment causes the specified list or dictionary element to be updated: - -```python -a = range(3) # a == [0, 1, 2] -b = a[2] # 2 -``` - -It is a dynamic error to attempt to update an element of an immutable type, such as a list or string, or a frozen value of a mutable type. - -### Slice Expressions - -A slice expression `a[start:stop:stride]` yields a new value containing a sub-sequence of `a`, which must be a string, or list. - -```bnf -subscript_suffix: "[" [test] [":" [test] [":" [test]]] "]" -``` - -Each of the `start`, `stop`, and `stride` operands is optional; if present, and not `None`, each must be an integer. -The `stride` value defaults to 1. If the stride is not specified, the colon preceding it may be omitted too. It is an error to specify a stride of zero. - -Conceptually, these operands specify a sequence of values `i` starting at start and successively adding `stride` until `i` reaches or passes `stop`. The result consists of the concatenation of values of `a[i]` for which `i` is valid.` - -The effective start and stop indices are computed from the three operands as follows. Let `n` be the length of the sequence. - -**If the stride is positive**: If the `start` operand was omitted, it defaults to -infinity. If the `end` operand was omitted, it defaults to +infinity. For either operand, if a negative value was supplied, `n` is added to it. The `start` and `end` values are then "clamped" to the nearest value in the range 0 to `n`, inclusive. - -**If the stride is negative**: If the `start` operand was omitted, it defaults to +infinity. If the `end` operand was omitted, it defaults to -infinity. For either operand, if a negative value was supplied, `n` is added to it. The `start` and `end` values are then "clamped" to the nearest value in the range -1 to `n`-1, inclusive. - -```python -"abc"[1:] # "bc" (remove first element) -"abc"[:-1] # "ab" (remove last element) -"abc"[1:-1] # "b" (remove first and last element) -"banana"[1::2] # "aaa" (select alternate elements starting at index 1) -"banana"[4::-2] # "nnb" (select alternate elements in reverse, starting at index 4) -``` - -It's not allowed to define a slice expression as a left value in KCL. -Cause list and string are immutable, re-slicing can directly operate to operand to ensure better performance. - -#### Quantifier Expressions - -Quantifier expressions act on collection: list or dict, generally used to obtain a certain result after processing the collection, mainly in the following four forms: - -```bnf -quant_expr: quant_op [ identifier ',' ] identifier 'in' quant_target '{' expr ['if' expr] '}' -quant_target: string | identifier | list_expr |list_comp | dict_expr | dict_comp -quant_op: 'all' | 'any' | 'filter' | 'map' -``` - -- **all** - - Used to detect that all elements in the collection satisfy the given logical expression, and return a boolean value as the result. - - Only when all elements in the collection satisfy the expression true, the `all` expression is true, otherwise it is false. - - If the original collection is empty, return true. - - Supports short-circuiting of logical expressions during expression execution. -- **any** - - Used to detect that at least one element in the collection satisfies the given logical expression, and returns a boolean value as the result. - - When at least one element in the collection satisfies the expression true, the `any` expression is true, otherwise it is false. - - If the original collection is empty, return false. - - Supports short-circuiting of logical expressions during expression execution. -- **map** - - Generate a new **list** by mapping the elements in the original collection. - - The length of the new list is exactly the same as the original collection. -- **filter** - - By logically judging and filtering the elements in the original collection, and returning the filtered sub-collection. - - Only when the element judges the expression to be true, it is added to the sub-collection. - - The type (list, dict and schema) of the new collection is exactly the same as the original collection, and the length range is `[0, len(original-collection)]`. - -**all** and **any** expression sample codes: - -```python -schema Config: - volumes: [{str:}] - services: [{str:}] - - check: - all service in services { - service.clusterIP == "NONE" if service.type == "ClusterIP" - }, "invalid cluster ip" - - any volume in volumes { - volume.mountPath in ["/home/admin", "/home/myapp"] - } -``` - -**map** and **filter** expression sample codes: - -```python -a = map e in [{name = "1", value = 1}, {name = "2", value = 2}] { - {name = e.name, value = int(e.value) ** 2} -} # [{"name": "1", value: 1}, {"name": "2", "value": 4}] - -b = map k, v in {a = "foo", b = "bar"} { v } # ["foo", "bar"] - -c = filter e in [{name = "1", value = 1}, {name = "2", value = 2}] { - int(e.value) > 1 -} # [{"name": "2", "value": 2}] - -d = filter _, v in {a = "foo", b = "bar"} { - v == "foo" -} # {"a": "foo"} -``` - -Please pay attention to distinguish the difference between any expression and any type. When `any` is used in type annotations, it means that the value of the variable is arbitrary, while the any expression means that one of the elements in a set satisfies the condition. diff --git a/versioned_docs/version-0.8.0/reference/lang/spec/index.md b/versioned_docs/version-0.8.0/reference/lang/spec/index.md deleted file mode 100644 index 88bbaa59..00000000 --- a/versioned_docs/version-0.8.0/reference/lang/spec/index.md +++ /dev/null @@ -1 +0,0 @@ -# KCL Spec diff --git a/versioned_docs/version-0.8.0/reference/lang/spec/lexical.md b/versioned_docs/version-0.8.0/reference/lang/spec/lexical.md deleted file mode 100644 index 8c85ee7b..00000000 --- a/versioned_docs/version-0.8.0/reference/lang/spec/lexical.md +++ /dev/null @@ -1,213 +0,0 @@ ---- -title: "Lexical" -linkTitle: "Lexical" -type: "docs" -weight: 2 -description: Lexical ---- - -## Lexical Conventions - -This chapter covers the KCL lexical conventions including grammar notation, lines, comments and tokens. - -## Grammar Notation - -The syntax is specified using Extended Backus-Naur Form (EBNF), porting to lark parser ([https://github.com/lark-parser/lark](https://github.com/lark-parser/lark)). - -``` -- name grammar production -- NAME lexical token -- "x" lexical token -- () grouping -- | alternation -- [] option (0 or 1 times) -- ? option (0 or 1 times) -- * repetition (0 to n times) -- + repetition (1 to n times) -``` - -## Source File Encoding - -KCL source code is Unicode text encoded in **UTF-8**. - -The following are basic Unicode elements, which will be used in literal notations. - -``` -newline ::= U+000A -quota ::= singlequote | doublequote -singlequote ::= U+0027 -doublequote ::= U+0022 -source character ::= Unicode code point -``` - -The form a...b in literal notations represents the set of characters from a through b. - -## Line Structure - -The line structure of KCL programs is equivalent to that of Python. - -A KCL program is divided into a number of logical lines. Each logical line consists of one or more physical lines. - -A token named `NEWLINE` is used to divide logical lines. - -A physical line is a sequence of characters end with a line termination sequence, which can be the ASCII LF (linefeed) character, the ASCII sequence CR LF (return followed by linefeed), or the ASCII CR (return) character. - -### Explicit Line Joining - -To join multiple physical lines into one logical line, the `\` character can be used. The character should be the last none-space character in each physical line except the very last line. - -> **note** -> -> Any character except the ASCII space, tab (`\t`) and formfeed (`\f`) is considered a none-space character. - -- A line ending in a backslash cannot carry a comment (, which will be introduced shortly afterwards). -- A backslash does not continue a comment. -- A backslash does not continue a token except for string literals (i.e., tokens other than string literals cannot be split across physical lines using a backslash). -- A backslash is illegal elsewhere on a line outside a string literal. - -### Implicit Line Joining - -Expressions in parentheses, square brackets or curly braces can be split over more than one physical line without using backslashes. - -- Implicitly continued lines can carry comments. -- The indentation of the continuation lines is not important. -- Blank continuation lines are allowed. -- There is no `NEWLINE` token between implicit continuation lines. -- Implicitly continued lines can also occur within triple-quoted strings (see below); in that case they cannot carry comments. - -### Blank Lines - -### Indentation - -### Comments - -Starting with a `#` character that is not part of a string literal is a comment. A comment ends at the end of the physical line. - -A comment signifies the end of the logical line unless the implicit line joining rules are invoked. - -Comments are ignored by the syntax. - -### Identifiers and Keywords - -Identifiers (also referred to as names) are described by the following lexical definitions. - -Within the ASCII range (from `U+0001` to `U+007F`), the valid characters for identifiers are the uppercase and lowercase letters `A` through `Z`, the underscore `_` and, except for the first character, the digits `0` through `9`. - -Identifiers are unlimited in length. The case is significant. - -### Keywords - -The following identifiers are used as reserved words, or keywords of the language, and cannot be used as ordinary identifiers. They must be spelled exactly as written here: - -``` -True False None Undefined import -and or in is not -as if else elif for -schema mixin protocol check assert -all any map filter lambda -rule -``` - -The following tokens are not used, but they are reserved as possible future keywords: - -``` -pass return validate rule flow -def del raise except try -finally while from with yield -global nonlocal struct class final -``` - -### Literals - -Literals are notations for constant values of some built-in types. - -### String Literals - -String literals are described by the following lexical definitions: - -``` -stringliteral ::= [stringprefix](shortstring | longstring) -stringprefix ::= "r" | "R" -shortstring ::= "'" shortstringitem* "'" | '"' shortstringitem* '"' -longstring ::= "'''" longstringitem* "'''" | '"""' longstringitem* '"""' -shortstringitem ::= shortstringchar | stringescapeseq -longstringitem ::= longstringchar | stringescapeseq -shortstringchar ::= -longstringchar ::= -stringescapeseq ::= "\" -``` - -Multiple adjacent string or bytes literals (delimited by whitespace),possibly using different quoting conventions, are allowed, and their meaning is the same as their concatenation. - -### Numeric Literals - -There are two types of numeric literals: integers and floating-point numbers. - -Integer literals are described by the following lexical definitions: - -``` -integer ::= decinteger | bininteger | octinteger | hexinteger -decinteger ::= nonzerodigit (["_"] digit)* | "0"+ (["_"] "0")* -bininteger ::= "0" ("b" | "B") (["_"] bindigit)+ -octinteger ::= "0" ("o" | "O") (["_"] octdigit)+ -hexinteger ::= "0" ("x" | "X") (["_"] hexdigit)+ -nonzerodigit ::= "1"..."9" -digit ::= "0"..."9" -bindigit ::= "0" | "1" -octdigit ::= "0"..."7" -hexdigit ::= digit | "a"..."f" | "A"..."F" -``` - -Floating-point literals are described by the following lexical definitions: - -``` -floatnumber ::= pointfloat | exponentfloat -pointfloat ::= [digitpart] fraction | digitpart "." -exponentfloat ::= (digitpart | pointfloat) exponent -digitpart ::= digit (["_"] digit)* -fraction ::= "." digitpart -exponent ::= ("e" | "E") ["+" | "-"] digitpart -``` - -## Operators and Delimiters - -### Operators - -The following tokens are operators: - -```python -+ - * ** / // % -<< >> & | ^ < > -~ <= >= == != @ -``` - -### Delimiters - -The following tokens serve as delimiters in the grammar: - -```python -( ) [ ] { } -, : . ; = += --= *= **= /= //= %= -<<= >>= &= |= ^= -``` - -The period can also occur in floating-point literals. - -The following printing ASCII characters have special meaning as part of other tokens or are otherwise significant to the lexical analyzer: - -``` -' " # \ -``` - -The following printing ASCII characters are not used in KCL. Their occurrence outside string literals and comments is an unconditional error: - -``` -? ` -``` - -## Reference - -Since the lexical conventions of KCL is very similar to that of Python, we use the following document as the reference when writing this chapter. - -- [https://docs.python.org/3/reference/lexical_analysis.html](https://docs.python.org/3/reference/lexical_analysis.html) diff --git a/versioned_docs/version-0.8.0/reference/lang/spec/variables.md b/versioned_docs/version-0.8.0/reference/lang/spec/variables.md deleted file mode 100644 index b3e1c539..00000000 --- a/versioned_docs/version-0.8.0/reference/lang/spec/variables.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: "Variables" -linkTitle: "Variable" -type: "docs" -weight: 2 -description: Variable ---- - -In KCL, variables can be defined using assign statements. For example, the following statement defines a variable `spam` to a string `"ham"`. - -```python -spam = "ham" -``` - -There are two types of variables, which are global variables and list comprehension local variables. - -- A global variable is defined not within any context. -- A comprehension local variable is defined inside a comprehension. - -A variable can be used after definition, until the end of the current scope. - -For a global variable, the scope is the module it is defined in. Note that a module can consists of multiple source files. - -For a list comprehension local variable, the scope is the list comprehension it is defined in. - -More information on modules, list comprehensions and scopes will be discussed in later chapters. - -## Immutability - -Global variables are immutable. In other words, once defined such a variable cannot be redefined (or, i.e., modified). - -The following code is illegal, and KCL will report an error during evaluation. - -```python -spam = "ham" -spam = "eggs" # Error: The immutability rule is violated! -``` - -- A variable starts with the `_` character is mutable. - -```python -_spam -cond = True -if cond: - _spam = "ham" -else: - _spam = "eggs" -``` - -## Variable Exporting - -As shown in the preview chapter, KCL is able to export evaluation results to the standard output according to a target data format. - -The rules are the followings: - -- Living global variables at the end of an evaluation will be dumped out. -- If the name of a variable starts with the `_` character, it will not be dumped out. - -## Uniqueness of Exported Variable Identifier - -Each exported variable identifier must be unique in its package, so that an exported variable could be located uniquely by package location path and variable identifier, such as 'a.b.c:var', in which 'a.b.c' locates a package. - -Two variable identifiers are different if: - -- they are spelled differently -- they are defined in different packages and are not compiled in a single execution - -Identifying an exported variable should be supported by the kcl compiler, which needs to provide corresponding identifying features through the command line and api form. diff --git a/versioned_docs/version-0.8.0/reference/lang/types/_category_.json b/versioned_docs/version-0.8.0/reference/lang/types/_category_.json deleted file mode 100644 index 8b257445..00000000 --- a/versioned_docs/version-0.8.0/reference/lang/types/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Types", - "position": 4 -} diff --git a/versioned_docs/version-0.8.0/reference/lang/types/types.md b/versioned_docs/version-0.8.0/reference/lang/types/types.md deleted file mode 100644 index ee88c64d..00000000 --- a/versioned_docs/version-0.8.0/reference/lang/types/types.md +++ /dev/null @@ -1,1381 +0,0 @@ -# Type System - -This document describes the type system of KCL, including: - -- Type rules -- Type checking -- Type conversion -- Type inference - -## Type Rules - -### Basic Definition - -#### Assertion - -All free variables of $S$ are defined in $\Gamma$ - -$$ -\Gamma \vdash S -$$ - -$\Gamma$ is a variable's well-formed environment, such as $x_1:T_1$, ..., $x_n:T_n$ - -The assertion of $S$ has three forms: - -**Environment assertion** indicates that $\Gamma$ is a well-formed type. - -$$ -\Gamma \vdash ◇ -$$ - -**Well-formed type assertion**. In the environment $\Gamma$, $nat$ is a type expression. - -$$ -\Gamma \vdash nat -$$ - -**Typing judgment assertion**. In the environment $\Gamma$,$E$ has the type $T$. - -$$ -\Gamma \vdash E: T -$$ - -#### Inference Rules - -Representation - -$$ -\frac{\Gamma \vdash S_1, ..., \Gamma \vdash S_n}{\Gamma \vdash S} -$$ - -In the inference rules, $u$, $v$, and $w$ are used to represent variables, $i$, $j$, $k$ are used to represent integers, $a$ and $b$ are used to represent floating point numbers, $s$ is used to represent strings, $c$ is used to represent literal values of constants (integers, floating point numbers, strings, boolean), $f$ is used to represent functions, $T$, $S$, $U$ are used to represent types. - -## Environment Rules - -Env ⌀ - -$$ -\frac{}{⌀ \vdash ◇ } -$$ - -## Type Definitions - -Type Bool - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash boolean} -$$ - -Type Int - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash integer} -$$ - -Type Float - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash float} -$$ - -Type String - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash string} -$$ - -Type Literal - -$$ -\frac{ c \in \{boolean, integer, float, string\}}{\Gamma \vdash literalof(c)} -$$ - -Type List - -$$ -\frac{\Gamma \vdash T \ T \neq Void}{\Gamma \vdash listof(T) } -$$ - -Type Dict - -$$ -\frac{\Gamma \vdash T_1 \ \Gamma \vdash T_2\ T_1 \neq Void \ \ T_2 \neq Void}{\Gamma \vdash dictof(T_k=T_1, T_v=T_2)} -$$ - -Type Struct - -$$ -\frac{\Gamma \vdash T_{1} \ ... \ \Gamma \vdash T_{n} \ \ T_i \neq Void \ K_1 \neq K_n}{\Gamma \vdash structof(K_1 : T_{1}, ... , K_n : T_{n})} -$$ - -Type Union - -$$ -\frac{\Gamma \vdash T_1 \ ... \ \Gamma \vdash T_n \ \ T_i \neq Void}{\Gamma \vdash unionof(T_1, ..., T_n)} -$$ - -Type None - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash None} -$$ - -Type Undefined - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Undefined} -$$ - -Type Void - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Void} -$$ - -Type Any - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Any} -$$ - -Type Nothing - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash Nothing} -$$ - -## Typing Judgment Rules - -### Operand Expr - -Exp Truth - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash true: boolean} -$$ - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash false: boolean} -$$ - -Exp Int - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash int: integer} -$$ - -Exp Flt - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash flt: float} -$$ - -Exp Str - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash str: string} -$$ - -Exp None - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash none: none} -$$ - -Exp Undefined - -$$ -\frac{\Gamma \vdash ◇}{\Gamma \vdash undefined: undefined} -$$ - -Expr ListExp - -$$ -\frac{\Gamma \vdash E_1: T_1 \ E_2: T_2 \ ... \ E_n: T_n}{\Gamma \vdash [E_1, E_2, ..., E_n]: listof \ sup(T_1, T_2, ..., T_n)} -$$ - -Expr ListComp - -$$ -\frac{\Gamma \vdash E_1: T_1 \ \Gamma \vdash v: T \ \Gamma \vdash E_2: listof \ T \ \Gamma \vdash E_3: boolean}{\Gamma \vdash [E_1 \ for \ v \ in \ E_2 \ if \ E_3]: listof(T_1) } -$$ - -Expr DictExp - -$$ -\frac{\Gamma \vdash E_{k1}: T_{k1} \ \Gamma \vdash E_{v1}: T_{v1} \ ... \ \Gamma \vdash E_{kn}: T_{kN} \ \Gamma \vdash E_{vn}: T_{vN}}{\Gamma \vdash \{E_{k1}: E_{v1}, ..., E_{{kn}}: E_{vn}\}: dictof(T_{k}=sup(T_{k1}, T_{k2}, ... T_{kn}), \ T_{v}=sup(T_{v1}, T_{v2}, ..., T_{vn}))} -$$ - -Expr DictComp - -$$ -\frac{\Gamma \vdash E_1: T_{rki} \ \Gamma \vdash E_2: T_{rvi} \ \Gamma \vdash v_1: T_k \ \Gamma \vdash v_2: T_v \ \Gamma \vdash E_3: dictof(T_{k}, \ T_{v}) \ \Gamma \vdash E_4: boolean}{\Gamma \vdash \{E_1:E_2 \ for \ (v_1, v_2) \ in \ E_3 \ if \ E_4\}: dictof(T_{k}=sup(T_{rk1}, T_{rk2}, ..., T_{rkn}), T_{v}=sup(T_{rv1}, T_{rv2}, ..., T_{rvn})) } -$$ - -Expr StructExpr - -$$ -\frac{\Gamma \vdash E_{1}: T_{1} \ ... \ \Gamma \vdash E_{n}: T_{n} \ K_1 \neq K_n}{\Gamma \vdash \{K_{1} = E_{1}, ..., K_{{n}} = E_{n}\}: structof(K_1 : T_{1}, ... , K_n : T_{n})} -$$ - -The literal type is the value type of basic type, the union type is the combination type of types, void, any, nothing are special type references, and there is no direct value expression correspondence. - -### Primary Expr - -Expr Index - -$$ -\frac{\Gamma \vdash E: listof(T) \ \Gamma \vdash Index: integer}{\Gamma \vdash E[Index]: T} -$$ - -Expr Call - -$$ -\frac{\Gamma \vdash E_1: T_1 \rightarrow T_2 \ \Gamma \vdash E_2: T_1}{\Gamma \vdash E_1 \ (E_2): T_2} -$$ - -Expr List Selector - -$$ -\frac{\Gamma \vdash E: listof(T) \ \Gamma \vdash Index: integer}{\Gamma \vdash E.[Index]: T} -$$ - -Expr Dict Selector - -$$ -\frac{\Gamma \vdash E: dictof(T_k = T_1, T_v=T_2) \ \Gamma \vdash S_1: string \ ... \ \Gamma \vdash S_n: string}{\Gamma \vdash E.\{S_1, ..., S_n\}: dictof(T_k = T_1, T_v=T_2)} -$$ - -Expr Struct Selector - -$$ -\frac{\Gamma \vdash E: structof(K_1 : T_{1}, ... , K_n : T_{n}) \ \Gamma \vdash K_i: string}{\Gamma \vdash E.K_i: T_{i}} -$$ - -### Unary Expr - -Expr + - -$$ -\frac{\Gamma \vdash E: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash \ +E: T} -$$ - -Expr - - -$$ -\frac{\Gamma \vdash E: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash \ -E: T} -$$ - -Expr ~ - -$$ -\frac{\Gamma \vdash E: integer}{\Gamma \vdash \ ~E: integer} -$$ - -Expr not - -$$ -\frac{\Gamma \vdash E: boolean}{\Gamma \vdash \ not \ E: boolean} -$$ - -### Binary Expr - -Expr op, op $\in$ {-, /, %, \*\*, //} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, float\}}{\Gamma \vdash E_1 \ op \ E_2: T} -$$ - -Expr + - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, float, string, listof(T_1)\}}{\Gamma \vdash E_1 \ + \ E_2: T} -$$ - -Expr \* - -$$ -\frac{\Gamma \vdash E_1: T_1 \ \ \ \Gamma \vdash E_2: T_2 \ \ \ \ (T_1==T_2 \in \{integer, float\}) \ or \ (T_1 == interger \ and \ T_2 \ \in \ \{string, listof(T_3)\}) \ or \ (T_2 == interger \ and \ T_1 \ \in \ \{string, listof(T_3)\})} {\Gamma \vdash E_1 \ * \ E_2: T} -$$ - -Expr % - -$$ -\frac{\Gamma \vdash E_1: interger \ \ \ \Gamma \vdash E_2: integer}{\Gamma \vdash E_1 \ \% \ E_2: interger} -$$ - -Expr op, op $\in$ \{or, and\} - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ op \ E_2: boolean} -$$ - -示例 - -Expr and - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ and \ E_2: boolean} -$$ - -Expr op, op $\in$ \{==, !=, <, >, <=, >=\} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T}{\Gamma \vdash E_1 \ op \ E_2: boolean} -$$ - -Expr > - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: boolean}{\Gamma \vdash E_1 \ > \ E_2: boolean} -$$ - -Expr op, op $\in$ {&, ^, ~, <<, >>} - -$$ -\frac{\Gamma \vdash E_1: integer \ \ \ \Gamma \vdash E_2: integer}{\Gamma \vdash E_1 \ op \ E_2: integer} -$$ - -Expr | - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{integer, listof(T_1), dictof(T_k, T_v), structof(K_1=T_1, ..., K_n=T_n)\}}{\Gamma \vdash E_1 \ | \ E_2: T} -$$ - -Expr op, op $\in$ {in, not in} - -$$ -\frac{\Gamma \vdash E_1: string \ \ \ \Gamma \vdash E_2: T \ \ \ T \in \{dictof, structof\}}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: listof(S), T \sqsubseteq S}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -Expr op $\in$ {is, is not} - -$$ -\frac{\Gamma \vdash E_1: T \ \ \ \Gamma \vdash E_2: T}{\Gamma \vdash E_1 \ op \ E_2: bool} -$$ - -### IF Expr - -Expr If - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash E_2: T \ \ \ \Gamma \vdash E_3: T}{\Gamma \vdash if \ E_1 \ then \ E_2 \ else \ E_3: T} -$$ - -### Stmt - -Stmt If - -$$ -\frac{\Gamma \vdash E_1: boolean \ \ \ \Gamma \vdash S_1: Void \ \ \ \Gamma \vdash S_2: Void}{\Gamma \vdash if \ E_1 \ then \ S_1 \ else \ S_2: Void} -$$ - -Stmt Assign - -$$ -\frac{\Gamma \vdash id: T_0 \ \ \ \Gamma \vdash T_1 \ \ \ \Gamma \vdash E: T_2}{\Gamma \vdash id: T_1 \ = \ E : Void} -$$ - -Type Alias - -$$ -\frac{\Gamma \vdash id: T_0 \ \ \ \Gamma \vdash T_1}{\Gamma \vdash type \ id \ = \ T_1 : Void} -$$ - -## Union - -List Union - -$$ -\frac{\Gamma \vdash \ listof(T) \ \ \ \Gamma \vdash \ listof(S)}{\Gamma \vdash \ listof(unionof(T, S))} -$$ - -Dict Union - -$$ -\frac{\Gamma \vdash \ dictof(T_1, T_2) \ \ \ \Gamma \vdash \ dictof(S_1, S_2)}{\Gamma \vdash \ dictof(unionof(T_1, S_1), unionof(T_2, S_2))} -$$ - -Struct Union - -Define two structures: $structof(K_{1}: T_{1}, ..., K_{n}: T_{n}),structof(H_{1}: S_{1}, ..., H_{m}: S_{n})$ - -Define their union types: - -$$ -structof(J_{1}: U_{1}, ..., J_{p}: U_{n}) = structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \bigcup structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) -$$ - -Example - -$$ -structof() \ \bigcup \ structof(H_{1}: T_{1}, ..., H_{m}: T_{n}) = structof(H_{1}: T_{1}, ..., H_{m}: T_{n}) -$$ - -$$ -structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \ \bigcup \ structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) = structof(K_1: T_1) :: (structof(K_{2}: T_{2}, ..., K_{n}: T_{n}) \ \bigcup \ structof(H_{1}: S_{1}, ..., H_{m}: S_{n})) -$$ - -where "::" denotes the operation of adding a dual to a structure, which is defined as follows: - -$$ -structof(K_{1}: T_{1}) :: structof() = structof(K_{1}: T_{1}) -$$ - -$$ -structof(K_{1}: T_{1}) :: structof(K_{1}: T_{1}', ..., K_n: T_{n}) = structof(K_{1}: union\_op(T_{1}, T_{1}'), ..., K_{n}: T_{n}) -$$ - -$$ -structof(K_{1}: T_{1}) :: structof(K_{2}: T_{2}, ..., K_n: T_{n}) = structof(K_{2}: T_2) :: structof(K_{1}: T_1) :: structof(K_{3}: T_3, ..., K_{n}: T_{n}) -$$ - -Based on this, the union of two structures is defined as: - -$$ -\frac{\Gamma \vdash structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \ \Gamma \vdash structof(H_{1}: S_{1}, ..., H_{m}: S_{n}) \ structof(J_{1}: U_{1}, ..., J_{p}: U_{n}) = structof(K_{1}: T_{1}, ..., K_{n}: T_{n}) \bigcup structof(H_{1}: S_{1}, ..., H_{m}: S_{n})}{\Gamma \vdash structof(J_{1}: U_{1}, ..., J_{p}: U_{n}))} -$$ - -where $union\_op(T_1, T_2)$ denotes different types of judgment operations for the same $K_i$. - -- When $T_1$ and $T_2$ have the partial order relation. If $T_1 \sqsubseteq T_2$, return $T_2$, otherwise return $T_1$, which is the minimum upper bound -- When $T_1$ and $T_2$ have no partial order relationship, there are three optional processing logic: - - Structure union failed, return a type error. - - Return the type of the latter $T_2$. - - Return the type $unionof (T_1, T_2)$. - -Here, we need to choose the appropriate processing method according to the actual needs. - -Structure inheritance can be regarded as a special union. The overall logic is similar to that of union, but in $union\_op(T_1, T_2)$ for the same $K_i$, the different types of judgment operations are as follows: - -- When $T_1$ and $T_2$ have the partial order relation and $T_1 \sqsubseteq T_2$, return $T_1$, that is, only if $T_1$ is the lower bound of $T_2$, the lower bound of $T_1$ shall prevail. -- Otherwise, a type error is returned. - -Through such inheritance design, we can achieve hierarchical, bottom-up and layer-by-layer contraction of type definition. - -## Operation - -KCL supports operations on structure attributes in the form of $p op E$. That is, for the given structure $A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})$, the path $p$ in the structure is specified with the value of $E$ (such as union, assign, insert, etc.). - -Define the following update operations: - -$$ -\frac{{\Gamma\vdash A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})}  {\Gamma\vdash p \in (K_{1}, ..., K_{n})} \ {\Gamma\vdash e:T}   k \neq k_1, ..., k \neq k_n} -{ A \{p \ op \ e\}:\{K_1:T_1, ..., K_n:T_n\}∪\{p:T\}} -$$ - -That is to say, the operation on the path $p$ is essentially a union of two structures. The rules for the same name attribute type union depend on the situation. For example, the path $p$ is an identifier $p=k_1$ that can be used as a field name $k_1$, and the field name in structure A is also $k_1$, its type is $T_1$, and the type of the expression $e$ is also $T_1$, then - -$$ -\frac{{\Gamma\vdash A: structof(K_{1}: T_{1}, ..., K_{n}: T_{n})}  {\Gamma\vdash p = K_{1}} \ {\Gamma\vdash e:T_1}   k \neq k_1, ..., k \neq k_n} -{ A \{p \ op \ e\}:\{K_1:T_1, ..., K_n:T_n\}} -$$ - -Note: - -- The type $T_1$ of the expression $e$ have the same type with the original attribute of the same name $K_1$. It can be relaxed appropriately according to the actual situation, such as the type of $e$ $\sqsubseteq T_1$ is enough. -- For the operation of nested multi-layer structures, the above rules can be used recursively. - -## Type Partial Order - -### Basic Types - -$$ -Type \ T \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ T -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Bool \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Int \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Float \sqsubseteq Type \ Any -$$ - -$$ -Type \ Int \sqsubseteq Type \ Float -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ String \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Literal \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ List \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Dict \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Struct \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ None \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Void \sqsubseteq Type \ Any -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Any -$$ - -### Literal Type - -$$ -Type \ Literal(Bool) \sqsubseteq Type \ Bool -$$ - -$$ -Type \ Literal(Int) \sqsubseteq Type \ Int -$$ - -$$ -Type \ Literal(Float) \sqsubseteq Type \ Float -$$ - -$$ -Type \ Literal(String) \sqsubseteq Type \ String -$$ - -### Union Type - -$$ -Type \ X \sqsubseteq Type \ Union(X, Y) -$$ - -### Introspect - -$$ -Type \ X \sqsubseteq Type \ X -$$ - -Example - -$$ -Type \ Bool \sqsubseteq Type \ Bool -$$ - -$$ -Type \ Int \sqsubseteq Type \ Int -$$ - -$$ -Type \ Float \sqsubseteq Type \ Float -$$ - -$$ -Type \ String \sqsubseteq Type \ String -$$ - -$$ -Type \ List \sqsubseteq Type \ List -$$ - -$$ -Type \ Dict \sqsubseteq Type \ Dict -$$ - -$$ -Type \ Struct \sqsubseteq Type \ Struct -$$ - -$$ -Type \ Nothing \sqsubseteq Type \ Nothing -$$ - -$$ -Type \ Any \sqsubseteq Type \ Any -$$ - -$$ -Type \ Union(Type Int, Type Bool) \sqsubseteq Type \ Union(Type Int, Type Bool) -$$ - -### Transmit - -$$ -Type \ X \sqsubseteq Type \ Z \ if \ Type \ X \sqsubseteq Type \ Y \ and \ Type \ Y \sqsubseteq \ Type \ Z -$$ - -### Contained - -$$ -Type \ List(T_1) \sqsubseteq Type \ List(T_2) \ if \ T_1 \sqsubseteq T_2 -$$ - -$$ -Type \ Dict(T_{k1}, T_{v1}) \sqsubseteq Type \ Dict(T_{k2}, T_{v2}) \ if \ T_{k1} \sqsubseteq T_{k2} \ and \ T_{v1} \sqsubseteq T_{v1} -$$ - -$$ -Type \ Structure(K_1: T_{a1}, K_2: T_{a2}, ..., K_n: T_{an}) \sqsubseteq Type \ Structure(K_1: T_{b1}, K_2: T_{b2}, ..., K_n: T_{bn}) \ if \ T_{a1} \sqsubseteq T_{b1} \ and \ T_{a2} \sqsubseteq T_{b2} \ and \ ... \ and \ T_{an} \sqsubseteq T_{bn} -$$ - -### Inheritance - -$$ -Type \ Struct \ A \sqsubseteq Type \ Struct \ B \ if \ A \ inherits \ B -$$ - -### None - -$$ -Type \ None \sqsubseteq Type \ X, X \notin \{Type \ Nothing, \ Type \ Void\} -$$ - -### Undefined - -$$ -Type \ Undefined \sqsubseteq Type \ X, X \notin \{Type \ Nothing, \ Type \ Void\} -$$ - -## Equality - -- Commutative law - -$$ -Type \ Union(X, Y) == Type \ Union(Y, X) -$$ - -Example - -$$ -Type \ Union(Int, Bool) == Type \ Union(Bool, Int) -$$ - -- Associative law - -$$ -Type \ Union(Union(X, Y), Z) == Type \ Union(X, Union(Y, Z)) -$$ - -Example - -$$ -Type \ Union(Union(Int, String), Bool) == Type \ Union(Int, Union(String, Bool)) -$$ - -- Idempotent - -$$ -Type \ Union(X, X) == Type \ X -$$ - -Example - -$$ -Type \ Union(Int, Int) == Type \ Int -$$ - -Partial order derivation - -$$ -Type \ Union(X, Y) == Type \ Y \ if \ X \sqsubseteq Y -$$ - -Example - -Assume that Struct A inherits Struct B - -$$ -Type \ Union(A, B) == Type \ B -$$ - -Idempotency is a special case of partial order reflexivity - -### List - -$$ -Type \ List(X) == Type \ List(Y) \ if \ X == Y -$$ - -### Dict - -$$ -Type \ Dict(T_k, T_v) == Type \ Dict(S_k, S_v) \ if \ T_k == S_k \ and \ T_v == S_v -$$ - -### Struct - -$$ -Type \ Struct(K_1: T_{1}, K_2: T_{2}, ..., K_n: T_{n}) == Type \ Struct(K_1: S_{1}, K_2: S_{2}, ..., K_n: S_{n}) \ if \ T_{1} == S_{1} \ and \ ... \ and \ T_{n} == S_{n} -$$ - -### Partial Order Checking - -$$ -Type \ X == Type \ Y \ if \ Type \ X \sqsubseteq Type \ Y \ and \ Type \ Y \sqsubseteq \ Type \ X -$$ - -## Basic Methods - -- `sup(t1: T, t2: T) -> T`: Calculate the minimum upper bound of two types `t1` and `t2` according to the type partial order. The union type needs to be created dynamically. -- `typeEqual(t1: T, t2: T) -> bool`: Compare whether the two types `t1` and `t2` are equal. -- `typeToString(t: T) -> string`: Resolve and convert the type to the corresponding string type recursively from top to bottom. - -### Sup Function - -- Type parameters, condition types and other characteristics are not considered temporarily. -- Use an ordered collection to store all types of `UnionType`. -- Use a global map to store all generated union types according to the name of `UnionType`. -- Calculate the inclusion relationship between types according to the partial order relationship. - -```go -// The Sup function returns the minimum supremum of all types in an array of types -func Sup(types: T[]) -> T { - typeOf(types, removeSubTypes=true) -} - -// Build a sup type from types [T1, T2, ... , Tn] -func typeOf(types: T[], removeSubTypes: bool = false) -> T { - assert isNotNullOrEmpty(types) - // 1. Initialize an ordered set to store the type array - typeSet: Set[T] = {} - // 2. Add the type array to the ordered set for sorting by the type id and de-duplication - addTypesToTypeSet(typeSet, types) - // 3. Remove sub types according to partial order relation rules e.g. sub schema types - if removeSubTypes { - removeSubTypes(typeSet) - } - if len(typeSet) == 1 { - // If the typeSet has only one type, return it - return typeSet[0] - } - // 4. Get or set the union type from the global union type map - id := getIdentifierFromTypeSet(typeSet) - unionType := globalUnionTypeMap.get(id) - if !unionType { - unionType = createUnionType(typeSet) // Build a new union type - globalUnionTypeMap.set(id, unionType) - } - return unionType -} - -// Add many types into the type set -func addTypesToTypeSet(typeSet: Set[T], types: T[]) -> void { - for type in types { - addTypeToTypeSet(typeSet, type) - } -} - -// Add one type into the type set -func addTypeToTypeSet(typeSet: Set[T], type: T) -> void { - if isUnion(type) { - return addTypesToTypeSet(typeSet, toUnionOf(type).types) - } - // Ignore the void type check - if !isVoid(type) { - // De-duplication according to the type of id - typeSet.add(type) - } -} - -func removeSubTypes(types: Set[T]) -> void { - for source in types { - for target in types { - if !typeEqual(source, target) { - // If the two types have an inheritance relationship, the base class is retained, or if the two types have a partial order relationship according to the relation table. - if (isPartialOrderRelatedTo(source, target)) { - types.remove(source) - } - } - } - } -} - -// isPartialOrderRelatedTo function Determine whether two types have a partial order relationship `source \sqsubseteq target` -// according to the partial order relationship table and rules -func isPartialOrderRelatedTo(source: T, target: T) -> bool { - assert isNotNullOrEmpty(source) - assert isNotNullOrEmpty(target) - if isNoneOrUndefined(source) and !isNothing(target) and !isVoid(target) { - return true - } - if isAny(target) { - return true - } - if typeEqual(source, target) { - return true - } - if isUnion(target) and source in target.types { - return true - } - // Literal Type - if (isStringLiteral(source) and isString(target)) or \ - (isBooleanLiteral(source) and isBool(target)) or \ - (isIntLiteral(source) and isInt(target)) or \ - (isFloatLiteral(source) and isFloat(target)) { - return true - } - if isInt(source) and isFloat(target) { - return true - } - if isList(source) and isList(target) { - return isPartialOrderRelatedTo(toListOf(source).eleType, toListOf(target).eleType - } - if isDict(source) and isDict(target) { - return isPartialOrderRelatedTo(toDictOf(source).keyType, toDictOf(target).keyType) and isPartialOrderRelatedTo(toDictOf(source).valueType, toDictOf(target).valueType) - } - if isStruct(source) and isStruct(target) { - if isTypeDerivedFrom(source, target) { - return true - } - // Empty Object - if len(target.keys) == 0 { - return true - } - if any([key Not in source.keys for key in target.keys]) { - return false - } - for key, sourceType in (source.keys, source.types) { - targetType = getKeyType(target, key) ? getKeyType(target, key) : anyTypeOf() - if !isPartialOrderRelatedTo(sourceType, targetType) { - return false - } - } - return true - } - return false -} -``` - -## Type Checking - -### Checker - -The type checker traverses the syntax tree from top to bottom through syntax-directed translation, and determines whether the program structure is a well-typed program according to context-sensitive training rules. - -The type checker depends on type rules, and the information of type environment $\Gamma$ is recorded in the symbol table. Use abstract syntax for type expressions, such as `listof (T)`. When the type check fails, a type mismatch error is generated, and the error message is generated according to the syntax context. - -### Basic Methods - -1. `isUpperBound(t1, t2): supUnify(t1, t2) == t2` -2. `supUnify(t1, t2):` - -- For the foundation type, `sup(t1, t2)` is calculated according to the partial order relationship -- For list, dict, Struct, recursively `supUnify` the types of elements -- When there is no partial order relationship, return `Nothing` - -### Checking Logic - -#### Operand Expr - -$D \to id: T$ - -``` -env.addtype(id.entry, T.type) -``` - -$T \to boolean$ - -``` -T.type = boolean -``` - -$T \to integer$ - -``` -T.type = integer -``` - -$T \to float$ - -``` -T.type = float -``` - -$T \to string$ - -``` -T.type = string -``` - -$T \to c, \ c \in \{boolean, integer, float, string\}$ - -``` -T.type = literalof(c) -``` - -$T \to None$ - -``` -T.type = None -``` - -$T \to Undefined$ - -``` -T.type = Undefined -``` - -$T \to \ [T_1]$ - -``` -T.type = listof (T1.type) -``` - -$T \to { \{T_1: T_2\} }$ - -``` -T.type = dictof (T1.type: T2.type) -``` - -$T \to { \{N_1: T_1, N2: T_2, ..., N_n: T_n\} }$ - -``` -T.type = structof (N1: T1.type, N2: T2.type, ..., Nn: Tn.type) -``` - -$E \to id$ - -``` -E.type = env.lookup(id.entry) -``` - -$E \to [E_1, E_2, ..., E_n]$ - -``` -func listExpr(E) { - supe = sup([e.type for e in E]]) - E.type = listof(type) -} -``` - -$E \to [E_1 \ for \ E_2 \ in \ E_3 \ if \ E_4]$ - -``` -func listComp(E) { - if !typeEqual(E4.type, boolean) { - raise type_error - } - if !isUpperBound(listof(Any), E3.type) { - raise type_error(E) - } - if !isUpperBound(E3.type, E2.type) { - raise type_error(E) - } - E.type = listof(E1.type) -} -``` - -$E \to \{E_{k1}: E_{v1}, ..., E_{kn}: E_{vn}\}$ - -``` -func dictExpr(E) { - supk := sup([e.type for e in E.keys()]]) - supv := sup([e.type for e in E.values()]]) - E.type = dictof(supk, supv) -} -``` - -$E \to \{E_1:E_2 \ for \ (E_3, E_4) \ in \ E_5 \ if \ E_6\}$ - -``` -func dictComp(E) { - if !typeEqual(E6.type, boolean) { - raise type_error(E) - } - if !isUpperBound(dictof(Any, Any), E5.type) { - raise type_error(E) - } - if !isUpperBound(E5.type, dictof(E3.type, E4.type)) { - raise type_error(E) - } - E.type = dictof(E1.type, E2.type) -} -``` - -$E \to \{E_{k1}: E_{v1}, ..., E_{kn}: E_{vn}\}$ - -``` -func dictExpr(E) { - supk := sup(Ek1, ..., Ekn) - supv = sup(Ev1, ..., Evn) - E.type = dictof(supk, supv) -} -``` - -$E \to \{N_{1} = E_{1}, ..., N_{{n}} = E_{n}\}$ - -``` -func structExpr(E) { - Struct = structof() - for n, e in E { - Struct.add(n, e.type) - } - E.type = Struct -} -``` - -#### Primary Expr - -$E \to E_1[E_2]$ - -``` -func sliceSuffix(E) { - if !isUpperBound(listof(Any), E.E1.type) { - raise type_error(E) - } - if typeEqual(E.E2.type, integer) { - raise type_error(E) - } - E.type = E.E1.type.eleType -} -``` - -$E \to E_1(E_2)$ - -``` -func callSuffix(E) { - if !typeEqual(E.E1.type, func) { - raise type_error(E) - } - if !isUpperBound(listof(E.E1.arguType), E.E2.type) { - raise type_error(E) - } - E.type = E.E1.returnType -} -``` - -#### Unary Expr - -According to the reasoning rules of each binocular operator, take `+` as an example. - -$E \to + E_1$ - -``` -func Plus(E) { - if !typeEqual(E.E1.type, [integer, float]) { - raise type_error(E) - } - E.type = E.E1.type -} -``` - -#### Binary Expr - -According to the reasoning rules of each binocular operator, take `%` as an example. - -$E \to E_1 \ % \ E_2$ - -``` -func Mod(E) { - if !(typeEqual(E.E1.type, [integer, float]) && typeEqual(E.E2.type, [integer, float])) { - raise type_error(E) - } - E.type = E.E1.type -} -``` - -#### IF Binary Expr - -$E \to if E_1 \ then \ E_2 else \ E_3$ - -``` -func ifExpr(E) { - if !typeEqual(E.type, boolean) { - raise type_error(E) - } - if !typeEqual(E_2.type, E_3.type) { - raise type_error(E) - } - E.type = E_2.type -} -``` - -#### Stmt - -$S \to if \ E \ then \ S_1 \ else \ S_2$ - -``` -func ifStmt(S) { - if !typeEqual(S.E.type, boolean) { - raise type_error(E) - } - if !typeEqual(S.S1.type, S.S2.type) { - raise type_error(E) - } - S.type = S.S1.type -} -``` - -$S \to id: T = E$ - -$S \to id = T E$ - -``` -func assignStmt(S) { - tpe := env.lookup(id.entry) - if tpe != nil && tpe != S.T { - raise type_error(E) - } - if isUpperBound(tpe, E.type) { - raise type_error(E) - } - env.addtype(id.entry, T.type) -} -``` - -## Type Conversion - -### Basic Definition - -Through syntax-directed translation, the value types involved in the operation are automatically converted according to the operator characteristics. - -### Conversion Rules - -$E \to E_1 \ op \ E_2, , op \in \{+, -, *, /, \%, **, //\}$ - -``` -func binOp(E) { - if E.E1.type == integer and E.E2.type == integer { - E.type = integer - } else if E.E1.type == integer and E.E2.type == float { - E.type = float - } else if E.E1.type == float and E.E2.type == integer { - E.type = float - } else if E.E1.type == float and E.E2.type == float { - E.type = float - } -} -``` - -## Type Inference - -### Basic Definition - -- Type rule derivation and type reconstruction in case of incomplete type information -- Derive and reconstruct the data structure types in the program from the bottom up, such as basic type, e.g., list, dict and struct types. - -### Basic Methods - -1. `typeOf(expr, subst)`: The input is the expression and substitution rule set, and the type of expr and the new substitution rule set are returned. -2. `unifier(t1, t2, subst, expr)`: Try substitution with `t1=t2`. If the substitution is successful (no occurrence and no conflict), add `t1=t2` to the subst and return the subst. Otherwise, an error has occurred or there is a conflict. - -### Inferential Logic - -$E \to id = E_1$ - -``` -func assignExpr(E, subst) { - return unifier(E.id.type, E.E_1.type, subst, E) -} -``` - -$unifier(t1, t2, subst, expr) \rightarrow subst$ - -``` -func unifier(t1, t2, subst, expr) { - t1 = applySubstToTypeEquation(t1, subst) - t2 = applySubstToTypeEquation(t2, subst) - - if t1 == t2 { - return subst - } - - if isTypeVar(t1) { - if isNoOccur(t1, t2) { - addTypeEquationToSubst(subst, t1, t2) - return subst - } else { - raise occurrence_violation_error(t1, t2, expr) - } - } - - if isTypeVar(t2) { - if isNoOccur(t2, t1) { - addTypeEquationToSubst(subst, t2, t1) - return subst - } else { - raise occurrence_violation_error(t2, t1, expr) - } - } - - if isList(t1) and isList(t2) { - return unifier(toListOf(t1).eleType, toListOf(t2).eleType, subst, expr) - } - if isDict(t1) and isDict(t2) { - dict1of := toDictOf(t1) - dict2of := toDictOf(t2) - subst = unifier(dict1of.keyType, dict2of.keyType, subst, expr) - subst = unifier(dict1of.valueType, dict2of.valueType, subst, expr) - return subst - } - if isStruct(t1) and isStruct(t2) { - Struct1of := tostructof(t1) - Struct2of := tostructof(t2) - for key, _ in Struct1of { - subst = unifier(t1[key].type, t2[key].type, subst, expr) - } - return subst - } - - raise unification_error(t1, t2, expr) -} - -func applySubstToTypeEquation(t, subst) { - // walks through the type t, replacing each type variable by its binding in the substitution -σ. If a variable is Not bound in the substitution, then it is left unchanged. - if isBasicType(t) { - return t - } - if isList(t) { - return listOf(applySubstToTypeEquation(toListOf(t).eleType, subst)) - } - if isDict(t) { - dictof := toDictOf(t) - kT := applySubstToTypeEquation(dictof.keyType, subst) - vT := applySubstToTypeEquation(dictof.valueType, subst) - return dictOf(kT, vT) - } - if isStruct(t) { - structof := tostructof(t) - s := structof() - for key, type in Struct1of { - kT := applySubstToTypeEquation(type, subst) - s.add(key, kT) - } - return s - } - if hasTypeVar(t) { - for tvar in t.vars { - if tvar in subst { - *tvar = subst[tvar] - } - } - } - return t -} - -func addTypeEquationToSubst(subst, tvar, t) { - // takes the substitution σ and adds the equation tv = t to it - for _, t in subst { - for tvar in t.vars { - tmp := applyOneSubst(tsvar, tvar, t) - *tvar = tmp - } - } - subst.add(tvar, t) -} - -func applyOneSubst(t0, tvar, t1) { - // substituting t1 for every occurrence of tv in t0. - if isBasicType(t0) { - return t0 - } - if isList(t0) { - return listOf(applyOneSubst(toListOf(t).eleType, tvar, t1)) - } - if isDict(t0) { - dictof := toDictOf(t) - kT := applyOneSubst(dictof.keyType, tvar, t1) - vT := applyOneSubst(dictof.valueType, tvar, t1) - return dictOf(kT, vT) - } - if isStruct(t0) { - structof := tostructof(t) - s := structof() - for key, type in Struct1of { - kT := applyOneSubst(type, tvar, t1) - s.add(key, kT) - } - return s - } - if t0 == tvar { - return t1 - } - return t0 -} - -func isNoOccur(tvar, t) { - // No variable bound in the substitution occurs in any of the right-hand sides of the substitution. - if isBasicType(t) { - return true - } - if isList(t) { - return isNoOccur(tvar, toListOf(t).eleType) - } - if isDict(t) { - dictof := toDictOf(t) - return isNoOccur(tvar, dictof.keyType) and isNoOccur(tvar, dictof.valueType) - } - if isStruct(t) { - structof := tostructof(t) - noOccur := true - for _, type in structof { - noOccur = noOccur and isNoOccur(tvar, type) - } - return noOccur - } - return tvar != t -} -``` - -### Example - -#### Normal Inference - -``` -T : { - a = 1 - b = "2" - c = a * 2 - d = { - d0 = [a, c] - } -} - -x: T = { - a = 10 -} -``` - -#### Occurrence Violation Error - -``` -T = { - a = a -} -``` - -#### Type Unification Error - -``` -T : { - a = 1 -} - -T : { - a = "1" -} -``` - -## Reference - -- [https://en.wikipedia.org/wiki/Type_system](https://en.wikipedia.org/wiki/Type_system) -- Pierce, Benjamin C. (2002). Types and Programming Languages. MIT Press. -- [https://www.cs.cornell.edu/courses/cs4110/2010fa/](https://www.cs.cornell.edu/courses/cs4110/2010fa/) -- [https://www.typescriptlang.org/docs/handbook/basic-types.html](https://www.typescriptlang.org/docs/handbook/basic-types.html) -- [https://www.typescriptlang.org/docs/handbook/advanced-types.html](https://www.typescriptlang.org/docs/handbook/advanced-types.html) diff --git a/versioned_docs/version-0.8.0/reference/model/_category_.json b/versioned_docs/version-0.8.0/reference/model/_category_.json deleted file mode 100644 index 398617be..00000000 --- a/versioned_docs/version-0.8.0/reference/model/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "System Package", - "position": 2 -} diff --git a/versioned_docs/version-0.8.0/reference/model/base64.md b/versioned_docs/version-0.8.0/reference/model/base64.md deleted file mode 100644 index 3f6e617b..00000000 --- a/versioned_docs/version-0.8.0/reference/model/base64.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: "base64" -linkTitle: "base64" -type: "docs" -description: base64 system module - base64 encode and decode function -weight: 100 ---- - -## encode - -`encode(value: str, encoding: str = "utf-8") -> str` - -Encode the string `value` using the codec registered for encoding. - -## decode - -`decode(value: str, encoding: str = "utf-8") -> str` - -Decode the string `value` using the codec registered for encoding. diff --git a/versioned_docs/version-0.8.0/reference/model/builtin.md b/versioned_docs/version-0.8.0/reference/model/builtin.md deleted file mode 100644 index 4bb34766..00000000 --- a/versioned_docs/version-0.8.0/reference/model/builtin.md +++ /dev/null @@ -1,386 +0,0 @@ ---- -title: "builtin" -sidebar_position: 1 ---- - -KCL provides a list of built-in functions that are automatically loaded and can be used directly without providing any module name. For example, `print` is a function provided by a widely used built-in module. - -## Type Conversion Functions - -KCL's `bool`, `int`, `float`, `str`, `list`, `dict` and other types have built-in conversion functions of the same name. Among them, `int` can not only be used to truncate floating-point numbers, but also can be used to convert strings to integers (decimal when parsing, other values can also be specified). - -The following are common uses of type-related functions: - -```py -b1 = bool(1) # true -b2 = bool(1.5) # true -b3 = bool("true") # true -b4 = bool("") # false -b5 = bool([]) # false -b6 = bool({}) # false - -i1 = int("11") # 11 -i2 = int("11", base=8) # 9 -i3 = int("11", base=2) # 3 - -f1 = float(1) # 1.0 -f2 = float("1.5") # 1.5 - -s1 = str(1) # 1 - -l1 = list([1, 2, 3]) -``` - -## String Builtin Member Functions - -- [String Spec](/docs/reference/lang/spec/datatypes) - -## print - -`print(*args:any, end:str='\n')` - -The built-in print function, which provides different types of variable parameter printing, adds a newline at the end by default. The following are common usages: - -```python -print("hello KCL") -print() -print(None, end=':') -print(None) -print(True) -print(False) -print(123) -print(123.0) -print('abc ${123}') -print("abc ${456}") -print([1,'a', True]) -print(1,'a', True) -print({}) -print({a: 123}) -``` - -The output is: - -```shell -hello KCL - -None:None -True -False -123 -123.0 -abc 123 -abc 456 -[1, 'a', True] -1 a True -{} -{'a': 123} -``` - -If you do not want the default newline, you can re-specify the ending string with the `end=''` named parameter. - -```python -print("Hello KCL", end='') -``` - -## multiplyof - -`multiplyof(a:int, b:int) -> bool` - -Check whether the integer `a` is an integer multiple of `b`, and return a boolean value: - -```python -print(multiplyof(2, 1)) # True -print(multiplyof(1, 2)) # False -print(multiplyof(0, 1)) # True -print(multiplyof(0, 2)) # True -print(multiplyof(1, 0)) # Error -``` - -`0` is a multiple of any number. But `b` cannot be `0`, otherwise an exception will be thrown. - -## isunique - -`isunique(list: [any]) -> bool` - -Check if there are duplicate elements in an array, and return a boolean value: - -```python -print(isunique([])) # True -print(isunique([1])) # True -print(isunique([1, 2])) # True - -print(isunique([1, 1])) # False -print(isunique([1, 1.0])) # False -print(isunique([1.1, 1.1])) # False - -print(isunique(['abc', "abc"])) # False -print(isunique(['abc', "a${'bc'}"])) # False -``` - -It should be noted that integers and floating-point numbers ignore the type difference and judge whether the values are equal. - -## len - -`len(x: str | [any] | {:}) -> int` - -Return the length of strings, lists, and arrays: - -```python -print(len([])) # 0 -print(len({})) # 0 - -print(len([1])) # 1 -print(len({abc:123})) # 1 - -print("abc") # 3 -``` - -Note: Calculating lengths on `schema` objects is not supported. - -## abs - -`abs(x: number) -> number` - -Calculate the absolute value of `x`. - -## all_true - -`all_true(x:str|[]|{:}) -> bool` - -Judging that all elements of a list or dictionary class are true, the usage is as follows: - -```python -print(all_true([])) # True -print(all_true({})) # True - -print(all_true([True])) # True -print(all_true([1])) # True - -print(all_true([True, False])) # False -print(all_true([True, None])) # False -``` - -Returns true when the list is empty. - -## any_true - -`any_true(x:str|[]|{:}) -> bool` - -Judging that at least one element in the iterable object is true, the usage is as follows: - -```python -print(any_true([])) # False -print(any_true([1])) # True -``` - -## bin - -`bin(x:number) -> str` - -A string that returns the binary representation of an integer, used as follows: - -```python -print(bin(8)) # 0b1000 -``` - -## hex - -`hex(number)` - -A string that returns the hexadecimal representation of an integer, used as follows: - -```python -print(hex(18)) # 0x12 -``` - -## oct - -`oct(number)` - -A string that returns the octal representation of an integer, used as follows: - -```python -print(oct(10)) # 0o12 -``` - -## option - -`option(key:str, type:str='', required=False, default=None, help="") -> any` - -Gets the value of the command line top level argument input. - -## ord - -`ord(c) -> int` - -Get the Unicode code point value of the character, the usage is as follows: - -```python -print(ord('A')) # 65 -print(ord('B')) # 66 -print(ord('C')) # 67 -``` - -## sorted - -`sorted(x: []) -> []` - -Returns the sorted list, used as follows: - -```python -_a = [] -_b = [2, 1] - -_c = sorted(_a) -_d = sorted(_b) - -print(_a) # [] -print(_b) # [2, 1] -print(_c) # [] -print(_d) # [1, 2] -``` - -## range - -`range(start:int, end:int, step=1) -> [int]` - -Generates an iterable list, used as follows: - -```python -print(range(1,5)) # [1, 2, 3, 4] -print(range(1,5, 2)) # [1, 3] -print(range(5, 1, -1)) # [5, 4, 3, 2] -``` - -## min - -`min(x:[number]) -> number` - -Returns the smallest element in the list, used as follows: - -```python -print(min([1,2])) # 1 -print(min([2,1])) # 1 -``` - -## max - -`max(x:[number]) -> number` - -Returns the largest element in the list, used as follows: - -```python -print(max([1,2])) # 2 -print(max([2,1])) # 2 -``` - -## sum - -`sum(x:[number], init_value=0) -> number` - -Returns the sum of all elements in the list, used as follows: - -``` -print(sum([1,2])) # 3 -print(sum([2,1], 1000)) # 1003 -``` - -## pow - -`pow(x: number, y: number, z: number = None) -> number` - -Computes `x**y`, or `(x**y)%z` if `z` is not empty, supports integer and floating point numbers, used as follows: - -```python -print(pow(2,3)) # 8 -print(pow(2, 3, 5)) # 8%5 == 3 - -print(pow(2, 0.5)) # 1.414 -``` - -## round - -`round(number: int|float, ndigits:int|None) -> float | int` - -Returns the rounded approximation of `number`. If `ndigits` is not `None` returns a float with the specified number of decimal places (cannot be negative), otherwise returns an integer structure, used as follows: - -```python -print(round(1)) # 1 -print(round(1.4)) # 1 -print(round(1.5)) # 2 - -print(round(1.5555, 1)) # 1.6 -print(round(1.5555, 2)) # 1.56 - -print(round(1.5555)) # 2 -print(round(1.5555, 0)) # 2.0 -``` - -It should be noted that the difference between `ndigits` being `None` and `0` is that the prefix returns `int` type, the latter returns `float` type. - -## typeof - -`typeof(x: any, full_name: bool = False) -> str` - -Output the type of `x` at runtime. When the `full_name` parameter is set to `True`, the package prefix of the form `pkg.schema` will be returned, used as follows: - -```python -import sub as pkg - -_a = 1 - -t1 = typeof(_a) -t2 = typeof("abc") - -schema Person: - name?: any - -_x1 = Person{} -t3 = typeof(_x1) - -_x2 = pkg.Person{} -t4 = typeof(_x2) -t5 = typeof(_x2, full_name=True) - -t6 = typeof(_x1, full_name=True) - -# Output -# t1: int -# t2: str -# t3: Person -# t4: Person -# t5: sub.Person -# t6: __main__.Person -``` - -## zip - -`zip(*args: str|list|dict)` - -It is used to take an iterable object as a parameter, pack the corresponding elements in the object into tuples, and then return a list composed of these tuples, used as follows: - -```py -a = zip([0, 1, 2], [3, 4, 5]) -b = zip([0, 1], [3, 4, 5]) -c = zip([0, 1, 2], [3, 4, 5, 6]) - -# Output -# a: -# - - 0 -# - 3 -# - - 1 -# - 4 -# - - 2 -# - 5 -# b: -# - - 0 -# - 3 -# - - 1 -# - 4 -# c: -# - - 0 -# - 3 -# - - 1 -# - 4 -# - - 2 -``` diff --git a/versioned_docs/version-0.8.0/reference/model/manifests.md b/versioned_docs/version-0.8.0/reference/model/manifests.md deleted file mode 100644 index ab31ad47..00000000 --- a/versioned_docs/version-0.8.0/reference/model/manifests.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: "manifests" -linkTitle: "manifests" -type: "docs" -description: manifests system module -weight: 100 ---- - -## yaml_stream - -```python -yaml_stream(values: [any], opts: {str:} = { - sort_keys = False - ignore_private = True - ignore_none = False - sep = "---" -}) -``` - -This function is used to serialize the KCL object list into YAML output with the --- separator. It has two parameters: - -- `values` - A list of KCL objects -- `opts` - The YAML serialization options - - `sort_keys`: Whether to sort the serialized results in the dictionary order of attribute names (the default is `False`). - - `ignore_private`: Whether to ignore the attribute output whose name starts with the character `_` (the default value is `True`). - - `ignore_none`: Whether to ignore the attribute with the value of' None '(the default value is `False`). - - `sep`: Set the separator between multiple YAML documents (the default value is `"---"`). - -Here's an example: - -```python -# Use the `import` keyword to import the `manifests` module. -import manifests - -# The schema `Deployment` definition. -schema Deployment: - apiVersion: str = "v1" - kind: str = "Deployment" - metadata: {str:} = { - name = "deploy" - } - spec: {str:} = { - replica = 2 - } - -# The schema `Service` definition. -schema Service: - apiVersion: str = "v1" - kind: str = "Service" - metadata: {str:} = { - name = "svc" - } - spec: {str:} = {} - -# Define two `Deployment` resources. -deployments = [Deployment {}, Deployment {}] -# Define two `Service` resources. -services = [Service {}, Service {}] -# Put them into a KCL list and call the `manifests.yaml_stream` function. -manifests.yaml_stream(deployments + services) -``` - -First, we use the `import` keyword to import the `manifests` module and define two deployment resources and two service resources. When we want to output these four resources in YAML stream format with `---` as the separator, we can put them into a KCL list and use the `manifests.yaml_stream` function pass it to the `values` parameter (if there is no special requirement, the `opts` parameter can generally use the default value). Finally, the YAML output is: - -```yaml -apiVersion: v1 -kind: Deployment -metadata: - name: deploy -spec: - replica: 2 ---- -apiVersion: v1 -kind: Deployment -metadata: - name: deploy -spec: - replica: 2 ---- -apiVersion: v1 -kind: Service -metadata: - name: svc ---- -apiVersion: v1 -kind: Service -metadata: - name: svc -``` diff --git a/versioned_docs/version-0.8.0/reference/model/net.md b/versioned_docs/version-0.8.0/reference/model/net.md deleted file mode 100644 index a4e83659..00000000 --- a/versioned_docs/version-0.8.0/reference/model/net.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: "net" -linkTitle: "net" -type: "docs" -description: net system module -weight: 100 ---- - -## split_host_port - -`split_host_port(ip_end_point: str) -> List[str]` - -Split the `host` and `port` from the `ip_end_point`. - -## join_host_port - -`join_host_port(host, port) -> str` - -Merge the `host` and `port`. - -## fqdn - -`fqdn(name: str = '') -> str` - -Return Fully Qualified Domain Name (FQDN). - -## parse_IP - -`parse_IP(ip) -> str` - -Parse `ip` to a real IP address - -## to_IP4 - -`to_IP4(ip) -> str` - -Get the IP4 form of `ip`. - -## to_IP16 - -`to_IP16(ip) -> int` - -Get the IP16 form of `ip`. - -## IP_string - -`IP_string(ip: str | int) -> str` - -Get the IP string. - -## is_IPv4 - -`is_IPv4(ip: str) -> bool` - -Whether `ip` is a IPv4 one. - -## is_IP - -`is_IP(ip: str) -> bool` - -Whether `ip` is a valid ip address. - -## is_loopback_IP - -`is_loopback_IP(ip: str) -> bool` - -Whether `ip` is a loopback one. - -## is_multicast_IP - -`is_multicast_IP(ip: str) -> bool` - -Whether `ip` is a multicast one. - -## is_interface_local_multicast_IP - -`is_interface_local_multicast_IP(ip: str) -> bool` - -Whether `ip` is a interface, local and multicast one. - -## is_link_local_multicast_IP - -`is_link_local_multicast_IP(ip: str) -> bool` - -Whether `ip` is a link local and multicast one. - -## is_link_local_unicast_IP - -`is_link_local_unicast_IP(ip: str) -> bool` - -Whether `ip` is a link local and unicast one. - -## is_global_unicast_IP - -`is_global_unicast_IP(ip: str) -> bool` - -Whether `ip` is a global and unicast one. - -## is_unspecified_IP - -`is_unspecified_IP(ip: str) -> bool` - -Whether `ip` is a unspecified one. diff --git a/versioned_docs/version-0.8.0/reference/model/regex.md b/versioned_docs/version-0.8.0/reference/model/regex.md deleted file mode 100644 index adde0630..00000000 --- a/versioned_docs/version-0.8.0/reference/model/regex.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "regex" -linkTitle: "regex" -type: "docs" -description: regex system module -weight: 100 ---- - -## replace - -`replace(string: str, pattern: str, replace: str, count=0) -> str` - -Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement. - -## match - -`match(string: str, pattern: str) -> bool` - -Try to apply the pattern at the start of the string, returning a bool value `True` if any match was found, or `False` if no match was found. - -## compile - -`compile(pattern: str) -> bool` - -Compile a regular expression pattern, returning a bool value denoting whether the pattern is valid. - -## findall - -`findall(string: str, pattern: str) -> List[str]` - -Return a list of all non-overlapping matches in the string. - -## search - -`search(string: str, pattern: str) -> bool` - -Scan through string looking for a match to the pattern, returning a bool value `True` if any match was found, or `False` if no match was found. - -## split - -`split(string: str, pattern: str, maxsplit=0) -> List[str]` - -Return a list composed of words from the string, splitting up to a maximum of `maxsplit` times using `pattern` as the separator. diff --git a/versioned_docs/version-0.8.0/reference/model/units.md b/versioned_docs/version-0.8.0/reference/model/units.md deleted file mode 100644 index 34465a53..00000000 --- a/versioned_docs/version-0.8.0/reference/model/units.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: "units" -linkTitle: "units" -type: "docs" -description: units system module - Unit handlers -weight: 100 ---- - -## Constants - -- Fixed point unit constants: `n`, `u`, `m`, `k`, `K`, `G`, `T` and `P`. -- Power of 2 unit constants: `Ki`, `Mi`, `Gi`, `Ti` and `Pi`. - -## Functions - -- `to_n(num: int) -> str` - Int literal to string with `n` suffix -- `to_u(num: int) -> str` - Int literal to string with `u` suffix -- `to_m(num: int) -> str` - Int literal to string with `m` suffix -- `to_K(num: int) -> str` - Int literal to string with `K` suffix -- `to_M(num: int) -> str` - Int literal to string with `M` suffix -- `to_G(num: int) -> str` - Int literal to string with `G` suffix -- `to_T(num: int) -> str` - Int literal to string with `T` suffix -- `to_P(num: int) -> str` - Int literal to string with `P` suffix -- `to_Ki(num: int) -> str` - Int literal to string with `Ki` suffix -- `to_Mi(num: int) -> str` - Int literal to string with `Mi` suffix -- `to_Gi(num: int) -> str` - Int literal to string with `Gi` suffix -- `to_Ti(num: int) -> str` - Int literal to string with `Ti` suffix -- `to_Pi(num: int) -> str` - Int literal to string with `Pi` suffix diff --git a/versioned_docs/version-0.8.0/reference/plugin/_category_.json b/versioned_docs/version-0.8.0/reference/plugin/_category_.json deleted file mode 100644 index e77dfb1c..00000000 --- a/versioned_docs/version-0.8.0/reference/plugin/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Plugin System", - "position": 4 -} diff --git a/versioned_docs/version-0.8.0/reference/xlang-api/_category_.json b/versioned_docs/version-0.8.0/reference/xlang-api/_category_.json deleted file mode 100644 index c2aafb21..00000000 --- a/versioned_docs/version-0.8.0/reference/xlang-api/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Multi-Language", - "position": 4 -} diff --git a/versioned_docs/version-0.8.0/reference/xlang-api/java-api.md b/versioned_docs/version-0.8.0/reference/xlang-api/java-api.md deleted file mode 100644 index 52c8cf34..00000000 --- a/versioned_docs/version-0.8.0/reference/xlang-api/java-api.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Java API - -At present, the KCL Java SDK is still in the early preview version. The KCL team will continue to update and provide more functions in the future. For more information, see [https://github.com/kcl-lang/kcl-java](https://github.com/kcl-lang/kcl-java) diff --git a/versioned_docs/version-0.8.0/reference/xlang-api/python-api.md b/versioned_docs/version-0.8.0/reference/xlang-api/python-api.md deleted file mode 100644 index e6ce67dc..00000000 --- a/versioned_docs/version-0.8.0/reference/xlang-api/python-api.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Python API - -At present, the KCL Python SDK is still in the early preview version. The KCL team will continue to update and provide more functions in the future. For more information, see [https://github.com/kcl-lang/kcl-py](https://github.com/kcl-lang/kcl-py) diff --git a/versioned_docs/version-0.8.0/tools/Ide/_category_.json b/versioned_docs/version-0.8.0/tools/Ide/_category_.json deleted file mode 100644 index d9bfcdd7..00000000 --- a/versioned_docs/version-0.8.0/tools/Ide/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "IDE", - "position": 2 -} diff --git a/versioned_docs/version-0.8.0/tools/Ide/intellij.md b/versioned_docs/version-0.8.0/tools/Ide/intellij.md deleted file mode 100644 index ce3bf4da..00000000 --- a/versioned_docs/version-0.8.0/tools/Ide/intellij.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -sidebar_position: 3 ---- - -# IntelliJ IDEA - -- IntelliJ KCL Extension: [https://github.com/kcl-lang/intellij-kcl](https://github.com/kcl-lang/intellij-kcl) - -![intellij](/img/docs/tools/Ide/intellij/overview.png) diff --git a/versioned_docs/version-0.8.0/tools/Ide/neovim.md b/versioned_docs/version-0.8.0/tools/Ide/neovim.md deleted file mode 100644 index 788daadb..00000000 --- a/versioned_docs/version-0.8.0/tools/Ide/neovim.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -sidebar_position: 2 ---- - -# NeoVim - -- NeoVim KCL Extension: [https://github.com/kcl-lang/kcl.nvim](https://github.com/kcl-lang/kcl.nvim) - -![kcl.nvim](/img/docs/tools/Ide/neovim/overview.png) diff --git a/versioned_docs/version-0.8.0/tools/_category_.json b/versioned_docs/version-0.8.0/tools/_category_.json deleted file mode 100644 index 5ecd522f..00000000 --- a/versioned_docs/version-0.8.0/tools/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Tools", - "position": 3 -} diff --git a/versioned_docs/version-0.8.0/tools/cli/_category_.json b/versioned_docs/version-0.8.0/tools/cli/_category_.json deleted file mode 100644 index 887061ef..00000000 --- a/versioned_docs/version-0.8.0/tools/cli/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Command Line Tools", - "position": 1 -} diff --git a/versioned_docs/version-0.8.0/tools/cli/index.md b/versioned_docs/version-0.8.0/tools/cli/index.md deleted file mode 100644 index ef4f69dc..00000000 --- a/versioned_docs/version-0.8.0/tools/cli/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# Command Line Tools - -KCL provides IDE plug-ins, rich language tools and OpenAPI tools. These tools provide a complete set of solutions, including configuration languages, model interfaces, automation tools, and best practices. diff --git a/versioned_docs/version-0.8.0/tools/cli/kcl/_category_.json b/versioned_docs/version-0.8.0/tools/cli/kcl/_category_.json deleted file mode 100644 index 4c605bd0..00000000 --- a/versioned_docs/version-0.8.0/tools/cli/kcl/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KCL Tools", - "position": 2 -} diff --git a/versioned_docs/version-0.8.0/tools/cli/openapi/_category_.json b/versioned_docs/version-0.8.0/tools/cli/openapi/_category_.json deleted file mode 100644 index 58e4c68a..00000000 --- a/versioned_docs/version-0.8.0/tools/cli/openapi/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "OpenAPI Tools", - "position": 3 -} diff --git a/versioned_docs/version-0.8.0/tools/cli/openapi/spec.md b/versioned_docs/version-0.8.0/tools/cli/openapi/spec.md deleted file mode 100644 index 41cbfe15..00000000 --- a/versioned_docs/version-0.8.0/tools/cli/openapi/spec.md +++ /dev/null @@ -1,438 +0,0 @@ -# KCL OpenAPI Spec - -[OpenAPI](https://www.openapis.org/) defines the API Specification for API providers to describe their operations and models in a normative way and provides generating tools to automatically convert to client codes in specific languages. - -The KCL OpenAPI Spec describes the rules about how the OpenAPI definitions are translated to the KCL schemas. - -## The File Structure of the KCL OpenAPI - -According to the OpenAPI 3.0 specification, an OpenAPI file should at least contains four root objects: `openapi`, `components`, `info`, `paths`. The KCL OpenAPI focuses on the part in which the models are defined in the `definitions` object. Yet the `paths` part which describes the Restful API operations is not considered by the KCL OpenAPI Spec. - -:::info -Note: In addition to the objects listed above, the OpenAPI spec also supports `servers`, `security`, `tags`, and `externalDocs` as optional root objects, but none of them are concerned by KCL OpenAPI when generating model codes, so we do not need to fill in this section. Yet it won't make any difference if you do. -::: - -To put it more comprehensible for beginners, let's take a quick look at the root objects that forms the typical KCL OpenAPI file (snippets from swagger example [Petstore](https://petstore.swagger.io/). The KCL OpenAPI tool only focuses on the `definitions` object which describes two data models (`Pet` and `Category`), and the model `Pet` contains three attributes: `name`, `id`, and `category`) - -## KCL schema - -The KCL schema structure defines the "type" of configuration data. - -:::info -More information about KCL schema, see [KCL Language Tour#Schema](../../../reference/lang/tour.md) -::: - -In the OpenAPI spec, a KCL schema can be defined by adding a `definition` element within the `definitions` object. - -Example: -The following example defines two schemas in KCL: `Pet` and `Category`, followed by the corresponding data models defined in OpenAPI: - -```python -# KCL schema -schema Pet: - name: str - id?: int - category?: Category - -schema Category: - name?: str - -# The corresponding OpenAPI spec -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "id": { - "type": "integer", - "format": "int64" - }, - "category": { - "$ref": "#/definitions/Category" - } - }, - "required": [ - "name" - ] - }, - "Category": { - "type": "object", - "properties": { - "name": { - "type": "string" - } - } - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### Schema Name - -In KCL, the schema name is declared immediately after the schema keyword, and in OpenAPI, the name of the model is defined by the key of the definition element. - -### Schema Type - -The type of KCL schema in OpenAPI is always "object". As in the previous example, the value of the `type` object in `Pet` should be `object`. - -### Schema Attribute - -Zero or more attributes can be defined in the KCL schema. The declaration of attributes generally includes the following parts: - -- Attribute annotation: Optional, starting with `@`, such as `@deprecated` to indicate a deprecated attribute -- Attribute name: Required -- Attribute optional modifiers(`?`): Optional. A question mark indicates that the current attribute is optional and may not be assigned. Conversely, the absence of a question mark indicates a required attribute -- Attribute type: Required. The attribute can be a primitive data type, a schema type, or a combination of the two preceding types -- Attribute default value: Optional - -The mapping between them and the OpenAPI spec is as follows: - -| Elements of KCL Schema Attribute | Corresponding Elements in OpenAPI | -| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| attribute annotation | Not supported. We are planning to add an extension `deprecate` field to the KCL-OpenAPI | -| attribute name | The key of the property under the `property` object | -| attribute optional modifiers(`?`) | In each element in the `definition` object, here's an optional `required` field which lists the all the required attributes of that model, and the attributes not listed are optional | -| attribute type | The basic types can be declared by a combination of `type` and `format`, and the schema type is declared by a `$ref` to the schema definition. KCL-OpenAPI spec adds a `x-kcl-types` extension to indicate a type union. `enum` indicates a union of several literal types. For the type declaration in KCL-OpenAPI, see the chapter - [basic data types](#basic-data-types) | -| attribute default value | The value of the `default` field is used to set the default value for the attribute | - -Example: - -The following KCL code defines a Pet model which contains two attributes: name (`string` type, `required`, with no attribute annotation and no default value) and id (`int64` type, optional, with no attribute annotation, and the default value is -1). - -```python -# the KCL schema Pet defines two attributes: name, id -schema Pet: - name: str - id?: int = -1 - -# The corresponding OpenAPI spec -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - "id": { - "type": "integer", - "format": "int64", - "default": -1 - } - }, - "required": [ - "name" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### Schema Index Signature - -In the KCL schema, the index signatures can be used to define attributes with undefined attribute names. The KCL schema index signature contains the following elements: - -- Type of the key in the index signature: Declared in square brackets. It must be the basic type -- Type of value in the index signature: Declared after the colon in the square brackets. It can be any valid KCL type -- Ellipses(`...`) in the index signature: In the square brackets, before the type declaration of the key. It indicates that the index signature is only used to constrain attributes not defined in the schema. The assentation of the symbol indicates that all defined and undefined attributes in the schema are constrained by the index signature. -- Alias for key in index signature: Declared in square brackets, immediately after the left square bracket and takes the form of `:`. The alias can then be used to reference the index signature by name -- The default value of the index signature: Assign a value to the index signature as the default value - -The index signature with its key in `string` type can be described based on the field `additionalProperties`. Other index signatures with a key in types besides `string`, and the `check` expressions used to validate the index signature are not supported by the KCL OpenAPI spec. - -The mapping between them and the OpenAPI spec is as follows: - -| Elements of KCL Index Signature | Corresponding Elements in OpenAPI | -| -------------------------------------------- | ----------------------------------------------------------------------------------------------- | -| Type of the key in the KCL index signature | Only string type is allowed in OpenAPI | -| Type of the value in the KCL index signature | Declared by the `type` in the `additionalProperties` field | -| Ellipses(`...`) in the index signature | Only the corresponding meaning of the attendance of the `...` symbol is allowed in OpenAPI | -| Alias for key in index signature | Not supported in KCL-OpenAPI yet. We are planning to add an `x-alias` extension to support that | -| Default value of the index signature | Not supported in KCL-OpenAPI | - -Example: - -The following KCL code defines a Pet model which contains two pre-declared attributes(`name` and `id`) and allows users to add attributes with `string` type keys and `bool` type values. - -```python -# the KCL schema Pet. Besides the pre-declared attributes name and id, it allows to add attributes with key in string type and value in bool type -schema Pet: - name: str - id?: int - [...str]: bool - -# The corresponding OpenAPI spec -{ - "definitions": { - "Pet": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - "id": { - "type": "integer", - "format": "int64", - } - }, - "additionalProperties": { - "type": "bool" - }, - "required": [ - "name" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -### Schema Inherit - -working in progress - -### Inline schema - -OpenAPI supports models to be declared inline. But KCL currently does not support that. The model defined inline in OpenAPI will be converted to a schema with a name in KCL. And the naming convention will be: - -| element to define an inline schema in OpenAPI | the name of the corresponding KCL schema | -| --------------------------------------------- | -------------------------------------------------------------- | -| inline Property | add the Property name at the end of the outer schema Name | -| AdditionalProperties | add "AdditionalProperties" at the end of the outer schema Name | - -We are planning to support inline schema in KCL, and when supported, the naming convention will be updated then. - -Example-1: - -The following KCL code defines a `Deployment` model which contains two attributes(`kind` and `spec`). And the schema of the `spec` attribute is defined inline. - -```python -# The OpenAPI spec -{ - "definitions": { - "Deployment": { - "type": "object", - "properties": { - "kind": { - "type": "string", - }, - "spec": { - "type": "object", - "properties": { - "replicas": { - "type": "integer", - "format": "int64" - } - } - } - }, - "required": [ - "kind", - "spec" - ], - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -# The corresponding KCL schemas -schema Deployment: - kind: str - spec: DeploymentSpec - -schema DeploymentSpec: - replicas?: int -``` - -Example-2: - -The following KCL code defines a Person model which contains a pre-declared attribute(`name`) and allows some `additionalProperties` to be assigned by user. And the type of the values in the `additionalProperties` is defined inline. - -```python -# The OpenAPI spec -{ - "definitions": { - "Person": { - "type": "object", - "properties": { - "name": { - "type": "string", - }, - }, - "required": [ - "name", - "spec" - ], - "additionalProperties": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "description": { - "type": "string" - } - }, - "required": [ - "name" - ] - }, - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} - -# The corresponding KCL schemas -schema Person: - name: str - [...str]: [PersonAdditionalProperties] - -schema PersonAdditionalProperties: - name: str - description?: str -``` - -## KCL Doc - -:::info -More information about KCL doc specification, please refer to the [KCL Document Specification](../kcl/docgen.md) -::: - -KCL documents consist of module documents and schema documents. And only the schema documents can be extracted from OpenAPI. The KCL schema document contains four parts: - -- Schema Description: Declared right after the schema declaration and before the schema attribute declaration. It provides an overview of schemas -- Schema Attribute Doc: Declared right after the schema Description and separated by `Attributes` + `---` delimiters. It describes the attribute -- Additional information about the schema: Declared right after the schema attribute doc and separated by `See Also` + `---` delimiters -- Example information about the schema: Declared right after the schema additional information and separated by `Examples` + `---` delimiters - -The mapping between them and the OpenAPI spec is as follows: - -| Elements of KCL Schema Document | Corresponding Elements in OpenAPI | -| --------------------------------------- | ------------------------------------------------------- | -| Schema Description | The value of the `description` field of the data model | -| Schema Attribute Doc | The value of the `description` field of the property | -| Additional information about the schema | The value of the `externalDocs` field of the data model | -| Example information about the schema | The value of the `example` field of the data model | - -Example: - -The following KCL code defines a Pet model with a schema description `The schema Pet definition`, and two attributes `name` and `id` with their attribute doc `The name of the pet` and `The id of the pet`; The additional information about the Pet schema is [here](https://petstore.swagger.io/) and the example to use the Pet schema are provided, too. - -```python -# The KCL schema Pet, with doc following the KCL Document Specification -schema Pet: - """The schema Pet definition - - Attributes - ---------- - name : str, default is Undefined, required - The name of the pet - id : int, default is -1, optional - The age of the pet - - See Also - -------- - Find more info here. https://petstore.swagger.io/ - - Examples - -------- - pet = Pet { - name = "doggie" - id = 123 - } - """ - name: str - id?: int = -1 - -# The corresponding OpenAPI Spec -{ - "definitions": { - "Pet": { - "description": "The schema Pet definition", - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "The name of the pet" - }, - "id": { - "type": "integer", - "format": "int64", - "default": -1, - "description": "The age of the pet" - } - }, - "required": [ - "name" - ], - "externalDocs": { - "description": "Find more info here", - "url": "https://petstore.swagger.io/" - }, - "example": { - "name": "doggie", - "id": 123 - } - } - }, - "swagger": "2.0", - "info": { - "title": "demo", - "version": "v1" - } -} -``` - -## Basic Data Types - -| JSON Schema type | swagger type | KCL type | comment | -| ---------------- | --------------------------- | --------------- | --------------------------------------------------------------------------- | -| boolean | boolean | bool | | -| number | number | float | | -| | number format double | **unsupported** | | -| | number format float | float | | -| integer | integer | int (32) | | -| | integer format int64 | **unsupported** | | -| | integer format int32 | int (32) | | -| string | string | str | | -| | string format byte | str | | -| | string format int-or-string | int \| str | | -| | string format binary | str | | -| | string format date | unsupported | As defined by full-date - [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) | -| | string format date-time | unsupported | As defined by date-time - [RFC3339](https://www.rfc-editor.org/rfc/rfc3339) | -| | string format password | unsupported | for swagger: A hint to UIs to obscure input | -| | datetime | datetime | | - -## Reference - -- OpenAPI spec 2.0: [https://swagger.io/specification/v2/](https://swagger.io/specification/v2/) -- OpenAPI spec 3.0: [https://spec.openapis.org/oas/v3.1.0](https://spec.openapis.org/oas/v3.1.0) -- OpenAPI spec 3.0: [https://swagger.io/specification/](https://swagger.io/specification/) -- OpenAPI spec 2.0: [https://swagger.io/specification/v2/#schemaObject](https://swagger.io/specification/v2/#schemaObject) -- Go swagger: [https://goswagger.io/use/models/schemas.html](https://goswagger.io/use/models/schemas.html) -- Swagger data models: [https://swagger.io/docs/specification/data-models/](https://swagger.io/docs/specification/data-models/) diff --git a/versioned_docs/version-0.8.0/tools/cli/package-management/command-reference/_category_.json b/versioned_docs/version-0.8.0/tools/cli/package-management/command-reference/_category_.json deleted file mode 100644 index 8c705ed9..00000000 --- a/versioned_docs/version-0.8.0/tools/cli/package-management/command-reference/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Command Reference", - "position": 4 -} diff --git a/versioned_docs/version-0.8.0/user_docs/concepts/_category_.json b/versioned_docs/version-0.8.0/user_docs/concepts/_category_.json deleted file mode 100644 index d40bb9de..00000000 --- a/versioned_docs/version-0.8.0/user_docs/concepts/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Concepts", - "position": 5 -} diff --git a/versioned_docs/version-0.8.0/user_docs/concepts/package-and-module.md b/versioned_docs/version-0.8.0/user_docs/concepts/package-and-module.md deleted file mode 100644 index a36e45c9..00000000 --- a/versioned_docs/version-0.8.0/user_docs/concepts/package-and-module.md +++ /dev/null @@ -1,156 +0,0 @@ -# Module and Package - -This section mainly describes how to organize files in KCL. - -## Overview - -Within a **module**, KCL organizes files grouped by **package**. A package can be defined within a module or be imported externally (through KCL package manager `kpm`). In the latter case, KCL maintains a copy of the package within the module in a dedicated location. - -## Module - -A KCL module contains a configuration laid out in a directory hierarchy. It contains everything that is needed to deterministically determine the outcome of a KCL configuration. The root of this directory is marked by containing a `kcl.mod` directory. The contents of this directory are mostly managed by the kcl tool such as `kpm`, etc. In that sense, `kcl.mod` is analogous to the `.git` directory marking the root directory of a repo, but where its contents are mostly managed by the git tool. Besides, a KCL module is the largest unit of the file organization, has a fixed location of all KCL files and dependencies. - -> Note: The use of a KCL module e.g., `kcl.mod` is optional, but required if one wants to manage, distribute, share and reuse code with a semantic version. - -### Creating a module - -A module can be created by running the following command within the module root: - -```bash -kpm init [module name] -``` - -The module name is **required** if a package within the module needs to import another package within the module. A module can also be created by setting up the `kcl.mod` file manually. - -## Package - -In KCL, a package is usually composed of a "folder" containing KCL files. This folder can be a real disk physical path, or it can be composed of multiple KCL files (usually main package). Different packages are uniquely located by different package paths (such as `kubernetes.core.v1`) - -Within the same module, different packages can be imported from each other through the import statement of relative or absolute path. During the KCL parsing process, the relative import will be replaced by absolute import and the corresponding KCL code will be found through the package path. - -### Relative Import Path - -We can use the operator `.` to realize the relative path import of KCL entry files. - -main.k: - -```python -import .model1 # Current directory module -import ..service # Parent directory -import ...root # Parent of parent directory - -s = service.ImageService {} -m = root.Schema {} -``` - -### Absolute Import Path - -The semantics of `import a.b.c.d` is - -1. If `kcl.mod` not exist, regard the current directory as the package root and search the path `a/b/c/d` from the current directory. -2. If the current directory search fails, search from the root path `ROOT_PATH/a/b/c/d`, else raise an import error. - -The definition of the root path `ROOT_PATH` is the directory corresponding to the `kcl.mod` file from the current directory. - -Code structure: - -``` -. -└── root - ├── kcl.mod - ├── model - │ ├── model1.k - | ├── model2.k - │ └── main.k - ├── service - │ └── service1.k - └── mixin - └── mixin1.k -``` - -### Builtin Package - -KCL has a collection of builtin packages such as `math`, `regex`, etc. To use a builtin package, import it directly and invoke the functions using its qualified identifier. For instance, - -```python -import regex - -image = "nginx:1.14.2" -is_match = regex.match(image, "^[a-zA-Z]+:\d+\.\d+\.\d+$") - -``` - -The output YAML is - -```yaml -image: nginx:1.14.2 -is_match: true -``` - -### Plugin Package - - - -KCL also has a collection of plugin packages such as `hello`, `project_context`, etc. To use a plugin package, import it with a `kcl_plugin.` package path prefix and invoke the functions using its qualified identifier. For instance, - -```python -import kcl_plugin.hello - -result = hello.add(1, 1) -``` - -The output YAML is - -```yaml -result: 2 -``` - -### Main Package - -In KCL, the composition of the main package is usually determined by the compiler parameters. This is because the KCL schema and constraints can be split across files in the package, or even organized across directories, considering the convenience of writing and maintaining the configuration in isolated blocks. - -#### Files belonging to a main package - -It is up to the user to decide which configurations and constraints to use using the KCL command line. For example, - -```bash -kcl file1.k file2.k -``` - -Thus, the main package contains two KCL files named `file1.k` and `file2.k`. - -If KCL is told to load the files for a specific directory, for example: - -```bash -kcl ./path/to/package -``` - -It will only look KCL files with `.k` suffix and ignore files with `_` prefix or `_test.k` into the main package. Besides, if the `./path/to/package` contains `kcl.yaml` files, `kcl.yaml` files be ignored. - -In addition, we can set main package files through configuring the command-line compilation setting file (e.g., `kcl.yaml`) as follows: - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k -``` - -```bash -kcl -Y kcl.yaml -``` - -> Note: If we do not specify any input files for KCL, KCL will find the default `kcl.yaml` from the command line execution path to read the input file. Besides, if we tell KCL both the input files and the compilation setting file, KCL will take input files entered by the user as the final value. - -```bash -# Whether the 'files' field is configured in `kcl.yaml` or not, the final value of input files is ["file1.k", "file2.k"] -kcl -Y kcl.yaml file1.k file2.k -``` - -## The relationship and difference between `kcl.mod` and `kcl.yaml` - -First of all, in KCL, `kcl.mod` and `kcl.yaml` are both optional. The difference is that `kcl.mod` determines the root path of the package path and whether a KCL module has the requirement of distribution and reuse, and `kcl.yaml` determines the KCL file composition of the main package. - -Secondly, for a kcl module for external use only, `kcl.yaml` is optional but `kcl.mod` is required, because it needs to declare the KCL version, module version, dependency and other information. - -Finally, for the KCL IDE plug-in, it needs to know the main package information to form a complete compilation process, so it needs to automatically look up the composition of the main package according to the position of the cursor, because no one can specify this information through the KCL command line. The general query logic is to find whether `kcl.yaml` exists. If it is found, the main package consists of the `files` attribute in `kcl.yaml`, and if not found, the main package consists of the current file. The KCL IDE plug-in is selectively aware of the `kcl.mod` file. When the `kcl.mod` file exists, the IDE plug-in reads the corresponding information of all package paths and their real paths in the external dependencies. diff --git a/versioned_docs/version-0.8.0/user_docs/concepts/type-and-definition.md b/versioned_docs/version-0.8.0/user_docs/concepts/type-and-definition.md deleted file mode 100644 index ed82315f..00000000 --- a/versioned_docs/version-0.8.0/user_docs/concepts/type-and-definition.md +++ /dev/null @@ -1,94 +0,0 @@ -# Type and Definition - -This section mainly covers the concepts related to types and definitions. - -## Type - -KCL features a **gradual static type system**, initially designed to consider scalability. Its aim is to significantly reduce the configuration writing difficulties for users while maintaining stability. Static typing enhances code quality, acts as documentation, and helps detect errors at an early stage when needed. For instance, defining a complete static type for data like JSON/YAML can be challenging, similar to how TypeScript adds complexity in handling type gymnastics due to the lack of runtime type checks for Javascript. In contrast, KCL incorporates a similar TypeScript type system while still retaining runtime type checks. Thus, type errors will always appear at runtime. Consequently, KCL has types, but they can be selectively used when necessary, and it handles interactions between typed and untyped code elegantly and securely. - -The configuration of attributes and types in KCL usually follows a simple pattern: - -$$ -k = (T) v -$$ - -where $k$ is the attribute name, $v$ is the attributes value, and $T$ is the type annotation. Since KCL has the ability of the type inference, $T$ is usually omitted. - -By default, KCL does not require type annotations and performs type checks at runtime. - -```python -name = "nginx" # The type of `name` is `str` -port = 80 # The type of `port` is `int` -``` - -As long as we operate on basic types such as integers and strings, it is generally sufficient to annotate the default type and directly write the configuration. KCL can infer the type of basic data. We recommend writing types for complex structures and function definitions, which will clearly provide a good input prompt for other users who use structures and functions. - -```python -# Types for schema -schema App: - name: str - domainType: "Standard" | "Customized" | "Global" - containerPort: int - volumes: [Volume] - services: [Service] - - check: - 1 <= containerPort <= 65535 - -schema Service: - clusterIP: str - $type: str - - check: - clusterIP == "None" if $type == "ClusterIP" - -schema Volume: - container: str = "*" # The default value of `container` is "*" - mountPath: str - - check: - mountPath not in ["/", "/boot", "/home", "dev", "/etc", "/root"] - -# Types for lambda -appFilterFunc = lambda apps: [App], name: str -> [App] { - [a for a in apps if a.name == name] -} -``` - -More formal definitions and usage of types are at the [type specification document](/docs/reference/lang/types/) and the [tour document of the type system](/docs/reference/lang/tour#type-system) - -**Schema** is the core type in KCL, just like a database schema, which defines the organization of configuration data. This includes logical constraints such as schema names, fields, data types, and the relationships between these entities. Patterns typically use visual representations to convey the architecture of a database, becoming the foundation for organizing configuration data. The process of designing schema patterns is also known as configuration modeling. KCL Schema typically serves various roles, such as application developers, DevOps platform administrators, and SRE, and provides them with a unified configuration interaction interface. - -In addition, the ability to enforce constraints from top to bottom is crucial for any large-scale configuration setting. Therefore, KCL not only provides the ability to define static types but also provides the rich ability to define constraints, which is to some extent equivalent to assertion statements in programming languages. To prevent assertions from constantly expanding, we place structural constraints together with structural type definitions and support custom error messages. - -In KCL, we can use schema to organize the configuration data to meet the requirements of model definition, abstraction, and templating. Schema is the core feature of KCL, which defines attributes, operations, and check-blocks. Usually, a formal form of KCL Schema can be written in the following form: - -$$ -S = \Sigma_{i = 1}^{N} \{s_i, T_i, \mathcal{T}[s_i]\}, -$$ - -where $N$ is the total number of attributes, $\mathcal{T}$ is the attribute constraint, $s_i$ and $T_i$ denotes the $i$-th attribute name and type. Simultaneously, to improve the reusability of the code and meet the needs of hierarchical definition, KCL draws on the experience of OOP and uses single inheritance to reuse and extend the schema. Schema inheritance can be regarded as a special type of partial order relationship, and satisfies - -$$ -unionof(T_1, T_2) = T_2 \Leftrightarrow T_1 \subseteq T_2, -$$ - -where $T_1$ and $T_2$ are both schema types. When the above equation is not satisfied, the KCL will throw a type check error. - -A typical schema with constraints is defined as follows: - -```python -import regex - -schema Secret: - name: str - # Data defines the keys and data that will be used by secret. - data?: {str:str} - - check: - all k in data { - regex.match(k, r"[A-Za-z0-9_.-]*") - } if data, "a valid secret data key must consist of alphanumeric characters, '-', '_' or '.'" -``` - -More specifications and usage of KCL schema and constraint is [here](/docs/reference/lang/spec/schema). diff --git a/versioned_docs/version-0.8.0/user_docs/getting-started/_category_.json b/versioned_docs/version-0.8.0/user_docs/getting-started/_category_.json deleted file mode 100644 index 1bf165d4..00000000 --- a/versioned_docs/version-0.8.0/user_docs/getting-started/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Get Started", - "position": 1 -} diff --git a/versioned_docs/version-0.8.0/user_docs/getting-started/kcl-quick-start.md b/versioned_docs/version-0.8.0/user_docs/getting-started/kcl-quick-start.md deleted file mode 100644 index 2316d9a6..00000000 --- a/versioned_docs/version-0.8.0/user_docs/getting-started/kcl-quick-start.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Quick Start - -KCL is a cloud-native domain configuration and policy language. At the beginning of its design, KCL was inspired by Python3, and at the same time absorbed the conceptual design of declarative and OOP programming paradigms. In this section we will quickly demonstrate the basic features of the KCL language. - -## 1. Hello KCL - -The best way to learn a new language is to write a few small programs, and the same goes for configuring languages. We can write KCL programs just like writing configuration. - -Here is a simple `hello.k`: - -```python -hello = "KCL" -``` - -Set the `hello` attribute to the `"KCL"` string. Then save the code to the `hello.k` file. - -How to execute this program depends on the specific development environment, we first assume that the local macOS or Linux system has installed the `kcl` command (or enter the **Docker** environment test by `docker run --rm -it kcllang/kcl`) and then run the following command: - -```shell -kcl hello.k -``` - -The output is - -```yaml -hello: KCL -``` - -The effect of command line execution is shown as follows: - -![](/img/docs/user_docs/getting-started/hello.gif) - -The output is configuration data in YAML format. Although this program is simple, we can verify the basic usage of the development environment and the `kcl` command line by executing the KCL configuration program to the output. - -## 2. A little more complicated configuration - -In addition to the common key-value pairs, common configuration data also has nested dictionary and list types, and the value basic type includes boolean and numeric types in addition to strings. Here's a slightly more complex `server.k` configuration: - -```python -# This is a KCL document - -title = "KCL Example" - -owner = { - name = "The KCL Authors" - data = "2020-01-02T03:04:05" -} - -database = { - enabled = True - ports = [8000, 8001, 8002] - data = [["delta", "phi"], [3.14]] - temp_targets = {cpu = 79.5, case = 72.0} -} - -servers = [ - {ip = "10.0.0.1", role = "frontend"} - {ip = "10.0.0.2", role = "backend"} -] -``` - -where `#` begins with a line comment. The value of `owner` is a dictionary. The value of the dictionary contains the content in the form of `{}`. The key-value inside the dictionary is similar to the `hello = "KCL"` example. `database` is another dictionary in which the value of the dictionary attribute appears boolean `True`, list `[]` and dictionary `{}`, in which the value of the numeric type also appears in the list and dictionary. The `servers` attribute is a list with dictionaries nested inside the list (dictionaries and lists, as well as the `schema` that will be discussed later, can be nested within each other). - -The YAML output of this configuration is as follows: - -```yaml -$ kcl server.k -title: KCL Example -owner: - name: The KCL Authors - data: '2020-01-02T03:04:05' -database: - enabled: true - ports: - - 8000 - - 8001 - - 8002 - data: - - - delta - - phi - - - 3.14 - temp_targets: - cpu: 79.5 - case: 72.0 -servers: -- ip: 10.0.0.1 - role: frontend -- ip: 10.0.0.2 - role: backend -``` - -## 3. Define the structure of the configuration using KCL schema - -The KCL provides abstract support for attributes with a fixed attribute structure and default value behavior through the `schema` syntax. - -For example, the configuration of `database` in the above example is generally the default value. We can define a structure for the default configuration of the database: - -```python -schema DatabaseConfig: - enabled: bool = True - ports: [int] = [8000, 8001, 8002] - data: [[str|float]] = [["delta", "phi"], [3.14]] - temp_targets: {str: float} = {cpu = 79.5, case = 72.0} -``` - -`enabled` is a boolean type; `ports` is an integer list type; `data` is a list of lists, and the inner list elements are strings or floats; `temp_targets` is a dictionary type, and the attribute value of the dictionary is floating point type. And each attribute of `DatabaseConfig` defines a default value. - -Then pass `database = DatabaseConfig {}` to generate a structure with the same attributes as the default values. We can also modify the default value: - -```python -database = DatabaseConfig { - ports = [2020, 2021] -} -``` - -`schema DatabaseConfig` not only provides default values for attributes, but also adds type information to attributes. Therefore, if we accidentally writes the wrong attribute value type, KCL will give a friendly error prompt, such as the following example where `ports` is wrongly written as a floating point type: - -```python -database = DatabaseConfig { - ports = [1.2, 1.3] -} -``` - -When executed, an error similar to the following will be generated (the displayed file path depends on the local environment): - -```shell -kcl server.k -``` - -The output is - -```shell -error[E2G22]: TypeError - --> /path/to/server.k:8:5 - | -8 | ports = [1.2, 1.3] - | ^ expected [int], got [float(1.2)|float(1.3)] - | - - --> /path/to/server.k:3:5 - | -3 | ports: [int] = [8000, 8001, 8002] - | ^ variable is defined here, its type is [int], but got [float(1.2)|float(1.3)] - | -``` - -Similarly we can encapsulate the attributes of the `servers` section with the following code: - -```python -schema ServerConfig: - ip: str - role: "frontend" | "backend" - -servers = [ - ServerConfig {ip = "10.0.0.1", role = "frontend"} - ServerConfig {ip = "10.0.0.2", role = "backend"} -] -``` - -The attribute `ip` of `ServerConfig` is a string type, and no default value is given. We must manually add the value of the `ip` attribute when generating the `ServerConfig` type attribute, otherwise the KCL will report a missing required attribute error. The `role` attribute is a `"frontend" | "backend"` enumerated string type. - -In addition, `schema` can also combine `check`, `mixin`, optional attributes, inheritance and extension modules to achieve more complex configuration and policy data abstraction, full language details can be found at [here](/docs/reference/lang/tour). diff --git a/versioned_docs/version-0.8.0/user_docs/guides/_category_.json b/versioned_docs/version-0.8.0/user_docs/guides/_category_.json deleted file mode 100644 index 40b1340d..00000000 --- a/versioned_docs/version-0.8.0/user_docs/guides/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "User Guide", - "position": 4 -} diff --git a/versioned_docs/version-0.8.0/user_docs/guides/abstraction.md b/versioned_docs/version-0.8.0/user_docs/guides/abstraction.md deleted file mode 100644 index cec40e2c..00000000 --- a/versioned_docs/version-0.8.0/user_docs/guides/abstraction.md +++ /dev/null @@ -1,151 +0,0 @@ ---- -title: "Abstraction" -sidebar_position: 3 ---- - -## Introduction - -Abstraction refers to a simplified representation of an entity, typically used in computing. It allows for the concealment of specific details while presenting the most relevant information to the programmer. Each abstraction is tailored to suit a specific need, and can greatly enhance the usability of a given entity. In the context of KCL, abstraction can make code easier to understand and maintain, while also simplifying the user interface. - -It should be noted that code abstraction is not meant to reduce code size, but rather to improve maintainability and extendability. During the process of abstracting code, factors such as reusability, readability, and scalability should be taken into consideration, and the code should be optimized as needed. - -The values of the good abstraction - -1. Provides distinct focal points for better comprehension for specific identities, roles, and scenarios. -2. Shields lower-level details to avoid potential errors. -3. Enhances user-friendliness and automation with better portability and good APIs. - -KCL may not assess the rationality of a user's abstraction, but it offers technical solutions to facilitate the process. - -## Use KCL for Abstraction - -**Now, let's begin to abstract Docker Compose and Kubernetes models into an application config.** - -Application centric development allows developers to focus on their workload's architecture rather than the tech stack in the target environment, infrastructure or platform. We define our application once with the `App` schema and then use the KCL CLI to translate it to multiple platforms, such as `Docker Compose` or `Kubernetes` with different versions. - -`Docker Compose` is a tool for defining and running multi-container Docker applications. With Docker Compose, you can define your application's services, networks, and volumes in a single file, and then use it to start and stop your application as a single unit. Docker Compose simplifies the process of running complex, multi-container applications by handling the details of networking, storage, and other infrastructure concerns. - -`Kubernetes manifests` are YAML files that define Kubernetes objects such as Pods, Deployments, and Services. Manifests provide a declarative way to define the desired state of your application, including the number of replicas, the image to use, and the network configuration. Kubernetes uses the manifests to create and manage the resources needed to deploy and run your application. - -Here are some references to learn more about Docker Compose and Kubernetes manifests: - -- [Docker Compose documentation](https://docs.docker.com/compose/) -- [Kubernetes manifest documentation](https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/) - -The application model aims to reduce developer toil and cognitive load by only having to define a single KCL file that works across multiple platforms, and it is designed to be applied to multiple environments to reduce the amount of configuration. Now, let's learn how to do this. - -### 0. Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/abstraction -``` - -We can run the following command to show the config. - -```bash -cat main.k -``` - -The output is - -```python -import .app - -app.App { - name = "app" - containers.nginx = { - image = "nginx" - ports = [{containerPort = 80}] - } - service.ports = [{ port = 80 }] -} -``` - -In the above code, we defined a configuration using the `App` schema, where we configured an `nginx` container and configured it with an `80` service port. - -Besides, KCL allows developers to define the resources required for their applications in a declarative manner and is tied to a platform such as Docker Compose or Kubernetes manifests and allows to generate a platform-specific configuration file such as `docker-compose.yaml` or a Kubernetes `manifests.yaml` file. Next, let's generate the corresponding configuration. - -### 2. Transform the Application Config into Docker Compose Config - -If we want to transform the application config into the docker compose config, we can run the command simply: - -```shell -kcl main.k docker_compose_render.k -``` - -The output is - -```yaml -services: - app: - image: nginx - ports: - - published: 80 - target: 80 - protocol: TCP -``` - -### 3. Transform the Application Config into Kubernetes Deployment and Service Manifests - -If we want to transform the application config into the Kubernetes manifests, we can run the command simply: - -```shell -kcl main.k kubernetes_render.k -``` - -The output is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: app - labels: - app: app -spec: - replicas: 1 - selector: - matchLabels: - app: app - template: - metadata: - labels: - app: app - spec: - containers: - - name: nginx - image: nginx - ports: - - protocol: TCP - containerPort: 80 ---- -apiVersion: v1 -kind: Service -metadata: - name: app - labels: - app: app -spec: - selector: - app: app - ports: - - port: 80 - protocol: TCP -``` - -Look, it's so simple. If you want to learn more information about the application model, you can refer to [here](https://github.com/kcl-lang/kcl-lang.io/tree/main/examples/abstraction). - -## Summary - -Through the use of KCL, we are able to separate the abstraction and implementation details of a model, allowing for the abstract model to be mapped to various infrastructures or platforms. This is achieved through flexible switching between different implementations and the combination of compilation, which shields configuration differences and ultimately reduces the cognitive burden. - -## Further Information - -In addition to manually maintaining the configuration, we can also use KCL APIs to integrate **automatic configuration changes** into our applications. For specific instructions, please refer to [here](/docs/user_docs/guides/automation). diff --git a/versioned_docs/version-0.8.0/user_docs/guides/ci-integration/1-github-actions.md b/versioned_docs/version-0.8.0/user_docs/guides/ci-integration/1-github-actions.md deleted file mode 100644 index c4a09c6e..00000000 --- a/versioned_docs/version-0.8.0/user_docs/guides/ci-integration/1-github-actions.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -id: github-actions -sidebar_label: Github Actions ---- - -# Github Actions Integration - -## Introduction - -In the GitOps section, we have introduced how to integrate KCL with GitOps. In this section, we will continue to provide sample solutions for KCL and CI integrations. We hope to implement the end-to-end application development process by using containers, Continuous Integration (CI) for generation, and GitOps for Continuous Deployment (CD). In this scheme, we use a **Flask application** and **Github Actions** as examples. - -> Note: You can use any containerized application and different CI systems such as **Gitlab CI**, **Jenkins CI**, etc. in this solution. - -The overall workflow is as follows: - -- Develop application code and submit it to the GitHub repository to trigger CI. -- GitHub Actions generate container images from application code and push them to the `docker.io` container registry. -- GitHub Actions automatically synchronizes and updates the KCL manifest deployment file based on the version of the container image in the docker.io container registry. - -## Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -## How to - -### 1. Get the Example - -We put the application source code and infrastructure deployment code in different repos, which can be maintained by different roles to achieve the separation of concerns. - -- Get the application code - -```shell -git clone https://github.com/kcl-lang/flask-demo.git/ -cd flask-demo -``` - -This is a web application written in Python. We can use the `Dockerfile` in the application directory to generate a container image of this application, and also use Github CI to automatically build a image named `flask_demo`, the CI configuration is as follows - -```yaml -# This is a basic workflow to help you get started with Actions - -name: CI - -# Controls when the workflow will run -on: - # Triggers the workflow on push or pull request events but only for the main branch - push: - branches: [main] - pull_request: - branches: [main] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "build" - build: - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - - - name: Docker Login - uses: docker/login-action@v1.10.0 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - logout: true - - # Runs a set of commands using the runners shell - - name: build image - run: | - make image - docker tag flask_demo:latest ${{ secrets.DOCKER_USERNAME }}/flask_demo:${{ github.sha }} - docker push ${{ secrets.DOCKER_USERNAME }}/flask_demo:${{ github.sha }} - - # Trigger KCL manifest - - name: Trigger CI - uses: InformaticsMatters/trigger-ci-action@1.0.1 - with: - ci-owner: kcl-lang - ci-repository: flask-demo-kcl-manifests - ci-ref: refs/heads/main - ci-user: kcl-bot - ci-user-token: ${{ secrets.DEPLOY_ACCESS_TOKEN }} - ci-name: CI - ci-inputs: >- - image=${{ secrets.DOCKER_USERNAME }}/flask_demo - sha-tag=${{ github.sha }} -``` - -We need the workflow in the source code repository to automatically trigger the workflow in the deployment manifest repository. At this point, we need to create a `secrets.DEPLOY_ACCESS_TOKEN` with Github CI operation permissions and **Docker Hub** image push account information `secrets.DOCKER_USERNAME` and `secrets.DOCKER_PASSWORD` can be configured in the `Secrets and variables` settings of the Github, as shown in the following figure - -![](/img/docs/user_docs/guides/ci-integration/github-secrets.png) - -### 2. Commit the Application Code - -After submitting in the `flask-demo` repository, Github will automatically build a container image and push it to the Docker hub. It will also then trigger the Action of the `flask-demo-kcl-manifest` repository and modify the image value in the deployment manifest repository through [KCL Automation API](/docs/user_docs/guides/automation). Now let's create a submission in the `flask-demo` repository, and we can see that the code submission triggers the Github CI process for the application repository. - -![](/img/docs/user_docs/guides/ci-integration/app-ci.png) - -### 3. Configuration Automatic Update - -After the Github CI process in the application repository is completed, an automatic update configuration CI will be triggered in the repository where the KCL configuration is stored and submitted to the main branch of the `flask-demo-kcl-manifests` repository. The commit information is as follows - -![](/img/docs/user_docs/guides/ci-integration/image-auto-update.png) - -- We can obtain the deployment manifest source code for compilation and validation - -```shell -git clone https://github.com/kcl-lang/flask-demo-kcl-manifests.git/ -cd flask-demo-kcl-manifests -git checkout main && git pull && kcl -``` - -The output YAML is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - replicas: 1 - selector: - matchLabels: - app: flask_demo - template: - metadata: - labels: - app: flask_demo - spec: - containers: - - name: flask_demo - image: "kcllang/flask_demo:6428cff4309afc8c1c40ad180bb9cfd82546be3e" - ports: - - protocol: TCP - containerPort: 5000 ---- -apiVersion: v1 -kind: Service -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - type: NodePort - selector: - app: flask_demo - ports: - - port: 5000 - protocol: TCP - targetPort: 5000 -``` - -From the above configuration, it can be seen that the image of the resource is indeed automatically updated to the newly constructed image value. In addition, we can also use the **Argo CD KCL plugin** to automatically synchronize data from the Git repository and deploy the application to the Kubernetes cluster. - -## Summary - -By integrating KCL and Github CI, we can integrate the container build and delivery workflow by automatically updating the image values in the configuration, in order to achieve end-to-end application development process and improve R&D deployment efficiency. diff --git a/versioned_docs/version-0.8.0/user_docs/guides/ci-integration/2-gitlab-ci.md b/versioned_docs/version-0.8.0/user_docs/guides/ci-integration/2-gitlab-ci.md deleted file mode 100644 index 124e9bd9..00000000 --- a/versioned_docs/version-0.8.0/user_docs/guides/ci-integration/2-gitlab-ci.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -id: gitlab-ci -sidebar_label: Gitlab CI ---- - -# Gitlab CI Integration - -## Introduction - -In the GitOps section, we have introduced how to integrate KCL with GitOps. In this section, we will continue to provide sample solutions for KCL and CI integrations. We hope to implement the end-to-end application development process by using containers, Continuous Integration (CI) for generation, and GitOps for Continuous Deployment (CD). In this scheme, we use a **Flask application** and **Gitlab CI** as examples. - -> Note: You can use any containerized application and different CI systems such as **Github Actions**, **Jenkins CI**, etc. in this solution. - -The overall workflow is as follows: - -- Develop application code and submit it to the Gitlab repository to trigger CI. -- Gitlab generate container images from application code and push them to the `docker.io` container registry. -- Gitlab CI automatically synchronizes and updates the KCL manifest deployment file based on the version of the container image in the docker.io container registry. - -## Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -## How to - -We put the application source code and infrastructure deployment code in different repos, which can be maintained by different roles to achieve the separation of concerns. - -### 1. Get the Example - -- Get the application code - -```shell -git clone https://gitlab.com/kcl-lang/flask-demo.git/ -cd flask-demo -``` - -This is a web application written in Python. We can use the `Dockerfile` in the application directory to generate a container image of this application, and also use Gitlab CI to automatically build a image named `flask_demo`, the CI configuration is as follows - -```yaml -stages: - - publish - - deploy - -publish: - stage: publish - image: - name: cnych/kaniko-executor:v0.22.0 - entrypoint: [""] - script: - - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json - - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile ./Dockerfile --destination $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA - only: - - main - -deploy: - stage: deploy - image: cnych/kustomize:v1.0 - before_script: - - git remote set-url origin https://gitlab.com/kcl-lang/flask-demo - - git config --global user.email "gitlab@git.local" - - git config --global user.name "GitLab CI/CD" - # Install KCL - - wget -q https://kcl-lang.io/script/install.sh -O - | /bin/bash - script: - - git checkout -B main - - cd deployment - # Image auto update - - /usr/local/kclvm/bin/kcl -d -O config.containers.flask_demo.image="$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" - - git commit -am '[skip ci] image update to $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA' - - git push origin main - only: - - main -``` - -We need the workflow in the source code repository to automatically trigger the workflow in the deployment manifest repository. At this point, we need to config `Settings -> CI/CD -> Variables` including `CI_REGISTRY`, `CI_REGISTRY_IMAGE`, `CI_REGISTRY_USER`, `CI_REGISTRY_PASSWORD`, `CI_USERNAME` and `CI_PASSWORD` and update application code to trigger automation build and deploy. - -![](/img/docs/user_docs/guides/ci-integration/gitlab-ci-variables.jpg) - -### 2. Commit the Application Code - -After submitting in the `flask-demo` repository, Gitlab will automatically build a container image and push it to the Docker hub. It will also then trigger the Action of the `flask-demo-kcl-manifest` repository and modify the image value in the deployment manifest repository through [KCL Automation API](/docs/user_docs/guides/automation). Now let's create a submission in the `flask-demo` repository, and we can see that the code submission triggers the Gitlab CI process for the application repository `Build -> Pipelines` page. - -### 3. Configuration Automatic Update - -After the Gitlab CI process in the application repository is completed, an automatic update configuration CI will be triggered in the repository where the KCL configuration is stored and submitted to the main branch of the `flask-demo` repository. - -- We can obtain the deployment manifest source code for compilation and validation - -```shell -git checkout main && git pull && cd deploy && kcl -``` - -The output YAML is - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - replicas: 1 - selector: - matchLabels: - app: flask_demo - template: - metadata: - labels: - app: flask_demo - spec: - containers: - - name: flask_demo - image: "kcllang/flask_demo:6428cff4309afc8c1c40ad180bb9cfd82546be3e" - ports: - - protocol: TCP - containerPort: 5000 ---- -apiVersion: v1 -kind: Service -metadata: - name: flask_demo - labels: - app: flask_demo -spec: - type: NodePort - selector: - app: flask_demo - ports: - - port: 5000 - protocol: TCP - targetPort: 5000 -``` - -From the above configuration, it can be seen that the image of the resource is indeed automatically updated to the newly constructed image value. In addition, we can also use the **Argo CD KCL plugin** to automatically synchronize data from the Git repository and deploy the application to the Kubernetes cluster. - -## Summary - -By integrating KCL and Gitlab CI, we can integrate the container build and delivery workflow by automatically updating the image values in the configuration, in order to achieve end-to-end application development process and improve R&D deployment efficiency. diff --git a/versioned_docs/version-0.8.0/user_docs/guides/ci-integration/_3-jenkins-ci.md b/versioned_docs/version-0.8.0/user_docs/guides/ci-integration/_3-jenkins-ci.md deleted file mode 100644 index f85d231f..00000000 --- a/versioned_docs/version-0.8.0/user_docs/guides/ci-integration/_3-jenkins-ci.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -id: github-ci -sidebar_label: Github CI ---- - -Coming Soon - -## Introduction - -## How to - -## Summary diff --git a/versioned_docs/version-0.8.0/user_docs/guides/ci-integration/_category_.json b/versioned_docs/version-0.8.0/user_docs/guides/ci-integration/_category_.json deleted file mode 100644 index 3145ed7f..00000000 --- a/versioned_docs/version-0.8.0/user_docs/guides/ci-integration/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "CI Integration", - "position": 12 -} \ No newline at end of file diff --git a/versioned_docs/version-0.8.0/user_docs/guides/data-integration.md b/versioned_docs/version-0.8.0/user_docs/guides/data-integration.md deleted file mode 100644 index c05b2e7b..00000000 --- a/versioned_docs/version-0.8.0/user_docs/guides/data-integration.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: "Data Integration" -sidebar_position: 4 ---- - -## Introduction - -In KCL, we can not only compile and output the configuration code written by KCL into YAML format data, but also directly embed JSON/YAML and other data into the KCL language. - -## Use KCL for Data Integration - -### 0. Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/data-integration -``` - -### 2. YAML Integration - -We can run the following command to show the YAML integration config. - -```bash -cat yaml.k -``` - -```python -import yaml - -schema Server: - ports: [int] - -server: Server = yaml.decode("""\ -ports: -- 80 -- 8080 -""") -server_yaml = yaml.encode({ - ports = [80, 8080] -}) -``` - -In the above code, we use the built-in `yaml` module of KCL and its `yaml.decode` function directly integrates YAML data, and uses the `Server` schema to directly verify the integrated YAML data. In addition, we can use `yaml.encode` to serialize YAML data. We can obtain the configuration output through the following command: - -```shell -kcl yaml.k -``` - -The output is - -```yaml -server: - ports: - - 80 - - 8080 -server_yaml: | - ports: - - 80 - - 8080 -``` - -### 3. JSON Integration - -Similarly, for JSON data, we can use `json.encode` and `json.decode` function performs data integration in the same way. - -We can run the following command to show the JSON integration config. - -```bash -cat json.k -``` - -```python -import json - -schema Server: - ports: [int] - -server: Server = json.decode('{"ports": [80, 8080]}') -server_json = json.encode({ - ports = [80, 8080] -}) -``` - -The output of the execution command is: - -```shell -kcl json.k -``` - -```yaml -server: - ports: - - 80 - - 8080 -server_json: '{"ports": [80, 8080]}' -``` - -## Summary - -This document introduces how to perform data integration in KCL, using the built-in yaml and json modules to directly integrate YAML and JSON data into the KCL language, and verify and serialize it using the corresponding decoding and encoding functions. diff --git a/versioned_docs/version-0.8.0/user_docs/guides/gitops/_category_.json b/versioned_docs/version-0.8.0/user_docs/guides/gitops/_category_.json deleted file mode 100644 index 29a73c67..00000000 --- a/versioned_docs/version-0.8.0/user_docs/guides/gitops/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "GitOps", - "position": 11 -} \ No newline at end of file diff --git a/versioned_docs/version-0.8.0/user_docs/guides/package-management/4-how-to/_category_.json b/versioned_docs/version-0.8.0/user_docs/guides/package-management/4-how-to/_category_.json deleted file mode 100644 index e3409c62..00000000 --- a/versioned_docs/version-0.8.0/user_docs/guides/package-management/4-how-to/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "How to", - "position": 4 -} diff --git a/versioned_docs/version-0.8.0/user_docs/guides/package-management/_category_.json b/versioned_docs/version-0.8.0/user_docs/guides/package-management/_category_.json deleted file mode 100644 index 1211443e..00000000 --- a/versioned_docs/version-0.8.0/user_docs/guides/package-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Package Management Tools", - "position": 7 -} diff --git a/versioned_docs/version-0.8.0/user_docs/guides/schema-definition.md b/versioned_docs/version-0.8.0/user_docs/guides/schema-definition.md deleted file mode 100644 index ecb118ac..00000000 --- a/versioned_docs/version-0.8.0/user_docs/guides/schema-definition.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -title: "Schema Definition" -sidebar_position: 3 ---- - -## Introduction - -The core scenario of KCL is write configurations and constraints. and a core feature of KCL is **modeling**. The keyword `schema` in KCL can be used to define structures and constraints, such as attribute types, default values, range check, and various other constraints. In addition, structures defined with KCL schema can be used in turn to verify implementation, validate input (JSON, YAML and other structured data) or generate code (multilingual structures, OpenAPI, and so on). - -## Use KCL for Defining Structures and Constraints - -### 0. Prerequisite - -- Install [KCL](https://kcl-lang.io/docs/user_docs/getting-started/install) - -### 1. Get the Example - -Firstly, let's get the example. - -```bash -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/definition -``` - -We can run the following command to show the config. - -```bash -cat main.k -``` - -The output is - -```python -import .app_module # A relative path import - -app: app_module.App { - domainType = "Standard" - containerPort = 80 - volumes = [ - { - mountPath = "/tmp" - } - ] - services = [ - { - clusterIP = "None" - $type = "ClusterIP" - } - ] -} -``` - -We put the `app` model into a separate `app_module.k`, then we can use the `import` keyword in `main.k` for modular management, such as the following file structure - -``` -. -├── app_module.k -└── main.k -``` - -The content of `app_module.k` is - -```python -schema App: - domainType: "Standard" | "Customized" | "Global" - containerPort: int - volumes: [Volume] - services: [Service] - - check: - 1 <= containerPort <= 65535 - -schema Service: - clusterIP: str - $type: str - - check: - clusterIP == "None" if $type == "ClusterIP" - -schema Volume: - container: str = "*" # The default value of `container` is "*" - mountPath: str - - check: - mountPath not in ["/", "/boot", "/home", "dev", "/etc", "/root"] -``` - -In the above file, we use the `schema` keyword to define three models `App`, `Service` and `Volume`. The `App` model has four attributes `domainType`, `containerPort`, `volumes` and `services`, where - -- The type of `domainType` is a string literal union type, similar to an "enumeration", which means that the value of `domainType` can only take one of `"Standard"`, `"Customized"` and `"Global"`. -- The type of `containerPort` is an integer (`int`). In addition, we use the `check` keyword to define its value range from 1 to 65535. -- The type of `services` is `Service` schema list type, and we use `?` to mark it as an optional attribute. -- The type of `volumes` is a `Volume` schema list type, and we use `?` to mark it as an optional attribute. - -We can get the YAML output of the `app` instance by using the following command line - -```shell -kcl main.k -``` - -The output is - -```yaml -app: - domainType: Standard - containerPort: 80 - volumes: - - container: "*" - mountPath: /tmp - services: - - clusterIP: None - type: ClusterIP -``` - -### 2. Output Configuration - -We can still get the YAML output of the `app` instance by using the following command line - -```shell -kcl main.k -``` - -The output is - -```yaml -app: - domainType: Standard - containerPort: 80 - volumes: - - container: "*" - mountPath: /tmp - services: - - clusterIP: None - type: ClusterIP -``` - -## Summary - -KCL is a language for defining configurations and constraints, with a core feature of modeling using the schema keyword. This allows for the definition of structures with attributes, default values, range checks, and other constraints. Structures defined using KCL schema can be used to validate data, or generate code. The example demonstrates how to define models using schema, import them for modular management, and output the YAML configuration of an instance of the defined structure using the kcl command. diff --git a/versioned_docs/version-0.8.0/user_docs/guides/secret-management/1-vault.md b/versioned_docs/version-0.8.0/user_docs/guides/secret-management/1-vault.md deleted file mode 100644 index 6da58286..00000000 --- a/versioned_docs/version-0.8.0/user_docs/guides/secret-management/1-vault.md +++ /dev/null @@ -1,142 +0,0 @@ ---- -id: vault -sidebar_label: Vault ---- - -# Vault - -## Introduction - -This guide will show you that KCL solves the secret management problem by integrating [Vault](https://developer.hashicorp.com/vault) and [Vals](https://github.com/helmfile/vals). - -## Prerequisites - -- Install [KCL](/docs/user_docs/getting-started/install) -- Prepare a [Kubernetes Cluster](https://kubernetes.io/) -- Install [Vault](https://developer.hashicorp.com/vault/downloads) -- Install [Vals](https://github.com/helmfile/vals) - -## How to - -### 1. Get the Example - -We put the application source code and infrastructure deployment code in different repos, which can be maintained by different roles to achieve the separation of concerns. - -- Get the application code - -```shell -git clone https://github.com/kcl-lang/kcl-lang.io.git/ -cd ./kcl-lang.io/examples/secret-management/vault -``` - -- Show the config - -```shell -cat main.k -``` - -The output is - -```python -# Secret Management using Vault and Vals - -apiVersion = "apps/v1" -kind = "Deployment" -metadata = { - name = "nginx" - labels.app = "nginx" - annotations: { - "secret-store": "vault" - # Valid format: - # "ref+vault://PATH/TO/KV_BACKEND#/KEY" - "foo": "ref+vault://secret/foo#/foo" - "bar": "ref+vault://secret/bar#/bar" - } -} -spec = { - replicas = 3 - selector.matchLabels = metadata.labels - template.metadata.labels = metadata.labels - template.spec.containers = [ - { - name = metadata.name - image = "${metadata.name}:1.14.2" - ports = [{ containerPort = 80 }] - } - ] -} -``` - -The main.k file extends the configuration of the Nginx application and customizes annotations. Among them, the value of annotation `foo` and `bar` follow secret reference format (`ref+vault://PATH/TO/KV_BACKEND#/KEY`): - -- `ref+vault`: indicates that this is a secret reference, and the external storage service is `Vault`. -- `PATH/TO/KV_BACKEND`: specifies the path where a secret is stored. -- `KEY`: specifies the key to reading secret. - -The complete format is concatenated using a style similar to URI expressions, which can retrieve a secret stored externally. - -### 2. Pre-store Secrets - -Start the Vault Server - -```shell -vault server -dev -export VAULT_ADDR='http://127.0.0.1:8200' -# Note: Replace with your token -export VAULT_TOKEN=yourtoken -``` - -After Vault is started in development mode and unpacked, secrets are pre-stored, and the path and keys are consistent with `main.k`: - -```shell -vault kv put secret/foo foo=foo -vault kv put secret/bar bar=bar -``` - -### 3. Deploy Configuration - -Using the following command to apply the deployment manifest. - -```shell -kcl main.k | vals eval -f - | kubectl apply -f - -``` - -The expect output is - -```shell -deployment.apps/nginx created -``` - -### 4. Verify Secrets - -Next, verify that the secrets have been retrieved from Vault and replace the values of annotations of Nginx: - -- Verify the `foo` annotation - -```shell -kubectl get deploy nginx -o yaml | grep 'foo:' -``` - -The output is - -```yaml -foo: foo -``` - -- Verify the `bar` annotation - -```shell -kubectl get deploy nginx -o yaml | grep 'bar:' -``` - -The output is - -```yaml -bar: bar -``` - -So far, we have retrieved the secrets hosted in `Vault` and put them into use. - -## Summary - -This guide introduces how KCL solves the secret management by integrating Vault and Vals. By following these steps, we can retrieve the secrets hosted in Vault and utilize them. diff --git a/versioned_docs/version-0.8.0/user_docs/guides/secret-management/_category_.json b/versioned_docs/version-0.8.0/user_docs/guides/secret-management/_category_.json deleted file mode 100644 index c57bb30e..00000000 --- a/versioned_docs/version-0.8.0/user_docs/guides/secret-management/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Secret Management", - "position": 13 -} diff --git a/versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json b/versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json deleted file mode 100644 index 6e90c03c..00000000 --- a/versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Mutate or Validate Kubernetes Manifests", - "position": 3 -} diff --git a/versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/_category_.json b/versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/_category_.json deleted file mode 100644 index 42681f2b..00000000 --- a/versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Kubernetes", - "position": 9 -} diff --git a/versioned_docs/version-0.8.0/user_docs/guides/working-with-konfig/4-best-practice.md b/versioned_docs/version-0.8.0/user_docs/guides/working-with-konfig/4-best-practice.md deleted file mode 100644 index ee0cc576..00000000 --- a/versioned_docs/version-0.8.0/user_docs/guides/working-with-konfig/4-best-practice.md +++ /dev/null @@ -1,449 +0,0 @@ ---- -id: practice -sidebar_label: Best Practice ---- - -# Best Practice - -This document aims to explain the best practices for integrating new models into the Konfig library and designing, building and writing KCL code models. New models are generally designed and abstracted using the best practice of separating front-end and back-end models. The direct purpose of distinguishing between front-end and back-end models is to separate `"user interface"` and `"model implementation"`, achieving a user-friendly and simple configuration interface as well as automated configuration query and modification interfaces. - -## Workflow - -![](/img/docs/user_docs/guides/konfig/workflow.png) - -1. **Coding**. Use the KCL OpenAPI tool to generate KCL schemas from the Customer Resources Definitions (CRDs) or OpenAPI Swagger models. These schemas define the atomic capabilities of the platform. -1. **Abstraction**. Based on these atomic capabilities, the platform abstracts user-oriented front-end models and provides a set of templates. These front- - end models cannot work independently, and corresponding back-end models are required. These back-end models will eventually obtain an instance of the front-end model at runtime; it parses the input front-end model and converts it into Kubernetes resources. -1. **Configuration**. Developers or SREs describe the requirements of applications based on front-end models. Users can define the base and different environment configurations for different environments e.g., base, development and production and different localities. In most cases, defining configurations only requires declaring key-value pairs. For some complex scenarios, users can define the logic to generate configurations. -1. **Automation**. After defining the user's configuration, all components have been defined and are ready to be automated. The platform can compile, execute, output, modify, query, and perform other automatic works through the KCL CLI or GPL-binding APIs. Users can also deploy the KCL configuration to the Kubernetes cluster with tools. - -## Model Structure - -Just as web applications provide a friendly user interface, and user input is further inferred at the backend of the application to obtain the final data that falls into the database, similarly, using KCL for model design also follows the logic of front-end and back-end separation. In addition, when the downstream required data content changes, we only need to modify the rendering/logic of the user configuration data to the backend model, thereby avoiding large-scale modification of user configurations. - -Taking the sidecar configuration of application services as an example: - -```python -# Config user interface. -user_sidecar_feature_gates: str - -# Downstream config of processing. -sidecars = [ - { - name = "sidecar_name" # Additional template for sidecars parameters, users do not need to configure them. - feature_gates = user_sidecar_feature_gates - } -] -``` - -## Best Practices for Konfig Modeling - -### Use Single Attribute Instead of Configuration Templates - -For some backend models, the configuration attributes that need to be filled in are often large and comprehensive designs, requiring users to actively input more complex configuration templates, and the filling content of this attribute is basically the same for different users. For example, the configuration of logic shown below requires users to fill in a large amount of template data, which has a high mental cost. - -A simple best practice is to abstract such commonly used and complex templates into a simple attribute `overQuota` with the `bool` type in the front-end model, allowing users to do multiple-choice questions instead of filling in blank questions. For example, when the `overQuota` attribute is `True`, the back-end model will render this complex logic. - -- The front-end attribute `overQuota` - -```python -overQuota: bool -``` - -- The back-end YAML output: - -```yaml -spec: - template: - spec: - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: k8s/is-over-quota - operator: In - values: - - "true" -``` - -In addition, different template names can be designed according to specific business scenarios to fill in the blanks, such as designing an attribute template in the code shown below to assist users in template selection instead of directly filling in the template content. The legal template value can be `"success_ratio"` or `"service_cost"`. When the backend model extends more templates, the front-end code does not need to make any modifications, only needs to adapt the corresponding template logic in the backend model. - -```python -schema SLI: - template: str = "success_ratio" -``` - -In addition, it is recommended to avoid using complex structures directly as front-end model attributes to avoid users needing to rely on too many KCL syntax features (such as unpacking, looping, etc.) or writing many temporary variables to complete the instantiation of the structure when using the model. - -### Use Literal Type and Union Type - -In the above section, it was mentioned that a string attribute can be used to represent different template names, and further, a literal type can be used to express the optional content of the template. For example, the following improvements can be made. - -```python -schema SLI: - template: "success_ratio" | "service_cost" = "success_ratio" -``` - -The type of template is a combination of two string types, indicating that the template can only be `"success_ratio"` or `"service_cost"`. When the user fills in the values of other strings, the KCL compiler will report an error. - -In addition to using union types for literal types, KCL also supports union for complex types such as schema types. For the support of this backend **oneof** configuration, KCL has built-in composite structure union types for support. For example, we can define our own SLI front-end types for various scenarios: `CustomSliDataSource`, `PQLSLIDataSource`, and `StackSLIDataSource`. - -```python -schema CustomSLIDataSource: - customPluginUrl: str - -schema PQLSLIDataSource: - total?: str - error?: str - success?: str - cost?: str - count?: str - -schema StackSLIDataSource: - stack: str - groupBy?: str - metric?: str - -# Simplify type definitions using type aliases -type DataSource = CustomSLIDataSource | PQLSLIDataSource | StackSLIDataSource - -schema DataConfiguration: - sources: {str: DataSource} -``` - -The advantage of designing this front-end model is that the compiler can statically check that the type written by the user can only be a certain type. If the back-end model is used directly, it cannot directly obtain the mapping relationship between different types of types and the fields that need to be filled in from the model. - -In addition, the overall design of the front-end model should also consider horizontal scalability, using the union type as much as possible, fully utilizing the advantages of coding, and avoiding unnecessary large amounts of code restructuring and modification when connecting to different backend or backend models. In addition, for the factory pattern commonly used in other GPL languages, union types can also be used instead in KCL. For example, if you want to obtain a constructor of a type based on the content of a string, you can directly use union types for optimization. - -Using the factory pattern in KCL: - -```python -schema DataA: - id?: int = 1 - value?: str = "value" - -schema DataB: - name?: str = "DataB" - -_dataFactory: {str:} = { - DataA = DataA - DataB = DataB -} -dataA = _dataFactory["DataA"]() -dataB = _dataFactory["DataB"]() -``` - -Replacing the factory pattern with the KCL union type. - -```python -schema DataA: - id?: int = 1 - value?: str = "value" - -schema DataB: - name?: str = "DataB" - -# Just use the union type. -dataA: DataA | DataB = DataA() -dataB: DataA | DataB = DataB() -``` - -### Use Dict Instead of List As Much As Possible - -To make it easier to modify configurations on-site or automate queries, it is advisable to define list or array attributes as dictionary types for easy indexing. In many complex configuration scenarios, the index of a list is arbitrary and the order of elements has no impact on the configuration. Using a dictionary type instead of a list type allows for more convenient data querying and modification. For example: - -```python -schema Person: - name: str - age: int - -schema House: - persons: [Person] - -house = House { - persons = [ - Person { - name = "Alice" - age = 18 - } - Person { - name = "Bob" - age = 10 - } - ] -} -``` - -For example, in the above example, if you want to query the age of the person named `"Alice"` from the list of persons in the house, you need to loop through the list to find Alice's age. However, if you define persons as a dictionary like the following code, it not only looks more concise in code, but you can also directly retrieve Alice's age by using house.persons.Alice.age. In addition, the information of the entire configuration is complete and has no redundant information. - -```python -schema Person: - age: int - -schema House: - persons: {str: Person} # Use Dict Instead of List - -house = House { - persons = { - Alice = Person { age = 18 } - Bob = Person { age = 10 } - } -} -``` - -### Write Validation Expressions for Models - -For frontend models, it is often necessary to validate the fields filled in by users. In this case, KCL's check expressions can be used in conjunction with KCL's built-in functions/syntax/system libraries to perform field validation. For frontend model validation, it is recommended to directly write it in the frontend model definition as a prerequisite for validation, in order to avoid unexpected errors that may occur when the errors are passed to the backend model. - -Use all/any expressions and check expressions for validation - -```python -import regex - -schema ConfigMap: - name: str - data: {str:str} - configMounts?: [ConfigMount] - - check: - all k in data { - regex.match(k, r"[A-Za-z0-9_.-]*") - }, "a valid config key must consist of alphanumeric characters, '-', '_' or '.'" - -schema ConfigMount: - containerName: str - mountPath: str - subPath?: str - - check: - ":" not in mountPath, "mount path must not contain ':'" -``` - -### Use Numerical Unit Type - -Numbers with units in KCL have a built-in type of `units.NumberMultiplier`, and any arithmetic operations are not allowed. - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -x0: NumberMultiplier = 1M # Ok -x1: NumberMultiplier = x0 # Ok -x2 = x0 + x1 # Error: unsupported operand type(s) for +: 'number_multiplier(1M)' and 'number_multiplier(1M)' -``` - -We can use the `int()/float()` function and `str()` function to convert the number unit type to integer or string type, and the resulting string retains the units of the original number unit type. - -```python -a: int = int(1Ki) # 1024 -b: str = str(1Mi) # "1Mi" -``` - -The definitions related to Kubernetes Resource in Konfig can be written using numerical unit types - -```python -import units - -type NumberMultiplier = units.NumberMultiplier - -schema Resource: - cpu?: NumberMultiplier | int = 1 - memory?: NumberMultiplier = 1024Mi - disk?: NumberMultiplier = 10Gi - epchygontee?: int -``` - -### Automated Modification of Front-end Model Instances - -In KCL, automated modification of front-end model instances can be achieved through the CLI and API. For example, if we want to modify the image content of an application (Konfig Stack Path: apps/nginx example/dev) configuration, we can directly execute the following command to modify the image content. - -```python -kcl -Y kcl.yaml ci-test/settings.yaml -o ci-test/stdout.golden.yaml -d -O :appConfiguration.image=\"test-image-v1\" -``` - -For more documentation related to automation, please refer to the [Automation Documents](/docs/user_docs/guides/automation) section. - -### Use Functions - -```python -# Define a function that adds two numbers and returns the result。 -add = lambda x, y { - x + y -} -# Define a function that subs two numbers and returns the result。 -sub = lambda x, y { - x - y -} -# Call the function, pass in arguments, and obtain the return value. -result = sub(add(2, 3), 2) # The result is 3. -``` - -The output YAML is - -```yaml -result: 3 -``` - -### Use Package and Module - -Create a package called `utils.k`, define a KCL function called `add` in it, and import it into another file for use. - -- `utils.k` - -```python -# utils.k - -# Define a function that adds two numbers and returns the result。 -add = lambda x, y { - x + y -} - -# Define a function that subs two numbers and returns the result。 -sub = lambda x, y { - x - y -} -``` - -- `main.k` - -```python -# main.k -import .utils - -# Call the function, pass in arguments, and obtain the return value. -result = utils.sub(utils.add(2, 3), 2) # The result is 3. -``` - -### Simplify Logical Expressions Using Configuration - -```python -# Complex Logic, `_cpu` is a non-exported and mutable attribute. -_cpu = 256 -_priority = "1" - -if _priority == "1": - _cpu = 256 -elif _priority == "2": - _cpu = 512 -elif _priority == "3": - _cpu = 1024 -else: - _cpu = 2048 - -# Simplify Logic Expression using Config -cpuMap = { - "1" = 256 - "2" = 512 - "3" = 1024 -} -# Get cpu from the cpuMap, when not found, use the default value 2048. -cpu = cpuMap[_priority] or 2048 -``` - -The output is - -```yaml -cpuMap: - "1": 256 - "2": 512 - "3": 1024 -cpu256: 256 -cpu2048: 2048 -``` - -### Separate Logic and Data - -We can use KCL **schema**, **config**, and **lambda** to separate **data** and **logic** as much as possible. - -For example, we can write the following code (main.k). - -```python -schema Student: - """Define a `Student` schema model with documents. - - Attributes - ---------- - name : str, required - The name of the student. - id : int, required. - The id number of the student. - grade : int, required. - The grade of the student. - - Examples - -------- - s = Student { - name = "Alice" - id = 1 - grade = 80 - } - - """ - name: str - id: int - grade: int - - # Define constraints for the `Student` model. - check: - id >= 0 - 0 <= grade <= 100 - -# Student data. -students: [Student] = [ - {name = "Alice", id = 1, grade = 85} - {name = "Bob", id = 2, grade = 70} - {name = "Charlie", id = 3, grade = 90} - {name = "David", id = 4, grade = 80} - {name = "Eve", id = 5, grade = 95} -] - -# Student logic. -query_student_where_name = lambda students: [Student], name: str { - # Query the first student where name is `name` - filter s in students { - s.name == name - }?[0] -} - -alice = query_student_where_name(students, name="Alice") -bob = query_student_where_name(students, name="Bob") -``` - -The output is - -```yaml -students: - - name: Alice - id: 1 - grade: 85 - - name: Bob - id: 2 - grade: 70 - - name: Charlie - id: 3 - grade: 90 - - name: David - id: 4 - grade: 80 - - name: Eve - id: 5 - grade: 95 -alice: - name: Alice - id: 1 - grade: 85 -bob: - name: Bob - id: 2 - grade: 70 -``` - -### Add Comments for Models - -To facilitate user understanding and automatic model documentation generation, it is necessary to write comments for the defined model. The comment content usually includes an explanation of the model, an explanation of model fields, types, default values, usage examples, and more. For detailed KCL schema code commenting guidelines and automatic model documentation generation, please refer to the [KCL Documentation Specification](/docs/tools/cli/kcl/docgen). Additionally, we can use the `kcl-doc generate` command to extract documentation from the user-specified file or directory and output it to the specified directory. - -## Backend Model - -The backend model is an "implementation model," which mainly includes the logical code to map the frontend model to the backend model. After the frontend model is written, we can use the frontend model schema to create frontend model instances, and write the corresponding backend mapping/rendering code to convert these frontend instances into the backend model. By using KCL's multi-file compilation and `Schema.instances()` function, the frontend and backend code can be highly decoupled, so that users only need to focus on frontend configuration without being aware of the complex validation and logical code of the model. diff --git a/versioned_docs/version-0.8.0/user_docs/guides/working-with-konfig/_category_.json b/versioned_docs/version-0.8.0/user_docs/guides/working-with-konfig/_category_.json deleted file mode 100644 index a71426f9..00000000 --- a/versioned_docs/version-0.8.0/user_docs/guides/working-with-konfig/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Konfig", - "position": 10 -} diff --git a/versioned_docs/version-0.8.0/user_docs/guides/working-with-kusion/_category_.json b/versioned_docs/version-0.8.0/user_docs/guides/working-with-kusion/_category_.json deleted file mode 100644 index 9f914498..00000000 --- a/versioned_docs/version-0.8.0/user_docs/guides/working-with-kusion/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "KusionStack", - "position": 15 -} diff --git a/versioned_docs/version-0.8.0/user_docs/guides/working-with-kusion/index.md b/versioned_docs/version-0.8.0/user_docs/guides/working-with-kusion/index.md deleted file mode 100644 index 2565ad03..00000000 --- a/versioned_docs/version-0.8.0/user_docs/guides/working-with-kusion/index.md +++ /dev/null @@ -1,15 +0,0 @@ -# KusionStack - -**KusionStack is an open-source cloud-native programmable technology stack!** - -KusionStack is a highly flexible programmable technology stack to enable unified application delivery and operation, inspired by the word Fusion, which aims to help enterprises build an application-centric configuration management plane and DevOps ecosystem. - -1. Fusion of hybrid scenarios of **private cloud**, **hybrid cloud**, and **multi-cloud** -2. Fusion of hybrid platform technologies of **cloud-native** and a variety of other platform technologies -3. Fusion of enterprise-level demands of **multi-project**, **multi-team**, **multi-role**, **multi-tenant**, and **multi-environment** - -Based on the concept of Platform as Code, developers can quickly unify the full configuration schemas, constraints, policies and configs across the application life cycle, work with the **hybrid technologies and cloud environment**, go through the **end-to-end workflow** from programming to launching, and truly achieve **write once, deliver anywhere**. - -![](/img/docs/user_docs/intro/kusion-stack-1.png) - -More documents and use cases at [https://kusionstack.io/](https://kusionstack.io/) diff --git a/versioned_docs/version-0.8.0/user_docs/support/_category_.json b/versioned_docs/version-0.8.0/user_docs/support/_category_.json deleted file mode 100644 index 60548d80..00000000 --- a/versioned_docs/version-0.8.0/user_docs/support/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "FAQ", - "position": 6 -} diff --git a/versioned_docs/version-0.8.0/user_docs/support/faq-cli.md b/versioned_docs/version-0.8.0/user_docs/support/faq-cli.md deleted file mode 100644 index ab012a34..00000000 --- a/versioned_docs/version-0.8.0/user_docs/support/faq-cli.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Command Line Tool - -## 1. What is the function of the `settings.yaml` in the application directory of the Konfig? - -The `settings.yaml` in KCL indicates the configuration file of the KCL command line tool. You can put the compiled configuration into it, such as the file to be compiled, the option dynamic parameter that needs to be input(`-d`), whether to ignore the null value(`-n`) and other configurations. - -For example, for the following arguments: - -```shell -kcl main.k -D key=value -n -r -``` - -It can be replaced by the following command line arguments and `settings.yaml` - -```shell -kcl -Y settings.yaml -``` - -settings.yaml - -```yaml -kcl_cli_configs: - files: - - main.k - disable_none: true - strict_range_check: true -kcl_options: - - key: key - value: value -``` - -- `kcl_cli_configs` indicates configurable compilation arguments, `file` indicates the KCL file used for compilation,`disable_none` indicates whether to use `-n`, `strict_range_check` indicates whether to use `-r`. -- `kcl_options` indicates dynamic options that can be configured, `key` indicates option name, `value` indicates option value - -Note: The file name does not need to be `settings.yaml`, but the configuration in it must meet the requirements. - -### 2. How to input dynamic options? How to get dynamic options in code? - -KCL supports multiple ways to input dynamic options - -- `-D`: Use the command line argument `-D` to input dynamic options. It supports basic data types str/int/float/bool and structured data types list/dict - -```shell -kcl main.k -D env-type=TEST -D deploy-topology='[{"cluster":"my-cluster","idc":"my-idc","replicas":2,"workspace":"my-idc","zone":"my-zone"}]' -``` - -- `-Y`: Use the command line argument `-Y` to input dynamic options by configuration file: - -```yaml -kcl_options: - - key: env-type - value: TEST - - key: deploy-topology - value: - - cluster: my-cluster - idc: my-idc - replicas: 2 - workspace: my-workspace - zone: my-zone -``` - -Use the built-in function `option()` to get it: - -```python -env = option("env-type") -deploy_topology = option("deploy-topology") -``` - -Output: - -```yaml -env: TEST -deploy_topology: - - cluster: my-cluster - idc: my-idc - replicas: 2 - workspace: my-workspace - zone: my-zone -``` - -### 3. How to compile multiple files? - -- Input multiple files in the command line: - -```shell -kcl file1.k file2.k file3.k -``` - -- Set multiple files in configuration file and use command line argument `-Y`: - -settings.yaml - -```yaml -kcl_cli_configs: - files: - - file1.k - - file2.k - - file3.k -``` - -```shell -kcl -Y settings.yaml -``` diff --git a/versioned_docs/version-0.8.0/user_docs/support/faq-yaml.md b/versioned_docs/version-0.8.0/user_docs/support/faq-yaml.md deleted file mode 100644 index b13a0f7a..00000000 --- a/versioned_docs/version-0.8.0/user_docs/support/faq-yaml.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -sidebar_position: 3 ---- - -# YAML - -## 1. What is the difference between single and double quote YAML strings? - -- YAML double-quoted strings are the only style that can express arbitrary strings, by using `\` escape characters, such as `\"` to escape double quotes `"`, `\\` to escape backslashes `\`, and a single backslash `\` can be used as a continuation character for double-quoted strings. -- YAML single-quoted strings differ from YAML double-quoted strings in that `\` and `"` can be used freely without escaping, but two single-quotes `''` are used to escape single-quote `'` characters. - -For the following example, the contents of the three string variables are the same. - -```yaml -string1: 'here '' s to "quotes"' -string2: 'here''s to "quotes"' -string3: here's to "quotes" -``` - -> Note: KCL's strategy for outputting YAML strings is to output unquoted strings or double-quoted strings preferentially when single quotes appear in the string content, and output single-quoted strings in other cases to avoid the burden of understanding. - -For more details, please refer to [YAML Spec v1.2](https://yaml.org/spec/1.2.1/) - -## 2. What is the meaning of symbols such as | - + > in YAML? - -When using KCL multi-line strings (triple quote strings), the output YAML often carries some special tokens, such as `|`, `-`, `+` and `>`, etc. These tokens usually are the representation method of YAML multi-line string, such as the following KCL code: - -```python -data = """This is a KCL multi line string (the first line) -This is a KCL multi line string (the second line) -This is a KCL multi line string (the third line) - - -""" -var = 1 -``` - -The output YAML is - -```yaml -data: |+ - This is a KCL multi line string (the first line) - This is a KCL multi line string (the second line) - This is a KCL multi line string (the third line) - - -var: 1 -``` - -- `|` represents **block style**, which is used to represent a multi-line string, where all newlines in the string represent the real newlines. -- `>` represents **folding style**, in which all newlines in the string will be replaced by spaces. -- `+` and `-` are used to control the use of newlines at the end of strings. The default is to keep a single newline at the end of the string. If we want to remove all newlines, we can put a `-` after the style indicator `|` or `>`. If we want to keep the newline at the end, we need to put a `+` after `|` or `>`. - -For more details, please refer to [YAML Multiline String](https://yaml-multiline.info/) and [YAML Spec v1.2](https://yaml.org/spec/1.2.1/) - -## 3. What is the meaning of numbers that appear after symbols | - + > such as |1 and |2 in YAML? - -Numbers represent **explicit indentation indicators** in YAML. For long strings in YAML, YAML usually the first non-blank line determines the indentation level of the string, and when the first non-blank line is preceded by a non-leading character, such as a newline, we must use **explicit indent indicators** to specify the indent level of the content, such as `|1` and `|2` etc. - -For example, for the following KCL code: - -```python -longStringStartWithNewline = """ -This is the second line -This is the third line -""" - -``` - -```yaml -longStringStartWithNewline: |2 - - This is the second line - This is the third line -``` - -- Writing long strings from the first line. - -```python -longString = """This is the second line -This is the third line -""" -``` - -- Writing long strings with line continuation characters. - -```python -longString = """\ -This is the second line -This is the third line -""" -``` - -The YAML output by the above two methods is: - -```yaml -longString: | - This is the second line - This is the third line -``` - -For more details, please refer to [YAML Spec v1.2](https://yaml.org/spec/1.2.1/) diff --git a/versioned_docs/version-0.5.3/community/contribute/_category_.json b/versioned_docs/version-0.8/community/contribute/_category_.json similarity index 100% rename from versioned_docs/version-0.5.3/community/contribute/_category_.json rename to versioned_docs/version-0.8/community/contribute/_category_.json diff --git a/versioned_docs/version-0.5.3/community/contribute/contribute-code.md b/versioned_docs/version-0.8/community/contribute/contribute-code.md similarity index 100% rename from versioned_docs/version-0.5.3/community/contribute/contribute-code.md rename to versioned_docs/version-0.8/community/contribute/contribute-code.md diff --git a/versioned_docs/version-0.5.3/community/contribute/contribute-docs.md b/versioned_docs/version-0.8/community/contribute/contribute-docs.md similarity index 100% rename from versioned_docs/version-0.5.3/community/contribute/contribute-docs.md rename to versioned_docs/version-0.8/community/contribute/contribute-docs.md diff --git a/versioned_docs/version-0.5.3/community/contribute/contribute.md b/versioned_docs/version-0.8/community/contribute/contribute.md similarity index 100% rename from versioned_docs/version-0.5.3/community/contribute/contribute.md rename to versioned_docs/version-0.8/community/contribute/contribute.md diff --git a/versioned_docs/version-0.8.0/community/contribute/git-guideline.md b/versioned_docs/version-0.8/community/contribute/git-guideline.md similarity index 100% rename from versioned_docs/version-0.8.0/community/contribute/git-guideline.md rename to versioned_docs/version-0.8/community/contribute/git-guideline.md diff --git a/versioned_docs/version-0.5.3/community/intro/_category_.json b/versioned_docs/version-0.8/community/intro/_category_.json similarity index 100% rename from versioned_docs/version-0.5.3/community/intro/_category_.json rename to versioned_docs/version-0.8/community/intro/_category_.json diff --git a/versioned_docs/version-0.5.3/community/intro/intro.md b/versioned_docs/version-0.8/community/intro/intro.md similarity index 100% rename from versioned_docs/version-0.5.3/community/intro/intro.md rename to versioned_docs/version-0.8/community/intro/intro.md diff --git a/versioned_docs/version-0.5.3/community/intro/license.md b/versioned_docs/version-0.8/community/intro/license.md similarity index 100% rename from versioned_docs/version-0.5.3/community/intro/license.md rename to versioned_docs/version-0.8/community/intro/license.md diff --git a/versioned_docs/version-0.5.3/community/intro/support.md b/versioned_docs/version-0.8/community/intro/support.md similarity index 100% rename from versioned_docs/version-0.5.3/community/intro/support.md rename to versioned_docs/version-0.8/community/intro/support.md diff --git a/versioned_docs/version-0.5.3/community/release-policy/_category_.json b/versioned_docs/version-0.8/community/release-policy/_category_.json similarity index 100% rename from versioned_docs/version-0.5.3/community/release-policy/_category_.json rename to versioned_docs/version-0.8/community/release-policy/_category_.json diff --git a/versioned_docs/version-0.5.3/community/release-policy/index.md b/versioned_docs/version-0.8/community/release-policy/index.md similarity index 100% rename from versioned_docs/version-0.5.3/community/release-policy/index.md rename to versioned_docs/version-0.8/community/release-policy/index.md diff --git a/versioned_docs/version-0.8.0/community/release-policy/kcl.md b/versioned_docs/version-0.8/community/release-policy/kcl.md similarity index 100% rename from versioned_docs/version-0.8.0/community/release-policy/kcl.md rename to versioned_docs/version-0.8/community/release-policy/kcl.md diff --git a/versioned_docs/version-0.8.0/community/release-policy/roadmap.md b/versioned_docs/version-0.8/community/release-policy/roadmap.md similarity index 100% rename from versioned_docs/version-0.8.0/community/release-policy/roadmap.md rename to versioned_docs/version-0.8/community/release-policy/roadmap.md diff --git a/versioned_docs/version-0.5.3/reference/_advanced-concepts/_category_.json b/versioned_docs/version-0.8/reference/_advanced-concepts/_category_.json similarity index 100% rename from versioned_docs/version-0.5.3/reference/_advanced-concepts/_category_.json rename to versioned_docs/version-0.8/reference/_advanced-concepts/_category_.json diff --git a/versioned_docs/version-0.5.3/reference/_advanced-concepts/build_cache.md b/versioned_docs/version-0.8/reference/_advanced-concepts/build_cache.md similarity index 100% rename from versioned_docs/version-0.5.3/reference/_advanced-concepts/build_cache.md rename to versioned_docs/version-0.8/reference/_advanced-concepts/build_cache.md diff --git a/versioned_docs/version-0.5.3/reference/_category_.json b/versioned_docs/version-0.8/reference/_category_.json similarity index 100% rename from versioned_docs/version-0.5.3/reference/_category_.json rename to versioned_docs/version-0.8/reference/_category_.json diff --git a/versioned_docs/version-0.5.3/reference/cheatsheets/_category_.json b/versioned_docs/version-0.8/reference/cheatsheets/_category_.json similarity index 100% rename from versioned_docs/version-0.5.3/reference/cheatsheets/_category_.json rename to versioned_docs/version-0.8/reference/cheatsheets/_category_.json diff --git a/versioned_docs/version-0.5.3/reference/cheatsheets/index.md b/versioned_docs/version-0.8/reference/cheatsheets/index.md similarity index 100% rename from versioned_docs/version-0.5.3/reference/cheatsheets/index.md rename to versioned_docs/version-0.8/reference/cheatsheets/index.md diff --git a/versioned_docs/version-0.5.3/reference/lang/_category_.json b/versioned_docs/version-0.8/reference/lang/_category_.json similarity index 100% rename from versioned_docs/version-0.5.3/reference/lang/_category_.json rename to versioned_docs/version-0.8/reference/lang/_category_.json diff --git a/versioned_docs/version-0.5.3/reference/lang/codelab/_category_.json b/versioned_docs/version-0.8/reference/lang/codelab/_category_.json similarity index 100% rename from versioned_docs/version-0.5.3/reference/lang/codelab/_category_.json rename to versioned_docs/version-0.8/reference/lang/codelab/_category_.json diff --git a/versioned_docs/version-0.5.3/reference/lang/codelab/collaborative.md b/versioned_docs/version-0.8/reference/lang/codelab/collaborative.md similarity index 100% rename from versioned_docs/version-0.5.3/reference/lang/codelab/collaborative.md rename to versioned_docs/version-0.8/reference/lang/codelab/collaborative.md diff --git a/versioned_docs/version-0.5.3/reference/lang/codelab/index.md b/versioned_docs/version-0.8/reference/lang/codelab/index.md similarity index 100% rename from versioned_docs/version-0.5.3/reference/lang/codelab/index.md rename to versioned_docs/version-0.8/reference/lang/codelab/index.md diff --git a/versioned_docs/version-0.5.3/reference/lang/codelab/schema.md b/versioned_docs/version-0.8/reference/lang/codelab/schema.md similarity index 100% rename from versioned_docs/version-0.5.3/reference/lang/codelab/schema.md rename to versioned_docs/version-0.8/reference/lang/codelab/schema.md diff --git a/versioned_docs/version-0.5.3/reference/lang/codelab/simple.md b/versioned_docs/version-0.8/reference/lang/codelab/simple.md similarity index 100% rename from versioned_docs/version-0.5.3/reference/lang/codelab/simple.md rename to versioned_docs/version-0.8/reference/lang/codelab/simple.md diff --git a/versioned_docs/version-0.5.3/reference/lang/error/_category_.json b/versioned_docs/version-0.8/reference/lang/error/_category_.json similarity index 100% rename from versioned_docs/version-0.5.3/reference/lang/error/_category_.json rename to versioned_docs/version-0.8/reference/lang/error/_category_.json diff --git a/versioned_docs/version-0.8.0/reference/lang/error/exception.md b/versioned_docs/version-0.8/reference/lang/error/exception.md similarity index 100% rename from versioned_docs/version-0.8.0/reference/lang/error/exception.md rename to versioned_docs/version-0.8/reference/lang/error/exception.md diff --git a/versioned_docs/version-0.5.3/reference/lang/error/index.md b/versioned_docs/version-0.8/reference/lang/error/index.md similarity index 100% rename from versioned_docs/version-0.5.3/reference/lang/error/index.md rename to versioned_docs/version-0.8/reference/lang/error/index.md diff --git a/versioned_docs/version-0.5.3/reference/lang/spec/_category_.json b/versioned_docs/version-0.8/reference/lang/spec/_category_.json similarity index 100% rename from versioned_docs/version-0.5.3/reference/lang/spec/_category_.json rename to versioned_docs/version-0.8/reference/lang/spec/_category_.json diff --git a/versioned_docs/version-0.8.0/reference/lang/spec/codestyle.md b/versioned_docs/version-0.8/reference/lang/spec/codestyle.md similarity index 100% rename from versioned_docs/version-0.8.0/reference/lang/spec/codestyle.md rename to versioned_docs/version-0.8/reference/lang/spec/codestyle.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/datatypes.md b/versioned_docs/version-0.8/reference/lang/spec/datatypes.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/datatypes.md rename to versioned_docs/version-0.8/reference/lang/spec/datatypes.md diff --git a/versioned_docs/version-0.8.0/reference/lang/spec/error.md b/versioned_docs/version-0.8/reference/lang/spec/error.md similarity index 100% rename from versioned_docs/version-0.8.0/reference/lang/spec/error.md rename to versioned_docs/version-0.8/reference/lang/spec/error.md diff --git a/versioned_docs/version-0.7.0/reference/lang/spec/expressions.md b/versioned_docs/version-0.8/reference/lang/spec/expressions.md similarity index 100% rename from versioned_docs/version-0.7.0/reference/lang/spec/expressions.md rename to versioned_docs/version-0.8/reference/lang/spec/expressions.md diff --git a/versioned_docs/version-0.5.3/reference/lang/spec/index.md b/versioned_docs/version-0.8/reference/lang/spec/index.md similarity index 100% rename from versioned_docs/version-0.5.3/reference/lang/spec/index.md rename to versioned_docs/version-0.8/reference/lang/spec/index.md diff --git a/versioned_docs/version-0.8.0/reference/lang/spec/kcl-spec.md b/versioned_docs/version-0.8/reference/lang/spec/kcl-spec.md similarity index 100% rename from versioned_docs/version-0.8.0/reference/lang/spec/kcl-spec.md rename to versioned_docs/version-0.8/reference/lang/spec/kcl-spec.md diff --git a/versioned_docs/version-0.5.3/reference/lang/spec/lexical.md b/versioned_docs/version-0.8/reference/lang/spec/lexical.md similarity index 100% rename from versioned_docs/version-0.5.3/reference/lang/spec/lexical.md rename to versioned_docs/version-0.8/reference/lang/spec/lexical.md diff --git a/versioned_docs/version-0.8.0/reference/lang/spec/modules.md b/versioned_docs/version-0.8/reference/lang/spec/modules.md similarity index 100% rename from versioned_docs/version-0.8.0/reference/lang/spec/modules.md rename to versioned_docs/version-0.8/reference/lang/spec/modules.md diff --git a/versioned_docs/version-0.8.0/reference/lang/spec/schema.md b/versioned_docs/version-0.8/reference/lang/spec/schema.md similarity index 100% rename from versioned_docs/version-0.8.0/reference/lang/spec/schema.md rename to versioned_docs/version-0.8/reference/lang/spec/schema.md diff --git a/versioned_docs/version-0.8.0/reference/lang/spec/statements.md b/versioned_docs/version-0.8/reference/lang/spec/statements.md similarity index 100% rename from versioned_docs/version-0.8.0/reference/lang/spec/statements.md rename to versioned_docs/version-0.8/reference/lang/spec/statements.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/variables.md b/versioned_docs/version-0.8/reference/lang/spec/variables.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/reference/lang/spec/variables.md rename to versioned_docs/version-0.8/reference/lang/spec/variables.md diff --git a/versioned_docs/version-0.8.0/reference/lang/tour.md b/versioned_docs/version-0.8/reference/lang/tour.md similarity index 100% rename from versioned_docs/version-0.8.0/reference/lang/tour.md rename to versioned_docs/version-0.8/reference/lang/tour.md diff --git a/versioned_docs/version-0.5.3/reference/lang/types/_category_.json b/versioned_docs/version-0.8/reference/lang/types/_category_.json similarity index 100% rename from versioned_docs/version-0.5.3/reference/lang/types/_category_.json rename to versioned_docs/version-0.8/reference/lang/types/_category_.json diff --git a/versioned_docs/version-0.5.3/reference/lang/types/types.md b/versioned_docs/version-0.8/reference/lang/types/types.md similarity index 100% rename from versioned_docs/version-0.5.3/reference/lang/types/types.md rename to versioned_docs/version-0.8/reference/lang/types/types.md diff --git a/versioned_docs/version-0.5.3/reference/model/_category_.json b/versioned_docs/version-0.8/reference/model/_category_.json similarity index 100% rename from versioned_docs/version-0.5.3/reference/model/_category_.json rename to versioned_docs/version-0.8/reference/model/_category_.json diff --git a/versioned_docs/version-0.5.3/reference/model/base64.md b/versioned_docs/version-0.8/reference/model/base64.md similarity index 100% rename from versioned_docs/version-0.5.3/reference/model/base64.md rename to versioned_docs/version-0.8/reference/model/base64.md diff --git a/versioned_docs/version-0.5.3/reference/model/builtin.md b/versioned_docs/version-0.8/reference/model/builtin.md similarity index 100% rename from versioned_docs/version-0.5.3/reference/model/builtin.md rename to versioned_docs/version-0.8/reference/model/builtin.md diff --git a/versioned_docs/version-0.8.0/reference/model/crypto.md b/versioned_docs/version-0.8/reference/model/crypto.md similarity index 100% rename from versioned_docs/version-0.8.0/reference/model/crypto.md rename to versioned_docs/version-0.8/reference/model/crypto.md diff --git a/versioned_docs/version-0.8.0/reference/model/datetime.md b/versioned_docs/version-0.8/reference/model/datetime.md similarity index 100% rename from versioned_docs/version-0.8.0/reference/model/datetime.md rename to versioned_docs/version-0.8/reference/model/datetime.md diff --git a/versioned_docs/version-0.8.0/reference/model/file.md b/versioned_docs/version-0.8/reference/model/file.md similarity index 100% rename from versioned_docs/version-0.8.0/reference/model/file.md rename to versioned_docs/version-0.8/reference/model/file.md diff --git a/versioned_docs/version-0.8.0/reference/model/json.md b/versioned_docs/version-0.8/reference/model/json.md similarity index 100% rename from versioned_docs/version-0.8.0/reference/model/json.md rename to versioned_docs/version-0.8/reference/model/json.md diff --git a/versioned_docs/version-0.5.3/reference/model/manifests.md b/versioned_docs/version-0.8/reference/model/manifests.md similarity index 100% rename from versioned_docs/version-0.5.3/reference/model/manifests.md rename to versioned_docs/version-0.8/reference/model/manifests.md diff --git a/versioned_docs/version-0.8.0/reference/model/math.md b/versioned_docs/version-0.8/reference/model/math.md similarity index 100% rename from versioned_docs/version-0.8.0/reference/model/math.md rename to versioned_docs/version-0.8/reference/model/math.md diff --git a/versioned_docs/version-0.5.3/reference/model/net.md b/versioned_docs/version-0.8/reference/model/net.md similarity index 100% rename from versioned_docs/version-0.5.3/reference/model/net.md rename to versioned_docs/version-0.8/reference/model/net.md diff --git a/versioned_docs/version-0.8.0/reference/model/overview.md b/versioned_docs/version-0.8/reference/model/overview.md similarity index 100% rename from versioned_docs/version-0.8.0/reference/model/overview.md rename to versioned_docs/version-0.8/reference/model/overview.md diff --git a/versioned_docs/version-0.5.3/reference/model/regex.md b/versioned_docs/version-0.8/reference/model/regex.md similarity index 100% rename from versioned_docs/version-0.5.3/reference/model/regex.md rename to versioned_docs/version-0.8/reference/model/regex.md diff --git a/versioned_docs/version-0.5.3/reference/model/units.md b/versioned_docs/version-0.8/reference/model/units.md similarity index 100% rename from versioned_docs/version-0.5.3/reference/model/units.md rename to versioned_docs/version-0.8/reference/model/units.md diff --git a/versioned_docs/version-0.8.0/reference/model/yaml.md b/versioned_docs/version-0.8/reference/model/yaml.md similarity index 100% rename from versioned_docs/version-0.8.0/reference/model/yaml.md rename to versioned_docs/version-0.8/reference/model/yaml.md diff --git a/versioned_docs/version-0.5.3/reference/plugin/_category_.json b/versioned_docs/version-0.8/reference/plugin/_category_.json similarity index 100% rename from versioned_docs/version-0.5.3/reference/plugin/_category_.json rename to versioned_docs/version-0.8/reference/plugin/_category_.json diff --git a/versioned_docs/version-0.8.0/reference/plugin/overview.md b/versioned_docs/version-0.8/reference/plugin/overview.md similarity index 100% rename from versioned_docs/version-0.8.0/reference/plugin/overview.md rename to versioned_docs/version-0.8/reference/plugin/overview.md diff --git a/versioned_docs/version-0.5.3/reference/xlang-api/_category_.json b/versioned_docs/version-0.8/reference/xlang-api/_category_.json similarity index 100% rename from versioned_docs/version-0.5.3/reference/xlang-api/_category_.json rename to versioned_docs/version-0.8/reference/xlang-api/_category_.json diff --git a/versioned_docs/version-0.8.0/reference/xlang-api/go-api.md b/versioned_docs/version-0.8/reference/xlang-api/go-api.md similarity index 100% rename from versioned_docs/version-0.8.0/reference/xlang-api/go-api.md rename to versioned_docs/version-0.8/reference/xlang-api/go-api.md diff --git a/versioned_docs/version-0.5.3/reference/xlang-api/java-api.md b/versioned_docs/version-0.8/reference/xlang-api/java-api.md similarity index 100% rename from versioned_docs/version-0.5.3/reference/xlang-api/java-api.md rename to versioned_docs/version-0.8/reference/xlang-api/java-api.md diff --git a/versioned_docs/version-0.8.0/reference/xlang-api/overview.md b/versioned_docs/version-0.8/reference/xlang-api/overview.md similarity index 100% rename from versioned_docs/version-0.8.0/reference/xlang-api/overview.md rename to versioned_docs/version-0.8/reference/xlang-api/overview.md diff --git a/versioned_docs/version-0.5.3/reference/xlang-api/python-api.md b/versioned_docs/version-0.8/reference/xlang-api/python-api.md similarity index 100% rename from versioned_docs/version-0.5.3/reference/xlang-api/python-api.md rename to versioned_docs/version-0.8/reference/xlang-api/python-api.md diff --git a/versioned_docs/version-0.8.0/reference/xlang-api/rest-api.md b/versioned_docs/version-0.8/reference/xlang-api/rest-api.md similarity index 100% rename from versioned_docs/version-0.8.0/reference/xlang-api/rest-api.md rename to versioned_docs/version-0.8/reference/xlang-api/rest-api.md diff --git a/versioned_docs/version-0.5.3/tools/Ide/_category_.json b/versioned_docs/version-0.8/tools/Ide/_category_.json similarity index 100% rename from versioned_docs/version-0.5.3/tools/Ide/_category_.json rename to versioned_docs/version-0.8/tools/Ide/_category_.json diff --git a/versioned_docs/version-0.8.0/tools/Ide/index.md b/versioned_docs/version-0.8/tools/Ide/index.md similarity index 100% rename from versioned_docs/version-0.8.0/tools/Ide/index.md rename to versioned_docs/version-0.8/tools/Ide/index.md diff --git a/versioned_docs/version-0.7.0/tools/Ide/intellij.md b/versioned_docs/version-0.8/tools/Ide/intellij.md similarity index 100% rename from versioned_docs/version-0.7.0/tools/Ide/intellij.md rename to versioned_docs/version-0.8/tools/Ide/intellij.md diff --git a/versioned_docs/version-0.7.0/tools/Ide/neovim.md b/versioned_docs/version-0.8/tools/Ide/neovim.md similarity index 100% rename from versioned_docs/version-0.7.0/tools/Ide/neovim.md rename to versioned_docs/version-0.8/tools/Ide/neovim.md diff --git a/versioned_docs/version-0.8.0/tools/Ide/vs-code.md b/versioned_docs/version-0.8/tools/Ide/vs-code.md similarity index 100% rename from versioned_docs/version-0.8.0/tools/Ide/vs-code.md rename to versioned_docs/version-0.8/tools/Ide/vs-code.md diff --git a/versioned_docs/version-0.5.3/tools/_category_.json b/versioned_docs/version-0.8/tools/_category_.json similarity index 100% rename from versioned_docs/version-0.5.3/tools/_category_.json rename to versioned_docs/version-0.8/tools/_category_.json diff --git a/versioned_docs/version-0.5.3/tools/cli/_category_.json b/versioned_docs/version-0.8/tools/cli/_category_.json similarity index 100% rename from versioned_docs/version-0.5.3/tools/cli/_category_.json rename to versioned_docs/version-0.8/tools/cli/_category_.json diff --git a/versioned_docs/version-0.5.3/tools/cli/index.md b/versioned_docs/version-0.8/tools/cli/index.md similarity index 100% rename from versioned_docs/version-0.5.3/tools/cli/index.md rename to versioned_docs/version-0.8/tools/cli/index.md diff --git a/versioned_docs/version-0.5.3/tools/cli/kcl/_category_.json b/versioned_docs/version-0.8/tools/cli/kcl/_category_.json similarity index 100% rename from versioned_docs/version-0.5.3/tools/cli/kcl/_category_.json rename to versioned_docs/version-0.8/tools/cli/kcl/_category_.json diff --git a/versioned_docs/version-0.8.0/tools/cli/kcl/docgen.md b/versioned_docs/version-0.8/tools/cli/kcl/docgen.md similarity index 100% rename from versioned_docs/version-0.8.0/tools/cli/kcl/docgen.md rename to versioned_docs/version-0.8/tools/cli/kcl/docgen.md diff --git a/versioned_docs/version-0.8.0/tools/cli/kcl/fmt.md b/versioned_docs/version-0.8/tools/cli/kcl/fmt.md similarity index 100% rename from versioned_docs/version-0.8.0/tools/cli/kcl/fmt.md rename to versioned_docs/version-0.8/tools/cli/kcl/fmt.md diff --git a/versioned_docs/version-0.8.0/tools/cli/kcl/import.md b/versioned_docs/version-0.8/tools/cli/kcl/import.md similarity index 100% rename from versioned_docs/version-0.8.0/tools/cli/kcl/import.md rename to versioned_docs/version-0.8/tools/cli/kcl/import.md diff --git a/versioned_docs/version-0.8.0/tools/cli/kcl/index.md b/versioned_docs/version-0.8/tools/cli/kcl/index.md similarity index 100% rename from versioned_docs/version-0.8.0/tools/cli/kcl/index.md rename to versioned_docs/version-0.8/tools/cli/kcl/index.md diff --git a/versioned_docs/version-0.8.0/tools/cli/kcl/lint.md b/versioned_docs/version-0.8/tools/cli/kcl/lint.md similarity index 100% rename from versioned_docs/version-0.8.0/tools/cli/kcl/lint.md rename to versioned_docs/version-0.8/tools/cli/kcl/lint.md diff --git a/versioned_docs/version-0.8.0/tools/cli/kcl/overview.md b/versioned_docs/version-0.8/tools/cli/kcl/overview.md similarity index 100% rename from versioned_docs/version-0.8.0/tools/cli/kcl/overview.md rename to versioned_docs/version-0.8/tools/cli/kcl/overview.md diff --git a/versioned_docs/version-0.8.0/tools/cli/kcl/run.md b/versioned_docs/version-0.8/tools/cli/kcl/run.md similarity index 100% rename from versioned_docs/version-0.8.0/tools/cli/kcl/run.md rename to versioned_docs/version-0.8/tools/cli/kcl/run.md diff --git a/versioned_docs/version-0.8.0/tools/cli/kcl/test.md b/versioned_docs/version-0.8/tools/cli/kcl/test.md similarity index 100% rename from versioned_docs/version-0.8.0/tools/cli/kcl/test.md rename to versioned_docs/version-0.8/tools/cli/kcl/test.md diff --git a/versioned_docs/version-0.8.0/tools/cli/kcl/vet.md b/versioned_docs/version-0.8/tools/cli/kcl/vet.md similarity index 100% rename from versioned_docs/version-0.8.0/tools/cli/kcl/vet.md rename to versioned_docs/version-0.8/tools/cli/kcl/vet.md diff --git a/versioned_docs/version-0.5.3/tools/cli/openapi/_category_.json b/versioned_docs/version-0.8/tools/cli/openapi/_category_.json similarity index 100% rename from versioned_docs/version-0.5.3/tools/cli/openapi/_category_.json rename to versioned_docs/version-0.8/tools/cli/openapi/_category_.json diff --git a/versioned_docs/version-0.8.0/tools/cli/openapi/crd-to-kcl.md b/versioned_docs/version-0.8/tools/cli/openapi/crd-to-kcl.md similarity index 100% rename from versioned_docs/version-0.8.0/tools/cli/openapi/crd-to-kcl.md rename to versioned_docs/version-0.8/tools/cli/openapi/crd-to-kcl.md diff --git a/versioned_docs/version-0.8.0/tools/cli/openapi/openapi-to-kcl.md b/versioned_docs/version-0.8/tools/cli/openapi/openapi-to-kcl.md similarity index 100% rename from versioned_docs/version-0.8.0/tools/cli/openapi/openapi-to-kcl.md rename to versioned_docs/version-0.8/tools/cli/openapi/openapi-to-kcl.md diff --git a/versioned_docs/version-0.7.0/tools/cli/openapi/spec.md b/versioned_docs/version-0.8/tools/cli/openapi/spec.md similarity index 100% rename from versioned_docs/version-0.7.0/tools/cli/openapi/spec.md rename to versioned_docs/version-0.8/tools/cli/openapi/spec.md diff --git a/versioned_docs/version-0.8.0/tools/cli/package-management/_category_.json b/versioned_docs/version-0.8/tools/cli/package-management/_category_.json similarity index 100% rename from versioned_docs/version-0.8.0/tools/cli/package-management/_category_.json rename to versioned_docs/version-0.8/tools/cli/package-management/_category_.json diff --git a/versioned_docs/version-0.8.0/tools/cli/package-management/command-reference/1.init.md b/versioned_docs/version-0.8/tools/cli/package-management/command-reference/1.init.md similarity index 100% rename from versioned_docs/version-0.8.0/tools/cli/package-management/command-reference/1.init.md rename to versioned_docs/version-0.8/tools/cli/package-management/command-reference/1.init.md diff --git a/versioned_docs/version-0.8.0/tools/cli/package-management/command-reference/10.help.md b/versioned_docs/version-0.8/tools/cli/package-management/command-reference/10.help.md similarity index 100% rename from versioned_docs/version-0.8.0/tools/cli/package-management/command-reference/10.help.md rename to versioned_docs/version-0.8/tools/cli/package-management/command-reference/10.help.md diff --git a/versioned_docs/version-0.8.0/tools/cli/package-management/command-reference/11.update.md b/versioned_docs/version-0.8/tools/cli/package-management/command-reference/11.update.md similarity index 100% rename from versioned_docs/version-0.8.0/tools/cli/package-management/command-reference/11.update.md rename to versioned_docs/version-0.8/tools/cli/package-management/command-reference/11.update.md diff --git a/versioned_docs/version-0.8.0/tools/cli/package-management/command-reference/2.add.md b/versioned_docs/version-0.8/tools/cli/package-management/command-reference/2.add.md similarity index 100% rename from versioned_docs/version-0.8.0/tools/cli/package-management/command-reference/2.add.md rename to versioned_docs/version-0.8/tools/cli/package-management/command-reference/2.add.md diff --git a/versioned_docs/version-0.8.0/tools/cli/package-management/command-reference/3.pkg.md b/versioned_docs/version-0.8/tools/cli/package-management/command-reference/3.pkg.md similarity index 100% rename from versioned_docs/version-0.8.0/tools/cli/package-management/command-reference/3.pkg.md rename to versioned_docs/version-0.8/tools/cli/package-management/command-reference/3.pkg.md diff --git a/versioned_docs/version-0.8.0/tools/cli/package-management/command-reference/4.metadata.md b/versioned_docs/version-0.8/tools/cli/package-management/command-reference/4.metadata.md similarity index 100% rename from versioned_docs/version-0.8.0/tools/cli/package-management/command-reference/4.metadata.md rename to versioned_docs/version-0.8/tools/cli/package-management/command-reference/4.metadata.md diff --git a/versioned_docs/version-0.8.0/tools/cli/package-management/command-reference/6.login.md b/versioned_docs/version-0.8/tools/cli/package-management/command-reference/6.login.md similarity index 100% rename from versioned_docs/version-0.8.0/tools/cli/package-management/command-reference/6.login.md rename to versioned_docs/version-0.8/tools/cli/package-management/command-reference/6.login.md diff --git a/versioned_docs/version-0.8.0/tools/cli/package-management/command-reference/7.logout.md b/versioned_docs/version-0.8/tools/cli/package-management/command-reference/7.logout.md similarity index 100% rename from versioned_docs/version-0.8.0/tools/cli/package-management/command-reference/7.logout.md rename to versioned_docs/version-0.8/tools/cli/package-management/command-reference/7.logout.md diff --git a/versioned_docs/version-0.8.0/tools/cli/package-management/command-reference/8.push.md b/versioned_docs/version-0.8/tools/cli/package-management/command-reference/8.push.md similarity index 100% rename from versioned_docs/version-0.8.0/tools/cli/package-management/command-reference/8.push.md rename to versioned_docs/version-0.8/tools/cli/package-management/command-reference/8.push.md diff --git a/versioned_docs/version-0.8.0/tools/cli/package-management/command-reference/9.pull.md b/versioned_docs/version-0.8/tools/cli/package-management/command-reference/9.pull.md similarity index 100% rename from versioned_docs/version-0.8.0/tools/cli/package-management/command-reference/9.pull.md rename to versioned_docs/version-0.8/tools/cli/package-management/command-reference/9.pull.md diff --git a/versioned_docs/version-0.5.3/reference/package-management/command-reference/_category_.json b/versioned_docs/version-0.8/tools/cli/package-management/command-reference/_category_.json similarity index 100% rename from versioned_docs/version-0.5.3/reference/package-management/command-reference/_category_.json rename to versioned_docs/version-0.8/tools/cli/package-management/command-reference/_category_.json diff --git a/versioned_docs/version-0.5.3/user_docs/concepts/_category_.json b/versioned_docs/version-0.8/user_docs/concepts/_category_.json similarity index 100% rename from versioned_docs/version-0.5.3/user_docs/concepts/_category_.json rename to versioned_docs/version-0.8/user_docs/concepts/_category_.json diff --git a/versioned_docs/version-0.8.0/user_docs/concepts/concepts.md b/versioned_docs/version-0.8/user_docs/concepts/concepts.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/concepts/concepts.md rename to versioned_docs/version-0.8/user_docs/concepts/concepts.md diff --git a/versioned_docs/version-0.5.3/user_docs/concepts/package-and-module.md b/versioned_docs/version-0.8/user_docs/concepts/package-and-module.md similarity index 100% rename from versioned_docs/version-0.5.3/user_docs/concepts/package-and-module.md rename to versioned_docs/version-0.8/user_docs/concepts/package-and-module.md diff --git a/versioned_docs/version-0.6.0/user_docs/concepts/type-and-definition.md b/versioned_docs/version-0.8/user_docs/concepts/type-and-definition.md similarity index 100% rename from versioned_docs/version-0.6.0/user_docs/concepts/type-and-definition.md rename to versioned_docs/version-0.8/user_docs/concepts/type-and-definition.md diff --git a/versioned_docs/version-0.5.3/user_docs/getting-started/_category_.json b/versioned_docs/version-0.8/user_docs/getting-started/_category_.json similarity index 100% rename from versioned_docs/version-0.5.3/user_docs/getting-started/_category_.json rename to versioned_docs/version-0.8/user_docs/getting-started/_category_.json diff --git a/versioned_docs/version-0.8.0/user_docs/getting-started/index.md b/versioned_docs/version-0.8/user_docs/getting-started/index.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/getting-started/index.md rename to versioned_docs/version-0.8/user_docs/getting-started/index.md diff --git a/versioned_docs/version-0.8.0/user_docs/getting-started/install.md b/versioned_docs/version-0.8/user_docs/getting-started/install.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/getting-started/install.md rename to versioned_docs/version-0.8/user_docs/getting-started/install.md diff --git a/versioned_docs/version-0.8.0/user_docs/getting-started/intro.md b/versioned_docs/version-0.8/user_docs/getting-started/intro.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/getting-started/intro.md rename to versioned_docs/version-0.8/user_docs/getting-started/intro.md diff --git a/versioned_docs/version-0.5.3/user_docs/getting-started/kcl-quick-start.md b/versioned_docs/version-0.8/user_docs/getting-started/kcl-quick-start.md similarity index 100% rename from versioned_docs/version-0.5.3/user_docs/getting-started/kcl-quick-start.md rename to versioned_docs/version-0.8/user_docs/getting-started/kcl-quick-start.md diff --git a/versioned_docs/version-0.5.3/user_docs/guides/_category_.json b/versioned_docs/version-0.8/user_docs/guides/_category_.json similarity index 100% rename from versioned_docs/version-0.5.3/user_docs/guides/_category_.json rename to versioned_docs/version-0.8/user_docs/guides/_category_.json diff --git a/versioned_docs/version-0.5.5/user_docs/guides/abstraction.md b/versioned_docs/version-0.8/user_docs/guides/abstraction.md similarity index 100% rename from versioned_docs/version-0.5.5/user_docs/guides/abstraction.md rename to versioned_docs/version-0.8/user_docs/guides/abstraction.md diff --git a/versioned_docs/version-0.8.0/user_docs/guides/automation.md b/versioned_docs/version-0.8/user_docs/guides/automation.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/automation.md rename to versioned_docs/version-0.8/user_docs/guides/automation.md diff --git a/versioned_docs/version-0.5.5/user_docs/guides/ci-integration/1-github-actions.md b/versioned_docs/version-0.8/user_docs/guides/ci-integration/1-github-actions.md similarity index 100% rename from versioned_docs/version-0.5.5/user_docs/guides/ci-integration/1-github-actions.md rename to versioned_docs/version-0.8/user_docs/guides/ci-integration/1-github-actions.md diff --git a/versioned_docs/version-0.5.5/user_docs/guides/ci-integration/2-gitlab-ci.md b/versioned_docs/version-0.8/user_docs/guides/ci-integration/2-gitlab-ci.md similarity index 100% rename from versioned_docs/version-0.5.5/user_docs/guides/ci-integration/2-gitlab-ci.md rename to versioned_docs/version-0.8/user_docs/guides/ci-integration/2-gitlab-ci.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/ci-integration/_3-jenkins-ci.md b/versioned_docs/version-0.8/user_docs/guides/ci-integration/_3-jenkins-ci.md similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/ci-integration/_3-jenkins-ci.md rename to versioned_docs/version-0.8/user_docs/guides/ci-integration/_3-jenkins-ci.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/ci-integration/_category_.json b/versioned_docs/version-0.8/user_docs/guides/ci-integration/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/ci-integration/_category_.json rename to versioned_docs/version-0.8/user_docs/guides/ci-integration/_category_.json diff --git a/versioned_docs/version-0.8.0/user_docs/guides/configuration.md b/versioned_docs/version-0.8/user_docs/guides/configuration.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/configuration.md rename to versioned_docs/version-0.8/user_docs/guides/configuration.md diff --git a/versioned_docs/version-0.5.5/user_docs/guides/data-integration.md b/versioned_docs/version-0.8/user_docs/guides/data-integration.md similarity index 100% rename from versioned_docs/version-0.5.5/user_docs/guides/data-integration.md rename to versioned_docs/version-0.8/user_docs/guides/data-integration.md diff --git a/versioned_docs/version-0.8.0/user_docs/guides/gitops/1-argocd.md b/versioned_docs/version-0.8/user_docs/guides/gitops/1-argocd.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/gitops/1-argocd.md rename to versioned_docs/version-0.8/user_docs/guides/gitops/1-argocd.md diff --git a/versioned_docs/version-0.8.0/user_docs/guides/gitops/2-fluxcd.md b/versioned_docs/version-0.8/user_docs/guides/gitops/2-fluxcd.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/gitops/2-fluxcd.md rename to versioned_docs/version-0.8/user_docs/guides/gitops/2-fluxcd.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/gitops/_category_.json b/versioned_docs/version-0.8/user_docs/guides/gitops/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/gitops/_category_.json rename to versioned_docs/version-0.8/user_docs/guides/gitops/_category_.json diff --git a/versioned_docs/version-0.8.0/user_docs/guides/index.md b/versioned_docs/version-0.8/user_docs/guides/index.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/index.md rename to versioned_docs/version-0.8/user_docs/guides/index.md diff --git a/versioned_docs/version-0.8.0/user_docs/guides/package-management/3-quick-start.md b/versioned_docs/version-0.8/user_docs/guides/package-management/3-quick-start.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/package-management/3-quick-start.md rename to versioned_docs/version-0.8/user_docs/guides/package-management/3-quick-start.md diff --git a/versioned_docs/version-0.8.0/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md b/versioned_docs/version-0.8/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md rename to versioned_docs/version-0.8/user_docs/guides/package-management/4-how-to/4-share_your_pkg.md diff --git a/versioned_docs/version-0.8.0/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md b/versioned_docs/version-0.8/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md rename to versioned_docs/version-0.8/user_docs/guides/package-management/4-how-to/5-share_your_pkg_docker.md diff --git a/versioned_docs/version-0.8.0/user_docs/guides/package-management/4-how-to/6-push_github_action.md b/versioned_docs/version-0.8/user_docs/guides/package-management/4-how-to/6-push_github_action.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/package-management/4-how-to/6-push_github_action.md rename to versioned_docs/version-0.8/user_docs/guides/package-management/4-how-to/6-push_github_action.md diff --git a/versioned_docs/version-0.8.0/user_docs/guides/package-management/4-how-to/7-publish_pkg_to_ah.md b/versioned_docs/version-0.8/user_docs/guides/package-management/4-how-to/7-publish_pkg_to_ah.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/package-management/4-how-to/7-publish_pkg_to_ah.md rename to versioned_docs/version-0.8/user_docs/guides/package-management/4-how-to/7-publish_pkg_to_ah.md diff --git a/versioned_docs/version-0.8.0/user_docs/guides/package-management/4-how-to/8-kcl_mod.md b/versioned_docs/version-0.8/user_docs/guides/package-management/4-how-to/8-kcl_mod.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/package-management/4-how-to/8-kcl_mod.md rename to versioned_docs/version-0.8/user_docs/guides/package-management/4-how-to/8-kcl_mod.md diff --git a/versioned_docs/version-0.8.0/user_docs/guides/package-management/4-how-to/9-kpm_oci.md b/versioned_docs/version-0.8/user_docs/guides/package-management/4-how-to/9-kpm_oci.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/package-management/4-how-to/9-kpm_oci.md rename to versioned_docs/version-0.8/user_docs/guides/package-management/4-how-to/9-kpm_oci.md diff --git a/versioned_docs/version-0.5.2/user_docs/guides/package-management/4-how-to/_category_.json b/versioned_docs/version-0.8/user_docs/guides/package-management/4-how-to/_category_.json similarity index 100% rename from versioned_docs/version-0.5.2/user_docs/guides/package-management/4-how-to/_category_.json rename to versioned_docs/version-0.8/user_docs/guides/package-management/4-how-to/_category_.json diff --git a/versioned_docs/version-0.5.3/user_docs/guides/package-management/_category_.json b/versioned_docs/version-0.8/user_docs/guides/package-management/_category_.json similarity index 100% rename from versioned_docs/version-0.5.3/user_docs/guides/package-management/_category_.json rename to versioned_docs/version-0.8/user_docs/guides/package-management/_category_.json diff --git a/versioned_docs/version-0.5.5/user_docs/guides/schema-definition.md b/versioned_docs/version-0.8/user_docs/guides/schema-definition.md similarity index 100% rename from versioned_docs/version-0.5.5/user_docs/guides/schema-definition.md rename to versioned_docs/version-0.8/user_docs/guides/schema-definition.md diff --git a/versioned_docs/version-0.5.4/user_docs/guides/secret-management/1-vault.md b/versioned_docs/version-0.8/user_docs/guides/secret-management/1-vault.md similarity index 100% rename from versioned_docs/version-0.5.4/user_docs/guides/secret-management/1-vault.md rename to versioned_docs/version-0.8/user_docs/guides/secret-management/1-vault.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/secret-management/_category_.json b/versioned_docs/version-0.8/user_docs/guides/secret-management/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/secret-management/_category_.json rename to versioned_docs/version-0.8/user_docs/guides/secret-management/_category_.json diff --git a/versioned_docs/version-0.8.0/user_docs/guides/validation.md b/versioned_docs/version-0.8/user_docs/guides/validation.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/validation.md rename to versioned_docs/version-0.8/user_docs/guides/validation.md diff --git a/versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/0-overview.md b/versioned_docs/version-0.8/user_docs/guides/working-with-k8s/0-overview.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/0-overview.md rename to versioned_docs/version-0.8/user_docs/guides/working-with-k8s/0-overview.md diff --git a/versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md b/versioned_docs/version-0.8/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md rename to versioned_docs/version-0.8/user_docs/guides/working-with-k8s/1-adopt-from-kubernetes.md diff --git a/versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md b/versioned_docs/version-0.8/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md rename to versioned_docs/version-0.8/user_docs/guides/working-with-k8s/2-generate-k8s-manifests.md diff --git a/versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md b/versioned_docs/version-0.8/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md rename to versioned_docs/version-0.8/user_docs/guides/working-with-k8s/3-mutate-manifests/1-kubectl-kcl-plugin.md diff --git a/versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md b/versioned_docs/version-0.8/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md rename to versioned_docs/version-0.8/user_docs/guides/working-with-k8s/3-mutate-manifests/2-helm-kcl-plugin.md diff --git a/versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md b/versioned_docs/version-0.8/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md rename to versioned_docs/version-0.8/user_docs/guides/working-with-k8s/3-mutate-manifests/3-kustomize-kcl-plugin.md diff --git a/versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md b/versioned_docs/version-0.8/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md rename to versioned_docs/version-0.8/user_docs/guides/working-with-k8s/3-mutate-manifests/4-kpt-kcl-sdk.md diff --git a/versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md b/versioned_docs/version-0.8/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md rename to versioned_docs/version-0.8/user_docs/guides/working-with-k8s/3-mutate-manifests/5-helmfile-kcl-plugin.md diff --git a/versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/6-kcl-operator.md b/versioned_docs/version-0.8/user_docs/guides/working-with-k8s/3-mutate-manifests/6-kcl-operator.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/6-kcl-operator.md rename to versioned_docs/version-0.8/user_docs/guides/working-with-k8s/3-mutate-manifests/6-kcl-operator.md diff --git a/versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/7-crossplane-kcl-function.md b/versioned_docs/version-0.8/user_docs/guides/working-with-k8s/3-mutate-manifests/7-crossplane-kcl-function.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/working-with-k8s/3-mutate-manifests/7-crossplane-kcl-function.md rename to versioned_docs/version-0.8/user_docs/guides/working-with-k8s/3-mutate-manifests/7-crossplane-kcl-function.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json b/versioned_docs/version-0.8/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json rename to versioned_docs/version-0.8/user_docs/guides/working-with-k8s/3-mutate-manifests/_category_.json diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/_category_.json b/versioned_docs/version-0.8/user_docs/guides/working-with-k8s/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-k8s/_category_.json rename to versioned_docs/version-0.8/user_docs/guides/working-with-k8s/_category_.json diff --git a/versioned_docs/version-0.8.0/user_docs/guides/working-with-konfig/1-overview.md b/versioned_docs/version-0.8/user_docs/guides/working-with-konfig/1-overview.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/working-with-konfig/1-overview.md rename to versioned_docs/version-0.8/user_docs/guides/working-with-konfig/1-overview.md diff --git a/versioned_docs/version-0.8.0/user_docs/guides/working-with-konfig/2-structure.md b/versioned_docs/version-0.8/user_docs/guides/working-with-konfig/2-structure.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/working-with-konfig/2-structure.md rename to versioned_docs/version-0.8/user_docs/guides/working-with-konfig/2-structure.md diff --git a/versioned_docs/version-0.8.0/user_docs/guides/working-with-konfig/3-quick-start.md b/versioned_docs/version-0.8/user_docs/guides/working-with-konfig/3-quick-start.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/working-with-konfig/3-quick-start.md rename to versioned_docs/version-0.8/user_docs/guides/working-with-konfig/3-quick-start.md diff --git a/versioned_docs/version-0.5.3/user_docs/guides/working-with-konfig/4-best-practice.md b/versioned_docs/version-0.8/user_docs/guides/working-with-konfig/4-best-practice.md similarity index 100% rename from versioned_docs/version-0.5.3/user_docs/guides/working-with-konfig/4-best-practice.md rename to versioned_docs/version-0.8/user_docs/guides/working-with-konfig/4-best-practice.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-konfig/_category_.json b/versioned_docs/version-0.8/user_docs/guides/working-with-konfig/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.6.0/user_docs/guides/working-with-konfig/_category_.json rename to versioned_docs/version-0.8/user_docs/guides/working-with-konfig/_category_.json diff --git a/versioned_docs/version-0.8.0/user_docs/guides/working-with-kubevela/_category_.json b/versioned_docs/version-0.8/user_docs/guides/working-with-kubevela/_category_.json similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/working-with-kubevela/_category_.json rename to versioned_docs/version-0.8/user_docs/guides/working-with-kubevela/_category_.json diff --git a/versioned_docs/version-0.8.0/user_docs/guides/working-with-kubevela/index.md b/versioned_docs/version-0.8/user_docs/guides/working-with-kubevela/index.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/working-with-kubevela/index.md rename to versioned_docs/version-0.8/user_docs/guides/working-with-kubevela/index.md diff --git a/i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-kusion/_category_.json b/versioned_docs/version-0.8/user_docs/guides/working-with-kusion/_category_.json similarity index 100% rename from i18n/zh-CN/docusaurus-plugin-content-docs/version-0.7.0/user_docs/guides/working-with-kusion/_category_.json rename to versioned_docs/version-0.8/user_docs/guides/working-with-kusion/_category_.json diff --git a/versioned_docs/version-0.5.3/user_docs/guides/working-with-kusion/index.md b/versioned_docs/version-0.8/user_docs/guides/working-with-kusion/index.md similarity index 100% rename from versioned_docs/version-0.5.3/user_docs/guides/working-with-kusion/index.md rename to versioned_docs/version-0.8/user_docs/guides/working-with-kusion/index.md diff --git a/versioned_docs/version-0.8.0/user_docs/guides/working-with-terraform/3-validation.md b/versioned_docs/version-0.8/user_docs/guides/working-with-terraform/3-validation.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/working-with-terraform/3-validation.md rename to versioned_docs/version-0.8/user_docs/guides/working-with-terraform/3-validation.md diff --git a/versioned_docs/version-0.8.0/user_docs/guides/working-with-terraform/_1-adopt-from-terraform.md b/versioned_docs/version-0.8/user_docs/guides/working-with-terraform/_1-adopt-from-terraform.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/working-with-terraform/_1-adopt-from-terraform.md rename to versioned_docs/version-0.8/user_docs/guides/working-with-terraform/_1-adopt-from-terraform.md diff --git a/versioned_docs/version-0.8.0/user_docs/guides/working-with-terraform/_2-abstraction.md b/versioned_docs/version-0.8/user_docs/guides/working-with-terraform/_2-abstraction.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/working-with-terraform/_2-abstraction.md rename to versioned_docs/version-0.8/user_docs/guides/working-with-terraform/_2-abstraction.md diff --git a/versioned_docs/version-0.8.0/user_docs/guides/working-with-terraform/_category_.json b/versioned_docs/version-0.8/user_docs/guides/working-with-terraform/_category_.json similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/guides/working-with-terraform/_category_.json rename to versioned_docs/version-0.8/user_docs/guides/working-with-terraform/_category_.json diff --git a/versioned_docs/version-0.5.3/user_docs/support/_category_.json b/versioned_docs/version-0.8/user_docs/support/_category_.json similarity index 100% rename from versioned_docs/version-0.5.3/user_docs/support/_category_.json rename to versioned_docs/version-0.8/user_docs/support/_category_.json diff --git a/versioned_docs/version-0.5.3/user_docs/support/faq-cli.md b/versioned_docs/version-0.8/user_docs/support/faq-cli.md similarity index 100% rename from versioned_docs/version-0.5.3/user_docs/support/faq-cli.md rename to versioned_docs/version-0.8/user_docs/support/faq-cli.md diff --git a/versioned_docs/version-0.8.0/user_docs/support/faq-install.md b/versioned_docs/version-0.8/user_docs/support/faq-install.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/support/faq-install.md rename to versioned_docs/version-0.8/user_docs/support/faq-install.md diff --git a/versioned_docs/version-0.8.0/user_docs/support/faq-kcl.md b/versioned_docs/version-0.8/user_docs/support/faq-kcl.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/support/faq-kcl.md rename to versioned_docs/version-0.8/user_docs/support/faq-kcl.md diff --git a/versioned_docs/version-0.5.3/user_docs/support/faq-yaml.md b/versioned_docs/version-0.8/user_docs/support/faq-yaml.md similarity index 100% rename from versioned_docs/version-0.5.3/user_docs/support/faq-yaml.md rename to versioned_docs/version-0.8/user_docs/support/faq-yaml.md diff --git a/versioned_docs/version-0.8.0/user_docs/support/support.md b/versioned_docs/version-0.8/user_docs/support/support.md similarity index 100% rename from versioned_docs/version-0.8.0/user_docs/support/support.md rename to versioned_docs/version-0.8/user_docs/support/support.md diff --git a/versioned_sidebars/version-0.5.0-sidebars.json b/versioned_sidebars/version-0.5-sidebars.json similarity index 100% rename from versioned_sidebars/version-0.5.0-sidebars.json rename to versioned_sidebars/version-0.5-sidebars.json diff --git a/versioned_sidebars/version-0.5.4-sidebars.json b/versioned_sidebars/version-0.5.4-sidebars.json deleted file mode 100644 index b7198684..00000000 --- a/versioned_sidebars/version-0.5.4-sidebars.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "docs": [ - { - "type": "autogenerated", - "dirName": "." - } - ], - "user_docs": [ - { - "type": "autogenerated", - "dirName": "user_docs" - } - ], - "reference": [ - { - "type": "autogenerated", - "dirName": "reference" - } - ], - "tools": [ - { - "type": "autogenerated", - "dirName": "tools" - } - ], - "community": [ - { - "type": "autogenerated", - "dirName": "community" - } - ] -} diff --git a/versioned_sidebars/version-0.5.5-sidebars.json b/versioned_sidebars/version-0.5.5-sidebars.json deleted file mode 100644 index b7198684..00000000 --- a/versioned_sidebars/version-0.5.5-sidebars.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "docs": [ - { - "type": "autogenerated", - "dirName": "." - } - ], - "user_docs": [ - { - "type": "autogenerated", - "dirName": "user_docs" - } - ], - "reference": [ - { - "type": "autogenerated", - "dirName": "reference" - } - ], - "tools": [ - { - "type": "autogenerated", - "dirName": "tools" - } - ], - "community": [ - { - "type": "autogenerated", - "dirName": "community" - } - ] -} diff --git a/versioned_sidebars/version-0.5.6-sidebars.json b/versioned_sidebars/version-0.5.6-sidebars.json deleted file mode 100644 index b7198684..00000000 --- a/versioned_sidebars/version-0.5.6-sidebars.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "docs": [ - { - "type": "autogenerated", - "dirName": "." - } - ], - "user_docs": [ - { - "type": "autogenerated", - "dirName": "user_docs" - } - ], - "reference": [ - { - "type": "autogenerated", - "dirName": "reference" - } - ], - "tools": [ - { - "type": "autogenerated", - "dirName": "tools" - } - ], - "community": [ - { - "type": "autogenerated", - "dirName": "community" - } - ] -} diff --git a/versioned_sidebars/version-0.5.1-sidebars.json b/versioned_sidebars/version-0.6-sidebars.json similarity index 100% rename from versioned_sidebars/version-0.5.1-sidebars.json rename to versioned_sidebars/version-0.6-sidebars.json diff --git a/versioned_sidebars/version-0.6.0-sidebars.json b/versioned_sidebars/version-0.6.0-sidebars.json deleted file mode 100644 index b7198684..00000000 --- a/versioned_sidebars/version-0.6.0-sidebars.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "docs": [ - { - "type": "autogenerated", - "dirName": "." - } - ], - "user_docs": [ - { - "type": "autogenerated", - "dirName": "user_docs" - } - ], - "reference": [ - { - "type": "autogenerated", - "dirName": "reference" - } - ], - "tools": [ - { - "type": "autogenerated", - "dirName": "tools" - } - ], - "community": [ - { - "type": "autogenerated", - "dirName": "community" - } - ] -} diff --git a/versioned_sidebars/version-0.5.2-sidebars.json b/versioned_sidebars/version-0.7-sidebars.json similarity index 100% rename from versioned_sidebars/version-0.5.2-sidebars.json rename to versioned_sidebars/version-0.7-sidebars.json diff --git a/versioned_sidebars/version-0.7.0-sidebars.json b/versioned_sidebars/version-0.7.0-sidebars.json deleted file mode 100644 index b7198684..00000000 --- a/versioned_sidebars/version-0.7.0-sidebars.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "docs": [ - { - "type": "autogenerated", - "dirName": "." - } - ], - "user_docs": [ - { - "type": "autogenerated", - "dirName": "user_docs" - } - ], - "reference": [ - { - "type": "autogenerated", - "dirName": "reference" - } - ], - "tools": [ - { - "type": "autogenerated", - "dirName": "tools" - } - ], - "community": [ - { - "type": "autogenerated", - "dirName": "community" - } - ] -} diff --git a/versioned_sidebars/version-0.5.3-sidebars.json b/versioned_sidebars/version-0.8-sidebars.json similarity index 100% rename from versioned_sidebars/version-0.5.3-sidebars.json rename to versioned_sidebars/version-0.8-sidebars.json diff --git a/versioned_sidebars/version-0.8.0-sidebars.json b/versioned_sidebars/version-0.8.0-sidebars.json deleted file mode 100644 index b7198684..00000000 --- a/versioned_sidebars/version-0.8.0-sidebars.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "docs": [ - { - "type": "autogenerated", - "dirName": "." - } - ], - "user_docs": [ - { - "type": "autogenerated", - "dirName": "user_docs" - } - ], - "reference": [ - { - "type": "autogenerated", - "dirName": "reference" - } - ], - "tools": [ - { - "type": "autogenerated", - "dirName": "tools" - } - ], - "community": [ - { - "type": "autogenerated", - "dirName": "community" - } - ] -} diff --git a/versions.json b/versions.json index 4857e5b3..702d45a0 100644 --- a/versions.json +++ b/versions.json @@ -1,14 +1,8 @@ [ - "0.8.0", - "0.7.0", - "0.6.0", - "0.5.6", - "0.5.5", - "0.5.4", - "0.5.3", - "0.5.2", - "0.5.1", - "0.5.0", + "0.8", + "0.7", + "0.6", + "0.5", "0.4.6", "0.4.5", "0.4.4",